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