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-2019 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 | |
18 | #ifndef DIALOG_CONTAINER_HXX |
19 | #define DIALOG_CONTAINER_HXX |
20 | |
21 | class Dialog; |
22 | class OSystem; |
23 | class EventHandler; |
24 | |
25 | #include "EventHandlerConstants.hxx" |
26 | #include "StellaKeys.hxx" |
27 | #include "Stack.hxx" |
28 | #include "bspf.hxx" |
29 | |
30 | /** |
31 | The base class for groups of dialog boxes. Each dialog box has a |
32 | parent. In most cases, the parent is itself a dialog box, but in the |
33 | case of the lower-most dialog box, this class is its parent. |
34 | |
35 | This class keeps track of its children (dialog boxes), organizes them into |
36 | a stack, and handles their events. |
37 | |
38 | @author Stephen Anthony |
39 | */ |
40 | class DialogContainer |
41 | { |
42 | friend class EventHandler; |
43 | friend class Dialog; |
44 | |
45 | public: |
46 | /** |
47 | Create a new DialogContainer stack |
48 | */ |
49 | explicit DialogContainer(OSystem& osystem); |
50 | virtual ~DialogContainer() = default; |
51 | |
52 | public: |
53 | /** |
54 | Update the dialog container with the current time. |
55 | This is useful if we want to trigger events at some specified time. |
56 | |
57 | @param time The current time in microseconds |
58 | */ |
59 | void updateTime(uInt64 time); |
60 | |
61 | /** |
62 | Handle a keyboard Unicode text event. |
63 | |
64 | @param text Unicode character string |
65 | */ |
66 | void handleTextEvent(char text); |
67 | |
68 | /** |
69 | Handle a keyboard single-key event. |
70 | |
71 | @param key Actual key symbol |
72 | @param mod Modifiers |
73 | @param pressed Pressed (true) or released (false) |
74 | */ |
75 | void handleKeyEvent(StellaKey key, StellaMod mod, bool pressed, bool repeat); |
76 | |
77 | /** |
78 | Handle a mouse motion event. |
79 | |
80 | @param x The x location |
81 | @param y The y location |
82 | */ |
83 | void handleMouseMotionEvent(int x, int y); |
84 | |
85 | /** |
86 | Handle a mouse button event. |
87 | |
88 | @param b The mouse button |
89 | @param pressed Whether the button was pressed (true) or released (false) |
90 | @param x The x location |
91 | @param y The y location |
92 | */ |
93 | void handleMouseButtonEvent(MouseButton b, bool pressed, int x, int y); |
94 | |
95 | /** |
96 | Handle a joystick button event. |
97 | |
98 | @param stick The joystick number |
99 | @param button The joystick button |
100 | @param pressed Pressed (true) or released (false) |
101 | */ |
102 | void handleJoyBtnEvent(int stick, int button, bool pressed); |
103 | |
104 | /** |
105 | Handle a joystick axis event. |
106 | |
107 | @param stick The joystick number |
108 | @param axis The joystick axis |
109 | @param adir Value associated with given axis |
110 | */ |
111 | void handleJoyAxisEvent(int stick, JoyAxis axis, JoyDir adir, int button); |
112 | |
113 | /** |
114 | Handle a joystick hat event. |
115 | |
116 | @param stick The joystick number |
117 | @param hat The joystick hat |
118 | @param hdir Direction of the given hat |
119 | */ |
120 | void handleJoyHatEvent(int stick, int hat, JoyHatDir hdir, int button); |
121 | |
122 | /** |
123 | Draw the stack of menus (full indicates to redraw all items). |
124 | |
125 | @return Answers whether any drawing actually occurred. |
126 | */ |
127 | bool draw(bool full = false); |
128 | |
129 | /** |
130 | Answers whether a full redraw is required. |
131 | */ |
132 | bool needsRedraw() const; |
133 | |
134 | /** |
135 | Answers whether the base dialog is currently active |
136 | (ie, there are no overlaid dialogs other than the bottom one) |
137 | */ |
138 | bool baseDialogIsActive() const; |
139 | |
140 | /** |
141 | Reset dialog stack to the main configuration menu. |
142 | */ |
143 | void reStack(); |
144 | |
145 | /** |
146 | Inform the container that it should resize according to the current |
147 | screen dimensions. We make this virtual, since the container may or |
148 | may not choose to do a resize, and even if it does, *how* it does it |
149 | is determined by the specific container. |
150 | */ |
151 | virtual void requestResize() { } |
152 | |
153 | /** |
154 | Return (and possibly create) the bottom-most dialog of this container. |
155 | */ |
156 | virtual Dialog* baseDialog() = 0; |
157 | |
158 | /** |
159 | Set input speeds |
160 | */ |
161 | static void setDoubleClickDelay(int delay) { _DOUBLE_CLICK_DELAY = delay; } |
162 | static void setControllerDelay(int delay) { _REPEAT_INITIAL_DELAY = delay; } |
163 | static void setControllerRate(int rate) { _REPEAT_SUSTAIN_DELAY = 1000 / rate; } |
164 | |
165 | private: |
166 | void reset(); |
167 | |
168 | /** |
169 | Add a dialog box to the stack. |
170 | */ |
171 | int addDialog(Dialog* d); |
172 | |
173 | /** |
174 | Remove the topmost dialog box from the stack. |
175 | */ |
176 | void removeDialog(); |
177 | |
178 | protected: |
179 | OSystem& myOSystem; |
180 | Common::FixedStack<Dialog*> myDialogStack; |
181 | |
182 | private: |
183 | // Indicates the most current time (in milliseconds) as set by updateTime() |
184 | uInt64 myTime; |
185 | |
186 | static uInt64 _DOUBLE_CLICK_DELAY; |
187 | static uInt64 _REPEAT_INITIAL_DELAY; |
188 | static uInt64 _REPEAT_SUSTAIN_DELAY; |
189 | static constexpr uInt64 _REPEAT_NONE = 1 << 24; // loooong |
190 | static constexpr uInt64 _LONG_PRESS_DELAY = 1000; // 1 second |
191 | |
192 | // For continuous 'mouse down' events |
193 | struct { |
194 | int x; |
195 | int y; |
196 | MouseButton b; |
197 | } myCurrentMouseDown; |
198 | uInt64 myClickRepeatTime; |
199 | |
200 | // For continuous 'joy button down' events |
201 | struct { |
202 | int stick; |
203 | int button; |
204 | } myCurrentButtonDown; |
205 | uInt64 myButtonRepeatTime; |
206 | uInt64 myButtonLongPressTime; |
207 | |
208 | // For continuous 'joy axis down' events |
209 | struct { |
210 | int stick; |
211 | JoyAxis axis; |
212 | JoyDir adir; |
213 | } myCurrentAxisDown; |
214 | uInt64 myAxisRepeatTime; |
215 | |
216 | // For continuous 'joy hat' events |
217 | struct { |
218 | int stick; |
219 | int hat; |
220 | JoyHatDir hdir; |
221 | } myCurrentHatDown; |
222 | uInt64 myHatRepeatTime; |
223 | |
224 | // Position and time of last mouse click (used to detect double clicks) |
225 | struct { |
226 | int x, y; // Position of mouse when the click occurred |
227 | int count; // How often was it already pressed? |
228 | uInt64 time; // Time |
229 | } myLastClick; |
230 | |
231 | private: |
232 | // Following constructors and assignment operators not supported |
233 | DialogContainer() = delete; |
234 | DialogContainer(const DialogContainer&) = delete; |
235 | DialogContainer(DialogContainer&&) = delete; |
236 | DialogContainer& operator=(const DialogContainer&) = delete; |
237 | DialogContainer& operator=(DialogContainer&&) = delete; |
238 | }; |
239 | |
240 | #endif |
241 | |