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
21class Dialog;
22class OSystem;
23class 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*/
40class 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