GUI: Implemented pressed state for buttons

This commit is contained in:
Oleksiy Kurochko 2012-05-03 19:32:08 +03:00 committed by Eugene Sandulenko
parent 8d157ae185
commit e6c317a922
15 changed files with 155 additions and 15 deletions

View file

@ -175,6 +175,7 @@ static const DrawDataInfo kDrawDataDefaults[] = {
{kDDButtonIdle, "button_idle", true, kDDWidgetBackgroundSlider}, {kDDButtonIdle, "button_idle", true, kDDWidgetBackgroundSlider},
{kDDButtonHover, "button_hover", false, kDDButtonIdle}, {kDDButtonHover, "button_hover", false, kDDButtonIdle},
{kDDButtonDisabled, "button_disabled", true, kDDNone}, {kDDButtonDisabled, "button_disabled", true, kDDNone},
{kDDButtonPressed, "button_pressed", false, kDDButtonIdle},
{kDDSliderFull, "slider_full", false, kDDNone}, {kDDSliderFull, "slider_full", false, kDDNone},
{kDDSliderHover, "slider_hover", 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; dd = kDDButtonHover;
else if (state == kStateDisabled) else if (state == kStateDisabled)
dd = kDDButtonDisabled; dd = kDDButtonDisabled;
else if (state == kStatePressed)
dd = kDDButtonPressed;
queueDD(dd, r, 0, hints & WIDGET_CLEARBG); queueDD(dd, r, 0, hints & WIDGET_CLEARBG);
queueDDText(getTextData(dd), getTextColor(dd), r, str, false, true, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV); 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; break;
case kStateEnabled: case kStateEnabled:
case kStatePressed:
colorId = kTextColorNormal; colorId = kTextColorNormal;
break; break;
} }
@ -1145,6 +1149,7 @@ void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, Wid
break; break;
case kStateEnabled: case kStateEnabled:
case kStatePressed:
colorId = kTextColorAlternative; colorId = kTextColorAlternative;
break; break;
} }

View file

@ -35,7 +35,7 @@
#include "graphics/pixelformat.h" #include "graphics/pixelformat.h"
#define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.11" #define SCUMMVM_THEME_VERSION_STR "SCUMMVM_STX0.8.12"
class OSystem; class OSystem;
@ -81,6 +81,7 @@ enum DrawData {
kDDButtonIdle, kDDButtonIdle,
kDDButtonHover, kDDButtonHover,
kDDButtonDisabled, kDDButtonDisabled,
kDDButtonPressed,
kDDSliderFull, kDDSliderFull,
kDDSliderHover, kDDSliderHover,
@ -178,7 +179,8 @@ public:
enum State { enum State {
kStateDisabled, ///< Indicates that the widget is disabled, that does NOT include that it is invisible kStateDisabled, ///< Indicates that the widget is disabled, that does NOT include that it is invisible
kStateEnabled, ///< Indicates that the widget is enabled 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; typedef State WidgetStateInfo;

View file

@ -42,7 +42,7 @@ namespace GUI {
Dialog::Dialog(int x, int y, int w, int h) Dialog::Dialog(int x, int y, int w, int h)
: GuiObject(x, y, w, 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) { _backgroundType(GUI::ThemeEngine::kDialogBackgroundDefault) {
// Some dialogs like LauncherDialog use internally a fixed size, even though // Some dialogs like LauncherDialog use internally a fixed size, even though
// their widgets rely on the layout to be initialized correctly by the theme. // 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) Dialog::Dialog(const Common::String &name)
: GuiObject(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) { _backgroundType(GUI::ThemeEngine::kDialogBackgroundDefault) {
// It may happen that we have 3x scaler in launcher (960xY) and then 640x480 // It may happen that we have 3x scaler in launcher (960xY) and then 640x480
@ -117,6 +117,12 @@ void Dialog::reflowLayout() {
GuiObject::reflowLayout(); GuiObject::reflowLayout();
} }
void Dialog::lostFocus() {
if (_tickleWidget) {
_tickleWidget->lostFocus();
}
}
void Dialog::setFocusWidget(Widget *widget) { void Dialog::setFocusWidget(Widget *widget) {
// The focus will change. Tell the old focused widget (if any) // The focus will change. Tell the old focused widget (if any)
// that it lost the focus. // that it lost the focus.
@ -308,6 +314,9 @@ void Dialog::handleTickle() {
// Focused widget receives tickle notifications // Focused widget receives tickle notifications
if (_focusedWidget && _focusedWidget->getFlags() & WIDGET_WANT_TICKLE) if (_focusedWidget && _focusedWidget->getFlags() & WIDGET_WANT_TICKLE)
_focusedWidget->handleTickle(); _focusedWidget->handleTickle();
if (_tickleWidget && _tickleWidget->getFlags() & WIDGET_WANT_TICKLE)
_tickleWidget->handleTickle();
} }
void Dialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { void Dialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {

View file

@ -52,6 +52,7 @@ protected:
Widget *_mouseWidget; Widget *_mouseWidget;
Widget *_focusedWidget; Widget *_focusedWidget;
Widget *_dragWidget; Widget *_dragWidget;
Widget *_tickleWidget;
bool _visible; bool _visible;
ThemeEngine::DialogBackground _backgroundType; ThemeEngine::DialogBackground _backgroundType;
@ -71,7 +72,13 @@ public:
void setFocusWidget(Widget *widget); void setFocusWidget(Widget *widget);
Widget *getFocusWidget() { return _focusedWidget; } Widget *getFocusWidget() { return _focusedWidget; }
void setTickleWidget(Widget *widget) { _tickleWidget = widget; }
void unSetTickleWidget() { _tickleWidget = NULL; }
Widget *getTickleWidget() { return _tickleWidget; }
virtual void reflowLayout(); virtual void reflowLayout();
virtual void lostFocus();
virtual void receivedFocus() {};
protected: protected:
virtual void open(); virtual void open();

View file

@ -381,7 +381,7 @@ void GuiManager::runLoop() {
if (tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis()) { if (tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis()) {
Widget *wdg = activeDialog->findWidget(_lastMousePosition.x, _lastMousePosition.y); 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 *tooltip = new Tooltip();
tooltip->setup(activeDialog, wdg, _lastMousePosition.x, _lastMousePosition.y); tooltip->setup(activeDialog, wdg, _lastMousePosition.x, _lastMousePosition.y);
tooltip->runModal(); tooltip->runModal();
@ -441,6 +441,11 @@ void GuiManager::restoreState() {
} }
void GuiManager::openDialog(Dialog *dialog) { void GuiManager::openDialog(Dialog *dialog) {
dialog->receivedFocus();
if (!_dialogStack.empty())
getTopDialog()->lostFocus();
_dialogStack.push(dialog); _dialogStack.push(dialog);
if (_redrawStatus != kRedrawFull) if (_redrawStatus != kRedrawFull)
_redrawStatus = kRedrawOpenDialog; _redrawStatus = kRedrawOpenDialog;
@ -458,7 +463,11 @@ void GuiManager::closeTopDialog() {
return; return;
// Remove the dialog from the stack // Remove the dialog from the stack
_dialogStack.pop(); _dialogStack.pop()->lostFocus();
if (!_dialogStack.empty())
getTopDialog()->receivedFocus();
if (_redrawStatus != kRedrawFull) if (_redrawStatus != kRedrawFull)
_redrawStatus = kRedrawCloseDialog; _redrawStatus = kRedrawCloseDialog;

View file

@ -663,7 +663,6 @@ LauncherDialog::LauncherDialog()
_list->setEditable(false); _list->setEditable(false);
_list->setNumberingMode(kListNumberingOff); _list->setNumberingMode(kListNumberingOff);
// Populate the list // Populate the list
updateListing(); updateListing();

View file

@ -460,6 +460,17 @@
"bevel='2' " "bevel='2' "
"/> " "/> "
"</drawdata> " "</drawdata> "
"<drawdata id='button_pressed' cache='false'> "
"<text font='text_button' "
"text_color='color_alternative_inverted' "
"vertical_align='center' "
"horizontal_align='center' "
"/> "
"<drawstep func='square' "
"fill='foreground' "
"fg_color='green' "
"/> "
"</drawdata> "
"<drawdata id='button_idle' cache='false'> " "<drawdata id='button_idle' cache='false'> "
"<text font='text_button' " "<text font='text_button' "
"text_color='color_button' " "text_color='color_button' "

Binary file not shown.

View file

@ -1 +1 @@
[SCUMMVM_STX0.8.11:ScummVM Classic Theme:No Author] [SCUMMVM_STX0.8.12:ScummVM Classic Theme:No Author]

View file

@ -541,6 +541,19 @@
/> />
</drawdata> </drawdata>
<!-- Pressed button -->
<drawdata id = 'button_pressed' cache = 'false'>
<text font = 'text_button'
text_color = 'color_alternative_inverted'
vertical_align = 'center'
horizontal_align = 'center'
/>
<drawstep func = 'square'
fill = 'foreground'
fg_color = 'green'
/>
</drawdata>
<drawdata id = 'button_idle' cache = 'false'> <drawdata id = 'button_idle' cache = 'false'>
<text font = 'text_button' <text font = 'text_button'
text_color = 'color_button' text_color = 'color_button'

Binary file not shown.

View file

@ -1 +1 @@
[SCUMMVM_STX0.8.11:ScummVM Modern Theme:No Author] [SCUMMVM_STX0.8.12:ScummVM Modern Theme:No Author]

View file

@ -740,6 +740,27 @@
/> />
</drawdata> </drawdata>
<!-- Pressed button -->
<drawdata id = 'button_pressed' cache = 'false'>
<text font = 'text_button'
text_color = 'color_button'
vertical_align = 'center'
horizontal_align = 'center'
/>
<drawstep func = 'roundedsq'
radius = '5'
stroke = '1'
fill = 'foreground'
shadow = '0'
factor = '0'
fg_color = '120, 40, 16'
gradient_start = '255, 0, 0'
gradient_end = '255, 0, 0'
bevel = '1'
bevel_color = 'black'
/>
</drawdata>
<!-- Idle button --> <!-- Idle button -->
<drawdata id = 'button_idle' cache = 'false'> <drawdata id = 'button_idle' cache = 'false'>
<text font = 'text_button' <text font = 'text_button'

View file

@ -30,6 +30,8 @@
#include "gui/ThemeEval.h" #include "gui/ThemeEval.h"
#include "gui/dialog.h"
namespace GUI { namespace GUI {
Widget::Widget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip) Widget::Widget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip)
@ -77,6 +79,8 @@ void Widget::updateState(int oldFlags, int newFlags) {
_state = ThemeEngine::kStateEnabled; _state = ThemeEngine::kStateEnabled;
if (newFlags & WIDGET_HILITED) if (newFlags & WIDGET_HILITED)
_state = ThemeEngine::kStateHighlight; _state = ThemeEngine::kStateHighlight;
if (newFlags & WIDGET_PRESSED)
_state = ThemeEngine::kStatePressed;
} else { } else {
_state = ThemeEngine::kStateDisabled; _state = ThemeEngine::kStateDisabled;
} }
@ -272,27 +276,33 @@ void StaticTextWidget::drawWidget() {
ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey) ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey)
: StaticTextWidget(boss, x, y, w, h, cleanupHotkey(label), Graphics::kTextAlignCenter, tooltip), CommandSender(boss), : StaticTextWidget(boss, x, y, w, h, cleanupHotkey(label), Graphics::kTextAlignCenter, tooltip), CommandSender(boss),
_cmd(cmd), _hotkey(hotkey) { _cmd(cmd), _hotkey(hotkey), _lastTime(0) {
if (hotkey == 0) if (hotkey == 0)
_hotkey = parseHotkey(label); _hotkey = parseHotkey(label);
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG); setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG | WIDGET_WANT_TICKLE);
_type = kButtonWidget; _type = kButtonWidget;
} }
ButtonWidget::ButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey) ButtonWidget::ButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey)
: StaticTextWidget(boss, name, cleanupHotkey(label), tooltip), CommandSender(boss), : StaticTextWidget(boss, name, cleanupHotkey(label), tooltip), CommandSender(boss),
_cmd(cmd) { _cmd(cmd), _lastTime(0) {
if (hotkey == 0) if (hotkey == 0)
_hotkey = parseHotkey(label); _hotkey = parseHotkey(label);
setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG); setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG | WIDGET_WANT_TICKLE);
_type = kButtonWidget; _type = kButtonWidget;
} }
void ButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) { void ButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) {
if (isEnabled() && x >= 0 && x < _w && y >= 0 && y < _h) if (isEnabled() && x >= 0 && x < _w && y >= 0 && y < _h) {
sendCommand(_cmd, 0); sendCommand(_cmd, 0);
startAnimatePressedState();
}
}
void ButtonWidget::handleMouseDown(int x, int y, int button, int clickCount) {
setPressedState();
} }
void ButtonWidget::drawWidget() { void ButtonWidget::drawWidget() {
@ -324,6 +334,44 @@ ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32
return button; 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 - #pragma mark -
PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey) PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey)

View file

@ -38,6 +38,7 @@ enum {
WIDGET_INVISIBLE = 1 << 1, WIDGET_INVISIBLE = 1 << 1,
WIDGET_HILITED = 1 << 2, WIDGET_HILITED = 1 << 2,
WIDGET_BORDER = 1 << 3, WIDGET_BORDER = 1 << 3,
WIDGET_PRESSED = 1 << 4,
//WIDGET_INV_BORDER = 1 << 4, //WIDGET_INV_BORDER = 1 << 4,
WIDGET_CLEARBG = 1 << 5, WIDGET_CLEARBG = 1 << 5,
WIDGET_WANT_TICKLE = 1 << 7, WIDGET_WANT_TICKLE = 1 << 7,
@ -73,6 +74,10 @@ enum {
kCaretBlinkTime = 300 kCaretBlinkTime = 300
}; };
enum {
kPressedButtonTime = 200
};
/* Widget */ /* Widget */
class Widget : public GuiObject { class Widget : public GuiObject {
friend class Dialog; friend class Dialog;
@ -189,11 +194,22 @@ public:
void setLabel(const Common::String &label); void setLabel(const Common::String &label);
void handleMouseUp(int x, int y, int button, int clickCount); 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 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: protected:
void drawWidget(); void drawWidget();
void wantTickle(bool tickled);
private:
uint32 _lastTime;
}; };
/* PicButtonWidget */ /* PicButtonWidget */