diff options
author | Peter Kohaut | 2018-12-05 18:18:13 +0100 |
---|---|---|
committer | Peter Kohaut | 2018-12-05 18:18:49 +0100 |
commit | 1855d1cf13de5c9f4cf84fc07ab4b5053cae5295 (patch) | |
tree | 0359b9125083f1fceefa6f121be22299a5ae7859 /engines/bladerunner/ui | |
parent | 216d4743489d2284eff6afd7bc7a7e5a92693eea (diff) | |
download | scummvm-rg350-1855d1cf13de5c9f4cf84fc07ab4b5053cae5295.tar.gz scummvm-rg350-1855d1cf13de5c9f4cf84fc07ab4b5053cae5295.tar.bz2 scummvm-rg350-1855d1cf13de5c9f4cf84fc07ab4b5053cae5295.zip |
BLADERUNNER: Add in-game saving screen
Diffstat (limited to 'engines/bladerunner/ui')
-rw-r--r-- | engines/bladerunner/ui/kia.h | 11 | ||||
-rw-r--r-- | engines/bladerunner/ui/kia_section_clues.h | 8 | ||||
-rw-r--r-- | engines/bladerunner/ui/kia_section_load.cpp | 47 | ||||
-rw-r--r-- | engines/bladerunner/ui/kia_section_load.h | 34 | ||||
-rw-r--r-- | engines/bladerunner/ui/kia_section_save.cpp | 407 | ||||
-rw-r--r-- | engines/bladerunner/ui/kia_section_save.h | 61 | ||||
-rw-r--r-- | engines/bladerunner/ui/ui_component.h | 1 | ||||
-rw-r--r-- | engines/bladerunner/ui/ui_container.cpp | 6 | ||||
-rw-r--r-- | engines/bladerunner/ui/ui_container.h | 1 | ||||
-rw-r--r-- | engines/bladerunner/ui/ui_input_box.cpp | 19 | ||||
-rw-r--r-- | engines/bladerunner/ui/ui_input_box.h | 8 |
11 files changed, 542 insertions, 61 deletions
diff --git a/engines/bladerunner/ui/kia.h b/engines/bladerunner/ui/kia.h index b5be9a7e08..c6d612f0df 100644 --- a/engines/bladerunner/ui/kia.h +++ b/engines/bladerunner/ui/kia.h @@ -115,14 +115,15 @@ class KIA { int _pogoPos; - Graphics::Surface _thumbnail; public: - bool _forceOpen; + bool _forceOpen; - KIALog *_log; - KIAScript *_script; - KIAShapes *_shapes; + KIALog *_log; + KIAScript *_script; + KIAShapes *_shapes; + + Graphics::Surface _thumbnail; public: KIA(BladeRunnerEngine *vm); diff --git a/engines/bladerunner/ui/kia_section_clues.h b/engines/bladerunner/ui/kia_section_clues.h index afd8b67433..1061e637df 100644 --- a/engines/bladerunner/ui/kia_section_clues.h +++ b/engines/bladerunner/ui/kia_section_clues.h @@ -45,10 +45,10 @@ class KIASectionClues : public KIASectionBase { int flags; }; - UIContainer *_uiContainer; - UIImagePicker *_buttons; - UIScrollBox *_cluesScrollBox; - UIScrollBox *_filterScrollBox; + UIContainer *_uiContainer; + UIImagePicker *_buttons; + UIScrollBox *_cluesScrollBox; + UIScrollBox *_filterScrollBox; bool _isOpen; bool _debugIntangible; diff --git a/engines/bladerunner/ui/kia_section_load.cpp b/engines/bladerunner/ui/kia_section_load.cpp index ba746cab3b..bbc3c74c68 100644 --- a/engines/bladerunner/ui/kia_section_load.cpp +++ b/engines/bladerunner/ui/kia_section_load.cpp @@ -35,8 +35,6 @@ #include "common/error.h" #include "common/system.h" -#include "engines/savestate.h" - namespace BladeRunner { KIASectionLoad::KIASectionLoad(BladeRunnerEngine *vm) : KIASectionBase(vm) { @@ -56,34 +54,35 @@ void KIASectionLoad::open() { _scrollBox->show(); _scrollBox->clearLines(); - SaveStateList saveList = SaveFileManager::list(_vm->getTargetName()); - - _saveSlotMax = -1; + _saveList = SaveFileManager::list(_vm->getTargetName()); - if (!saveList.empty()) { + if (!_saveList.empty()) { _scrollBox->addLine(_vm->_textOptions->getText(36), -1, 4); // Load game: - for (Common::Array<SaveStateDescriptor>::iterator save = saveList.begin(); save != saveList.end(); save++) { - _scrollBox->addLine(save->getDescription(), save->getSaveSlot(), 0); - _saveSlotMax = MAX(_saveSlotMax, save->getSaveSlot()); + for (uint i = 0; i < _saveList.size(); ++i) { + _scrollBox->addLine(_saveList[i].getDescription(), i, 0); } _scrollBox->addLine("", -1, 4); } + _newGameEasyLineId = _saveList.size(); + _newGameMediumLineId = _saveList.size() + 1; + _newGameHardLineId = _saveList.size() + 2; _scrollBox->addLine(_vm->_textOptions->getText(37), -1, 4); // New game: - _scrollBox->addLine(_vm->_textOptions->getText(20), _saveSlotMax + 1, 0); // Easy - _scrollBox->addLine(_vm->_textOptions->getText(28), _saveSlotMax + 2, 0); // Medium - _scrollBox->addLine(_vm->_textOptions->getText(29), _saveSlotMax + 3, 0); // Hard + _scrollBox->addLine(_vm->_textOptions->getText(20), _newGameEasyLineId, 0); // Easy + _scrollBox->addLine(_vm->_textOptions->getText(28), _newGameMediumLineId, 0); // Medium + _scrollBox->addLine(_vm->_textOptions->getText(29), _newGameHardLineId, 0); // Hard - _hoveredSaveSlot = -1; + _hoveredLineId = -1; _timeLast = _vm->getTotalPlayTime(); _timeLeft = 800; } void KIASectionLoad::close() { _scrollBox->hide(); - _vm->_kia->playerReset(); + + _saveList.clear(); } void KIASectionLoad::draw(Graphics::Surface &surface){ @@ -91,12 +90,12 @@ void KIASectionLoad::draw(Graphics::Surface &surface){ _uiContainer->draw(surface); - int selectedSaveSlot = _scrollBox->getSelectedLineData(); + int selectedLineId = _scrollBox->getSelectedLineData(); - if (_hoveredSaveSlot != selectedSaveSlot) { - if (selectedSaveSlot >= 0) { + if (_hoveredLineId != selectedLineId) { + if (selectedLineId >= 0 && selectedLineId < (int)_saveList.size()) { if (_timeLeft == 0) { - SaveStateDescriptor desc = SaveFileManager::queryMetaInfos(_vm->getTargetName(), selectedSaveSlot); + SaveStateDescriptor desc = SaveFileManager::queryMetaInfos(_vm->getTargetName(), selectedLineId); const Graphics::Surface *thumbnail = desc.getThumbnail(); if (thumbnail != nullptr) { _vm->_kia->playImage(*thumbnail); @@ -106,15 +105,15 @@ void KIASectionLoad::draw(Graphics::Surface &surface){ _vm->_kia->playerReset(); _timeLeft = 800; } - _hoveredSaveSlot = selectedSaveSlot; + _hoveredLineId = selectedLineId; } uint32 now = _vm->getTotalPlayTime(); - if (selectedSaveSlot >= 0) { + if (selectedLineId >= 0 && selectedLineId < (int)_saveList.size()) { if (_timeLeft) { uint32 timeDiff = now - _timeLast; if (timeDiff >= _timeLeft) { - SaveStateDescriptor desc = SaveFileManager::queryMetaInfos(_vm->getTargetName(), selectedSaveSlot); + SaveStateDescriptor desc = SaveFileManager::queryMetaInfos(_vm->getTargetName(), _saveList[selectedLineId].getSaveSlot()); const Graphics::Surface *thumbnail = desc.getThumbnail(); if (thumbnail != nullptr) { _vm->_kia->playImage(*thumbnail); @@ -144,11 +143,11 @@ void KIASectionLoad::scrollBoxCallback(void *callbackData, void *source, int lin KIASectionLoad *self = (KIASectionLoad *)callbackData; if (mouseButton == 0 && source == self->_scrollBox && lineData >= 0) { - if (lineData == self->_saveSlotMax + 1) { + if (lineData == self->_newGameEasyLineId) { self->_vm->newGame(0); - } else if (lineData == self->_saveSlotMax + 2) { + } else if (lineData == self->_newGameMediumLineId) { self->_vm->newGame(1); - } else if (lineData == self->_saveSlotMax + 3) { + } else if (lineData == self->_newGameHardLineId) { self->_vm->newGame(2); } else { self->_vm->loadGameState(lineData); diff --git a/engines/bladerunner/ui/kia_section_load.h b/engines/bladerunner/ui/kia_section_load.h index 040fc090cc..820b39f5e6 100644 --- a/engines/bladerunner/ui/kia_section_load.h +++ b/engines/bladerunner/ui/kia_section_load.h @@ -28,6 +28,8 @@ #include "common/scummsys.h" #include "common/str.h" +#include "engines/savestate.h" + namespace Graphics { struct Surface; } @@ -38,33 +40,31 @@ class UIContainer; class UIScrollBox; class KIASectionLoad : public KIASectionBase { + UIContainer *_uiContainer; + UIScrollBox *_scrollBox; - struct Save { - Common::String name; - int slotNum; - }; - - UIContainer *_uiContainer; - UIScrollBox *_scrollBox; + uint32 _timeLast; + uint32 _timeLeft; - uint32 _timeLast; - uint32 _timeLeft; + SaveStateList _saveList; - int _hoveredSaveSlot; - int _saveSlotMax; + int _hoveredLineId; + int _newGameEasyLineId; + int _newGameMediumLineId; + int _newGameHardLineId; public: KIASectionLoad(BladeRunnerEngine *vm); ~KIASectionLoad(); - void open(); - void close(); + void open() override; + void close() override; - void draw(Graphics::Surface &surface); + void draw(Graphics::Surface &surface) override; - void handleMouseMove(int mouseX, int mouseY); - void handleMouseDown(bool mainButton); - void handleMouseUp(bool mainButton); + void handleMouseMove(int mouseX, int mouseY) override; + void handleMouseDown(bool mainButton) override; + void handleMouseUp(bool mainButton) override; private: static void scrollBoxCallback(void *callbackData, void *source, int lineData, int mouseButton); diff --git a/engines/bladerunner/ui/kia_section_save.cpp b/engines/bladerunner/ui/kia_section_save.cpp new file mode 100644 index 0000000000..997cb75778 --- /dev/null +++ b/engines/bladerunner/ui/kia_section_save.cpp @@ -0,0 +1,407 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "bladerunner/ui/kia_section_save.h" + +#include "bladerunner/audio_player.h" +#include "bladerunner/bladerunner.h" +#include "bladerunner/font.h" +#include "bladerunner/game_info.h" +#include "bladerunner/savefile.h" +#include "bladerunner/text_resource.h" +#include "bladerunner/ui/kia.h" +#include "bladerunner/ui/kia_shapes.h" +#include "bladerunner/ui/ui_container.h" +#include "bladerunner/ui/ui_image_picker.h" +#include "bladerunner/ui/ui_input_box.h" +#include "bladerunner/ui/ui_scroll_box.h" + +#include "common/error.h" +#include "common/keyboard.h" +#include "common/system.h" + +namespace BladeRunner { + +KIASectionSave::KIASectionSave(BladeRunnerEngine *vm) : KIASectionBase(vm) { + _uiContainer = new UIContainer(_vm); + + _scrollBox = new UIScrollBox(_vm, scrollBoxCallback, this, 1024, 0, true, Common::Rect(155, 158, 461, 346), Common::Rect(506, 160, 506, 350)); + _uiContainer->add(_scrollBox); + + _inputBox = new UIInputBox(_vm, inputBoxCallback, this, Common::Rect(155, 367, 461, 376), 41, ""); + _uiContainer->add(_inputBox); + _inputBox->hide(); + + _buttons = new UIImagePicker(_vm, 3); + + _mouseX = 0; + _mouseY = 0; + + _selectedLineId = -1; + _hoveredLineId = -1; + _newSaveLineId = -1; +} + +KIASectionSave::~KIASectionSave() { + delete _buttons; + + _uiContainer->clear(); + delete _inputBox; + delete _scrollBox; + delete _uiContainer; +} + +void KIASectionSave::open() { + _scheduledSwitch = false; + _state = kStateNormal; + + _buttons->resetImages(); + _buttons->defineImage( + 0, + Common::Rect(460, 366, 497, 402), + _vm->_kia->_shapes->get(82), + _vm->_kia->_shapes->get(83), + _vm->_kia->_shapes->get(84), + _vm->_textOptions->getText(22) // Save + ); + + _scrollBox->show(); + + _saveList = SaveFileManager::list(_vm->getTargetName()); + + bool ableToSaveGame = true; + + _newSaveLineId = _saveList.size(); + + if (!_saveList.empty() || ableToSaveGame) { + + _buttons->activate(nullptr, nullptr, nullptr, onButtonPressed, this); + _inputBox->show(); + + _scrollBox->clearLines(); + + if (ableToSaveGame) { + _scrollBox->addLine(_vm->_textOptions->getText(23), _newSaveLineId, 0); + } + + for (uint i = 0; i < _saveList.size(); ++i) { + _scrollBox->addLine(_saveList[i].getDescription(), i, 0); + } + + if (ableToSaveGame) { + // New save + _selectedLineId = _newSaveLineId; + _inputBox->setText(""); + } else { + // Overwrite first save + _selectedLineId = 0; + _inputBox->setText(_saveList[_selectedLineId].getDescription()); + } + + _scrollBox->setFlags(_selectedLineId, 8); + } + + _hoveredLineId = -1; + _timeLast = _vm->getTotalPlayTime(); + _timeLeft = 800; +} + +void KIASectionSave::close() { + _inputBox->hide(); + _scrollBox->hide(); + _buttons->deactivate(); + + _vm->_kia->playerReset(); + + _saveList.clear(); +} + +void KIASectionSave::draw(Graphics::Surface &surface){ + _vm->_kia->_shapes->get(69)->draw(surface, 501, 123); + _buttons->draw(surface); + + if (_state == kStateNormal) { + const char *textChooseSlot = _vm->_textOptions->getText(24); // Choose a slot ... + int textChooseSlotWidth = _vm->_mainFont->getTextWidth(textChooseSlot); + _vm->_mainFont->drawColor(textChooseSlot, surface, 308 - textChooseSlotWidth / 2, 143, 0x7BB8); + + // Original game shows warnings/error here, but we don't have any + + const char *textTypeName = _vm->_textOptions->getText(24); // Type a name ... + int textTypeNameWidth = _vm->_mainFont->getTextWidth(textTypeName); + _vm->_mainFont->drawColor(textTypeName, surface, 308 - textTypeNameWidth / 2, 352, 0x7BB8); + + _uiContainer->draw(surface); + } else if (_state == kStateOverwrite) { + surface.fillRect(Common::Rect(155, 230, 462, 239), 0x28E4); + + const Common::String &saveName = _saveList[_selectedLineId].getDescription(); + int saveNameWidth = _vm->_mainFont->getTextWidth(saveName); + _vm->_mainFont->drawColor(saveName, surface, 308 - saveNameWidth / 2, 230, 0x7751); + + const char *textOverwrite = _vm->_textOptions->getText(35); // Overwrite previously saved game? + int textOverwriteWidth = _vm->_mainFont->getTextWidth(textOverwrite); + _vm->_mainFont->drawColor(textOverwrite, surface, 308 - textOverwriteWidth / 2, 240, 0x7BB8); + } else if (_state == kStateDelete) { + surface.fillRect(Common::Rect(155, 230, 462, 239), 0x28E4); + + const Common::String &saveName = _saveList[_selectedLineId].getDescription(); + int saveNameWidth = _vm->_mainFont->getTextWidth(saveName); // Delete this game? + _vm->_mainFont->drawColor(saveName, surface, 308 - saveNameWidth / 2, 230, 0x7751); + + const char *textDelete = _vm->_textOptions->getText(40); + int textDeleteWidth = _vm->_mainFont->getTextWidth(textDelete); + _vm->_mainFont->drawColor(textDelete, surface, 308 - textDeleteWidth / 2, 240, 0x7BB8); + } + + int selectedLineId = _scrollBox->getSelectedLineData(); + + if (selectedLineId != _hoveredLineId) { + if (selectedLineId >= 0 && selectedLineId < (int)_saveList.size()) { + if (_timeLeft == 0) { + SaveStateDescriptor desc = SaveFileManager::queryMetaInfos(_vm->getTargetName(), selectedLineId); + const Graphics::Surface *thumbnail = desc.getThumbnail(); + if (thumbnail != nullptr) { + _vm->_kia->playImage(*thumbnail); + } + } + } else { + _vm->_kia->playerReset(); + _timeLeft = 800; + } + _hoveredLineId = selectedLineId; + } + + uint32 now = _vm->getTotalPlayTime(); + if (selectedLineId >= 0 && selectedLineId < (int)_saveList.size()) { + if (_timeLeft) { + uint32 timeDiff = now - _timeLast; + if (timeDiff >= _timeLeft) { + SaveStateDescriptor desc = SaveFileManager::queryMetaInfos(_vm->getTargetName(), _saveList[selectedLineId].getSaveSlot()); + const Graphics::Surface *thumbnail = desc.getThumbnail(); + if (thumbnail != nullptr) { + _vm->_kia->playImage(*thumbnail); + } + } else { + _timeLeft -= timeDiff; + } + } + } + + _timeLast = now; + _buttons->drawTooltip(surface, _mouseX, _mouseY); +} + +void KIASectionSave::handleKeyUp(const Common::KeyState &kbd) { + if (_state == kStateNormal) { + _uiContainer->handleKeyUp(kbd); + } else if (_state == kStateOverwrite) { + if (kbd.keycode == Common::KEYCODE_RETURN) { + save(); + changeState(kStateNormal); + } + } else if (_state == kStateDelete) { + if (kbd.keycode == Common::KEYCODE_RETURN) { + deleteSave(); + changeState(kStateNormal); + } + } +} + +void KIASectionSave::handleKeyDown(const Common::KeyState &kbd) { + if (_state == kStateNormal) { + if (kbd.keycode == Common::KEYCODE_DELETE && _selectedLineId != _newSaveLineId) { + changeState(kStateDelete); + } + + _uiContainer->handleKeyDown(kbd); + } +} + +void KIASectionSave::handleMouseMove(int mouseX, int mouseY) { + _mouseX = mouseX; + _mouseY = mouseY; + + _buttons->handleMouseAction(_mouseX, _mouseY, false, false, false); + + if (_state == kStateNormal) { + _uiContainer->handleMouseMove(_mouseX, _mouseY); + } +} + +void KIASectionSave::handleMouseDown(bool mainButton) { + if (mainButton) { + if (_state == kStateNormal) { + _uiContainer->handleMouseDown(false); + } + + _buttons->handleMouseAction(_mouseX, _mouseY, true, false, false); + } +} + +void KIASectionSave::handleMouseUp(bool mainButton) { + if (mainButton) { + _buttons->handleMouseAction(_mouseX, _mouseY, false, true, false); + + if (_state == kStateNormal) { + _uiContainer->handleMouseUp(false); + } + } +} + +void KIASectionSave::scrollBoxCallback(void *callbackData, void *source, int lineData, int mouseButton) { + KIASectionSave *self = (KIASectionSave *)callbackData; + + if (mouseButton == 0 && source == self->_scrollBox && lineData >= 0 && lineData <= (int)self->_saveList.size()) { + self->_scrollBox->resetFlags(self->_selectedLineId, 8); + self->_selectedLineId = lineData; + self->_scrollBox->setFlags(self->_selectedLineId, 8); + + if (self->_selectedLineId == self->_newSaveLineId) { + self->_inputBox->setText(""); + } else { + self->_inputBox->setText(self->_saveList[self->_selectedLineId].getDescription()); + } + + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(131), 40, 0, 0, 50, 0); + self->_vm->_kia->resume(); + } +} + +void KIASectionSave::inputBoxCallback(void *callbackData, void *source) { + KIASectionSave *self = (KIASectionSave *)callbackData; + if (source == self->_inputBox) { + if (self->_selectedLineId == self->_newSaveLineId) { + self->save(); + } else { + self->changeState(kStateOverwrite); + } + } +} + +void KIASectionSave::onButtonPressed(int buttonId, void *callbackData) { + KIASectionSave *self = (KIASectionSave *)callbackData; + + if (buttonId == 0) { + if (self->_selectedLineId == self->_newSaveLineId) + { + self->save(); + } + else + { + self->changeState(kStateOverwrite); + } + } else if (buttonId == 1) { + self->changeState(kStateNormal); + self->_vm->_audioPlayer->playAud(self->_vm->_gameInfo->getSfxTrack(134), 90, -50, -50, 50, 0); + } else if (buttonId == 2) { + if (self->_state == kStateOverwrite) + { + self->save(); + } + else if (self->_state == kStateDelete) + { + self->deleteSave(); + } + } +} + +void KIASectionSave::changeState(State state) { + _state = state; + if (state == kStateNormal) { + _buttons->resetImages(); + _buttons->defineImage( + 0, + Common::Rect(460, 366, 497, 402), + _vm->_kia->_shapes->get(82), + _vm->_kia->_shapes->get(83), + _vm->_kia->_shapes->get(84), + _vm->_textOptions->getText(22) // Save + ); + } else { + _buttons->resetImages(); + _buttons->defineImage( + 1, + Common::Rect(318, 260, 357, 299), + _vm->_kia->_shapes->get(126), + _vm->_kia->_shapes->get(127), + _vm->_kia->_shapes->get(128), + _vm->_textOptions->getText(38) // No + ); + _buttons->defineImage( + 2, + Common::Rect(258, 260, 297, 299), + _vm->_kia->_shapes->get(129), + _vm->_kia->_shapes->get(130), + _vm->_kia->_shapes->get(131), + _vm->_textOptions->getText(39) // Yes + ); + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(135), 90, 0, 0, 50, 0); + } +} + +void KIASectionSave::save() { + int slot = -1; + + if (_selectedLineId < (int)_saveList.size()) { + slot = _saveList[_selectedLineId].getSaveSlot(); + } else { + // Find first available save slot + for (int i = 0; i < (int)_saveList.size(); ++i) { + if (_saveList[i].getSaveSlot() != i) { + slot = i; + break; + } + } + + if (slot == -1) { + slot = _saveList.size(); + } + } + + Common::OutSaveFile *saveFile = BladeRunner::SaveFileManager::openForSaving(_vm->getTargetName(), slot); + if (saveFile == nullptr || saveFile->err()) { + delete saveFile; + } + + BladeRunner::SaveFileHeader header; + header._name = _inputBox->getText(); + + BladeRunner::SaveFileManager::writeHeader(*saveFile, header); + + _vm->saveGame(*saveFile, _vm->_kia->_thumbnail); + + saveFile->finalize(); + + delete saveFile; + + _vm->_audioPlayer->playAud(_vm->_gameInfo->getSfxTrack(513), 90, 0, 0, 50, 0); + + _scheduledSwitch = true; +} +void KIASectionSave::deleteSave() { + BladeRunner::SaveFileManager::remove(_vm->getTargetName(), _saveList[_selectedLineId].getSaveSlot()); + close(); + open(); +} + +} // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/kia_section_save.h b/engines/bladerunner/ui/kia_section_save.h index 5e2f5f26ac..d3af65288e 100644 --- a/engines/bladerunner/ui/kia_section_save.h +++ b/engines/bladerunner/ui/kia_section_save.h @@ -25,13 +25,72 @@ #include "bladerunner/ui/kia_section_base.h" +#include "common/scummsys.h" +#include "common/str.h" + +#include "engines/savestate.h" + +namespace Graphics { +struct Surface; +} + namespace BladeRunner { +class UIContainer; +class UIScrollBox; +class UIInputBox; +class UIImagePicker; + class KIASectionSave : public KIASectionBase { + enum State { + kStateNormal = 0, + kStateOverwrite = 1, + kStateDelete = 2 + }; + + UIContainer *_uiContainer; + UIScrollBox *_scrollBox; + UIInputBox *_inputBox; + UIImagePicker *_buttons; + + uint32 _timeLast; + uint32 _timeLeft; + + SaveStateList _saveList; + + State _state; + + int _mouseX; + int _mouseY; + + int _hoveredLineId; + int _selectedLineId; + int _newSaveLineId; public: - KIASectionSave(BladeRunnerEngine *vm): KIASectionBase(vm){} + KIASectionSave(BladeRunnerEngine *vm); + ~KIASectionSave(); + + void open() override; + void close() override; + + void draw(Graphics::Surface &surface) override; + + void handleKeyUp(const Common::KeyState &kbd) override; + void handleKeyDown(const Common::KeyState &kbd) override; + void handleMouseMove(int mouseX, int mouseY) override; + void handleMouseDown(bool mainButton) override; + void handleMouseUp(bool mainButton) override; + +private: + static void scrollBoxCallback(void *callbackData, void *source, int lineData, int mouseButton); + static void inputBoxCallback(void *callbackData, void *source); + + static void onButtonPressed(int buttonId, void *callbackData); + void changeState(State state); + void save(); + void deleteSave(); }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/ui_component.h b/engines/bladerunner/ui/ui_component.h index c3a8c21b21..aae944d3ad 100644 --- a/engines/bladerunner/ui/ui_component.h +++ b/engines/bladerunner/ui/ui_component.h @@ -54,6 +54,7 @@ public: virtual void handleMouseDown(bool alternateButton) {} virtual void handleMouseUp(bool alternateButton) {} virtual void handleKeyUp(const Common::KeyState &kbd) {} + virtual void handleKeyDown(const Common::KeyState &kbd) {} }; } // End of namespace BladeRunner diff --git a/engines/bladerunner/ui/ui_container.cpp b/engines/bladerunner/ui/ui_container.cpp index e84809d379..34a8cecfb1 100644 --- a/engines/bladerunner/ui/ui_container.cpp +++ b/engines/bladerunner/ui/ui_container.cpp @@ -56,6 +56,12 @@ void UIContainer::handleKeyUp(const Common::KeyState &kbd) { } } +void UIContainer::handleKeyDown(const Common::KeyState &kbd) { + for (Common::Array<UIComponent*>::iterator component = _components.begin(); component != _components.end(); component++) { + (*component)->handleKeyDown(kbd); + } +} + void UIContainer::add(UIComponent *component) { _components.push_back(component); } diff --git a/engines/bladerunner/ui/ui_container.h b/engines/bladerunner/ui/ui_container.h index 8e49d36dda..6d5a20765e 100644 --- a/engines/bladerunner/ui/ui_container.h +++ b/engines/bladerunner/ui/ui_container.h @@ -43,6 +43,7 @@ public: void handleMouseDown(bool alternateButton); void handleMouseUp(bool alternateButton); void handleKeyUp(const Common::KeyState &kbd); + void handleKeyDown(const Common::KeyState &kbd); void add(UIComponent *component); void clear(); diff --git a/engines/bladerunner/ui/ui_input_box.cpp b/engines/bladerunner/ui/ui_input_box.cpp index fb46ec8d34..466238f8d3 100644 --- a/engines/bladerunner/ui/ui_input_box.cpp +++ b/engines/bladerunner/ui/ui_input_box.cpp @@ -40,7 +40,6 @@ UIInputBox::UIInputBox(BladeRunnerEngine *vm, UIComponentCallback *valueChangedC _rect = rect; _maxLength = maxLength; - _length = 0; setText(text); _cursorIsVisible = false; @@ -85,11 +84,9 @@ void UIInputBox::hide() { void UIInputBox::handleKeyUp(const Common::KeyState &kbd) { if (_isVisible) { - if (charIsValid(kbd)) { - _text += kbd.ascii; - } else if (kbd.keycode == Common::KEYCODE_BACKSPACE) { - _text.deleteLastChar(); - } else if (kbd.keycode == Common::KEYCODE_RETURN && !_text.empty()) { + // Check for "Enter" in keyUp instead of in keyDown as keyDown is repeating characters + // and that can screw up UX (which is not great in the original game either). + if (kbd.keycode == Common::KEYCODE_RETURN && !_text.empty()) { if (_valueChangedCallback) { _valueChangedCallback(_callbackData, this); } @@ -97,6 +94,16 @@ void UIInputBox::handleKeyUp(const Common::KeyState &kbd) { } } +void UIInputBox::handleKeyDown(const Common::KeyState &kbd) { + if (_isVisible) { + if (charIsValid(kbd) && _text.size() < _maxLength) { + _text += kbd.ascii; + } else if (kbd.keycode == Common::KEYCODE_BACKSPACE) { + _text.deleteLastChar(); + } + } +} + bool UIInputBox::charIsValid(const Common::KeyState &kbd) { return kbd.ascii >= ' ' && kbd.ascii != '<' diff --git a/engines/bladerunner/ui/ui_input_box.h b/engines/bladerunner/ui/ui_input_box.h index 4dfe0785fc..e3aee9996e 100644 --- a/engines/bladerunner/ui/ui_input_box.h +++ b/engines/bladerunner/ui/ui_input_box.h @@ -37,8 +37,7 @@ class UIInputBox : public UIComponent { bool _isVisible; Common::Rect _rect; - int _maxLength; - int _length; + uint _maxLength; Common::String _text; bool _cursorIsVisible; @@ -48,7 +47,7 @@ class UIInputBox : public UIComponent { public: UIInputBox(BladeRunnerEngine *vm, UIComponentCallback *valueChangedCallback, void *callbackData, Common::Rect rect, int maxLength, const Common::String &text); - void draw(Graphics::Surface &surface); + void draw(Graphics::Surface &surface) override; void setText(const Common::String &text); const Common::String &getText(); @@ -56,7 +55,8 @@ public: void show(); void hide(); - void handleKeyUp(const Common::KeyState &kbd); + void handleKeyUp(const Common::KeyState &kbd) override; + void handleKeyDown(const Common::KeyState &kbd) override; private: bool charIsValid(const Common::KeyState &kbd); |