1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4 
5 #ifndef __I_EVENT_RECEIVER_H_INCLUDED__
6 #define __I_EVENT_RECEIVER_H_INCLUDED__
7 
8 #include "ILogger.h"
9 #include "Keycodes.h"
10 #include "irrString.h"
11 
12 namespace irr
13 {
14 	//! Enumeration for all event types there are.
15 	enum EEVENT_TYPE
16 	{
17 		//! An event of the graphical user interface.
18 		/** GUI events are created by the GUI environment or the GUI elements in response
19 		to mouse or keyboard events. When a GUI element receives an event it will either
20 		process it and return true, or pass the event to its parent. If an event is not absorbed
21 		before it reaches the root element then it will then be passed to the user receiver. */
22 		EET_GUI_EVENT = 0,
23 
24 		//! A mouse input event.
25 		/** Mouse events are created by the device and passed to IrrlichtDevice::postEventFromUser
26 		in response to mouse input received from the operating system.
27 		Mouse events are first passed to the user receiver, then to the GUI environment and its elements,
28 		then finally the input receiving scene manager where it is passed to the active camera.
29 		*/
30 		EET_MOUSE_INPUT_EVENT,
31 
32 		//! A key input event.
33 		/** Like mouse events, keyboard events are created by the device and passed to
34 		IrrlichtDevice::postEventFromUser. They take the same path as mouse events. */
35 		EET_KEY_INPUT_EVENT,
36 
37         //! A touch input event.
38 		EET_TOUCH_INPUT_EVENT,
39 
40         //! A accelerometer event.
41         EET_ACCELEROMETER_EVENT,
42 
43         //! A gyroscope event.
44         EET_GYROSCOPE_EVENT,
45 
46         //! A device motion event.
47         EET_DEVICE_MOTION_EVENT,
48 
49 		//! A joystick (joypad, gamepad) input event.
50 		/** Joystick events are created by polling all connected joysticks once per
51 		device run() and then passing the events to IrrlichtDevice::postEventFromUser.
52 		They take the same path as mouse events.
53 		Windows, SDL: Implemented.
54 		Linux: Implemented, with POV hat issues.
55 		MacOS / Other: Not yet implemented.
56 		*/
57 		EET_JOYSTICK_INPUT_EVENT,
58 
59 		//! A log event
60 		/** Log events are only passed to the user receiver if there is one. If they are absorbed by the
61 		user receiver then no text will be sent to the console. */
62 		EET_LOG_TEXT_EVENT,
63 
64 		//! A user event with user data.
65 		/** This is not used by Irrlicht and can be used to send user
66 		specific data though the system. The Irrlicht 'window handle'
67 		can be obtained from IrrlichtDevice::getExposedVideoData()
68 		The usage and behavior depends on the operating system:
69 		Windows: send a WM_USER message to the Irrlicht Window; the
70 			wParam and lParam will be used to populate the
71 			UserData1 and UserData2 members of the SUserEvent.
72 		Linux: send a ClientMessage via XSendEvent to the Irrlicht
73 			Window; the data.l[0] and data.l[1] members will be
74 			casted to s32 and used as UserData1 and UserData2.
75 		MacOS: Not yet implemented
76 		*/
77 		EET_USER_EVENT,
78 
79 		//! Pass on raw events from the OS
80 		EET_SYSTEM_EVENT,
81 
82 		//! Application state events like a resume, pause etc.
83 		EET_APPLICATION_EVENT,
84 
85 		//! SDL text event
86 		EET_SDL_TEXT_EVENT,
87 
88 		//! This enum is never used, it only forces the compiler to
89 		//! compile these enumeration values to 32 bit.
90 		EGUIET_FORCE_32_BIT = 0x7fffffff
91 
92 	};
93 
94 	//! Enumeration for all mouse input events
95 	enum EMOUSE_INPUT_EVENT
96 	{
97 		//! Left mouse button was pressed down.
98 		EMIE_LMOUSE_PRESSED_DOWN = 0,
99 
100 		//! Right mouse button was pressed down.
101 		EMIE_RMOUSE_PRESSED_DOWN,
102 
103 		//! Middle mouse button was pressed down.
104 		EMIE_MMOUSE_PRESSED_DOWN,
105 
106 		//! Left mouse button was left up.
107 		EMIE_LMOUSE_LEFT_UP,
108 
109 		//! Right mouse button was left up.
110 		EMIE_RMOUSE_LEFT_UP,
111 
112 		//! Middle mouse button was left up.
113 		EMIE_MMOUSE_LEFT_UP,
114 
115 		//! The mouse cursor changed its position.
116 		EMIE_MOUSE_MOVED,
117 
118 		//! The mouse wheel was moved. Use Wheel value in event data to find out
119 		//! in what direction and how fast.
120 		EMIE_MOUSE_WHEEL,
121 
122 		//! Left mouse button double click.
123 		//! This event is generated after the second EMIE_LMOUSE_PRESSED_DOWN event.
124 		EMIE_LMOUSE_DOUBLE_CLICK,
125 
126 		//! Right mouse button double click.
127 		//! This event is generated after the second EMIE_RMOUSE_PRESSED_DOWN event.
128 		EMIE_RMOUSE_DOUBLE_CLICK,
129 
130 		//! Middle mouse button double click.
131 		//! This event is generated after the second EMIE_MMOUSE_PRESSED_DOWN event.
132 		EMIE_MMOUSE_DOUBLE_CLICK,
133 
134 		//! Left mouse button triple click.
135 		//! This event is generated after the third EMIE_LMOUSE_PRESSED_DOWN event.
136 		EMIE_LMOUSE_TRIPLE_CLICK,
137 
138 		//! Right mouse button triple click.
139 		//! This event is generated after the third EMIE_RMOUSE_PRESSED_DOWN event.
140 		EMIE_RMOUSE_TRIPLE_CLICK,
141 
142 		//! Middle mouse button triple click.
143 		//! This event is generated after the third EMIE_MMOUSE_PRESSED_DOWN event.
144 		EMIE_MMOUSE_TRIPLE_CLICK,
145 
146 		//! No real event. Just for convenience to get number of events
147 		EMIE_COUNT
148 	};
149 
150 	//! Masks for mouse button states
151 	enum E_MOUSE_BUTTON_STATE_MASK
152 	{
153 		EMBSM_LEFT    = 0x01,
154 		EMBSM_RIGHT   = 0x02,
155 		EMBSM_MIDDLE  = 0x04,
156 
157 		//! currently only on windows
158 		EMBSM_EXTRA1  = 0x08,
159 
160 		//! currently only on windows
161 		EMBSM_EXTRA2  = 0x10,
162 
163 		EMBSM_FORCE_32_BIT = 0x7fffffff
164 	};
165 
166     //! Enumeration for all touch input events
167 	enum ETOUCH_INPUT_EVENT
168 	{
169 		//! Touch was pressed down.
170 		ETIE_PRESSED_DOWN = 0,
171 
172 		//! Touch was left up.
173 		ETIE_LEFT_UP,
174 
175 		//! The touch changed its position.
176 		ETIE_MOVED,
177 
178 		//! No real event. Just for convenience to get number of events
179 		ETIE_COUNT
180 	};
181 
182 	enum ESYSTEM_EVENT_TYPE
183 	{
184 		//! From Android command handler for native activity messages
185 		ESET_ANDROID_CMD = 0,
186 
187 		// TODO: for example ESET_WINDOWS_MESSAGE for win32 message loop events
188 
189 		//! No real event, but to get number of event types
190 		ESET_COUNT
191 	};
192 
193 	//! Enumeration for a commonly used application state events (it's useful mainly for mobile devices)
194 	enum EAPPLICATION_EVENT_TYPE
195 	{
196 		//! The application will be resumed.
197 		EAET_WILL_RESUME = 0,
198 
199 		//! The application has been resumed.
200 		EAET_DID_RESUME,
201 
202 		//! The application will be paused.
203 		EAET_WILL_PAUSE,
204 
205 		//! The application has been paused.
206 		EAET_DID_PAUSE,
207 
208 		//! The application will be terminated.
209 		EAET_WILL_TERMINATE,
210 
211 		//! The application received a memory warning.
212 		EAET_MEMORY_WARNING,
213 
214 		//! No real event, but to get number of event types.
215 		EAET_COUNT
216 	};
217 
218 	namespace gui
219 	{
220 
221 		class IGUIElement;
222 
223 		//! Enumeration for all events which are sendable by the gui system
224 		enum EGUI_EVENT_TYPE
225 		{
226 			//! A gui element has lost its focus.
227 			/** GUIEvent.Caller is losing the focus to GUIEvent.Element.
228 			If the event is absorbed then the focus will not be changed. */
229 			EGET_ELEMENT_FOCUS_LOST = 0,
230 
231 			//! A gui element has got the focus.
232 			/** If the event is absorbed then the focus will not be changed. */
233 			EGET_ELEMENT_FOCUSED,
234 
235 			//! The mouse cursor hovered over a gui element.
236 			/** If an element has sub-elements you also get this message for the subelements */
237 			EGET_ELEMENT_HOVERED,
238 
239 			//! The mouse cursor left the hovered element.
240 			/** If an element has sub-elements you also get this message for the subelements */
241 			EGET_ELEMENT_LEFT,
242 
243 			//! An element would like to close.
244 			/** Windows and context menus use this event when they would like to close,
245 			this can be cancelled by absorbing the event. */
246 			EGET_ELEMENT_CLOSED,
247 
248 			//! A button was clicked.
249 			EGET_BUTTON_CLICKED,
250 
251 			//! A scrollbar has changed its position.
252 			EGET_SCROLL_BAR_CHANGED,
253 
254 			//! A checkbox has changed its check state.
255 			EGET_CHECKBOX_CHANGED,
256 
257 			//! A new item in a listbox was selected.
258 			/** NOTE: You also get this event currently when the same item was clicked again after more than 500 ms. */
259 			EGET_LISTBOX_CHANGED,
260 
261 			//! An item in the listbox was selected, which was already selected.
262 			/** NOTE: You get the event currently only if the item was clicked again within 500 ms or selected by "enter" or "space". */
263 			EGET_LISTBOX_SELECTED_AGAIN,
264 
265 			//! A file has been selected in the file dialog
266 			EGET_FILE_SELECTED,
267 
268 			//! A directory has been selected in the file dialog
269 			EGET_DIRECTORY_SELECTED,
270 
271 			//! A file open dialog has been closed without choosing a file
272 			EGET_FILE_CHOOSE_DIALOG_CANCELLED,
273 
274 			//! 'Yes' was clicked on a messagebox
275 			EGET_MESSAGEBOX_YES,
276 
277 			//! 'No' was clicked on a messagebox
278 			EGET_MESSAGEBOX_NO,
279 
280 			//! 'OK' was clicked on a messagebox
281 			EGET_MESSAGEBOX_OK,
282 
283 			//! 'Cancel' was clicked on a messagebox
284 			EGET_MESSAGEBOX_CANCEL,
285 
286 			//! In an editbox 'ENTER' was pressed
287 			EGET_EDITBOX_ENTER,
288 
289 			//! The text in an editbox was changed. This does not include automatic changes in text-breaking.
290 			EGET_EDITBOX_CHANGED,
291 
292             //! The marked area in an editbox was changed.
293 			EGET_EDITBOX_MARKING_CHANGED,
294 
295 			//! The tab was changed in an tab control
296 			EGET_TAB_CHANGED,
297 
298 			//! A menu item was selected in a (context) menu
299 			EGET_MENU_ITEM_SELECTED,
300 
301 			//! The selection in a combo box has been changed
302 			EGET_COMBO_BOX_CHANGED,
303 
304 			//! The value of a spin box has changed
305 			EGET_SPINBOX_CHANGED,
306 
307 			//! A table has changed
308 			EGET_TABLE_CHANGED,
309 			EGET_TABLE_HEADER_CHANGED,
310 			EGET_TABLE_SELECTED_AGAIN,
311 
312 			//! A tree view node lost selection. See IGUITreeView::getLastEventNode().
313 			EGET_TREEVIEW_NODE_DESELECT,
314 
315 			//! A tree view node was selected. See IGUITreeView::getLastEventNode().
316 			EGET_TREEVIEW_NODE_SELECT,
317 
318 			//! A tree view node was expanded. See IGUITreeView::getLastEventNode().
319 			EGET_TREEVIEW_NODE_EXPAND,
320 
321 			//! A tree view node was collapsed. See IGUITreeView::getLastEventNode().
322 			EGET_TREEVIEW_NODE_COLLAPSE,
323 
324 			//! deprecated - use EGET_TREEVIEW_NODE_COLLAPSE instead. This
325 			//! may be removed by Irrlicht 1.9
326 			EGET_TREEVIEW_NODE_COLLAPS = EGET_TREEVIEW_NODE_COLLAPSE,
327 
328 			//! No real event. Just for convenience to get number of events
329 			EGET_COUNT
330 		};
331 	} // end namespace gui
332 
333 
334 //! SEvents hold information about an event. See irr::IEventReceiver for details on event handling.
335 struct SEvent
336 {
337 	//! Any kind of GUI event.
338 	struct SGUIEvent
339 	{
340 		//! IGUIElement who called the event
341 		gui::IGUIElement* Caller;
342 
343 		//! If the event has something to do with another element, it will be held here.
344 		gui::IGUIElement* Element;
345 
346 		//! Type of GUI Event
347 		gui::EGUI_EVENT_TYPE EventType;
348 
349 	};
350 
351 	//! Any kind of mouse event.
352 	struct SMouseInput
353 	{
354 		//! X position of mouse cursor
355 		s32 X;
356 
357 		//! Y position of mouse cursor
358 		s32 Y;
359 
360 		//! mouse wheel delta, often 1.0 or -1.0, but can have other values < 0.f or > 0.f;
361 		/** Only valid if event was EMIE_MOUSE_WHEEL */
362 		f32 Wheel;
363 
364 		//! True if shift was also pressed
365 		bool Shift:1;
366 
367 		//! True if ctrl was also pressed
368 		bool Control:1;
369 
370 		//! A bitmap of button states. You can use isButtonPressed() to determine
371 		//! if a button is pressed or not.
372 		//! Currently only valid if the event was EMIE_MOUSE_MOVED
373 		u32 ButtonStates;
374 
375 		//! Is the left button pressed down?
isLeftPressedSEvent::SMouseInput376 		bool isLeftPressed() const { return 0 != ( ButtonStates & EMBSM_LEFT ); }
377 
378 		//! Is the right button pressed down?
isRightPressedSEvent::SMouseInput379 		bool isRightPressed() const { return 0 != ( ButtonStates & EMBSM_RIGHT ); }
380 
381 		//! Is the middle button pressed down?
isMiddlePressedSEvent::SMouseInput382 		bool isMiddlePressed() const { return 0 != ( ButtonStates & EMBSM_MIDDLE ); }
383 
384 		//! Type of mouse event
385 		EMOUSE_INPUT_EVENT Event;
386 	};
387 
388 	//! Any kind of keyboard event.
389 	struct SKeyInput
390 	{
391 		//! Character corresponding to the key (0, if not a character, value undefined in key releases)
392 		char32_t Char;
393 
394 		//! Key which has been pressed or released
395 		EKEY_CODE Key;
396 
397 		//! System dependent code. Only set for systems which are described below, otherwise undefined.
398 		//! Android: int32_t with physical key as returned by AKeyEvent_getKeyCode
399 		u32 SystemKeyCode;
400 
401 		//! If not true, then the key was left up
402 		bool PressedDown:1;
403 
404 		//! True if shift was also pressed
405 		bool Shift:1;
406 
407 		//! True if ctrl was also pressed
408 		bool Control:1;
409 	};
410 
411     //! Any kind of touch event.
412 	struct STouchInput
413 	{
414         // Touch ID.
415         size_t ID;
416 
417         // X position of simple touch.
418 		s32 X;
419 
420         // Y position of simple touch.
421 		s32 Y;
422 
423 		//! Type of touch event.
424 		ETOUCH_INPUT_EVENT Event;
425 	};
426 
427 
428     //! Any kind of accelerometer event.
429 	struct SAccelerometerEvent
430 	{
431 
432         // X acceleration.
433 		f64 X;
434 
435         // Y acceleration.
436 		f64 Y;
437 
438         // Z acceleration.
439 		f64 Z;
440 	};
441 
442     //! Any kind of gyroscope event.
443 	struct SGyroscopeEvent
444 	{
445 
446         // X rotation.
447 		f64 X;
448 
449         // Y rotation.
450 		f64 Y;
451 
452         // Z rotation.
453 		f64 Z;
454 	};
455 
456     //! Any kind of device motion event.
457 	struct SDeviceMotionEvent
458 	{
459 
460         // X angle - roll.
461 		f64 X;
462 
463         // Y angle - pitch.
464 		f64 Y;
465 
466         // Z angle - yaw.
467 		f64 Z;
468 	};
469 
470 	//! A joystick event.
471 	/** Unlike other events, joystick events represent the result of polling
472 	 * each connected joystick once per run() of the device. Joystick events will
473 	 * not be generated by default.  If joystick support is available for the
474 	 * active device, _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ is defined, and
475 	 * @ref irr::IrrlichtDevice::activateJoysticks() has been called, an event of
476 	 * this type will be generated once per joystick per @ref IrrlichtDevice::run()
477 	 * regardless of whether the state of the joystick has actually changed. */
478 	struct SJoystickEvent
479 	{
480 		enum
481 		{
482 			NUMBER_OF_BUTTONS = 32,
483 
484 			AXIS_X = 0, // e.g. analog stick 1 left to right
485 			AXIS_Y,		// e.g. analog stick 1 top to bottom
486 			AXIS_Z,		// e.g. throttle, or analog 2 stick 2 left to right
487 			AXIS_R,		// e.g. rudder, or analog 2 stick 2 top to bottom
488 			AXIS_U,
489 			AXIS_V,
490 			NUMBER_OF_AXES = 32
491 		};
492 
493 		/** For AXIS_X, AXIS_Y, AXIS_Z, AXIS_R, AXIS_U and AXIS_V
494 		 * Values are in the range -32768 to 32767, with 0 representing
495 		 * the center position.  You will receive the raw value from the
496 		 * joystick, and so will usually want to implement a dead zone around
497 		 * the center of the range. Axes not supported by this joystick will
498 		 * always have a value of 0. On Linux, POV hats are represented as axes,
499 		 * usually the last two active axis.
500 		 */
501 		s16 Axis[NUMBER_OF_AXES];
502 
503 		//! The ID of the joystick which generated this event.
504 		/** This is an internal Irrlicht index; it does not map directly
505 		 * to any particular hardware joystick. */
506 		u32 AxisChanged;
507 
508 		/** A bitmap of button states.  You can use IsButtonPressed() to
509 		 ( check the state of each button from 0 to (NUMBER_OF_BUTTONS - 1) */
510 		u32 ButtonStates;
511 
512 		//! The ID of the joystick which generated this event.
513 		/** This is an internal Irrlicht index; it does not map directly
514 		 * to any particular hardware joystick. */
515 		u32 Joystick;
516 
517 		//! A helper function to check if a button is pressed.
IsAxisChangedSEvent::SJoystickEvent518 		bool IsAxisChanged(u32 axis) const
519 		{
520 			if(axis >= (u32)NUMBER_OF_AXES)
521 				return false;
522 
523 			return (AxisChanged & (1 << axis)) ? true : false;
524 		}
525 
526 		//! A helper function to check if a button is pressed.
IsButtonPressedSEvent::SJoystickEvent527 		bool IsButtonPressed(u32 button) const
528 		{
529 			if(button >= (u32)NUMBER_OF_BUTTONS)
530 				return false;
531 
532 			return (ButtonStates & (1 << button)) ? true : false;
533 		}
534 	};
535 
536 	//! Any kind of log event.
537 	struct SLogEvent
538 	{
539 		//! Pointer to text which has been logged
540 		const c8* Text;
541 
542 		//! Log level in which the text has been logged
543 		ELOG_LEVEL Level;
544 	};
545 
546 	//! Any kind of user event.
547 	struct SUserEvent
548 	{
549 		//! Some user specified data as int
550 		s32 UserData1;
551 
552 		//! Another user specified data as int
553 		s32 UserData2;
554 	};
555 
556 	// Raw events from the OS
557 	struct SSystemEvent
558 	{
559 		//! Android command handler native activity messages.
560 		struct SAndroidCmd
561 		{
562 			//!  APP_CMD_ enums defined in android_native_app_glue.h from the Android NDK
563 			s32 Cmd;
564 		};
565 
566 		// TOOD: more structs for iphone, Windows, X11, etc.
567 
568 		ESYSTEM_EVENT_TYPE EventType;
569 		union
570 		{
571 			struct SAndroidCmd AndroidCmd;
572 		};
573 	};
574 
575 	// Application state event
576 	struct SApplicationEvent
577 	{
578 		EAPPLICATION_EVENT_TYPE EventType;
579 	};
580 
581 	// Application state event
582 	struct SSDLTextEvent
583 	{
584 		u32 Type; // SDL_TEXTEDITING or SDL_TEXTINPUT
585 		c8 Text[32];
586 		s32 Start; // SDL_TEXTEDITING usage
587 		s32 Length; // SDL_TEXTEDITING usage
588 	};
589 
590 	EEVENT_TYPE EventType;
591 	union
592 	{
593 		struct SGUIEvent GUIEvent;
594 		struct SMouseInput MouseInput;
595 		struct SKeyInput KeyInput;
596         struct STouchInput TouchInput;
597         struct SAccelerometerEvent AccelerometerEvent;
598         struct SGyroscopeEvent GyroscopeEvent;
599         struct SDeviceMotionEvent DeviceMotionEvent;
600 		struct SJoystickEvent JoystickEvent;
601 		struct SLogEvent LogEvent;
602 		struct SUserEvent UserEvent;
603 		struct SSystemEvent SystemEvent;
604 		struct SApplicationEvent ApplicationEvent;
605 		struct SSDLTextEvent SDLTextEvent;
606 	};
607 
608 };
609 
610 //! Interface of an object which can receive events.
611 /** Many of the engine's classes inherit IEventReceiver so they are able to
612 process events. Events usually start at a postEventFromUser function and are
613 passed down through a chain of event receivers until OnEvent returns true. See
614 irr::EEVENT_TYPE for a description of where each type of event starts, and the
615 path it takes through the system. */
616 class IEventReceiver
617 {
618 public:
619 
620 	//! Destructor
~IEventReceiver()621 	virtual ~IEventReceiver() {}
622 
623 	//! Called if an event happened.
624 	/** Please take care that you should only return 'true' when you want to _prevent_ Irrlicht
625 	* from processing the event any further. So 'true' does mean that an event is completely done.
626 	* Therefore your return value for all unprocessed events should be 'false'.
627 	\return True if the event was processed.
628 	*/
629 	virtual bool OnEvent(const SEvent& event) = 0;
630 };
631 
632 
633 //! Information on a joystick, returned from @ref irr::IrrlichtDevice::activateJoysticks()
634 struct SJoystickInfo
635 {
636 	//! The ID of the joystick
637 	/** This is an internal Irrlicht index; it does not map directly
638 	 * to any particular hardware joystick. It corresponds to the
639 	 * irr::SJoystickEvent Joystick ID. */
640 	u8				Joystick;
641 
642 	//! The name that the joystick uses to identify itself.
643 	core::stringc	Name;
644 
645 	//! The number of buttons that the joystick has.
646 	u32				Buttons;
647 
648 	//! The number of axes that the joystick has, i.e. X, Y, Z, R, U, V.
649 	/** Note: with a Linux device, the POV hat (if any) will use two axes. These
650 	 *  will be included in this count. */
651 	u32				Axes;
652 
653 	//! An indication of whether the joystick has a POV hat.
654 	/** A Windows device will identify the presence or absence or the POV hat.  A
655 	 *  Linux device cannot, and will always return POV_HAT_UNKNOWN. */
656 	enum
657 	{
658 		//! A hat is definitely present.
659 		POV_HAT_PRESENT,
660 
661 		//! A hat is definitely not present.
662 		POV_HAT_ABSENT,
663 
664 		//! The presence or absence of a hat cannot be determined.
665 		POV_HAT_UNKNOWN
666 	} PovHat;
667 
668     //! Set if the name of the joystick is useful:
669     /** On windows the generic name is useless, since it's always the same
670      *  indepentent of what joystick is connected ("Microsoft PC-joystick driver").
671      *  We will try to get a better name from the registry, but if this should
672      *  fail this flag is set and used by STK. */
673     bool HasGenericName;
674 
675 }; // struct SJoystickInfo
676 
677 
678 } // end namespace irr
679 
680 #endif
681 
682