From 7198181b093732592d678fc95c64698fe0470715 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sat, 19 Oct 2002 01:22:41 +0000 Subject: reworked the way the save/load dialog works. yup, still not perfect, but we're hopefully getting closer. Feedback welcome svn-id: r5189 --- gui/ListWidget.cpp | 32 ++++++++++++++++- gui/ListWidget.h | 5 ++- gui/dialog.cpp | 5 +++ gui/dialog.h | 1 + gui/newgui.cpp | 25 ++++++++------ gui/newgui.h | 2 +- gui/widget.cpp | 39 +++++++++++++++------ gui/widget.h | 32 +++++++++++------ scumm/dialogs.cpp | 100 ++++++++++++++++++++++++++++++++++++++++------------- scumm/dialogs.h | 13 ++++++- 10 files changed, 194 insertions(+), 60 deletions(-) diff --git a/gui/ListWidget.cpp b/gui/ListWidget.cpp index b477f4f9ea..84275b43b7 100644 --- a/gui/ListWidget.cpp +++ b/gui/ListWidget.cpp @@ -48,6 +48,17 @@ ListWidget::~ListWidget() { } +void ListWidget::setList(const StringList& list) +{ + int size = list.size(); + _list = list; + if (_currentPos >= size) + _currentPos = size - 1; + _selectedItem = -1; + _editMode = false; + scrollBarRecalc(); +} + void ListWidget::scrollBarRecalc() { _scrollBar->_numEntries = _list.size(); @@ -136,8 +147,8 @@ bool ListWidget::handleKeyDown(char key, int modifiers) if (_selectedItem >= 0) { // override continuous enter keydown if (_editable && (_currentKeyDown != '\n' && _currentKeyDown != '\r')) { - _editMode = true; dirty = true; + _editMode = true; _backupString = _list[_selectedItem]; } } @@ -271,3 +282,22 @@ void ListWidget::scrollToCurrent() { _scrollBar->_currentPos = _currentPos; _scrollBar->recalc(); } + +void ListWidget::startEditMode() +{ + if (_editable && !_editMode && _selectedItem >= 0) { + _editMode = true; + _backupString = _list[_selectedItem]; + _list[_selectedItem] += '_'; + draw(); + } +} + +void ListWidget::abortEditMode() +{ + if (_editMode) { + _editMode = false; + _list[_selectedItem] = _backupString; + draw(); + } +} diff --git a/gui/ListWidget.h b/gui/ListWidget.h index 59af0ba1b2..3140218df0 100644 --- a/gui/ListWidget.h +++ b/gui/ListWidget.h @@ -58,7 +58,7 @@ public: ListWidget(Dialog *boss, int x, int y, int w, int h); virtual ~ListWidget(); - void setList(const StringList& list) { _list = list; scrollBarRecalc(); } + void setList(const StringList& list); const StringList& getList() const { return _list; } int getSelected() const { return _selectedItem; } const String& getSelectedString() const { return _list[_selectedItem]; } @@ -76,6 +76,9 @@ public: virtual bool wantsFocus() { return true; }; void scrollBarRecalc(); + + void startEditMode(); + void abortEditMode(); protected: void drawWidget(bool hilite); diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 679637967b..6110225df0 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -287,3 +287,8 @@ Widget *Dialog::addButton(int x, int y, const ScummVM::String &label, uint32 cmd return new ButtonWidget(this, x, y, kButtonWidth, 16, label, cmd, hotkey); } +Widget *Dialog::addPushButton(int x, int y, const ScummVM::String &label, uint32 cmd, char hotkey) +{ + return new PushButtonWidget(this, x, y, kButtonWidth, 16, label, cmd, hotkey); +} + diff --git a/gui/dialog.h b/gui/dialog.h index 82ad3d9292..df08db9a01 100644 --- a/gui/dialog.h +++ b/gui/dialog.h @@ -73,6 +73,7 @@ protected: Widget* findWidget(int x, int y); // Find the widget at pos x,y if any Widget* addButton(int x, int y, const ScummVM::String &label, uint32 cmd, char hotkey); + Widget* addPushButton(int x, int y, const ScummVM::String &label, uint32 cmd, char hotkey); }; #endif diff --git a/gui/newgui.cpp b/gui/newgui.cpp index ffe8d503cc..0ce93c7300 100644 --- a/gui/newgui.cpp +++ b/gui/newgui.cpp @@ -87,7 +87,7 @@ NewGui::NewGui(OSystem *system) : _system(system), _screen(0), _needRedraw(false // Setup some default GUI colors. // TODO - either use nicer values, or maybe make this configurable? _bgcolor = RGB_TO_16(0, 0, 0); - _color = RGB_TO_16(80, 80, 80); + _color = RGB_TO_16(96, 96, 96); _shadowcolor = RGB_TO_16(64, 64, 64); _textcolor = RGB_TO_16(32, 160, 32); _textcolorhi = RGB_TO_16(0, 255, 0); @@ -261,17 +261,20 @@ int16 *NewGui::getBasePtr(int x, int y) return _screen + x + y * _screenPitch; } -void NewGui::box(int x, int y, int width, int height) +void NewGui::box(int x, int y, int width, int height, bool inverted) { - hline(x + 1, y, x + width - 2, _color); - hline(x, y + 1, x + width - 1, _color); - vline(x, y + 1, y + height - 2, _color); - vline(x + 1, y, y + height - 1, _color); - - hline(x + 1, y + height - 2, x + width - 1, _shadowcolor); - hline(x + 1, y + height - 1, x + width - 2, _shadowcolor); - vline(x + width - 1, y + 1, y + height - 2, _shadowcolor); - vline(x + width - 2, y + 1, y + height - 1, _shadowcolor); + int16 colorA = inverted ? _shadowcolor : _color; + int16 colorB = inverted ? _color : _shadowcolor; + + hline(x + 1, y, x + width - 2, colorA); + hline(x, y + 1, x + width - 1, colorA); + vline(x, y + 1, y + height - 2, colorA); + vline(x + 1, y, y + height - 1, colorA); + + hline(x + 1, y + height - 2, x + width - 1, colorB); + hline(x + 1, y + height - 1, x + width - 2, colorB); + vline(x + width - 1, y + 1, y + height - 2, colorB); + vline(x + width - 2, y + 1, y + height - 1, colorB); } void NewGui::line(int x, int y, int x2, int y2, int16 color) diff --git a/gui/newgui.h b/gui/newgui.h index 957c63c1fa..d1ba430d0d 100644 --- a/gui/newgui.h +++ b/gui/newgui.h @@ -119,7 +119,7 @@ public: // Drawing primitives int16 *getBasePtr(int x, int y); - void box(int x, int y, int width, int height); + void box(int x, int y, int width, int height, bool inverted = false); void line(int x, int y, int x2, int y2, int16 color); void blendRect(int x, int y, int w, int h, int16 color); void fillRect(int x, int y, int w, int h, int16 color); diff --git a/gui/widget.cpp b/gui/widget.cpp index 463c0a7b3d..1451dce773 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -26,9 +26,7 @@ #ifdef _MSC_VER - # pragma warning( disable : 4068 ) // unknown pragma - #endif @@ -59,7 +57,7 @@ void Widget::draw() // Draw border if (_flags & WIDGET_BORDER) { - gui->box(_x, _y, _w, _h); + gui->box(_x, _y, _w, _h, (_flags & WIDGET_INV_BORDER) == WIDGET_INV_BORDER); _x += 4; _y += 4; _w -= 8; @@ -111,9 +109,10 @@ void StaticTextWidget::drawWidget(bool hilite) ButtonWidget::ButtonWidget(Dialog *boss, int x, int y, int w, int h, const String &label, uint32 cmd, uint8 hotkey) - : StaticTextWidget(boss, x, y, w, h, label, kTextAlignCenter), CommandSender(boss), _cmd(cmd), _hotkey(hotkey) + : StaticTextWidget(boss, x, y, w, h, label, kTextAlignCenter), CommandSender(boss), + _cmd(cmd), _hotkey(hotkey) { - _flags = WIDGET_ENABLED | WIDGET_BORDER | WIDGET_CLEARBG ; + _flags = WIDGET_ENABLED | WIDGET_BORDER | WIDGET_CLEARBG; _type = kButtonWidget; } @@ -131,6 +130,27 @@ void ButtonWidget::drawWidget(bool hilite) hilite ? gui->_textcolorhi : gui->_textcolor, _align); } + +#pragma mark - + + +PushButtonWidget::PushButtonWidget(Dialog *boss, int x, int y, int w, int h, const String &label, uint32 cmd, uint8 hotkey) + : ButtonWidget(boss, x, y, w, h, label, cmd, hotkey), _state(false) +{ + _flags = WIDGET_ENABLED | WIDGET_BORDER | WIDGET_CLEARBG; + _type = kButtonWidget; +} + +void PushButtonWidget::setState(bool state) +{ + if (_state != state) { + _state = state; + _flags ^= WIDGET_INV_BORDER; + draw(); + } +} + + #pragma mark - @@ -147,17 +167,16 @@ static uint32 checked_img[8] = { }; CheckboxWidget::CheckboxWidget(Dialog *boss, int x, int y, int w, int h, const String &label, uint32 cmd, uint8 hotkey) - : ButtonWidget(boss, x, y, w, h, label, cmd, hotkey), _state(false) + : PushButtonWidget(boss, x, y, w, h, label, cmd, hotkey) { _flags = WIDGET_ENABLED; _type = kCheckboxWidget; } -void CheckboxWidget::handleMouseDown(int x, int y, int button, int clickCount) +void CheckboxWidget::handleMouseUp(int x, int y, int button, int clickCount) { - if (isEnabled()) { - _state = !_state; - draw(); + if (isEnabled() && x >= 0 && x < _w && y >= 0 && y < _h) { + toggleState(); sendCommand(_cmd, 0); } } diff --git a/gui/widget.h b/gui/widget.h index 99808d49a3..8f15309bf0 100644 --- a/gui/widget.h +++ b/gui/widget.h @@ -31,10 +31,11 @@ enum { WIDGET_INVISIBLE = 1 << 1, WIDGET_HILITED = 1 << 2, WIDGET_BORDER = 1 << 3, - WIDGET_CLEARBG = 1 << 4, - WIDGET_WANT_TICKLE = 1 << 5, - WIDGET_TRACK_MOUSE = 1 << 6, - WIDGET_RETAIN_FOCUS = 1 << 7 // Retain focus on mouse up. By default widgets lose focus on mouseup, but some widgets might want to retain it - widgets where you enter text, for instance + WIDGET_INV_BORDER = 1 << 4, + WIDGET_CLEARBG = 1 << 5, + WIDGET_WANT_TICKLE = 1 << 7, + WIDGET_TRACK_MOUSE = 1 << 8, + WIDGET_RETAIN_FOCUS = 1 << 9 // Retain focus on mouse up. By default widgets lose focus on mouseup, but some widgets might want to retain it - widgets where you enter text, for instance }; @@ -152,8 +153,8 @@ protected: class ButtonWidget : public StaticTextWidget, public CommandSender { friend class Dialog; // Needed for the hotkey handling protected: - uint32 _cmd; - uint8 _hotkey; + uint32 _cmd; + uint8 _hotkey; public: ButtonWidget(Dialog *boss, int x, int y, int w, int h, const String &label, uint32 cmd = 0, uint8 hotkey = 0); @@ -168,16 +169,25 @@ protected: void drawWidget(bool hilite); }; -/* CheckboxWidget */ -class CheckboxWidget : public ButtonWidget { +/* PushButtonWidget */ +class PushButtonWidget : public ButtonWidget { protected: bool _state; public: - CheckboxWidget(Dialog *boss, int x, int y, int w, int h, const String &label, uint32 cmd = 0, uint8 hotkey = 0); - void setState(bool state) { _state = state; } + PushButtonWidget(Dialog *boss, int x, int y, int w, int h, const String &label, uint32 cmd = 0, uint8 hotkey = 0); + + void setState(bool state); + void toggleState() { setState(!_state); } bool getState() const { return _state; } +}; - void handleMouseDown(int x, int y, int button, int clickCount); +/* CheckboxWidget */ +class CheckboxWidget : public PushButtonWidget { +protected: +public: + CheckboxWidget(Dialog *boss, int x, int y, int w, int h, const String &label, uint32 cmd = 0, uint8 hotkey = 0); + + void handleMouseUp(int x, int y, int button, int clickCount); virtual void handleMouseEntered(int button) {} virtual void handleMouseLeft(int button) {} diff --git a/scumm/dialogs.cpp b/scumm/dialogs.cpp index c1aec50393..3d846c60fc 100644 --- a/scumm/dialogs.cpp +++ b/scumm/dialogs.cpp @@ -307,47 +307,63 @@ SaveLoadDialog::SaveLoadDialog(NewGui *gui, Scumm *scumm) // addResText(10, 7, 240, 16, 2); // addResText(10, 7, 240, 16, 3); - addButton(200, 20, queryResString(4), kSaveCmd, 'S'); // Save - addButton(200, 40, queryResString(5), kLoadCmd, 'L'); // Load + _saveButton = (PushButtonWidget *)addPushButton(200, 20, queryResString(4), kSaveCmd, 'S'); + _loadButton = (PushButtonWidget *)addPushButton(200, 40, queryResString(5), kLoadCmd, 'L'); addButton(200, 60, queryResString(6), kPlayCmd, 'P'); // Play addButton(200, 80, queryCustomString(17), kOptionsCmd, 'O'); // Options addButton(200, 100, queryResString(8), kQuitCmd, 'Q'); // Quit _savegameList = new ListWidget(this, 10, 20, 180, 90); - _savegameList->setNumberingMode(kListNumberingZero); - - // Get savegame names - ScummVM::StringList l; - char name[32]; +} - for (int i = 0; i <= 80; i++) { // 80 - got this value from the old GUI - _scumm->getSavegameName(i, name); - l.push_back(name); - } +void SaveLoadDialog::open() +{ + _saveMode = false; + _saveButton->setState(false); + _loadButton->setState(true); + fillList(); - _savegameList->setList(l); + ScummDialog::open(); } void SaveLoadDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { switch (cmd) { - case kListItemActivatedCmd: case kSaveCmd: - if (_savegameList->getSelected() >= 1 && !_savegameList->getSelectedString().isEmpty()) { - _scumm->_saveLoadSlot = _savegameList->getSelected(); - _scumm->_saveLoadCompatible = false; - _scumm->_saveLoadFlag = 1; // 1 for save, I assume (Painelf) - strcpy(_scumm->_saveLoadName, _savegameList->getSelectedString().c_str()); - close(); + if (!_saveMode) { + _saveMode = true; + _saveButton->setState(true); + _loadButton->setState(false); + fillList(); + draw(); } break; - case kListItemDoubleClickedCmd: case kLoadCmd: + if (_saveMode) { + _saveMode = false; + _saveButton->setState(false); + _loadButton->setState(true); + fillList(); + draw(); + } + break; + case kListItemDoubleClickedCmd: if (_savegameList->getSelected() >= 0 && !_savegameList->getSelectedString().isEmpty()) { - _scumm->_saveLoadSlot = _savegameList->getSelected(); - _scumm->_saveLoadCompatible = false; - _scumm->_saveLoadFlag = 2; // 2 for load. Magic number anyone? - close(); + if (_saveMode) { + // Start editing the selected item, for saving + _savegameList->startEditMode(); + } else { + load(); + } + } + break; + case kListItemActivatedCmd: + if (_savegameList->getSelected() >= 0 && !_savegameList->getSelectedString().isEmpty()) { + if (_saveMode) { + save(); + } else { + load(); + } } break; case kPlayCmd: @@ -364,9 +380,45 @@ void SaveLoadDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat } } +void SaveLoadDialog::fillList() +{ + // Get savegame names + ScummVM::StringList l; + char name[32]; + int i = _saveMode ? 1 : 0; + + for (; i <= 80; i++) { // 80 - got this value from the old GUI + _scumm->getSavegameName(i, name); + l.push_back(name); + } + + _savegameList->setList(l); + _savegameList->setNumberingMode(_saveMode ? kListNumberingOne : kListNumberingZero); +} + +void SaveLoadDialog::save() +{ + // Save the selected item + _scumm->_saveLoadSlot = _savegameList->getSelected() + 1; + _scumm->_saveLoadCompatible = false; + _scumm->_saveLoadFlag = 1; // 1 for save, I assume (Painelf) + strcpy(_scumm->_saveLoadName, _savegameList->getSelectedString().c_str()); + close(); +} + +void SaveLoadDialog::load() +{ + // Load the selected item + _scumm->_saveLoadSlot = _savegameList->getSelected(); + _scumm->_saveLoadCompatible = false; + _scumm->_saveLoadFlag = 2; // 2 for load. Magic number anyone? + close(); +} + #pragma mark - + enum { kMasterVolumeChanged = 'mavc', kMusicVolumeChanged = 'muvc', diff --git a/scumm/dialogs.h b/scumm/dialogs.h index 8f3f752148..2a3dde696f 100644 --- a/scumm/dialogs.h +++ b/scumm/dialogs.h @@ -51,10 +51,21 @@ class SaveLoadDialog : public ScummDialog { public: SaveLoadDialog(NewGui *gui, Scumm *scumm); + virtual void open(); + virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); protected: - ListWidget *_savegameList; + ListWidget *_savegameList; + + PushButtonWidget *_saveButton; + PushButtonWidget *_loadButton; + + bool _saveMode; + + void fillList(); + void save(); + void load(); }; -- cgit v1.2.3