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