1 //============================================================================
2 //
3 //   SSSS    tt          lll  lll
4 //  SS  SS   tt           ll   ll
5 //  SS     tttttt  eeee   ll   ll   aaaa
6 //   SSSS    tt   ee  ee  ll   ll      aa
7 //      SS   tt   eeeeee  ll   ll   aaaaa  --  "An Atari 2600 VCS Emulator"
8 //  SS  SS   tt   ee      ll   ll  aa  aa
9 //   SSSS     ttt  eeeee llll llll  aaaaa
10 //
11 // Copyright (c) 1995-2021 by Bradford W. Mott, Stephen Anthony
12 // and the Stella Team
13 //
14 // See the file "License.txt" for information on usage and redistribution of
15 // this file, and for a DISCLAIMER OF ALL WARRANTIES.
16 //
17 //   Based on code from ScummVM - Scumm Interpreter
18 //   Copyright (C) 2002-2004 The ScummVM project
19 //============================================================================
20 
21 #ifndef GUI_OBJECT_HXX
22 #define GUI_OBJECT_HXX
23 
24 class Dialog;
25 class DialogContainer;
26 class Widget;
27 class OSystem;
28 
29 #include "Command.hxx"
30 #include "Vec.hxx"
31 
32 using WidgetArray = vector<Widget*>;
33 
34 /**
35   This is the base class for all GUI objects/widgets.
36 
37   @author  Stephen Anthony
38 */
39 class GuiObject : public CommandReceiver
40 {
41   friend class Widget;
42   friend class DialogContainer;
43 
44   public:
45     enum : uInt32 {
46       FLAG_ENABLED = 1 << 0,
47       FLAG_INVISIBLE = 1 << 1,
48       FLAG_HILITED = 1 << 2,
49       FLAG_BORDER = 1 << 3,
50       FLAG_CLEARBG = 1 << 4,
51       FLAG_TRACK_MOUSE = 1 << 5,
52       FLAG_RETAIN_FOCUS = 1 << 6,
53       FLAG_WANTS_TAB = 1 << 7,
54       FLAG_WANTS_RAWDATA = 1 << 8,
55       FLAG_NOBG = 1 << 9,
56       FLAG_MOUSE_FOCUS = 1 << 10
57     };
58 
59   public:
60     // The commands generated by various widgets
61     enum {
62       kOKCmd           = 'OK  ',
63       kCloseCmd        = 'CLOS',
64       kNextCmd         = 'NEXT',
65       kPrevCmd         = 'PREV',
66       kDefaultsCmd     = 'DEFA',
67       kSetPositionCmd  = 'SETP'
68     };
69 
70   public:
GuiObject(OSystem & osystem,DialogContainer & parent,Dialog & dialog,int x,int y,int w,int h)71     GuiObject(OSystem& osystem, DialogContainer& parent, Dialog& dialog,
72               int x, int y, int w, int h)
73       : myOSystem{osystem},
74         myParent{parent},
75         myDialog{dialog},
76         _x{x}, _y{y}, _w{w}, _h{h} { }
77 
78     ~GuiObject() override = default;
79 
instance() const80     OSystem& instance() const       { return myOSystem; }
parent() const81     DialogContainer& parent() const { return myParent;  }
dialog() const82     Dialog& dialog() const          { return myDialog;  }
83 
getAbsX() const84     virtual int getAbsX() const     { return _x; }
getAbsY() const85     virtual int getAbsY() const     { return _y; }
getChildX() const86     virtual int getChildX() const   { return getAbsX(); }
getChildY() const87     virtual int getChildY() const   { return getAbsY(); }
getWidth() const88     virtual int getWidth() const    { return _w; }
getHeight() const89     virtual int getHeight() const   { return _h; }
90 
setWidth(int w)91     virtual void setWidth(int w)    { _w = w; }
setHeight(int h)92     virtual void setHeight(int h)   { _h = h; }
93 
94     virtual bool isVisible() const = 0;
95 
96     virtual void setDirty() = 0;
97     virtual void setDirtyChain() = 0;
clearDirty()98     void clearDirty() { _dirty = false; }
clearDirtyChain()99     void clearDirtyChain() { _dirtyChain = false; }
isDirty() const100     bool isDirty() const { return _dirty; }
isChainDirty() const101     bool isChainDirty() const { return _dirtyChain; }
102 
103     // The GUI indicates if its underlying surface needs to be redrawn
104     //  and then re-rendered
needsRedraw()105     virtual bool needsRedraw() { return isDirty() || isChainDirty(); }
106 
107     virtual void tick() = 0;
108 
setFlags(uInt32 flags,bool updateDirty=true)109     void setFlags(uInt32 flags, bool updateDirty = true)
110     {
111       uInt32 oldFlags = _flags;
112 
113       _flags |= flags;
114       if(updateDirty && oldFlags != _flags)
115         setDirty();
116     }
clearFlags(uInt32 flags,bool updateDirty=true)117     void clearFlags(uInt32 flags, bool updateDirty = true)
118     {
119       uInt32 oldFlags = _flags;
120 
121       _flags &= ~flags;
122       if(updateDirty && oldFlags != _flags)
123         setDirty();
124     }
getFlags() const125     uInt32 getFlags() const { return _flags; }
126 
hasBorder() const127     bool hasBorder() const { return _flags & FLAG_BORDER; }
clearsBackground() const128     bool clearsBackground() const { return _flags & FLAG_CLEARBG; }
hasBackground() const129     bool hasBackground() const { return !(_flags & FLAG_NOBG); }
130 
131     /** Add given widget(s) to the focus list */
132     virtual void addFocusWidget(Widget* w) = 0;
133     virtual void addToFocusList(const WidgetArray& list) = 0;
134 
135     /** Return focus list for this object */
getFocusList()136     WidgetArray& getFocusList() { return _focusList; }
137 
138     /** Redraw the focus list */
redrawFocus()139     virtual void redrawFocus() { }
140 
141     /** Special characters for menues */
142     const string ELLIPSIS = "\x1d";
143     const string DEGREE = "\x1c";
144 
145   protected:
146     virtual void releaseFocus() = 0;
147     virtual void draw() = 0;
148     virtual void drawChain() = 0;
149 
150     virtual const string getHelpURL() const = 0;
151     virtual bool hasHelp() const = 0;
152 
153   private:
154     OSystem&         myOSystem;
155     DialogContainer& myParent;
156     Dialog&          myDialog;
157 
158   protected:
159     int         _x{0}, _y{0}, _w{0}, _h{0};
160     bool        _dirty{false};
161     bool        _dirtyChain{false};
162     uInt32      _flags{0};
163 
164     Widget*     _firstWidget{nullptr};
165     WidgetArray _focusList;
166 
167   private:
168     // Following constructors and assignment operators not supported
169     GuiObject() = delete;
170     GuiObject(const GuiObject&) = delete;
171     GuiObject(GuiObject&&) = delete;
172     GuiObject& operator=(const GuiObject&) = delete;
173     GuiObject& operator=(GuiObject&&) = delete;
174 };
175 
176 #endif
177