aboutsummaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
Diffstat (limited to 'gui')
-rw-r--r--gui/GuiManager.cpp31
-rw-r--r--gui/GuiManager.h6
-rw-r--r--gui/PopUpWidget.cpp4
-rw-r--r--gui/PopUpWidget.h2
-rw-r--r--gui/TabWidget.cpp4
-rw-r--r--gui/ThemeEngine.cpp72
-rw-r--r--gui/ThemeEngine.h19
-rw-r--r--gui/ThemeParser.cpp3
-rw-r--r--gui/browser.cpp6
-rw-r--r--gui/chooser.cpp4
-rw-r--r--gui/dialog.h1
-rw-r--r--gui/launcher.cpp38
-rw-r--r--gui/massadd.cpp4
-rw-r--r--gui/message.cpp4
-rw-r--r--gui/options.cpp32
-rw-r--r--gui/saveload.cpp6
-rw-r--r--gui/themebrowser.cpp4
-rw-r--r--gui/themes/default.inc14
-rw-r--r--gui/themes/scummclassic.zipbin55147 -> 55660 bytes
-rw-r--r--gui/themes/scummclassic/classic_gfx.stx9
-rw-r--r--gui/themes/scummclassic/classic_layout.stx4
-rw-r--r--gui/themes/scummclassic/classic_layout_lowres.stx4
-rw-r--r--gui/themes/scummmodern.zipbin162581 -> 162933 bytes
-rw-r--r--gui/themes/scummmodern/scummmodern_gfx.stx7
-rw-r--r--gui/themes/scummmodern/scummmodern_layout.stx4
-rw-r--r--gui/themes/scummmodern/scummmodern_layout_lowres.stx4
-rw-r--r--gui/widget.cpp129
-rw-r--r--gui/widget.h57
28 files changed, 361 insertions, 111 deletions
diff --git a/gui/GuiManager.cpp b/gui/GuiManager.cpp
index 9f04c382cb..49c078a723 100644
--- a/gui/GuiManager.cpp
+++ b/gui/GuiManager.cpp
@@ -27,6 +27,7 @@
#include "common/util.h"
#include "common/config-manager.h"
#include "common/algorithm.h"
+#include "common/timer.h"
#include "common/translation.h"
#include "backends/keymapper/keymapper.h"
@@ -49,7 +50,7 @@ enum {
// Constructor
GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled),
- _stateIsSaved(false), _cursorAnimateCounter(0), _cursorAnimateTimer(0) {
+ _stateIsSaved(false), _cursorAnimateCounter(0), _cursorAnimateTimer(0) {
_theme = 0;
_useStdCursor = false;
@@ -75,10 +76,13 @@ GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled),
error(_t("Failed to load any GUI theme, aborting"));
}
}
+
+ _tooltip = new Tooltip(this);
}
GuiManager::~GuiManager() {
delete _theme;
+ delete _tooltip;
}
#ifdef ENABLE_KEYMAPPER
@@ -220,6 +224,13 @@ 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;
@@ -278,6 +289,8 @@ void GuiManager::runLoop() {
}
Common::Event event;
+
+ bool eventTookplace = false;
while (eventMan->pollEvent(event)) {
// The top dialog can change during the event loop. In that case, flush all the
@@ -300,16 +313,21 @@ void GuiManager::runLoop() {
switch (event.type) {
case Common::EVENT_KEYDOWN:
activeDialog->handleKeyDown(event.kbd);
+ eventTookplace = true;
break;
case Common::EVENT_KEYUP:
activeDialog->handleKeyUp(event.kbd);
+ eventTookplace = true;
break;
case Common::EVENT_MOUSEMOVE:
activeDialog->handleMouseMoved(mouse.x, mouse.y, 0);
+ _tooltip->setMouseXY(mouse.x, mouse.y);
+ eventTookplace = true;
break;
// We don't distinguish between mousebuttons (for now at least)
case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_RBUTTONDOWN:
+ eventTookplace = true;
button = (event.type == Common::EVENT_LBUTTONDOWN ? 1 : 2);
time = _system->getMillis();
if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay)
@@ -326,18 +344,22 @@ void GuiManager::runLoop() {
break;
case Common::EVENT_LBUTTONUP:
case Common::EVENT_RBUTTONUP:
+ eventTookplace = true;
button = (event.type == Common::EVENT_LBUTTONUP ? 1 : 2);
activeDialog->handleMouseUp(mouse.x, mouse.y, button, _lastClick.count);
break;
case Common::EVENT_WHEELUP:
+ eventTookplace = true;
activeDialog->handleMouseWheel(mouse.x, mouse.y, -1);
break;
case Common::EVENT_WHEELDOWN:
+ eventTookplace = true;
activeDialog->handleMouseWheel(mouse.x, mouse.y, 1);
break;
case Common::EVENT_QUIT:
return;
case Common::EVENT_SCREEN_CHANGED:
+ eventTookplace = true;
screenChange();
break;
default:
@@ -345,6 +367,13 @@ void GuiManager::runLoop() {
}
}
+ if (eventTookplace) {
+ _tooltip->setVisible(false);
+
+ _system->getTimerManager()->removeTimerProc(&tooltipCallback);
+ _system->getTimerManager()->installTimerProc(&tooltipCallback, 2*1000000, this);
+ }
+
// Delay for a moment
_system->delayMillis(10);
}
diff --git a/gui/GuiManager.h b/gui/GuiManager.h
index 3187a0ba73..2591838416 100644
--- a/gui/GuiManager.h
+++ b/gui/GuiManager.h
@@ -60,6 +60,7 @@ typedef Common::FixedStack<Dialog *> DialogStack;
*/
class GuiManager : public Common::Singleton<GuiManager> {
friend class Dialog;
+ friend class Tooltip;
friend class Common::Singleton<SingletonBaseType>;
GuiManager();
~GuiManager();
@@ -91,6 +92,9 @@ public:
* @return true if the a screen change indeed occurred, false otherwise
*/
bool checkScreenChange();
+
+ Tooltip *getTooltip() { return _tooltip; }
+
protected:
enum RedrawStatus {
kRedrawDisabled = 0,
@@ -114,6 +118,8 @@ protected:
bool _useStdCursor;
+ Tooltip *_tooltip;
+
// position and time of last mouse click (used to detect double clicks)
struct {
int16 x, y; // Position of mouse when the click occured
diff --git a/gui/PopUpWidget.cpp b/gui/PopUpWidget.cpp
index 7463399e0b..1bd9cc5063 100644
--- a/gui/PopUpWidget.cpp
+++ b/gui/PopUpWidget.cpp
@@ -378,8 +378,8 @@ void PopUpDialog::drawMenuEntry(int entry, bool hilite) {
// PopUpWidget
//
-PopUpWidget::PopUpWidget(GuiObject *boss, const String &name)
- : Widget(boss, name), CommandSender(boss) {
+PopUpWidget::PopUpWidget(GuiObject *boss, const String &name, const char *tooltip)
+ : Widget(boss, name, tooltip), CommandSender(boss) {
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_IGNORE_DRAG);
_type = kPopUpWidget;
diff --git a/gui/PopUpWidget.h b/gui/PopUpWidget.h
index bd1d3b3918..d1c89e45ae 100644
--- a/gui/PopUpWidget.h
+++ b/gui/PopUpWidget.h
@@ -59,7 +59,7 @@ protected:
int _rightPadding;
public:
- PopUpWidget(GuiObject *boss, const String &name);
+ PopUpWidget(GuiObject *boss, const String &name, const char *tooltip = 0);
void handleMouseDown(int x, int y, int button, int clickCount);
void handleMouseWheel(int x, int y, int direction);
diff --git a/gui/TabWidget.cpp b/gui/TabWidget.cpp
index 275e3613b5..ca409e50ab 100644
--- a/gui/TabWidget.cpp
+++ b/gui/TabWidget.cpp
@@ -68,8 +68,8 @@ void TabWidget::init() {
int x = _w - _butRP - _butW * 2 - 2;
int y = _butTP - _tabHeight;
- _navLeft = new ButtonWidget(this, x, y, _butW, _butH, "<", kCmdLeft);
- _navRight = new ButtonWidget(this, x + _butW + 2, y, _butW, _butH, ">", kCmdRight);
+ _navLeft = new ButtonWidget(this, x, y, _butW, _butH, "<", 0, kCmdLeft);
+ _navRight = new ButtonWidget(this, x + _butW + 2, y, _butW, _butH, ">", 0, kCmdRight);
}
TabWidget::~TabWidget() {
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 5bde44d792..8f4f767a94 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -1070,7 +1070,7 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co
}
}
-void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font, FontColor color) {
+void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, Graphics::TextAlign align, TextInversionState inverted, int deltax, bool useEllipsis, FontStyle font, FontColor color, bool restore) {
if (!ready())
return;
@@ -1121,13 +1121,7 @@ void ThemeEngine::drawText(const Common::Rect &r, const Common::String &str, Wid
return;
}
- TextData textId = kTextDataNone;
- if (font == kFontStyleNormal)
- textId = kTextDataNormalFont;
- else
- textId = kTextDataDefault;
-
- bool restore = true;
+ TextData textId = fontStyleToData(font);
switch (inverted) {
case kTextInversion:
@@ -1169,7 +1163,69 @@ void ThemeEngine::debugWidgetPosition(const char *name, const Common::Rect &r) {
_screen.vLine(r.right, r.top, r.bottom, 0xFFFF);
}
+ThemeEngine::StoredState *ThemeEngine::storeState(const Common::Rect &r) {
+ StoredState *state = new StoredState;
+ byte *dst;
+ byte *src;
+
+ state->r.top = r.top;
+ state->r.bottom = r.bottom;
+ state->r.left = r.left;
+ state->r.right = r.right;
+
+ state->r.clip(_screen.w, _screen.h);
+ state->screen.create(state->r.width(), state->r.height(), _screen.bytesPerPixel);
+ state->backBuffer.create(state->r.width(), state->r.height(), _backBuffer.bytesPerPixel);
+
+ src = (byte *)_screen.getBasePtr(state->r.left, state->r.top);
+ dst = (byte *)state->screen.getBasePtr(0, 0);
+
+ for (int i = state->r.height(); i > 0; i--) {
+ memcpy(dst, src, state->r.width() * _screen.bytesPerPixel);
+ src += _screen.pitch;
+ dst += state->screen.pitch;
+ }
+
+ src = (byte *)_backBuffer.getBasePtr(state->r.left, state->r.top);
+ dst = (byte *)state->backBuffer.getBasePtr(0, 0);
+
+ for (int i = state->r.height(); i > 0; i--) {
+ memcpy(dst, src, state->r.width() * _backBuffer.bytesPerPixel);
+ src += _backBuffer.pitch;
+ dst += state->backBuffer.pitch;
+ }
+
+ return state;
+}
+
+void ThemeEngine::restoreState(StoredState *state) {
+ byte *dst;
+ byte *src;
+
+ if (!state)
+ return;
+
+ src = (byte *)state->screen.getBasePtr(0, 0);
+ dst = (byte *)_screen.getBasePtr(state->r.left, state->r.top);
+
+ for (int i = state->r.height(); i > 0; i--) {
+ memcpy(dst, src, state->r.width() * _screen.bytesPerPixel);
+ src += state->screen.pitch;
+ dst += _screen.pitch;
+ }
+
+ src = (byte *)state->backBuffer.getBasePtr(0, 0);
+ dst = (byte *)_backBuffer.getBasePtr(state->r.left, state->r.top);
+
+ for (int i = state->r.height(); i > 0; i--) {
+ memcpy(dst, src, state->r.width() * _backBuffer.bytesPerPixel);
+ src += state->backBuffer.pitch;
+ dst += _backBuffer.pitch;
+ }
+
+ addDirtyRect(state->r);
+}
/**********************************************************
* Screen/overlay management
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 2ef6fe3781..5f474f1a88 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -112,6 +112,7 @@ enum TextData {
kTextDataDefault = 0,
kTextDataButton,
kTextDataNormalFont,
+ kTextDataTooltip,
kTextDataMAX
};
@@ -177,7 +178,7 @@ public:
enum TextInversionState {
kTextInversionNone, ///< Indicates that the text should not be drawn inverted
kTextInversion, ///< Indicates that the text should be drawn inverted, but not focused
- kTextInversionFocus ///< Indicates thte the test should be drawn inverted, and focused
+ kTextInversionFocus ///< Indicates that the text should be drawn inverted, and focused
};
enum ScrollbarState {
@@ -196,6 +197,7 @@ public:
kFontStyleFixedNormal = 3, ///< Fixed size font.
kFontStyleFixedBold = 4, ///< Fixed size bold font.
kFontStyleFixedItalic = 5, ///< Fixed size italic font.
+ kFontStyleTooltip = 6, ///< Tiny console font
kFontStyleMax
};
@@ -259,6 +261,17 @@ public:
void enable();
void disable();
+ struct StoredState {
+ Common::Rect r;
+ Graphics::Surface screen;
+ Graphics::Surface backBuffer;
+
+ StoredState() {}
+ };
+
+ StoredState *storeState(const Common::Rect &r);
+ void restoreState(StoredState *state);
+
/**
* Implementation of the GUI::Theme API. Called when a
* new dialog is opened. Note that the boolean parameter
@@ -284,6 +297,8 @@ public:
TextData fontStyleToData(FontStyle font) const {
if (font == kFontStyleNormal)
return kTextDataNormalFont;
+ if (font == kFontStyleTooltip)
+ return kTextDataTooltip;
return kTextDataDefault;
}
@@ -336,7 +351,7 @@ public:
void drawDialogBackground(const Common::Rect &r, DialogBackground type, WidgetStateInfo state = kStateEnabled);
- void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal);
+ void drawText(const Common::Rect &r, const Common::String &str, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignCenter, TextInversionState inverted = kTextInversionNone, int deltax = 0, bool useEllipsis = true, FontStyle font = kFontStyleBold, FontColor color = kFontColorNormal, bool restore = true);
void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state = kStateEnabled, FontColor color = kFontColorNormal);
diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp
index e22d440bd9..4cabf6ad2e 100644
--- a/gui/ThemeParser.cpp
+++ b/gui/ThemeParser.cpp
@@ -42,7 +42,8 @@ struct TextDataInfo {
static const TextDataInfo kTextDataDefaults[] = {
{ kTextDataDefault, "text_default" },
{ kTextDataButton, "text_button" },
- { kTextDataNormalFont, "text_normal" }
+ { kTextDataNormalFont, "text_normal" },
+ { kTextDataTooltip, "tooltip_normal" }
};
diff --git a/gui/browser.cpp b/gui/browser.cpp
index 000359e1e7..0d95e5397b 100644
--- a/gui/browser.cpp
+++ b/gui/browser.cpp
@@ -66,9 +66,9 @@ BrowserDialog::BrowserDialog(const char *title, bool dirBrowser)
_backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
// Buttons
- new ButtonWidget(this, "Browser.Up", _("Go up"), kGoUpCmd);
- new ButtonWidget(this, "Browser.Cancel", _("Cancel"), kCloseCmd);
- new ButtonWidget(this, "Browser.Choose", _("Choose"), kChooseCmd);
+ new ButtonWidget(this, "Browser.Up", _("Go up"), _("Go to previous directory level"), kGoUpCmd);
+ new ButtonWidget(this, "Browser.Cancel", _("Cancel"), 0, kCloseCmd);
+ new ButtonWidget(this, "Browser.Choose", _("Choose"), 0, kChooseCmd);
}
void BrowserDialog::open() {
diff --git a/gui/chooser.cpp b/gui/chooser.cpp
index 7039e40947..a7b453c957 100644
--- a/gui/chooser.cpp
+++ b/gui/chooser.cpp
@@ -46,8 +46,8 @@ ChooserDialog::ChooserDialog(const String &title, String dialogId)
_list->setEditable(false);
// Buttons
- new ButtonWidget(this, dialogId + ".Cancel", _("Cancel"), kCloseCmd);
- _chooseButton = new ButtonWidget(this, dialogId + ".Choose", _("Choose"), kChooseCmd);
+ new ButtonWidget(this, dialogId + ".Cancel", _("Cancel"), 0, kCloseCmd);
+ _chooseButton = new ButtonWidget(this, dialogId + ".Choose", _("Choose"), 0, kChooseCmd);
_chooseButton->setEnabled(false);
}
diff --git a/gui/dialog.h b/gui/dialog.h
index 5008f272ba..1845786044 100644
--- a/gui/dialog.h
+++ b/gui/dialog.h
@@ -44,6 +44,7 @@ enum {
class Dialog : public GuiObject {
friend class GuiManager;
+ friend class Tooltip;
protected:
Widget *_mouseWidget;
Widget *_focusedWidget;
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index b12c56dbde..829a57469b 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -202,7 +202,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
//
_graphicsTabId = tab->addTab(g_system->getOverlayWidth() > 320 ? _("Graphics") : _("GFX"));
- _globalGraphicsOverride = new CheckboxWidget(tab, "GameOptions_Graphics.EnableTabCheckbox", _("Override global graphic settings"), kCmdGlobalGraphicsOverride);
+ _globalGraphicsOverride = new CheckboxWidget(tab, "GameOptions_Graphics.EnableTabCheckbox", _("Override global graphic settings"), 0, kCmdGlobalGraphicsOverride);
addGraphicControls(tab, "GameOptions_Graphics.");
@@ -211,7 +211,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
//
tab->addTab(_("Audio"));
- _globalAudioOverride = new CheckboxWidget(tab, "GameOptions_Audio.EnableTabCheckbox", _("Override global audio settings"), kCmdGlobalAudioOverride);
+ _globalAudioOverride = new CheckboxWidget(tab, "GameOptions_Audio.EnableTabCheckbox", _("Override global audio settings"), 0, kCmdGlobalAudioOverride);
addAudioControls(tab, "GameOptions_Audio.");
addSubtitleControls(tab, "GameOptions_Audio.");
@@ -221,7 +221,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
//
tab->addTab(_("Volume"));
- _globalVolumeOverride = new CheckboxWidget(tab, "GameOptions_Volume.EnableTabCheckbox", _("Override global volume settings"), kCmdGlobalVolumeOverride);
+ _globalVolumeOverride = new CheckboxWidget(tab, "GameOptions_Volume.EnableTabCheckbox", _("Override global volume settings"), 0, kCmdGlobalVolumeOverride);
addVolumeControls(tab, "GameOptions_Volume.");
@@ -230,7 +230,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
//
tab->addTab(_("MIDI"));
- _globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _("Override global MIDI settings"), kCmdGlobalMIDIOverride);
+ _globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _("Override global MIDI settings"), 0, kCmdGlobalMIDIOverride);
if (_guioptions & Common::GUIO_NOMIDI)
_globalMIDIOverride->setEnabled(false);
@@ -246,15 +246,15 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
// in the small version of the GUI.
// GUI: Button + Label for the game path
- new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _("Game Path:"), kCmdGameBrowser);
+ new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _("Game Path:"), 0, kCmdGameBrowser);
_gamePathWidget = new StaticTextWidget(tab, "GameOptions_Paths.GamepathText", gamePath);
// GUI: Button + Label for the additional path
- new ButtonWidget(tab, "GameOptions_Paths.Extrapath", _("Extra Path:"), kCmdExtraBrowser);
+ new ButtonWidget(tab, "GameOptions_Paths.Extrapath", _("Extra Path:"), 0, kCmdExtraBrowser);
_extraPathWidget = new StaticTextWidget(tab, "GameOptions_Paths.ExtrapathText", extraPath);
// GUI: Button + Label for the save path
- new ButtonWidget(tab, "GameOptions_Paths.Savepath", _("Save Path:"), kCmdSaveBrowser);
+ new ButtonWidget(tab, "GameOptions_Paths.Savepath", _("Save Path:"), 0, kCmdSaveBrowser);
_savePathWidget = new StaticTextWidget(tab, "GameOptions_Paths.SavepathText", savePath);
// Activate the first tab
@@ -262,8 +262,8 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc)
_tabWidget = tab;
// Add OK & Cancel buttons
- new ButtonWidget(this, "GameOptions.Cancel", _("Cancel"), kCloseCmd);
- new ButtonWidget(this, "GameOptions.Ok", _("OK"), kOKCmd);
+ new ButtonWidget(this, "GameOptions.Cancel", _("Cancel"), 0, kCloseCmd);
+ new ButtonWidget(this, "GameOptions.Ok", _("OK"), 0, kOKCmd);
}
void EditGameDialog::open() {
@@ -497,36 +497,36 @@ LauncherDialog::LauncherDialog()
new StaticTextWidget(this, "Launcher.Version", gScummVMFullVersion);
#endif
- new ButtonWidget(this, "Launcher.QuitButton", _("~Q~uit"), kQuitCmd);
- new ButtonWidget(this, "Launcher.AboutButton", _("A~b~out..."), kAboutCmd);
- new ButtonWidget(this, "Launcher.OptionsButton", _("~O~ptions..."), kOptionsCmd);
+ new ButtonWidget(this, "Launcher.QuitButton", _("~Q~uit"), 0, kQuitCmd);
+ new ButtonWidget(this, "Launcher.AboutButton", _("A~b~out..."), 0, kAboutCmd);
+ new ButtonWidget(this, "Launcher.OptionsButton", _("~O~ptions..."), 0, kOptionsCmd);
_startButton =
- new ButtonWidget(this, "Launcher.StartButton", _("~S~tart"), kStartCmd);
+ new ButtonWidget(this, "Launcher.StartButton", _("~S~tart"), 0, kStartCmd);
_loadButton =
- new ButtonWidget(this, "Launcher.LoadGameButton", _("~L~oad..."), kLoadGameCmd);
+ new ButtonWidget(this, "Launcher.LoadGameButton", _("~L~oad..."), 0, kLoadGameCmd);
// Above the lowest button rows: two more buttons (directly below the list box)
_addButton =
- new ButtonWidget(this, "Launcher.AddGameButton", _("~A~dd Game..."), kAddGameCmd);
+ new ButtonWidget(this, "Launcher.AddGameButton", _("~A~dd Game..."), _("Hold Shift for Mass Add"), kAddGameCmd);
_editButton =
- new ButtonWidget(this, "Launcher.EditGameButton", _("~E~dit Game..."), kEditGameCmd);
+ new ButtonWidget(this, "Launcher.EditGameButton", _("~E~dit Game..."), 0, kEditGameCmd);
_removeButton =
- new ButtonWidget(this, "Launcher.RemoveGameButton", _("~R~emove Game"), kRemoveGameCmd);
+ new ButtonWidget(this, "Launcher.RemoveGameButton", _("~R~emove Game"), 0, kRemoveGameCmd);
// Search box
_searchDesc = 0;
#ifndef DISABLE_FANCY_THEMES
_searchPic = 0;
if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) {
- _searchPic = new GraphicsWidget(this, "Launcher.SearchPic");
+ _searchPic = new GraphicsWidget(this, "Launcher.SearchPic", _("Search in game list"));
_searchPic->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageSearch));
} else
#endif
_searchDesc = new StaticTextWidget(this, "Launcher.SearchDesc", _("Search:"));
_searchWidget = new EditTextWidget(this, "Launcher.Search", _search, kSearchCmd);
- _searchClearButton = new ButtonWidget(this, "Launcher.SearchClearButton", "C", kSearchClearCmd);
+ _searchClearButton = new ButtonWidget(this, "Launcher.SearchClearButton", "C", _("Clear value"), kSearchClearCmd);
// Add list with game titles
_list = new ListWidget(this, "Launcher.GameList", kListSearchCmd);
diff --git a/gui/massadd.cpp b/gui/massadd.cpp
index 36efdfdd59..b981520cdc 100644
--- a/gui/massadd.cpp
+++ b/gui/massadd.cpp
@@ -89,10 +89,10 @@ MassAddDialog::MassAddDialog(const Common::FSNode &startDir)
_list->setNumberingMode(kListNumberingOff);
_list->setList(l);
- _okButton = new ButtonWidget(this, "MassAdd.Ok", _("OK"), kOkCmd, Common::ASCII_RETURN);
+ _okButton = new ButtonWidget(this, "MassAdd.Ok", _("OK"), 0, kOkCmd, Common::ASCII_RETURN);
_okButton->setEnabled(false);
- new ButtonWidget(this, "MassAdd.Cancel", _("Cancel"), kCancelCmd, Common::ASCII_ESCAPE);
+ new ButtonWidget(this, "MassAdd.Cancel", _("Cancel"), 0, kCancelCmd, Common::ASCII_ESCAPE);
// Build a map from all configured game paths to the targets using them
const Common::ConfigManager::DomainMap &domains = ConfMan.getGameDomains();
diff --git a/gui/message.cpp b/gui/message.cpp
index 12ac3123a4..6406976569 100644
--- a/gui/message.cpp
+++ b/gui/message.cpp
@@ -89,10 +89,10 @@ MessageDialog::MessageDialog(const Common::String &message, const char *defaultB
}
if (defaultButton)
- new ButtonWidget(this, okButtonPos, _h - buttonHeight - 8, buttonWidth, buttonHeight, defaultButton, kOkCmd, Common::ASCII_RETURN); // Confirm dialog
+ new ButtonWidget(this, okButtonPos, _h - buttonHeight - 8, buttonWidth, buttonHeight, defaultButton, 0, kOkCmd, Common::ASCII_RETURN); // Confirm dialog
if (altButton)
- new ButtonWidget(this, cancelButtonPos, _h - buttonHeight - 8, buttonWidth, buttonHeight, altButton, kCancelCmd, Common::ASCII_ESCAPE); // Cancel dialog
+ new ButtonWidget(this, cancelButtonPos, _h - buttonHeight - 8, buttonWidth, buttonHeight, altButton, 0, kCancelCmd, Common::ASCII_ESCAPE); // Cancel dialog
}
void MessageDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
diff --git a/gui/options.cpp b/gui/options.cpp
index e9be2834a4..ac7b2dc475 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -642,9 +642,9 @@ void OptionsDialog::addAudioControls(GuiObject *boss, const Common::String &pref
void OptionsDialog::addMIDIControls(GuiObject *boss, const Common::String &prefix) {
// SoundFont
- _soundFontButton = new ButtonWidget(boss, prefix + "mcFontButton", _("SoundFont:"), kChooseSoundFontCmd);
+ _soundFontButton = new ButtonWidget(boss, prefix + "mcFontButton", _("SoundFont:"), 0, kChooseSoundFontCmd);
_soundFont = new StaticTextWidget(boss, prefix + "mcFontPath", _("None"));
- _soundFontClearButton = new ButtonWidget(boss, prefix + "mcFontClearButton", "C", kClearSoundFontCmd);
+ _soundFontClearButton = new ButtonWidget(boss, prefix + "mcFontClearButton", "C", _("Clear value"), kClearSoundFontCmd);
// Multi midi setting
_multiMidiCheckbox = new CheckboxWidget(boss, prefix + "mcMixedCheckbox", _("Mixed AdLib/MIDI mode"));
@@ -657,7 +657,7 @@ void OptionsDialog::addMIDIControls(GuiObject *boss, const Common::String &prefi
// MIDI gain setting (FluidSynth uses this)
_midiGainDesc = new StaticTextWidget(boss, prefix + "mcMidiGainText", _("MIDI gain:"));
- _midiGainSlider = new SliderWidget(boss, prefix + "mcMidiGainSlider", kMidiGainChanged);
+ _midiGainSlider = new SliderWidget(boss, prefix + "mcMidiGainSlider", 0, kMidiGainChanged);
_midiGainSlider->setMinValue(0);
_midiGainSlider->setMaxValue(1000);
_midiGainLabel = new StaticTextWidget(boss, prefix + "mcMidiGainLabel", "1.00");
@@ -687,7 +687,7 @@ void OptionsDialog::addSubtitleControls(GuiObject *boss, const Common::String &p
// Subtitle speed
_subSpeedDesc = new StaticTextWidget(boss, prefix + "subSubtitleSpeedDesc", _("Subtitle speed:"));
- _subSpeedSlider = new SliderWidget(boss, prefix + "subSubtitleSpeedSlider", kSubtitleSpeedChanged);
+ _subSpeedSlider = new SliderWidget(boss, prefix + "subSubtitleSpeedSlider", 0, kSubtitleSpeedChanged);
_subSpeedLabel = new StaticTextWidget(boss, prefix + "subSubtitleSpeedLabel", "100%");
_subSpeedSlider->setMinValue(0); _subSpeedSlider->setMaxValue(maxSliderVal);
_subSpeedLabel->setFlags(WIDGET_CLEARBG);
@@ -699,24 +699,24 @@ void OptionsDialog::addVolumeControls(GuiObject *boss, const Common::String &pre
// Volume controllers
_musicVolumeDesc = new StaticTextWidget(boss, prefix + "vcMusicText", _("Music volume:"));
- _musicVolumeSlider = new SliderWidget(boss, prefix + "vcMusicSlider", kMusicVolumeChanged);
+ _musicVolumeSlider = new SliderWidget(boss, prefix + "vcMusicSlider", 0, kMusicVolumeChanged);
_musicVolumeLabel = new StaticTextWidget(boss, prefix + "vcMusicLabel", "100%");
_musicVolumeSlider->setMinValue(0);
_musicVolumeSlider->setMaxValue(Audio::Mixer::kMaxMixerVolume);
_musicVolumeLabel->setFlags(WIDGET_CLEARBG);
- _muteCheckbox = new CheckboxWidget(boss, prefix + "vcMuteCheckbox", _("Mute All"), kMuteAllChanged);
+ _muteCheckbox = new CheckboxWidget(boss, prefix + "vcMuteCheckbox", _("Mute All"), 0, kMuteAllChanged);
_sfxVolumeDesc = new StaticTextWidget(boss, prefix + "vcSfxText", _("SFX volume:"));
- _sfxVolumeSlider = new SliderWidget(boss, prefix + "vcSfxSlider", kSfxVolumeChanged);
+ _sfxVolumeSlider = new SliderWidget(boss, prefix + "vcSfxSlider", 0, kSfxVolumeChanged);
_sfxVolumeLabel = new StaticTextWidget(boss, prefix + "vcSfxLabel", "100%");
_sfxVolumeSlider->setMinValue(0);
_sfxVolumeSlider->setMaxValue(Audio::Mixer::kMaxMixerVolume);
_sfxVolumeLabel->setFlags(WIDGET_CLEARBG);
_speechVolumeDesc = new StaticTextWidget(boss, prefix + "vcSpeechText" , _("Speech volume:"));
- _speechVolumeSlider = new SliderWidget(boss, prefix + "vcSpeechSlider", kSpeechVolumeChanged);
+ _speechVolumeSlider = new SliderWidget(boss, prefix + "vcSpeechSlider", 0, kSpeechVolumeChanged);
_speechVolumeLabel = new StaticTextWidget(boss, prefix + "vcSpeechLabel", "100%");
_speechVolumeSlider->setMinValue(0);
_speechVolumeSlider->setMaxValue(Audio::Mixer::kMaxMixerVolume);
@@ -792,24 +792,24 @@ GlobalOptionsDialog::GlobalOptionsDialog()
// truncated in the small version of the GUI.
// Save game path
- new ButtonWidget(tab, "GlobalOptions_Paths.SaveButton", _("Save Path: "), kChooseSaveDirCmd);
+ new ButtonWidget(tab, "GlobalOptions_Paths.SaveButton", _("Save Path: "), 0, kChooseSaveDirCmd);
_savePath = new StaticTextWidget(tab, "GlobalOptions_Paths.SavePath", "/foo/bar");
- new ButtonWidget(tab, "GlobalOptions_Paths.ThemeButton", _("Theme Path:"), kChooseThemeDirCmd);
+ new ButtonWidget(tab, "GlobalOptions_Paths.ThemeButton", _("Theme Path:"), 0, kChooseThemeDirCmd);
_themePath = new StaticTextWidget(tab, "GlobalOptions_Paths.ThemePath", _("None"));
- new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _("Extra Path:"), kChooseExtraDirCmd);
+ new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _("Extra Path:"), 0, kChooseExtraDirCmd);
_extraPath = new StaticTextWidget(tab, "GlobalOptions_Paths.ExtraPath", _("None"));
#ifdef DYNAMIC_MODULES
- new ButtonWidget(tab, "GlobalOptions_Paths.PluginsButton", _("Plugins Path:"), kChoosePluginsDirCmd);
+ new ButtonWidget(tab, "GlobalOptions_Paths.PluginsButton", _("Plugins Path:"), 0, kChoosePluginsDirCmd);
_pluginsPath = new StaticTextWidget(tab, "GlobalOptions_Paths.PluginsPath", _("None"));
#endif
#endif
tab->addTab(_("Misc"));
- new ButtonWidget(tab, "GlobalOptions_Misc.ThemeButton", _("Theme:"), kChooseThemeCmd);
+ new ButtonWidget(tab, "GlobalOptions_Misc.ThemeButton", _("Theme:"), 0, kChooseThemeCmd);
_curTheme = new StaticTextWidget(tab, "GlobalOptions_Misc.CurTheme", g_gui.theme()->getThemeName());
@@ -827,7 +827,7 @@ GlobalOptionsDialog::GlobalOptionsDialog()
}
#ifdef SMALL_SCREEN_DEVICE
- new ButtonWidget(tab, "GlobalOptions_Misc.KeysButton", _("Keys"), kChooseKeyMappingCmd);
+ new ButtonWidget(tab, "GlobalOptions_Misc.KeysButton", _("Keys"), 0, kChooseKeyMappingCmd);
#endif
// TODO: joystick setting
@@ -856,8 +856,8 @@ GlobalOptionsDialog::GlobalOptionsDialog()
_tabWidget = tab;
// Add OK & Cancel buttons
- new ButtonWidget(this, "GlobalOptions.Cancel", _("Cancel"), kCloseCmd);
- new ButtonWidget(this, "GlobalOptions.Ok", _("OK"), kOKCmd);
+ new ButtonWidget(this, "GlobalOptions.Cancel", _("Cancel"), 0, kCloseCmd);
+ new ButtonWidget(this, "GlobalOptions.Ok", _("OK"), 0, kOKCmd);
#ifdef SMALL_SCREEN_DEVICE
_keysDialog = new KeysDialog();
diff --git a/gui/saveload.cpp b/gui/saveload.cpp
index bd5aadc206..cef7269b95 100644
--- a/gui/saveload.cpp
+++ b/gui/saveload.cpp
@@ -62,11 +62,11 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel)
_playtime = new StaticTextWidget(this, 0, 0, 10, 10, _("No playtime saved"), Graphics::kTextAlignCenter);
// Buttons
- new GUI::ButtonWidget(this, "SaveLoadChooser.Cancel", _("Cancel"), kCloseCmd);
- _chooseButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Choose", buttonLabel, kChooseCmd);
+ new GUI::ButtonWidget(this, "SaveLoadChooser.Cancel", _("Cancel"), 0, kCloseCmd);
+ _chooseButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Choose", buttonLabel, 0, kChooseCmd);
_chooseButton->setEnabled(false);
- _deleteButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Delete", _("Delete"), kDelCmd);
+ _deleteButton = new GUI::ButtonWidget(this, "SaveLoadChooser.Delete", _("Delete"), 0, kDelCmd);
_deleteButton->setEnabled(false);
_delSupport = _metaInfoSupport = _thumbnailSupport = false;
diff --git a/gui/themebrowser.cpp b/gui/themebrowser.cpp
index 987408e1b4..c8f732fe5f 100644
--- a/gui/themebrowser.cpp
+++ b/gui/themebrowser.cpp
@@ -53,8 +53,8 @@ ThemeBrowser::ThemeBrowser() : Dialog("Browser") {
_backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
// Buttons
- new ButtonWidget(this, "Browser.Cancel", _("Cancel"), kCloseCmd);
- new ButtonWidget(this, "Browser.Choose", _("Choose"), kChooseCmd);
+ new ButtonWidget(this, "Browser.Cancel", _("Cancel"), 0, kCloseCmd);
+ new ButtonWidget(this, "Browser.Choose", _("Choose"), 0, kChooseCmd);
}
void ThemeBrowser::open() {
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index 17294703f4..1009f31816 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -27,6 +27,9 @@
"<font id='text_normal' "
"file='default' "
"/> "
+"<font id='tooltip_normal' "
+"file='builtinConsole' "
+"/> "
"<text_color id='color_normal' "
"color='green' "
"/> "
@@ -411,6 +414,11 @@
"bevel='2' "
"/> "
"</drawdata> "
+"<drawdata id='widget_small' cache='false'> "
+"<drawstep func='square' "
+"stroke='0' "
+"/> "
+"</drawdata> "
"</render_info> "
"<layout_info resolution='-320xY,-256x240,-Xx272'> "
"<globals> "
@@ -425,6 +433,9 @@
"<def var='KeyMapper.Spacing' value='10'/> "
"<def var='KeyMapper.LabelWidth' value='100'/> "
"<def var='KeyMapper.ButtonWidth' value='80'/> "
+"<def var='Tooltip.MaxWidth' value='100'/> "
+"<def var='Tooltip.XDelta' value='16'/> "
+"<def var='Tooltip.YDelta' value='16'/> "
"<widget name='OptionsLabel' "
"size='110,Globals.Line.Height' "
"textalign='right' "
@@ -1181,6 +1192,9 @@
"<def var='KeyMapper.Spacing' value='5'/> "
"<def var='KeyMapper.LabelWidth' value='80'/> "
"<def var='KeyMapper.ButtonWidth' value='60'/> "
+"<def var='Tooltip.MaxWidth' value='70'/> "
+"<def var='Tooltip.XDelta' value='8'/> "
+"<def var='Tooltip.YDelta' value='8'/> "
"<widget name='Button' "
"size='72,16' "
"/> "
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index cc288765ac..3f3f9cee37 100644
--- a/gui/themes/scummclassic.zip
+++ b/gui/themes/scummclassic.zip
Binary files differ
diff --git a/gui/themes/scummclassic/classic_gfx.stx b/gui/themes/scummclassic/classic_gfx.stx
index e107c1f04d..05040751f9 100644
--- a/gui/themes/scummclassic/classic_gfx.stx
+++ b/gui/themes/scummclassic/classic_gfx.stx
@@ -52,6 +52,9 @@
<font id = 'text_normal'
file = 'default'
/>
+ <font id = 'tooltip_normal'
+ file = 'builtinConsole'
+ />
<text_color id = 'color_normal'
color = 'green'
@@ -486,4 +489,10 @@
bevel = '2'
/>
</drawdata>
+
+ <drawdata id = 'widget_small' cache = 'false'>
+ <drawstep func = 'square'
+ stroke = '0'
+ />
+ </drawdata>
</render_info>
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index 9f241c06e5..e4a31e0971 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -41,6 +41,10 @@
<def var = 'KeyMapper.LabelWidth' value = '100'/>
<def var = 'KeyMapper.ButtonWidth' value = '80'/>
+ <def var = 'Tooltip.MaxWidth' value = '100'/>
+ <def var = 'Tooltip.XDelta' value = '16'/> <!-- basically cursor size -->
+ <def var = 'Tooltip.YDelta' value = '16'/>
+
<widget name = 'OptionsLabel'
size = '110, Globals.Line.Height'
textalign = 'right'
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index 19fbb2d0bd..c994968677 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -42,6 +42,10 @@
<def var = 'KeyMapper.LabelWidth' value = '80'/>
<def var = 'KeyMapper.ButtonWidth' value = '60'/>
+ <def var = 'Tooltip.MaxWidth' value = '70'/>
+ <def var = 'Tooltip.XDelta' value = '8'/> <!-- basically cursor size -->
+ <def var = 'Tooltip.YDelta' value = '8'/>
+
<widget name = 'Button'
size = '72, 16'
/>
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index 1f3a017b45..22e8ccaa90 100644
--- a/gui/themes/scummmodern.zip
+++ b/gui/themes/scummmodern.zip
Binary files differ
diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx
index 13f9cd2196..3ed915200a 100644
--- a/gui/themes/scummmodern/scummmodern_gfx.stx
+++ b/gui/themes/scummmodern/scummmodern_gfx.stx
@@ -114,6 +114,9 @@
<font id = 'text_normal'
file = 'helvr12-l1.bdf'
/>
+ <font id = 'tooltip_normal'
+ file = 'builtinConsole'
+ />
<text_color id = 'color_normal'
color = 'black'
@@ -649,10 +652,8 @@
/>
</drawdata>
- <!-- Where is it used? -->
<drawdata id = 'widget_small' cache = 'false'>
- <drawstep func = 'roundedsq'
- radius = '6'
+ <drawstep func = 'square'
stroke = '0'
gradient_start = 'blandyellow'
gradient_end = 'xtrabrightred'
diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx
index dfc2fcee8d..1488967a9c 100644
--- a/gui/themes/scummmodern/scummmodern_layout.stx
+++ b/gui/themes/scummmodern/scummmodern_layout.stx
@@ -48,6 +48,10 @@
<def var = 'KeyMapper.LabelWidth' value = '100'/>
<def var = 'KeyMapper.ButtonWidth' value = '80'/>
+ <def var = 'Tooltip.MaxWidth' value = '100'/>
+ <def var = 'Tooltip.XDelta' value = '16'/> <!-- basically cursor size -->
+ <def var = 'Tooltip.YDelta' value = '32'/>
+
<widget name = 'OptionsLabel'
size = '110, Globals.Line.Height'
textalign = 'right'
diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
index 49dc6c03a0..079da11c34 100644
--- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx
+++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
@@ -48,6 +48,10 @@
<def var = 'KeyMapper.LabelWidth' value = '80'/>
<def var = 'KeyMapper.ButtonWidth' value = '60'/>
+ <def var = 'Tooltip.MaxWidth' value = '70'/>
+ <def var = 'Tooltip.XDelta' value = '9'/> <!-- basically cursor size -->
+ <def var = 'Tooltip.YDelta' value = '18'/>
+
<widget name = 'OptionsLabel'
size = '100, Globals.Line.Height'
textalign = 'right'
diff --git a/gui/widget.cpp b/gui/widget.cpp
index 1958ffe398..6b5095f89e 100644
--- a/gui/widget.cpp
+++ b/gui/widget.cpp
@@ -32,14 +32,14 @@
namespace GUI {
-Widget::Widget(GuiObject *boss, int x, int y, int w, int h)
- : GuiObject(x, y, w, h), _type(0), _boss(boss),
+Widget::Widget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip)
+ : GuiObject(x, y, w, h), _type(0), _boss(boss), _tooltip(tooltip),
_id(0), _flags(0), _hasFocus(false), _state(ThemeEngine::kStateEnabled) {
init();
}
-Widget::Widget(GuiObject *boss, const Common::String &name)
- : GuiObject(name), _type(0), _boss(boss),
+Widget::Widget(GuiObject *boss, const Common::String &name, const char *tooltip)
+ : GuiObject(name), _type(0), _boss(boss), _tooltip(tooltip),
_id(0), _flags(0), _hasFocus(false), _state(ThemeEngine::kStateDisabled) {
init();
}
@@ -224,15 +224,88 @@ Common::String Widget::cleanupHotkey(const Common::String &label) {
#pragma mark -
-StaticTextWidget::StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &text, Graphics::TextAlign align)
- : Widget(boss, x, y, w, h), _align(align) {
+Tooltip::Tooltip(GuiManager *guiManager) : GuiObject(0, 0, 0, 0) {
+ _guiManager = guiManager;
+
+ _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) {
+ 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);
_type = kStaticTextWidget;
_label = text;
}
-StaticTextWidget::StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::String &text)
- : Widget(boss, name) {
+StaticTextWidget::StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::String &text, const char *tooltip)
+ : Widget(boss, name, tooltip) {
setFlags(WIDGET_ENABLED);
_type = kStaticTextWidget;
_label = text;
@@ -272,8 +345,8 @@ void StaticTextWidget::drawWidget() {
#pragma mark -
-ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, uint32 cmd, uint8 hotkey)
- : StaticTextWidget(boss, x, y, w, h, cleanupHotkey(label), Graphics::kTextAlignCenter), CommandSender(boss),
+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),
_cmd(cmd) {
if (hotkey == 0)
@@ -283,8 +356,8 @@ ButtonWidget::ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Co
_type = kButtonWidget;
}
-ButtonWidget::ButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, uint32 cmd, uint8 hotkey)
- : StaticTextWidget(boss, name, cleanupHotkey(label)), CommandSender(boss),
+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),
_cmd(cmd) {
if (hotkey == 0)
_hotkey = parseHotkey(label);
@@ -303,14 +376,14 @@ void ButtonWidget::drawWidget() {
#pragma mark -
-CheckboxWidget::CheckboxWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, uint32 cmd, uint8 hotkey)
- : ButtonWidget(boss, x, y, w, h, label, cmd, hotkey), _state(false) {
+CheckboxWidget::CheckboxWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey)
+ : ButtonWidget(boss, x, y, w, h, label, tooltip, cmd, hotkey), _state(false) {
setFlags(WIDGET_ENABLED);
_type = kCheckboxWidget;
}
-CheckboxWidget::CheckboxWidget(GuiObject *boss, const Common::String &name, const Common::String &label, uint32 cmd, uint8 hotkey)
- : ButtonWidget(boss, name, label, cmd, hotkey), _state(false) {
+CheckboxWidget::CheckboxWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey)
+ : ButtonWidget(boss, name, label, tooltip, cmd, hotkey), _state(false) {
setFlags(WIDGET_ENABLED);
_type = kCheckboxWidget;
}
@@ -364,15 +437,15 @@ void RadiobuttonGroup::setEnabled(bool ena) {
#pragma mark -
-RadiobuttonWidget::RadiobuttonWidget(GuiObject *boss, int x, int y, int w, int h, RadiobuttonGroup *group, int value, const Common::String &label, uint8 hotkey)
- : ButtonWidget(boss, x, y, w, h, label, 0, hotkey), _state(false), _value(value), _group(group) {
+RadiobuttonWidget::RadiobuttonWidget(GuiObject *boss, int x, int y, int w, int h, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip, uint8 hotkey)
+ : ButtonWidget(boss, x, y, w, h, label, tooltip, 0, hotkey), _state(false), _value(value), _group(group) {
setFlags(WIDGET_ENABLED);
_type = kRadiobuttonWidget;
_group->addButton(this);
}
-RadiobuttonWidget::RadiobuttonWidget(GuiObject *boss, const Common::String &name, RadiobuttonGroup *group, int value, const Common::String &label, uint8 hotkey)
- : ButtonWidget(boss, name, label, 0, hotkey), _state(false), _value(value), _group(group) {
+RadiobuttonWidget::RadiobuttonWidget(GuiObject *boss, const Common::String &name, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip, uint8 hotkey)
+ : ButtonWidget(boss, name, label, tooltip, 0, hotkey), _state(false), _value(value), _group(group) {
setFlags(WIDGET_ENABLED);
_type = kRadiobuttonWidget;
_group->addButton(this);
@@ -404,15 +477,15 @@ void RadiobuttonWidget::drawWidget() {
#pragma mark -
-SliderWidget::SliderWidget(GuiObject *boss, int x, int y, int w, int h, uint32 cmd)
- : Widget(boss, x, y, w, h), CommandSender(boss),
+SliderWidget::SliderWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd)
+ : Widget(boss, x, y, w, h, tooltip), CommandSender(boss),
_cmd(cmd), _value(0), _oldValue(0), _valueMin(0), _valueMax(100), _isDragging(false) {
setFlags(WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG);
_type = kSliderWidget;
}
-SliderWidget::SliderWidget(GuiObject *boss, const Common::String &name, uint32 cmd)
- : Widget(boss, name), CommandSender(boss),
+SliderWidget::SliderWidget(GuiObject *boss, const Common::String &name, const char *tooltip, uint32 cmd)
+ : Widget(boss, name, tooltip), CommandSender(boss),
_cmd(cmd), _value(0), _oldValue(0), _valueMin(0), _valueMax(100), _isDragging(false) {
setFlags(WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG);
_type = kSliderWidget;
@@ -484,14 +557,14 @@ int SliderWidget::posToValue(int pos) {
#pragma mark -
-GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h)
- : Widget(boss, x, y, w, h), _gfx(), _alpha(256), _transparency(false) {
+GraphicsWidget::GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip)
+ : Widget(boss, x, y, w, h, tooltip), _gfx(), _alpha(256), _transparency(false) {
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
_type = kGraphicsWidget;
}
-GraphicsWidget::GraphicsWidget(GuiObject *boss, const Common::String &name)
- : Widget(boss, name), _gfx(), _alpha(256), _transparency(false) {
+GraphicsWidget::GraphicsWidget(GuiObject *boss, const Common::String &name, const char *tooltip)
+ : Widget(boss, name, tooltip), _gfx(), _alpha(256), _transparency(false) {
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG);
_type = kGraphicsWidget;
}
diff --git a/gui/widget.h b/gui/widget.h
index 0b075c19db..7b5fe9253f 100644
--- a/gui/widget.h
+++ b/gui/widget.h
@@ -27,6 +27,7 @@
#include "common/scummsys.h"
#include "common/str.h"
+#include "common/str-array.h"
#include "common/keyboard.h"
#include "graphics/surface.h"
#include "gui/object.h"
@@ -86,6 +87,7 @@ protected:
uint16 _id;
bool _hasFocus;
ThemeEngine::WidgetStateInfo _state;
+ const char *_tooltip;
private:
uint16 _flags;
@@ -95,8 +97,8 @@ public:
static Widget *findWidgetInChain(Widget *start, const char *name);
public:
- Widget(GuiObject *boss, int x, int y, int w, int h);
- Widget(GuiObject *boss, const Common::String &name);
+ Widget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip = 0);
+ Widget(GuiObject *boss, const Common::String &name, const char *tooltip = 0);
virtual ~Widget();
void init();
@@ -139,6 +141,8 @@ public:
uint8 parseHotkey(const Common::String &label);
Common::String cleanupHotkey(const Common::String &label);
+ const char *getTooltip() const { return _tooltip; }
+
protected:
void updateState(int oldFlags, int newFlags);
@@ -155,14 +159,39 @@ 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:
Common::String _label;
Graphics::TextAlign _align;
public:
- StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &text, Graphics::TextAlign align);
- StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::String &text);
+ StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &text, Graphics::TextAlign align, const char *tooltip = 0);
+ StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::String &text, const char *tooltip = 0);
void setValue(int value);
void setLabel(const Common::String &label);
const Common::String &getLabel() const { return _label; }
@@ -180,8 +209,8 @@ protected:
uint32 _cmd;
uint8 _hotkey;
public:
- ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, uint32 cmd = 0, uint8 hotkey = 0);
- ButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, uint32 cmd = 0, uint8 hotkey = 0);
+ ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip = 0, uint32 cmd = 0, uint8 hotkey = 0);
+ ButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip = 0, uint32 cmd = 0, uint8 hotkey = 0);
void setCmd(uint32 cmd) { _cmd = cmd; }
uint32 getCmd() const { return _cmd; }
@@ -199,8 +228,8 @@ class CheckboxWidget : public ButtonWidget {
protected:
bool _state;
public:
- CheckboxWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, uint32 cmd = 0, uint8 hotkey = 0);
- CheckboxWidget(GuiObject *boss, const Common::String &name, const Common::String &label, uint32 cmd = 0, uint8 hotkey = 0);
+ CheckboxWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip = 0, uint32 cmd = 0, uint8 hotkey = 0);
+ CheckboxWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip = 0, uint32 cmd = 0, uint8 hotkey = 0);
void handleMouseUp(int x, int y, int button, int clickCount);
virtual void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); draw(); }
@@ -245,8 +274,8 @@ protected:
int _value;
public:
- RadiobuttonWidget(GuiObject *boss, int x, int y, int w, int h, RadiobuttonGroup *group, int value, const Common::String &label, uint8 hotkey = 0);
- RadiobuttonWidget(GuiObject *boss, const Common::String &name, RadiobuttonGroup *group, int value, const Common::String &label, uint8 hotkey = 0);
+ RadiobuttonWidget(GuiObject *boss, int x, int y, int w, int h, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip = 0, uint8 hotkey = 0);
+ RadiobuttonWidget(GuiObject *boss, const Common::String &name, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip = 0, uint8 hotkey = 0);
void handleMouseUp(int x, int y, int button, int clickCount);
virtual void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); draw(); }
@@ -272,8 +301,8 @@ protected:
bool _isDragging;
uint _labelWidth;
public:
- SliderWidget(GuiObject *boss, int x, int y, int w, int h, uint32 cmd = 0);
- SliderWidget(GuiObject *boss, const Common::String &name, uint32 cmd = 0);
+ SliderWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip = 0, uint32 cmd = 0);
+ SliderWidget(GuiObject *boss, const Common::String &name, const char *tooltip = 0, uint32 cmd = 0);
void setCmd(uint32 cmd) { _cmd = cmd; }
uint32 getCmd() const { return _cmd; }
@@ -304,8 +333,8 @@ protected:
/* GraphicsWidget */
class GraphicsWidget : public Widget {
public:
- GraphicsWidget(GuiObject *boss, int x, int y, int w, int h);
- GraphicsWidget(GuiObject *boss, const Common::String &name);
+ GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip = 0);
+ GraphicsWidget(GuiObject *boss, const Common::String &name, const char *tooltip = 0);
~GraphicsWidget();
void setGfx(const Graphics::Surface *gfx);