1 /* BEvents.hpp 2 * Copyright (C) 2018, 2019 Sven Jähnichen 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef BEVENTS_HPP_ 19 #define BEVENTS_HPP_ 20 21 #include <cstdint> 22 #include <string> 23 #include "BDevices.hpp" 24 #include "../BUtilities/Any.hpp" 25 #include "../BUtilities/RectArea.hpp" 26 27 namespace BWidgets 28 { 29 class Widget; // Forward declaration 30 } 31 32 namespace BEvents 33 { 34 35 //TODO switch toward three pointer event handling states: pass, handle, block 36 37 /** 38 * Enumeration of event types 39 */ 40 enum EventType 41 { 42 CONFIGURE_REQUEST_EVENT, 43 EXPOSE_REQUEST_EVENT, 44 CLOSE_REQUEST_EVENT, 45 KEY_PRESS_EVENT, 46 KEY_RELEASE_EVENT, 47 BUTTON_PRESS_EVENT, 48 BUTTON_RELEASE_EVENT, 49 BUTTON_CLICK_EVENT, 50 POINTER_MOTION_EVENT, 51 POINTER_DRAG_EVENT, 52 WHEEL_SCROLL_EVENT, 53 VALUE_CHANGED_EVENT, 54 FOCUS_IN_EVENT, 55 FOCUS_OUT_EVENT, 56 MESSAGE_EVENT, 57 NO_EVENT 58 }; 59 60 /** 61 * Class BEvents::Event 62 * 63 * Main class of events. Only contains the event type and (a pointer to) the 64 * widget which caused the event. All other event classes are derived from this 65 * class. 66 */ 67 class Event 68 { 69 protected: 70 BWidgets::Widget* eventWidget; 71 EventType eventType; 72 73 public: Event()74 Event () : 75 Event (nullptr, NO_EVENT) {} Event(BWidgets::Widget * widget,const EventType type)76 Event (BWidgets::Widget* widget, const EventType type) : 77 eventWidget (widget), eventType (type) {} 78 ~Event()79 virtual ~Event () {} 80 81 /** 82 * Gets a pointer to the widget which caused the event. 83 * @return Pointer to the widget 84 */ getWidget()85 BWidgets::Widget* getWidget () 86 {return eventWidget;} 87 88 /** 89 * Gets the type of the event 90 * @return Event type 91 */ getEventType() const92 EventType getEventType () const 93 {return eventType;} 94 95 }; 96 /* 97 * End of class BEvents::Event 98 *****************************************************************************/ 99 100 101 /** 102 * Class BEvents::WidgetEvent 103 * 104 * Widget events are emitted by an (event) widget if the widget is requested 105 * by an other (request) widget. This event class is typically used if opening 106 * or closing of a window or an request widget is requested. 107 */ 108 class WidgetEvent : public Event 109 { 110 protected: 111 BWidgets::Widget* requestWidget; 112 113 public: WidgetEvent()114 WidgetEvent () : 115 WidgetEvent (nullptr, nullptr, NO_EVENT) {} WidgetEvent(BWidgets::Widget * eventWidget,BWidgets::Widget * requestWidget,const EventType type)116 WidgetEvent (BWidgets::Widget* eventWidget, BWidgets::Widget* requestWidget, const EventType type) : 117 Event (eventWidget, type), requestWidget (requestWidget) {} 118 119 /** 120 * Gets a pointer to the widget which request the event. 121 * @return Pointer to the widget 122 */ getRequestWidget()123 BWidgets::Widget* getRequestWidget () 124 {return requestWidget;} 125 126 }; 127 /* 128 * End of class BEvents::WidgetEvent 129 *****************************************************************************/ 130 131 132 /** 133 * Class BEvents::ExposeEvent 134 * 135 * Expose events are emitted by a parent event widget (or window) if the visual 136 * output of a child (request) widget is requested to be 137 * updated. An expose event additionally contains the coordinates (x, y, width 138 * and height) of the output region (relative to the widgets origin) that should 139 * be updated. 140 */ 141 class ExposeEvent : public WidgetEvent 142 { 143 protected: 144 BUtilities::RectArea exposeArea; 145 146 public: ExposeEvent()147 ExposeEvent () : 148 ExposeEvent (nullptr, nullptr, NO_EVENT, 0, 0, 0, 0) {}; ExposeEvent(BWidgets::Widget * eventWidget,BWidgets::Widget * requestWidget,const EventType type,const double x,const double y,const double width,const double height)149 ExposeEvent (BWidgets::Widget* eventWidget, BWidgets::Widget* requestWidget, const EventType type, 150 const double x, const double y, const double width, const double height) : 151 ExposeEvent (eventWidget, requestWidget, type, BUtilities::RectArea (x, y, width, height)) {} ExposeEvent(BWidgets::Widget * eventWidget,BWidgets::Widget * requestWidget,const EventType type,const BUtilities::RectArea & area)152 ExposeEvent (BWidgets::Widget* eventWidget, BWidgets::Widget* requestWidget, const EventType type, 153 const BUtilities::RectArea& area) : 154 WidgetEvent (eventWidget, requestWidget, type), 155 exposeArea (area) {} 156 157 /** 158 * Redefines the area coordinates of the output region for the expose 159 * event 160 * @param area Area coordinates relative to the widgets origin 161 */ setArea(const BUtilities::RectArea & area)162 void setArea (const BUtilities::RectArea& area) 163 {exposeArea = area;} 164 165 /** 166 * Gets the area coordinates of the output region for the expose event 167 * @return Area coordinates relative to the widgets origin 168 */ getArea() const169 BUtilities::RectArea getArea () const 170 {return exposeArea;} 171 }; 172 /* 173 * End of class BEvents::ExposeEvent 174 *****************************************************************************/ 175 176 /** 177 * Class BEvents::KeyEvent 178 * 179 * Key events are emitted by the system if a key is pressed or released. 180 */ 181 class KeyEvent : public Event 182 { 183 protected: 184 BUtilities::Point point; 185 uint32_t key; 186 187 public: KeyEvent()188 KeyEvent () : 189 KeyEvent (nullptr, NO_EVENT, 0, 0, 0) {} KeyEvent(BWidgets::Widget * widget,const EventType type,const double x,const double y,const uint32_t unicode)190 KeyEvent (BWidgets::Widget* widget, const EventType type, const double x, const double y, const uint32_t unicode) : 191 KeyEvent (widget, type, BUtilities::Point (x, y), unicode) {} KeyEvent(BWidgets::Widget * widget,const EventType type,const BUtilities::Point & position,const uint32_t unicode)192 KeyEvent (BWidgets::Widget* widget, const EventType type, const BUtilities::Point& position, const uint32_t unicode) : 193 Event (widget, type), 194 point (position), 195 key (unicode) {} 196 197 /** 198 * Redefines the point coordinates of the key event 199 * @param coords Point coordinates relative to the widgets origin 200 */ setPosition(const BUtilities::Point & coords)201 void setPosition (const BUtilities::Point& coords) 202 {point = coords;} 203 204 /** 205 * Gets the point coordinates of the key event 206 * @return coords Point coordinates relative to the widgets origin 207 */ getPosition() const208 BUtilities::Point getPosition () const 209 {return point;} 210 211 /** 212 * Gets the key that caused of the key event 213 * @return Unicode of the key 214 */ getKey() const215 uint32_t getKey () const 216 {return key;} 217 getKeyUTF8() const218 std::string getKeyUTF8 () const 219 { 220 // Invalide unicode 221 if (key > 0x0010ffff) return ""; 222 223 std::string s = ""; 224 225 // 7 bit ASCII: utf-8 = unicode 226 if (key < 0x80) s += char (key); 227 228 // 2/3/4(/5/6) byte utf-8 229 else 230 { 231 uint32_t steps = 2; 232 for (uint32_t i = 3; i <= 6; ++i) 233 { 234 if (key >= (uint32_t (2) << (5 * (i - 1)))) steps = i; 235 } 236 237 char c = char ((0xFF & (0xFF << (8 - steps))) | (key >> (6 * (steps - 1)))); 238 s += c; 239 240 for (uint32_t i = steps - 1; i >= 1; --i) 241 { 242 char c = char (0x80 | ((key >> (6 * (i - 1))) & 0x3f)); 243 s += c; 244 } 245 } 246 247 return s; 248 } 249 }; 250 /* 251 * End of class BEvents::KeyEvent 252 *****************************************************************************/ 253 254 /** 255 * Class BEvents::PointerEvent 256 * 257 * Pointer events are emitted by the system (via pugl and the main window) if 258 * buttons are pressed or released and/or the pointer is moved over a widget. 259 * The pointer event contains data about the position (relative to the 260 * respective widget and the button pressed (or not). 261 * Pointer events will be handled by the respective widget and can be 262 * redirected to external callback functions. 263 */ 264 class PointerEvent : public Event 265 { 266 protected: 267 BUtilities::Point point, origin, delta; 268 BDevices::ButtonCode buttonNr; 269 270 271 public: PointerEvent()272 PointerEvent () : 273 PointerEvent (nullptr, NO_EVENT, 0, 0, 0, 0, 0, 0, BDevices::NO_BUTTON) {} PointerEvent(BWidgets::Widget * widget,const EventType type,const double x,const double y,const double xOrigin,const double yOrigin,const double deltaX,const double deltaY,const BDevices::ButtonCode button)274 PointerEvent (BWidgets::Widget* widget, const EventType type, 275 const double x, const double y, const double xOrigin, const double yOrigin, 276 const double deltaX, const double deltaY, const BDevices::ButtonCode button) : 277 PointerEvent (widget, type, BUtilities::Point (x, y), BUtilities::Point (xOrigin, yOrigin), BUtilities::Point (deltaX, deltaY), button) {} PointerEvent(BWidgets::Widget * widget,const EventType type,const BUtilities::Point & point,const BUtilities::Point & origin,const BUtilities::Point & delta,const BDevices::ButtonCode button)278 PointerEvent (BWidgets::Widget* widget, const EventType type, const BUtilities::Point& point, 279 const BUtilities::Point& origin, const BUtilities::Point& delta, 280 const BDevices::ButtonCode button) : 281 Event (widget, type), point (point), origin (origin), delta (delta), buttonNr (button) {} 282 283 /** 284 * Redefines the point coordinate of the pointer event 285 * @param pont Point coordinate relative to the widgets origin 286 */ setPosition(const BUtilities::Point & coords)287 void setPosition (const BUtilities::Point& coords) 288 {point = coords;} 289 290 /** 291 * Gets the point coordinate of the pointer event 292 * @return Point coordinate relative to the widgets origin 293 */ getPosition() const294 BUtilities::Point getPosition () const 295 {return point;} 296 297 /** 298 * Redefines the point coordinate of the position where the button was 299 * initially pressed 300 * @param origin Point coordinate relative to the widgets origin 301 */ setOrigin(const BUtilities::Point & coords)302 void setOrigin (const BUtilities::Point& coords) 303 {origin = coords;} 304 305 /** 306 * Gets the point coordinate of the pointer position where the respective 307 * button was initially pressed. The returned value is the same as 308 * for getPoint() for BUTTON_PRESS_EVENTs, 0.0 for POINTER_MOTION_EVENTs. 309 * @return Point coordinate relative to the widgets origin 310 */ getOrigin() const311 BUtilities::Point getOrigin () const 312 {return origin;} 313 314 /** 315 * Redefines the pointers movement 316 * @param delta Movement of the pointer 317 */ setDelta(const BUtilities::Point & coords)318 void setDelta (const BUtilities::Point& coords) 319 {delta = coords;} 320 321 /** 322 * Gets the movement (relative to the last PointerEvent) 323 * @return Change in coordinates 324 */ getDelta() const325 BUtilities::Point getDelta () const 326 {return delta;} 327 328 /** 329 * Redefines the button pressed of the pointer event 330 * @param button Button pressed 331 */ setButton(const BDevices::ButtonCode button)332 void setButton (const BDevices::ButtonCode button) 333 {buttonNr = button;} 334 335 /** 336 * Gets the button pressed of the pointer event 337 * @return Button pressed 338 */ getButton() const339 BDevices::ButtonCode getButton () const 340 {return buttonNr;} 341 }; 342 /* 343 * End of class BEvents::PointerEvent 344 *****************************************************************************/ 345 346 /** 347 * Class BEvents::WheelEvent 348 * 349 * Wheel events are emitted by the system (via pugl and the main window) if 350 * a (mouse) wheel is turned. 351 * The wheel event contains data about the relative change of the wheel and 352 * about the pointer position (relative to the respective widget. 353 * Wheel events will be handled by the respective widget and can be 354 * redirected to external callback functions. 355 */ 356 class WheelEvent : public Event 357 { 358 protected: 359 BUtilities::Point point; 360 BUtilities::Point delta; 361 362 public: WheelEvent()363 WheelEvent () : 364 WheelEvent (nullptr, NO_EVENT, 0, 0, 0, 0) {} WheelEvent(BWidgets::Widget * widget,const EventType type,const double x,const double y,const double deltaX,const double deltaY)365 WheelEvent (BWidgets::Widget* widget, const EventType type, const double x, const double y, const double deltaX, const double deltaY) : 366 WheelEvent (widget, type, BUtilities::Point (x, y), BUtilities::Point (deltaX, deltaY)) {} 367 WheelEvent(BWidgets::Widget * widget,const EventType type,const BUtilities::Point & point,const BUtilities::Point delta)368 WheelEvent (BWidgets::Widget* widget, const EventType type, const BUtilities::Point& point, const BUtilities::Point delta) : 369 Event (widget, type), point (point), delta (delta) {} 370 371 /** 372 * Redefines the pointers coordinate 373 * @param x Point coordinate relative to the widgets origin 374 */ setPosition(const BUtilities::Point & coords)375 void setPosition (const BUtilities::Point& coords) 376 {point = coords;} 377 378 /** 379 * Gets the pointers coordinate of the wheel event 380 * @return Point coordinate relative to the widgets origin 381 */ getPosition() const382 BUtilities::Point getPosition () const 383 {return point;} 384 385 /** 386 * Redefines the wheels movement 387 * @param delta Movement of the wheel 388 */ setDelta(const BUtilities::Point & coords)389 void setDelta (const BUtilities::Point& coords) 390 {delta = coords;} 391 392 /** 393 * Gets the xmovement of the wheel 394 * @return Change in coordinate 395 */ getDelta() const396 BUtilities::Point getDelta () const 397 {return delta;} 398 }; 399 /* 400 * End of class BEvents::WheelEvent 401 *****************************************************************************/ 402 403 404 /** 405 * Class BEvents::ValueChangedEvent 406 * 407 * Value changed events are emitted by widgets (namely BWidgets::ValueWidget) 408 * if their setValue method is called. The event additionally exposes the 409 * changed value (that should also be accessible via 410 * BWidgets::ValueWidget::getValue ()). Value changed events can be handled 411 * internally (e.g., by composite widgets) and can also be redirected to 412 * external callback functions. 413 */ 414 class ValueChangedEvent : public Event 415 { 416 protected: 417 double value; 418 419 public: ValueChangedEvent()420 ValueChangedEvent () : 421 ValueChangedEvent (nullptr, 0.0) {} ValueChangedEvent(BWidgets::Widget * widget,const double val)422 ValueChangedEvent (BWidgets::Widget* widget, const double val) : 423 Event (widget, VALUE_CHANGED_EVENT), value (val) {} 424 425 /** 426 * Redefines the value exposed by the event. This method doesn't change the 427 * value within a widget! 428 * @param val New value 429 */ setValue(const double val)430 void setValue (const double val) 431 {value = val;} 432 433 /** 434 * Gets the value exposed by the event 435 * @return Value of the event 436 */ getValue() const437 double getValue () const 438 {return value;} 439 }; 440 /* 441 * End of class BEvents::ValueChangedEvent 442 *****************************************************************************/ 443 444 /** 445 * Class BEvents::FocusEvent 446 * 447 * Focus events are emitted by widgets if the pointer rests for a predefined 448 * time over the widget 449 */ 450 class FocusEvent : public Event 451 { 452 protected: 453 BUtilities::Point point; 454 455 public: FocusEvent()456 FocusEvent () : 457 FocusEvent (nullptr, NO_EVENT, 0, 0) {} FocusEvent(BWidgets::Widget * widget,const EventType type,const double x,const double y)458 FocusEvent (BWidgets::Widget* widget, const EventType type, const double x, const double y) : 459 FocusEvent (widget, type, BUtilities::Point (x, y)) {} FocusEvent(BWidgets::Widget * widget,const EventType type,const BUtilities::Point & point)460 FocusEvent (BWidgets::Widget* widget, const EventType type, const BUtilities::Point& point) : 461 Event (widget, type), point (point) {} 462 463 /** 464 * Redefines the pointers coordinate 465 * @param x Point coordinate relative to the widgets origin 466 */ setPosition(const BUtilities::Point & coords)467 void setPosition (const BUtilities::Point& coords) 468 {point = coords;} 469 470 /** 471 * Gets the pointers coordinate of the wheel event 472 * @return Point coordinate relative to the widgets origin 473 */ getPosition() const474 BUtilities::Point getPosition () const 475 {return point;} 476 }; 477 /* 478 * End of class BEvents::ValueChangedEvent 479 *****************************************************************************/ 480 481 /** 482 * Class BEvents::MessageEvent 483 * 484 * Ubiquitous event type 485 */ 486 class MessageEvent : public Event 487 { 488 protected: 489 std::string messageName; 490 BUtilities::Any messageContent; 491 492 public: MessageEvent()493 MessageEvent () : 494 MessageEvent (nullptr, "", BUtilities::Any ()) {} MessageEvent(BWidgets::Widget * widget,const std::string & name,const BUtilities::Any & content)495 MessageEvent (BWidgets::Widget* widget, const std::string& name, const BUtilities::Any& content) : 496 Event (widget, MESSAGE_EVENT), messageName (name), messageContent (content) {} 497 setName(const std::string & name)498 void setName (const std::string& name) 499 {messageName = name;} 500 getName() const501 std::string getName () const 502 {return messageName;} 503 setContent(const BUtilities::Any & content)504 void setContent (const BUtilities::Any& content) 505 {messageContent = content;} 506 getContent() const507 BUtilities::Any getContent () const 508 {return messageContent;} 509 }; 510 511 } 512 513 #endif /* BEVENTS_HPP_ */ 514