|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- /*
- * DISTRHO Plugin Framework (DPF)
- * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any purpose with
- * or without fee is hereby granted, provided that the above copyright notice and this
- * permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
- * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
- #ifndef DGL_WIDGET_HPP_INCLUDED
- #define DGL_WIDGET_HPP_INCLUDED
-
- #include "Geometry.hpp"
-
- START_NAMESPACE_DGL
-
- // --------------------------------------------------------------------------------------------------------------------
- // Forward class names
-
- class Application;
- class SubWidget;
- class TopLevelWidget;
- class Window;
-
- // --------------------------------------------------------------------------------------------------------------------
-
- /**
- Base DGL Widget class.
-
- This is the base Widget class, from which all widgets are built.
-
- All widgets have a parent widget where they'll be drawn, this can be the top-level widget or a group widget.
- This parent is never changed during a widget's lifetime.
-
- Widgets receive events in relative coordinates. (0, 0) means its top-left position.
-
- The top-level widget will draw subwidgets in the order they are constructed.
- Early subwidgets are drawn first, at the bottom, then newer ones on top.
- Events are sent in the inverse order so that the top-most widgets get
- a chance to catch the event and stop its propagation.
-
- All widget event callbacks do nothing by default and onDisplay MUST be reimplemented by subclasses.
-
- @note It is not possible to subclass this Widget class directly, you must use SubWidget or TopLevelWidget instead.
- */
- class Widget
- {
- public:
- /**
- Base event data.
- These are the fields present on all Widget events.
- */
- struct BaseEvent {
- /** Currently active keyboard modifiers. @see Modifier */
- uint mod;
- /** Event flags. @see EventFlag */
- uint flags;
- /** Event timestamp (if any). */
- uint time;
-
- /** Constructor for default/null values */
- BaseEvent() noexcept : mod(0x0), flags(0x0), time(0) {}
- /** Destuctor */
- virtual ~BaseEvent() noexcept {}
- };
-
- /**
- Keyboard event.
-
- This event represents low-level key presses and releases.
- This can be used for "direct" keyboard handing like key bindings, but must not be interpreted as text input.
-
- Keys are represented portably as Unicode code points, using the "natural" code point for the key.
- The @a key field is the code for the pressed key, without any modifiers applied.
- For example, a press or release of the 'A' key will have `key` 97 ('a')
- regardless of whether shift or control are being held.
-
- Alternatively, the raw @a keycode can be used to work directly with physical keys,
- but note that this value is not portable and differs between platforms and hardware.
-
- @see onKeyboard
- */
- struct KeyboardEvent : BaseEvent {
- /** True if the key was pressed, false if released. */
- bool press;
- /** Unicode point of the key pressed. */
- uint key;
- /** Raw keycode. */
- uint keycode;
-
- /** Constructor for default/null values */
- KeyboardEvent() noexcept
- : BaseEvent(),
- press(false),
- key(0),
- keycode(0) {}
- };
-
- /**
- Special keyboard event.
-
- DEPRECATED This used to be part of DPF due to pugl, but now deprecated and simply non-functional.
- All events go through KeyboardEvent or CharacterInputEvent, use those instead.
- */
- struct DISTRHO_DEPRECATED_BY("KeyboardEvent") SpecialEvent : BaseEvent {
- bool press;
- Key key;
-
- /** Constructor for default/null values */
- SpecialEvent() noexcept
- : BaseEvent(),
- press(false),
- key(Key(0)) {}
- };
-
- /**
- Character input event.
-
- This event represents text input, usually as the result of a key press.
- The text is given both as a Unicode character code and a UTF-8 string.
-
- Note that this event is generated by the platform's input system,
- so there is not necessarily a direct correspondence between text events and physical key presses.
- For example, with some input methods a sequence of several key presses will generate a single character.
-
- @see onCharacterInput
- */
- struct CharacterInputEvent : BaseEvent {
- /** Raw key code. */
- uint keycode;
- /** Unicode character code. */
- uint character;
- /** UTF-8 string. */
- char string[8];
-
- /** Constructor for default/null values */
- CharacterInputEvent() noexcept
- : BaseEvent(),
- keycode(0),
- character(0),
- #ifdef DISTRHO_PROPER_CPP11_SUPPORT
- string{'\0','\0','\0','\0','\0','\0','\0','\0'} {}
- #else
- string() { std::memset(string, 0, sizeof(string)); }
- #endif
- };
-
- /**
- Mouse press or release event.
- @see onMouse
- */
- struct MouseEvent : BaseEvent {
- /** The button number starting from 1. @see MouseButton */
- uint button;
- /** True if the button was pressed, false if released. */
- bool press;
- /** The widget-relative coordinates of the pointer. */
- Point<double> pos;
- /** The absolute coordinates of the pointer. */
- Point<double> absolutePos;
-
- /** Constructor for default/null values */
- MouseEvent() noexcept
- : BaseEvent(),
- button(0),
- press(false),
- pos(0.0, 0.0),
- absolutePos(0.0, 0.0) {}
- };
-
- /**
- Mouse motion event.
- @see onMotion
- */
- struct MotionEvent : BaseEvent {
- /** The widget-relative coordinates of the pointer. */
- Point<double> pos;
- /** The absolute coordinates of the pointer. */
- Point<double> absolutePos;
-
- /** Constructor for default/null values */
- MotionEvent() noexcept
- : BaseEvent(),
- pos(0.0, 0.0),
- absolutePos(0.0, 0.0) {}
- };
-
- /**
- Mouse scroll event.
-
- The scroll distance is expressed in "lines",
- an arbitrary unit that corresponds to a single tick of a detented mouse wheel.
- For example, `delta.y` = 1.0 scrolls 1 line up.
- Some systems and devices support finer resolution and/or higher values for fast scrolls,
- so programs should handle any value gracefully.
-
- @see onScroll
- */
- struct ScrollEvent : BaseEvent {
- /** The widget-relative coordinates of the pointer. */
- Point<double> pos;
- /** The absolute coordinates of the pointer. */
- Point<double> absolutePos;
- /** The scroll distance. */
- Point<double> delta;
- /** The direction of the scroll or "smooth". */
- ScrollDirection direction;
-
- /** Constructor for default/null values */
- ScrollEvent() noexcept
- : BaseEvent(),
- pos(0.0, 0.0),
- absolutePos(0.0, 0.0),
- delta(0.0, 0.0),
- direction(kScrollSmooth) {}
- };
-
- /**
- Resize event.
- @see onResize
- */
- struct ResizeEvent {
- /** The new widget size. */
- Size<uint> size;
- /** The previous size, can be null. */
- Size<uint> oldSize;
-
- /** Constructor for default/null values */
- ResizeEvent() noexcept
- : size(0, 0),
- oldSize(0, 0) {}
- };
-
- /**
- Widget position changed event.
- @see onPositionChanged
- */
- struct PositionChangedEvent {
- /** The new absolute position of the widget. */
- Point<int> pos;
- /** The previous absolute position of the widget. */
- Point<int> oldPos;
-
- /** Constructor for default/null values */
- PositionChangedEvent() noexcept
- : pos(0, 0),
- oldPos(0, 0) {}
- };
-
- private:
- /**
- Private constructor, reserved for TopLevelWidget class.
- */
- explicit Widget(TopLevelWidget* topLevelWidget);
-
- /**
- Private constructor, reserved for SubWidget class.
- */
- explicit Widget(Widget* widgetToGroupTo);
-
- public:
- /**
- Destructor.
- */
- virtual ~Widget();
-
- /**
- Check if this widget is visible within its parent window.
- Invisible widgets do not receive events except resize.
- */
- bool isVisible() const noexcept;
-
- /**
- Set widget visible (or not) according to @a visible.
- */
- void setVisible(bool visible);
-
- /**
- Show widget.
- This is the same as calling setVisible(true).
- */
- void show();
-
- /**
- Hide widget.
- This is the same as calling setVisible(false).
- */
- void hide();
-
- /**
- Get width.
- */
- uint getWidth() const noexcept;
-
- /**
- Get height.
- */
- uint getHeight() const noexcept;
-
- /**
- Get size.
- */
- const Size<uint> getSize() const noexcept;
-
- /**
- Set width.
- */
- void setWidth(uint width) noexcept;
-
- /**
- Set height.
- */
- void setHeight(uint height) noexcept;
-
- /**
- Set size using @a width and @a height values.
- */
- void setSize(uint width, uint height) noexcept;
-
- /**
- Set size.
- */
- void setSize(const Size<uint>& size) noexcept;
-
- /**
- Get the Id associated with this widget.
- @see setId
- */
- uint getId() const noexcept;
-
- /**
- Set an Id to be associated with this widget.
- @see getId
- */
- void setId(uint id) noexcept;
-
- /**
- Get the application associated with this widget's window.
- This is the same as calling `getTopLevelWidget()->getApp()`.
- */
- Application& getApp() const noexcept;
-
- /**
- Get the window associated with this widget.
- This is the same as calling `getTopLevelWidget()->getWindow()`.
- */
- Window& getWindow() const noexcept;
-
- /**
- Get the graphics context associated with this widget's window.
- GraphicsContext is an empty struct and needs to be casted into a different type in order to be usable,
- for example GraphicsContext.
- @see CairoSubWidget, CairoTopLevelWidget
- */
- const GraphicsContext& getGraphicsContext() const noexcept;
-
- /**
- Get top-level widget, as passed directly in the constructor
- or going up the chain of group widgets until it finds the top-level one.
- */
- TopLevelWidget* getTopLevelWidget() const noexcept;
-
- /**
- Request repaint of this widget's area to the window this widget belongs to.
- On the raw Widget class this function does nothing.
- */
- virtual void repaint() noexcept;
-
- DISTRHO_DEPRECATED_BY("getApp()")
- Application& getParentApp() const noexcept { return getApp(); }
-
- DISTRHO_DEPRECATED_BY("getWindow()")
- Window& getParentWindow() const noexcept { return getWindow(); }
-
- protected:
- /**
- A function called to draw the widget contents.
- */
- virtual void onDisplay() = 0;
-
- /**
- A function called when a key is pressed or released.
- @return True to stop event propagation, false otherwise.
- */
- virtual bool onKeyboard(const KeyboardEvent&);
-
- /**
- A function called when an UTF-8 character is received.
- @return True to stop event propagation, false otherwise.
- */
- virtual bool onCharacterInput(const CharacterInputEvent&);
-
- /**
- A function called when a mouse button is pressed or released.
- @return True to stop event propagation, false otherwise.
- */
- virtual bool onMouse(const MouseEvent&);
-
- /**
- A function called when the pointer moves.
- @return True to stop event propagation, false otherwise.
- */
- virtual bool onMotion(const MotionEvent&);
-
- /**
- A function called on scrolling (e.g. mouse wheel or track pad).
- @return True to stop event propagation, false otherwise.
- */
- virtual bool onScroll(const ScrollEvent&);
-
- /**
- A function called when the widget is resized.
- */
- virtual void onResize(const ResizeEvent&);
-
- /**
- A function called when a special key is pressed or released.
- DEPRECATED use onKeyboard or onCharacterInput
- */
- #if defined(__clang__)
- # pragma clang diagnostic push
- # pragma clang diagnostic ignored "-Wdeprecated-declarations"
- #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460
- # pragma GCC diagnostic push
- # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- #endif
- virtual bool onSpecial(const SpecialEvent&) { return false; }
- #if defined(__clang__)
- # pragma clang diagnostic pop
- #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460
- # pragma GCC diagnostic pop
- #endif
-
- private:
- struct PrivateData;
- PrivateData* const pData;
- friend class SubWidget;
- friend class TopLevelWidget;
-
- DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Widget)
- };
-
- // --------------------------------------------------------------------------------------------------------------------
-
- END_NAMESPACE_DGL
-
- #endif // DGL_WIDGET_HPP_INCLUDED
|