GUI: Implement tooltips. FR #2821513.

FR #2821513: "GUI: add tooltips".
Added tooltips for Add Game button, clear field buttons and couple
other.

Current problem: Only first call correctly restores text. I could
not find where restore information gets lost.

svn-id: r49774
This commit is contained in:
Eugene Sandulenko 2010-06-15 10:52:35 +00:00
parent ea7405d7ef
commit 01f9006ee7
30 changed files with 375 additions and 125 deletions

View file

@ -86,31 +86,31 @@ MainMenuDialog::MainMenuDialog(Engine *engine)
StaticTextWidget *version = new StaticTextWidget(this, "GlobalMenu.Version", gScummVMVersionDate);
version->setAlign(Graphics::kTextAlignCenter);
new GUI::ButtonWidget(this, "GlobalMenu.Resume", _("~R~esume"), kPlayCmd, 'P');
new GUI::ButtonWidget(this, "GlobalMenu.Resume", _("~R~esume"), 0, kPlayCmd, 'P');
_loadButton = new GUI::ButtonWidget(this, "GlobalMenu.Load", _("~L~oad"), kLoadCmd);
_loadButton = new GUI::ButtonWidget(this, "GlobalMenu.Load", _("~L~oad"), 0, kLoadCmd);
// TODO: setEnabled -> setVisible
_loadButton->setEnabled(_engine->hasFeature(Engine::kSupportsLoadingDuringRuntime));
_saveButton = new GUI::ButtonWidget(this, "GlobalMenu.Save", _("~S~ave"), kSaveCmd);
_saveButton = new GUI::ButtonWidget(this, "GlobalMenu.Save", _("~S~ave"), 0, kSaveCmd);
// TODO: setEnabled -> setVisible
_saveButton->setEnabled(_engine->hasFeature(Engine::kSupportsSavingDuringRuntime));
new GUI::ButtonWidget(this, "GlobalMenu.Options", _("~O~ptions"), kOptionsCmd);
new GUI::ButtonWidget(this, "GlobalMenu.Options", _("~O~ptions"), 0, kOptionsCmd);
// The help button is disabled by default.
// To enable "Help", an engine needs to use a subclass of MainMenuDialog
// (at least for now, we might change how this works in the future).
_helpButton = new GUI::ButtonWidget(this, "GlobalMenu.Help", _("~H~elp"), kHelpCmd);
_helpButton = new GUI::ButtonWidget(this, "GlobalMenu.Help", _("~H~elp"), 0, kHelpCmd);
_helpButton->setEnabled(false);
new GUI::ButtonWidget(this, "GlobalMenu.About", _("~A~bout"), kAboutCmd);
new GUI::ButtonWidget(this, "GlobalMenu.About", _("~A~bout"), 0, kAboutCmd);
_rtlButton = new GUI::ButtonWidget(this, "GlobalMenu.RTL", _("~R~eturn to Launcher"), kRTLCmd);
_rtlButton = new GUI::ButtonWidget(this, "GlobalMenu.RTL", _("~R~eturn to Launcher"), 0, kRTLCmd);
_rtlButton->setEnabled(_engine->hasFeature(Engine::kSupportsRTL));
new GUI::ButtonWidget(this, "GlobalMenu.Quit", _("~Q~uit"), kQuitCmd);
new GUI::ButtonWidget(this, "GlobalMenu.Quit", _("~Q~uit"), 0, kQuitCmd);
_aboutDialog = new GUI::AboutDialog();
_optionsDialog = new ConfigDialog(_engine->hasFeature(Engine::kSupportsSubtitleOptions));
@ -298,11 +298,11 @@ ConfigDialog::ConfigDialog(bool subtitleControls)
// Add the buttons
//
new GUI::ButtonWidget(this, "GlobalConfig.Ok", _("~O~K"), GUI::kOKCmd);
new GUI::ButtonWidget(this, "GlobalConfig.Cancel", _("~C~ancel"), GUI::kCloseCmd);
new GUI::ButtonWidget(this, "GlobalConfig.Ok", _("~O~K"), 0, GUI::kOKCmd);
new GUI::ButtonWidget(this, "GlobalConfig.Cancel", _("~C~ancel"), 0, GUI::kCloseCmd);
#ifdef SMALL_SCREEN_DEVICE
new GUI::ButtonWidget(this, "GlobalConfig.Keys", _("~K~eys"), kKeysCmd);
new GUI::ButtonWidget(this, "GlobalConfig.Keys", _("~K~eys"), 0, kKeysCmd);
_keysDialog = NULL;
#endif
}

View file

@ -284,9 +284,9 @@ HelpDialog::HelpDialog(const GameSettings &game)
_numPages = ScummHelp::numPages(_game.id);
_prevButton = new GUI::ButtonWidget(this, "ScummHelp.Prev", _("~P~revious"), kPrevCmd);
_nextButton = new GUI::ButtonWidget(this, "ScummHelp.Next", _("~N~ext"), kNextCmd);
new GUI::ButtonWidget(this, "ScummHelp.Close", _("~C~lose"), GUI::kCloseCmd);
_prevButton = new GUI::ButtonWidget(this, "ScummHelp.Prev", _("~P~revious"), 0, kPrevCmd);
_nextButton = new GUI::ButtonWidget(this, "ScummHelp.Next", _("~N~ext"), 0, kNextCmd);
new GUI::ButtonWidget(this, "ScummHelp.Close", _("~C~lose"), 0, GUI::kCloseCmd);
_prevButton->clearFlags(WIDGET_ENABLED);
_numLines = HELP_NUM_LINES;

View file

@ -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);
}

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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() {

View file

@ -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

View file

@ -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);

View file

@ -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" }
};

View file

@ -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() {

View file

@ -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);
}

View file

@ -44,6 +44,7 @@ enum {
class Dialog : public GuiObject {
friend class GuiManager;
friend class Tooltip;
protected:
Widget *_mouseWidget;
Widget *_focusedWidget;

View file

@ -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);

View file

@ -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();

View file

@ -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) {

View file

@ -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();

View file

@ -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;

View file

@ -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() {

View file

@ -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' "
"/> "

Binary file not shown.

View file

@ -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>

View file

@ -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'

View file

@ -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'
/>

Binary file not shown.

View file

@ -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'

View file

@ -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'

View file

@ -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'

View file

@ -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;
}

View file

@ -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);