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"
24 // --------------------------------------------------------------------------------------------------------------------
25 // Forward class names
32 // --------------------------------------------------------------------------------------------------------------------
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.
58 These are the fields present on all Widget events.
61 /** Currently active keyboard modifiers. @see Modifier */
63 /** Event flags. @see EventFlag */
65 /** Event timestamp (if any). */
68 /** Constructor for default/null values */
69 BaseEvent() noexcept
: mod(0x0), flags(0x0), time(0) {}
71 virtual ~BaseEvent() noexcept
{}
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.
90 struct KeyboardEvent
: BaseEvent
{
91 /** True if the key was pressed, false if released. */
93 /** Unicode point of the key pressed. */
98 /** Constructor for default/null values */
99 KeyboardEvent() noexcept
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
{
116 /** Constructor for default/null values */
117 SpecialEvent() noexcept
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
{
138 /** Unicode character code. */
143 /** Constructor for default/null values */
144 CharacterInputEvent() noexcept
148 #ifdef DISTRHO_PROPER_CPP11_SUPPORT
149 string
{'\0','\0','\0','\0','\0','\0','\0','\0'} {}
151 string() { std::memset(string
, 0, sizeof(string
)); }
156 Mouse press or release event.
159 struct MouseEvent
: BaseEvent
{
160 /** The button number starting from 1. @see MouseButton */
162 /** True if the button was pressed, false if released. */
164 /** The widget-relative coordinates of the pointer. */
166 /** The absolute coordinates of the pointer. */
167 Point
<double> absolutePos
;
169 /** Constructor for default/null values */
170 MouseEvent() noexcept
175 absolutePos(0.0, 0.0) {}
182 struct MotionEvent
: BaseEvent
{
183 /** The widget-relative coordinates of the pointer. */
185 /** The absolute coordinates of the pointer. */
186 Point
<double> absolutePos
;
188 /** Constructor for default/null values */
189 MotionEvent() noexcept
192 absolutePos(0.0, 0.0) {}
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.
206 struct ScrollEvent
: BaseEvent
{
207 /** The widget-relative coordinates of the pointer. */
209 /** The absolute coordinates of the pointer. */
210 Point
<double> absolutePos
;
211 /** The scroll distance. */
213 /** The direction of the scroll or "smooth". */
214 ScrollDirection direction
;
216 /** Constructor for default/null values */
217 ScrollEvent() noexcept
220 absolutePos(0.0, 0.0),
222 direction(kScrollSmooth
) {}
230 /** The new widget size. */
232 /** The previous size, can be null. */
235 /** Constructor for default/null values */
236 ResizeEvent() noexcept
242 Widget position changed event.
243 @see onPositionChanged
245 struct PositionChangedEvent
{
246 /** The new absolute position of the widget. */
248 /** The previous absolute position of the widget. */
251 /** Constructor for default/null values */
252 PositionChangedEvent() noexcept
259 Private constructor, reserved for TopLevelWidget class.
261 explicit Widget(TopLevelWidget
* topLevelWidget
);
264 Private constructor, reserved for SubWidget class.
266 explicit Widget(Widget
* widgetToGroupTo
);
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
);
287 This is the same as calling setVisible(true).
293 This is the same as calling setVisible(false).
300 uint
getWidth() const noexcept
;
305 uint
getHeight() const noexcept
;
310 const Size
<uint
> getSize() const noexcept
;
315 void setWidth(uint width
) noexcept
;
320 void setHeight(uint height
) noexcept
;
323 Set size using @a width and @a height values.
325 void setSize(uint width
, uint height
) noexcept
;
330 void setSize(const Size
<uint
>& size
) noexcept
;
333 Get the Id associated with this widget.
336 uint
getId() const noexcept
;
339 Set an Id to be associated with this widget.
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(); }
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"
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
443 PrivateData
* const pData
;
444 friend class SubWidget
;
445 friend class TopLevelWidget
;
447 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Widget
)
450 // --------------------------------------------------------------------------------------------------------------------
454 #endif // DGL_WIDGET_HPP_INCLUDED