1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Input/BsInputFwd.h"
7#include "Math/BsVector2I.h"
8#include "Math/BsRect2I.h"
9#include "Utility/BsEvent.h"
10
11namespace bs
12{
13 /** @addtogroup Platform-Internal
14 * @{
15 */
16
17 /** Contains values representing default mouse cursor types. */
18 enum class PlatformCursorType
19 {
20 Arrow,
21 Wait,
22 IBeam,
23 Help,
24 Hand,
25 SizeAll,
26 SizeNESW,
27 SizeNS,
28 SizeNWSE,
29 SizeWE
30 };
31
32 /**
33 * Contains values reprenting window non client areas.
34 *
35 * @note These are used for things like resize/move and tell the OS where each of those areas are on our window.
36 */
37 enum class NonClientAreaBorderType
38 {
39 TopLeft,
40 Top,
41 TopRight,
42 Left,
43 Right,
44 BottomLeft,
45 Bottom,
46 BottomRight
47 };
48
49 /** Types of mouse buttons provided by the OS. */
50 enum class OSMouseButton
51 {
52 Left, Middle, Right, Count
53 };
54
55 /** Describes pointer (mouse, touch) states as reported by the OS. */
56 struct BS_CORE_EXPORT OSPointerButtonStates
57 {
58 OSPointerButtonStates()
59 {
60 mouseButtons[0] = false;
61 mouseButtons[1] = false;
62 mouseButtons[2] = false;
63
64 shift = false;
65 ctrl = false;
66 }
67
68 bool mouseButtons[(UINT32)OSMouseButton::Count];
69 bool shift, ctrl;
70 };
71
72 /** Represents a specific non client area used for window resizing. */
73 struct BS_CORE_EXPORT NonClientResizeArea
74 {
75 NonClientAreaBorderType type;
76 Rect2I area;
77 };
78
79 /** Contains a list of window move and resize non client areas. */
80 struct BS_CORE_EXPORT WindowNonClientAreaData
81 {
82 Vector<NonClientResizeArea> resizeAreas;
83 Vector<Rect2I> moveAreas;
84 };
85
86 /** Provides access to various operating system functions, including the main message pump. */
87 class BS_CORE_EXPORT Platform
88 {
89 public:
90 struct Pimpl;
91
92 Platform() { }
93 virtual ~Platform();
94
95 /**
96 * Retrieves the cursor position in screen coordinates.
97 *
98 * @note Thread safe.
99 */
100 static Vector2I getCursorPosition();
101
102 /**
103 * Moves the cursor to the specified screen position.
104 *
105 * @note Thread safe.
106 */
107 static void setCursorPosition(const Vector2I& screenPos);
108
109 /**
110 * Capture mouse to this window so that we get mouse input even if the mouse leaves the window area.
111 *
112 * @note Thread safe.
113 */
114 static void captureMouse(const RenderWindow& window);
115
116 /**
117 * Releases the mouse capture set by captureMouse().
118 *
119 * @note Thread safe.
120 */
121 static void releaseMouseCapture();
122
123 /**
124 * Checks if provided over screen position is over the specified window.
125 */
126 static bool isPointOverWindow(const RenderWindow& window, const Vector2I& screenPos);
127
128 /**
129 * Limit cursor movement to the specified window.
130 *
131 * @note Thread safe.
132 */
133 static void clipCursorToWindow(const RenderWindow& window);
134
135 /**
136 * Clip cursor to specific area on the screen.
137 *
138 * @note Thread safe.
139 */
140
141 static void clipCursorToRect(const Rect2I& screenRect);
142
143 /**
144 * Disables cursor clipping.
145 *
146 * @note Thread safe.
147 */
148 static void clipCursorDisable();
149
150 /**
151 * Hides the cursor.
152 *
153 * @note Thread safe.
154 */
155 static void hideCursor();
156
157 /**
158 * Shows the cursor.
159 *
160 * @note Thread safe.
161 */
162 static void showCursor();
163
164 /**
165 * Query if the cursor is hidden.
166 *
167 * @note Thread safe.
168 */
169 static bool isCursorHidden();
170
171 /**
172 * Sets a cursor using a custom image.
173 *
174 * @param[in] pixelData Cursor image data.
175 * @param[in] hotSpot Offset on the cursor image to where the actual input happens (for example tip of the
176 * Arrow cursor).
177 *
178 * @note Thread safe.
179 */
180 static void setCursor(PixelData& pixelData, const Vector2I& hotSpot);
181
182 /**
183 * Sets an icon for the main application window.
184 *
185 * @param[in] pixelData Icon image data. This will be resized to the required icon size, depending on platform
186 * implementation.
187 *
188 * @note Thread safe.
189 */
190 static void setIcon(const PixelData& pixelData);
191
192 /**
193 * Sets custom caption non client areas for the specified window. Using custom client areas will override window
194 * move/drag operation and trigger when user interacts with the custom area.
195 *
196 * @note
197 * Thread safe.
198 * @note
199 * All provided areas are relative to the specified window. Mostly useful for frameless windows that don't have
200 * typical caption bar.
201 */
202 static void setCaptionNonClientAreas(const ct::RenderWindow& window, const Vector<Rect2I>& nonClientAreas);
203
204 /**
205 * Sets custom non client areas for the specified window. Using custom client areas will override window resize
206 * operation and trigger when user interacts with the custom area.
207 *
208 * @note
209 * Thread safe.
210 * @note
211 * All provided areas are relative to the specified window. Mostly useful for frameless windows that don't have
212 * typical border.
213 */
214 static void setResizeNonClientAreas(const ct::RenderWindow& window, const Vector<NonClientResizeArea>& nonClientAreas);
215
216 /**
217 * Resets the non client areas for the specified windows and allows the platform to use the default values.
218 *
219 * @note Thread safe.
220 */
221 static void resetNonClientAreas(const ct::RenderWindow& window);
222
223 /**
224 * Causes the current thread to pause execution for the specified amount of time.
225 *
226 * @param[in] duration Duration in milliseconds. Providing zero will give up the current time-slice.
227 *
228 * @note This method relies on timer granularity being set to 1 millisecond. If it is not, you can expect
229 * this method to potentially take significantly longer if you are providing it with low ms values (<10).
230 */
231 static void sleep(UINT32 duration);
232
233 /**
234 * Opens the provided folder using the default application, as specified by the operating system.
235 *
236 * @param[in] path Absolute path to the folder to open.
237 */
238 static void openFolder(const Path& path);
239
240 /**
241 * Adds a string to the clipboard.
242 *
243 * @note Thread safe.
244 */
245 static void copyToClipboard(const String& string);
246
247 /**
248 * Reads a string from the clipboard and returns it. If there is no string in the clipboard it returns an empty
249 * string.
250 *
251 * @note
252 * Both wide and normal strings will be read, but normal strings will be converted to a wide string before returning.
253 * @note
254 * Thread safe.
255 */
256 static String copyFromClipboard();
257
258 /**
259 * Converts a keyboard key-code to a Unicode character.
260 *
261 * @note
262 * Normally this will output a single character, but it can happen it outputs multiple in case a accent/diacritic
263 * character could not be combined with the virtual key into a single character.
264 */
265 static String keyCodeToUnicode(UINT32 keyCode);
266
267 /**
268 * Message pump. Processes OS messages and returns when it's free.
269 *
270 * @note Core thread only.
271 */
272 static void _messagePump();
273
274 /** Called during application start up from the sim thread. Must be called before any other operations are done. */
275 static void _startUp();
276
277 /** Called once per frame from the sim thread. */
278 static void _update();
279
280 /** Called once per frame from the core thread. */
281 static void _coreUpdate();
282
283 /** Called during application shut down from the sim thread. */
284 static void _shutDown();
285
286 /**
287 * Triggered whenever the pointer moves.
288 *
289 * @note Core thread only.
290 */
291 static Event<void(const Vector2I&, const OSPointerButtonStates&)> onCursorMoved;
292
293 /**
294 * Triggered whenever a pointer button is pressed.
295 *
296 * @note Core thread only.
297 */
298 static Event<void(const Vector2I&, OSMouseButton button, const OSPointerButtonStates&)> onCursorButtonPressed;
299
300 /**
301 * Triggered whenever pointer button is released.
302 *
303 * @note Core thread only.
304 */
305 static Event<void(const Vector2I&, OSMouseButton button, const OSPointerButtonStates&)> onCursorButtonReleased;
306
307 /**
308 * Triggered whenever a pointer button is double clicked.
309 *
310 * @note Core thread only.
311 */
312 static Event<void(const Vector2I&, const OSPointerButtonStates&)> onCursorDoubleClick;
313
314 /**
315 * Triggered whenever an input command is entered.
316 *
317 * @note Core thread only.
318 */
319 static Event<void(InputCommandType)> onInputCommand;
320
321 /**
322 * Triggered whenever the mouse wheel is scolled.
323 *
324 * @note Core thread only.
325 */
326 static Event<void(float)> onMouseWheelScrolled;
327
328 /**
329 * Triggered whenever a character is entered.
330 *
331 * @note Core thread only.
332 */
333 static Event<void(UINT32)> onCharInput;
334
335 /**
336 * Triggered whenever mouse capture state for the window is changed (it receives or loses it).
337 *
338 * @note Core thread only.
339 */
340 static Event<void()> onMouseCaptureChanged;
341 protected:
342 static Pimpl* mData;
343 };
344
345 /** @} */
346}