1 module gfm.sdl2.mouse; 2 3 import derelict.sdl2.sdl; 4 import gfm.sdl2.sdl; 5 import gfm.sdl2.surface; 6 7 /// Holds SDL mouse state. 8 final class SDL2Mouse 9 { 10 public 11 { 12 /// Returns: true if a specific mouse button defined by mask is pressed 13 /// Example: 14 /// -------------------- 15 /// // Check if the left mouse button is pressed 16 /// if(_sdl2.mouse.isButtonPressed(SDL_BUTTON_LMASK)) 17 /// ... 18 /// -------------------- 19 bool isButtonPressed(int mask) pure const nothrow 20 { 21 return (_buttonState & mask) != 0; 22 } 23 24 /// Returns: X coordinate of mouse pointer. 25 int x() pure const nothrow 26 { 27 return _x; 28 } 29 30 /// Returns: Y coordinate of mouse pointer. 31 int y() pure const nothrow 32 { 33 return _y; 34 } 35 36 /// Returns: X relative movement on last motion event. 37 int lastDeltaX() pure const nothrow 38 { 39 return _lastDeltaX; 40 } 41 42 /// Returns: Y relative movement on last motion event. 43 int lastDeltaY() pure const nothrow 44 { 45 return _lastDeltaY; 46 } 47 48 /// Returns: Coordinates of mouse pointer. 49 SDL_Point position() pure const nothrow 50 { 51 return SDL_Point(_x, _y); 52 } 53 54 /// Returns: Previous coordinates of mouse pointer. Useful in onMouseMove event callback. 55 SDL_Point previousPosition() pure const nothrow 56 { 57 return SDL_Point(_x - _lastDeltaX, _y - _lastDeltaY); 58 } 59 60 /// Returns: How much was scrolled by X coordinate since the last call. 61 int wheelDeltaX() nothrow 62 { 63 int value = _wheelX; 64 _wheelX = 0; 65 return value; 66 } 67 68 /// Returns: How much was scrolled by Y coordinate since the last call. 69 int wheelDeltaY() nothrow 70 { 71 int value = _wheelY; 72 _wheelY = 0; 73 return value; 74 } 75 /+ 76 /// Use this function to capture the mouse and to track input outside an SDL window. 77 /// See_also: $(LINK https://wiki.libsdl.org/SDL_CaptureMouse) 78 /// Throws: $(D SDL2Exception) on error. 79 void startCapture() 80 { 81 if (SDL_CaptureMouse(SDL_TRUE) != 0) 82 _sdl2.throwSDL2Exception("SDL_CaptureMouse"); 83 } 84 85 /// Use this function to stop capturing the mouse. 86 /// See_also: $(LINK https://wiki.libsdl.org/SDL_CaptureMouse) 87 /// Throws: $(D SDL2Exception) on error. 88 void stopCapture() 89 { 90 if (SDL_CaptureMouse(SDL_FALSE) != 0) 91 _sdl2.throwSDL2Exception("SDL_CaptureMouse"); 92 } 93 +/ 94 } 95 96 package 97 { 98 this(SDL2 sdl2) 99 { 100 _sdl2 = sdl2; 101 } 102 103 void updateMotion(const(SDL_MouseMotionEvent)* event) 104 { 105 // Get mouse buttons state but ignore mouse coordinates 106 // because we get them from event data 107 _buttonState = SDL_GetMouseState(null, null); 108 _x = event.x; 109 _y = event.y; 110 _lastDeltaX = event.xrel; 111 _lastDeltaY = event.yrel; 112 } 113 114 void updateButtons(const(SDL_MouseButtonEvent)* event) 115 { 116 // get mouse buttons state but ignore mouse coordinates 117 // because we get them from event data 118 _buttonState = SDL_GetMouseState(null, null); 119 _x = event.x; 120 _y = event.y; 121 } 122 123 void updateWheel(const(SDL_MouseWheelEvent)* event) 124 { 125 _buttonState = SDL_GetMouseState(&_x, &_y); 126 _wheelX += event.x; 127 _wheelY += event.y; 128 } 129 } 130 131 private 132 { 133 SDL2 _sdl2; 134 135 // Last button state 136 int _buttonState; 137 138 // Last mouse coordinates 139 int _x = 0, 140 _y = 0; 141 142 // mouse wheel scrolled amounts 143 int _wheelX = 0, 144 _wheelY = 0; 145 146 int _lastDeltaX = 0, 147 _lastDeltaY = 0; 148 } 149 } 150 151 152 /// Mouse cursor, can be created from custom bitmap or from system defaults. 153 final class SDL2Cursor 154 { 155 public 156 { 157 /// Creates a cursor from a SDL surface. 158 /// The surface should outlive this cursor, its ownership will not be taken. 159 /// See_also: $(LINK http://wiki.libsdl.org/SDL_CreateColorCursor) 160 /// Throws: $(D SDL2Exception) on error. 161 this(SDL2 sdl2, SDL2Surface surface, int hotspotX, int hotspotY) 162 { 163 _sdl2 = sdl2; 164 _handle = SDL_CreateColorCursor(surface.handle(), hotspotX, hotspotY); 165 if(_handle is null) 166 _sdl2.throwSDL2Exception("SDL_CreateColorCursor"); 167 _owned = true; 168 } 169 170 /// Creates a system cursor. 171 /// See_also: $(LINK http://wiki.libsdl.org/SDL_CreateSystemCursor) 172 /// Throws: $(D SDL2Exception) on error. 173 this(SDL2 sdl2, SDL_SystemCursor id) 174 { 175 _sdl2 = sdl2; 176 _handle = SDL_CreateSystemCursor(id); 177 if(_handle is null) 178 _sdl2.throwSDL2Exception("SDL_CreateSystemCursor"); 179 _owned = true; 180 } 181 182 /// Returns: Default cursor. 183 /// See_also: $(LINK http://wiki.libsdl.org/SDL_GetDefaultCursor) 184 /// Throws: $(D SDL2Exception) on error. 185 static SDL2Cursor getDefault(SDL2 sdl2) 186 { 187 SDL_Cursor* handle = SDL_GetDefaultCursor(); 188 if(handle is null) 189 sdl2.throwSDL2Exception("SDL_GetDefaultCursor"); 190 191 return new SDL2Cursor(sdl2, handle); 192 193 } 194 195 /// Returns: Current cursor. 196 /// See_also: $(LINK http://wiki.libsdl.org/SDL_GetCursor) 197 /// Throws: $(D SDL2Exception) on error. 198 static SDL2Cursor getCurrent(SDL2 sdl2) 199 { 200 SDL_Cursor* handle = SDL_GetCursor(); 201 if(handle is null) 202 sdl2.throwSDL2Exception("SDL_GetCursor"); 203 204 return new SDL2Cursor(sdl2, handle); 205 } 206 207 ~this() 208 { 209 close(); 210 } 211 212 /// Returns: SDL handle. 213 SDL_Cursor* handle() 214 { 215 return _handle; 216 } 217 218 void close() 219 { 220 if (_owned && _handle !is null) 221 { 222 SDL_FreeCursor(_handle); 223 _handle = null; 224 } 225 } 226 227 void setCurrent() 228 { 229 SDL_SetCursor(_handle); 230 } 231 } 232 233 private 234 { 235 SDL2 _sdl2; 236 SDL_Cursor* _handle; 237 SDL2Surface _surface; 238 bool _owned; 239 240 // Create with specified handle. 241 this(SDL2 sdl2, SDL_Cursor* handle) 242 { 243 _sdl2 = sdl2; 244 _handle = handle; 245 _owned = false; 246 } 247 } 248 }