1 /*
2  * DSFML - The Simple and Fast Multimedia Library for D
3  *
4  * Copyright (c) 2013 - 2018 Jeremy DeHaan (dehaan.jeremiah@gmail.com)
5  *
6  * This software is provided 'as-is', without any express or implied warranty.
7  * In no event will the authors be held liable for any damages arising from the
8  * use of this software.
9  *
10  * Permission is granted to anyone to use this software for any purpose,
11  * including commercial applications, and to alter it and redistribute it
12  * freely, subject to the following restrictions:
13  *
14  * 1. The origin of this software must not be misrepresented; you must not claim
15  * that you wrote the original software. If you use this software in a product,
16  * an acknowledgment in the product documentation would be appreciated but is
17  * not required.
18  *
19  * 2. Altered source versions must be plainly marked as such, and must not be
20  * misrepresented as being the original software.
21  *
22  * 3. This notice may not be removed or altered from any source distribution
23  *
24  *
25  * DSFML is based on SFML (Copyright Laurent Gomila)
26  */
27 
28 /**
29  * $(U Mouse) provides an interface to the state of the mouse. It only contains
30  * static functions (a single mouse is assumed), so it's not meant to be
31  * instanciated.
32  *
33  * This class allows users to query the mouse state at any time and directly, without having to deal with
34  * a window and its events. Compared to the MouseMoved, MouseButtonPressed and MouseButtonReleased events,
35  * Mouse can retrieve the state of the cursor and the buttons at any time (you don't need to store and update
36  * a boolean on your side in order to know if a button is pressed or released), and you always get the real
37  * state of the mouse, even if it is moved, pressed or released when your window is out of focus and no event is triggered.
38  *
39  * The setPosition and getPosition functions can be used to change or retrieve the current position of the
40  * mouse pointer. There are two versions: one that operates in global coordinates (relative to the desktop)
41  * and one that operates in window coordinates (relative to a specific window).
42  *
43  * Example:
44  * ---
45  * if (Mouse.isButtonPressed(Mouse.Button.Left))
46  * {
47  *     // left click...
48  * }
49  *
50  * // get global mouse position
51  * auto position = Mouse.getPosition();
52  *
53  * // set mouse position relative to a window
54  * Mouse.setPosition(Vector2i(100, 200), window);
55  * ---
56  *
57  * See_Also:
58  * $(JOYSTICK_LINK), $(KEYBOARD_LINK), $(TOUCH_LINK)
59  */
60 module dsfml.window.mouse;
61 
62 import dsfml.system.vector2;
63 import dsfml.window.window;
64 
65 /**
66 * Give access to the real-time state of the mouse.
67 */
68 final abstract class Mouse
69 {
70     /// Mouse buttons.
71     enum Button
72     {
73         /// The left mouse button
74         Left,
75         /// The right mouse button
76         Right,
77         /// The middle (wheel) mouse button
78         Middle,
79         /// The first extra mouse button
80         XButton1,
81         /// The second extra mouse button
82         XButton2,
83 
84         ///Keep last -- the total number of mouse buttons
85         Count
86 
87     }
88 
89     /// Mouse wheels.
90     enum Wheel
91     {
92         /// Vertically oriented mouse wheel
93         VerticalWheel,
94         /// Horizontally oriented mouse wheel
95         HorizontalWheel
96     }
97 
98     /**
99      * Set the current position of the mouse in desktop coordinates.
100      *
101      * This function sets the global position of the mouse cursor on the
102      * desktop.
103      *
104      * Params:
105      * 		position = New position of the mouse
106      */
107     static void setPosition(Vector2i position)
108     {
109         sfMouse_setPosition(position.x, position.y,null);
110     }
111 
112     /**
113      * Set the current position of the mouse in window coordinates.
114      *
115      * This function sets the current position of the mouse cursor, relative to the given window.
116      *
117      * Params:
118      * 		position   = New position of the mouse
119      * 		relativeTo = Reference window
120      */
121     static void setPosition(Vector2i position, const(Window) relativeTo)
122     {
123         relativeTo.mouse_SetPosition(position);
124     }
125 
126     /**
127      * Get the current position of the mouse in desktop coordinates.
128      *
129      * This function returns the global position of the mouse cursor on the
130      * desktop.
131      *
132      * Returns: Current position of the mouse.
133      */
134     static Vector2i getPosition()
135     {
136         Vector2i temp;
137         sfMouse_getPosition(null,&temp.x, &temp.y);
138 
139         return temp;
140     }
141 
142     /**
143      * Get the current position of the mouse in window coordinates.
144      *
145      * This function returns the current position of the mouse cursor, relative
146      * to the given window.
147      *
148      * Params:
149      *     relativeTo = Reference window
150      *
151      * Returns: Current position of the mouse.
152      */
153     static Vector2i getPosition(const(Window) relativeTo)
154     {
155         return relativeTo.mouse_getPosition();
156     }
157 
158     /**
159      * Check if a mouse button is pressed.
160      *
161      * Params:
162      * 		button = Button to check
163      *
164      * Returns: true if the button is pressed, false otherwise.
165      */
166     static bool isButtonPressed(Button button)
167     {
168         return (sfMouse_isButtonPressed(button) );
169     }
170 }
171 
172 unittest
173 {
174     version(DSFML_Unittest_Window)
175     {
176         import std.stdio;
177 
178         writeln("Unit test for Mouse class");
179 
180         writeln("Current mouse position: ", Mouse.getPosition().toString());
181 
182         Mouse.setPosition(Vector2i(100,400));
183 
184         writeln("New mouse position: ", Mouse.getPosition().toString());
185     }
186 }
187 
188 private extern(C)
189 {
190     //Check if a mouse button is pressed
191     bool sfMouse_isButtonPressed(int button);
192 
193     //Get the current position of the mouse
194     void sfMouse_getPosition(const(sfWindow)* relativeTo, int* x, int* y);
195 
196     //Set the current position of the mouse
197     void sfMouse_setPosition(int x, int y, const(sfWindow)* relativeTo);
198 }