1 /* 2 * DISTRHO Plugin Framework (DPF) 3 * Copyright (C) 2012-2019 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 <vector> 23 24 // ----------------------------------------------------------------------- 25 // Forward class names 26 27 #ifdef DISTRHO_DEFINES_H_INCLUDED 28 START_NAMESPACE_DISTRHO 29 class UI; 30 END_NAMESPACE_DISTRHO 31 #endif 32 33 START_NAMESPACE_DGL 34 35 class Application; 36 class ImageSlider; 37 class NanoWidget; 38 class Window; 39 class StandaloneWindow; 40 41 // ----------------------------------------------------------------------- 42 43 /** 44 Base DGL Widget class. 45 46 This is the base Widget class, from which all widgets are built. 47 48 All widgets have a parent Window where they'll be drawn. 49 This parent is never changed during the widget lifetime. 50 51 Widgets receive events in relative coordinates. 52 (0, 0) means its top-left position. 53 54 Windows paint widgets in the order they are constructed. HandleNanoImage::Handle55 Early widgets are drawn first, at the bottom, then newer ones on top. 56 Events are sent in the inverse order so that the top-most widget gets 57 a chance to catch the event and stop its propagation. 58 59 All widget event callbacks do nothing by default. 60 */ 61 class Widget 62 { 63 public: 64 /** 65 Base event data. 66 @a mod The currently active keyboard modifiers, @see Modifier. 67 @a time The timestamp (if any). 68 */ 69 struct BaseEvent { 70 uint mod; 71 uint32_t time; 72 73 /** Constuctor */ 74 BaseEvent() noexcept : mod(0x0), time(0) {} 75 /** Destuctor */ 76 virtual ~BaseEvent() noexcept {} 77 }; 78 79 /** 80 Keyboard event. 81 @a press True if the key was pressed, false if released. 82 @a key Unicode point of the key pressed. 83 @see onKeyboard 84 */ 85 struct KeyboardEvent : BaseEvent { 86 bool press; 87 uint key; 88 89 /** Constuctor */ 90 KeyboardEvent() noexcept 91 : BaseEvent(), 92 press(false), 93 key(0) {} 94 }; 95 96 /** 97 Special keyboard event. 98 @a press True if the key was pressed, false if released. 99 @a key The key pressed. 100 @see onSpecial 101 */ 102 struct SpecialEvent : BaseEvent { 103 bool press; 104 Key key; 105 106 /** Constuctor */ 107 SpecialEvent() noexcept 108 : BaseEvent(), 109 press(false), 110 key(Key(0)) {} 111 }; 112 113 /** 114 Mouse event. 115 @a button The button number (1 = left, 2 = middle, 3 = right). 116 @a press True if the button was pressed, false if released. 117 @a pos The widget-relative coordinates of the pointer. 118 @see onMouse 119 */ 120 struct MouseEvent : BaseEvent { 121 int button; 122 bool press; 123 Point<int> pos; 124 125 /** Constuctor */ 126 MouseEvent() noexcept 127 : BaseEvent(), 128 button(0), 129 press(false), 130 pos(0, 0) {} 131 }; 132 133 /** 134 Mouse motion event. 135 @a pos The widget-relative coordinates of the pointer. 136 @see onMotion 137 */ 138 struct MotionEvent : BaseEvent { 139 Point<int> pos; 140 141 /** Constuctor */ 142 MotionEvent() noexcept 143 : BaseEvent(), 144 pos(0, 0) {} 145 }; 146 147 /** 148 Mouse scroll event. 149 @a pos The widget-relative coordinates of the pointer. 150 @a delta The scroll distance. 151 @see onScroll 152 */ 153 struct ScrollEvent : BaseEvent { 154 Point<int> pos; 155 Point<float> delta; 156 157 /** Constuctor */ 158 ScrollEvent() noexcept 159 : BaseEvent(), 160 pos(0, 0), 161 delta(0.0f, 0.0f) {} 162 }; 163 164 /** 165 Resize event. 166 @a size The new widget size. 167 @a oldSize The previous size, may be null. 168 @see onResize 169 */ 170 struct ResizeEvent { 171 Size<uint> size; 172 Size<uint> oldSize; 173 174 /** Constuctor */ 175 ResizeEvent() noexcept 176 : size(0, 0), 177 oldSize(0, 0) {} 178 }; 179 180 /** 181 Widget position changed event. 182 @a pos The new absolute position of the widget. 183 @a oldPos The previous absolute position of the widget. 184 @see onPositionChanged 185 */ 186 struct PositionChangedEvent { 187 Point<int> pos; 188 Point<int> oldPos; 189 190 /** Constuctor */ 191 PositionChangedEvent() noexcept 192 : pos(0, 0), 193 oldPos(0, 0) {} 194 }; 195 196 /** 197 Constructor. 198 */ 199 explicit Widget(Window& parent); 200 201 /** 202 Constructor for a subwidget. 203 */ 204 explicit Widget(Widget* groupWidget); 205 206 /** 207 Destructor. 208 */ 209 virtual ~Widget(); 210 211 /** 212 Check if this widget is visible within its parent window. 213 Invisible widgets do not receive events except resize. 214 */ 215 bool isVisible() const noexcept; 216 217 /** 218 Set widget visible (or not) according to @a yesNo. 219 */ 220 void setVisible(bool yesNo); 221 222 /** 223 Show widget. 224 This is the same as calling setVisible(true). 225 */ 226 void show(); 227 228 /** 229 Hide widget. 230 This is the same as calling setVisible(false). 231 */ 232 void hide(); 233 234 /** 235 Get width. 236 */ 237 uint getWidth() const noexcept; 238 239 /** 240 Get height. 241 */ 242 uint getHeight() const noexcept; 243 244 /** 245 Get size. 246 */ 247 const Size<uint>& getSize() const noexcept; 248 249 /** 250 Set width. 251 */ 252 void setWidth(uint width) noexcept; 253 254 /** 255 Set height. 256 */ 257 void setHeight(uint height) noexcept; 258 259 /** 260 Set size using @a width and @a height values. 261 */ 262 void setSize(uint width, uint height) noexcept; 263 264 /** 265 Set size. 266 */ 267 void setSize(const Size<uint>& size) noexcept; 268 269 /** 270 Get absolute X. 271 */ 272 int getAbsoluteX() const noexcept; 273 274 /** 275 Get absolute Y. 276 */ 277 int getAbsoluteY() const noexcept; 278 279 /** 280 Get absolute position. 281 */ 282 const Point<int>& getAbsolutePos() const noexcept; 283 284 /** 285 Set absolute X. 286 */ 287 void setAbsoluteX(int x) noexcept; 288 289 /** 290 Set absolute Y. 291 */ 292 void setAbsoluteY(int y) noexcept; 293 294 /** 295 Set absolute position using @a x and @a y values. 296 */ 297 void setAbsolutePos(int x, int y) noexcept; 298 299 /** 300 Set absolute position. 301 */ 302 void setAbsolutePos(const Point<int>& pos) noexcept; 303 304 /** 305 Get this widget's window application. 306 Same as calling getParentWindow().getApp(). 307 */ 308 Application& getParentApp() const noexcept; 309 310 /** 311 Get parent window, as passed in the constructor. 312 */ 313 Window& getParentWindow() const noexcept; 314 315 /** 316 Check if this widget contains the point defined by @a x and @a y. 317 */ 318 bool contains(int x, int y) const noexcept; 319 320 /** 321 Check if this widget contains the point @a pos. 322 */ 323 bool contains(const Point<int>& pos) const noexcept; 324 325 /** 326 Tell this widget's window to repaint itself. 327 */ 328 void repaint() noexcept; 329 330 /** 331 Get the Id associated with this widget. 332 @see setId 333 */ 334 uint getId() const noexcept; 335 336 /** 337 Set an Id to be associated with this widget. 338 @see getId 339 */ 340 void setId(uint id) noexcept; 341 342 protected: 343 /** 344 A function called to draw the view contents with OpenGL. 345 */ 346 virtual void onDisplay() = 0; 347 348 /** 349 A function called when a key is pressed or released. 350 @return True to stop event propagation, false otherwise. 351 */ 352 virtual bool onKeyboard(const KeyboardEvent&); 353 354 /** 355 A function called when a special key is pressed or released. 356 @return True to stop event propagation, false otherwise. 357 */ 358 virtual bool onSpecial(const SpecialEvent&); 359 360 /** 361 A function called when a mouse button is pressed or released. 362 @return True to stop event propagation, false otherwise. 363 */ 364 virtual bool onMouse(const MouseEvent&); 365 366 /** 367 A function called when the pointer moves. 368 @return True to stop event propagation, false otherwise. 369 */ 370 virtual bool onMotion(const MotionEvent&); 371 372 /** 373 A function called on scrolling (e.g. mouse wheel or track pad). 374 @return True to stop event propagation, false otherwise. 375 */ 376 virtual bool onScroll(const ScrollEvent&); 377 378 /** 379 A function called when the widget is resized. 380 */ 381 virtual void onResize(const ResizeEvent&); 382 383 /** 384 A function called when the widget's absolute position is changed. 385 */ 386 virtual void onPositionChanged(const PositionChangedEvent&); 387 388 private: 389 struct PrivateData; 390 PrivateData* const pData; 391 392 /** @internal */ 393 explicit Widget(Widget* groupWidget, bool addToSubWidgets); 394 395 friend class ImageSlider; 396 friend class NanoWidget; 397 friend class Window; 398 friend class StandaloneWindow; 399 #ifdef DISTRHO_DEFINES_H_INCLUDED 400 friend class DISTRHO_NAMESPACE::UI; 401 #endif 402 403 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Widget) 404 }; 405 406 // ----------------------------------------------------------------------- 407 408 END_NAMESPACE_DGL 409 410 #endif // DGL_WIDGET_HPP_INCLUDED 411