[ElmSharp] Fix SetNextFocusObject issue (#401)
[platform/core/csapi/tizenfx.git] / external / src / OpenTK / OpenTK / Input / MouseState.cs
1  //
2  // The Open Toolkit Library License
3  //
4  // Copyright (c) 2006 - 2009 the Open Toolkit library.
5  //
6  // Permission is hereby granted, free of charge, to any person obtaining a copy
7  // of this software and associated documentation files (the "Software"), to deal
8  // in the Software without restriction, including without limitation the rights to
9  // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10  // the Software, and to permit persons to whom the Software is furnished to do
11  // so, subject to the following conditions:
12  //
13  // The above copyright notice and this permission notice shall be included in all
14  // copies or substantial portions of the Software.
15  //
16  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18  // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20  // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21  // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  // OTHER DEALINGS IN THE SOFTWARE.
24  //
25
26 using System;
27
28 namespace OpenTK.Input
29 {
30     /// <summary>
31     /// Encapsulates the state of a mouse device.
32     /// </summary>
33     public struct MouseState : IEquatable<MouseState>
34     {
35         internal const int MaxButtons = 16; // we are storing in an ushort
36         private Vector2 position;
37         private MouseScroll scroll;
38         private ushort buttons;
39
40         /// <summary>
41         /// Gets a <see cref="System.Boolean"/> indicating whether the specified
42         /// <see cref="OpenTK.Input.MouseButton"/> is pressed.
43         /// </summary>
44         /// <param name="button">The <see cref="OpenTK.Input.MouseButton"/> to check.</param>
45         /// <returns>True if key is pressed; false otherwise.</returns>
46         public bool this[MouseButton button]
47         {
48             get { return IsButtonDown(button); }
49             internal set
50             {
51                 if (value)
52                 {
53                     EnableBit((int)button);
54                 }
55                 else
56                 {
57                     DisableBit((int)button);
58                 }
59             }
60         }
61
62         /// <summary>
63         /// Gets a <see cref="System.Boolean"/> indicating whether this button is down.
64         /// </summary>
65         /// <param name="button">The <see cref="OpenTK.Input.MouseButton"/> to check.</param>
66         public bool IsButtonDown(MouseButton button)
67         {
68             return ReadBit((int)button);
69         }
70
71         /// <summary>
72         /// Gets a <see cref="System.Boolean"/> indicating whether this button is up.
73         /// </summary>
74         /// <param name="button">The <see cref="OpenTK.Input.MouseButton"/> to check.</param>
75         public bool IsButtonUp(MouseButton button)
76         {
77             return !ReadBit((int)button);
78         }
79
80         /// <summary>
81         /// Gets the absolute wheel position in integer units.
82         /// To support high-precision mice, it is recommended to use <see cref="WheelPrecise"/> instead.
83         /// </summary>
84         public int Wheel
85         {
86             get { return (int)Math.Round(scroll.Y, MidpointRounding.AwayFromZero); }
87         }
88
89         /// <summary>
90         /// Gets the absolute wheel position in floating-point units.
91         /// </summary>
92         public float WheelPrecise
93         {
94             get { return scroll.Y; }
95         }
96
97         /// <summary>
98         /// Gets a <see cref="OpenTK.Input.MouseScroll"/> instance,
99         /// representing the current state of the mouse scroll wheel.
100         /// </summary>
101         public MouseScroll Scroll
102         {
103             get { return scroll; }
104         }
105
106         /// <summary>
107         /// Gets an integer representing the absolute x position of the pointer, in window pixel coordinates.
108         /// </summary>
109         public int X
110         {
111             get { return (int)Math.Round(position.X); }
112             internal set { position.X = value; }
113         }
114
115         /// <summary>
116         /// Gets an integer representing the absolute y position of the pointer, in window pixel coordinates.
117         /// </summary>
118         public int Y
119         {
120             get { return (int)Math.Round(position.Y); }
121             internal set { position.Y = value; }
122         }
123
124         /// <summary>
125         /// Gets a <see cref="System.Boolean"/> indicating whether the left mouse button is pressed.
126         /// This property is intended for XNA compatibility.
127         /// </summary>
128         public ButtonState LeftButton
129         {
130             get { return IsButtonDown(MouseButton.Left) ? ButtonState.Pressed : ButtonState.Released; }
131         }
132
133         /// <summary>
134         /// Gets a <see cref="System.Boolean"/> indicating whether the middle mouse button is pressed.
135         /// This property is intended for XNA compatibility.
136         /// </summary>
137         public ButtonState MiddleButton
138         {
139             get { return IsButtonDown(MouseButton.Middle) ? ButtonState.Pressed : ButtonState.Released; }
140         }
141
142         /// <summary>
143         /// Gets a <see cref="System.Boolean"/> indicating whether the right mouse button is pressed.
144         /// This property is intended for XNA compatibility.
145         /// </summary>
146         public ButtonState RightButton
147         {
148             get { return IsButtonDown(MouseButton.Right) ? ButtonState.Pressed : ButtonState.Released; }
149         }
150
151         /// <summary>
152         /// Gets a <see cref="System.Boolean"/> indicating whether the first extra mouse button is pressed.
153         /// This property is intended for XNA compatibility.
154         /// </summary>
155         public ButtonState XButton1
156         {
157             get { return IsButtonDown(MouseButton.Button1) ? ButtonState.Pressed : ButtonState.Released; }
158         }
159
160         /// <summary>
161         /// Gets a <see cref="System.Boolean"/> indicating whether the second extra mouse button is pressed.
162         /// This property is intended for XNA compatibility.
163         /// </summary>
164         public ButtonState XButton2
165         {
166             get { return IsButtonDown(MouseButton.Button2) ? ButtonState.Pressed : ButtonState.Released; }
167         }
168
169         /// <summary>
170         /// Gets a value indicating whether any button is down.
171         /// </summary>
172         /// <value><c>true</c> if any button is down; otherwise, <c>false</c>.</value>
173         public bool IsAnyButtonDown
174         {
175             get
176             {
177                 // If any bit is set then a button is down.
178                 return buttons != 0;
179             }
180         }
181
182         /// <summary>
183         /// Gets the absolute wheel position in integer units. This property is intended for XNA compatibility.
184         /// To support high-precision mice, it is recommended to use <see cref="WheelPrecise"/> instead.
185         /// </summary>
186         public int ScrollWheelValue
187         {
188             get { return Wheel; }
189         }
190
191         /// <summary>
192         /// Gets a value indicating whether this instance is connected.
193         /// </summary>
194         /// <value><c>true</c> if this instance is connected; otherwise, <c>false</c>.</value>
195         public bool IsConnected { get; internal set; }
196
197         /// <summary>
198         /// Checks whether two <see cref="MouseState" /> instances are equal.
199         /// </summary>
200         /// <param name="left">
201         /// A <see cref="MouseState"/> instance.
202         /// </param>
203         /// <param name="right">
204         /// A <see cref="MouseState"/> instance.
205         /// </param>
206         /// <returns>
207         /// True if both left is equal to right; false otherwise.
208         /// </returns>
209         public static bool operator ==(MouseState left, MouseState right)
210         {
211             return left.Equals(right);
212         }
213
214         /// <summary>
215         /// Checks whether two <see cref="MouseState" /> instances are not equal.
216         /// </summary>
217         /// <param name="left">
218         /// A <see cref="MouseState"/> instance.
219         /// </param>
220         /// <param name="right">
221         /// A <see cref="MouseState"/> instance.
222         /// </param>
223         /// <returns>
224         /// True if both left is not equal to right; false otherwise.
225         /// </returns>
226         public static bool operator !=(MouseState left, MouseState right)
227         {
228             return !left.Equals(right);
229         }
230
231         /// <summary>
232         /// Compares to an object instance for equality.
233         /// </summary>
234         /// <param name="obj">
235         /// The <see cref="System.Object"/> to compare to.
236         /// </param>
237         /// <returns>
238         /// True if this instance is equal to obj; false otherwise.
239         /// </returns>
240         public override bool Equals(object obj)
241         {
242             if (obj is MouseState)
243             {
244                 return this == (MouseState)obj;
245             }
246             else
247             {
248                 return false;
249             }
250         }
251
252         /// <summary>
253         /// Generates a hashcode for the current instance.
254         /// </summary>
255         /// <returns>
256         /// A <see cref="System.Int32"/> represting the hashcode for this instance.
257         /// </returns>
258         public override int GetHashCode()
259         {
260             return buttons.GetHashCode() ^ X.GetHashCode() ^ Y.GetHashCode() ^ scroll.GetHashCode();
261         }
262
263         /// <summary>
264         /// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.MouseState"/>.
265         /// </summary>
266         /// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.MouseState"/>.</returns>
267         public override string ToString()
268         {
269             string b = Convert.ToString(buttons, 2).PadLeft(10, '0');
270             return String.Format("[X={0}, Y={1}, Scroll={2}, Buttons={3}, IsConnected={4}]",
271                 X, Y, Scroll, b, IsConnected);
272         }
273
274         internal Vector2 Position
275         {
276             get { return position; }
277             set { position = value; }
278         }
279
280         internal bool ReadBit(int offset)
281         {
282             ValidateOffset(offset);
283             return (buttons & (1 << offset)) != 0;
284         }
285
286         internal void EnableBit(int offset)
287         {
288             ValidateOffset(offset);
289             buttons |= unchecked((ushort)(1 << offset));
290         }
291
292         internal void DisableBit(int offset)
293         {
294             ValidateOffset(offset);
295             buttons &= unchecked((ushort)(~(1 << offset)));
296         }
297
298         internal void MergeBits(MouseState other)
299         {
300             buttons |= other.buttons;
301             SetScrollRelative(other.scroll.X, other.scroll.Y);
302             X += other.X;
303             Y += other.Y;
304             IsConnected |= other.IsConnected;
305         }
306
307         internal void SetIsConnected(bool value)
308         {
309             IsConnected = value;
310         }
311
312         internal void SetScrollAbsolute(float x, float y)
313         {
314             scroll.X = x;
315             scroll.Y = y;
316         }
317
318         internal void SetScrollRelative(float x, float y)
319         {
320             scroll.X += x;
321             scroll.Y += y;
322         }
323
324         private static void ValidateOffset(int offset)
325         {
326             if (offset < 0 || offset >= 16)
327             {
328                 throw new ArgumentOutOfRangeException("offset");
329             }
330         }
331
332         /// <summary>
333         /// Compares two MouseState instances.
334         /// </summary>
335         /// <param name="other">The instance to compare two.</param>
336         /// <returns>True, if both instances are equal; false otherwise.</returns>
337         public bool Equals(MouseState other)
338         {
339             return
340                 buttons == other.buttons &&
341                 X == other.X &&
342                 Y == other.Y &&
343                 Scroll == other.Scroll;
344         }
345     }
346 }