1 /* 2 ******************************************************************************************* 3 * Dgame (a D game framework) - Copyright (c) Randy Schütt 4 * 5 * This software is provided 'as-is', without any express or implied warranty. 6 * In no event will the authors be held liable for any damages arising from 7 * the use of this software. 8 * 9 * Permission is granted to anyone to use this software for any purpose, 10 * including commercial applications, and to alter it and redistribute it 11 * freely, subject to the following restrictions: 12 * 13 * 1. The origin of this software must not be misrepresented; you must not claim 14 * that you wrote the original software. If you use this software in a product, 15 * an acknowledgment in the product documentation would be appreciated but is 16 * not required. 17 * 18 * 2. Altered source versions must be plainly marked as such, and must not be 19 * misrepresented as being the original software. 20 * 21 * 3. This notice may not be removed or altered from any source distribution. 22 ******************************************************************************************* 23 */ 24 module Dgame.System.Mouse; 25 26 private: 27 28 import derelict.sdl2.types; 29 import derelict.sdl2.functions; 30 31 import Dgame.Graphic.Surface; 32 import Dgame.Math.Vector2; 33 34 public: 35 36 /** 37 * Represent the Mouse 38 * 39 * Author: Randy Schuett (rswhite4@googlemail.com) 40 */ 41 final abstract class Mouse { 42 public: 43 /** 44 * Supported mouse buttons 45 */ 46 enum Button : ubyte { 47 Left = 1, /// 48 Middle = 2, /// 49 Right = 3, /// 50 X1 = 4, /// 51 X2 = 5, /// 52 Other /// 53 } 54 55 /** 56 * Possible System cursors 57 */ 58 enum SystemCursor { 59 Arrow = SDL_SYSTEM_CURSOR_ARROW, /// 60 IBeam = SDL_SYSTEM_CURSOR_IBEAM, /// 61 Wait = SDL_SYSTEM_CURSOR_WAIT, /// 62 CrossHair = SDL_SYSTEM_CURSOR_CROSSHAIR, /// 63 WaitArrow = SDL_SYSTEM_CURSOR_WAITARROW, /// 64 SizeNWSE = SDL_SYSTEM_CURSOR_SIZENWSE, /// 65 SizeNESW = SDL_SYSTEM_CURSOR_SIZENESW, /// 66 SizeWE = SDL_SYSTEM_CURSOR_SIZEWE, /// 67 SizeNS = SDL_SYSTEM_CURSOR_SIZENS, /// 68 SizeAll = SDL_SYSTEM_CURSOR_SIZEALL, /// 69 None = SDL_SYSTEM_CURSOR_NO, /// 70 Hand = SDL_SYSTEM_CURSOR_HAND /// 71 } 72 73 /** 74 * The Cursor representation 75 */ 76 alias Cursor = SDL_Cursor*; 77 78 private static Cursor _cursor; 79 80 @nogc 81 static ~this() nothrow { 82 if (_cursor) 83 SDL_FreeCursor(_cursor); 84 } 85 86 /** 87 * Returns if the given button is pressed. 88 * 89 * See: Mouse.Button 90 */ 91 @nogc 92 static bool isPressed(Button btn) nothrow { 93 return (SDL_GetMouseState(null, null) & SDL_BUTTON(btn)) != 0; 94 } 95 96 /** 97 * Returns the current cursor position 98 */ 99 @nogc 100 static Vector2i getCursorPosition() nothrow { 101 int x, y; 102 SDL_GetMouseState(&x, &y); 103 104 return Vector2i(x, y); 105 } 106 107 /** 108 * Returns the relative cursor position. 109 * x and y are set to the mouse deltas since the last call 110 */ 111 @nogc 112 static Vector2i getRelativeCursorPosition() nothrow { 113 int x, y; 114 SDL_GetRelativeMouseState(&x, &y); 115 116 return Vector2i(x, y); 117 } 118 119 static if (SDL_VERSION_ATLEAST(2, 0, 4)) { 120 /** 121 * Returns the global cursor position. 122 * x and y will be reported relative to the top-left of the Desktop 123 */ 124 @nogc 125 static Vector2i getGlobalCursorPosition() nothrow { 126 int x, y; 127 SDL_GetGlobalMouseState(&x, &y); 128 129 return Vector2i(x, y); 130 } 131 } 132 133 /** 134 * Set the cursor position inside the window. 135 * 136 * Note: A call to this function generates a mouse motion event. 137 */ 138 @nogc 139 static void setCursorPosition(int x, int y) nothrow { 140 SDL_Window* wnd = SDL_GetMouseFocus(); 141 if (wnd) 142 SDL_WarpMouseInWindow(wnd, x, y); 143 } 144 145 /** 146 * Set the cursor position inside the window. 147 * 148 * Note: A call to this function generates a mouse motion event. 149 */ 150 @nogc 151 static void setCursorPosition(const Vector2i pos) nothrow { 152 Mouse.setCursorPosition(pos.x, pos.y); 153 } 154 155 static if (SDL_VERSION_ATLEAST(2, 0, 4)) { 156 /** 157 * Set the cursor position in global screen space. 158 * 159 * Note: A call to this function generates a mouse motion event. 160 */ 161 @nogc 162 static void setGlobalCursorPosition(int x, int y) nothrow { 163 SDL_WarpMouseGlobal(x, y); 164 } 165 166 /** 167 * Set the cursor position in global screen space. 168 * 169 * Note: A call to this function generates a mouse motion event. 170 */ 171 @nogc 172 static void setGlobalCursorPosition(const Vector2i pos) nothrow { 173 Mouse.setGlobalCursorPosition(pos.x, pos.y); 174 } 175 } 176 177 /** 178 * Returns if the Relative mouse mode is enabled/supported. 179 */ 180 @nogc 181 static bool hasRelativeMouse() nothrow { 182 return SDL_GetRelativeMouseMode() == SDL_TRUE; 183 } 184 185 /** 186 * Tries to enable/disable the relative mouse mode. 187 * While the mouse is in relative mode, the cursor is hidden, 188 * and the driver will try to report continuous motion in the current Window. 189 * Only relative motion events will be delivered, the mouse position will not change. 190 */ 191 @nogc 192 static bool enableRelativeMouse(bool enable) nothrow { 193 return SDL_SetRelativeMouseMode(enable) == 0; 194 } 195 196 /** 197 * Enable or disable that the cursor is shown on the window. 198 */ 199 @nogc 200 static void showCursor(bool enable) nothrow { 201 SDL_ShowCursor(enable); 202 } 203 204 static if (SDL_VERSION_ATLEAST(2, 0, 4)) { 205 /** 206 * Capture the mouse and track input outside of an Window. 207 */ 208 @nogc 209 static void captureCursor(bool enable) nothrow { 210 SDL_CaptureMouse(enable); 211 } 212 } 213 214 /** 215 * Create a Surface cursor. 216 */ 217 @nogc 218 static Cursor createCursor(ref Surface srfc, int hx, int hy) nothrow { 219 Cursor my_cursor = srfc.setAsCursorAt(hx, hy); 220 if (my_cursor && _cursor) { 221 SDL_FreeCursor(_cursor); 222 _cursor = my_cursor; 223 } 224 225 return _cursor; 226 } 227 228 /** 229 * Create a system cursor. 230 */ 231 @nogc 232 static Cursor createCursor(SystemCursor cursor) nothrow { 233 Cursor my_cursor = SDL_CreateSystemCursor(cursor); 234 if (my_cursor && _cursor) { 235 SDL_FreeCursor(_cursor); 236 _cursor = my_cursor; 237 } 238 239 return _cursor; 240 } 241 242 /** 243 * Set the active cursor. 244 */ 245 @nogc 246 static void setCursor(Cursor cursor) nothrow { 247 SDL_SetCursor(cursor); 248 } 249 250 /** 251 * Returns the active cursor. 252 */ 253 @nogc 254 static Cursor getCursor() nothrow { 255 return SDL_GetCursor(); 256 } 257 258 /** 259 * Get the default cursor. 260 */ 261 @nogc 262 static Cursor getDefaultCursor() nothrow { 263 return SDL_GetDefaultCursor(); 264 } 265 }