diff options
author | Eugene Sandulenko | 2010-07-23 19:36:47 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2010-07-23 19:36:47 +0000 |
commit | d6695e180cfedb723a670d94d8ed132ed896498d (patch) | |
tree | 488fc9682e3c448fc29d2d98cba7b51b4efe9151 /gui | |
parent | 0e5aa06db03e782137a40942b1d5fe97dfbcfad0 (diff) | |
download | scummvm-rg350-d6695e180cfedb723a670d94d8ed132ed896498d.tar.gz scummvm-rg350-d6695e180cfedb723a670d94d8ed132ed896498d.tar.bz2 scummvm-rg350-d6695e180cfedb723a670d94d8ed132ed896498d.zip |
GUI: Fix tooltip drawing
With help of Tanoku tooltips were switched from widgets to dialogs
which helped to fix nasty bug with background not being restored.
Although it is basically a hack around inconsistent font backbuffering
in our GUI code, for the time being it is feasible.
The patch was extended with way to specify tooltip background in the
theme file.
svn-id: r51217
Diffstat (limited to 'gui')
-rw-r--r-- | gui/GuiManager.cpp | 36 | ||||
-rw-r--r-- | gui/GuiManager.h | 6 | ||||
-rw-r--r-- | gui/ThemeEngine.cpp | 5 | ||||
-rw-r--r-- | gui/ThemeEngine.h | 2 | ||||
-rw-r--r-- | gui/Tooltip.cpp | 101 | ||||
-rw-r--r-- | gui/Tooltip.h | 50 | ||||
-rw-r--r-- | gui/module.mk | 1 | ||||
-rw-r--r-- | gui/themes/default.inc | 7 | ||||
-rw-r--r-- | gui/themes/scummclassic.zip | bin | 56900 -> 57060 bytes | |||
-rw-r--r-- | gui/themes/scummclassic/classic_gfx.stx | 8 | ||||
-rw-r--r-- | gui/themes/scummmodern.zip | bin | 164185 -> 164369 bytes | |||
-rw-r--r-- | gui/themes/scummmodern/scummmodern_gfx.stx | 9 | ||||
-rw-r--r-- | gui/widget.cpp | 77 | ||||
-rw-r--r-- | gui/widget.h | 25 |
14 files changed, 207 insertions, 120 deletions
diff --git a/gui/GuiManager.cpp b/gui/GuiManager.cpp index ff747c6e92..ab370425ab 100644 --- a/gui/GuiManager.cpp +++ b/gui/GuiManager.cpp @@ -45,11 +45,12 @@ namespace GUI { enum { kDoubleClickDelay = 500, // milliseconds - kCursorAnimateDelay = 250 + kCursorAnimateDelay = 250, + kTooltipDelay = 1250 }; // Constructor -GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), +GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), _tooltipCheck(false), _stateIsSaved(false), _cursorAnimateCounter(0), _cursorAnimateTimer(0) { _theme = 0; _useStdCursor = false; @@ -77,7 +78,7 @@ GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), } } - _tooltip = new Tooltip(this); + _tooltip = 0; } GuiManager::~GuiManager() { @@ -224,13 +225,6 @@ Dialog *GuiManager::getTopDialog() const { return _dialogStack.top(); } -static void tooltipCallback(void *ref) { - GuiManager *guiManager = (GuiManager *)ref; - - guiManager->getTooltip()->setVisible(true); - g_system->getTimerManager()->removeTimerProc(&tooltipCallback); -} - void GuiManager::runLoop() { Dialog *activeDialog = getTopDialog(); bool didSaveState = false; @@ -321,7 +315,14 @@ void GuiManager::runLoop() { break; case Common::EVENT_MOUSEMOVE: activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); - _tooltip->setMouseXY(mouse.x, mouse.y); + + if (mouse.x != _lastMousePosition.x || mouse.y != _lastMousePosition.y) { + _lastMousePosition.x = mouse.x; + _lastMousePosition.y = mouse.y; + _lastMousePosition.time = _system->getMillis(); + } + + _tooltipCheck = true; eventTookplace = true; break; // We don't distinguish between mousebuttons (for now at least) @@ -367,11 +368,16 @@ void GuiManager::runLoop() { } } - if (eventTookplace) { - _tooltip->setVisible(false); + if (_tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis()) { + if (_tooltip == 0) + _tooltip = new Tooltip(); + + _tooltipCheck = false; + _tooltip->tooltipModal(_lastMousePosition.x, _lastMousePosition.y); + } - _system->getTimerManager()->removeTimerProc(&tooltipCallback); - _system->getTimerManager()->installTimerProc(&tooltipCallback, 2*1000000, this); + if (eventTookplace && _tooltip) { + _tooltip->mustClose(); } // Delay for a moment diff --git a/gui/GuiManager.h b/gui/GuiManager.h index 2a187a92f9..ee1351dc9b 100644 --- a/gui/GuiManager.h +++ b/gui/GuiManager.h @@ -33,6 +33,7 @@ #include "graphics/font.h" #include "gui/widget.h" +#include "gui/Tooltip.h" #include "gui/ThemeEngine.h" class OSystem; @@ -93,8 +94,6 @@ public: */ bool checkScreenChange(); - Tooltip *getTooltip() { return _tooltip; } - protected: enum RedrawStatus { kRedrawDisabled = 0, @@ -119,13 +118,14 @@ protected: bool _useStdCursor; Tooltip *_tooltip; + bool _tooltipCheck; // position and time of last mouse click (used to detect double clicks) struct { int16 x, y; // Position of mouse when the click occurred uint32 time; // Time int count; // How often was it already pressed? - } _lastClick; + } _lastClick, _lastMousePosition; // mouse cursor state int _cursorAnimateCounter; diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp index 6c2d8f1f7f..874df9e947 100644 --- a/gui/ThemeEngine.cpp +++ b/gui/ThemeEngine.cpp @@ -165,6 +165,7 @@ static const DrawDataInfo kDrawDataDefaults[] = { {kDDMainDialogBackground, "mainmenu_bg", true, kDDNone}, {kDDSpecialColorBackground, "special_bg", true, kDDNone}, {kDDPlainColorBackground, "plain_bg", true, kDDNone}, + {kDDTooltipBackground, "tooltip_bg", true, kDDNone}, {kDDDefaultBackground, "default_bg", true, kDDNone}, {kDDTextSelectionBackground, "text_selection", false, kDDNone}, {kDDTextSelectionFocusBackground, "text_selection_focus", false, kDDNone}, @@ -984,6 +985,10 @@ void ThemeEngine::drawDialogBackground(const Common::Rect &r, DialogBackground b queueDD(kDDPlainColorBackground, r); break; + case kDialogBackgroundTooltip: + queueDD(kDDTooltipBackground, r); + break; + case kDialogBackgroundDefault: queueDD(kDDDefaultBackground, r); break; diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index 3173aa4aca..f736559def 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -61,6 +61,7 @@ enum DrawData { kDDMainDialogBackground, kDDSpecialColorBackground, kDDPlainColorBackground, + kDDTooltipBackground, kDDDefaultBackground, kDDTextSelectionBackground, kDDTextSelectionFocusBackground, @@ -162,6 +163,7 @@ public: kDialogBackgroundMain, kDialogBackgroundSpecial, kDialogBackgroundPlain, + kDialogBackgroundTooltip, kDialogBackgroundDefault }; diff --git a/gui/Tooltip.cpp b/gui/Tooltip.cpp new file mode 100644 index 0000000000..64c34688df --- /dev/null +++ b/gui/Tooltip.cpp @@ -0,0 +1,101 @@ +/* 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. + * + * $URL$ + * $Id$ + */ + +#include "common/util.h" +#include "graphics/fontman.h" +#include "gui/widget.h" +#include "gui/dialog.h" +#include "gui/GuiManager.h" + +#include "gui/Tooltip.h" +#include "gui/ThemeEval.h" + +namespace GUI { + + +Tooltip::Tooltip() : + Dialog(-1, -1, -1, -1), _maxWidth(-1) { + + _backgroundType = GUI::ThemeEngine::kDialogBackgroundTooltip; +} + +void Tooltip::mustClose() { + if (isVisible()) + Dialog::close(); +} + +bool Tooltip::tooltipModal(int x, int y) { + Widget *wdg; + + if (!g_gui.getTopDialog()) + return false; + + wdg = g_gui.getTopDialog()->findWidget(x, y); + + if (!wdg || !wdg->getTooltip()) + return false; + + if (_maxWidth == -1) { + _maxWidth = g_gui.xmlEval()->getVar("Globals.Tooltip.MaxWidth", 100); + _xdelta = g_gui.xmlEval()->getVar("Globals.Tooltip.XDelta", 0); + _ydelta = g_gui.xmlEval()->getVar("Globals.Tooltip.YDelta", 0); + } + + const Graphics::Font *tooltipFont = g_gui.theme()->getFont(ThemeEngine::kFontStyleTooltip); + + _wrappedLines.clear(); + _w = tooltipFont->wordWrapText(wdg->getTooltip(), _maxWidth - 4, _wrappedLines); + _h = (tooltipFont->getFontHeight() + 2) * _wrappedLines.size(); + + _x = MIN<int16>(g_gui.getTopDialog()->_x + x + _xdelta, g_gui.getWidth() - _w - 3); + _y = MIN<int16>(g_gui.getTopDialog()->_y + y + _ydelta, g_gui.getHeight() - _h - 3); + + open(); + g_gui.runLoop(); + + return true; +} + +void Tooltip::drawDialog() { + int num = 0; + int h = g_gui.theme()->getFontHeight(ThemeEngine::kFontStyleTooltip) + 2; + + Dialog::drawDialog(); + + for (Common::StringArray::const_iterator i = _wrappedLines.begin(); i != _wrappedLines.end(); ++i, ++num) { + g_gui.theme()->drawText( + Common::Rect(_x + 1, _y + 1 + num * h, _x + 1 +_w, _y + 1+ (num + 1) * h), *i, + ThemeEngine::kStateEnabled, + Graphics::kTextAlignLeft, + ThemeEngine::kTextInversionNone, + 0, + false, + ThemeEngine::kFontStyleTooltip, + ThemeEngine::kFontColorNormal, + false + ); + } +} + +} diff --git a/gui/Tooltip.h b/gui/Tooltip.h new file mode 100644 index 0000000000..60f3cf3a19 --- /dev/null +++ b/gui/Tooltip.h @@ -0,0 +1,50 @@ +/* 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. + * + * $URL$ + * $Id$ + */ + +#ifndef GUI_TOOLTIP_H +#define GUI_TOOLTIP_H + +#include "gui/dialog.h" + +namespace GUI { + +class Tooltip : public Dialog { +public: + Tooltip(); + ~Tooltip() {} + + void drawDialog(); + bool tooltipModal(int x, int y); + void mustClose(); + +protected: + Common::String _text; + int _maxWidth; + int _xdelta, _ydelta; + + Common::StringArray _wrappedLines; +}; +} + +#endif diff --git a/gui/module.mk b/gui/module.mk index 9bf1a08d4b..72b5fa18f3 100644 --- a/gui/module.mk +++ b/gui/module.mk @@ -25,6 +25,7 @@ MODULE_OBJS := \ ThemeEval.o \ ThemeLayout.o \ ThemeParser.o \ + Tooltip.o \ widget.o ifdef MACOSX diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 086fecc123..915ec55dca 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -877,6 +877,13 @@ "bevel='2' " "/> " "</drawdata> " +"<drawdata id='tooltip_bg' cache='false'> " +"<drawstep func='bevelsq' " +"bevel='2' " +"fill='foreground' " +"fg_color='black' " +"/> " +"</drawdata> " "<drawdata id='separator' cache='false'> " "<drawstep func='square' " "fill='foreground' " diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip Binary files differindex b5866337ad..4a31a8ebb9 100644 --- a/gui/themes/scummclassic.zip +++ b/gui/themes/scummclassic.zip diff --git a/gui/themes/scummclassic/classic_gfx.stx b/gui/themes/scummclassic/classic_gfx.stx index 8c03aa932c..d672db2540 100644 --- a/gui/themes/scummclassic/classic_gfx.stx +++ b/gui/themes/scummclassic/classic_gfx.stx @@ -142,6 +142,14 @@ /> </drawdata> + <drawdata id = 'tooltip_bg' cache = 'false'> + <drawstep func = 'bevelsq' + bevel = '2' + fill = 'foreground' + fg_color = 'black' + /> + </drawdata> + <drawdata id = 'separator' cache = 'false'> <drawstep func = 'square' fill = 'foreground' diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip Binary files differindex aba0c944c3..b5e8f24019 100644 --- a/gui/themes/scummmodern.zip +++ b/gui/themes/scummmodern.zip diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx index ad41475a96..cfe00a7016 100644 --- a/gui/themes/scummmodern/scummmodern_gfx.stx +++ b/gui/themes/scummmodern/scummmodern_gfx.stx @@ -516,6 +516,15 @@ /> </drawdata> + <!-- Tooltip --> + <drawdata id = 'tooltip_bg' cache = 'false'> + <drawstep func = 'square' + fill = 'foreground' + fg_color = 'blandyellow' + shadow = '3' + /> + </drawdata> + <!-- Idle button --> <drawdata id = 'button_idle' cache = 'false'> <text font = 'text_button' diff --git a/gui/widget.cpp b/gui/widget.cpp index 6dd79c9d4f..07cf4407a2 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -224,83 +224,6 @@ Common::String Widget::cleanupHotkey(const Common::String &label) { #pragma mark - -Tooltip::Tooltip(GuiManager *guiManager) : GuiObject(0, 0, 0, 0) { - _guiManager = guiManager; - - _visible = false; - _maxWidth = -1; - _storedState = 0; -} - -void Tooltip::draw() { - int num = 0; - int h = g_gui.theme()->getFontHeight(ThemeEngine::kFontStyleTooltip) + 2; - - // Make Rect bigger for compensating the shadow - _storedState = g_gui.theme()->storeState(Common::Rect(_x - 5, _y - 5, _x + _w + 5, _y + _h + 5)); - - g_gui.theme()->startBuffering(); - g_gui.theme()->drawWidgetBackground(Common::Rect(_x, _y, _x + _w, _y + _h), 0, ThemeEngine::kWidgetBackgroundBorderSmall); - - for (Common::StringArray::const_iterator i = _wrappedLines.begin(); i != _wrappedLines.end(); ++i, ++num) { - g_gui.theme()->drawText(Common::Rect(_x + 1, _y + 1 + num * h, _x + 1 +_w, _y + 1+ (num + 1) * h), *i, ThemeEngine::kStateEnabled, Graphics::kTextAlignLeft, ThemeEngine::kTextInversionNone, 0, false, ThemeEngine::kFontStyleTooltip, ThemeEngine::kFontColorNormal, false); - } - g_gui.theme()->finishBuffering(); -} - -void Tooltip::reflowLayout() { -} - -void Tooltip::setMouseXY(int x, int y) { - _mouseX = x; - _mouseY = y; -} - -void Tooltip::setVisible(bool state) { - if (state == _visible) - return; - - if (state) { - if (!_guiManager->getTopDialog()) - return; - - Widget *wdg = _guiManager->getTopDialog()->findWidget(_mouseX, _mouseY); - - if (!wdg) - return; - - if (wdg->getTooltip()) { - _visible = state; - - // Cache config values. - // NOTE: we cannot do it in the consturctor - if (_maxWidth == -1) { - _maxWidth = g_gui.xmlEval()->getVar("Globals.Tooltip.MaxWidth", 100); - _xdelta = g_gui.xmlEval()->getVar("Globals.Tooltip.XDelta", 0); - _ydelta = g_gui.xmlEval()->getVar("Globals.Tooltip.YDelta", 0); - } - - const Graphics::Font *tooltipFont = g_gui.theme()->getFont(ThemeEngine::kFontStyleTooltip); - - _wrappedLines.clear(); - _w = tooltipFont->wordWrapText(wdg->getTooltip(), _maxWidth - 4, _wrappedLines); - _h = (tooltipFont->getFontHeight() + 2) * _wrappedLines.size(); - - _x = MIN<int16>(_guiManager->getTopDialog()->_x + _mouseX + _xdelta, g_gui.getWidth() - _w - 3); - _y = MIN<int16>(_guiManager->getTopDialog()->_y + _mouseY + _ydelta, g_gui.getHeight() - _h - 3); - - draw(); - } - } else { - _visible = state; - - g_gui.theme()->restoreState(_storedState); - delete _storedState; - } -} - -#pragma mark - - StaticTextWidget::StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &text, Graphics::TextAlign align, const char *tooltip) : Widget(boss, x, y, w, h, tooltip), _align(align) { setFlags(WIDGET_ENABLED); diff --git a/gui/widget.h b/gui/widget.h index 25e4b9a235..92bfbf8256 100644 --- a/gui/widget.h +++ b/gui/widget.h @@ -159,31 +159,6 @@ protected: void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { assert(_boss); _boss->handleCommand(sender, cmd, data); } }; -class GuiManager; - -class Tooltip : public GuiObject { -public: - Tooltip(GuiManager *guiManager); - - bool isVisible() const { return _visible; } - void draw(); - void reflowLayout(); - void releaseFocus() {} - void setVisible(bool state); - void setMouseXY(int x, int y); - -protected: - Common::String _text; - GuiManager *_guiManager; - bool _visible; - int _mouseX, _mouseY; - int _maxWidth; - int _xdelta, _ydelta; - - Common::StringArray _wrappedLines; - ThemeEngine::StoredState *_storedState; -}; - /* StaticTextWidget */ class StaticTextWidget : public Widget { protected: |