ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

widget.h

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #ifndef GUI_WIDGET_H
00024 #define GUI_WIDGET_H
00025 
00026 #include "common/scummsys.h"
00027 #include "common/array.h"
00028 #include "common/str.h"
00029 #include "common/keyboard.h"
00030 #include "graphics/font.h"
00031 #include "graphics/surface.h"
00032 #include "gui/object.h"
00033 #include "gui/ThemeEngine.h"
00034 #include "common/text-to-speech.h"
00035 #include "common/system.h"
00036 #include "common/config-manager.h"
00037 
00038 namespace GUI {
00039 
00040 class ScrollContainerWidget;
00041 
00042 enum {
00043     WIDGET_ENABLED      = 1 <<  0,
00044     WIDGET_INVISIBLE    = 1 <<  1,
00045     WIDGET_HILITED      = 1 <<  2,
00046     WIDGET_BORDER       = 1 <<  3,
00047     WIDGET_PRESSED      = 1 <<  4,
00048     //WIDGET_INV_BORDER = 1 <<  4,
00049     WIDGET_CLEARBG      = 1 <<  5,
00050     WIDGET_WANT_TICKLE  = 1 <<  7,
00051     WIDGET_TRACK_MOUSE  = 1 <<  8,
00052     // Retain focus on mouse up. By default widgets lose focus on mouseup,
00053     // but some widgets might want to retain it - widgets where you enter
00054     // text, for instance
00055     WIDGET_RETAIN_FOCUS = 1 <<  9,
00056     // Usually widgets would lock mouse input when the user pressed the
00057     // left mouse button till the user releases it.
00058     // The PopUpWidget for example does not want this behavior, since the
00059     // mouse down will open up a new dialog which silently eats the mouse
00060     // up event for its own purposes.
00061     WIDGET_IGNORE_DRAG  = 1 << 10
00062 };
00063 
00064 enum {
00065     kStaticTextWidget   = 'TEXT',
00066     kEditTextWidget     = 'EDIT',
00067     kButtonWidget       = 'BTTN',
00068     kCheckboxWidget     = 'CHKB',
00069     kRadiobuttonWidget  = 'RDBT',
00070     kSliderWidget       = 'SLDE',
00071     kListWidget         = 'LIST',
00072     kScrollBarWidget    = 'SCRB',
00073     kPopUpWidget        = 'POPU',
00074     kTabWidget          = 'TABW',
00075     kGraphicsWidget     = 'GFXW',
00076     kContainerWidget    = 'CTNR',
00077     kScrollContainerWidget = 'SCTR'
00078 };
00079 
00080 enum {
00081     kCaretBlinkTime = 300
00082 };
00083 
00084 enum {
00085     kPressedButtonTime = 200
00086 };
00087 
00088 enum {
00089     kPicButtonStateEnabled = 0,
00090     kPicButtonHighlight = 1,
00091     kPicButtonStateDisabled = 2,
00092     kPicButtonStatePressed = 3,
00093 
00094     kPicButtonStateMax = 3
00095 };
00096 
00097 /* Widget */
00098 class Widget : public GuiObject {
00099     friend class Dialog;
00100 protected:
00101     uint32      _type;
00102     GuiObject   *_boss;
00103     Widget      *_next;
00104     bool        _hasFocus;
00105     ThemeEngine::WidgetStateInfo _state;
00106     Common::String _tooltip;
00107 
00108 private:
00109     uint16      _flags;
00110     bool        _needsRedraw;
00111 
00112 public:
00113     static Widget *findWidgetInChain(Widget *start, int x, int y);
00114     static Widget *findWidgetInChain(Widget *start, const char *name);
00115     static bool containsWidgetInChain(Widget *start, Widget *search);
00116 
00117 public:
00118     Widget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip = nullptr);
00119     Widget(GuiObject *boss, const Common::String &name, const char *tooltip = nullptr);
00120     ~Widget() override;
00121 
00122     void init();
00123     void resize(int x, int y, int w, int h);
00124 
00125     void setNext(Widget *w) { _next = w; }
00126     Widget *next() { return _next; }
00127 
00128     int16   getAbsX() const override    { return _x + _boss->getChildX(); }
00129     int16   getAbsY() const override    { return _y + _boss->getChildY(); }
00130 
00131     virtual void setPos(int x, int y) { _x = x; _y = y; }
00132     virtual void setSize(int w, int h) { _w = w; _h = h; }
00133 
00135     virtual void getMinSize(int &minWidth, int &minHeight) { minHeight = -1; minWidth = -1; }
00136 
00137     virtual void handleMouseDown(int x, int y, int button, int clickCount) {}
00138     virtual void handleMouseUp(int x, int y, int button, int clickCount) {}
00139     virtual void handleMouseEntered(int button) {}
00140     virtual void handleMouseLeft(int button) {}
00141     virtual void handleMouseMoved(int x, int y, int button) {}
00142     virtual void handleMouseWheel(int x, int y, int direction) {}
00143     virtual bool handleKeyDown(Common::KeyState state) { return false; }    // Return true if the event was handled
00144     virtual bool handleKeyUp(Common::KeyState state) { return false; }  // Return true if the event was handled
00145     virtual void handleTickle() {}
00146 
00148     virtual void markAsDirty();
00149 
00151     virtual void draw();
00152 
00153     void receivedFocus() { _hasFocus = true; receivedFocusWidget(); }
00154     void lostFocus() { _hasFocus = false; lostFocusWidget(); }
00155     virtual bool wantsFocus() { return false; }
00156 
00157     void setFlags(int flags);
00158     void clearFlags(int flags);
00159     int getFlags() const        { return _flags; }
00160 
00161     void setEnabled(bool e);
00162     bool isEnabled() const;
00163 
00164     void setVisible(bool e);
00165     bool isVisible() const override;
00166 
00167     bool useRTL() const;
00168 
00169     uint8 parseHotkey(const Common::String &label);
00170     Common::String cleanupHotkey(const Common::String &label);
00171 
00172     bool hasTooltip() const { return !_tooltip.empty(); }
00173     const Common::String &getTooltip() const { return _tooltip; }
00174     void setTooltip(const Common::String &tooltip) { _tooltip = tooltip; }
00175 
00176     virtual bool containsWidget(Widget *) const { return false; }
00177 
00178     void read(Common::String str);
00179 
00180 protected:
00181     void updateState(int oldFlags, int newFlags);
00182 
00183     virtual void drawWidget() = 0;
00184 
00185     virtual void receivedFocusWidget() {}
00186     virtual void lostFocusWidget() {}
00187 
00188     virtual Widget *findWidget(int x, int y) { return this; }
00189 
00190     void releaseFocus() override { assert(_boss); _boss->releaseFocus(); }
00191 
00192     // By default, delegate unhandled commands to the boss
00193     void handleCommand(CommandSender *sender, uint32 cmd, uint32 data) override { assert(_boss); _boss->handleCommand(sender, cmd, data); }
00194 };
00195 
00196 /* StaticTextWidget */
00197 class StaticTextWidget : public Widget {
00198 protected:
00199     Common::String          _label;
00200     Graphics::TextAlign     _align;
00201     ThemeEngine::FontStyle  _font;
00202 public:
00203     StaticTextWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &text, Graphics::TextAlign align, const char *tooltip = nullptr, ThemeEngine::FontStyle font = ThemeEngine::kFontStyleBold);
00204     StaticTextWidget(GuiObject *boss, const Common::String &name, const Common::String &text, const char *tooltip = nullptr, ThemeEngine::FontStyle font = ThemeEngine::kFontStyleBold);
00205     void setValue(int value);
00206     void setLabel(const Common::String &label);
00207     void handleMouseEntered(int button) override    { readLabel(); }
00208     const Common::String &getLabel() const      { return _label; }
00209     void setAlign(Graphics::TextAlign align);
00210     Graphics::TextAlign getAlign() const        { return _align; }
00211     void readLabel() { read(_label); }
00212 
00213 protected:
00214     void drawWidget() override;
00215 };
00216 
00217 /* ButtonWidget */
00218 class ButtonWidget : public StaticTextWidget, public CommandSender {
00219     friend class Dialog;    // Needed for the hotkey handling
00220 protected:
00221     uint32  _cmd;
00222     uint8   _hotkey;
00223 public:
00224     ButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip = nullptr, uint32 cmd = 0, uint8 hotkey = 0);
00225     ButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip = nullptr, uint32 cmd = 0, uint8 hotkey = 0);
00226 
00227     void getMinSize(int &minWidth, int &minHeight) override;
00228 
00229     void setCmd(uint32 cmd)             { _cmd = cmd; }
00230     uint32 getCmd() const               { return _cmd; }
00231 
00232     void setLabel(const Common::String &label);
00233 
00234     void handleMouseUp(int x, int y, int button, int clickCount) override;
00235     void handleMouseDown(int x, int y, int button, int clickCount) override;
00236     void handleMouseEntered(int button) override    { readLabel(); if (_duringPress) { setFlags(WIDGET_PRESSED); } else { setFlags(WIDGET_HILITED); } markAsDirty(); }
00237     void handleMouseLeft(int button) override   { clearFlags(WIDGET_HILITED | WIDGET_PRESSED); markAsDirty(); }
00238 
00239     void setHighLighted(bool enable);
00240     void setPressedState();
00241     void setUnpressedState();
00242 protected:
00243     void drawWidget() override;
00244     bool _duringPress;
00245 };
00246 
00247 /* DropdownButtonWidget */
00248 class DropdownButtonWidget : public ButtonWidget {
00249 public:
00250     DropdownButtonWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip = nullptr, uint32 cmd = 0, uint8 hotkey = 0);
00251     DropdownButtonWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip = nullptr, uint32 cmd = 0, uint8 hotkey = 0);
00252 
00253     void handleMouseMoved(int x, int y, int button) override;
00254     void handleMouseUp(int x, int y, int button, int clickCount) override;
00255     void reflowLayout() override;
00256     void getMinSize(int &minWidth, int &minHeight) override;
00257 
00258 
00259     void appendEntry(const Common::String &label, uint32 cmd);
00260     void clearEntries();
00261 
00262 protected:
00263     struct Entry {
00264         Common::String label;
00265         uint32 cmd;
00266     };
00267     typedef Common::Array<Entry> EntryList;
00268 
00269     // Widget API
00270     void drawWidget() override;
00271 
00272     void reset();
00273     bool isInDropDown(int x, int y) const;
00274 
00275     EntryList _entries;
00276 
00277     uint32 _dropdownWidth;
00278     bool _inDropdown;
00279     bool _inButton;
00280 };
00281 
00282 /* PicButtonWidget */
00283 class PicButtonWidget : public ButtonWidget {
00284 public:
00285     PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip = nullptr, uint32 cmd = 0, uint8 hotkey = 0);
00286     PicButtonWidget(GuiObject *boss, const Common::String &name, const char *tooltip = nullptr, uint32 cmd = 0, uint8 hotkey = 0);
00287     ~PicButtonWidget() override;
00288 
00289     void setGfx(const Graphics::Surface *gfx, int statenum = kPicButtonStateEnabled);
00290     void setGfx(int w, int h, int r, int g, int b, int statenum = kPicButtonStateEnabled);
00291 
00292     void useAlpha(int alpha) { _alpha = alpha; }
00293     void useThemeTransparency(bool enable) { _transparency = enable; }
00294     void setButtonDisplay(bool enable) {_showButton = enable; }
00295 
00296 protected:
00297     void drawWidget() override;
00298 
00299     Graphics::Surface _gfx[kPicButtonStateMax + 1];
00300     int _alpha;
00301     bool _transparency;
00302     bool _showButton;
00303 };
00304 
00305 /* CheckboxWidget */
00306 class CheckboxWidget : public ButtonWidget {
00307 protected:
00308     bool    _state;
00309 public:
00310     CheckboxWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip = nullptr, uint32 cmd = 0, uint8 hotkey = 0);
00311     CheckboxWidget(GuiObject *boss, const Common::String &name, const Common::String &label, const char *tooltip = nullptr, uint32 cmd = 0, uint8 hotkey = 0);
00312 
00313     void handleMouseUp(int x, int y, int button, int clickCount) override;
00314     void handleMouseEntered(int button) override    { readLabel(); setFlags(WIDGET_HILITED); markAsDirty(); }
00315     void handleMouseLeft(int button) override   { clearFlags(WIDGET_HILITED); markAsDirty(); }
00316 
00317     void setState(bool state);
00318     void toggleState()          { setState(!_state); }
00319     bool getState() const       { return _state; }
00320 
00321 protected:
00322     void drawWidget() override;
00323 };
00324 
00325 class RadiobuttonWidget;
00326 
00327 class RadiobuttonGroup : public CommandSender {
00328 public:
00329     RadiobuttonGroup(GuiObject *boss, uint32 cmd = 0);
00330     ~RadiobuttonGroup() override {}
00331 
00332     void addButton(RadiobuttonWidget *button) { _buttons.push_back(button); }
00333     Common::Array<RadiobuttonWidget *> getButtonList() const { return _buttons; }
00334 
00335     void setValue(int state);
00336     int getValue() const { return _value; }
00337 
00338     void setEnabled(bool ena);
00339 
00340     void setCmd(uint32 cmd)             { _cmd = cmd; }
00341     uint32 getCmd() const               { return _cmd; }
00342 
00343 protected:
00344     Common::Array<RadiobuttonWidget *> _buttons;
00345     int _value;
00346     uint32  _cmd;
00347 };
00348 
00349 /* RadiobuttonWidget */
00350 class RadiobuttonWidget : public ButtonWidget {
00351 protected:
00352     bool    _state;
00353     int _value;
00354 
00355 public:
00356     RadiobuttonWidget(GuiObject *boss, int x, int y, int w, int h, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip = nullptr, uint8 hotkey = 0);
00357     RadiobuttonWidget(GuiObject *boss, const Common::String &name, RadiobuttonGroup *group, int value, const Common::String &label, const char *tooltip = nullptr, uint8 hotkey = 0);
00358 
00359     void handleMouseUp(int x, int y, int button, int clickCount) override;
00360     void handleMouseEntered(int button) override    { readLabel(); setFlags(WIDGET_HILITED); markAsDirty(); }
00361     void handleMouseLeft(int button) override   { clearFlags(WIDGET_HILITED); markAsDirty(); }
00362 
00363     void setState(bool state, bool setGroup = true);
00364     void toggleState()          { setState(!_state); }
00365     bool getState() const       { return _state; }
00366     int getValue() const            { return _value; }
00367 
00368 protected:
00369     void drawWidget() override;
00370 
00371     RadiobuttonGroup *_group;
00372 };
00373 
00374 /* SliderWidget */
00375 class SliderWidget : public Widget, public CommandSender {
00376 protected:
00377     uint32  _cmd;
00378     int     _value, _oldValue;
00379     int     _valueMin, _valueMax;
00380     bool    _isDragging;
00381     uint    _labelWidth;
00382 public:
00383     SliderWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip = nullptr, uint32 cmd = 0);
00384     SliderWidget(GuiObject *boss, const Common::String &name, const char *tooltip = nullptr, uint32 cmd = 0);
00385 
00386     void setCmd(uint32 cmd)     { _cmd = cmd; }
00387     uint32 getCmd() const       { return _cmd; }
00388 
00389     void setValue(int value)    { _value = value; }
00390     int getValue() const        { return _value; }
00391 
00392     void setMinValue(int value) { _valueMin = value; }
00393     int getMinValue() const     { return _valueMin; }
00394     void setMaxValue(int value) { _valueMax = value; }
00395     int getMaxValue() const     { return _valueMax; }
00396 
00397     void handleMouseMoved(int x, int y, int button) override;
00398     void handleMouseDown(int x, int y, int button, int clickCount) override;
00399     void handleMouseUp(int x, int y, int button, int clickCount) override;
00400     void handleMouseEntered(int button) override    { setFlags(WIDGET_HILITED); markAsDirty(); }
00401     void handleMouseLeft(int button) override   { clearFlags(WIDGET_HILITED); markAsDirty(); }
00402     void handleMouseWheel(int x, int y, int direction) override;
00403 
00404 protected:
00405     void drawWidget() override;
00406 
00407     int valueToPos(int value);
00408     int posToValue(int pos);
00409     int valueToBarWidth(int value);
00410 };
00411 
00412 /* GraphicsWidget */
00413 class GraphicsWidget : public Widget {
00414 public:
00415     GraphicsWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip = nullptr);
00416     GraphicsWidget(GuiObject *boss, const Common::String &name, const char *tooltip = nullptr);
00417     ~GraphicsWidget() override;
00418 
00419     void setGfx(const Graphics::Surface *gfx);
00420     void setGfx(int w, int h, int r, int g, int b);
00421 
00422     void useAlpha(int alpha) { _alpha = alpha; }
00423     void useThemeTransparency(bool enable) { _transparency = enable; }
00424 
00425 protected:
00426     void drawWidget() override;
00427 
00428     Graphics::Surface _gfx;
00429     int _alpha;
00430     bool _transparency;
00431 };
00432 
00433 /* ContainerWidget */
00434 class ContainerWidget : public Widget {
00435 public:
00436     ContainerWidget(GuiObject *boss, int x, int y, int w, int h);
00437     ContainerWidget(GuiObject *boss, const Common::String &name);
00438     ~ContainerWidget() override;
00439 
00440     bool containsWidget(Widget *) const override;
00441     Widget *findWidget(int x, int y) override;
00442     void removeWidget(Widget *widget) override;
00443 
00444     void setBackgroundType(ThemeEngine::WidgetBackground backgroundType);
00445 protected:
00446     void drawWidget() override;
00447 
00448     ThemeEngine::WidgetBackground _backgroundType;
00449 };
00450 
00451 /* OptionsContainerWidget */
00452 class OptionsContainerWidget : public Widget {
00453 public:
00461     OptionsContainerWidget(GuiObject *boss, const Common::String &name, const Common::String &dialogLayout,
00462                            bool scrollable, const Common::String &domain);
00463     ~OptionsContainerWidget() override;
00464 
00466     virtual void load() = 0;
00467 
00473     virtual bool save() = 0;
00474 
00475     void setParentDialog(Dialog *parentDialog) { _parentDialog = parentDialog; }
00476     void setDomain(const Common::String &domain) { _domain = domain; }
00477 
00478 protected:
00479     enum {
00481         kReflowCmd = 'REFL'
00482     };
00483 
00484     // Widget API
00485     void reflowLayout() override;
00486     void drawWidget() override {}
00487     bool containsWidget(Widget *widget) const override;
00488     Widget *findWidget(int x, int y) override;
00489     void removeWidget(Widget *widget) override;
00490 
00492     GuiObject *widgetsBoss();
00493 
00499     virtual void defineLayout(ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const {}
00500 
00501     Common::String _domain;
00502     const Common::String _dialogLayout;
00503 
00504     Dialog *_parentDialog;
00505 
00506 private:
00507     ScrollContainerWidget *_scrollContainer;
00508 };
00509 
00510 ButtonWidget *addClearButton(GuiObject *boss, const Common::String &name, uint32 cmd, int x=0, int y=0, int w=0, int h=0);
00511 
00512 } // End of namespace GUI
00513 
00514 #endif


Generated on Sat Jul 4 2020 05:01:41 for ResidualVM by doxygen 1.7.1
curved edge   curved edge