Line data Source code
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 joystick (joypad, gamepad) input event.
38 : /** Joystick events are created by polling all connected joysticks once per
39 : device run() and then passing the events to IrrlichtDevice::postEventFromUser.
40 : They take the same path as mouse events.
41 : Windows, SDL: Implemented.
42 : Linux: Implemented, with POV hat issues.
43 : MacOS / Other: Not yet implemented.
44 : */
45 : EET_JOYSTICK_INPUT_EVENT,
46 :
47 : //! A log event
48 : /** Log events are only passed to the user receiver if there is one. If they are absorbed by the
49 : user receiver then no text will be sent to the console. */
50 : EET_LOG_TEXT_EVENT,
51 :
52 : //! A user event with user data.
53 : /** This is not used by Irrlicht and can be used to send user
54 : specific data though the system. The Irrlicht 'window handle'
55 : can be obtained from IrrlichtDevice::getExposedVideoData()
56 : The usage and behavior depends on the operating system:
57 : Windows: send a WM_USER message to the Irrlicht Window; the
58 : wParam and lParam will be used to populate the
59 : UserData1 and UserData2 members of the SUserEvent.
60 : Linux: send a ClientMessage via XSendEvent to the Irrlicht
61 : Window; the data.l[0] and data.l[1] members will be
62 : casted to s32 and used as UserData1 and UserData2.
63 : MacOS: Not yet implemented
64 : */
65 : EET_USER_EVENT,
66 :
67 : //! This enum is never used, it only forces the compiler to
68 : //! compile these enumeration values to 32 bit.
69 : EGUIET_FORCE_32_BIT = 0x7fffffff
70 :
71 : };
72 :
73 : //! Enumeration for all mouse input events
74 : enum EMOUSE_INPUT_EVENT
75 : {
76 : //! Left mouse button was pressed down.
77 : EMIE_LMOUSE_PRESSED_DOWN = 0,
78 :
79 : //! Right mouse button was pressed down.
80 : EMIE_RMOUSE_PRESSED_DOWN,
81 :
82 : //! Middle mouse button was pressed down.
83 : EMIE_MMOUSE_PRESSED_DOWN,
84 :
85 : //! Left mouse button was left up.
86 : EMIE_LMOUSE_LEFT_UP,
87 :
88 : //! Right mouse button was left up.
89 : EMIE_RMOUSE_LEFT_UP,
90 :
91 : //! Middle mouse button was left up.
92 : EMIE_MMOUSE_LEFT_UP,
93 :
94 : //! The mouse cursor changed its position.
95 : EMIE_MOUSE_MOVED,
96 :
97 : //! The mouse wheel was moved. Use Wheel value in event data to find out
98 : //! in what direction and how fast.
99 : EMIE_MOUSE_WHEEL,
100 :
101 : //! Left mouse button double click.
102 : //! This event is generated after the second EMIE_LMOUSE_PRESSED_DOWN event.
103 : EMIE_LMOUSE_DOUBLE_CLICK,
104 :
105 : //! Right mouse button double click.
106 : //! This event is generated after the second EMIE_RMOUSE_PRESSED_DOWN event.
107 : EMIE_RMOUSE_DOUBLE_CLICK,
108 :
109 : //! Middle mouse button double click.
110 : //! This event is generated after the second EMIE_MMOUSE_PRESSED_DOWN event.
111 : EMIE_MMOUSE_DOUBLE_CLICK,
112 :
113 : //! Left mouse button triple click.
114 : //! This event is generated after the third EMIE_LMOUSE_PRESSED_DOWN event.
115 : EMIE_LMOUSE_TRIPLE_CLICK,
116 :
117 : //! Right mouse button triple click.
118 : //! This event is generated after the third EMIE_RMOUSE_PRESSED_DOWN event.
119 : EMIE_RMOUSE_TRIPLE_CLICK,
120 :
121 : //! Middle mouse button triple click.
122 : //! This event is generated after the third EMIE_MMOUSE_PRESSED_DOWN event.
123 : EMIE_MMOUSE_TRIPLE_CLICK,
124 :
125 : //! No real event. Just for convenience to get number of events
126 : EMIE_COUNT
127 : };
128 :
129 : //! Masks for mouse button states
130 : enum E_MOUSE_BUTTON_STATE_MASK
131 : {
132 : EMBSM_LEFT = 0x01,
133 : EMBSM_RIGHT = 0x02,
134 : EMBSM_MIDDLE = 0x04,
135 :
136 : //! currently only on windows
137 : EMBSM_EXTRA1 = 0x08,
138 :
139 : //! currently only on windows
140 : EMBSM_EXTRA2 = 0x10,
141 :
142 : EMBSM_FORCE_32_BIT = 0x7fffffff
143 : };
144 :
145 : namespace gui
146 : {
147 :
148 : class IGUIElement;
149 :
150 : //! Enumeration for all events which are sendable by the gui system
151 : enum EGUI_EVENT_TYPE
152 : {
153 : //! A gui element has lost its focus.
154 : /** GUIEvent.Caller is losing the focus to GUIEvent.Element.
155 : If the event is absorbed then the focus will not be changed. */
156 : EGET_ELEMENT_FOCUS_LOST = 0,
157 :
158 : //! A gui element has got the focus.
159 : /** If the event is absorbed then the focus will not be changed. */
160 : EGET_ELEMENT_FOCUSED,
161 :
162 : //! The mouse cursor hovered over a gui element.
163 : /** If an element has sub-elements you also get this message for the subelements */
164 : EGET_ELEMENT_HOVERED,
165 :
166 : //! The mouse cursor left the hovered element.
167 : /** If an element has sub-elements you also get this message for the subelements */
168 : EGET_ELEMENT_LEFT,
169 :
170 : //! An element would like to close.
171 : /** Windows and context menus use this event when they would like to close,
172 : this can be cancelled by absorbing the event. */
173 : EGET_ELEMENT_CLOSED,
174 :
175 : //! A button was clicked.
176 : EGET_BUTTON_CLICKED,
177 :
178 : //! A scrollbar has changed its position.
179 : EGET_SCROLL_BAR_CHANGED,
180 :
181 : //! A checkbox has changed its check state.
182 : EGET_CHECKBOX_CHANGED,
183 :
184 : //! A new item in a listbox was selected.
185 : /** NOTE: You also get this event currently when the same item was clicked again after more than 500 ms. */
186 : EGET_LISTBOX_CHANGED,
187 :
188 : //! An item in the listbox was selected, which was already selected.
189 : /** NOTE: You get the event currently only if the item was clicked again within 500 ms or selected by "enter" or "space". */
190 : EGET_LISTBOX_SELECTED_AGAIN,
191 :
192 : //! A file has been selected in the file dialog
193 : EGET_FILE_SELECTED,
194 :
195 : //! A directory has been selected in the file dialog
196 : EGET_DIRECTORY_SELECTED,
197 :
198 : //! A file open dialog has been closed without choosing a file
199 : EGET_FILE_CHOOSE_DIALOG_CANCELLED,
200 :
201 : //! 'Yes' was clicked on a messagebox
202 : EGET_MESSAGEBOX_YES,
203 :
204 : //! 'No' was clicked on a messagebox
205 : EGET_MESSAGEBOX_NO,
206 :
207 : //! 'OK' was clicked on a messagebox
208 : EGET_MESSAGEBOX_OK,
209 :
210 : //! 'Cancel' was clicked on a messagebox
211 : EGET_MESSAGEBOX_CANCEL,
212 :
213 : //! In an editbox 'ENTER' was pressed
214 : EGET_EDITBOX_ENTER,
215 :
216 : //! The text in an editbox was changed. This does not include automatic changes in text-breaking.
217 : EGET_EDITBOX_CHANGED,
218 :
219 : //! The marked area in an editbox was changed.
220 : EGET_EDITBOX_MARKING_CHANGED,
221 :
222 : //! The tab was changed in an tab control
223 : EGET_TAB_CHANGED,
224 :
225 : //! A menu item was selected in a (context) menu
226 : EGET_MENU_ITEM_SELECTED,
227 :
228 : //! The selection in a combo box has been changed
229 : EGET_COMBO_BOX_CHANGED,
230 :
231 : //! The value of a spin box has changed
232 : EGET_SPINBOX_CHANGED,
233 :
234 : //! A table has changed
235 : EGET_TABLE_CHANGED,
236 : EGET_TABLE_HEADER_CHANGED,
237 : EGET_TABLE_SELECTED_AGAIN,
238 :
239 : //! A tree view node lost selection. See IGUITreeView::getLastEventNode().
240 : EGET_TREEVIEW_NODE_DESELECT,
241 :
242 : //! A tree view node was selected. See IGUITreeView::getLastEventNode().
243 : EGET_TREEVIEW_NODE_SELECT,
244 :
245 : //! A tree view node was expanded. See IGUITreeView::getLastEventNode().
246 : EGET_TREEVIEW_NODE_EXPAND,
247 :
248 : //! A tree view node was collapsed. See IGUITreeView::getLastEventNode().
249 : EGET_TREEVIEW_NODE_COLLAPSE,
250 :
251 : //! deprecated - use EGET_TREEVIEW_NODE_COLLAPSE instead. This
252 : //! may be removed by Irrlicht 1.9
253 : EGET_TREEVIEW_NODE_COLLAPS = EGET_TREEVIEW_NODE_COLLAPSE,
254 :
255 : //! No real event. Just for convenience to get number of events
256 : EGET_COUNT
257 : };
258 : } // end namespace gui
259 :
260 :
261 : //! SEvents hold information about an event. See irr::IEventReceiver for details on event handling.
262 : struct SEvent
263 : {
264 : //! Any kind of GUI event.
265 : struct SGUIEvent
266 : {
267 : //! IGUIElement who called the event
268 : gui::IGUIElement* Caller;
269 :
270 : //! If the event has something to do with another element, it will be held here.
271 : gui::IGUIElement* Element;
272 :
273 : //! Type of GUI Event
274 : gui::EGUI_EVENT_TYPE EventType;
275 :
276 : };
277 :
278 : //! Any kind of mouse event.
279 : struct SMouseInput
280 : {
281 : //! X position of mouse cursor
282 : s32 X;
283 :
284 : //! Y position of mouse cursor
285 : s32 Y;
286 :
287 : //! mouse wheel delta, often 1.0 or -1.0, but can have other values < 0.f or > 0.f;
288 : /** Only valid if event was EMIE_MOUSE_WHEEL */
289 : f32 Wheel;
290 :
291 : //! True if shift was also pressed
292 : bool Shift:1;
293 :
294 : //! True if ctrl was also pressed
295 : bool Control:1;
296 :
297 : //! A bitmap of button states. You can use isButtonPressed() to determine
298 : //! if a button is pressed or not.
299 : //! Currently only valid if the event was EMIE_MOUSE_MOVED
300 : u32 ButtonStates;
301 :
302 : //! Is the left button pressed down?
303 2588 : bool isLeftPressed() const { return 0 != ( ButtonStates & EMBSM_LEFT ); }
304 :
305 : //! Is the right button pressed down?
306 2688 : bool isRightPressed() const { return 0 != ( ButtonStates & EMBSM_RIGHT ); }
307 :
308 : //! Is the middle button pressed down?
309 2584 : bool isMiddlePressed() const { return 0 != ( ButtonStates & EMBSM_MIDDLE ); }
310 :
311 : //! Type of mouse event
312 : EMOUSE_INPUT_EVENT Event;
313 : };
314 :
315 : //! Any kind of keyboard event.
316 : struct SKeyInput
317 : {
318 : //! Character corresponding to the key (0, if not a character)
319 : wchar_t Char;
320 :
321 : //! Key which has been pressed or released
322 : EKEY_CODE Key;
323 :
324 : //! If not true, then the key was left up
325 : bool PressedDown:1;
326 :
327 : //! True if shift was also pressed
328 : bool Shift:1;
329 :
330 : //! True if ctrl was also pressed
331 : bool Control:1;
332 : };
333 :
334 : //! A joystick event.
335 : /** Unlike other events, joystick events represent the result of polling
336 : * each connected joystick once per run() of the device. Joystick events will
337 : * not be generated by default. If joystick support is available for the
338 : * active device, _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ is defined, and
339 : * @ref irr::IrrlichtDevice::activateJoysticks() has been called, an event of
340 : * this type will be generated once per joystick per @ref IrrlichtDevice::run()
341 : * regardless of whether the state of the joystick has actually changed. */
342 : struct SJoystickEvent
343 : {
344 : enum
345 : {
346 : NUMBER_OF_BUTTONS = 32,
347 :
348 : AXIS_X = 0, // e.g. analog stick 1 left to right
349 : AXIS_Y, // e.g. analog stick 1 top to bottom
350 : AXIS_Z, // e.g. throttle, or analog 2 stick 2 left to right
351 : AXIS_R, // e.g. rudder, or analog 2 stick 2 top to bottom
352 : AXIS_U,
353 : AXIS_V,
354 : NUMBER_OF_AXES
355 : };
356 :
357 : /** A bitmap of button states. You can use IsButtonPressed() to
358 : ( check the state of each button from 0 to (NUMBER_OF_BUTTONS - 1) */
359 : u32 ButtonStates;
360 :
361 : /** For AXIS_X, AXIS_Y, AXIS_Z, AXIS_R, AXIS_U and AXIS_V
362 : * Values are in the range -32768 to 32767, with 0 representing
363 : * the center position. You will receive the raw value from the
364 : * joystick, and so will usually want to implement a dead zone around
365 : * the center of the range. Axes not supported by this joystick will
366 : * always have a value of 0. On Linux, POV hats are represented as axes,
367 : * usually the last two active axis.
368 : */
369 : s16 Axis[NUMBER_OF_AXES];
370 :
371 : /** The POV represents the angle of the POV hat in degrees * 100,
372 : * from 0 to 35,900. A value of 65535 indicates that the POV hat
373 : * is centered (or not present).
374 : * This value is only supported on Windows. On Linux, the POV hat
375 : * will be sent as 2 axes instead. */
376 : u16 POV;
377 :
378 : //! The ID of the joystick which generated this event.
379 : /** This is an internal Irrlicht index; it does not map directly
380 : * to any particular hardware joystick. */
381 : u8 Joystick;
382 :
383 : //! A helper function to check if a button is pressed.
384 : bool IsButtonPressed(u32 button) const
385 : {
386 : if(button >= (u32)NUMBER_OF_BUTTONS)
387 : return false;
388 :
389 : return (ButtonStates & (1 << button)) ? true : false;
390 : }
391 : };
392 :
393 :
394 : //! Any kind of log event.
395 : struct SLogEvent
396 : {
397 : //! Pointer to text which has been logged
398 : const c8* Text;
399 :
400 : //! Log level in which the text has been logged
401 : ELOG_LEVEL Level;
402 : };
403 :
404 : //! Any kind of user event.
405 : struct SUserEvent
406 : {
407 : //! Some user specified data as int
408 : s32 UserData1;
409 :
410 : //! Another user specified data as int
411 : s32 UserData2;
412 : };
413 :
414 : EEVENT_TYPE EventType;
415 : union
416 : {
417 : struct SGUIEvent GUIEvent;
418 : struct SMouseInput MouseInput;
419 : struct SKeyInput KeyInput;
420 : struct SJoystickEvent JoystickEvent;
421 : struct SLogEvent LogEvent;
422 : struct SUserEvent UserEvent;
423 : };
424 :
425 : };
426 :
427 : //! Interface of an object which can receive events.
428 : /** Many of the engine's classes inherit IEventReceiver so they are able to
429 : process events. Events usually start at a postEventFromUser function and are
430 : passed down through a chain of event receivers until OnEvent returns true. See
431 : irr::EEVENT_TYPE for a description of where each type of event starts, and the
432 : path it takes through the system. */
433 12 : class IEventReceiver
434 : {
435 : public:
436 :
437 : //! Destructor
438 7 : virtual ~IEventReceiver() {}
439 :
440 : //! Called if an event happened.
441 : /** Please take care that you should only return 'true' when you want to _prevent_ Irrlicht
442 : * from processing the event any further. So 'true' does mean that an event is completely done.
443 : * Therefore your return value for all unprocessed events should be 'false'.
444 : \return True if the event was processed.
445 : */
446 : virtual bool OnEvent(const SEvent& event) = 0;
447 : };
448 :
449 :
450 : //! Information on a joystick, returned from @ref irr::IrrlichtDevice::activateJoysticks()
451 : struct SJoystickInfo
452 : {
453 : //! The ID of the joystick
454 : /** This is an internal Irrlicht index; it does not map directly
455 : * to any particular hardware joystick. It corresponds to the
456 : * irr::SJoystickEvent Joystick ID. */
457 : u8 Joystick;
458 :
459 : //! The name that the joystick uses to identify itself.
460 : core::stringc Name;
461 :
462 : //! The number of buttons that the joystick has.
463 : u32 Buttons;
464 :
465 : //! The number of axes that the joystick has, i.e. X, Y, Z, R, U, V.
466 : /** Note: with a Linux device, the POV hat (if any) will use two axes. These
467 : * will be included in this count. */
468 : u32 Axes;
469 :
470 : //! An indication of whether the joystick has a POV hat.
471 : /** A Windows device will identify the presence or absence or the POV hat. A
472 : * Linux device cannot, and will always return POV_HAT_UNKNOWN. */
473 : enum
474 : {
475 : //! A hat is definitely present.
476 : POV_HAT_PRESENT,
477 :
478 : //! A hat is definitely not present.
479 : POV_HAT_ABSENT,
480 :
481 : //! The presence or absence of a hat cannot be determined.
482 : POV_HAT_UNKNOWN
483 : } PovHat;
484 : }; // struct SJoystickInfo
485 :
486 :
487 : } // end namespace irr
488 :
489 : #endif
490 :
|