| GL Studio C++ Runtime API

events.h
Go to the documentation of this file.
1/*! \file
2 \brief The standard Mouse and keyboard events and event structures
3
4 \par Copyright Information
5
6 Copyright (c) 2015 by The DiSTI Corporation.<br />
7 11301 Corporate Blvd., Suite 100<br />
8 Orlando, FL 32817<br />
9 USA<br />
10 <br />
11 All rights reserved.<br />
12
13 This Software contains proprietary trade secrets of DiSTI and may not be
14 reproduced, in whole or part, in any form, or by any means of electronic,
15 mechanical, or otherwise, without the written permission of DiSTI. Said
16 permission may be derived through the purchase of applicable DiSTI product
17 licenses which detail the distribution rights of this content and any
18 Derivative Works based on this or other copyrighted DiSTI Software.
19
20 NO WARRANTY. THE SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND,
21 AND ANY USE OF THIS SOFTWARE PRODUCT IS AT YOUR OWN RISK. TO THE MAXIMUM EXTENT
22 PERMITTED BY APPLICABLE LAW, DISTI AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES
23 AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
24 IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND/OR FITNESS FOR A
25 PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, WITH REGARD TO THE SOFTWARE.
26
27 LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
28 IN NO EVENT SHALL DISTI OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
29 INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION,
30 DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
31 INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
32 INABILITY TO USE THE SOFTWARE, EVEN IF DISTI HAS BEEN ADVISED OF THE POSSIBILITY
33 OF SUCH DAMAGES. DISTI'S ENTIRE LIABILITY AND YOUR EXCLUSIVE REMEDY SHALL NOT
34 EXCEED FIVE DOLLARS (US$5.00).
35
36 The aforementioned terms and restrictions are governed by the laws of the
37 State of Florida and the United States of America. Use, distribution,
38 duplication, or disclosure by the U. S. Government is subject to
39"Restricted Rights" as set forth in DFARS 252.227-7014(c)(1)(ii).
40*/
41#ifndef INCLUDED_DISTI_EVENTS_H
42#define INCLUDED_DISTI_EVENTS_H
43
44#include "component_base.h"
45#include "display.h"
46#include "gls_include.h"
47#include "group.h"
48#include "timer.h"
49#include <string>
50
51#ifdef __VXWORKS__
52# include <cctype> //tolower
53#endif
54
55 namespace disti
56{
57/** Enumeration for event types */
58 typedef enum
59{
60 EVENT_MOUSE, /**< A Mouse (or touch screen) event */
61 EVENT_KEYBOARD, /**< A Keyboard event */
62 EVENT_TIMER, /**< Unused */
63 EVENT_OBJECT, /**< An event emitted by an object */
64 EVENT_KEYBOARD_UP /**< A Keyboard up event (uses KeyboardEvent class) */
65} EventType_e;
66
67/** Enumeration for mouse event types */
68 typedef enum
69{
70 MOUSE_DOWN, /**< A Mouse button was pushed down */
71 MOUSE_UP, /**< A Mouse button was released */
72 MOUSE_MOVE, /**< The mouse moved */
73 MOUSE_DRAG, /**< The mouse moved while a button was held down */
74 MOUSE_LEAVE, /**< The mouse exited the object */
75 MOUSE_ENTER, /**< The mouse entered the object */
76 MOUSE_WHEEL_MINUS, /**< The mouse wheel was turned in the negative direction */
77 MOUSE_WHEEL_PLUS, /**< The mouse wheel was turned in the positive direction */
78 MOUSE_RECEIVE_MULTITOUCH, /**< Handle this event to receive input from multiple touches at the same time */
79 MOUSE_CANCEL, /**< Handle this event to interrupt the current mouse event */
80 MOUSE_DOUBLE /**< A Mouse button was pushed down twice */
81} MouseEventType_e;
82
83/** Enumeration for mouse buttons */
84 typedef enum
85{
86 MOUSE_LBUTTON = 1, /**< Mask that matches only left mouse button */
87 MOUSE_MBUTTON = 2, /**< Mask that matches only middle mouse button */
88 MOUSE_RBUTTON = 4, /**< Mask that matches only right mouse button */
89 MOUSE_BUTTON_ANY = 7 /**< Mask that matches any mouse button */
90} MouseButtonType_e;
91
92/** Enumeration for keyboard modifiers */
93 typedef enum
94{
95 NONE_STATE = 0,
96 SHIFT_STATE = 0x00010000,
97 CAPS_LOCK_STATE = 0x00020000,
98 CTRL_STATE = 0x00040000,
99 ALT_STATE = 0x00080000,
100 NUM_LOCK_STATE = 0x00100000,
101 META_STATE = 0x00400000,
102 SCROLL_LOCK_STATE = 0x00800000,
103 BUTTON1_STATE = 0x01000000,
104 BUTTON2_STATE = 0x02000000,
105 BUTTON3_STATE = 0x04000000
106} SpecialKeyState_e;
107
108/** The base class for all user defined events.
109 * Each new class of event is assigned an event type.
110 * Each new event is assigned an event subtype
111 */
112 class DisplayEvent
113{
114 public:
115 unsigned short eventType; /**< Major event code. e.g., EVENT_MOUSE */
116 unsigned short eventSubtype; /**< Minor event code. e.g., MOUSE_DOWN */
117
118 /** Default constructor */
119 DisplayEvent()
120 : eventType( 0u )
121 , eventSubtype( 0u )
122 {
123 }
124
125 /// Copy constructor
126 /// \param source The event to copy from.
127 DisplayEvent( const DisplayEvent& source )
128 : eventType( source.eventType )
129 , eventSubtype( source.eventSubtype )
130 {
131 }
132
133 /** Virtual deconstructor to enable RTTI */
134 virtual ~DisplayEvent()
135 {
136 }
137};
138
139/** An event with location fields */
140 class LocationEvent : public DisplayEvent
141{
142 public:
143 /** Location of the event in window coordinates
144 * x and y window coordinates in pixels.
145 * z is from 0.0 -> 1.0 and represents the depth.
146 * z == 0 is at the near cliping plane.
147 * z == 0.5 represents half way between near
148 * and far cliping planes.
149 */
150 Vector winLoc;
151
152 /** x,y,z of event in logical design coordinates */
153 Vector lCoords;
154
155 /** x,y,z of event in object DCS coordinates */
156 Vector oCoords;
157
158 // These references are included for backwards compatibility with GL Studio 2.1.
159 // They are simply references into the above vectors. New code should not use these!
160 float& x; /**< Reference to winLoc.x */
161 float& y; /**< Reference to winLoc.y */
162 float& z; /**< Reference to winLoc.z */
163
164 float& lx; /**< Reference to lCoords.x */
165 float& ly; /**< Reference to lCoords.y */
166 float& lz; /**< Reference to lCoords.z */
167
168 float& ox; /**< Reference to oCoords.x */
169 float& oy; /**< Reference to oCoords.y */
170 float& oz; /**< Reference to oCoords.z */
171
172 /** Because of the use of the references, all automatically generated methods
173 * must be defined to allow for copying. */
174
175 /** Default constructor */
176 LocationEvent()
177 : DisplayEvent()
178 , x( winLoc.x )
179 , y( winLoc.y )
180 , z( winLoc.z )
181 , lx( lCoords.x )
182 , ly( lCoords.y )
183 , lz( lCoords.z )
184 , ox( oCoords.x )
185 , oy( oCoords.y )
186 , oz( oCoords.z )
187 {
188 }
189
190 /// Copy Constructor
191 /// \param source The event to copy from.
192 LocationEvent( const LocationEvent& source )
193 : DisplayEvent( source )
194 , winLoc( source.winLoc )
195 , lCoords( source.lCoords )
196 , oCoords( source.oCoords )
197 , x( winLoc.x )
198 , y( winLoc.y )
199 , z( winLoc.z )
200 , lx( lCoords.x )
201 , ly( lCoords.y )
202 , lz( lCoords.z )
203 , ox( oCoords.x )
204 , oy( oCoords.y )
205 , oz( oCoords.z )
206 {
207 }
208
209 /// Assignment operator
210 /// \param source The event to copy from.
211 /// \return The resulting event (this).
212 LocationEvent operator=( const LocationEvent& source )
213 {
214 eventType = source.eventType;
215 eventSubtype = source.eventSubtype;
216 winLoc = source.winLoc;
217 lCoords = source.lCoords;
218 oCoords = source.oCoords;
219 return *this;
220 }
221};
222
223/** A mouse event */
224 class MouseEvent : public LocationEvent
225{
226 public:
227 /** Default Constructor */
228 MouseEvent()
229 : LocationEvent()
230 , buttonMask( 0u )
231 , clicks( 0u )
232 , modifiers( 0 )
233 , cursorID( 0u )
234 {
235 eventType = EVENT_MOUSE;
236 }
237
238 /// Copy Constructor
239 /// \param source The event to copy from.
240 MouseEvent( const MouseEvent& source )
241 : LocationEvent( source )
242 , buttonMask( source.buttonMask )
243 , clicks( source.clicks )
244 , modifiers( source.modifiers )
245 , cursorID( source.cursorID )
246 {
247 }
248
249 /// Copy Constructor from LocationEvent
250 /// \param source The event to copy from.
251 MouseEvent( const LocationEvent& source )
252 : LocationEvent( source )
253 , buttonMask( 0u )
254 , clicks( 0u )
255 , modifiers( 0 )
256 , cursorID( 0u )
257 {
258 eventType = EVENT_MOUSE;
259 }
260
261 /// Assignment operator
262 /// \param source The event to copy from.
263 /// \return The resulting event (this).
264 MouseEvent operator=( const MouseEvent& source )
265 {
266 LocationEvent::operator=( source );
267 buttonMask = source.buttonMask;
268 clicks = source.clicks;
269 modifiers = source.modifiers;
270 cursorID = source.cursorID;
271 return *this;
272 }
273
274 unsigned char buttonMask; /**< bitfield: which button was pressed for this event */
275 unsigned char clicks; /**< Number of times a button was pressed */
276 int modifiers; /**< bitfield: which buttons or modifiers were depressed before event \sa SpecialKeyState_e */
277 unsigned int cursorID; /**< cursor id for multi-touch support */
278};
279
280/** A keyboard event */
281 class KeyboardEvent : public LocationEvent
282{
283 public:
284 /// Default Constructor
285 KeyboardEvent()
286 : LocationEvent()
287 , keysym( 0 )
288 , event_text( 0 )
289 , modifiers( 0 )
290 {
291 }
292
293 /// Copy Constructor
294 /// \param source The event to copy from.
295 KeyboardEvent( const KeyboardEvent& source )
296 : LocationEvent( source )
297 , keysym( source.keysym )
298 , event_text( source.event_text )
299 , modifiers( source.modifiers )
300 {
301 }
302
303 /// Copy Constructor from LocationEvent
304 /// \param source The event to copy from.
305 KeyboardEvent( const LocationEvent& source )
306 : LocationEvent( source )
307 , keysym( 0 )
308 , event_text( 0 )
309 , modifiers( 0 )
310 {
311 }
312
313 /// Assignment operator
314 /// \param source The event to copy from.
315 /// \return The resulting event (this).
316 KeyboardEvent operator=( const KeyboardEvent& source )
317 {
318 LocationEvent::operator=( source );
319 keysym = source.keysym;
320 event_text = source.event_text;
321 modifiers = source.modifiers;
322 return *this;
323 }
324
325 int keysym; /**< FLTK code for key that was pressed */
326 int event_text; /**< FLTK event text code for key that was pressed */
327 int modifiers; /**< bitfield: which modifiers or buttons were pressed \sa SpecialKeyState_e */
328};
329
330/** The ObjectEvent class
331 * This event is intended to be emitted by objects, rather than by a mouse or keyboard.
332 */
333 class ObjectEvent : public DisplayEvent
334{
335 DisplayObject* _initiator; /**< The display object that initiated the event */
336 char* _eventName; /**< String event name */
337 char* _eventData; /**< Any additional data for this event. A NULL terminated string */
338
339 public:
340 ObjectEvent()
341 : DisplayEvent()
342 , _initiator( NULL )
343 , _eventName( NULL )
344 , _eventData( NULL )
345 {
346 eventType = EVENT_OBJECT;
347 }
348
349 /** Create an ObjectEvent, setting the initator and event name
350 * \param initiator Pointer to the object that initated the event
351 * \param eventName Name of the event
352 * \param eventData Data of the event
353 */
354 ObjectEvent( DisplayObject* initiator, const char* eventName, const char* eventData = NULL )
355 : DisplayEvent()
356 , _initiator( initiator )
357 , _eventName( NULL )
358 , _eventData( NULL )
359 {
360 int size = (int)strlen( eventName ) + 1;
361 _eventName = new char[ size ];
362#if defined( _WIN32 )
363 strcpy_s( _eventName, size, eventName );
364#else
365 strcpy( _eventName, eventName );
366#endif
367 if( eventData )
368 {
369 size = (int)strlen( eventData ) + 1;
370 _eventData = new char[ size ];
371#if defined( _WIN32 )
372 strcpy_s( _eventData, size, eventData );
373#else
374 strcpy( _eventData, eventData );
375#endif
376 }
377
378 eventType = EVENT_OBJECT;
379 }
380
381 /** Create an ObjectEvent, setting the initator and event subtype
382 * \param initiator Pointer to the object that initated the event
383 * \param eventSubtypeArg The arbitrary event subtype
384 */
385 ObjectEvent( DisplayObject* initiator, unsigned short eventSubtypeArg )
386 : DisplayEvent()
387 , _initiator( initiator )
388 , _eventName( NULL )
389 , _eventData( NULL )
390 {
391 eventType = EVENT_OBJECT;
392 eventSubtype = eventSubtypeArg;
393 }
394
395 virtual ~ObjectEvent()
396 {
397 delete[] _eventName;
398 _eventName = NULL;
399
400 delete[] _eventData;
401 _eventData = NULL;
402 }
403
404 /** \return Pointer to the object that initiated the event (may be NULL)
405 */
406 DisplayObject* Initiator() const { return _initiator; }
407
408 /** Set which object initiated the event
409 * \param initiator Pointer to the object that initiated the event
410 */
411 void Initiator( DisplayObject* initiator ) { _initiator = initiator; }
412
413 /** \return The name of the event
414 */
415 const char* EventName() const
416 {
417 if( _eventName )
418 {
419 return _eventName;
420 }
421 else
422 {
423 return "";
424 }
425 }
426
427 /** Set the name of the event
428 * For CRT safety, this should only be called by the constructing code
429 * \param newName The name to set
430 */
431 void EventName( const char* newName )
432 {
433 delete[] _eventName;
434 _eventName = NULL;
435
436 if( newName )
437 {
438 int size = (int)strlen( newName ) + 1;
439 _eventName = new char[ size ];
440#if defined( _WIN32 )
441 strcpy_s( _eventName, size, newName );
442#else
443 strcpy( _eventName, newName );
444#endif
445 }
446 }
447
448 /** \return The data of the event, NULL terminated
449 */
450 const char* EventData() const
451 {
452 if( _eventData )
453 {
454 return _eventData;
455 }
456 else
457 {
458 return "";
459 }
460 }
461
462 /** Set the data of the event, NULL terminated.
463 * For CRT safety, this should only be called by the constructing code
464 * \param newData The name to set
465 */
466 void EventData( const char* newData )
467 {
468 delete[] _eventData;
469 _eventData = NULL;
470
471 if( newData )
472 {
473 int size = (int)strlen( newData ) + 1;
474 _eventData = new char[ size ];
475#if defined( _WIN32 )
476 strcpy_s( _eventData, size, newData );
477#else
478 strcpy( _eventData, newData );
479#endif
480 }
481 }
482
483 /// \param eventName The name to compare.
484 /// \return True if the name of this event matches the given name.
485 bool EventNameIs( const char* eventName ) const
486 {
487 if( !_eventName || !eventName )
488 {
489 return false;
490 }
491
492 return ( 0 == strcmp( _eventName, eventName ) );
493 }
494
495 /// \param eventData The name to compare.
496 /// \return True if the name of this event matches the given name.
497 bool EventDataIs( const char* eventData ) const
498 {
499 if( !_eventData || !eventData )
500 {
501 return false;
502 }
503
504 return ( 0 == strcmp( _eventData, eventData ) );
505 }
506};
507
508/// Emits the specfied ObjectEvent.
509/// \param self The object emitting the event.
510/// \param event A complete ObjectEvent object to emit.
511 inline void EmitObjectEvent( DisplayObject* self, ObjectEvent* event )
512{
513 if( self->ParentGroup() )
514 {
515 self->ParentGroup()->handle( event );
516 }
517 else if( dynamic_cast<ComponentBase*>( self ) )
518 {
519 // Called when our ParentGroup is NULL and we are wrapped by an RSO Interface.
520 self->handle( event );
521 }
522}
523
524/// Creates an ObjectEvent from the given NULL terminated strings and emits it.
525/// \param self The object emitting the event.
526/// \param eventName The name of the event e.g. "StateChanged".
527/// \param eventData Optional additional user data.
528 inline void EmitObjectEvent( DisplayObject* self, const char* eventName, const char* eventData = NULL )
529{
530 ObjectEvent temp( self, eventName, eventData );
531 EmitObjectEvent( self, &temp );
532}
533
534/** \return true if the given DisplayEvent is an ObjectEvent and it's event name matches the given string.
535 * \param event The event to check
536 * \param eventName The eventName to compare
537 * \param eventData optional eventData to compare, if NULL, it will not be checked, otherwise, it will.
538 */
539 inline bool ObjectEventIs( DisplayEvent* event, const char* eventName, const char* eventData = NULL )
540{
541 ObjectEvent* objEvent = dynamic_cast<ObjectEvent*>( event );
542 bool is = ( objEvent && objEvent->EventNameIs( eventName ) );
543 if( is && eventData )
544 {
545 is = objEvent->EventDataIs( eventData );
546 }
547 return is;
548}
549
550/** Basic on event test, given the event and subevent enums. */
551#define ON( event, subevent ) if( ( ev->eventType == ( event ) ) && ( ev->eventSubtype == ( subevent ) ) )
552
553/** On mouse button up event test, given the mouse button enum. */
554#define ON_MOUSE_UP( btnMask ) if( ( ev->eventType == EVENT_MOUSE ) && ( ev->eventSubtype == MOUSE_UP ) && ( (btnMask)&mev->buttonMask ) )
555
556/** On mouse button down event test, given the mouse button enum. */
557#define ON_MOUSE_DOWN( btnMask ) if( ( ev->eventType == EVENT_MOUSE ) && ( ev->eventSubtype == MOUSE_DOWN ) && ( (btnMask)&mev->buttonMask ) )
558
559/** On mouse button held during a drag event test, given the mouse button enum. */
560#define ON_MOUSE_DRAG( btnMask ) if( ( ev->eventType == EVENT_MOUSE ) && ( ev->eventSubtype == MOUSE_DRAG ) && ( (btnMask)&mev->buttonMask ) )
561
562/** On keyboard key down event test, given the alpha numeric key to test. */
563#define ON_KEY_DOWN( testKey ) if( ( ev->eventType == EVENT_KEYBOARD ) && OnKeyEvent( kev, true, int( testKey ) ) )
564
565/** On keyboard key up event test, given the alpha numeric key to test. */
566#define ON_KEY_UP( testKey ) if( ( ev->eventType == EVENT_KEYBOARD_UP ) && OnKeyEvent( kev, true, int( testKey ) ) )
567
568/** On keyboard key down with modifiers event test, given the alpha numeric key and modifiers to test. */
569#define ON_KEY_DOWN_WITH_MODIFIER( testKey, modifierMask ) if( ( ev->eventType == EVENT_KEYBOARD ) && OnKeyEvent( kev, true, int( testKey ), modifierMask ) )
570
571/** On keyboard key up with modifiers event test, given the alpha numeric key and modifiers to test. */
572#define ON_KEY_UP_WITH_MODIFIER( testKey, modifierMask ) if( ( ev->eventType == EVENT_KEYBOARD_UP ) && OnKeyEvent( kev, true, int( testKey ), modifierMask ) )
573
574/** On keyboard key down event test, given the special key to test. */
575#define ON_SPECIAL_KEY_DOWN( keySym ) if( ( ev->eventType == EVENT_KEYBOARD ) && OnKeyEvent( kev, false, int( keySym ) ) )
576
577/** On keyboard key up event test, given the special key to test. */
578#define ON_SPECIAL_KEY_UP( keySym ) if( ( ev->eventType == EVENT_KEYBOARD_UP ) && OnKeyEvent( kev, false, int( keySym ) ) )
579
580/** On keyboard key down with modifiers event test, given the special key and modifiers to test. */
581#define ON_SPECIAL_KEY_DOWN_WITH_MODIFIER( keySym, modifierMask ) if( ( ev->eventType == EVENT_KEYBOARD ) && OnKeyEvent( kev, false, int( keySym ), modifierMask ) )
582
583/** On keyboard key up with modifiers event test, given the special key and modifiers to test. */
584#define ON_SPECIAL_KEY_UP_WITH_MODIFIER( keySym, modifierMask ) if( ( ev->eventType == EVENT_KEYBOARD_UP ) && OnKeyEvent( kev, false, int( keySym ), modifierMask ) )
585
586/** On keyboard key down event test. */
587#define ON_ANY_KEY_DOWN() if( ( ev->eventType == EVENT_KEYBOARD ) )
588
589/** On keyboard key up event test. */
590#define ON_ANY_KEY_UP() if( ( ev->eventType == EVENT_KEYBOARD_UP ) )
591
592/** Examples:
593 * ON( EVENT_MOUSE, MOUSE_DOWN )
594 * {
595 * }
596 * ON_MOUSE_DOWN( MOUSE_LBUTTON )
597 * {
598 * }
599 * ON_KEY_DOWN( 'a' )
600 * {
601 * }
602 * ON_KEY_DOWN_WITH_MODIFIER( 'B', FL_SHIFT )
603 * {
604 * }
605 * ON_KEY_DOWN_WITH_MODIFIER( 'c', FL_SHIFT | FL_CTRL )
606 * {
607 * }
608 * ON_SPECIAL_KEY_DOWN( FL_KP+'1' )
609 * {
610 * }
611 * ON_SPECIAL_KEY_DOWN_WITH_MODIFIER( FL_F+1, FL_CTRL )
612 * {
613 * }
614 * For a comprehensive list of keys and modifiers refer to Enumerations.H.
615 */
616
617/// A convenience function to compare a KeyboardEvent against a particular keyboard key / modifier combo.
618/// \param kev The KeyboardEvent to check.
619/// \param alphaNumeric Whether or not to try to compare to kev->event_text versus kev->keysym.
620/// \param key The key to look for in the event.
621/// \param modifierMask Any modifiers to look for in the event.
622/// \return True if the incoming key event matches the other incoming parameters.
623 inline bool OnKeyEvent( KeyboardEvent* kev, bool alphaNumeric, int key, int modifierMask = 0 )
624{
625 bool keySuccess = false;
626
627 if( alphaNumeric )
628 {
629 /** If CTRL is expected we need to look at keysym instead.
630 * Because CTRL changes the output of the key press to something unexpected
631 * we need to check against the key press action instead.
632 */
633 if( CTRL_STATE & modifierMask )
634 {
635 /** keysym is always lowercase */
636 key = std::tolower( key );
637 keySuccess = ( key == kev->keysym );
638 }
639 else
640 {
641 keySuccess = ( key == kev->event_text );
642 }
643 }
644 else
645 {
646 keySuccess = ( key == kev->keysym );
647 }
648
649 /** Compare to zero to avoid performance warnings.
650 * Did we find the modifiers we're looking for (modifierMask) in the modifiers currently pressed (kev->modifiers)?
651 * OR Are we not looking for any modifiers AND none of the modifiers are currently pressed?
652 * (ignoring the lock state and mouse button modifiers)
653 */
654 bool modSuccess = ( 0 != ( modifierMask & kev->modifiers ) || ( 0 == modifierMask && 0 == ( int( SHIFT_STATE | CTRL_STATE | ALT_STATE | META_STATE ) & kev->modifiers ) ) );
655
656 return ( keySuccess && modSuccess );
657}
658
659 template<class T>
660/** Event Compressor */
661 class EventCompressor
662{
663 public:
664 typedef DisplayObject* ( T::*EventSenderCbType )( DisplayEvent* ev ); ///< Typedef for a event callback function pointer.
665
666 protected:
667 MouseEvent _lastCompressedEvent; ///< The result of event compression, i.e. what all the other events boiled down to.
668 bool _lastEventWasCompressed; ///< If true, the event we're passing along was compressed.
669 EventSenderCbType _handleCb; ///< The callback function that will process this event.
670 T* _objectPtr; ///< The object containing the callback function.
671 bool _sendingCompressed; ///< Flag set to avoid compressing an already compressed event (infinite loop).
672 bool _active; ///< If active, events will be compressed, i.e. multiple MOUSE_DRAG will be boiled down to one equivalent MOUSE_DRAG.
673
674 public:
675 /// Set the current active state for event compression.
676 /// \param val The new active state to set.
677 void Active( bool val ) { _active = val; }
678
679 /// \return The current active state of event compression.
680 bool Active() { return _active; }
681
682 /// Construct a new EventCompressor object to compress events for the given object.
683 /// \param objectPtr The object to receive compressed events, contains the callback function.
684 /// \param cb The callback function to receive compressed events.
685 EventCompressor( T* objectPtr, EventSenderCbType cb )
686 : _lastEventWasCompressed( false )
687 , _handleCb( cb )
688 , _objectPtr( objectPtr )
689 , _sendingCompressed( false )
690 , _active( true )
691 {
692 }
693
694 /// Caller should stop processing this event if returns true
695 /// Caller *MUST* call SendAnyCompressedEvents() before
696 /// drawing to make sure any saved events are processed.
697 /// \param ev The event to compress.
698 /// \return True if event was compressed.
699 bool CompressEvent( const DisplayEvent& ev )
700 {
701 if( !_active || _sendingCompressed )
702 {
703 return false;
704 }
705
706 bool compressed = false;
707 if( EVENT_MOUSE == ev.eventType && ( MOUSE_MOVE == ev.eventSubtype || MOUSE_DRAG == ev.eventSubtype ) )
708 {
709 MouseEvent* mev = (MouseEvent*)&ev;
710
711 if( !_lastEventWasCompressed || ( _lastEventWasCompressed && _lastCompressedEvent.eventType == ev.eventType && _lastCompressedEvent.eventSubtype == ev.eventSubtype && _lastCompressedEvent.cursorID == mev->cursorID ) )
712 {
713 // Replace with this event, and don't send
714 _lastCompressedEvent = *mev;
715 _lastEventWasCompressed = true;
716 compressed = true;
717 }
718 }
719
720 // If we did not compress the event, send any pending ones.
721 if( !compressed )
722 {
723 SendAnyCompressedEvents();
724 }
725 return compressed;
726 }
727
728 /// Passes along the resulting compressed event to the target object's callback function.
729 void SendAnyCompressedEvents()
730 {
731 // Avoids infinite loop
732 if( _sendingCompressed )
733 {
734 return;
735 }
736
737 if( _lastEventWasCompressed )
738 {
739 _sendingCompressed = true;
740 // Call the callback
741 ( _objectPtr->*( _handleCb ) )( &_lastCompressedEvent );
742 // The event is no longer valid
743 _sendingCompressed = false;
744
745 _lastEventWasCompressed = false;
746 }
747 }
748};
749
750} // namespace disti
751
752#endif // INCLUDED_DISTI_EVENTS_H
disti::ComponentBase
Definition: component_base.h:68
disti::DisplayEvent
Definition: events.h:113
disti::DisplayEvent::~DisplayEvent
virtual ~DisplayEvent()
Definition: events.h:134
disti::DisplayEvent::DisplayEvent
DisplayEvent(const DisplayEvent &source)
Definition: events.h:127
disti::DisplayEvent::eventSubtype
unsigned short eventSubtype
Definition: events.h:116
disti::DisplayEvent::eventType
unsigned short eventType
Definition: events.h:115
disti::DisplayEvent::DisplayEvent
DisplayEvent()
Definition: events.h:119
disti::DisplayObject
Definition: display.h:96
disti::DisplayObject::handle
virtual DisplayObject * handle(DisplayEvent *ev)
disti::DisplayObject::ParentGroup
virtual void ParentGroup(Group *group)
disti::EventCompressor
Definition: events.h:662
disti::EventCompressor::_lastEventWasCompressed
bool _lastEventWasCompressed
If true, the event we're passing along was compressed.
Definition: events.h:668
disti::EventCompressor::CompressEvent
bool CompressEvent(const DisplayEvent &ev)
Definition: events.h:699
disti::EventCompressor::SendAnyCompressedEvents
void SendAnyCompressedEvents()
Passes along the resulting compressed event to the target object's callback function.
Definition: events.h:729
disti::EventCompressor::_sendingCompressed
bool _sendingCompressed
Flag set to avoid compressing an already compressed event (infinite loop).
Definition: events.h:671
disti::EventCompressor::EventCompressor
EventCompressor(T *objectPtr, EventSenderCbType cb)
Definition: events.h:685
disti::EventCompressor::_objectPtr
T * _objectPtr
The object containing the callback function.
Definition: events.h:670
disti::EventCompressor::_handleCb
EventSenderCbType _handleCb
The callback function that will process this event.
Definition: events.h:669
disti::EventCompressor::_active
bool _active
If active, events will be compressed, i.e. multiple MOUSE_DRAG will be boiled down to one equivalent ...
Definition: events.h:672
disti::EventCompressor::_lastCompressedEvent
MouseEvent _lastCompressedEvent
The result of event compression, i.e. what all the other events boiled down to.
Definition: events.h:667
disti::EventCompressor::EventSenderCbType
DisplayObject *(T::* EventSenderCbType)(DisplayEvent *ev)
Typedef for a event callback function pointer.
Definition: events.h:664
disti::EventCompressor::Active
void Active(bool val)
Definition: events.h:677
disti::EventCompressor::Active
bool Active()
Definition: events.h:680
disti::KeyboardEvent
Definition: events.h:282
disti::KeyboardEvent::KeyboardEvent
KeyboardEvent()
Default Constructor.
Definition: events.h:285
disti::KeyboardEvent::modifiers
int modifiers
Definition: events.h:327
disti::KeyboardEvent::KeyboardEvent
KeyboardEvent(const KeyboardEvent &source)
Definition: events.h:295
disti::KeyboardEvent::event_text
int event_text
Definition: events.h:326
disti::KeyboardEvent::keysym
int keysym
Definition: events.h:325
disti::KeyboardEvent::KeyboardEvent
KeyboardEvent(const LocationEvent &source)
Definition: events.h:305
disti::KeyboardEvent::operator=
KeyboardEvent operator=(const KeyboardEvent &source)
Definition: events.h:316
disti::LocationEvent
Definition: events.h:141
disti::LocationEvent::y
float & y
Definition: events.h:161
disti::LocationEvent::oy
float & oy
Definition: events.h:169
disti::LocationEvent::ox
float & ox
Definition: events.h:168
disti::LocationEvent::winLoc
Vector winLoc
Definition: events.h:150
disti::LocationEvent::ly
float & ly
Definition: events.h:165
disti::LocationEvent::lz
float & lz
Definition: events.h:166
disti::LocationEvent::z
float & z
Definition: events.h:162
disti::LocationEvent::lCoords
Vector lCoords
Definition: events.h:153
disti::LocationEvent::oz
float & oz
Definition: events.h:170
disti::LocationEvent::oCoords
Vector oCoords
Definition: events.h:156
disti::LocationEvent::LocationEvent
LocationEvent()
Definition: events.h:176
disti::LocationEvent::LocationEvent
LocationEvent(const LocationEvent &source)
Definition: events.h:192
disti::LocationEvent::lx
float & lx
Definition: events.h:164
disti::LocationEvent::x
float & x
Definition: events.h:160
disti::LocationEvent::operator=
LocationEvent operator=(const LocationEvent &source)
Definition: events.h:212
disti::MouseEvent
Definition: events.h:225
disti::MouseEvent::buttonMask
unsigned char buttonMask
Definition: events.h:274
disti::MouseEvent::modifiers
int modifiers
Definition: events.h:276
disti::MouseEvent::MouseEvent
MouseEvent(const LocationEvent &source)
Definition: events.h:251
disti::MouseEvent::cursorID
unsigned int cursorID
Definition: events.h:277
disti::MouseEvent::clicks
unsigned char clicks
Definition: events.h:275
disti::MouseEvent::MouseEvent
MouseEvent()
Definition: events.h:228
disti::MouseEvent::operator=
MouseEvent operator=(const MouseEvent &source)
Definition: events.h:264
disti::MouseEvent::MouseEvent
MouseEvent(const MouseEvent &source)
Definition: events.h:240
disti::ObjectEvent
Definition: events.h:334
disti::ObjectEvent::ObjectEvent
ObjectEvent(DisplayObject *initiator, const char *eventName, const char *eventData=NULL)
Definition: events.h:354
disti::ObjectEvent::EventData
const char * EventData() const
Definition: events.h:450
disti::ObjectEvent::ObjectEvent
ObjectEvent(DisplayObject *initiator, unsigned short eventSubtypeArg)
Definition: events.h:385
disti::ObjectEvent::EventData
void EventData(const char *newData)
Definition: events.h:466
disti::ObjectEvent::EventDataIs
bool EventDataIs(const char *eventData) const
Definition: events.h:497
disti::ObjectEvent::Initiator
DisplayObject * Initiator() const
Definition: events.h:406
disti::ObjectEvent::EventName
const char * EventName() const
Definition: events.h:415
disti::ObjectEvent::EventName
void EventName(const char *newName)
Definition: events.h:431
disti::ObjectEvent::Initiator
void Initiator(DisplayObject *initiator)
Definition: events.h:411
disti::ObjectEvent::EventNameIs
bool EventNameIs(const char *eventName) const
Definition: events.h:485
disti::VertexNoColor
Definition: vertex.h:85
component_base.h
The disti::ComponentBase class.
display.h
The disti::DisplayObject class and global enumerations.
gls_include.h
A file for all GL Studio files to include.
group.h
The disti::Group class. Implements groups of objects.
disti
Definition: bmpimage.h:47
disti::MouseButtonType_e
MouseButtonType_e
Definition: events.h:85
disti::MOUSE_BUTTON_ANY
@ MOUSE_BUTTON_ANY
Definition: events.h:89
disti::MOUSE_LBUTTON
@ MOUSE_LBUTTON
Definition: events.h:86
disti::MOUSE_RBUTTON
@ MOUSE_RBUTTON
Definition: events.h:88
disti::MOUSE_MBUTTON
@ MOUSE_MBUTTON
Definition: events.h:87
disti::EmitObjectEvent
void EmitObjectEvent(DisplayObject *self, ObjectEvent *event)
Definition: events.h:511
disti::OnKeyEvent
bool OnKeyEvent(KeyboardEvent *kev, bool alphaNumeric, int key, int modifierMask=0)
Definition: events.h:623
disti::EventType_e
EventType_e
Definition: events.h:59
disti::EVENT_MOUSE
@ EVENT_MOUSE
Definition: events.h:60
disti::EVENT_KEYBOARD_UP
@ EVENT_KEYBOARD_UP
Definition: events.h:64
disti::EVENT_OBJECT
@ EVENT_OBJECT
Definition: events.h:63
disti::EVENT_TIMER
@ EVENT_TIMER
Definition: events.h:62
disti::EVENT_KEYBOARD
@ EVENT_KEYBOARD
Definition: events.h:61
disti::SpecialKeyState_e
SpecialKeyState_e
Definition: events.h:94
disti::ObjectEventIs
bool ObjectEventIs(DisplayEvent *event, const char *eventName, const char *eventData=NULL)
Definition: events.h:539
disti::MouseEventType_e
MouseEventType_e
Definition: events.h:69
disti::MOUSE_DOWN
@ MOUSE_DOWN
Definition: events.h:70
disti::MOUSE_ENTER
@ MOUSE_ENTER
Definition: events.h:75
disti::MOUSE_UP
@ MOUSE_UP
Definition: events.h:71
disti::MOUSE_DRAG
@ MOUSE_DRAG
Definition: events.h:73
disti::MOUSE_CANCEL
@ MOUSE_CANCEL
Definition: events.h:79
disti::MOUSE_MOVE
@ MOUSE_MOVE
Definition: events.h:72
disti::MOUSE_WHEEL_PLUS
@ MOUSE_WHEEL_PLUS
Definition: events.h:77
disti::MOUSE_RECEIVE_MULTITOUCH
@ MOUSE_RECEIVE_MULTITOUCH
Definition: events.h:78
disti::MOUSE_LEAVE
@ MOUSE_LEAVE
Definition: events.h:74
disti::MOUSE_WHEEL_MINUS
@ MOUSE_WHEEL_MINUS
Definition: events.h:76
disti::MOUSE_DOUBLE
@ MOUSE_DOUBLE
Definition: events.h:80
timer.h
The disti::Timer class. An OS portable timing class.