BsInput.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsModule.h"
  4. #include "BsRect2I.h"
  5. #include "BsOSInputHandler.h"
  6. #include "BsRawInputHandler.h"
  7. #include "BsInputFwd.h"
  8. namespace BansheeEngine
  9. {
  10. /**
  11. * @brief Primary module used for dealing with input. Allows you to receieve
  12. * and query raw or OS input for mouse/keyboard/gamepad.
  13. *
  14. * All inputs are received through an input handler, which can be overriden to
  15. * provide custom input functionality.
  16. */
  17. class BS_CORE_EXPORT Input : public Module<Input>
  18. {
  19. /**
  20. * @brief Possible button states
  21. */
  22. enum class ButtonState
  23. {
  24. Off, /**< Button is not being pressed. */
  25. On, /**< Button is being pressed. */
  26. ToggledOn, /**< Button has been pressed this frame. */
  27. ToggledOff /**< Button has been released this frame. */
  28. };
  29. /**
  30. * @brief Contains axis and device data per device
  31. */
  32. struct DeviceData
  33. {
  34. DeviceData();
  35. Vector<RawAxisState> axes;
  36. ButtonState keyStates[BC_Count];
  37. };
  38. public:
  39. Input();
  40. ~Input();
  41. /**
  42. * @brief Triggered whenever a button is first pressed.
  43. */
  44. Event<void(const ButtonEvent&)> onButtonDown;
  45. /**
  46. * @brief Triggered whenever a button is first released.
  47. */
  48. Event<void(const ButtonEvent&)> onButtonUp;
  49. /**
  50. * @brief Triggered whenever user inputs a text character.
  51. */
  52. Event<void(const TextInputEvent&)> onCharInput;
  53. /**
  54. * @brief Triggers when some pointing device (mouse cursor, touch) moves.
  55. */
  56. Event<void(const PointerEvent&)> onPointerMoved;
  57. /**
  58. * @brief Triggers when some pointing device (mouse cursor, touch) button is pressed.
  59. */
  60. Event<void(const PointerEvent&)> onPointerPressed;
  61. /**
  62. * @brief Triggers when some pointing device (mouse cursor, touch) button is released.
  63. */
  64. Event<void(const PointerEvent&)> onPointerReleased;
  65. /**
  66. * @brief Triggers when some pointing device (mouse cursor, touch) button is double clicked.
  67. */
  68. Event<void(const PointerEvent&)> onPointerDoubleClick;
  69. // TODO Low priority: Remove this, I can emulate it using virtual input
  70. /**
  71. * @brief Triggers on special input commands.
  72. */
  73. Event<void(InputCommandType)> onInputCommand;
  74. /**
  75. * @brief Registers a new input handler. Replaces any previous input handler.
  76. *
  77. * @note Internal method.
  78. */
  79. void _registerRawInputHandler(std::shared_ptr<RawInputHandler> inputHandler);
  80. /**
  81. * @brief Called every frame. Dispatches any callbacks resulting from input by the user.
  82. *
  83. * @note Internal method.
  84. */
  85. void _update();
  86. /**
  87. * @brief Returns value of the specified input axis. Normally in range [-1.0, 1.0] but can be outside
  88. * the range for devices with unbound axes (e.g. mouse).
  89. *
  90. * @param type Type of axis to query. Usually a type from InputAxis but can be a custom value.
  91. * @param deviceIdx Index of the device in case more than one is hooked up (0 - primary).
  92. */
  93. float getAxisValue(UINT32 type, UINT32 deviceIdx = 0) const;
  94. /**
  95. * @brief Query if the provided button is currently being held (this frame or previous frames).
  96. *
  97. * @param keyCode Code of the button to query.
  98. * @param deviceIdx Device to query the button on (0 - primary).
  99. */
  100. bool isButtonHeld(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
  101. /**
  102. * @brief Query if the provided button is currently being released (one true for one frame).
  103. *
  104. * @param keyCode Code of the button to query.
  105. * @param deviceIdx Device to query the button on (0 - primary).
  106. */
  107. bool isButtonUp(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
  108. /**
  109. * @brief Query if the provided button is currently being pressed (one true for one frame).
  110. *
  111. * @param keyCode Code of the button to query.
  112. * @param deviceIdx Device to query the button on (0 - primary).
  113. */
  114. bool isButtonDown(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
  115. /**
  116. * @brief Returns positions of the pointer (e.g. mouse cursor) relative to the screen.
  117. */
  118. Vector2I getPointerPosition() const;
  119. /**
  120. * @brief Returns difference between last and current pointer position.
  121. */
  122. Vector2I getPointerDelta() const { return mPointerDelta; }
  123. /**
  124. * @brief Query if the provided pointer button is currently
  125. * being held (this frame or previous frames).
  126. *
  127. * @param pointerButton Code of the button to query.
  128. */
  129. bool isPointerButtonHeld(PointerEventButton pointerButton) const;
  130. /**
  131. * @brief Query if the provided pointer button is currently
  132. * being released (one true for one frame).
  133. *
  134. * @param pointerButton Code of the button to query.
  135. */
  136. bool isPointerButtonUp(PointerEventButton pointerButton) const;
  137. /**
  138. * @brief Query if the provided pointer button is currently
  139. * being pressed (one true for one frame).
  140. *
  141. * @param pointerButton Code of the button to query.
  142. */
  143. bool isPointerButtonDown(PointerEventButton pointerButton) const;
  144. /**
  145. * @brief Query if the provided the left pointer button has been
  146. * double-clicked this frame.
  147. */
  148. bool isPointerDoubleClicked() const;
  149. /**
  150. * @brief Enables or disables mouse smoothing. Smoothing makes the changes to
  151. * mouse axes more gradual.
  152. */
  153. void setMouseSmoothing(bool enabled);
  154. private:
  155. /**
  156. * @brief Triggered by input handler when a button is pressed.
  157. */
  158. void buttonDown(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp);
  159. /**
  160. * @brief Triggered by input handler when a button is released.
  161. */
  162. void buttonUp(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp);
  163. /**
  164. * @brief Triggered by input handler when a single character is input.
  165. */
  166. void charInput(UINT32 chr);
  167. /**
  168. * @brief Triggered by input handler when a mouse/joystick axis is moved.
  169. */
  170. void axisMoved(UINT32 deviceIdx, const RawAxisState& state, UINT32 axis);
  171. /**
  172. * @brief Cursor movement as OS reports it. Used for screen cursor position.
  173. */
  174. void cursorMoved(const PointerEvent& event);
  175. /**
  176. * @brief Cursor button presses as OS reports it.
  177. */
  178. void cursorPressed(const PointerEvent& event);
  179. /**
  180. * @brief Cursor button releases as OS reports it.
  181. */
  182. void cursorReleased(const PointerEvent& event);
  183. /**
  184. * @brief Cursor button releases as OS reports it.
  185. */
  186. void cursorDoubleClick(const PointerEvent& event);
  187. /**
  188. * @brief Input commands as OS reports them.
  189. */
  190. void inputCommandEntered(InputCommandType commandType);
  191. /**
  192. * @brief Called when window in focus changes, as reported by the OS.
  193. */
  194. void inputWindowChanged(RenderWindow& win);
  195. private:
  196. std::shared_ptr<RawInputHandler> mRawInputHandler;
  197. std::shared_ptr<OSInputHandler> mOSInputHandler;
  198. Vector<DeviceData> mDevices;
  199. Vector2I mPointerPosition;
  200. Vector2I mPointerDelta;
  201. ButtonState mPointerButtonStates[3];
  202. bool mPointerDoubleClicked;
  203. bool mLastPositionSet;
  204. /************************************************************************/
  205. /* STATICS */
  206. /************************************************************************/
  207. static const int HISTORY_BUFFER_SIZE; // Size of buffer used for input smoothing
  208. static const float WEIGHT_MODIFIER;
  209. };
  210. /**
  211. * @copydoc Input
  212. */
  213. BS_CORE_EXPORT Input& gInput();
  214. }