mirror of
https://github.com/libretro/scummvm.git
synced 2024-11-30 21:00:39 +00:00
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
This commit is contained in:
parent
0e5aa06db0
commit
d6695e180c
@ -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();
|
||||
|
||||
_system->getTimerManager()->removeTimerProc(&tooltipCallback);
|
||||
_system->getTimerManager()->installTimerProc(&tooltipCallback, 2*1000000, this);
|
||||
_tooltipCheck = false;
|
||||
_tooltip->tooltipModal(_lastMousePosition.x, _lastMousePosition.y);
|
||||
}
|
||||
|
||||
if (eventTookplace && _tooltip) {
|
||||
_tooltip->mustClose();
|
||||
}
|
||||
|
||||
// Delay for a moment
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -61,6 +61,7 @@ enum DrawData {
|
||||
kDDMainDialogBackground,
|
||||
kDDSpecialColorBackground,
|
||||
kDDPlainColorBackground,
|
||||
kDDTooltipBackground,
|
||||
kDDDefaultBackground,
|
||||
kDDTextSelectionBackground,
|
||||
kDDTextSelectionFocusBackground,
|
||||
@ -162,6 +163,7 @@ public:
|
||||
kDialogBackgroundMain,
|
||||
kDialogBackgroundSpecial,
|
||||
kDialogBackgroundPlain,
|
||||
kDialogBackgroundTooltip,
|
||||
kDialogBackgroundDefault
|
||||
};
|
||||
|
||||
|
101
gui/Tooltip.cpp
Normal file
101
gui/Tooltip.cpp
Normal file
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
50
gui/Tooltip.h
Normal file
50
gui/Tooltip.h
Normal file
@ -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
|
@ -25,6 +25,7 @@ MODULE_OBJS := \
|
||||
ThemeEval.o \
|
||||
ThemeLayout.o \
|
||||
ThemeParser.o \
|
||||
Tooltip.o \
|
||||
widget.o
|
||||
|
||||
ifdef MACOSX
|
||||
|
@ -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' "
|
||||
|
Binary file not shown.
@ -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'
|
||||
|
Binary file not shown.
@ -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'
|
||||
|
@ -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);
|
||||
|
25
gui/widget.h
25
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:
|
||||
|
Loading…
Reference in New Issue
Block a user