diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index fdd7750af9e..be0a5db601e 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -175,6 +175,7 @@ static const DrawDataInfo kDrawDataDefaults[] = { {kDDButtonIdle, "button_idle", true, kDDWidgetBackgroundSlider}, {kDDButtonHover, "button_hover", false, kDDButtonIdle}, {kDDButtonDisabled, "button_disabled", true, kDDNone}, + {kDDButtonPressed, "button_pressed", false, kDDButtonIdle}, {kDDSliderFull, "slider_full", false, kDDNone}, {kDDSliderHover, "slider_hover", false, kDDNone}, @@ -877,6 +878,8 @@ void ThemeEngine::drawButton(const Common::Rect &r, const Common::String &str, W dd = kDDButtonHover; else if (state == kStateDisabled) dd = kDDButtonDisabled; + else if (state == kStatePressed) + dd = kDDButtonPressed; queueDD(dd, r, 0, hints & WIDGET_CLEARBG); queueDDText(getTextData(dd), getTextColor(dd), r, str, false, true, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV); @@ -1125,6 +1128,7 @@ void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, Wid break; case kStateEnabled: + case kStatePressed: colorId = kTextColorNormal; break; } @@ -1145,6 +1149,7 @@ void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, Wid break; case kStateEnabled: + case kStatePressed: colorId = kTextColorAlternative; break; } diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index 0495a85c88c..acded085f50 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -35,7 +35,7 @@ #include "graphics/pixelformat.h" -#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.11" +#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.12" class OSystem; @@ -81,6 +81,7 @@ enum DrawData { kDDButtonIdle, kDDButtonHover, kDDButtonDisabled, + kDDButtonPressed, kDDSliderFull, kDDSliderHover, @@ -178,7 +179,8 @@ public: enum State { kStateDisabled, ///< Indicates that the widget is disabled, that does NOT include that it is invisible kStateEnabled, ///< Indicates that the widget is enabled - kStateHighlight ///< Indicates that the widget is highlighted by the user + kStateHighlight, ///< Indicates that the widget is highlighted by the user + kStatePressed ///< Indicates that the widget is pressed, currently works for buttons }; typedef State WidgetStateInfo; diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 2201e83ca54..ffca15bbc82 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -42,7 +42,7 @@ namespace GUI { Dialog::Dialog(int x, int y, int w, int h) : GuiObject(x, y, w, h), - _mouseWidget(0), _focusedWidget(0), _dragWidget(0), _visible(false), + _mouseWidget(0), _focusedWidget(0), _dragWidget(0), _tickleWidget(0), _visible(false), _backgroundType(GUI::ThemeEngine::kDialogBackgroundDefault) { // Some dialogs like LauncherDialog use internally a fixed size, even though // their widgets rely on the layout to be initialized correctly by the theme. @@ -54,7 +54,7 @@ Dialog::Dialog(int x, int y, int w, int h) Dialog::Dialog(const Common::String &name) : GuiObject(name), - _mouseWidget(0), _focusedWidget(0), _dragWidget(0), _visible(false), + _mouseWidget(0), _focusedWidget(0), _dragWidget(0), _tickleWidget(0), _visible(false), _backgroundType(GUI::ThemeEngine::kDialogBackgroundDefault) { // It may happen that we have 3x scaler in launcher (960xY) and then 640x480 @@ -117,6 +117,12 @@ void Dialog::reflowLayout() { GuiObject::reflowLayout(); } +void Dialog::lostFocus() { + if (_tickleWidget) { + _tickleWidget->lostFocus(); + } +} + void Dialog::setFocusWidget(Widget *widget) { // The focus will change. Tell the old focused widget (if any) // that it lost the focus. @@ -308,6 +314,9 @@ void Dialog::handleTickle() { // Focused widget receives tickle notifications if (_focusedWidget && _focusedWidget->getFlags() & WIDGET_WANT_TICKLE) _focusedWidget->handleTickle(); + + if (_tickleWidget && _tickleWidget->getFlags() & WIDGET_WANT_TICKLE) + _tickleWidget->handleTickle(); } void Dialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { diff --git a/gui/dialog.h b/gui/dialog.h index f5a5f94a68b..f923c1f5b88 100644 --- a/gui/dialog.h +++ b/gui/dialog.h @@ -52,6 +52,7 @@ protected: Widget *_mouseWidget; Widget *_focusedWidget; Widget *_dragWidget; + Widget *_tickleWidget; bool _visible; ThemeEngine::DialogBackground _backgroundType; @@ -71,7 +72,13 @@ public: void setFocusWidget(Widget *widget); Widget *getFocusWidget() { return _focusedWidget; } + void setTickleWidget(Widget *widget) { _tickleWidget = widget; } + void unSetTickleWidget() { _tickleWidget = NULL; } + Widget *getTickleWidget() { return _tickleWidget; } + virtual void reflowLayout(); + virtual void lostFocus(); + virtual void receivedFocus() {}; protected: virtual void open(); diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp index ffecd928bcb..abd781e1a38 100644 --- a/gui/gui-manager.cpp +++ b/gui/gui-manager.cpp @@ -381,7 +381,7 @@ void GuiManager::runLoop() { if (tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis()) { Widget *wdg = activeDialog->findWidget(_lastMousePosition.x, _lastMousePosition.y); - if (wdg && wdg->getTooltip()) { + if (wdg && wdg->getTooltip() && !(wdg->getFlags() & WIDGET_PRESSED)) { Tooltip *tooltip = new Tooltip(); tooltip->setup(activeDialog, wdg, _lastMousePosition.x, _lastMousePosition.y); tooltip->runModal(); @@ -441,6 +441,11 @@ void GuiManager::restoreState() { } void GuiManager::openDialog(Dialog *dialog) { + dialog->receivedFocus(); + + if (!_dialogStack.empty()) + getTopDialog()->lostFocus(); + _dialogStack.push(dialog); if (_redrawStatus != kRedrawFull) _redrawStatus = kRedrawOpenDialog; @@ -458,7 +463,11 @@ void GuiManager::closeTopDialog() { return; // Remove the dialog from the stack - _dialogStack.pop(); + _dialogStack.pop()->lostFocus(); + + if (!_dialogStack.empty()) + getTopDialog()->receivedFocus(); + if (_redrawStatus != kRedrawFull) _redrawStatus = kRedrawCloseDialog; diff --git a/gui/launcher.cpp b/gui/launcher.cpp index a86a98f8190..c8ed3126c4b 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -663,7 +663,6 @@ LauncherDialog::LauncherDialog() _list->setEditable(false); _list->setNumberingMode(kListNumberingOff); - // Populate the list updateListing(); diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 542f776dbd6..5ee9b9202a7 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -460,6 +460,17 @@ "bevel='2' " "/> " " " +" " +" " +" " +" " " " " + + + + + + + + + + + + = 0 && x < _w && y >= 0 && y < _h) + if (isEnabled() && x >= 0 && x < _w && y >= 0 && y < _h) { sendCommand(_cmd, 0); + startAnimatePressedState(); + } +} + +void ButtonWidget::handleMouseDown(int x, int y, int button, int clickCount) { + setPressedState(); } void ButtonWidget::drawWidget() { @@ -324,6 +334,44 @@ ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 return button; } +void ButtonWidget::setHighLighted(bool enable) { + (enable) ? setFlags(WIDGET_HILITED) : clearFlags(WIDGET_HILITED); + draw(); +} + +void ButtonWidget::handleTickle() { + if (_lastTime) { + uint32 curTime = g_system->getMillis(); + if (curTime - _lastTime > kPressedButtonTime) { + stopAnimatePressedState(); + } + } +} + +void ButtonWidget::setPressedState() { + wantTickle(true); + setFlags(WIDGET_PRESSED); + draw(); +} + +void ButtonWidget::stopAnimatePressedState() { + wantTickle(false); + _lastTime = 0; + clearFlags(WIDGET_PRESSED); + draw(); +} + +void ButtonWidget::startAnimatePressedState() { + _lastTime = g_system->getMillis(); +} + +void ButtonWidget::wantTickle(bool tickled) { + if (tickled) + ((GUI::Dialog *)_boss)->setTickleWidget(this); + else + ((GUI::Dialog *)_boss)->unSetTickleWidget(); +} + #pragma mark - PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey) diff --git a/gui/widget.h b/gui/widget.h index 789fc092315..6a6c67ced94 100644 --- a/gui/widget.h +++ b/gui/widget.h @@ -38,6 +38,7 @@ enum { WIDGET_INVISIBLE = 1 << 1, WIDGET_HILITED = 1 << 2, WIDGET_BORDER = 1 << 3, + WIDGET_PRESSED = 1 << 4, //WIDGET_INV_BORDER = 1 << 4, WIDGET_CLEARBG = 1 << 5, WIDGET_WANT_TICKLE = 1 << 7, @@ -73,6 +74,10 @@ enum { kCaretBlinkTime = 300 }; +enum { + kPressedButtonTime = 200 +}; + /* Widget */ class Widget : public GuiObject { friend class Dialog; @@ -189,11 +194,22 @@ public: void setLabel(const Common::String &label); void handleMouseUp(int x, int y, int button, int clickCount); + void handleMouseDown(int x, int y, int button, int clickCount); void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); draw(); } - void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); draw(); } + void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED | WIDGET_PRESSED); draw(); } + void handleTickle(); + void setHighLighted(bool enable); + void setPressedState(); + void startAnimatePressedState(); + void stopAnimatePressedState(); + + void lostFocusWidget() { stopAnimatePressedState(); } protected: void drawWidget(); + void wantTickle(bool tickled); +private: + uint32 _lastTime; }; /* PicButtonWidget */