CmOSInputHandler.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "CmOSInputHandler.h"
  2. #include "CmPlatform.h"
  3. #include "CmInput.h"
  4. #include "CmMath.h"
  5. namespace CamelotFramework
  6. {
  7. OSInputHandler::OSInputHandler()
  8. :mMouseScroll(0.0f)
  9. {
  10. mCharInputConn = Platform::onCharInput.connect(boost::bind(&OSInputHandler::charInput, this, _1));
  11. mCursorMovedConn = Platform::onCursorMoved.connect(boost::bind(&OSInputHandler::cursorMoved, this, _1, _2));
  12. mCursorPressedConn = Platform::onCursorButtonPressed.connect(boost::bind(&OSInputHandler::cursorPressed, this, _1, _2, _3));
  13. mCursorReleasedConn = Platform::onCursorButtonReleased.connect(boost::bind(&OSInputHandler::cursorReleased, this, _1, _2, _3));
  14. mCursorDoubleClickConn = Platform::onCursorDoubleClick.connect(boost::bind(&OSInputHandler::cursorDoubleClick, this, _1, _2));
  15. mInputCommandConn = Platform::onInputCommand.connect(boost::bind(&OSInputHandler::inputCommandEntered, this, _1));
  16. mMouseWheelScrolledConn = Platform::onMouseWheelScrolled.connect(boost::bind(&OSInputHandler::mouseWheelScrolled, this, _1));
  17. }
  18. OSInputHandler::~OSInputHandler()
  19. {
  20. mCharInputConn.disconnect();
  21. mCursorMovedConn.disconnect();
  22. mCursorPressedConn.disconnect();
  23. mCursorReleasedConn.disconnect();
  24. mCursorDoubleClickConn.disconnect();
  25. mInputCommandConn.disconnect();
  26. mMouseWheelScrolledConn.disconnect();
  27. }
  28. void OSInputHandler::update()
  29. {
  30. WString inputString;
  31. Int2 mousePosition;
  32. float mouseScroll;
  33. OSPositionalInputButtonStates mouseMoveBtnState;
  34. Queue<ButtonStateChange>::type buttonStates;
  35. Queue<DoubleClick>::type doubleClicks;
  36. Queue<InputCommandType>::type inputCommands;
  37. {
  38. CM_LOCK_MUTEX(mOSInputMutex);
  39. inputString = mInputString;
  40. mInputString.clear();
  41. mousePosition = mCursorPosition;
  42. mouseScroll = mMouseScroll;
  43. mMouseScroll = 0.0f;
  44. mouseMoveBtnState = mMouseMoveBtnState;
  45. buttonStates = mButtonStates;
  46. mButtonStates = Queue<ButtonStateChange>::type();
  47. inputCommands = mInputCommands;
  48. mInputCommands = Queue<InputCommandType>::type();
  49. doubleClicks = mDoubleClicks;
  50. mDoubleClicks = Queue<DoubleClick>::type();
  51. }
  52. if(mousePosition != mLastCursorPos || (Math::abs(mouseScroll) > 0.00001f))
  53. {
  54. if(!onCursorMoved.empty())
  55. {
  56. PositionalInputEvent event;
  57. event.alt = false;
  58. event.shift = mouseMoveBtnState.shift;
  59. event.control = mouseMoveBtnState.ctrl;
  60. event.buttonStates[0] = mouseMoveBtnState.mouseButtons[0];
  61. event.buttonStates[1] = mouseMoveBtnState.mouseButtons[1];
  62. event.buttonStates[2] = mouseMoveBtnState.mouseButtons[2];
  63. event.mouseWheelScrollAmount = mouseScroll;
  64. event.type = PositionalInputEventType::CursorMoved;
  65. event.screenPos = mousePosition;
  66. onCursorMoved(event);
  67. }
  68. mLastCursorPos = mousePosition;
  69. }
  70. while(!buttonStates.empty())
  71. {
  72. ButtonStateChange& btnState = buttonStates.front();
  73. PositionalInputEvent event;
  74. event.alt = false;
  75. event.shift = btnState.btnStates.shift;
  76. event.control = btnState.btnStates.ctrl;
  77. event.buttonStates[0] = btnState.btnStates.mouseButtons[0];
  78. event.buttonStates[1] = btnState.btnStates.mouseButtons[1];
  79. event.buttonStates[2] = btnState.btnStates.mouseButtons[2];
  80. switch(btnState.button)
  81. {
  82. case OSMouseButton::Left:
  83. event.button = PositionalInputEventButton::Left;
  84. break;
  85. case OSMouseButton::Middle:
  86. event.button = PositionalInputEventButton::Middle;
  87. break;
  88. case OSMouseButton::Right:
  89. event.button = PositionalInputEventButton::Right;
  90. break;
  91. }
  92. event.screenPos = btnState.cursorPos;
  93. if(btnState.pressed)
  94. {
  95. event.type = PositionalInputEventType::ButtonPressed;
  96. if(!onCursorPressed.empty())
  97. onCursorPressed(event);
  98. }
  99. else
  100. {
  101. event.type = PositionalInputEventType::ButtonReleased;
  102. if(!onCursorReleased.empty())
  103. onCursorReleased(event);
  104. }
  105. buttonStates.pop();
  106. }
  107. while(!doubleClicks.empty())
  108. {
  109. if(!onDoubleClick.empty())
  110. {
  111. DoubleClick& btnState = doubleClicks.front();
  112. PositionalInputEvent event;
  113. event.alt = false;
  114. event.shift = btnState.btnStates.shift;
  115. event.control = btnState.btnStates.ctrl;
  116. event.buttonStates[0] = btnState.btnStates.mouseButtons[0];
  117. event.buttonStates[1] = btnState.btnStates.mouseButtons[1];
  118. event.buttonStates[2] = btnState.btnStates.mouseButtons[2];
  119. event.button = PositionalInputEventButton::Left;
  120. event.screenPos = btnState.cursorPos;
  121. event.type = PositionalInputEventType::DoubleClick;
  122. onDoubleClick(event);
  123. }
  124. doubleClicks.pop();
  125. }
  126. while(!inputCommands.empty())
  127. {
  128. if(!onInputCommand.empty())
  129. onInputCommand(inputCommands.front());
  130. inputCommands.pop();
  131. }
  132. if(!onCharInput.empty())
  133. {
  134. for(auto& curChar : inputString)
  135. {
  136. onCharInput((UINT32)curChar);
  137. }
  138. }
  139. }
  140. void OSInputHandler::charInput(UINT32 character)
  141. {
  142. CM_LOCK_MUTEX(mOSInputMutex);
  143. mInputString += character;
  144. }
  145. void OSInputHandler::cursorMoved(const Int2& cursorPos, OSPositionalInputButtonStates& btnStates)
  146. {
  147. CM_LOCK_MUTEX(mOSInputMutex);
  148. mCursorPosition = cursorPos;
  149. mMouseMoveBtnState = btnStates;
  150. }
  151. void OSInputHandler::cursorPressed(const Int2& cursorPos,
  152. OSMouseButton button, OSPositionalInputButtonStates& btnStates)
  153. {
  154. CM_LOCK_MUTEX(mOSInputMutex);
  155. mButtonStates.push(ButtonStateChange());
  156. ButtonStateChange& btnState = mButtonStates.back();
  157. btnState.cursorPos = cursorPos;
  158. btnState.button = button;
  159. btnState.pressed = true;
  160. btnState.btnStates = btnStates;
  161. }
  162. void OSInputHandler::cursorReleased(const Int2& cursorPos,
  163. OSMouseButton button, OSPositionalInputButtonStates& btnStates)
  164. {
  165. CM_LOCK_MUTEX(mOSInputMutex);
  166. mButtonStates.push(ButtonStateChange());
  167. ButtonStateChange& btnState = mButtonStates.back();
  168. btnState.cursorPos = cursorPos;
  169. btnState.button = button;
  170. btnState.pressed = false;
  171. btnState.btnStates = btnStates;
  172. }
  173. void OSInputHandler::cursorDoubleClick(const Int2& cursorPos, OSPositionalInputButtonStates& btnStates)
  174. {
  175. CM_LOCK_MUTEX(mOSInputMutex);
  176. mDoubleClicks.push(DoubleClick());
  177. DoubleClick& btnState = mDoubleClicks.back();
  178. btnState.cursorPos = cursorPos;
  179. btnState.btnStates = btnStates;
  180. }
  181. void OSInputHandler::inputCommandEntered(InputCommandType commandType)
  182. {
  183. CM_LOCK_MUTEX(mOSInputMutex);
  184. mInputCommands.push(commandType);
  185. }
  186. void OSInputHandler::mouseWheelScrolled(float scrollPos)
  187. {
  188. CM_LOCK_MUTEX(mOSInputMutex);
  189. mMouseScroll = scrollPos;
  190. }
  191. }