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 	import derelict.sdl2.types;
28 	import derelict.sdl2.functions;
29 	
30 	import Dgame.Graphics.Surface;
31 }
32 
33 /**
34  * Represent the Mouse
35  */
36 final abstract class Mouse {
37 public:
38 	/**
39 	 * Shorthand for SDL_Cursor*
40 	 */
41 	alias Cursor = SDL_Cursor*;
42 	
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 	 * Supported mouse states
57 	 */
58 	enum State : ubyte {
59 		Released, /** */
60 		Pressed /** */
61 	}
62 	
63 	/**
64 	 * Supported mouse motion states
65 	 */
66 	enum MotionStates : ubyte {
67 		LMask  = 0x1, /** */
68 		MMask  = 0x2, /** */
69 		RMask  = 0x4, /** */
70 		X1Mask = 0x8, /** */
71 		X2Mask = 0x10 /** */
72 	}
73 	
74 	/**
75 	 * Creates a cursor at the given positions with the given Surface.
76 	 */
77 	static Cursor create(ref Surface srfc, short x, short y) {
78 		return SDL_CreateColorCursor(srfc.ptr, x, y);
79 	}
80 	
81 	/**
82 	 * Creates a cursor from pixel data.
83 	 * 
84 	 * See: http://wiki.libsdl.org/moin.fcg/SDL_CreateCursor
85 	 */
86 	static Cursor create(const ubyte* data, const ubyte* mask,
87 	                     ushort width, ushort height, short x, short y)
88 	{
89 		return SDL_CreateCursor(data, mask, width, height, x, y);
90 	}
91 	
92 	/**
93 	 * Destroys the given cursor.
94 	 */
95 	static void destroyCursor(Cursor cursor) {
96 		SDL_FreeCursor(cursor);
97 	}
98 	
99 	/**
100 	 * Set a new cursor.
101 	 */
102 	static void setCursor(Cursor cursor) {
103 		SDL_SetCursor(cursor);
104 	}
105 	
106 	/**
107 	 * Returns the current cursor.
108 	 */
109 	static Cursor getCursor() {
110 		return SDL_GetCursor();
111 	}
112 	
113 	/**
114 	 * Returns the mouse state and (if y and y aren't null) the current position.
115 	 * 
116 	 * See: Mouse.State enum
117 	 */
118 	static uint getState(int* x = null, int* y = null) {
119 		return SDL_GetMouseState(x, y);
120 	}
121 	
122 	/**
123 	 * Returns the relative mouse state and (if y and y aren't null) the relative position.
124 	 * This means the difference of the positions since the last call of this method.
125 	 * 
126 	 * See: Mouse.RelativeState enum
127 	 */
128 	static uint getRelativeState(int* x = null, int* y = null) {
129 		return SDL_GetRelativeMouseState(x, y);
130 	}
131 	
132 	/**
133 	 * Returns if the given button is pressed.
134 	 * 
135 	 * See: Mouse.Button
136 	 */
137 	static bool hasState(Button btn) {
138 		return (Mouse.getState() & SDL_BUTTON(btn)) != 0;
139 	}
140 	
141 	/**
142 	 * 
143 	 */
144 	static bool hasRelativeState(Button btn) {
145 		return (Mouse.getState() & SDL_BUTTON(btn)) != 0;
146 	}
147 	
148 	/**
149 	 * Returns the cursor position as static array.
150 	 */
151 	static int[2] getCursorPosition() {
152 		int x, y;
153 		Mouse.getState(&x, &y);
154 		
155 		return [x, y];
156 	}
157 	
158 	/**
159 	 * Enable or disable that the cursor is shown on the window.
160 	 */
161 	static void showCursor(bool enable) {
162 		SDL_ShowCursor(enable);
163 	}
164 	
165 	/**
166 	 * Set the cursor position inside the window.
167 	 */
168 	static void setCursorPosition(short x, short y) {
169 		SDL_Window* wnd = SDL_GetMouseFocus();
170 		if (wnd !is null)
171 			SDL_WarpMouseInWindow(wnd, x, y);
172 	}
173 	
174 	/**
175 	 * Alias for setting cursor position
176 	 */
177 	alias warp = setCursorPosition;
178 	
179 	/**
180 	 * Returns if the Relative mouse mode is enabled/supported.
181 	 */
182 	static bool hasRelativeMouse() {
183 		return SDL_GetRelativeMouseMode() == SDL_TRUE;
184 	}
185 	
186 	/**
187 	 * Tries to enable/disable the relative mouse mode.
188 	 */
189 	static bool enableRelativeMouse(bool enable) {
190 		return SDL_SetRelativeMouseMode(enable) == 0;
191 	}
192 }