Sparkle 0.0.1
Loading...
Searching...
No Matches
spk_widget.hpp
1#pragma once
2
3#include <array>
4#include <limits>
5#include <optional>
6#include <stdexcept>
7#include <string>
8#include <vector>
9
10#include "structure/design_pattern/spk_activable_object.hpp"
11#include "structure/design_pattern/spk_inherence_object.hpp"
12
13#include "structure/graphics/spk_extend_2d.hpp"
14
15#include "structure/system/event/spk_keyboard_event.hpp"
16#include "structure/system/event/spk_mouse_event.hpp"
17#include "structure/system/event/spk_paint_event.hpp"
18#include "structure/system/event/spk_system_event.hpp"
19#include "structure/system/event/spk_update_event.hpp"
20
21#include "structure/opengl/spk_view_region.hpp"
22
23#include "structure/widget/spk_resizable_element.hpp"
24
25#include "structure/graphics/spk_font.hpp"
26#include "structure/graphics/spk_sprite_sheet.hpp"
27
28#include "structure/graphics/painter/spk_texture_painter.hpp"
29
30namespace spk
31{
32 namespace Module
33 {
34 class KeyboardModule;
35 class MouseModule;
36 class SystemModule;
37 class UpdateModule;
38 class PaintModule;
39 }
40
51 class Widget : public InherenceObject<Widget>, public ActivableObject, public ResizableElement
52 {
53 public:
86
88 enum class FocusType
89 {
90 Keyboard = 0,
91 Mouse = 1
92 };
93
94 static inline const size_t NbFocusType = 2;
95
96 private:
97 static inline std::array<Widget *, NbFocusType> _focusedWidgets = {nullptr, nullptr};
98
99 public:
105 static Widget *focusedWidget(FocusType p_focusType);
106
111 void takeFocus(FocusType p_focusType);
112
118 void releaseFocus(FocusType p_focusType);
119
125 bool hasFocus(FocusType p_focusType) const;
126
130 void takeAllFocus();
131
135 void releaseAllFocus();
136
137 private:
138 template <typename TEvent>
139 using EventHandler = void (Widget::*)(TEvent &);
140
141 template <typename TEvent>
142 void _propagateEvent(TEvent &p_event, EventHandler<TEvent> p_onEventHandler, EventHandler<TEvent> p_childHandler)
143 {
144 if (isActive() == false || p_event.isConsumed == true)
145 {
146 return;
147 }
148
149 for (auto child : children())
150 {
151 if (child != nullptr)
152 {
153 (child->*p_childHandler)(p_event);
154
155 if (p_event.isConsumed == true)
156 {
157 break;
158 }
159 }
160 }
161
162 if (p_event.isConsumed == true)
163 {
164 return;
165 }
166
167 (this->*p_onEventHandler)(p_event);
168 }
169
170 private:
171 std::wstring _name;
172
173 bool _isViewRegionUpdatePending = false;
174 spk::Vector2 _anchorRatio = {0.0f, 0.0f};
175 spk::Vector2 _sizeRatio = {1.0f, 1.0f};
176 spk::OpenGL::ViewRegion _viewRegion;
177 spk::Extend2D _geometry = {{0.0f, 0.0f}, {0.0f, 0.0f}};
178
179 std::recursive_mutex _geometryEditionMutex;
180
181 spk::OpenGL::FrameBufferObject _fbo;
182
183 spk::TexturePainter _painter;
184 spk::TextureMesh _fboMesh;
185
186 float _layer = 0;
187
188 void _computeRatio();
189
190 void _sortChildByLayer();
191
192 void _applyResize();
193
194 public:
200 Widget(const std::wstring &p_name, Widget *p_parent);
201 ~Widget() override;
202
207 void addChild(Widget *p_child) override;
208
213 const float &layer() const;
214
219 void setLayer(const float &p_newLayer);
220
225 const std::wstring &name() const;
226
231 void setName(const std::wstring &p_name);
232
238 void setGeometry(const spk::Extend2D &p_geometry) override;
239
244 const spk::Extend2D &geometry() const;
245
250 const spk::OpenGL::ViewRegion &viewRegion() const;
251
257 const spk::OpenGL::FrameBufferObject &frameBufferObject() const;
263 const spk::OpenGL::FrameBufferObject &fbo() const;
264
269
270 protected:
275 virtual void _onPaintEvent(spk::PaintEvent &p_event);
276
281 virtual void _onKeyPressEvent(spk::KeyPressEvent &p_event);
282
287 virtual void _onKeyReleaseEvent(spk::KeyReleaseEvent &p_event);
288
293 virtual void _onGlyphEvent(spk::GlyphEvent &p_event);
294
299 virtual void _onMousePressEvent(spk::MousePressEvent &p_event);
300
305 virtual void _onMouseReleaseEvent(spk::MouseReleaseEvent &p_event);
306
311 virtual void _onMouseDoubleClickEvent(spk::MouseDoubleClickEvent &p_event);
312
317 virtual void _onMouseMotionEvent(spk::MouseMotionEvent &p_event);
318
323 virtual void _onMouseWheelEvent(spk::MouseWheelEvent &p_event);
324
329 virtual void _onEnterResizeModeEvent(spk::EnterResizeModeEvent &p_event);
330
335 virtual void _onResizeEvent(spk::ResizeEvent &p_event);
336
341 virtual void _onExitResizeModeEvent(spk::ExitResizeModeEvent &p_event);
342
347 virtual void _onQuitEvent(spk::QuitEvent &p_event);
348
353 virtual void _onMoveEvent(spk::MoveEvent &p_event);
354
359 virtual void _onFullScreenModeEvent(spk::FullScreenModeEvent &p_event);
360
365 virtual void _onMaximizedModeEvent(spk::MaximizedModeEvent &p_event);
366
371 virtual void _onFocusEvent(spk::FocusEvent &p_event);
372
377 virtual void _onUpdateEvent(spk::UpdateEvent &p_event);
378
380 virtual void _onGeometryChange();
381
382 private:
383 friend class Module::KeyboardModule;
384 friend class Module::MouseModule;
385 friend class Module::SystemModule;
386 friend class Module::UpdateModule;
387 friend class Module::PaintModule;
388
389 void _handlePaintEvent(spk::PaintEvent &p_event);
390
391 void _handleKeyPressEvent(spk::KeyPressEvent &p_event);
392
393 void _handleKeyReleaseEvent(spk::KeyReleaseEvent &p_event);
394
395 void _handleGlyphEvent(spk::GlyphEvent &p_event);
396
397 void _handleMousePressEvent(spk::MousePressEvent &p_event);
398
399 void _handleMouseReleaseEvent(spk::MouseReleaseEvent &p_event);
400
401 void _handleMouseDoubleClickEvent(spk::MouseDoubleClickEvent &p_event);
402
403 void _handleMouseMotionEvent(spk::MouseMotionEvent &p_event);
404
405 void _handleMouseWheelEvent(spk::MouseWheelEvent &p_event);
406
407 void _handleEnterResizeModeEvent(spk::EnterResizeModeEvent &p_event);
408
409 void _handleResizeEvent(spk::ResizeEvent &p_event);
410
411 void _handleExitResizeModeEvent(spk::ExitResizeModeEvent &p_event);
412
413 void _handleQuitEvent(spk::QuitEvent &p_event);
414
415 void _handleMoveEvent(spk::MoveEvent &p_event);
416
417 void _handleFullScreenModeEvent(spk::FullScreenModeEvent &p_event);
418
419 void _handleMaximizedModeEvent(spk::MaximizedModeEvent &p_event);
420
421 void _handleFocusEvent(spk::FocusEvent &p_event);
422
423 void _handleUpdateEvent(spk::UpdateEvent &p_event);
424 };
425}
ActivableObject()
Builds a deactivated object.
Definition spk_activable_object.hpp:35
bool isActive() const
Checks whether the object is currently activated.
Definition spk_activable_object.hpp:77
Loads font data and provides cached bitmap atlases per size.
Definition spk_font.hpp:33
virtual std::vector< Widget * > & children()
Definition spk_inherence_object.hpp:94
Dispatches keyboard events to a bound widget and tracks keyboard state.
Definition spk_keyboard_module.hpp:23
Dispatches mouse events to a bound widget and tracks mouse state.
Definition spk_mouse_module.hpp:23
Forwards paint events to the bound widget.
Definition spk_paint_module.hpp:17
Handles system-level events (creation, resize, quit) for the application and its widget tree.
Definition spk_system_module.hpp:18
Forwards update ticks to the bound widget.
Definition spk_update_module.hpp:17
Loads an image and exposes individual sprite regions.
Definition spk_sprite_sheet.hpp:21
Base class for interactive UI elements handling focus and events.
Definition spk_widget.hpp:52
void setGeometry(const spk::Extend2D &p_geometry) override
Requests a specific viewport and scissor region for the widget.
Definition spk_widget.cpp:168
const spk::OpenGL::ViewRegion & viewRegion() const
Accesses the computed view region.
Definition spk_widget.cpp:200
virtual void _onResizeEvent(spk::ResizeEvent &p_event)
Resize handling hook.
Definition spk_widget.cpp:260
virtual void _onQuitEvent(spk::QuitEvent &p_event)
Quit event handler hook.
Definition spk_widget.cpp:268
virtual void _onMouseWheelEvent(spk::MouseWheelEvent &p_event)
Mouse wheel handler for derived widgets.
Definition spk_widget.cpp:252
virtual void _onMouseDoubleClickEvent(spk::MouseDoubleClickEvent &p_event)
Mouse double click handler for derived widgets.
Definition spk_widget.cpp:244
virtual void _onUpdateEvent(spk::UpdateEvent &p_event)
Frame update handler hook.
Definition spk_widget.cpp:288
virtual void _onKeyPressEvent(spk::KeyPressEvent &p_event)
Keyboard press handler for derived widgets.
Definition spk_widget.cpp:224
virtual void _onGeometryChange()
Notifies derived widgets that the view region changed.
Definition spk_widget.cpp:292
virtual void _onPaintEvent(spk::PaintEvent &p_event)
Paint event hook for derived widgets.
Definition spk_widget.cpp:220
virtual void _onMousePressEvent(spk::MousePressEvent &p_event)
Mouse button press handler for derived widgets.
Definition spk_widget.cpp:236
virtual void _onMouseReleaseEvent(spk::MouseReleaseEvent &p_event)
Mouse button release handler for derived widgets.
Definition spk_widget.cpp:240
virtual void _onMouseMotionEvent(spk::MouseMotionEvent &p_event)
Mouse motion handler for derived widgets.
Definition spk_widget.cpp:248
virtual void _onEnterResizeModeEvent(spk::EnterResizeModeEvent &p_event)
Callback for entering resize mode.
Definition spk_widget.cpp:256
const spk::Extend2D & geometry() const
Returns the current widget geometry.
Definition spk_widget.cpp:195
virtual void _onMoveEvent(spk::MoveEvent &p_event)
Window move handler hook.
Definition spk_widget.cpp:272
virtual void _onExitResizeModeEvent(spk::ExitResizeModeEvent &p_event)
Callback invoked when leaving resize mode.
Definition spk_widget.cpp:264
static const size_t NbFocusType
Number of focus slots tracked at runtime.
Definition spk_widget.hpp:94
Widget(const std::wstring &p_name, Widget *p_parent)
Builds a widget optionally attached to a parent.
Definition spk_widget.cpp:103
void takeAllFocus()
Acquires both keyboard and mouse focus.
Definition spk_widget.cpp:48
const float & layer() const
Current rendering layer of the widget.
Definition spk_widget.cpp:136
virtual void _onFocusEvent(spk::FocusEvent &p_event)
Focus change handler hook.
Definition spk_widget.cpp:284
FocusType
Types of focus a widget can own.
Definition spk_widget.hpp:89
virtual void _onFullScreenModeEvent(spk::FullScreenModeEvent &p_event)
Full screen toggle handler hook.
Definition spk_widget.cpp:276
void releaseFocus(FocusType p_focusType)
Releases a previously acquired focus type.
Definition spk_widget.cpp:34
bool hasFocus(FocusType p_focusType) const
Checks if this widget currently owns a focus type.
Definition spk_widget.cpp:43
virtual void _onKeyReleaseEvent(spk::KeyReleaseEvent &p_event)
Keyboard release handler for derived widgets.
Definition spk_widget.cpp:228
void releaseAllFocus()
Releases both keyboard and mouse focus types.
Definition spk_widget.cpp:54
virtual void _onMaximizedModeEvent(spk::MaximizedModeEvent &p_event)
Maximized mode change handler.
Definition spk_widget.cpp:280
const spk::OpenGL::FrameBufferObject & frameBufferObject() const
Returns the frame buffer object used for widget rendering.
Definition spk_widget.cpp:205
void setName(const std::wstring &p_name)
Sets the widget name.
Definition spk_widget.cpp:163
void takeFocus(FocusType p_focusType)
Grants this widget ownership of the requested focus type.
Definition spk_widget.cpp:29
const spk::OpenGL::FrameBufferObject & fbo() const
Alias for frameBufferObject().
Definition spk_widget.cpp:210
static Widget * focusedWidget(FocusType p_focusType)
Retrieves the widget currently owning a focus type.
Definition spk_widget.cpp:24
virtual void _onGlyphEvent(spk::GlyphEvent &p_event)
Text glyph input handler for derived widgets.
Definition spk_widget.cpp:232
void addChild(Widget *p_child) override
Adds a child widget and sorts the hierarchy by layer.
Definition spk_widget.cpp:130
void setLayer(const float &p_newLayer)
Updates the widget layer and propagates relative offsets to children.
Definition spk_widget.cpp:141
const std::wstring & name() const
Retrieves the widget name.
Definition spk_widget.cpp:158
void requireGeometryChange()
Marks the widget view region as needing recomputation.
Definition spk_widget.cpp:215
Defines glyph and outline sizes for a font bitmap.
Definition spk_font.hpp:40
Collection of default assets used by widgets when no overrides are supplied.
Definition spk_widget.hpp:64
static spk::SpriteSheet defaultInterfaceWindowButtonReleased
Default sprite sheet for released interface window buttons.
Definition spk_widget.hpp:74
static spk::SpriteSheet defaultNineSliceLight
Default light-themed nine-slice sprite sheet.
Definition spk_widget.hpp:70
static spk::SpriteSheet defaultBreak
Default sprite sheet for separators and breaks.
Definition spk_widget.hpp:80
static spk::SpriteSheet defaultInterfaceWindowButtonPressed
Default sprite sheet for pressed interface window buttons.
Definition spk_widget.hpp:76
static spk::SpriteSheet defaultSliderBody
Default sprite sheet for slider bodies.
Definition spk_widget.hpp:78
static spk::Font::Size defaultFontSize
Default font size used when widgets do not specify one.
Definition spk_widget.hpp:84
static spk::Font defaultFont
Default font used when widgets do not specify one.
Definition spk_widget.hpp:82
static spk::SpriteSheet defaultIconset
Default sprite sheet used for widget icons.
Definition spk_widget.hpp:72
static spk::SpriteSheet defaultNineSlice
Default nine-slice sprite sheet for general widget backgrounds.
Definition spk_widget.hpp:66
static spk::SpriteSheet defaultPressedNineSlice
Default nine-slice sprite sheet for pressed widget backgrounds.
Definition spk_widget.hpp:68