From 1aa5200bb824119651e19a1809d9c07292da57fe Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 14 Jun 2012 03:33:50 +0200 Subject: GUI: Create an interface for save/load dialogs. --- gui/saveload-dialog.cpp | 380 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 380 insertions(+) create mode 100644 gui/saveload-dialog.cpp (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp new file mode 100644 index 0000000000..b8e64c4d99 --- /dev/null +++ b/gui/saveload-dialog.cpp @@ -0,0 +1,380 @@ +/* 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 "gui/saveload-dialog.h" +#include "common/translation.h" + +#include "gui/message.h" +#include "gui/gui-manager.h" +#include "gui/ThemeEval.h" + +#include "graphics/scaler.h" + +namespace GUI { + +SaveLoadChooserDialog::SaveLoadChooserDialog(const Common::String &dialogName) + : Dialog(dialogName), _metaEngine(0), _delSupport(false), _metaInfoSupport(false), + _thumbnailSupport(false), _saveDateSupport(false), _playTimeSupport(false) { +} + +SaveLoadChooserDialog::SaveLoadChooserDialog(int x, int y, int w, int h) + : Dialog(x, y, w, h), _metaEngine(0), _delSupport(false), _metaInfoSupport(false), + _thumbnailSupport(false), _saveDateSupport(false), _playTimeSupport(false) { +} + +void SaveLoadChooserDialog::open() { + Dialog::open(); + + // So that quitting ScummVM will not cause the dialog result to say a + // savegame was selected. + setResult(-1); +} + +int SaveLoadChooserDialog::run(const Common::String &target, const MetaEngine *metaEngine) { + _metaEngine = metaEngine; + _target = target; + _delSupport = _metaEngine->hasFeature(MetaEngine::kSupportsDeleteSave); + _metaInfoSupport = _metaEngine->hasFeature(MetaEngine::kSavesSupportMetaInfo); + _thumbnailSupport = _metaInfoSupport && _metaEngine->hasFeature(MetaEngine::kSavesSupportThumbnail); + _saveDateSupport = _metaInfoSupport && _metaEngine->hasFeature(MetaEngine::kSavesSupportCreationDate); + _playTimeSupport = _metaInfoSupport && _metaEngine->hasFeature(MetaEngine::kSavesSupportPlayTime); + + return runIntern(); +} + +// SaveLoadChooserSimple implementation + +enum { + kChooseCmd = 'CHOS', + kDelCmd = 'DEL ' +}; + +SaveLoadChooserSimple::SaveLoadChooserSimple(const String &title, const String &buttonLabel, bool saveMode) + : SaveLoadChooserDialog("SaveLoadChooser"), _list(0), _chooseButton(0), _deleteButton(0), _gfxWidget(0) { + _backgroundType = ThemeEngine::kDialogBackgroundSpecial; + + new StaticTextWidget(this, "SaveLoadChooser.Title", title); + + // Add choice list + _list = new GUI::ListWidget(this, "SaveLoadChooser.List"); + _list->setNumberingMode(GUI::kListNumberingZero); + _list->setEditable(saveMode); + + _gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10); + + _date = new StaticTextWidget(this, 0, 0, 10, 10, _("No date saved"), Graphics::kTextAlignCenter); + _time = new StaticTextWidget(this, 0, 0, 10, 10, _("No time saved"), Graphics::kTextAlignCenter); + _playtime = new StaticTextWidget(this, 0, 0, 10, 10, _("No playtime saved"), Graphics::kTextAlignCenter); + + // Buttons + new GUI::ButtonWidget(this, "SaveLoadChooser.Cancel", _("Cancel"), 0, kCloseCmd); + _chooseButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Choose", buttonLabel, 0, kChooseCmd); + _chooseButton->setEnabled(false); + + _deleteButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Delete", _("Delete"), 0, kDelCmd); + _deleteButton->setEnabled(false); + + _delSupport = _metaInfoSupport = _thumbnailSupport = false; + + _container = new GUI::ContainerWidget(this, 0, 0, 10, 10); +// _container->setHints(GUI::THEME_HINT_USE_SHADOW); +} + +int SaveLoadChooserSimple::runIntern() { + if (_gfxWidget) + _gfxWidget->setGfx(0); + + _resultString.clear(); + reflowLayout(); + updateSaveList(); + + return Dialog::runModal(); +} + +const Common::String &SaveLoadChooserSimple::getResultString() const { + int selItem = _list->getSelected(); + return (selItem >= 0) ? _list->getSelectedString() : _resultString; +} + +void SaveLoadChooserSimple::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { + int selItem = _list->getSelected(); + + switch (cmd) { + case GUI::kListItemActivatedCmd: + case GUI::kListItemDoubleClickedCmd: + if (selItem >= 0 && _chooseButton->isEnabled()) { + if (_list->isEditable() || !_list->getSelectedString().empty()) { + _list->endEditMode(); + if (!_saveList.empty()) { + setResult(_saveList[selItem].getSaveSlot()); + _resultString = _list->getSelectedString(); + } + close(); + } + } + break; + case kChooseCmd: + _list->endEditMode(); + if (!_saveList.empty()) { + setResult(_saveList[selItem].getSaveSlot()); + _resultString = _list->getSelectedString(); + } + close(); + break; + case GUI::kListSelectionChangedCmd: + updateSelection(true); + break; + case kDelCmd: + if (selItem >= 0 && _delSupport) { + MessageDialog alert(_("Do you really want to delete this savegame?"), + _("Delete"), _("Cancel")); + if (alert.runModal() == GUI::kMessageOK) { + _metaEngine->removeSaveState(_target.c_str(), _saveList[selItem].getSaveSlot()); + + setResult(-1); + _list->setSelected(-1); + + updateSaveList(); + updateSelection(true); + } + } + break; + case kCloseCmd: + setResult(-1); + default: + SaveLoadChooserDialog::handleCommand(sender, cmd, data); + } +} + +void SaveLoadChooserSimple::reflowLayout() { + if (g_gui.xmlEval()->getVar("Globals.SaveLoadChooser.ExtInfo.Visible") == 1 && _thumbnailSupport) { + int16 x, y; + uint16 w, h; + + if (!g_gui.xmlEval()->getWidgetData("SaveLoadChooser.Thumbnail", x, y, w, h)) + error("Error when loading position data for Save/Load Thumbnails"); + + int thumbW = kThumbnailWidth; + int thumbH = kThumbnailHeight2; + int thumbX = x + (w >> 1) - (thumbW >> 1); + int thumbY = y + kLineHeight; + + int textLines = 0; + if (!_saveDateSupport) + textLines++; + if (!_playTimeSupport) + textLines++; + + _container->resize(x, y, w, h - (kLineHeight * textLines)); + _gfxWidget->resize(thumbX, thumbY, thumbW, thumbH); + + int height = thumbY + thumbH + kLineHeight; + + if (_saveDateSupport) { + _date->resize(thumbX, height, kThumbnailWidth, kLineHeight); + height += kLineHeight; + _time->resize(thumbX, height, kThumbnailWidth, kLineHeight); + height += kLineHeight; + } + + if (_playTimeSupport) + _playtime->resize(thumbX, height, kThumbnailWidth, kLineHeight); + + _container->setVisible(true); + _gfxWidget->setVisible(true); + + _date->setVisible(_saveDateSupport); + _time->setVisible(_saveDateSupport); + + _playtime->setVisible(_playTimeSupport); + + _fillR = 0; + _fillG = 0; + _fillB = 0; + updateSelection(false); + } else { + _container->setVisible(false); + _gfxWidget->setVisible(false); + _date->setVisible(false); + _time->setVisible(false); + _playtime->setVisible(false); + } + + SaveLoadChooserDialog::reflowLayout(); +} + +void SaveLoadChooserSimple::updateSelection(bool redraw) { + int selItem = _list->getSelected(); + + bool isDeletable = _delSupport; + bool isWriteProtected = false; + bool startEditMode = _list->isEditable(); + + _gfxWidget->setGfx(-1, -1, _fillR, _fillG, _fillB); + _date->setLabel(_("No date saved")); + _time->setLabel(_("No time saved")); + _playtime->setLabel(_("No playtime saved")); + + if (selItem >= 0 && _metaInfoSupport) { + SaveStateDescriptor desc = _metaEngine->querySaveMetaInfos(_target.c_str(), _saveList[selItem].getSaveSlot()); + + isDeletable = desc.getDeletableFlag() && _delSupport; + isWriteProtected = desc.getWriteProtectedFlag(); + + // Don't allow the user to change the description of write protected games + if (isWriteProtected) + startEditMode = false; + + if (_thumbnailSupport) { + const Graphics::Surface *thumb = desc.getThumbnail(); + if (thumb) { + _gfxWidget->setGfx(thumb); + _gfxWidget->useAlpha(256); + } + } + + if (_saveDateSupport) { + const Common::String &saveDate = desc.getSaveDate(); + if (!saveDate.empty()) + _date->setLabel(_("Date: ") + saveDate); + + const Common::String &saveTime = desc.getSaveTime(); + if (!saveTime.empty()) + _time->setLabel(_("Time: ") + saveTime); + } + + if (_playTimeSupport) { + const Common::String &playTime = desc.getPlayTime(); + if (!playTime.empty()) + _playtime->setLabel(_("Playtime: ") + playTime); + } + } + + + if (_list->isEditable()) { + // Disable the save button if nothing is selected, or if the selected + // game is write protected + _chooseButton->setEnabled(selItem >= 0 && !isWriteProtected); + + if (startEditMode) { + _list->startEditMode(); + + if (_chooseButton->isEnabled() && _list->getSelectedString() == _("Untitled savestate") && + _list->getSelectionColor() == ThemeEngine::kFontColorAlternate) { + _list->setEditString(""); + _list->setEditColor(ThemeEngine::kFontColorNormal); + } + } + } else { + // Disable the load button if nothing is selected, or if an empty + // list item is selected. + _chooseButton->setEnabled(selItem >= 0 && !_list->getSelectedString().empty()); + } + + // Delete will always be disabled if the engine doesn't support it. + _deleteButton->setEnabled(isDeletable && (selItem >= 0) && (!_list->getSelectedString().empty())); + + if (redraw) { + _gfxWidget->draw(); + _date->draw(); + _time->draw(); + _playtime->draw(); + _chooseButton->draw(); + _deleteButton->draw(); + + draw(); + } +} + +void SaveLoadChooserSimple::close() { + _metaEngine = 0; + _target.clear(); + _saveList.clear(); + _list->setList(StringArray()); + + SaveLoadChooserDialog::close(); +} + +void SaveLoadChooserSimple::updateSaveList() { + _saveList = _metaEngine->listSaves(_target.c_str()); + + int curSlot = 0; + int saveSlot = 0; + StringArray saveNames; + ListWidget::ColorList colors; + for (SaveStateList::const_iterator x = _saveList.begin(); x != _saveList.end(); ++x) { + // Handle gaps in the list of save games + saveSlot = x->getSaveSlot(); + if (curSlot < saveSlot) { + while (curSlot < saveSlot) { + SaveStateDescriptor dummySave(curSlot, ""); + _saveList.insert_at(curSlot, dummySave); + saveNames.push_back(dummySave.getDescription()); + colors.push_back(ThemeEngine::kFontColorNormal); + curSlot++; + } + + // Sync the save list iterator + for (x = _saveList.begin(); x != _saveList.end(); ++x) { + if (x->getSaveSlot() == saveSlot) + break; + } + } + + // Show "Untitled savestate" for empty/whitespace savegame descriptions + Common::String description = x->getDescription(); + Common::String trimmedDescription = description; + trimmedDescription.trim(); + if (trimmedDescription.empty()) { + description = _("Untitled savestate"); + colors.push_back(ThemeEngine::kFontColorAlternate); + } else { + colors.push_back(ThemeEngine::kFontColorNormal); + } + + saveNames.push_back(description); + curSlot++; + } + + // Fill the rest of the save slots with empty saves + + int maximumSaveSlots = _metaEngine->getMaximumSaveSlot(); + +#ifdef __DS__ + // Low memory on the DS means too many save slots are impractical, so limit + // the maximum here. + if (maximumSaveSlots > 99) { + maximumSaveSlots = 99; + } +#endif + + Common::String emptyDesc; + for (int i = curSlot; i <= maximumSaveSlots; i++) { + saveNames.push_back(emptyDesc); + SaveStateDescriptor dummySave(i, ""); + _saveList.push_back(dummySave); + colors.push_back(ThemeEngine::kFontColorNormal); + } + + _list->setList(saveNames, &colors); +} + +} // End of namespace GUI -- cgit v1.2.3 From b4882ce6bdb8f3a0df0085fa43ed3bbaf5cb47e1 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Fri, 15 Jun 2012 22:39:57 +0200 Subject: GUI: Implement a new load chooser, which displays a list of thumbnails. --- gui/saveload-dialog.cpp | 192 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index b8e64c4d99..6740fcad13 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -377,4 +377,196 @@ void SaveLoadChooserSimple::updateSaveList() { _list->setList(saveNames, &colors); } +// LoadChooserThumbnailed implementation + +enum { + kNextCmd = 'NEXT', + kPrevCmd = 'PREV' +}; + +LoadChooserThumbnailed::LoadChooserThumbnailed(const Common::String &title) + : SaveLoadChooserDialog("SaveLoadChooser"), _lines(0), _columns(0), _entriesPerPage(0), + _curPage(0), _buttons() { + _backgroundType = ThemeEngine::kDialogBackgroundSpecial; + + new StaticTextWidget(this, "SaveLoadChooser.Title", title); + + // Buttons + new GUI::ButtonWidget(this, "SaveLoadChooser.Delete", _("Cancel"), 0, kCloseCmd); + _nextButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Choose", _("Next"), 0, kNextCmd); + _nextButton->setEnabled(false); + + _prevButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Cancel", _("Prev"), 0, kPrevCmd); + _prevButton->setEnabled(false); +} + +const Common::String &LoadChooserThumbnailed::getResultString() const { + // FIXME: This chooser is only for loading, thus the result is never used + // anyway. But this is still an ugly hack. + return _target; +} + +void LoadChooserThumbnailed::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { + if (cmd <= _entriesPerPage) { + setResult(_saveList[cmd - 1 + _curPage * _entriesPerPage].getSaveSlot()); + close(); + } + + switch (cmd) { + case kNextCmd: + ++_curPage; + updateSaves(); + draw(); + break; + + case kPrevCmd: + --_curPage; + updateSaves(); + draw(); + break; + + case kCloseCmd: + setResult(-1); + default: + SaveLoadChooserDialog::handleCommand(sender, cmd, data); + } +} + +void LoadChooserThumbnailed::handleMouseWheel(int x, int y, int direction) { + if (direction > 0) { + if (_nextButton->isEnabled()) { + ++_curPage; + updateSaves(); + draw(); + } + } else { + if (_prevButton->isEnabled()) { + --_curPage; + updateSaves(); + draw(); + } + } +} + +void LoadChooserThumbnailed::open() { + SaveLoadChooserDialog::open(); + + _curPage = 0; + updateSaves(); +} + +void LoadChooserThumbnailed::reflowLayout() { + SaveLoadChooserDialog::reflowLayout(); + destroyButtons(); + + const uint16 availableWidth = getWidth() - 20; + uint16 availableHeight; + + int16 x, y; + uint16 w; + g_gui.xmlEval()->getWidgetData("SaveLoadChooser.List", x, y, w, availableHeight); + + const int16 buttonWidth = kThumbnailWidth + 6; + const int16 buttonHeight = kThumbnailHeight2 + 6; + + const int16 containerFrameWidthAdd = 10; + const int16 containerFrameHeightAdd = 0; + const int16 containerWidth = buttonWidth + containerFrameWidthAdd; + const int16 containerHeight = buttonHeight + kLineHeight + containerFrameHeightAdd; + + const int16 defaultSpacingHorizontal = 4; + const int16 defaultSpacingVertical = 4; + const int16 slotAreaWidth = containerWidth + defaultSpacingHorizontal; + const int16 slotAreaHeight = containerHeight + defaultSpacingHorizontal; + + const uint oldEntriesPerPage = _entriesPerPage; + _columns = MAX(1, availableWidth / slotAreaWidth); + _lines = MAX(1, availableHeight / slotAreaHeight); + _entriesPerPage = _columns * _lines; + // Recalculate the page number + if (!_saveList.empty() && oldEntriesPerPage != 0) { + _curPage = (_curPage * oldEntriesPerPage) / _entriesPerPage; + } + + const uint addX = _columns > 1 ? (availableWidth % slotAreaWidth) / (_columns - 1) : 0; + const uint addY = _lines > 1 ? (availableHeight % slotAreaHeight) / (_lines - 1) : 0; + + _buttons.reserve(_lines * _columns); + y += defaultSpacingVertical / 2; + for (uint curLine = 0; curLine < _lines; ++curLine, y += slotAreaHeight + addY) { + for (uint curColumn = 0, curX = x + defaultSpacingHorizontal / 2; curColumn < _columns; ++curColumn, curX += slotAreaWidth + addX) { + ContainerWidget *container = new ContainerWidget(this, curX, y, containerWidth, containerHeight); + container->setVisible(false); + + int dstY = y + containerFrameHeightAdd / 2; + int dstX = curX + containerFrameWidthAdd / 2; + + PicButtonWidget *button = new PicButtonWidget(this, dstX, dstY, buttonWidth, buttonHeight, 0, curLine * _columns + curColumn + 1); + button->setVisible(false); + dstY += buttonHeight; + + StaticTextWidget *description = new StaticTextWidget(this, dstX, dstY, buttonWidth, kLineHeight, Common::String(), Graphics::kTextAlignLeft); + description->setVisible(false); + + _buttons.push_back(SlotButton(container, button, description)); + } + } + + if (!_target.empty()) + updateSaves(); +} + +void LoadChooserThumbnailed::close() { + SaveLoadChooserDialog::close(); + hideButtons(); +} + +int LoadChooserThumbnailed::runIntern() { + return SaveLoadChooserDialog::runModal(); +} + +void LoadChooserThumbnailed::destroyButtons() { + for (ButtonArray::iterator i = _buttons.begin(), end = _buttons.end(); i != end; ++i) { + removeWidget(i->container); + removeWidget(i->button); + removeWidget(i->description); + } + + _buttons.clear(); +} + +void LoadChooserThumbnailed::hideButtons() { + for (ButtonArray::iterator i = _buttons.begin(), end = _buttons.end(); i != end; ++i) { + i->button->setGfx(0); + i->setVisible(false); + } + +} + +void LoadChooserThumbnailed::updateSaves() { + hideButtons(); + + _saveList = _metaEngine->listSaves(_target.c_str()); + + for (uint i = _curPage * _entriesPerPage, curNum = 0; i < _saveList.size() && curNum < _entriesPerPage; ++i, ++curNum) { + const uint saveSlot = _saveList[i].getSaveSlot(); + + SaveStateDescriptor desc = _metaEngine->querySaveMetaInfos(_target.c_str(), saveSlot); + SlotButton &curButton = _buttons[curNum]; + curButton.setVisible(true); + curButton.button->setGfx(desc.getThumbnail()); + curButton.description->setLabel(Common::String::format("%d. %s", saveSlot, desc.getDescription().c_str())); + } + + if (_curPage > 0) + _prevButton->setEnabled(true); + else + _prevButton->setEnabled(false); + + if ((_curPage + 1) * _entriesPerPage < _saveList.size()) + _nextButton->setEnabled(true); + else + _nextButton->setEnabled(false); +} + } // End of namespace GUI -- cgit v1.2.3 From d7db655c5b832691fbaa0d0d175de38f43217dc2 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 20 Jun 2012 03:42:32 +0200 Subject: GUI: Show additional meta data in the thumbnail load chooser via tooltip. --- gui/saveload-dialog.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 6740fcad13..5d9d489fec 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -556,6 +556,33 @@ void LoadChooserThumbnailed::updateSaves() { curButton.setVisible(true); curButton.button->setGfx(desc.getThumbnail()); curButton.description->setLabel(Common::String::format("%d. %s", saveSlot, desc.getDescription().c_str())); + + Common::String tooltip(_("Name: ")); + tooltip += desc.getDescription(); + + if (_saveDateSupport) { + const Common::String &saveDate = desc.getSaveDate(); + if (!saveDate.empty()) { + tooltip += "\n"; + tooltip += _("Date: ") + saveDate; + } + + const Common::String &saveTime = desc.getSaveTime(); + if (!saveTime.empty()) { + tooltip += "\n"; + tooltip += _("Time: ") + saveTime; + } + } + + if (_playTimeSupport) { + const Common::String &playTime = desc.getPlayTime(); + if (!playTime.empty()) { + tooltip += "\n"; + tooltip += _("Playtime: ") + playTime; + } + } + + curButton.button->setTooltip(tooltip); } if (_curPage > 0) -- cgit v1.2.3 From 0b5b58829cbb76a2da1c4de19dd51e30fc2c5a3d Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Fri, 29 Jun 2012 14:57:54 +0200 Subject: GUI: Don't distribute vertical space between buttons in the thumbnail load chooser. --- gui/saveload-dialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 5d9d489fec..8537937c0f 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -489,11 +489,11 @@ void LoadChooserThumbnailed::reflowLayout() { } const uint addX = _columns > 1 ? (availableWidth % slotAreaWidth) / (_columns - 1) : 0; - const uint addY = _lines > 1 ? (availableHeight % slotAreaHeight) / (_lines - 1) : 0; + //const uint addY = _lines > 1 ? (availableHeight % slotAreaHeight) / (_lines - 1) : 0; _buttons.reserve(_lines * _columns); y += defaultSpacingVertical / 2; - for (uint curLine = 0; curLine < _lines; ++curLine, y += slotAreaHeight + addY) { + for (uint curLine = 0; curLine < _lines; ++curLine, y += slotAreaHeight/* + addY*/) { for (uint curColumn = 0, curX = x + defaultSpacingHorizontal / 2; curColumn < _columns; ++curColumn, curX += slotAreaWidth + addX) { ContainerWidget *container = new ContainerWidget(this, curX, y, containerWidth, containerHeight); container->setVisible(false); -- cgit v1.2.3 From 0db0b650e215847005676755363565879c2a7b94 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Fri, 29 Jun 2012 14:58:33 +0200 Subject: GUI: Fix copy&paste error affecting vertical spacing in thumbnail load chooser. --- gui/saveload-dialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 8537937c0f..1d8a9872aa 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -477,7 +477,7 @@ void LoadChooserThumbnailed::reflowLayout() { const int16 defaultSpacingHorizontal = 4; const int16 defaultSpacingVertical = 4; const int16 slotAreaWidth = containerWidth + defaultSpacingHorizontal; - const int16 slotAreaHeight = containerHeight + defaultSpacingHorizontal; + const int16 slotAreaHeight = containerHeight + defaultSpacingVertical; const uint oldEntriesPerPage = _entriesPerPage; _columns = MAX(1, availableWidth / slotAreaWidth); -- cgit v1.2.3 From 7860c5bfc93055f1ebcbf037876cd2abd42818c5 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Fri, 29 Jun 2012 15:00:56 +0200 Subject: GUI: Only update save list when the dialog opens in thumbnail load chooser. --- gui/saveload-dialog.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 1d8a9872aa..25c722eec1 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -452,6 +452,7 @@ void LoadChooserThumbnailed::open() { SaveLoadChooserDialog::open(); _curPage = 0; + _saveList = _metaEngine->listSaves(_target.c_str()); updateSaves(); } @@ -546,8 +547,6 @@ void LoadChooserThumbnailed::hideButtons() { void LoadChooserThumbnailed::updateSaves() { hideButtons(); - _saveList = _metaEngine->listSaves(_target.c_str()); - for (uint i = _curPage * _entriesPerPage, curNum = 0; i < _saveList.size() && curNum < _entriesPerPage; ++i, ++curNum) { const uint saveSlot = _saveList[i].getSaveSlot(); -- cgit v1.2.3 From d3e5763276826d3f469fd93077c2f1ef6ef61314 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Fri, 29 Jun 2012 15:52:56 +0200 Subject: GUI: Allow the user to switch between list and thumbnail based load chooser. --- gui/saveload-dialog.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 6 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 25c722eec1..45bf1c49fc 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -30,14 +30,23 @@ namespace GUI { -SaveLoadChooserDialog::SaveLoadChooserDialog(const Common::String &dialogName) +enum { + kListSwitchCmd = 'LIST', + kGridSwitchCmd = 'GRID' +}; + +SaveLoadChooserDialog::SaveLoadChooserDialog(const Common::String &dialogName, const bool saveMode) : Dialog(dialogName), _metaEngine(0), _delSupport(false), _metaInfoSupport(false), - _thumbnailSupport(false), _saveDateSupport(false), _playTimeSupport(false) { + _thumbnailSupport(false), _saveDateSupport(false), _playTimeSupport(false), _saveMode(saveMode), + _listButton(0), _gridButton(0) { + addChooserButtons(); } -SaveLoadChooserDialog::SaveLoadChooserDialog(int x, int y, int w, int h) +SaveLoadChooserDialog::SaveLoadChooserDialog(int x, int y, int w, int h, const bool saveMode) : Dialog(x, y, w, h), _metaEngine(0), _delSupport(false), _metaInfoSupport(false), - _thumbnailSupport(false), _saveDateSupport(false), _playTimeSupport(false) { + _thumbnailSupport(false), _saveDateSupport(false), _playTimeSupport(false), _saveMode(saveMode), + _listButton(0), _gridButton(0) { + addChooserButtons(); } void SaveLoadChooserDialog::open() { @@ -60,6 +69,63 @@ int SaveLoadChooserDialog::run(const Common::String &target, const MetaEngine *m return runIntern(); } +void SaveLoadChooserDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { + switch (cmd) { + case kListSwitchCmd: + setResult(kSwitchToList); + close(); + break; + + case kGridSwitchCmd: + setResult(kSwitchToGrid); + close(); + break; + + default: + break; + } + + return Dialog::handleCommand(sender, cmd, data); +} + +void SaveLoadChooserDialog::addChooserButtons() { + if (_listButton) { + removeWidget(_listButton); + delete _listButton; + } + + if (_gridButton) { + removeWidget(_gridButton); + delete _gridButton; + } + + _listButton = createSwitchButton("SaveLoadChooser.ListSwitch", "L", _("List view"), ThemeEngine::kImageList, kListSwitchCmd); + _gridButton = createSwitchButton("SaveLoadChooser.GridSwitch", "G", _("Grid view"), ThemeEngine::kImageGrid, kGridSwitchCmd); + if (!_metaInfoSupport || !_thumbnailSupport || _saveMode) + _gridButton->setEnabled(false); +} + +void SaveLoadChooserDialog::reflowLayout() { + addChooserButtons(); + + Dialog::reflowLayout(); +} + +GUI::ButtonWidget *SaveLoadChooserDialog::createSwitchButton(const Common::String &name, const char *desc, const char *tooltip, const char *image, uint32 cmd) { + ButtonWidget *button; + +#ifndef DISABLE_FANCY_THEMES + if (g_gui.xmlEval()->getVar("Globals.ShowChooserPics") == 1 && g_gui.theme()->supportsImages()) { + button = new PicButtonWidget(this, name, tooltip, cmd); + ((PicButtonWidget *)button)->useThemeTransparency(true); + ((PicButtonWidget *)button)->setGfx(g_gui.theme()->getImageSurface(image)); + } else +#endif + button = new ButtonWidget(this, name, desc, tooltip, cmd); + + return button; +} + // SaveLoadChooserSimple implementation enum { @@ -68,7 +134,7 @@ enum { }; SaveLoadChooserSimple::SaveLoadChooserSimple(const String &title, const String &buttonLabel, bool saveMode) - : SaveLoadChooserDialog("SaveLoadChooser"), _list(0), _chooseButton(0), _deleteButton(0), _gfxWidget(0) { + : SaveLoadChooserDialog("SaveLoadChooser", saveMode), _list(0), _chooseButton(0), _deleteButton(0), _gfxWidget(0) { _backgroundType = ThemeEngine::kDialogBackgroundSpecial; new StaticTextWidget(this, "SaveLoadChooser.Title", title); @@ -385,7 +451,7 @@ enum { }; LoadChooserThumbnailed::LoadChooserThumbnailed(const Common::String &title) - : SaveLoadChooserDialog("SaveLoadChooser"), _lines(0), _columns(0), _entriesPerPage(0), + : SaveLoadChooserDialog("SaveLoadChooser", false), _lines(0), _columns(0), _entriesPerPage(0), _curPage(0), _buttons() { _backgroundType = ThemeEngine::kDialogBackgroundSpecial; -- cgit v1.2.3 From 37fd9b7384e8b7eda1a1966ccdab642357078a6b Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Fri, 29 Jun 2012 15:55:46 +0200 Subject: GUI: Fix memory leaks in LoadChooserThumbnailed::destroyButtons. GuiObject::removeWidget only removes the widget from the widget list, but doesn't delete it. Oops. --- gui/saveload-dialog.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 45bf1c49fc..1a6083bf9e 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -595,8 +595,11 @@ int LoadChooserThumbnailed::runIntern() { void LoadChooserThumbnailed::destroyButtons() { for (ButtonArray::iterator i = _buttons.begin(), end = _buttons.end(); i != end; ++i) { removeWidget(i->container); + delete i->container; removeWidget(i->button); + delete i->button; removeWidget(i->description); + delete i->description; } _buttons.clear(); -- cgit v1.2.3 From c1426f783d91976d221c059c37b606411445d438 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Fri, 29 Jun 2012 16:15:46 +0200 Subject: GUI: Use a black rect when no thumbnail is available in the thumbnail load chooser. --- gui/saveload-dialog.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 1a6083bf9e..12b34e49fb 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -622,7 +622,12 @@ void LoadChooserThumbnailed::updateSaves() { SaveStateDescriptor desc = _metaEngine->querySaveMetaInfos(_target.c_str(), saveSlot); SlotButton &curButton = _buttons[curNum]; curButton.setVisible(true); - curButton.button->setGfx(desc.getThumbnail()); + const Graphics::Surface *thumbnail = desc.getThumbnail(); + if (thumbnail) { + curButton.button->setGfx(desc.getThumbnail()); + } else { + curButton.button->setGfx(kThumbnailWidth, kThumbnailHeight2, 0, 0, 0); + } curButton.description->setLabel(Common::String::format("%d. %s", saveSlot, desc.getDescription().c_str())); Common::String tooltip(_("Name: ")); -- cgit v1.2.3 From 10bfb82d3b7ba31b7b8f57560ff55b010dd7de3e Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Fri, 29 Jun 2012 16:16:36 +0200 Subject: GUI: Use a slightly bigger vertical spacing in the thumbnail load chooser. --- gui/saveload-dialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 12b34e49fb..0a94fede51 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -542,7 +542,7 @@ void LoadChooserThumbnailed::reflowLayout() { const int16 containerHeight = buttonHeight + kLineHeight + containerFrameHeightAdd; const int16 defaultSpacingHorizontal = 4; - const int16 defaultSpacingVertical = 4; + const int16 defaultSpacingVertical = 8; const int16 slotAreaWidth = containerWidth + defaultSpacingHorizontal; const int16 slotAreaHeight = containerHeight + defaultSpacingVertical; -- cgit v1.2.3 From 236db5ed87acf603898243734e2c5273c23568cb Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 1 Jul 2012 15:58:42 +0200 Subject: GUI: Automatically switch to list based save/load chooser when changing resolution below 640x400. --- gui/saveload-dialog.cpp | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 0a94fede51..3a778b2fa4 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -21,6 +21,7 @@ #include "gui/saveload-dialog.h" #include "common/translation.h" +#include "common/config-manager.h" #include "gui/message.h" #include "gui/gui-manager.h" @@ -73,11 +74,17 @@ void SaveLoadChooserDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd switch (cmd) { case kListSwitchCmd: setResult(kSwitchToList); + // We save the requested dialog type here to avoid the setting to be + // overwritten when our reflowLayout logic selects a different dialog + // type. + ConfMan.set("gui_saveload_chooser", "list", Common::ConfigManager::kApplicationDomain); close(); break; case kGridSwitchCmd: setResult(kSwitchToGrid); + // See above. + ConfMan.set("gui_saveload_chooser", "grid", Common::ConfigManager::kApplicationDomain); close(); break; @@ -101,13 +108,45 @@ void SaveLoadChooserDialog::addChooserButtons() { _listButton = createSwitchButton("SaveLoadChooser.ListSwitch", "L", _("List view"), ThemeEngine::kImageList, kListSwitchCmd); _gridButton = createSwitchButton("SaveLoadChooser.GridSwitch", "G", _("Grid view"), ThemeEngine::kImageGrid, kGridSwitchCmd); - if (!_metaInfoSupport || !_thumbnailSupport || _saveMode) + if (!_metaInfoSupport || !_thumbnailSupport || _saveMode || !(g_gui.getWidth() >= 640 && g_gui.getHeight() >= 400)) _gridButton->setEnabled(false); } void SaveLoadChooserDialog::reflowLayout() { addChooserButtons(); + const SaveLoadChooserType currentType = getType(); + SaveLoadChooserType requestedType; + + const Common::String &userConfig = ConfMan.get("gui_saveload_chooser", Common::ConfigManager::kApplicationDomain); + if (!_saveMode && g_gui.getWidth() >= 640 && g_gui.getHeight() >= 400 + && _metaEngine->hasFeature(MetaEngine::kSavesSupportMetaInfo) + && _metaEngine->hasFeature(MetaEngine::kSavesSupportThumbnail) + && userConfig.equalsIgnoreCase("grid")) { + // In case we are 640x400 or higher, this dialog is not in save mode, + // the user requested the grid dialog and the engines supports it we + // try to set it up. + requestedType = kSaveLoadDialogGrid; + } else { + // In all other cases we want to use the list dialog. + requestedType = kSaveLoadDialogList; + } + + // Change the dialog type if there is any need for it. + if (requestedType != currentType) { + switch (requestedType) { + case kSaveLoadDialogGrid: + setResult(kSwitchToGrid); + break; + + case kSaveLoadDialogList: + setResult(kSwitchToList); + break; + } + + close(); + } + Dialog::reflowLayout(); } -- cgit v1.2.3 From bd3d5fb8ffed3938c68a723d5c5bfbb6b56fb0ec Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 1 Jul 2012 16:07:48 +0200 Subject: GUI: Clean up save load chooser selection code. --- gui/saveload-dialog.cpp | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 3a778b2fa4..dce09aaec8 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -31,6 +31,22 @@ namespace GUI { +SaveLoadChooserType getRequestedSaveLoadDialog(const bool saveMode, const MetaEngine &metaEngine) { + const Common::String &userConfig = ConfMan.get("gui_saveload_chooser", Common::ConfigManager::kApplicationDomain); + if (!saveMode && g_gui.getWidth() >= 640 && g_gui.getHeight() >= 400 + && metaEngine.hasFeature(MetaEngine::kSavesSupportMetaInfo) + && metaEngine.hasFeature(MetaEngine::kSavesSupportThumbnail) + && userConfig.equalsIgnoreCase("grid")) { + // In case we are 640x400 or higher, this dialog is not in save mode, + // the user requested the grid dialog and the engines supports it we + // try to set it up. + return kSaveLoadDialogGrid; + } else { + // In all other cases we want to use the list dialog. + return kSaveLoadDialogList; + } +} + enum { kListSwitchCmd = 'LIST', kGridSwitchCmd = 'GRID' @@ -73,7 +89,7 @@ int SaveLoadChooserDialog::run(const Common::String &target, const MetaEngine *m void SaveLoadChooserDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { switch (cmd) { case kListSwitchCmd: - setResult(kSwitchToList); + setResult(kSwitchSaveLoadDialog); // We save the requested dialog type here to avoid the setting to be // overwritten when our reflowLayout logic selects a different dialog // type. @@ -82,7 +98,7 @@ void SaveLoadChooserDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd break; case kGridSwitchCmd: - setResult(kSwitchToGrid); + setResult(kSwitchSaveLoadDialog); // See above. ConfMan.set("gui_saveload_chooser", "grid", Common::ConfigManager::kApplicationDomain); close(); @@ -116,34 +132,11 @@ void SaveLoadChooserDialog::reflowLayout() { addChooserButtons(); const SaveLoadChooserType currentType = getType(); - SaveLoadChooserType requestedType; - - const Common::String &userConfig = ConfMan.get("gui_saveload_chooser", Common::ConfigManager::kApplicationDomain); - if (!_saveMode && g_gui.getWidth() >= 640 && g_gui.getHeight() >= 400 - && _metaEngine->hasFeature(MetaEngine::kSavesSupportMetaInfo) - && _metaEngine->hasFeature(MetaEngine::kSavesSupportThumbnail) - && userConfig.equalsIgnoreCase("grid")) { - // In case we are 640x400 or higher, this dialog is not in save mode, - // the user requested the grid dialog and the engines supports it we - // try to set it up. - requestedType = kSaveLoadDialogGrid; - } else { - // In all other cases we want to use the list dialog. - requestedType = kSaveLoadDialogList; - } + const SaveLoadChooserType requestedType = getRequestedSaveLoadDialog(_saveMode, *_metaEngine); // Change the dialog type if there is any need for it. if (requestedType != currentType) { - switch (requestedType) { - case kSaveLoadDialogGrid: - setResult(kSwitchToGrid); - break; - - case kSaveLoadDialogList: - setResult(kSwitchToList); - break; - } - + setResult(kSwitchSaveLoadDialog); close(); } -- cgit v1.2.3 From 3256081b2b1c604b1367ba3b5fc3fea8bd76d842 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 1 Jul 2012 16:47:40 +0200 Subject: GUI: Add page display to grid based load chooser. --- gui/saveload-dialog.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index dce09aaec8..3d542b1dc8 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -496,6 +496,10 @@ LoadChooserThumbnailed::LoadChooserThumbnailed(const Common::String &title) _prevButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Cancel", _("Prev"), 0, kPrevCmd); _prevButton->setEnabled(false); + + // Page display + _pageDisplay = new GUI::StaticTextWidget(this, "SaveLoadChooser.PageDisplay", Common::String()); + _pageDisplay->setAlign(Graphics::kTextAlignRight); } const Common::String &LoadChooserThumbnailed::getResultString() const { @@ -555,6 +559,11 @@ void LoadChooserThumbnailed::open() { } void LoadChooserThumbnailed::reflowLayout() { + removeWidget(_pageDisplay); + if (g_gui.xmlEval()->getVar("Globals.ShowChooserPageDisplay") == 1) { + _pageDisplay->init(); + } + SaveLoadChooserDialog::reflowLayout(); destroyButtons(); @@ -690,6 +699,9 @@ void LoadChooserThumbnailed::updateSaves() { curButton.button->setTooltip(tooltip); } + const uint numPages = _saveList.size() / _entriesPerPage + 1; + _pageDisplay->setLabel(Common::String::format("%u/%u", _curPage + 1, numPages)); + if (_curPage > 0) _prevButton->setEnabled(true); else -- cgit v1.2.3 From 049e61b4459fd6fdbcf29c5d0e29d35755de82e3 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 1 Jul 2012 17:17:04 +0200 Subject: GUI: Fix small memory leak in grid based load chooser. --- gui/saveload-dialog.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 3d542b1dc8..d7fa9c686a 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -502,6 +502,11 @@ LoadChooserThumbnailed::LoadChooserThumbnailed(const Common::String &title) _pageDisplay->setAlign(Graphics::kTextAlignRight); } +LoadChooserThumbnailed::~LoadChooserThumbnailed() { + removeWidget(_pageDisplay); + delete _pageDisplay; +} + const Common::String &LoadChooserThumbnailed::getResultString() const { // FIXME: This chooser is only for loading, thus the result is never used // anyway. But this is still an ugly hack. -- cgit v1.2.3 From e37c0be0d91029284cee1e3ff895de15e59248f8 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 9 Jul 2012 02:17:57 +0200 Subject: GUI: Fix missing button background in grid based chooser. Now the thumbnail button and the descriptions are sub widgets of the container widget. --- gui/saveload-dialog.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index d7fa9c686a..cf97737a1b 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -611,15 +611,13 @@ void LoadChooserThumbnailed::reflowLayout() { ContainerWidget *container = new ContainerWidget(this, curX, y, containerWidth, containerHeight); container->setVisible(false); - int dstY = y + containerFrameHeightAdd / 2; - int dstX = curX + containerFrameWidthAdd / 2; + int dstY = containerFrameHeightAdd / 2; + int dstX = containerFrameWidthAdd / 2; - PicButtonWidget *button = new PicButtonWidget(this, dstX, dstY, buttonWidth, buttonHeight, 0, curLine * _columns + curColumn + 1); - button->setVisible(false); + PicButtonWidget *button = new PicButtonWidget(container, dstX, dstY, buttonWidth, buttonHeight, 0, curLine * _columns + curColumn + 1); dstY += buttonHeight; - StaticTextWidget *description = new StaticTextWidget(this, dstX, dstY, buttonWidth, kLineHeight, Common::String(), Graphics::kTextAlignLeft); - description->setVisible(false); + StaticTextWidget *description = new StaticTextWidget(container, dstX, dstY, buttonWidth, kLineHeight, Common::String(), Graphics::kTextAlignLeft); _buttons.push_back(SlotButton(container, button, description)); } @@ -642,10 +640,6 @@ void LoadChooserThumbnailed::destroyButtons() { for (ButtonArray::iterator i = _buttons.begin(), end = _buttons.end(); i != end; ++i) { removeWidget(i->container); delete i->container; - removeWidget(i->button); - delete i->button; - removeWidget(i->description); - delete i->description; } _buttons.clear(); -- cgit v1.2.3 From 90eb773c5d862d38f3dc834d51c5a57319c61c3f Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Fri, 13 Jul 2012 17:17:58 +0200 Subject: GUI: Implement saving in the grid based save/load chooser. --- gui/saveload-dialog.cpp | 179 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 160 insertions(+), 19 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index cf97737a1b..8f61d038e5 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -26,14 +26,15 @@ #include "gui/message.h" #include "gui/gui-manager.h" #include "gui/ThemeEval.h" +#include "gui/widgets/edittext.h" #include "graphics/scaler.h" namespace GUI { -SaveLoadChooserType getRequestedSaveLoadDialog(const bool saveMode, const MetaEngine &metaEngine) { +SaveLoadChooserType getRequestedSaveLoadDialog(const MetaEngine &metaEngine) { const Common::String &userConfig = ConfMan.get("gui_saveload_chooser", Common::ConfigManager::kApplicationDomain); - if (!saveMode && g_gui.getWidth() >= 640 && g_gui.getHeight() >= 400 + if (g_gui.getWidth() >= 640 && g_gui.getHeight() >= 400 && metaEngine.hasFeature(MetaEngine::kSavesSupportMetaInfo) && metaEngine.hasFeature(MetaEngine::kSavesSupportThumbnail) && userConfig.equalsIgnoreCase("grid")) { @@ -124,7 +125,7 @@ void SaveLoadChooserDialog::addChooserButtons() { _listButton = createSwitchButton("SaveLoadChooser.ListSwitch", "L", _("List view"), ThemeEngine::kImageList, kListSwitchCmd); _gridButton = createSwitchButton("SaveLoadChooser.GridSwitch", "G", _("Grid view"), ThemeEngine::kImageGrid, kGridSwitchCmd); - if (!_metaInfoSupport || !_thumbnailSupport || _saveMode || !(g_gui.getWidth() >= 640 && g_gui.getHeight() >= 400)) + if (!_metaInfoSupport || !_thumbnailSupport || !(g_gui.getWidth() >= 640 && g_gui.getHeight() >= 400)) _gridButton->setEnabled(false); } @@ -132,7 +133,7 @@ void SaveLoadChooserDialog::reflowLayout() { addChooserButtons(); const SaveLoadChooserType currentType = getType(); - const SaveLoadChooserType requestedType = getRequestedSaveLoadDialog(_saveMode, *_metaEngine); + const SaveLoadChooserType requestedType = getRequestedSaveLoadDialog(*_metaEngine); // Change the dialog type if there is any need for it. if (requestedType != currentType) { @@ -479,12 +480,13 @@ void SaveLoadChooserSimple::updateSaveList() { enum { kNextCmd = 'NEXT', - kPrevCmd = 'PREV' + kPrevCmd = 'PREV', + kNewSaveCmd = 'SAVE' }; -LoadChooserThumbnailed::LoadChooserThumbnailed(const Common::String &title) - : SaveLoadChooserDialog("SaveLoadChooser", false), _lines(0), _columns(0), _entriesPerPage(0), - _curPage(0), _buttons() { +LoadChooserThumbnailed::LoadChooserThumbnailed(const Common::String &title, bool saveMode) + : SaveLoadChooserDialog("SaveLoadChooser", saveMode), _lines(0), _columns(0), _entriesPerPage(0), + _curPage(0), _newSaveContainer(0), _nextFreeSaveSlot(0), _buttons() { _backgroundType = ThemeEngine::kDialogBackgroundSpecial; new StaticTextWidget(this, "SaveLoadChooser.Title", title); @@ -508,14 +510,18 @@ LoadChooserThumbnailed::~LoadChooserThumbnailed() { } const Common::String &LoadChooserThumbnailed::getResultString() const { - // FIXME: This chooser is only for loading, thus the result is never used - // anyway. But this is still an ugly hack. - return _target; + return _resultString; } void LoadChooserThumbnailed::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { if (cmd <= _entriesPerPage) { - setResult(_saveList[cmd - 1 + _curPage * _entriesPerPage].getSaveSlot()); + const SaveStateDescriptor &desc = _saveList[cmd - 1 + _curPage * _entriesPerPage]; + + if (_saveMode) { + _resultString = desc.getDescription(); + } + + setResult(desc.getSaveSlot()); close(); } @@ -532,6 +538,11 @@ void LoadChooserThumbnailed::handleCommand(GUI::CommandSender *sender, uint32 cm draw(); break; + case kNewSaveCmd: + setResult(_nextFreeSaveSlot); + close(); + break; + case kCloseCmd: setResult(-1); default: @@ -560,6 +571,30 @@ void LoadChooserThumbnailed::open() { _curPage = 0; _saveList = _metaEngine->listSaves(_target.c_str()); + _resultString.clear(); + + // Determine the next free save slot for save mode + if (_saveMode) { + int lastSlot = -1; + _nextFreeSaveSlot = -1; + for (SaveStateList::const_iterator x = _saveList.begin(); x != _saveList.end(); ++x) { + const int curSlot = x->getSaveSlot(); + + // In case there was a gap found use the slot. + if (lastSlot + 1 < curSlot) { + _nextFreeSaveSlot = lastSlot + 1; + break; + } + + lastSlot = curSlot; + } + + // Use the next available slot otherwise. + if (_nextFreeSaveSlot == -1 && lastSlot + 1 < _metaEngine->getMaximumSaveSlot()) { + _nextFreeSaveSlot = lastSlot + 1; + } + } + updateSaves(); } @@ -596,9 +631,20 @@ void LoadChooserThumbnailed::reflowLayout() { _columns = MAX(1, availableWidth / slotAreaWidth); _lines = MAX(1, availableHeight / slotAreaHeight); _entriesPerPage = _columns * _lines; + + // In save mode the first button is always "New Save", thus we need to + // adjust the entries per page here. + if (_saveMode) { + --_entriesPerPage; + } + // Recalculate the page number if (!_saveList.empty() && oldEntriesPerPage != 0) { - _curPage = (_curPage * oldEntriesPerPage) / _entriesPerPage; + if (_entriesPerPage != 0) { + _curPage = (_curPage * oldEntriesPerPage) / _entriesPerPage; + } else { + _curPage = 0; + } } const uint addX = _columns > 1 ? (availableWidth % slotAreaWidth) / (_columns - 1) : 0; @@ -608,13 +654,32 @@ void LoadChooserThumbnailed::reflowLayout() { y += defaultSpacingVertical / 2; for (uint curLine = 0; curLine < _lines; ++curLine, y += slotAreaHeight/* + addY*/) { for (uint curColumn = 0, curX = x + defaultSpacingHorizontal / 2; curColumn < _columns; ++curColumn, curX += slotAreaWidth + addX) { - ContainerWidget *container = new ContainerWidget(this, curX, y, containerWidth, containerHeight); - container->setVisible(false); - int dstY = containerFrameHeightAdd / 2; int dstX = containerFrameWidthAdd / 2; - PicButtonWidget *button = new PicButtonWidget(container, dstX, dstY, buttonWidth, buttonHeight, 0, curLine * _columns + curColumn + 1); + // In the save mode we will always create a new save button as the first button. + if (_saveMode && curLine == 0 && curColumn == 0) { + _newSaveContainer = new ContainerWidget(this, curX, y, containerWidth, containerHeight); + ButtonWidget *newSave = new ButtonWidget(_newSaveContainer, dstX, dstY, buttonWidth, buttonHeight, _("New Save"), _("Create a new save game"), kNewSaveCmd); + // In case no more slots are free, we will disable the new save button + if (_nextFreeSaveSlot == -1) { + newSave->setEnabled(false); + } + continue; + } + + ContainerWidget *container = new ContainerWidget(this, curX, y, containerWidth, containerHeight); + container->setVisible(false); + + // Command 0 cannot be used, since it won't be send. Thus we will adjust + // command number here, if required. This is only the case for load mode + // since for save mode, the first button used is index 1 anyway. + uint buttonCmd = curLine * _columns + curColumn; + if (!_saveMode) { + buttonCmd += 1; + } + + PicButtonWidget *button = new PicButtonWidget(container, dstX, dstY, buttonWidth, buttonHeight, 0, buttonCmd); dstY += buttonHeight; StaticTextWidget *description = new StaticTextWidget(container, dstX, dstY, buttonWidth, kLineHeight, Common::String(), Graphics::kTextAlignLeft); @@ -633,10 +698,41 @@ void LoadChooserThumbnailed::close() { } int LoadChooserThumbnailed::runIntern() { - return SaveLoadChooserDialog::runModal(); + int slot; + do { + const SaveLoadChooserType currentType = getType(); + const SaveLoadChooserType requestedType = getRequestedSaveLoadDialog(*_metaEngine); + + // Catch resolution changes when the save name dialog was open. + if (currentType != requestedType) { + setResult(kSwitchSaveLoadDialog); + return kSwitchSaveLoadDialog; + } + + slot = runModal(); + } while (_saveMode && slot >= 0 && !selectDescription()); + + return slot; +} + +bool LoadChooserThumbnailed::selectDescription() { + _savenameDialog.setDescription(_resultString); + _savenameDialog.setTargetSlot(getResult()); + if (_savenameDialog.runModal() == 0) { + _resultString = _savenameDialog.getDescription(); + return true; + } else { + return false; + } } void LoadChooserThumbnailed::destroyButtons() { + if (_newSaveContainer) { + removeWidget(_newSaveContainer); + delete _newSaveContainer; + _newSaveContainer = 0; + } + for (ButtonArray::iterator i = _buttons.begin(), end = _buttons.end(); i != end; ++i) { removeWidget(i->container); delete i->container; @@ -696,9 +792,17 @@ void LoadChooserThumbnailed::updateSaves() { } curButton.button->setTooltip(tooltip); + + // In save mode we disable the button, when it's write protected. + // TODO: Maybe we should not display it at all then? + if (_saveMode && desc.getWriteProtectedFlag()) { + curButton.button->setEnabled(false); + } else { + curButton.button->setEnabled(true); + } } - const uint numPages = _saveList.size() / _entriesPerPage + 1; + const uint numPages = (_entriesPerPage != 0) ? (_saveList.size() / _entriesPerPage + 1) : 1; _pageDisplay->setLabel(Common::String::format("%u/%u", _curPage + 1, numPages)); if (_curPage > 0) @@ -712,4 +816,41 @@ void LoadChooserThumbnailed::updateSaves() { _nextButton->setEnabled(false); } +SavenameDialog::SavenameDialog() + : Dialog("SavenameDialog") { + _title = new StaticTextWidget(this, "SavenameDialog.DescriptionText", Common::String()); + + new ButtonWidget(this, "SavenameDialog.Cancel", _("Cancel"), 0, kCloseCmd); + new ButtonWidget(this, "SavenameDialog.Ok", _("Ok"), 0, kOKCmd); + + _description = new EditTextWidget(this, "SavenameDialog.Description", Common::String(), 0, 0, kOKCmd); +} + +void SavenameDialog::setDescription(const Common::String &desc) { + _description->setEditString(desc); +} + +const Common::String &SavenameDialog::getDescription() { + return _description->getEditString(); +} + +void SavenameDialog::open() { + Dialog::open(); + setResult(-1); + + _title->setLabel(Common::String::format(_("Enter a description for slot %d:"), _targetSlot)); +} + +void SavenameDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { + switch (cmd) { + case kOKCmd: + setResult(0); + close(); + break; + + default: + Dialog::handleCommand(sender, cmd, data); + } +} + } // End of namespace GUI -- cgit v1.2.3 From 89b638128ff0482a01cfd3d058d87aa95faf58c3 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Tue, 24 Jul 2012 23:24:17 +0200 Subject: GUI: Rename LoadChooserThumbnailed to SaveLoadChooserGrid. --- gui/saveload-dialog.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 8f61d038e5..2ceace2c8a 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -476,7 +476,7 @@ void SaveLoadChooserSimple::updateSaveList() { _list->setList(saveNames, &colors); } -// LoadChooserThumbnailed implementation +// SaveLoadChooserGrid implementation enum { kNextCmd = 'NEXT', @@ -484,7 +484,7 @@ enum { kNewSaveCmd = 'SAVE' }; -LoadChooserThumbnailed::LoadChooserThumbnailed(const Common::String &title, bool saveMode) +SaveLoadChooserGrid::SaveLoadChooserGrid(const Common::String &title, bool saveMode) : SaveLoadChooserDialog("SaveLoadChooser", saveMode), _lines(0), _columns(0), _entriesPerPage(0), _curPage(0), _newSaveContainer(0), _nextFreeSaveSlot(0), _buttons() { _backgroundType = ThemeEngine::kDialogBackgroundSpecial; @@ -504,16 +504,16 @@ LoadChooserThumbnailed::LoadChooserThumbnailed(const Common::String &title, bool _pageDisplay->setAlign(Graphics::kTextAlignRight); } -LoadChooserThumbnailed::~LoadChooserThumbnailed() { +SaveLoadChooserGrid::~SaveLoadChooserGrid() { removeWidget(_pageDisplay); delete _pageDisplay; } -const Common::String &LoadChooserThumbnailed::getResultString() const { +const Common::String &SaveLoadChooserGrid::getResultString() const { return _resultString; } -void LoadChooserThumbnailed::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { +void SaveLoadChooserGrid::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { if (cmd <= _entriesPerPage) { const SaveStateDescriptor &desc = _saveList[cmd - 1 + _curPage * _entriesPerPage]; @@ -550,7 +550,7 @@ void LoadChooserThumbnailed::handleCommand(GUI::CommandSender *sender, uint32 cm } } -void LoadChooserThumbnailed::handleMouseWheel(int x, int y, int direction) { +void SaveLoadChooserGrid::handleMouseWheel(int x, int y, int direction) { if (direction > 0) { if (_nextButton->isEnabled()) { ++_curPage; @@ -566,7 +566,7 @@ void LoadChooserThumbnailed::handleMouseWheel(int x, int y, int direction) { } } -void LoadChooserThumbnailed::open() { +void SaveLoadChooserGrid::open() { SaveLoadChooserDialog::open(); _curPage = 0; @@ -598,7 +598,7 @@ void LoadChooserThumbnailed::open() { updateSaves(); } -void LoadChooserThumbnailed::reflowLayout() { +void SaveLoadChooserGrid::reflowLayout() { removeWidget(_pageDisplay); if (g_gui.xmlEval()->getVar("Globals.ShowChooserPageDisplay") == 1) { _pageDisplay->init(); @@ -692,12 +692,12 @@ void LoadChooserThumbnailed::reflowLayout() { updateSaves(); } -void LoadChooserThumbnailed::close() { +void SaveLoadChooserGrid::close() { SaveLoadChooserDialog::close(); hideButtons(); } -int LoadChooserThumbnailed::runIntern() { +int SaveLoadChooserGrid::runIntern() { int slot; do { const SaveLoadChooserType currentType = getType(); @@ -715,7 +715,7 @@ int LoadChooserThumbnailed::runIntern() { return slot; } -bool LoadChooserThumbnailed::selectDescription() { +bool SaveLoadChooserGrid::selectDescription() { _savenameDialog.setDescription(_resultString); _savenameDialog.setTargetSlot(getResult()); if (_savenameDialog.runModal() == 0) { @@ -726,7 +726,7 @@ bool LoadChooserThumbnailed::selectDescription() { } } -void LoadChooserThumbnailed::destroyButtons() { +void SaveLoadChooserGrid::destroyButtons() { if (_newSaveContainer) { removeWidget(_newSaveContainer); delete _newSaveContainer; @@ -741,7 +741,7 @@ void LoadChooserThumbnailed::destroyButtons() { _buttons.clear(); } -void LoadChooserThumbnailed::hideButtons() { +void SaveLoadChooserGrid::hideButtons() { for (ButtonArray::iterator i = _buttons.begin(), end = _buttons.end(); i != end; ++i) { i->button->setGfx(0); i->setVisible(false); @@ -749,7 +749,7 @@ void LoadChooserThumbnailed::hideButtons() { } -void LoadChooserThumbnailed::updateSaves() { +void SaveLoadChooserGrid::updateSaves() { hideButtons(); for (uint i = _curPage * _entriesPerPage, curNum = 0; i < _saveList.size() && curNum < _entriesPerPage; ++i, ++curNum) { -- cgit v1.2.3 From 91196e53750f328b30703ffd09cbf3f5e877dc8e Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Tue, 24 Jul 2012 23:25:10 +0200 Subject: GUI: Also disable the switch-to-list button in the choosers, when the grid one isn't available. --- gui/saveload-dialog.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 2ceace2c8a..159e9617ad 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -125,8 +125,10 @@ void SaveLoadChooserDialog::addChooserButtons() { _listButton = createSwitchButton("SaveLoadChooser.ListSwitch", "L", _("List view"), ThemeEngine::kImageList, kListSwitchCmd); _gridButton = createSwitchButton("SaveLoadChooser.GridSwitch", "G", _("Grid view"), ThemeEngine::kImageGrid, kGridSwitchCmd); - if (!_metaInfoSupport || !_thumbnailSupport || !(g_gui.getWidth() >= 640 && g_gui.getHeight() >= 400)) + if (!_metaInfoSupport || !_thumbnailSupport || !(g_gui.getWidth() >= 640 && g_gui.getHeight() >= 400)) { _gridButton->setEnabled(false); + _listButton->setEnabled(false); + } } void SaveLoadChooserDialog::reflowLayout() { -- cgit v1.2.3 From 8e791896b80009dc779770d8761abc89755fee93 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Tue, 24 Jul 2012 23:26:47 +0200 Subject: GUI: Remove an unnecessary empty line. --- gui/saveload-dialog.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 159e9617ad..f81fdc210c 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -748,7 +748,6 @@ void SaveLoadChooserGrid::hideButtons() { i->button->setGfx(0); i->setVisible(false); } - } void SaveLoadChooserGrid::updateSaves() { -- cgit v1.2.3 From bab992ab98dba252e6106161502ec2b945540ea1 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Tue, 24 Jul 2012 23:27:59 +0200 Subject: GUI: Remove unecessary explicit GUI namespace uses. --- gui/saveload-dialog.cpp | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index f81fdc210c..9f7664b809 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -87,7 +87,7 @@ int SaveLoadChooserDialog::run(const Common::String &target, const MetaEngine *m return runIntern(); } -void SaveLoadChooserDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { +void SaveLoadChooserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { switch (cmd) { case kListSwitchCmd: setResult(kSwitchSaveLoadDialog); @@ -146,7 +146,7 @@ void SaveLoadChooserDialog::reflowLayout() { Dialog::reflowLayout(); } -GUI::ButtonWidget *SaveLoadChooserDialog::createSwitchButton(const Common::String &name, const char *desc, const char *tooltip, const char *image, uint32 cmd) { +ButtonWidget *SaveLoadChooserDialog::createSwitchButton(const Common::String &name, const char *desc, const char *tooltip, const char *image, uint32 cmd) { ButtonWidget *button; #ifndef DISABLE_FANCY_THEMES @@ -175,28 +175,28 @@ SaveLoadChooserSimple::SaveLoadChooserSimple(const String &title, const String & new StaticTextWidget(this, "SaveLoadChooser.Title", title); // Add choice list - _list = new GUI::ListWidget(this, "SaveLoadChooser.List"); - _list->setNumberingMode(GUI::kListNumberingZero); + _list = new ListWidget(this, "SaveLoadChooser.List"); + _list->setNumberingMode(kListNumberingZero); _list->setEditable(saveMode); - _gfxWidget = new GUI::GraphicsWidget(this, 0, 0, 10, 10); + _gfxWidget = new GraphicsWidget(this, 0, 0, 10, 10); _date = new StaticTextWidget(this, 0, 0, 10, 10, _("No date saved"), Graphics::kTextAlignCenter); _time = new StaticTextWidget(this, 0, 0, 10, 10, _("No time saved"), Graphics::kTextAlignCenter); _playtime = new StaticTextWidget(this, 0, 0, 10, 10, _("No playtime saved"), Graphics::kTextAlignCenter); // Buttons - new GUI::ButtonWidget(this, "SaveLoadChooser.Cancel", _("Cancel"), 0, kCloseCmd); - _chooseButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Choose", buttonLabel, 0, kChooseCmd); + new ButtonWidget(this, "SaveLoadChooser.Cancel", _("Cancel"), 0, kCloseCmd); + _chooseButton = new ButtonWidget(this, "SaveLoadChooser.Choose", buttonLabel, 0, kChooseCmd); _chooseButton->setEnabled(false); - _deleteButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Delete", _("Delete"), 0, kDelCmd); + _deleteButton = new ButtonWidget(this, "SaveLoadChooser.Delete", _("Delete"), 0, kDelCmd); _deleteButton->setEnabled(false); _delSupport = _metaInfoSupport = _thumbnailSupport = false; - _container = new GUI::ContainerWidget(this, 0, 0, 10, 10); -// _container->setHints(GUI::THEME_HINT_USE_SHADOW); + _container = new ContainerWidget(this, 0, 0, 10, 10); +// _container->setHints(THEME_HINT_USE_SHADOW); } int SaveLoadChooserSimple::runIntern() { @@ -219,8 +219,8 @@ void SaveLoadChooserSimple::handleCommand(CommandSender *sender, uint32 cmd, uin int selItem = _list->getSelected(); switch (cmd) { - case GUI::kListItemActivatedCmd: - case GUI::kListItemDoubleClickedCmd: + case kListItemActivatedCmd: + case kListItemDoubleClickedCmd: if (selItem >= 0 && _chooseButton->isEnabled()) { if (_list->isEditable() || !_list->getSelectedString().empty()) { _list->endEditMode(); @@ -240,14 +240,14 @@ void SaveLoadChooserSimple::handleCommand(CommandSender *sender, uint32 cmd, uin } close(); break; - case GUI::kListSelectionChangedCmd: + case kListSelectionChangedCmd: updateSelection(true); break; case kDelCmd: if (selItem >= 0 && _delSupport) { MessageDialog alert(_("Do you really want to delete this savegame?"), _("Delete"), _("Cancel")); - if (alert.runModal() == GUI::kMessageOK) { + if (alert.runModal() == kMessageOK) { _metaEngine->removeSaveState(_target.c_str(), _saveList[selItem].getSaveSlot()); setResult(-1); @@ -494,15 +494,15 @@ SaveLoadChooserGrid::SaveLoadChooserGrid(const Common::String &title, bool saveM new StaticTextWidget(this, "SaveLoadChooser.Title", title); // Buttons - new GUI::ButtonWidget(this, "SaveLoadChooser.Delete", _("Cancel"), 0, kCloseCmd); - _nextButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Choose", _("Next"), 0, kNextCmd); + new ButtonWidget(this, "SaveLoadChooser.Delete", _("Cancel"), 0, kCloseCmd); + _nextButton = new ButtonWidget(this, "SaveLoadChooser.Choose", _("Next"), 0, kNextCmd); _nextButton->setEnabled(false); - _prevButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Cancel", _("Prev"), 0, kPrevCmd); + _prevButton = new ButtonWidget(this, "SaveLoadChooser.Cancel", _("Prev"), 0, kPrevCmd); _prevButton->setEnabled(false); // Page display - _pageDisplay = new GUI::StaticTextWidget(this, "SaveLoadChooser.PageDisplay", Common::String()); + _pageDisplay = new StaticTextWidget(this, "SaveLoadChooser.PageDisplay", Common::String()); _pageDisplay->setAlign(Graphics::kTextAlignRight); } @@ -515,7 +515,7 @@ const Common::String &SaveLoadChooserGrid::getResultString() const { return _resultString; } -void SaveLoadChooserGrid::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { +void SaveLoadChooserGrid::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { if (cmd <= _entriesPerPage) { const SaveStateDescriptor &desc = _saveList[cmd - 1 + _curPage * _entriesPerPage]; @@ -842,7 +842,7 @@ void SavenameDialog::open() { _title->setLabel(Common::String::format(_("Enter a description for slot %d:"), _targetSlot)); } -void SavenameDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { +void SavenameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { switch (cmd) { case kOKCmd: setResult(0); -- cgit v1.2.3 From ca225cc7e0affd4bca287def475e34dabe251d8a Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Tue, 24 Jul 2012 23:34:35 +0200 Subject: GUI: Strip a trailing whitespace. --- gui/saveload-dialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 9f7664b809..f59d67e490 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -604,7 +604,7 @@ void SaveLoadChooserGrid::reflowLayout() { removeWidget(_pageDisplay); if (g_gui.xmlEval()->getVar("Globals.ShowChooserPageDisplay") == 1) { _pageDisplay->init(); - } + } SaveLoadChooserDialog::reflowLayout(); destroyButtons(); -- cgit v1.2.3 From 7d519074053ab0482c1d163a626a9554b52a8783 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Tue, 24 Jul 2012 23:46:54 +0200 Subject: GUI: Add possibility to disable the grid based chooser via DISABLE_SAVELOADCHOOSER_GRID. --- gui/saveload-dialog.cpp | 60 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 19 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index f59d67e490..3c793c9e25 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -32,6 +32,7 @@ namespace GUI { +#ifndef DISABLE_SAVELOADCHOOSER_GRID SaveLoadChooserType getRequestedSaveLoadDialog(const MetaEngine &metaEngine) { const Common::String &userConfig = ConfMan.get("gui_saveload_chooser", Common::ConfigManager::kApplicationDomain); if (g_gui.getWidth() >= 640 && g_gui.getHeight() >= 400 @@ -52,19 +53,30 @@ enum { kListSwitchCmd = 'LIST', kGridSwitchCmd = 'GRID' }; +#endif // !DISABLE_SAVELOADCHOOSER_GRID SaveLoadChooserDialog::SaveLoadChooserDialog(const Common::String &dialogName, const bool saveMode) : Dialog(dialogName), _metaEngine(0), _delSupport(false), _metaInfoSupport(false), - _thumbnailSupport(false), _saveDateSupport(false), _playTimeSupport(false), _saveMode(saveMode), - _listButton(0), _gridButton(0) { + _thumbnailSupport(false), _saveDateSupport(false), _playTimeSupport(false), _saveMode(saveMode) +#ifndef DISABLE_SAVELOADCHOOSER_GRID + , _listButton(0), _gridButton(0) +#endif // !DISABLE_SAVELOADCHOOSER_GRID + { +#ifndef DISABLE_SAVELOADCHOOSER_GRID addChooserButtons(); +#endif // !DISABLE_SAVELOADCHOOSER_GRID } SaveLoadChooserDialog::SaveLoadChooserDialog(int x, int y, int w, int h, const bool saveMode) : Dialog(x, y, w, h), _metaEngine(0), _delSupport(false), _metaInfoSupport(false), - _thumbnailSupport(false), _saveDateSupport(false), _playTimeSupport(false), _saveMode(saveMode), - _listButton(0), _gridButton(0) { + _thumbnailSupport(false), _saveDateSupport(false), _playTimeSupport(false), _saveMode(saveMode) +#ifndef DISABLE_SAVELOADCHOOSER_GRID + , _listButton(0), _gridButton(0) +#endif // !DISABLE_SAVELOADCHOOSER_GRID + { +#ifndef DISABLE_SAVELOADCHOOSER_GRID addChooserButtons(); +#endif // !DISABLE_SAVELOADCHOOSER_GRID } void SaveLoadChooserDialog::open() { @@ -88,6 +100,7 @@ int SaveLoadChooserDialog::run(const Common::String &target, const MetaEngine *m } void SaveLoadChooserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { +#ifndef DISABLE_SAVELOADCHOOSER_GRID switch (cmd) { case kListSwitchCmd: setResult(kSwitchSaveLoadDialog); @@ -108,10 +121,29 @@ void SaveLoadChooserDialog::handleCommand(CommandSender *sender, uint32 cmd, uin default: break; } +#endif // !DISABLE_SAVELOADCHOOSER_GRID return Dialog::handleCommand(sender, cmd, data); } +void SaveLoadChooserDialog::reflowLayout() { +#ifndef DISABLE_SAVELOADCHOOSER_GRID + addChooserButtons(); + + const SaveLoadChooserType currentType = getType(); + const SaveLoadChooserType requestedType = getRequestedSaveLoadDialog(*_metaEngine); + + // Change the dialog type if there is any need for it. + if (requestedType != currentType) { + setResult(kSwitchSaveLoadDialog); + close(); + } +#endif // !DISABLE_SAVELOADCHOOSER_GRID + + Dialog::reflowLayout(); +} + +#ifndef DISABLE_SAVELOADCHOOSER_GRID void SaveLoadChooserDialog::addChooserButtons() { if (_listButton) { removeWidget(_listButton); @@ -131,21 +163,6 @@ void SaveLoadChooserDialog::addChooserButtons() { } } -void SaveLoadChooserDialog::reflowLayout() { - addChooserButtons(); - - const SaveLoadChooserType currentType = getType(); - const SaveLoadChooserType requestedType = getRequestedSaveLoadDialog(*_metaEngine); - - // Change the dialog type if there is any need for it. - if (requestedType != currentType) { - setResult(kSwitchSaveLoadDialog); - close(); - } - - Dialog::reflowLayout(); -} - ButtonWidget *SaveLoadChooserDialog::createSwitchButton(const Common::String &name, const char *desc, const char *tooltip, const char *image, uint32 cmd) { ButtonWidget *button; @@ -160,6 +177,7 @@ ButtonWidget *SaveLoadChooserDialog::createSwitchButton(const Common::String &na return button; } +#endif // !DISABLE_SAVELOADCHOOSER_GRID // SaveLoadChooserSimple implementation @@ -480,6 +498,8 @@ void SaveLoadChooserSimple::updateSaveList() { // SaveLoadChooserGrid implementation +#ifndef DISABLE_SAVELOADCHOOSER_GRID + enum { kNextCmd = 'NEXT', kPrevCmd = 'PREV', @@ -854,4 +874,6 @@ void SavenameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat } } +#endif // !DISABLE_SAVELOADCHOOSER_GRID + } // End of namespace GUI -- cgit v1.2.3 From 71daae7bbc03c1d9327f5353b1450f9d0d9774da Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 25 Jul 2012 17:21:36 +0200 Subject: GUI: Use "OK" instead of "Ok" in SavenameDialog. --- gui/saveload-dialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 3c793c9e25..c714147488 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -842,7 +842,7 @@ SavenameDialog::SavenameDialog() _title = new StaticTextWidget(this, "SavenameDialog.DescriptionText", Common::String()); new ButtonWidget(this, "SavenameDialog.Cancel", _("Cancel"), 0, kCloseCmd); - new ButtonWidget(this, "SavenameDialog.Ok", _("Ok"), 0, kOKCmd); + new ButtonWidget(this, "SavenameDialog.Ok", _("OK"), 0, kOKCmd); _description = new EditTextWidget(this, "SavenameDialog.Description", Common::String(), 0, 0, kOKCmd); } -- cgit v1.2.3 From e7cd238809520c9f3ee7ee820b3a106b7f72c2e2 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 12 Aug 2012 14:56:20 +0200 Subject: GUI: Remove left-over code from theme based fill color in thumbnail display. --- gui/saveload-dialog.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 0b36ff5d59..8e214bce90 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -188,8 +188,6 @@ enum { SaveLoadChooserSimple::SaveLoadChooserSimple(const String &title, const String &buttonLabel, bool saveMode) : SaveLoadChooserDialog("SaveLoadChooser", saveMode), _list(0), _chooseButton(0), _deleteButton(0), _gfxWidget(0) { - _fillR = _fillG = _fillB = 0; - _backgroundType = ThemeEngine::kDialogBackgroundSpecial; new StaticTextWidget(this, "SaveLoadChooser.Title", title); @@ -327,9 +325,6 @@ void SaveLoadChooserSimple::reflowLayout() { _playtime->setVisible(_playTimeSupport); - _fillR = 0; - _fillG = 0; - _fillB = 0; updateSelection(false); } else { _container->setVisible(false); @@ -349,7 +344,9 @@ void SaveLoadChooserSimple::updateSelection(bool redraw) { bool isWriteProtected = false; bool startEditMode = _list->isEditable(); - _gfxWidget->setGfx(-1, -1, _fillR, _fillG, _fillB); + // We used to support letting the themes specify the fill color with our + // initial theme based GUI. But this support was dropped. + _gfxWidget->setGfx(-1, -1, 0, 0, 0); _date->setLabel(_("No date saved")); _time->setLabel(_("No time saved")); _playtime->setLabel(_("No playtime saved")); -- cgit v1.2.3 From 9ba145419faa46b85baf5982f0c62ab76268b0af Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 12 Aug 2012 15:16:27 +0200 Subject: GUI: Mark parts of the grid based chooser layout code as HACK. --- gui/saveload-dialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 8e214bce90..d1a66dc28a 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -620,6 +620,8 @@ void SaveLoadChooserGrid::open() { } void SaveLoadChooserGrid::reflowLayout() { + // HACK: The page display is not available in low resolution layout. We + // remove and readd the widget here to avoid our GUI from erroring out. removeWidget(_pageDisplay); if (g_gui.xmlEval()->getVar("Globals.ShowChooserPageDisplay") == 1) { _pageDisplay->init(); @@ -628,6 +630,8 @@ void SaveLoadChooserGrid::reflowLayout() { SaveLoadChooserDialog::reflowLayout(); destroyButtons(); + // HACK: The whole code below really works around the fact, that we have + // no easy way to dynamically layout widgets. const uint16 availableWidth = getWidth() - 20; uint16 availableHeight; -- cgit v1.2.3 From c9f3d83c9eed2134b89e59cf32f2489a99e4139f Mon Sep 17 00:00:00 2001 From: Alyssa Milburn Date: Tue, 14 Aug 2012 23:48:24 +0200 Subject: GUI: Fix out-of-bounds in new chooser. --- gui/saveload-dialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index d1a66dc28a..850dfcc78f 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -535,7 +535,7 @@ const Common::String &SaveLoadChooserGrid::getResultString() const { } void SaveLoadChooserGrid::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { - if (cmd <= _entriesPerPage) { + if (cmd <= _entriesPerPage && cmd + _curPage * _entriesPerPage <= _saveList.size()) { const SaveStateDescriptor &desc = _saveList[cmd - 1 + _curPage * _entriesPerPage]; if (_saveMode) { -- cgit v1.2.3 From 66fb399227acd92db3dc8d9ee193a41609cf3d39 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 26 Sep 2012 02:11:39 +0200 Subject: GUI: Save/restore the last used page in the grid save/load dialog. This allows opening the dialog on (nearly) the same page again as when it was closed. Sadly due to the different number of entries in the save and load version this is not always exactly the same page as before. Same goes for resolution changes. Thanks to wjp for suggesting this. --- gui/saveload-dialog.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 850dfcc78f..63d8d25fe0 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -590,10 +590,21 @@ void SaveLoadChooserGrid::handleMouseWheel(int x, int y, int direction) { void SaveLoadChooserGrid::open() { SaveLoadChooserDialog::open(); - _curPage = 0; _saveList = _metaEngine->listSaves(_target.c_str()); _resultString.clear(); + // Load information to restore the last page the user had open. + assert(_entriesPerPage != 0); + const uint lastPos = ConfMan.getInt("gui_saveload_last_pos"); + const uint listSize = _saveList.size(); + if (lastPos < listSize) { + _curPage = lastPos / _entriesPerPage; + } else if (listSize) { + _curPage = (_saveList.size() - 1) / _entriesPerPage; + } else { + _curPage = 0; + } + // Determine the next free save slot for save mode if (_saveMode) { int lastSlot = -1; @@ -718,6 +729,24 @@ void SaveLoadChooserGrid::reflowLayout() { } void SaveLoadChooserGrid::close() { + // Save the current page. + const int result = getResult(); + if (result >= 0 && result != _nextFreeSaveSlot) { + // If the user selected a slot we use that one. We ignore new slots + // here, since otherwise the dialog would reset to page 0 when the + // user cancels the savename dialog. + ConfMan.setInt("gui_saveload_last_pos", result); + } else { + // Otherwise save the first entry on the current page. + // This is less precise than the solution above, since the number of + // entries shown differs between save and load version of the dialog, + // thus it might wrap to a different page than expected. + // Similar things happen on resolution changes. + // TODO: Should we ignore this here? Is the user likely to be + // interested in having this page restored when he canceled? + ConfMan.setInt("gui_saveload_last_pos", _curPage * _entriesPerPage); + } + SaveLoadChooserDialog::close(); hideButtons(); } @@ -737,6 +766,12 @@ int SaveLoadChooserGrid::runIntern() { slot = runModal(); } while (_saveMode && slot >= 0 && !selectDescription()); + // Special case for new save games. We need to handle this here, since + // we cannot handle it in close() without problems. + if (slot == _nextFreeSaveSlot) { + ConfMan.setInt("gui_saveload_last_pos", slot); + } + return slot; } -- cgit v1.2.3 From bc1743b225597715164e3d2701b2c4b5731415a4 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 26 Sep 2012 02:45:34 +0200 Subject: GUI: Save/restore last scroll position in the list save/load dialog. This should give a better user experience, since the user will not have to scroll back to where he was when he used the dialog last. Thanks to wjp for suggesting this. --- gui/saveload-dialog.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index 63d8d25fe0..c8f7556e66 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -422,7 +422,28 @@ void SaveLoadChooserSimple::updateSelection(bool redraw) { } } +void SaveLoadChooserSimple::open() { + SaveLoadChooserDialog::open(); + + // Scroll the list to the last used entry. + _list->scrollTo(ConfMan.getInt("gui_saveload_last_pos")); +} + void SaveLoadChooserSimple::close() { + // Save the current scroll position/used entry. + const int result = getResult(); + if (result >= 0) { + ConfMan.setInt("gui_saveload_last_pos", result); + } else { + // Use the current scroll position here. + // TODO: This means we canceled the dialog (or switch to the grid). Do + // we want to save this position here? Does the user want that? + // TODO: Do we want to save the current scroll position or the + // currently selected item here? The scroll position is what the user + // currently sees and seems to make more sense. + ConfMan.setInt("gui_saveload_last_pos", _list->getCurrentScrollPos()); + } + _metaEngine = 0; _target.clear(); _saveList.clear(); -- cgit v1.2.3 From 40fb004509620323a466ee1f49addc773094e21f Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 26 Sep 2012 02:49:24 +0200 Subject: GUI: Fix maximum page number calculation in grid chooser. This avoids a off by one error in some cases. --- gui/saveload-dialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index c8f7556e66..cd0f96d60c 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -882,7 +882,7 @@ void SaveLoadChooserGrid::updateSaves() { } } - const uint numPages = (_entriesPerPage != 0) ? (_saveList.size() / _entriesPerPage + 1) : 1; + const uint numPages = (_entriesPerPage != 0 && !_saveList.empty()) ? ((_saveList.size() + _entriesPerPage - 1) / _entriesPerPage) : 1; _pageDisplay->setLabel(Common::String::format("%u/%u", _curPage + 1, numPages)); if (_curPage > 0) -- cgit v1.2.3 From 89abab97e3124fa25eb4c7d3e8b38501747a8d17 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 26 Sep 2012 04:17:31 +0200 Subject: JANITORIAL: Remove trailing whitespaces. Powered by: git ls-files "*.cpp" "*.h" "*.m" "*.mm" | xargs sed -i -e 's/[ \t]*$//' --- gui/saveload-dialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index cd0f96d60c..be6cefda26 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -735,7 +735,7 @@ void SaveLoadChooserGrid::reflowLayout() { if (!_saveMode) { buttonCmd += 1; } - + PicButtonWidget *button = new PicButtonWidget(container, dstX, dstY, buttonWidth, buttonHeight, 0, buttonCmd); dstY += buttonHeight; @@ -788,7 +788,7 @@ int SaveLoadChooserGrid::runIntern() { } while (_saveMode && slot >= 0 && !selectDescription()); // Special case for new save games. We need to handle this here, since - // we cannot handle it in close() without problems. + // we cannot handle it in close() without problems. if (slot == _nextFreeSaveSlot) { ConfMan.setInt("gui_saveload_last_pos", slot); } -- cgit v1.2.3 From 9942b5ab600f6b71b5d10921d11bf761f5eef298 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 26 Sep 2012 16:10:35 +0200 Subject: GUI: Support for page restoring for non-continuous save lists in the grid chooser. --- gui/saveload-dialog.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'gui/saveload-dialog.cpp') diff --git a/gui/saveload-dialog.cpp b/gui/saveload-dialog.cpp index be6cefda26..df8dda7470 100644 --- a/gui/saveload-dialog.cpp +++ b/gui/saveload-dialog.cpp @@ -618,14 +618,22 @@ void SaveLoadChooserGrid::open() { assert(_entriesPerPage != 0); const uint lastPos = ConfMan.getInt("gui_saveload_last_pos"); const uint listSize = _saveList.size(); - if (lastPos < listSize) { - _curPage = lastPos / _entriesPerPage; - } else if (listSize) { - _curPage = (_saveList.size() - 1) / _entriesPerPage; - } else { - _curPage = 0; + uint bestMatch = 0; + uint diff = 0xFFFFFFFF; + + // We look for the nearest available slot, since a slot might be missing + // due to the user deleting it via the list based chooser, by deleting + // it by hand, etc. + for (uint i = 0; i < listSize; ++i) { + uint curDiff = ABS(_saveList[i].getSaveSlot() - (int)lastPos); + if (curDiff < diff) { + diff = curDiff; + bestMatch = i; + } } + _curPage = bestMatch / _entriesPerPage; + // Determine the next free save slot for save mode if (_saveMode) { int lastSlot = -1; @@ -765,7 +773,7 @@ void SaveLoadChooserGrid::close() { // Similar things happen on resolution changes. // TODO: Should we ignore this here? Is the user likely to be // interested in having this page restored when he canceled? - ConfMan.setInt("gui_saveload_last_pos", _curPage * _entriesPerPage); + ConfMan.setInt("gui_saveload_last_pos", !_saveList.empty() ? _saveList[_curPage * _entriesPerPage].getSaveSlot() : 0); } SaveLoadChooserDialog::close(); -- cgit v1.2.3