CmPlatformImpl.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #pragma once
  2. #include "CmPrerequisites.h"
  3. #include "CmInputFwd.h"
  4. #include "CmInt2.h"
  5. #include "CmRect.h"
  6. #include <boost/signals.hpp>
  7. namespace CamelotFramework
  8. {
  9. // Encapsulate native cursor type so we can avoid including windows.h as it pollutes the global namespace
  10. struct CM_EXPORT NativeCursorData
  11. {
  12. struct Pimpl;
  13. NativeCursorData();
  14. ~NativeCursorData();
  15. Pimpl* data;
  16. };
  17. struct CM_EXPORT NonClientResizeArea
  18. {
  19. NonClientAreaBorderType type;
  20. Rect area;
  21. };
  22. struct CM_EXPORT WindowNonClientAreaData
  23. {
  24. Vector<NonClientResizeArea>::type resizeAreas;
  25. Vector<Rect>::type moveAreas;
  26. };
  27. /**
  28. * @brief Provides access to various Windows operating system functions, including
  29. * the main message pump.
  30. */
  31. class CM_EXPORT Platform
  32. {
  33. public:
  34. Platform() { }
  35. virtual ~Platform() { }
  36. /**
  37. * @brief Moves the cursor to the specified screen position.
  38. *
  39. * @note Thread safe.
  40. */
  41. static void setCursorPosition(const Int2& screenPos);
  42. /**
  43. * @brief Capture mouse to this window so that we get mouse input even if the mouse leaves the window area.
  44. *
  45. * @note Thread safe.
  46. */
  47. static void captureMouse(const RenderWindow& window);
  48. /**
  49. * @brief Releases the mouse capture set by "captureMouse"
  50. *
  51. * @note Thread safe.
  52. */
  53. static void releaseMouseCapture();
  54. /**
  55. * @brief Checks if provided over screen position is over the specified window.
  56. */
  57. static bool isPointOverWindow(const RenderWindow& window, const Int2& screenPos);
  58. /**
  59. * @brief Limit cursor movement to the specified window.
  60. *
  61. * @note Thread safe.
  62. */
  63. static void clipCursorToWindow(const RenderWindow& window);
  64. /**
  65. * @brief Clip cursor to specific area on the screen.
  66. *
  67. * @note Thread safe.
  68. */
  69. static void clipCursorToRect(const Rect& screenRect);
  70. /**
  71. * @brief Disables cursor clipping.
  72. *
  73. * @note Thread safe.
  74. */
  75. static void clipCursorDisable();
  76. /**
  77. * @brief Hides the cursor.
  78. *
  79. * @note Thread safe.
  80. */
  81. static void hideCursor();
  82. /**
  83. * @brief Shows the cursor.
  84. *
  85. * @note Thread safe.
  86. */
  87. static void showCursor();
  88. /**
  89. * @brief Query if the cursor is hidden.
  90. *
  91. * @note Thread safe.
  92. */
  93. static bool isCursorHidden() { return mIsCursorHidden; }
  94. /**
  95. * @brief Sets a cursor icon. Uses built-in platform cursor types.
  96. *
  97. * @note Thread safe.
  98. */
  99. static void setCursor(CursorType type);
  100. /**
  101. * @brief Sets a cursor using a custom image.
  102. *
  103. * @param pixelData Cursor image data.
  104. * @param hotSpot Offset on the cursor image to where the actual input happens (e.g. tip of the Arrow cursor).
  105. *
  106. * @note Thread safe.
  107. */
  108. static void setCustomCursor(PixelData& pixelData, const Int2& hotSpot);
  109. /**
  110. * @brief Sets custom caption non client areas for the specified window. Using custom client
  111. * areas will override window move/drag operation and trigger when user interacts
  112. * with the custom area.
  113. *
  114. * @note Thread safe.
  115. * All provided areas are relative to the specified window.
  116. * Mostly useful for frameless windows that don't have typical caption bar.
  117. */
  118. static void setCaptionNonClientAreas(const RenderWindow& window, const Vector<Rect>::type& nonClientAreas);
  119. /**
  120. * @brief Sets custom non client areas for the specified window. Using custom client
  121. * areas will override window resize operation and trigger when user interacts
  122. * with the custom area.
  123. *
  124. * @note Thread safe.
  125. * All provided areas are relative to the specified window.
  126. * Mostly useful for frameless windows that don't have typical border.
  127. */
  128. static void setResizeNonClientAreas(const RenderWindow& window, const Vector<NonClientResizeArea>::type& nonClientAreas);
  129. /**
  130. * @brief Resets the non client areas for the specified windows and allows
  131. * the platform to use the default values.
  132. *
  133. * @note Thread safe.
  134. */
  135. static void resetNonClientAreas(const RenderWindow& window);
  136. /**
  137. * @brief Adds a string to the clipboard.
  138. */
  139. static void copyToClipboard(const WString& string);
  140. /**
  141. * @brief Reads a string from the clipboard and returns it. If there is no
  142. * string in the clipboard it returns an empty string.
  143. *
  144. * @note Both wide and normal strings will be read, but normal strings will be converted to
  145. * a wide string before returning.
  146. */
  147. static WString copyFromClipboard();
  148. /**
  149. * @brief Queries the internal system performance counter you can use for very precise time
  150. * measurements. Value is in "queryPerformanceFrequency" units.
  151. */
  152. static UINT64 queryPerformanceCounter();
  153. /**
  154. * @brief Queries the internal system performance counter frequency. Used for interpreting
  155. * data returned by "queryPerformanceCounter".
  156. */
  157. static UINT64 queryPerformanceFrequency();
  158. /**
  159. * @brief Message pump. Processes OS messages and returns when it's free.
  160. *
  161. * @note This method must be called from the core thread.
  162. * Internal method.
  163. */
  164. static void messagePump();
  165. /**
  166. * @brief Called once per frame from the sim thread.
  167. *
  168. * @note Internal method.
  169. */
  170. static void update();
  171. // Callbacks triggered on the sim thread
  172. static boost::signal<void(RenderWindow*)> onMouseLeftWindow;
  173. // Callbacks triggered on the core thread. Be careful so that none
  174. // of the connected methods call methods intended for sim thread.
  175. static boost::signal<void(const Int2&, OSPositionalInputButtonStates)> onCursorMoved;
  176. static boost::signal<void(const Int2&, OSMouseButton button, OSPositionalInputButtonStates)> onCursorButtonPressed;
  177. static boost::signal<void(const Int2&, OSMouseButton button, OSPositionalInputButtonStates)> onCursorButtonReleased;
  178. static boost::signal<void(const Int2&, OSPositionalInputButtonStates)> onCursorDoubleClick;
  179. static boost::signal<void(InputCommandType)> onInputCommand;
  180. static boost::signal<void(float)> onMouseWheelScrolled;
  181. static boost::signal<void(UINT32)> onCharInput;
  182. static boost::signal<void(RenderWindow*)> onWindowFocusReceived;
  183. static boost::signal<void(RenderWindow*)> onWindowFocusLost;
  184. static boost::signal<void(RenderWindow*)> onWindowMovedOrResized;
  185. static boost::signal<void()> onMouseCaptureChanged;
  186. protected:
  187. static bool mIsCursorHidden;
  188. static NativeCursorData mCursor;
  189. static bool mUsingCustomCursor;
  190. static Map<const RenderWindow*, WindowNonClientAreaData>::type mNonClientAreas;
  191. static bool mIsTrackingMouse;
  192. static Vector<RenderWindow*>::type mMouseLeftWindows;
  193. CM_STATIC_MUTEX(mSync);
  194. static void win32ShowCursor();
  195. static void win32HideCursor();
  196. static void windowFocusReceived(RenderWindow* window);
  197. static void windowFocusLost(RenderWindow* window);
  198. static void windowMovedOrResized(RenderWindow* window);
  199. };
  200. }