Cleanup
[carla.git] / source / modules / dgl / Widget.hpp
blob38a49b1f160ad9567bb18888a49c63878177b9fb
1 /*
2 * DISTRHO Plugin Framework (DPF)
3 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
5 * Permission to use, copy, modify, and/or distribute this software for any purpose with
6 * or without fee is hereby granted, provided that the above copyright notice and this
7 * permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #ifndef DGL_WIDGET_HPP_INCLUDED
18 #define DGL_WIDGET_HPP_INCLUDED
20 #include "Geometry.hpp"
22 START_NAMESPACE_DGL
24 // --------------------------------------------------------------------------------------------------------------------
25 // Forward class names
27 class Application;
28 class SubWidget;
29 class TopLevelWidget;
30 class Window;
32 // --------------------------------------------------------------------------------------------------------------------
34 /**
35 Base DGL Widget class.
37 This is the base Widget class, from which all widgets are built.
39 All widgets have a parent widget where they'll be drawn, this can be the top-level widget or a group widget.
40 This parent is never changed during a widget's lifetime.
42 Widgets receive events in relative coordinates. (0, 0) means its top-left position.
44 The top-level widget will draw subwidgets in the order they are constructed.
45 Early subwidgets are drawn first, at the bottom, then newer ones on top.
46 Events are sent in the inverse order so that the top-most widgets get
47 a chance to catch the event and stop its propagation.
49 All widget event callbacks do nothing by default and onDisplay MUST be reimplemented by subclasses.
51 @note It is not possible to subclass this Widget class directly, you must use SubWidget or TopLevelWidget instead.
53 class Widget
55 public:
56 /**
57 Base event data.
58 These are the fields present on all Widget events.
60 struct BaseEvent {
61 /** Currently active keyboard modifiers. @see Modifier */
62 uint mod;
63 /** Event flags. @see EventFlag */
64 uint flags;
65 /** Event timestamp (if any). */
66 uint time;
68 /** Constructor for default/null values */
69 BaseEvent() noexcept : mod(0x0), flags(0x0), time(0) {}
70 /** Destuctor */
71 virtual ~BaseEvent() noexcept {}
74 /**
75 Keyboard event.
77 This event represents low-level key presses and releases.
78 This can be used for "direct" keyboard handing like key bindings, but must not be interpreted as text input.
80 Keys are represented portably as Unicode code points, using the "natural" code point for the key.
81 The @a key field is the code for the pressed key, without any modifiers applied.
82 For example, a press or release of the 'A' key will have `key` 97 ('a')
83 regardless of whether shift or control are being held.
85 Alternatively, the raw @a keycode can be used to work directly with physical keys,
86 but note that this value is not portable and differs between platforms and hardware.
88 @see onKeyboard
90 struct KeyboardEvent : BaseEvent {
91 /** True if the key was pressed, false if released. */
92 bool press;
93 /** Unicode point of the key pressed. */
94 uint key;
95 /** Raw keycode. */
96 uint keycode;
98 /** Constructor for default/null values */
99 KeyboardEvent() noexcept
100 : BaseEvent(),
101 press(false),
102 key(0),
103 keycode(0) {}
107 Special keyboard event.
109 DEPRECATED This used to be part of DPF due to pugl, but now deprecated and simply non-functional.
110 All events go through KeyboardEvent or CharacterInputEvent, use those instead.
112 struct DISTRHO_DEPRECATED_BY("KeyboardEvent") SpecialEvent : BaseEvent {
113 bool press;
114 Key key;
116 /** Constructor for default/null values */
117 SpecialEvent() noexcept
118 : BaseEvent(),
119 press(false),
120 key(Key(0)) {}
124 Character input event.
126 This event represents text input, usually as the result of a key press.
127 The text is given both as a Unicode character code and a UTF-8 string.
129 Note that this event is generated by the platform's input system,
130 so there is not necessarily a direct correspondence between text events and physical key presses.
131 For example, with some input methods a sequence of several key presses will generate a single character.
133 @see onCharacterInput
135 struct CharacterInputEvent : BaseEvent {
136 /** Raw key code. */
137 uint keycode;
138 /** Unicode character code. */
139 uint character;
140 /** UTF-8 string. */
141 char string[8];
143 /** Constructor for default/null values */
144 CharacterInputEvent() noexcept
145 : BaseEvent(),
146 keycode(0),
147 character(0),
148 #ifdef DISTRHO_PROPER_CPP11_SUPPORT
149 string{'\0','\0','\0','\0','\0','\0','\0','\0'} {}
150 #else
151 string() { std::memset(string, 0, sizeof(string)); }
152 #endif
156 Mouse press or release event.
157 @see onMouse
159 struct MouseEvent : BaseEvent {
160 /** The button number starting from 1. @see MouseButton */
161 uint button;
162 /** True if the button was pressed, false if released. */
163 bool press;
164 /** The widget-relative coordinates of the pointer. */
165 Point<double> pos;
166 /** The absolute coordinates of the pointer. */
167 Point<double> absolutePos;
169 /** Constructor for default/null values */
170 MouseEvent() noexcept
171 : BaseEvent(),
172 button(0),
173 press(false),
174 pos(0.0, 0.0),
175 absolutePos(0.0, 0.0) {}
179 Mouse motion event.
180 @see onMotion
182 struct MotionEvent : BaseEvent {
183 /** The widget-relative coordinates of the pointer. */
184 Point<double> pos;
185 /** The absolute coordinates of the pointer. */
186 Point<double> absolutePos;
188 /** Constructor for default/null values */
189 MotionEvent() noexcept
190 : BaseEvent(),
191 pos(0.0, 0.0),
192 absolutePos(0.0, 0.0) {}
196 Mouse scroll event.
198 The scroll distance is expressed in "lines",
199 an arbitrary unit that corresponds to a single tick of a detented mouse wheel.
200 For example, `delta.y` = 1.0 scrolls 1 line up.
201 Some systems and devices support finer resolution and/or higher values for fast scrolls,
202 so programs should handle any value gracefully.
204 @see onScroll
206 struct ScrollEvent : BaseEvent {
207 /** The widget-relative coordinates of the pointer. */
208 Point<double> pos;
209 /** The absolute coordinates of the pointer. */
210 Point<double> absolutePos;
211 /** The scroll distance. */
212 Point<double> delta;
213 /** The direction of the scroll or "smooth". */
214 ScrollDirection direction;
216 /** Constructor for default/null values */
217 ScrollEvent() noexcept
218 : BaseEvent(),
219 pos(0.0, 0.0),
220 absolutePos(0.0, 0.0),
221 delta(0.0, 0.0),
222 direction(kScrollSmooth) {}
226 Resize event.
227 @see onResize
229 struct ResizeEvent {
230 /** The new widget size. */
231 Size<uint> size;
232 /** The previous size, can be null. */
233 Size<uint> oldSize;
235 /** Constructor for default/null values */
236 ResizeEvent() noexcept
237 : size(0, 0),
238 oldSize(0, 0) {}
242 Widget position changed event.
243 @see onPositionChanged
245 struct PositionChangedEvent {
246 /** The new absolute position of the widget. */
247 Point<int> pos;
248 /** The previous absolute position of the widget. */
249 Point<int> oldPos;
251 /** Constructor for default/null values */
252 PositionChangedEvent() noexcept
253 : pos(0, 0),
254 oldPos(0, 0) {}
257 private:
259 Private constructor, reserved for TopLevelWidget class.
261 explicit Widget(TopLevelWidget* topLevelWidget);
264 Private constructor, reserved for SubWidget class.
266 explicit Widget(Widget* widgetToGroupTo);
268 public:
270 Destructor.
272 virtual ~Widget();
275 Check if this widget is visible within its parent window.
276 Invisible widgets do not receive events except resize.
278 bool isVisible() const noexcept;
281 Set widget visible (or not) according to @a visible.
283 void setVisible(bool visible);
286 Show widget.
287 This is the same as calling setVisible(true).
289 void show();
292 Hide widget.
293 This is the same as calling setVisible(false).
295 void hide();
298 Get width.
300 uint getWidth() const noexcept;
303 Get height.
305 uint getHeight() const noexcept;
308 Get size.
310 const Size<uint> getSize() const noexcept;
313 Set width.
315 void setWidth(uint width) noexcept;
318 Set height.
320 void setHeight(uint height) noexcept;
323 Set size using @a width and @a height values.
325 void setSize(uint width, uint height) noexcept;
328 Set size.
330 void setSize(const Size<uint>& size) noexcept;
333 Get the Id associated with this widget.
334 @see setId
336 uint getId() const noexcept;
339 Set an Id to be associated with this widget.
340 @see getId
342 void setId(uint id) noexcept;
345 Get the application associated with this widget's window.
346 This is the same as calling `getTopLevelWidget()->getApp()`.
348 Application& getApp() const noexcept;
351 Get the window associated with this widget.
352 This is the same as calling `getTopLevelWidget()->getWindow()`.
354 Window& getWindow() const noexcept;
357 Get the graphics context associated with this widget's window.
358 GraphicsContext is an empty struct and needs to be casted into a different type in order to be usable,
359 for example GraphicsContext.
360 @see CairoSubWidget, CairoTopLevelWidget
362 const GraphicsContext& getGraphicsContext() const noexcept;
365 Get top-level widget, as passed directly in the constructor
366 or going up the chain of group widgets until it finds the top-level one.
368 TopLevelWidget* getTopLevelWidget() const noexcept;
371 Request repaint of this widget's area to the window this widget belongs to.
372 On the raw Widget class this function does nothing.
374 virtual void repaint() noexcept;
376 DISTRHO_DEPRECATED_BY("getApp()")
377 Application& getParentApp() const noexcept { return getApp(); }
379 DISTRHO_DEPRECATED_BY("getWindow()")
380 Window& getParentWindow() const noexcept { return getWindow(); }
382 protected:
384 A function called to draw the widget contents.
386 virtual void onDisplay() = 0;
389 A function called when a key is pressed or released.
390 @return True to stop event propagation, false otherwise.
392 virtual bool onKeyboard(const KeyboardEvent&);
395 A function called when an UTF-8 character is received.
396 @return True to stop event propagation, false otherwise.
398 virtual bool onCharacterInput(const CharacterInputEvent&);
401 A function called when a mouse button is pressed or released.
402 @return True to stop event propagation, false otherwise.
404 virtual bool onMouse(const MouseEvent&);
407 A function called when the pointer moves.
408 @return True to stop event propagation, false otherwise.
410 virtual bool onMotion(const MotionEvent&);
413 A function called on scrolling (e.g. mouse wheel or track pad).
414 @return True to stop event propagation, false otherwise.
416 virtual bool onScroll(const ScrollEvent&);
419 A function called when the widget is resized.
421 virtual void onResize(const ResizeEvent&);
424 A function called when a special key is pressed or released.
425 DEPRECATED use onKeyboard or onCharacterInput
427 #if defined(__clang__)
428 # pragma clang diagnostic push
429 # pragma clang diagnostic ignored "-Wdeprecated-declarations"
430 #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460
431 # pragma GCC diagnostic push
432 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
433 #endif
434 virtual bool onSpecial(const SpecialEvent&) { return false; }
435 #if defined(__clang__)
436 # pragma clang diagnostic pop
437 #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460
438 # pragma GCC diagnostic pop
439 #endif
441 private:
442 struct PrivateData;
443 PrivateData* const pData;
444 friend class SubWidget;
445 friend class TopLevelWidget;
447 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Widget)
450 // --------------------------------------------------------------------------------------------------------------------
452 END_NAMESPACE_DGL
454 #endif // DGL_WIDGET_HPP_INCLUDED