Mercurial > hg > pub > prymula > com
comparison DPF-Prymula-audioplugins/dpf/dgl/Widget.hpp @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:cf2cb71d31dd | 3:84e66ea83026 |
---|---|
1 /* | |
2 * DISTRHO Plugin Framework (DPF) | |
3 * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com> | |
4 * | |
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. | |
8 * | |
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. | |
15 */ | |
16 | |
17 #ifndef DGL_WIDGET_HPP_INCLUDED | |
18 #define DGL_WIDGET_HPP_INCLUDED | |
19 | |
20 #include "Geometry.hpp" | |
21 | |
22 #include <list> | |
23 | |
24 START_NAMESPACE_DGL | |
25 | |
26 // -------------------------------------------------------------------------------------------------------------------- | |
27 // Forward class names | |
28 | |
29 class Application; | |
30 class SubWidget; | |
31 class TopLevelWidget; | |
32 class Window; | |
33 | |
34 // -------------------------------------------------------------------------------------------------------------------- | |
35 | |
36 /** | |
37 Base DGL Widget class. | |
38 | |
39 This is the base Widget class, from which all widgets are built. | |
40 | |
41 All widgets have a parent widget where they'll be drawn, this can be the top-level widget or a group widget. | |
42 This parent is never changed during a widget's lifetime. | |
43 | |
44 Widgets receive events in relative coordinates. (0, 0) means its top-left position. | |
45 | |
46 The top-level widget will draw subwidgets in the order they are constructed. | |
47 Early subwidgets are drawn first, at the bottom, then newer ones on top. | |
48 Events are sent in the inverse order so that the top-most widgets get | |
49 a chance to catch the event and stop its propagation. | |
50 | |
51 All widget event callbacks do nothing by default and onDisplay MUST be reimplemented by subclasses. | |
52 | |
53 @note It is not possible to subclass this Widget class directly, you must use SubWidget or TopLevelWidget instead. | |
54 */ | |
55 class Widget | |
56 { | |
57 public: | |
58 /** | |
59 Base event data. | |
60 These are the fields present on all Widget events. | |
61 */ | |
62 struct BaseEvent { | |
63 /** Currently active keyboard modifiers. @see Modifier */ | |
64 uint mod; | |
65 /** Event flags. @see EventFlag */ | |
66 uint flags; | |
67 /** Event timestamp in milliseconds (if any). */ | |
68 uint time; | |
69 | |
70 /** Constructor for default/null values */ | |
71 BaseEvent() noexcept : mod(0x0), flags(0x0), time(0) {} | |
72 /** Destuctor */ | |
73 virtual ~BaseEvent() noexcept {} | |
74 }; | |
75 | |
76 /** | |
77 Keyboard event. | |
78 | |
79 This event represents low-level key presses and releases. | |
80 This can be used for "direct" keyboard handing like key bindings, but must not be interpreted as text input. | |
81 | |
82 Keys are represented portably as Unicode code points, using the "natural" code point for the key. | |
83 The @a key field is the code for the pressed key, without any modifiers applied. | |
84 For example, a press or release of the 'A' key will have `key` 97 ('a') | |
85 regardless of whether shift or control are being held. | |
86 | |
87 Alternatively, the raw @a keycode can be used to work directly with physical keys, | |
88 but note that this value is not portable and differs between platforms and hardware. | |
89 | |
90 @see onKeyboard | |
91 */ | |
92 struct KeyboardEvent : BaseEvent { | |
93 /** True if the key was pressed, false if released. */ | |
94 bool press; | |
95 /** Unicode point of the key pressed. */ | |
96 uint key; | |
97 /** Raw keycode. */ | |
98 uint keycode; | |
99 | |
100 /** Constructor for default/null values */ | |
101 KeyboardEvent() noexcept | |
102 : BaseEvent(), | |
103 press(false), | |
104 key(0), | |
105 keycode(0) {} | |
106 }; | |
107 | |
108 /** | |
109 Special keyboard event. | |
110 | |
111 DEPRECATED This used to be part of DPF due to pugl, but now deprecated and simply non-functional. | |
112 All events go through KeyboardEvent or CharacterInputEvent, use those instead. | |
113 */ | |
114 struct DISTRHO_DEPRECATED_BY("KeyboardEvent") SpecialEvent : BaseEvent { | |
115 bool press; | |
116 Key key; | |
117 | |
118 /** Constructor for default/null values */ | |
119 SpecialEvent() noexcept | |
120 : BaseEvent(), | |
121 press(false), | |
122 key(Key(0)) {} | |
123 }; | |
124 | |
125 /** | |
126 Character input event. | |
127 | |
128 This event represents text input, usually as the result of a key press. | |
129 The text is given both as a Unicode character code and a UTF-8 string. | |
130 | |
131 Note that this event is generated by the platform's input system, | |
132 so there is not necessarily a direct correspondence between text events and physical key presses. | |
133 For example, with some input methods a sequence of several key presses will generate a single character. | |
134 | |
135 @see onCharacterInput | |
136 */ | |
137 struct CharacterInputEvent : BaseEvent { | |
138 /** Raw key code. */ | |
139 uint keycode; | |
140 /** Unicode character code. */ | |
141 uint character; | |
142 /** UTF-8 string. */ | |
143 char string[8]; | |
144 | |
145 /** Constructor for default/null values */ | |
146 CharacterInputEvent() noexcept | |
147 : BaseEvent(), | |
148 keycode(0), | |
149 character(0), | |
150 #ifdef DISTRHO_PROPER_CPP11_SUPPORT | |
151 string{'\0','\0','\0','\0','\0','\0','\0','\0'} {} | |
152 #else | |
153 string() { std::memset(string, 0, sizeof(string)); } | |
154 #endif | |
155 }; | |
156 | |
157 /** | |
158 Mouse press or release event. | |
159 @see onMouse | |
160 */ | |
161 struct MouseEvent : BaseEvent { | |
162 /** The button number starting from 1. @see MouseButton */ | |
163 uint button; | |
164 /** True if the button was pressed, false if released. */ | |
165 bool press; | |
166 /** The widget-relative coordinates of the pointer. */ | |
167 Point<double> pos; | |
168 /** The absolute coordinates of the pointer. */ | |
169 Point<double> absolutePos; | |
170 | |
171 /** Constructor for default/null values */ | |
172 MouseEvent() noexcept | |
173 : BaseEvent(), | |
174 button(0), | |
175 press(false), | |
176 pos(0.0, 0.0), | |
177 absolutePos(0.0, 0.0) {} | |
178 }; | |
179 | |
180 /** | |
181 Mouse motion event. | |
182 @see onMotion | |
183 */ | |
184 struct MotionEvent : BaseEvent { | |
185 /** The widget-relative coordinates of the pointer. */ | |
186 Point<double> pos; | |
187 /** The absolute coordinates of the pointer. */ | |
188 Point<double> absolutePos; | |
189 | |
190 /** Constructor for default/null values */ | |
191 MotionEvent() noexcept | |
192 : BaseEvent(), | |
193 pos(0.0, 0.0), | |
194 absolutePos(0.0, 0.0) {} | |
195 }; | |
196 | |
197 /** | |
198 Mouse scroll event. | |
199 | |
200 The scroll distance is expressed in "lines", | |
201 an arbitrary unit that corresponds to a single tick of a detented mouse wheel. | |
202 For example, `delta.y` = 1.0 scrolls 1 line up. | |
203 Some systems and devices support finer resolution and/or higher values for fast scrolls, | |
204 so programs should handle any value gracefully. | |
205 | |
206 @see onScroll | |
207 */ | |
208 struct ScrollEvent : BaseEvent { | |
209 /** The widget-relative coordinates of the pointer. */ | |
210 Point<double> pos; | |
211 /** The absolute coordinates of the pointer. */ | |
212 Point<double> absolutePos; | |
213 /** The scroll distance. */ | |
214 Point<double> delta; | |
215 /** The direction of the scroll or "smooth". */ | |
216 ScrollDirection direction; | |
217 | |
218 /** Constructor for default/null values */ | |
219 ScrollEvent() noexcept | |
220 : BaseEvent(), | |
221 pos(0.0, 0.0), | |
222 absolutePos(0.0, 0.0), | |
223 delta(0.0, 0.0), | |
224 direction(kScrollSmooth) {} | |
225 }; | |
226 | |
227 /** | |
228 Resize event. | |
229 @see onResize | |
230 */ | |
231 struct ResizeEvent { | |
232 /** The new widget size. */ | |
233 Size<uint> size; | |
234 /** The previous size, can be null. */ | |
235 Size<uint> oldSize; | |
236 | |
237 /** Constructor for default/null values */ | |
238 ResizeEvent() noexcept | |
239 : size(0, 0), | |
240 oldSize(0, 0) {} | |
241 }; | |
242 | |
243 /** | |
244 Widget position changed event. | |
245 @see onPositionChanged | |
246 */ | |
247 struct PositionChangedEvent { | |
248 /** The new absolute position of the widget. */ | |
249 Point<int> pos; | |
250 /** The previous absolute position of the widget. */ | |
251 Point<int> oldPos; | |
252 | |
253 /** Constructor for default/null values */ | |
254 PositionChangedEvent() noexcept | |
255 : pos(0, 0), | |
256 oldPos(0, 0) {} | |
257 }; | |
258 | |
259 private: | |
260 /** | |
261 Private constructor, reserved for TopLevelWidget class. | |
262 */ | |
263 explicit Widget(TopLevelWidget* topLevelWidget); | |
264 | |
265 /** | |
266 Private constructor, reserved for SubWidget class. | |
267 */ | |
268 explicit Widget(Widget* widgetToGroupTo); | |
269 | |
270 public: | |
271 /** | |
272 Destructor. | |
273 */ | |
274 virtual ~Widget(); | |
275 | |
276 /** | |
277 Check if this widget is visible within its parent window. | |
278 Invisible widgets do not receive events except resize. | |
279 */ | |
280 bool isVisible() const noexcept; | |
281 | |
282 /** | |
283 Set widget visible (or not) according to @a visible. | |
284 */ | |
285 void setVisible(bool visible); | |
286 | |
287 /** | |
288 Show widget. | |
289 This is the same as calling setVisible(true). | |
290 */ | |
291 void show(); | |
292 | |
293 /** | |
294 Hide widget. | |
295 This is the same as calling setVisible(false). | |
296 */ | |
297 void hide(); | |
298 | |
299 /** | |
300 Get width. | |
301 */ | |
302 uint getWidth() const noexcept; | |
303 | |
304 /** | |
305 Get height. | |
306 */ | |
307 uint getHeight() const noexcept; | |
308 | |
309 /** | |
310 Get size. | |
311 */ | |
312 const Size<uint> getSize() const noexcept; | |
313 | |
314 /** | |
315 Set width. | |
316 */ | |
317 void setWidth(uint width) noexcept; | |
318 | |
319 /** | |
320 Set height. | |
321 */ | |
322 void setHeight(uint height) noexcept; | |
323 | |
324 /** | |
325 Set size using @a width and @a height values. | |
326 */ | |
327 void setSize(uint width, uint height) noexcept; | |
328 | |
329 /** | |
330 Set size. | |
331 */ | |
332 void setSize(const Size<uint>& size) noexcept; | |
333 | |
334 /** | |
335 Get the Id associated with this widget. | |
336 Returns 0 by default. | |
337 @see setId | |
338 */ | |
339 uint getId() const noexcept; | |
340 | |
341 /** | |
342 Get the name associated with this widget. | |
343 This is complately optional, mostly useful for debugging purposes. | |
344 Returns an empty string by default. | |
345 @see setName | |
346 */ | |
347 const char* getName() const noexcept; | |
348 | |
349 /** | |
350 Set an Id to be associated with this widget. | |
351 @see getId | |
352 */ | |
353 void setId(uint id) noexcept; | |
354 | |
355 /** | |
356 Set a name to be associated with this widget. | |
357 This is complately optional, only useful for debugging purposes. | |
358 @note name must not be null | |
359 @see getName | |
360 */ | |
361 void setName(const char* name) noexcept; | |
362 | |
363 /** | |
364 Get the application associated with this widget's window. | |
365 This is the same as calling `getTopLevelWidget()->getApp()`. | |
366 */ | |
367 Application& getApp() const noexcept; | |
368 | |
369 /** | |
370 Get the window associated with this widget. | |
371 This is the same as calling `getTopLevelWidget()->getWindow()`. | |
372 */ | |
373 Window& getWindow() const noexcept; | |
374 | |
375 /** | |
376 Get the graphics context associated with this widget's window. | |
377 GraphicsContext is an empty struct and needs to be casted into a different type in order to be usable, | |
378 for example GraphicsContext. | |
379 @see CairoSubWidget, CairoTopLevelWidget | |
380 */ | |
381 const GraphicsContext& getGraphicsContext() const noexcept; | |
382 | |
383 /** | |
384 Get top-level widget, as passed directly in the constructor | |
385 or going up the chain of group widgets until it finds the top-level one. | |
386 */ | |
387 TopLevelWidget* getTopLevelWidget() const noexcept; | |
388 | |
389 /** | |
390 Get list of children (a subwidgets) that belong to this widget. | |
391 */ | |
392 std::list<SubWidget*> getChildren() const noexcept; | |
393 | |
394 /** | |
395 Request repaint of this widget's area to the window this widget belongs to. | |
396 On the raw Widget class this function does nothing. | |
397 */ | |
398 virtual void repaint() noexcept; | |
399 | |
400 DISTRHO_DEPRECATED_BY("getApp()") | |
401 Application& getParentApp() const noexcept { return getApp(); } | |
402 | |
403 DISTRHO_DEPRECATED_BY("getWindow()") | |
404 Window& getParentWindow() const noexcept { return getWindow(); } | |
405 | |
406 protected: | |
407 /** | |
408 A function called to draw the widget contents. | |
409 */ | |
410 virtual void onDisplay() = 0; | |
411 | |
412 /** | |
413 A function called when a key is pressed or released. | |
414 @return True to stop event propagation, false otherwise. | |
415 */ | |
416 virtual bool onKeyboard(const KeyboardEvent&); | |
417 | |
418 /** | |
419 A function called when an UTF-8 character is received. | |
420 @return True to stop event propagation, false otherwise. | |
421 */ | |
422 virtual bool onCharacterInput(const CharacterInputEvent&); | |
423 | |
424 /** | |
425 A function called when a mouse button is pressed or released. | |
426 @return True to stop event propagation, false otherwise. | |
427 */ | |
428 virtual bool onMouse(const MouseEvent&); | |
429 | |
430 /** | |
431 A function called when the pointer moves. | |
432 @return True to stop event propagation, false otherwise. | |
433 */ | |
434 virtual bool onMotion(const MotionEvent&); | |
435 | |
436 /** | |
437 A function called on scrolling (e.g. mouse wheel or track pad). | |
438 @return True to stop event propagation, false otherwise. | |
439 */ | |
440 virtual bool onScroll(const ScrollEvent&); | |
441 | |
442 /** | |
443 A function called when the widget is resized. | |
444 */ | |
445 virtual void onResize(const ResizeEvent&); | |
446 | |
447 /** | |
448 A function called when a special key is pressed or released. | |
449 DEPRECATED use onKeyboard or onCharacterInput | |
450 */ | |
451 #if defined(_MSC_VER) | |
452 #pragma warning(push) | |
453 #pragma warning(disable:4996) | |
454 #elif defined(__clang__) | |
455 #pragma clang diagnostic push | |
456 #pragma clang diagnostic ignored "-Wdeprecated-declarations" | |
457 #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460 | |
458 #pragma GCC diagnostic push | |
459 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |
460 #endif | |
461 virtual bool onSpecial(const SpecialEvent&) { return false; } | |
462 #if defined(_MSC_VER) | |
463 #pragma warning(pop) | |
464 #elif defined(__clang__) | |
465 #pragma clang diagnostic pop | |
466 #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460 | |
467 #pragma GCC diagnostic pop | |
468 #endif | |
469 | |
470 private: | |
471 struct PrivateData; | |
472 PrivateData* const pData; | |
473 friend class SubWidget; | |
474 friend class TopLevelWidget; | |
475 | |
476 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Widget) | |
477 }; | |
478 | |
479 // -------------------------------------------------------------------------------------------------------------------- | |
480 | |
481 END_NAMESPACE_DGL | |
482 | |
483 #endif // DGL_WIDGET_HPP_INCLUDED |