Simple GUI Library
gui_event.h
Go to the documentation of this file.
1/**
2 * @author Nikita Mochalov (github.com/tralf-strues)
3 * @file gui_event.h
4 * @date 2021-10-23
5 *
6 * @copyright Copyright (c) 2021
7 */
8
9#pragma once
10
11#include "sml/events/event.h"
12#include "sml/events/system_events.h"
13#include "sml/sml_log.h"
14
15namespace Sgl
16{
17 enum GuiEventType
18 {
19 MOUSE_ENTERED = Sml::SML_EVENT_TYPE_FIRST_UNSPECIFIED,
20 MOUSE_EXITED,
21
22 FOCUS_RECEIVED,
23 FOCUS_LOST,
24 ACTION_PERFORMED,
25
26 /* Drag & drop events */
27 DRAG_START,
28 DRAG_END,
29 DRAG_MOVE
30 };
31
32 enum GuiEventCategory
33 {
34 EVENT_CATEGORY_GUI = Sml::SML_EVENT_CATEGORY_FIRST_UNSPECIFIED,
35 EVENT_CATEGORY_DRAG_AND_DROP
36 };
37
38 class Component;
39
40 //------------------------------------------------------------------------------
41 // Event category [GUI]
42 //------------------------------------------------------------------------------
43 template<typename C>
44 class ComponentEventListener : public Sml::Listener
45 {
46 public:
47 ComponentEventListener(C* component) : m_Component(component) {}
48 C* getComponent() { return m_Component; }
49 void setComponent(C* component) { m_Component = component; }
50
51 private:
52 C* m_Component = nullptr;
53 };
54
55 class MouseEnteredEvent : public Sml::MouseEvent
56 {
57 public:
58 MouseEnteredEvent(int32_t x = 0, int32_t y = 0, Sml::EventTarget* target = nullptr)
59 : Sml::MouseEvent(x, y, target)
60 {
61 m_Type = getStaticType();
62 m_Category = getStaticCategory();
63 }
64
65 DEFINE_STATIC_EVENT_TYPE(MOUSE_ENTERED)
66 DEFINE_STATIC_EVENT_CATEGORY(EVENT_CATEGORY_GUI | Sml::MouseEvent::getStaticCategory())
67 };
68
69 class MouseExitedEvent : public Sml::MouseEvent
70 {
71 public:
72 MouseExitedEvent(int32_t x = 0, int32_t y = 0, Sml::EventTarget* target = nullptr)
73 : Sml::MouseEvent(x, y, target)
74 {
75 m_Type = getStaticType();
76 m_Category = getStaticCategory();
77 }
78
79 DEFINE_STATIC_EVENT_TYPE(MOUSE_EXITED)
80 DEFINE_STATIC_EVENT_CATEGORY(EVENT_CATEGORY_GUI | Sml::MouseEvent::getStaticCategory())
81 };
82
83 template<typename C>
85 {
86 public:
87 DEFINE_STATIC_LISTENED_EVENT_TYPES(MouseEnteredEvent::getStaticType(),
88 MouseExitedEvent::getStaticType())
89 public:
90 HoverListener(C* component) : ComponentEventListener<C>(component) {}
91
92 virtual void onEvent(Sml::Event* event) override final
93 {
94 switch (event->getType())
95 {
96 case MouseEnteredEvent::getStaticType():
97 {
98 onMouseEntered(dynamic_cast<MouseEnteredEvent*>(event));
99 break;
100 }
101
102 case MouseExitedEvent::getStaticType():
103 {
104 onMouseExited(dynamic_cast<MouseExitedEvent*>(event));
105 break;
106 }
107
108 default:
109 {
110 LOG_LIB_ERROR("HoverListener got invalid Event with type %" PRIu32, event->getType());
111 break;
112 }
113 };
114
115 event->consume();
116 }
117
118 virtual void onMouseEntered(MouseEnteredEvent* event) {}
119 virtual void onMouseExited(MouseExitedEvent* event) {}
120
121 private:
122 };
123
124 class FocusReceivedEvent : public Sml::Event
125 {
126 public:
127 FocusReceivedEvent(Component* prevFocus, Sml::EventTarget* target = nullptr)
128 : Sml::Event(getStaticType(), getStaticCategory(), target), m_PreviousFocus(prevFocus) {}
129
130 Component* getPreviousFocus() { return m_PreviousFocus; }
131 Component* getNewFocus() { return reinterpret_cast<Component*>(m_Target); }
132
133 DEFINE_STATIC_EVENT_TYPE(FOCUS_RECEIVED)
134 DEFINE_STATIC_EVENT_CATEGORY(EVENT_CATEGORY_GUI)
135
136 private:
137 Component* m_PreviousFocus = nullptr;
138 };
139
140 class FocusLostEvent : public Sml::Event
141 {
142 public:
143 FocusLostEvent(Component* newFocus, Sml::EventTarget* target = nullptr)
144 : Sml::Event(getStaticType(), getStaticCategory(), target), m_NewFocus(newFocus) {}
145
146 Component* getPreviousFocus() { return reinterpret_cast<Component*>(m_Target); }
147 Component* getNewFocus() { return m_NewFocus; }
148
149 DEFINE_STATIC_EVENT_TYPE(FOCUS_LOST)
150 DEFINE_STATIC_EVENT_CATEGORY(EVENT_CATEGORY_GUI)
151
152 private:
153 Component* m_NewFocus = nullptr;
154 };
155
156 template<typename C>
158 {
159 public:
160 DEFINE_STATIC_LISTENED_EVENT_TYPES(FocusReceivedEvent::getStaticType(), FocusLostEvent::getStaticType())
161
162 public:
163 FocusListener(C* component) : ComponentEventListener<C>(component) {}
164
165 virtual void onEvent(Sml::Event* event) override final
166 {
167 switch (event->getType())
168 {
169 case FocusReceivedEvent::getStaticType():
170 {
171 onFocusReceived(dynamic_cast<FocusReceivedEvent*>(event));
172 break;
173 }
174
175 case FocusLostEvent::getStaticType():
176 {
177 onFocusLost(dynamic_cast<FocusLostEvent*>(event));
178 break;
179 }
180
181 default:
182 {
183 LOG_LIB_ERROR("FocusListener received invalid event of type %d!", event->getType());
184 }
185 }
186
187 event->consume();
188 }
189
190 virtual void onFocusReceived(FocusReceivedEvent* event) {}
191 virtual void onFocusLost(FocusLostEvent* event) {}
192 };
193
194 class ActionEvent : public Sml::Event
195 {
196 public:
197 ActionEvent(Sml::EventTarget* target = nullptr)
198 : Sml::Event(getStaticType(), getStaticCategory(), target) {}
199
200 DEFINE_STATIC_EVENT_TYPE(ACTION_PERFORMED)
201 DEFINE_STATIC_EVENT_CATEGORY(EVENT_CATEGORY_GUI)
202 };
203
204 template<typename C>
206 {
207 public:
208 DEFINE_STATIC_LISTENED_EVENT_TYPES(ActionEvent::getStaticType())
209
210 public:
211 ActionListener(C* component = nullptr) : ComponentEventListener<C>(component) {}
212
213 virtual void onEvent(Sml::Event* event) override final
214 {
215 onAction(dynamic_cast<ActionEvent*>(event));
216 event->consume();
217 }
218
219 virtual void onAction(ActionEvent* event) = 0;
220 };
221
222 //------------------------------------------------------------------------------
223 // Event category [GUI->DRAG_AND_DROP]
224 //------------------------------------------------------------------------------
225 class DragEvent : public Sml::Event
226 {
227 public:
228 DragEvent(int32_t x, int32_t y, Sml::EventTarget* target = nullptr)
229 : Sml::Event(getStaticType(), getStaticCategory(), target), m_X(x), m_Y(y) {}
230
231 DEFINE_STATIC_EVENT_TYPE(Sml::INVALID_EVENT_TYPE)
232 DEFINE_STATIC_EVENT_CATEGORY(EVENT_CATEGORY_GUI | EVENT_CATEGORY_DRAG_AND_DROP)
233
234 int32_t getX() const { return m_X; }
235 void setX(int32_t x) { m_X = x; }
236
237 int32_t getY() const { return m_Y; }
238 void setY(int32_t y) { m_Y = y; }
239
240 private:
241 int32_t m_X = 0;
242 int32_t m_Y = 0;
243 };
244
246 {
247 public:
248 DragStartEvent(int32_t x, int32_t y, Sml::EventTarget* target = nullptr) : DragEvent(x, y, target)
249 {
250 m_Type = getStaticType();
251 m_Category = getStaticCategory();
252 }
253
254 DEFINE_STATIC_EVENT_TYPE(DRAG_START)
255 DEFINE_STATIC_EVENT_CATEGORY(DragEvent::getStaticCategory())
256 };
257
258 class DragEndEvent : public DragEvent
259 {
260 public:
261 DragEndEvent(int32_t x, int32_t y, Sml::EventTarget* target = nullptr) : DragEvent(x, y, target)
262 {
263 m_Type = getStaticType();
264 m_Category = getStaticCategory();
265 }
266
267 DEFINE_STATIC_EVENT_TYPE(DRAG_END)
268 DEFINE_STATIC_EVENT_CATEGORY(DragEvent::getStaticCategory())
269 };
270
272 {
273 public:
274 DragMoveEvent(int32_t x, int32_t y, int32_t deltaX, int32_t deltaY, Sml::EventTarget* target = nullptr)
275 : DragEvent(x, y, target), m_DeltaX(deltaX), m_DeltaY(deltaY)
276 {
277 m_Type = getStaticType();
278 m_Category = getStaticCategory();
279 }
280
281 int32_t getDeltaX() const { return m_DeltaX; }
282 int32_t getDeltaY() const { return m_DeltaY; }
283
284 DEFINE_STATIC_EVENT_TYPE(DRAG_MOVE)
285 DEFINE_STATIC_EVENT_CATEGORY(DragEvent::getStaticCategory())
286
287 private:
288 int32_t m_DeltaX = 0;
289 int32_t m_DeltaY = 0;
290 };
291
292 template<typename C>
294 {
295 public:
296 DEFINE_STATIC_LISTENED_EVENT_TYPES(DragStartEvent::getStaticType(),
297 DragEndEvent::getStaticType(),
298 DragMoveEvent::getStaticType())
299
300 public:
301 DragListener(C* component) : ComponentEventListener<C>(component) {}
302
303 virtual void onEvent(Sml::Event* event) override final
304 {
305 switch (event->getType())
306 {
307 case DragStartEvent::getStaticType():
308 {
309 onDragStart(dynamic_cast<DragStartEvent*>(event));
310 break;
311 }
312
313 case DragEndEvent::getStaticType():
314 {
315 onDragEnd(dynamic_cast<DragEndEvent*>(event));
316 break;
317 }
318
319 case DragMoveEvent::getStaticType():
320 {
321 onDragMove(dynamic_cast<DragMoveEvent*>(event));
322 break;
323 }
324 }
325
326 event->consume();
327 }
328
329 virtual void onDragStart(DragStartEvent* event) {}
330 virtual void onDragEnd(DragEndEvent* event) {}
331 virtual void onDragMove(DragMoveEvent* event) {}
332 };
333}