[Platform] Improved mouse interface
- The complete mouse state is now available in mouse events - Horizontal wheels are now supported - MouseState now takes up less memory and has a simpler internal implementation.
This commit is contained in:
parent
e85377c350
commit
94fdf1881c
16 changed files with 675 additions and 552 deletions
|
@ -126,8 +126,8 @@ namespace Examples.Tests
|
|||
{
|
||||
mouse_pos.X = e.X;
|
||||
mouse_pos.Y = e.Y;
|
||||
mouse_pos.Z = e.Wheel.X;
|
||||
mouse_pos.W = e.Wheel.Y;
|
||||
mouse_pos.Z = e.Mouse.Scroll.X;
|
||||
mouse_pos.W = e.Mouse.Scroll.Y;
|
||||
}
|
||||
|
||||
void MouseButtonHandler(object sender, MouseButtonEventArgs e)
|
||||
|
@ -149,8 +149,8 @@ namespace Examples.Tests
|
|||
|
||||
void MouseWheelHandler(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
mouse_pos.Z += e.Wheel.Y;
|
||||
mouse_pos.W += e.Wheel.X;
|
||||
mouse_pos.Z += e.Mouse.Scroll.Y;
|
||||
mouse_pos.W += e.Mouse.Scroll.X;
|
||||
}
|
||||
|
||||
static int Clamp(int val, int min, int max)
|
||||
|
|
|
@ -361,398 +361,4 @@ namespace OpenTK.Input
|
|||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a mouse wheel.
|
||||
/// </summary>
|
||||
public sealed class MouseWheel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the X offset of the wheel.
|
||||
/// </summary>
|
||||
/// <value>The x.</value>
|
||||
public float X { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Y offset of the wheel.
|
||||
/// </summary>
|
||||
/// <value>The y.</value>
|
||||
public float Y { get; internal set; }
|
||||
}
|
||||
|
||||
#region Event Arguments
|
||||
|
||||
/// <summary>
|
||||
/// Defines the event data for <see cref="MouseDevice"/> events.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Do not cache instances of this type outside their event handler.
|
||||
/// If necessary, you can clone an instance using the
|
||||
/// <see cref="MouseEventArgs(MouseEventArgs)"/> constructor.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class MouseEventArgs : EventArgs
|
||||
{
|
||||
#region Fields
|
||||
|
||||
int x, y;
|
||||
int buttons;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance.
|
||||
/// </summary>
|
||||
public MouseEventArgs()
|
||||
{
|
||||
Wheel = new MouseWheel();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance.
|
||||
/// </summary>
|
||||
/// <param name="x">The X position.</param>
|
||||
/// <param name="y">The Y position.</param>
|
||||
public MouseEventArgs(int x, int y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance.
|
||||
/// </summary>
|
||||
/// <param name="args">The <see cref="MouseEventArgs"/> instance to clone.</param>
|
||||
public MouseEventArgs(MouseEventArgs args)
|
||||
: this(args.x, args.y)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Members
|
||||
|
||||
internal void SetButton(MouseButton button, ButtonState state)
|
||||
{
|
||||
if (button < 0 || button > MouseButton.LastButton)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ButtonState.Pressed:
|
||||
buttons |= 1 << (int)button;
|
||||
break;
|
||||
|
||||
case ButtonState.Released:
|
||||
buttons &= ~(1 << (int)button);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal ButtonState GetButton(MouseButton button)
|
||||
{
|
||||
if (button < 0 || button > MouseButton.LastButton)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
return
|
||||
(buttons & (1 << (int)button)) != 0 ?
|
||||
ButtonState.Pressed : ButtonState.Released;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the X position of the mouse for the event.
|
||||
/// </summary>
|
||||
public int X { get { return x; } internal set { x = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Y position of the mouse for the event.
|
||||
/// </summary>
|
||||
public int Y { get { return y; } internal set { y = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the status of the mouse wheel.
|
||||
/// </summary>
|
||||
public MouseWheel Wheel { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ButtonState"/> of the left mouse button.
|
||||
/// </summary>
|
||||
public ButtonState LeftButton
|
||||
{
|
||||
get { return GetButton(MouseButton.Left); }
|
||||
internal set { SetButton(MouseButton.Left, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ButtonState"/> of the right mouse button.
|
||||
/// </summary>
|
||||
public ButtonState RightButton
|
||||
{
|
||||
get { return GetButton(MouseButton.Right); }
|
||||
internal set { SetButton(MouseButton.Right, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ButtonState"/> of the middle mouse button.
|
||||
/// </summary>
|
||||
public ButtonState MiddleButton
|
||||
{
|
||||
get { return GetButton(MouseButton.Middle); }
|
||||
internal set { SetButton(MouseButton.Middle, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ButtonState"/> of the first extra mouse button.
|
||||
/// </summary>
|
||||
public ButtonState X1Button
|
||||
{
|
||||
get { return GetButton(MouseButton.Button1); }
|
||||
internal set { SetButton(MouseButton.Button1, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ButtonState"/> of the second extra mouse button.
|
||||
/// </summary>
|
||||
public ButtonState X2Button
|
||||
{
|
||||
get { return GetButton(MouseButton.Button2); }
|
||||
internal set { SetButton(MouseButton.Button2, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="System.Drawing.Point"/> representing the location of the mouse for the event.
|
||||
/// </summary>
|
||||
public Point Position
|
||||
{
|
||||
get { return new Point(x, y); }
|
||||
set
|
||||
{
|
||||
X = value.X;
|
||||
Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the event data for <see cref="MouseDevice.Move"/> events.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Do not cache instances of this type outside their event handler.
|
||||
/// If necessary, you can clone an instance using the
|
||||
/// <see cref="MouseMoveEventArgs(MouseMoveEventArgs)"/> constructor.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class MouseMoveEventArgs : MouseEventArgs
|
||||
{
|
||||
#region Fields
|
||||
|
||||
int x_delta, y_delta;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
||||
/// </summary>
|
||||
public MouseMoveEventArgs() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="x">The X position.</param>
|
||||
/// <param name="y">The Y position.</param>
|
||||
/// <param name="xDelta">The change in X position produced by this event.</param>
|
||||
/// <param name="yDelta">The change in Y position produced by this event.</param>
|
||||
public MouseMoveEventArgs(int x, int y, int xDelta, int yDelta)
|
||||
: base(x, y)
|
||||
{
|
||||
XDelta = xDelta;
|
||||
YDelta = yDelta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="args">The <see cref="MouseMoveEventArgs"/> instance to clone.</param>
|
||||
public MouseMoveEventArgs(MouseMoveEventArgs args)
|
||||
: this(args.X, args.Y, args.XDelta, args.YDelta)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change in X position produced by this event.
|
||||
/// </summary>
|
||||
public int XDelta { get { return x_delta; } internal set { x_delta = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change in Y position produced by this event.
|
||||
/// </summary>
|
||||
public int YDelta { get { return y_delta; } internal set { y_delta = value; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the event data for <see cref="MouseDevice.ButtonDown"/> and <see cref="MouseDevice.ButtonUp"/> events.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Do not cache instances of this type outside their event handler.
|
||||
/// If necessary, you can clone an instance using the
|
||||
/// <see cref="MouseButtonEventArgs(MouseButtonEventArgs)"/> constructor.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class MouseButtonEventArgs : MouseEventArgs
|
||||
{
|
||||
#region Fields
|
||||
|
||||
MouseButton button;
|
||||
bool pressed;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
||||
/// </summary>
|
||||
public MouseButtonEventArgs() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="x">The X position.</param>
|
||||
/// <param name="y">The Y position.</param>
|
||||
/// <param name="button">The mouse button for the event.</param>
|
||||
/// <param name="pressed">The current state of the button.</param>
|
||||
public MouseButtonEventArgs(int x, int y, MouseButton button, bool pressed)
|
||||
: base(x, y)
|
||||
{
|
||||
this.button = button;
|
||||
this.pressed = pressed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="args">The <see cref="MouseButtonEventArgs"/> instance to clone.</param>
|
||||
public MouseButtonEventArgs(MouseButtonEventArgs args)
|
||||
: this(args.X, args.Y, args.Button, args.IsPressed)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="MouseButton"/> that triggered this event.
|
||||
/// </summary>
|
||||
public MouseButton Button { get { return button; } internal set { button = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Boolean representing the state of the mouse button for the event.
|
||||
/// </summary>
|
||||
public bool IsPressed
|
||||
{
|
||||
get { return GetButton(Button) == ButtonState.Pressed; }
|
||||
internal set { SetButton(Button, value ? ButtonState.Pressed : ButtonState.Released); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the event data for <see cref="MouseDevice.WheelChanged"/> events.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Do not cache instances of this type outside their event handler.
|
||||
/// If necessary, you can clone an instance using the
|
||||
/// <see cref="MouseWheelEventArgs(MouseWheelEventArgs)"/> constructor.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class MouseWheelEventArgs : MouseEventArgs
|
||||
{
|
||||
#region Fields
|
||||
|
||||
float delta;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
||||
/// </summary>
|
||||
public MouseWheelEventArgs() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="x">The X position.</param>
|
||||
/// <param name="y">The Y position.</param>
|
||||
/// <param name="value">The value of the wheel.</param>
|
||||
/// <param name="delta">The change in value of the wheel for this event.</param>
|
||||
public MouseWheelEventArgs(int x, int y, int value, int delta)
|
||||
: base(x, y)
|
||||
{
|
||||
Wheel.Y = value;
|
||||
this.delta = delta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="args">The <see cref="MouseWheelEventArgs"/> instance to clone.</param>
|
||||
public MouseWheelEventArgs(MouseWheelEventArgs args)
|
||||
: this(args.X, args.Y, args.Value, args.Delta)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the wheel in integer units.
|
||||
/// To support high-precision mice, it is recommended to use <see cref="ValuePrecise"/> instead.
|
||||
/// </summary>
|
||||
public int Value { get { return (int)Math.Round(Wheel.Y, MidpointRounding.AwayFromZero); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change in value of the wheel for this event in integer units.
|
||||
/// To support high-precision mice, it is recommended to use <see cref="DeltaPrecise"/> instead.
|
||||
/// </summary>
|
||||
public int Delta { get { return (int)Math.Round(delta, MidpointRounding.AwayFromZero); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the precise value of the wheel in floating-point units.
|
||||
/// </summary>
|
||||
public float ValuePrecise { get { return Wheel.Y; } internal set { Wheel.Y = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the precise change in value of the wheel for this event in floating-point units.
|
||||
/// </summary>
|
||||
public float DeltaPrecise { get { return delta; } internal set { delta = value; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
370
Source/OpenTK/Input/MouseEventArgs.cs
Normal file
370
Source/OpenTK/Input/MouseEventArgs.cs
Normal file
|
@ -0,0 +1,370 @@
|
|||
#region License
|
||||
//
|
||||
// MouseEventArgs.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenTK.Input
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the event data for <see cref="MouseDevice"/> events.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Do not cache instances of this type outside their event handler.
|
||||
/// If necessary, you can clone an instance using the
|
||||
/// <see cref="MouseEventArgs(MouseEventArgs)"/> constructor.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class MouseEventArgs : EventArgs
|
||||
{
|
||||
#region Fields
|
||||
|
||||
MouseState state;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance.
|
||||
/// </summary>
|
||||
public MouseEventArgs()
|
||||
{
|
||||
state.SetIsConnected(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance.
|
||||
/// </summary>
|
||||
/// <param name="x">The X position.</param>
|
||||
/// <param name="y">The Y position.</param>
|
||||
public MouseEventArgs(int x, int y)
|
||||
: this()
|
||||
{
|
||||
state.X = x;
|
||||
state.Y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance.
|
||||
/// </summary>
|
||||
/// <param name="args">The <see cref="MouseEventArgs"/> instance to clone.</param>
|
||||
public MouseEventArgs(MouseEventArgs args)
|
||||
: this(args.X, args.Y)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Members
|
||||
|
||||
internal void SetButton(MouseButton button, ButtonState state)
|
||||
{
|
||||
if (button < 0 || button > MouseButton.LastButton)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ButtonState.Pressed:
|
||||
this.state.EnableBit((int)button);
|
||||
break;
|
||||
|
||||
case ButtonState.Released:
|
||||
this.state.DisableBit((int)button);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal ButtonState GetButton(MouseButton button)
|
||||
{
|
||||
if (button < 0 || button > MouseButton.LastButton)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
return
|
||||
state.ReadBit((int)button) ?
|
||||
ButtonState.Pressed : ButtonState.Released;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the X position of the mouse for the event.
|
||||
/// </summary>
|
||||
public int X { get { return state.X; } internal set { state.X = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Y position of the mouse for the event.
|
||||
/// </summary>
|
||||
public int Y { get { return state.Y; } internal set { state.Y = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="System.Drawing.Point"/> representing the location of the mouse for the event.
|
||||
/// </summary>
|
||||
public Point Position
|
||||
{
|
||||
get { return new Point(state.X, state.Y); }
|
||||
set
|
||||
{
|
||||
X = value.X;
|
||||
Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current <see cref="OpenTK.Input.MouseState"/>.
|
||||
/// </summary>
|
||||
public MouseState Mouse
|
||||
{
|
||||
get { return state; }
|
||||
internal set { state = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the event data for <see cref="MouseDevice.Move"/> events.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Do not cache instances of this type outside their event handler.
|
||||
/// If necessary, you can clone an instance using the
|
||||
/// <see cref="MouseMoveEventArgs(MouseMoveEventArgs)"/> constructor.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class MouseMoveEventArgs : MouseEventArgs
|
||||
{
|
||||
#region Fields
|
||||
|
||||
int x_delta, y_delta;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
||||
/// </summary>
|
||||
public MouseMoveEventArgs() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="x">The X position.</param>
|
||||
/// <param name="y">The Y position.</param>
|
||||
/// <param name="xDelta">The change in X position produced by this event.</param>
|
||||
/// <param name="yDelta">The change in Y position produced by this event.</param>
|
||||
public MouseMoveEventArgs(int x, int y, int xDelta, int yDelta)
|
||||
: base(x, y)
|
||||
{
|
||||
XDelta = xDelta;
|
||||
YDelta = yDelta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="args">The <see cref="MouseMoveEventArgs"/> instance to clone.</param>
|
||||
public MouseMoveEventArgs(MouseMoveEventArgs args)
|
||||
: this(args.X, args.Y, args.XDelta, args.YDelta)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change in X position produced by this event.
|
||||
/// </summary>
|
||||
public int XDelta { get { return x_delta; } internal set { x_delta = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change in Y position produced by this event.
|
||||
/// </summary>
|
||||
public int YDelta { get { return y_delta; } internal set { y_delta = value; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the event data for <see cref="MouseDevice.ButtonDown"/> and <see cref="MouseDevice.ButtonUp"/> events.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Do not cache instances of this type outside their event handler.
|
||||
/// If necessary, you can clone an instance using the
|
||||
/// <see cref="MouseButtonEventArgs(MouseButtonEventArgs)"/> constructor.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class MouseButtonEventArgs : MouseEventArgs
|
||||
{
|
||||
#region Fields
|
||||
|
||||
MouseButton button;
|
||||
bool pressed;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
||||
/// </summary>
|
||||
public MouseButtonEventArgs() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="x">The X position.</param>
|
||||
/// <param name="y">The Y position.</param>
|
||||
/// <param name="button">The mouse button for the event.</param>
|
||||
/// <param name="pressed">The current state of the button.</param>
|
||||
public MouseButtonEventArgs(int x, int y, MouseButton button, bool pressed)
|
||||
: base(x, y)
|
||||
{
|
||||
this.button = button;
|
||||
this.pressed = pressed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="args">The <see cref="MouseButtonEventArgs"/> instance to clone.</param>
|
||||
public MouseButtonEventArgs(MouseButtonEventArgs args)
|
||||
: this(args.X, args.Y, args.Button, args.IsPressed)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="MouseButton"/> that triggered this event.
|
||||
/// </summary>
|
||||
public MouseButton Button { get { return button; } internal set { button = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Boolean representing the state of the mouse button for the event.
|
||||
/// </summary>
|
||||
public bool IsPressed
|
||||
{
|
||||
get { return GetButton(Button) == ButtonState.Pressed; }
|
||||
internal set { SetButton(Button, value ? ButtonState.Pressed : ButtonState.Released); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the event data for <see cref="MouseDevice.WheelChanged"/> events.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Do not cache instances of this type outside their event handler.
|
||||
/// If necessary, you can clone an instance using the
|
||||
/// <see cref="MouseWheelEventArgs(MouseWheelEventArgs)"/> constructor.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public class MouseWheelEventArgs : MouseEventArgs
|
||||
{
|
||||
#region Fields
|
||||
|
||||
float delta;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
||||
/// </summary>
|
||||
public MouseWheelEventArgs() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="x">The X position.</param>
|
||||
/// <param name="y">The Y position.</param>
|
||||
/// <param name="value">The value of the wheel.</param>
|
||||
/// <param name="delta">The change in value of the wheel for this event.</param>
|
||||
public MouseWheelEventArgs(int x, int y, int value, int delta)
|
||||
: base(x, y)
|
||||
{
|
||||
Mouse.SetScrollAbsolute(Mouse.Scroll.X, value);
|
||||
this.delta = delta;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="args">The <see cref="MouseWheelEventArgs"/> instance to clone.</param>
|
||||
public MouseWheelEventArgs(MouseWheelEventArgs args)
|
||||
: this(args.X, args.Y, args.Value, args.Delta)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the wheel in integer units.
|
||||
/// To support high-precision mice, it is recommended to use <see cref="ValuePrecise"/> instead.
|
||||
/// </summary>
|
||||
public int Value { get { return (int)Math.Round(Mouse.Scroll.Y, MidpointRounding.AwayFromZero); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the change in value of the wheel for this event in integer units.
|
||||
/// To support high-precision mice, it is recommended to use <see cref="DeltaPrecise"/> instead.
|
||||
/// </summary>
|
||||
public int Delta { get { return (int)Math.Round(delta, MidpointRounding.AwayFromZero); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the precise value of the wheel in floating-point units.
|
||||
/// </summary>
|
||||
public float ValuePrecise
|
||||
{
|
||||
get { return Mouse.Scroll.Y; }
|
||||
internal set { Mouse.SetScrollAbsolute(Mouse.Scroll.X, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the precise change in value of the wheel for this event in floating-point units.
|
||||
/// </summary>
|
||||
public float DeltaPrecise { get { return delta; } internal set { delta = value; } }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
119
Source/OpenTK/Input/MouseScrollWheel.cs
Normal file
119
Source/OpenTK/Input/MouseScrollWheel.cs
Normal file
|
@ -0,0 +1,119 @@
|
|||
#region License
|
||||
//
|
||||
// MouseWheel.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Input
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the state of a mouse wheel.
|
||||
/// </summary>
|
||||
public struct MouseScrollWheel : IEquatable<MouseScrollWheel>
|
||||
{
|
||||
#region Public Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the absolute horizontal offset of the wheel,
|
||||
/// or 0 if no horizontal scroll wheel exists.
|
||||
/// </summary>
|
||||
/// <value>The x.</value>
|
||||
public float X { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the absolute vertical offset of the wheel,
|
||||
/// or 0 if no vertical scroll wheel exists.
|
||||
/// </summary>
|
||||
/// <value>The y.</value>
|
||||
public float Y { get; internal set; }
|
||||
|
||||
/// <param name="left">A <see cref="MouseScrollWheel"/> instance to test for equality.</param>
|
||||
/// <param name="right">A <see cref="MouseScrollWheel"/> instance to test for equality.</param>
|
||||
public static bool operator ==(MouseScrollWheel left, MouseScrollWheel right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <param name="left">A <see cref="MouseScrollWheel"/> instance to test for inequality.</param>
|
||||
/// <param name="right">A <see cref="MouseScrollWheel"/> instance to test for inequality.</param>
|
||||
public static bool operator !=(MouseScrollWheel left, MouseScrollWheel right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.MouseScrollWheel"/>.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.MouseScrollWheel"/>.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[MouseScrollWheel: X={0}, Y={1}]", X, Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a <see cref="OpenTK.Input.MouseScrollWheel"/> object.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
|
||||
/// hash table.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() ^ Y.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.MouseScrollWheel"/>.
|
||||
/// </summary>
|
||||
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.MouseScrollWheel"/>.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
|
||||
/// <see cref="OpenTK.Input.MouseScrollWheel"/>; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return
|
||||
obj is MouseScrollWheel &&
|
||||
Equals((MouseScrollWheel)obj);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEquatable Members
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="OpenTK.Input.MouseScrollWheel"/> is equal to the current <see cref="OpenTK.Input.MouseScrollWheel"/>.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="OpenTK.Input.MouseScrollWheel"/> to compare with the current <see cref="OpenTK.Input.MouseScrollWheel"/>.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.MouseScrollWheel"/> is equal to the current
|
||||
/// <see cref="OpenTK.Input.MouseScrollWheel"/>; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(MouseScrollWheel other)
|
||||
{
|
||||
return X == other.X && Y == other.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -38,13 +38,9 @@ namespace OpenTK.Input
|
|||
{
|
||||
#region Fields
|
||||
|
||||
// Allocate enough ints to store all mouse buttons
|
||||
const int IntSize = sizeof(int);
|
||||
const int NumInts = ((int)MouseButton.LastButton + IntSize - 1) / IntSize;
|
||||
// The following line triggers bogus CS0214 in gmcs 2.0.1, sigh...
|
||||
unsafe fixed int Buttons[NumInts];
|
||||
int x, y;
|
||||
float wheel;
|
||||
MouseScrollWheel scroll;
|
||||
ushort buttons;
|
||||
bool is_connected;
|
||||
|
||||
#endregion
|
||||
|
@ -93,7 +89,7 @@ namespace OpenTK.Input
|
|||
/// </summary>
|
||||
public int Wheel
|
||||
{
|
||||
get { return (int)Math.Round(wheel, MidpointRounding.AwayFromZero); }
|
||||
get { return (int)Math.Round(scroll.Y, MidpointRounding.AwayFromZero); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -101,11 +97,16 @@ namespace OpenTK.Input
|
|||
/// </summary>
|
||||
public float WheelPrecise
|
||||
{
|
||||
get { return wheel; }
|
||||
internal set
|
||||
{
|
||||
wheel = value;
|
||||
}
|
||||
get { return scroll.Y; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="OpenTK.Input.MouseScrollWheel"/> instance,
|
||||
/// representing the current state of the mouse scroll wheel.
|
||||
/// </summary>
|
||||
public MouseScrollWheel Scroll
|
||||
{
|
||||
get { return scroll; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -253,13 +254,7 @@ namespace OpenTK.Input
|
|||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (int* b = Buttons)
|
||||
{
|
||||
return b->GetHashCode() ^ X.GetHashCode() ^ Y.GetHashCode() ^ WheelPrecise.GetHashCode();
|
||||
}
|
||||
}
|
||||
return buttons.GetHashCode() ^ X.GetHashCode() ^ Y.GetHashCode() ^ scroll.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -269,60 +264,27 @@ namespace OpenTK.Input
|
|||
internal bool ReadBit(int offset)
|
||||
{
|
||||
ValidateOffset(offset);
|
||||
|
||||
int int_offset = offset / 32;
|
||||
int bit_offset = offset % 32;
|
||||
unsafe
|
||||
{
|
||||
fixed (int* b = Buttons)
|
||||
{
|
||||
return (*(b + int_offset) & (1 << bit_offset)) != 0u;
|
||||
}
|
||||
}
|
||||
return (buttons & (1 << offset)) != 0;
|
||||
}
|
||||
|
||||
internal void EnableBit(int offset)
|
||||
{
|
||||
ValidateOffset(offset);
|
||||
|
||||
int int_offset = offset / 32;
|
||||
int bit_offset = offset % 32;
|
||||
unsafe
|
||||
{
|
||||
fixed (int* b = Buttons)
|
||||
{
|
||||
*(b + int_offset) |= 1 << bit_offset;
|
||||
}
|
||||
}
|
||||
buttons |= unchecked((ushort)(1 << offset));
|
||||
}
|
||||
|
||||
internal void DisableBit(int offset)
|
||||
{
|
||||
ValidateOffset(offset);
|
||||
|
||||
int int_offset = offset / 32;
|
||||
int bit_offset = offset % 32;
|
||||
unsafe
|
||||
{
|
||||
fixed (int* b = Buttons)
|
||||
{
|
||||
*(b + int_offset) &= ~(1 << bit_offset);
|
||||
}
|
||||
}
|
||||
buttons &= unchecked((ushort)(~(1 << offset)));
|
||||
}
|
||||
|
||||
internal void MergeBits(MouseState other)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
int* b2 = other.Buttons;
|
||||
fixed (int* b1 = Buttons)
|
||||
{
|
||||
for (int i = 0; i < NumInts; i++)
|
||||
*(b1 + i) |= *(b2 + i);
|
||||
}
|
||||
|
||||
WheelPrecise += other.WheelPrecise;
|
||||
buttons |= other.buttons;
|
||||
SetScrollRelative(other.scroll.X, other.scroll.Y);
|
||||
X += other.X;
|
||||
Y += other.Y;
|
||||
IsConnected |= other.IsConnected;
|
||||
|
@ -334,13 +296,29 @@ namespace OpenTK.Input
|
|||
IsConnected = value;
|
||||
}
|
||||
|
||||
#region Internal Members
|
||||
|
||||
internal void SetScrollAbsolute(float x, float y)
|
||||
{
|
||||
scroll.X = x;
|
||||
scroll.Y = y;
|
||||
}
|
||||
|
||||
internal void SetScrollRelative(float x, float y)
|
||||
{
|
||||
scroll.X += x;
|
||||
scroll.Y += y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Members
|
||||
|
||||
static void ValidateOffset(int offset)
|
||||
{
|
||||
if (offset < 0 || offset >= NumInts * IntSize)
|
||||
if (offset < 0 || offset >= 16)
|
||||
throw new ArgumentOutOfRangeException("offset");
|
||||
}
|
||||
|
||||
|
@ -355,18 +333,11 @@ namespace OpenTK.Input
|
|||
/// <returns>True, if both instances are equal; false otherwise.</returns>
|
||||
public bool Equals(MouseState other)
|
||||
{
|
||||
bool equal = true;
|
||||
unsafe
|
||||
{
|
||||
int* b2 = other.Buttons;
|
||||
fixed (int* b1 = Buttons)
|
||||
{
|
||||
for (int i = 0; equal && i < NumInts; i++)
|
||||
equal &= *(b1 + i) == *(b2 + i);
|
||||
}
|
||||
equal &= X == other.X && Y == other.Y && WheelPrecise == other.WheelPrecise;
|
||||
}
|
||||
return equal;
|
||||
return
|
||||
buttons == other.buttons &&
|
||||
X == other.X &&
|
||||
Y == other.Y &&
|
||||
Scroll == other.Scroll;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -798,6 +798,8 @@
|
|||
<Compile Include="WindowIcon.cs" />
|
||||
<Compile Include="Platform\MacOS\Cocoa\NSBitmapFormat.cs" />
|
||||
<Compile Include="Platform\NativeWindowBase.cs" />
|
||||
<Compile Include="Input\MouseScrollWheel.cs" />
|
||||
<Compile Include="Input\MouseEventArgs.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace OpenTK.Platform
|
|||
|
||||
window.MouseWheel += (sender, e) =>
|
||||
{
|
||||
mouse.WheelPrecise = e.Wheel.Y;
|
||||
mouse.WheelPrecise = e.Mouse.Scroll.Y;
|
||||
};
|
||||
|
||||
// Hook keyboard events
|
||||
|
|
|
@ -517,7 +517,9 @@ namespace OpenTK.Platform.MacOS
|
|||
MathHelper.Clamp((int)Math.Round(p.Y + dy), 0, Height));
|
||||
}
|
||||
|
||||
InputDriver.Mouse[0].Position = p;
|
||||
MouseState.X = p.X;
|
||||
MouseState.Y = p.Y;
|
||||
OnMouseMove();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -534,7 +536,8 @@ namespace OpenTK.Platform.MacOS
|
|||
factor = 1.0f / scrollFactor; // Problem: Don't know what factor to use here, but this seems to work.
|
||||
}
|
||||
|
||||
InputDriver.Mouse[0].WheelPrecise += scrollingDelta * factor;
|
||||
MouseState.SetScrollRelative(0, scrollingDelta * factor);
|
||||
OnMouseWheel();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -543,7 +546,8 @@ namespace OpenTK.Platform.MacOS
|
|||
case NSEventType.OtherMouseDown:
|
||||
{
|
||||
var buttonNumber = Cocoa.SendInt(e, selButtonNumber);
|
||||
InputDriver.Mouse[0][GetMouseButton(buttonNumber)] = true;
|
||||
MouseState[GetMouseButton(buttonNumber)] = true;
|
||||
OnMouseDown();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -552,7 +556,8 @@ namespace OpenTK.Platform.MacOS
|
|||
case NSEventType.OtherMouseUp:
|
||||
{
|
||||
var buttonNumber = Cocoa.SendInt(e, selButtonNumber);
|
||||
InputDriver.Mouse[0][GetMouseButton(buttonNumber)] = false;
|
||||
MouseState[GetMouseButton(buttonNumber)] = false;
|
||||
OnMouseUp();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -324,7 +324,7 @@ namespace OpenTK.Platform.MacOS
|
|||
break;
|
||||
|
||||
case HIDUsageGD.Wheel:
|
||||
mouse.State.WheelPrecise += v_int;
|
||||
mouse.State.SetScrollRelative(0, v_int);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -332,6 +332,15 @@ namespace OpenTK.Platform.MacOS
|
|||
case HIDPage.Button:
|
||||
mouse.State[OpenTK.Input.MouseButton.Left + usage - 1] = v_int == 1;
|
||||
break;
|
||||
|
||||
case HIDPage.Consumer:
|
||||
switch ((HIDUsageCD)usage)
|
||||
{
|
||||
case HIDUsageCD.ACPan:
|
||||
mouse.State.SetScrollRelative(v_int, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1107,6 +1116,12 @@ namespace OpenTK.Platform.MacOS
|
|||
VendorDefinedStart = 0xFF00
|
||||
}
|
||||
|
||||
// Consumer electronic devices
|
||||
enum HIDUsageCD
|
||||
{
|
||||
ACPan = 0x0238
|
||||
}
|
||||
|
||||
// Generic desktop usage
|
||||
enum HIDUsageGD
|
||||
{
|
||||
|
|
|
@ -40,22 +40,25 @@ namespace OpenTK.Platform
|
|||
{
|
||||
readonly LegacyInputDriver LegacyInputDriver;
|
||||
|
||||
readonly protected MouseButtonEventArgs MouseDownArgs = new MouseButtonEventArgs();
|
||||
readonly protected MouseButtonEventArgs MouseUpArgs = new MouseButtonEventArgs();
|
||||
readonly protected MouseMoveEventArgs MouseMoveArgs = new MouseMoveEventArgs();
|
||||
readonly protected MouseWheelEventArgs MouseWheelArgs = new MouseWheelEventArgs();
|
||||
readonly MouseButtonEventArgs MouseDownArgs = new MouseButtonEventArgs();
|
||||
readonly MouseButtonEventArgs MouseUpArgs = new MouseButtonEventArgs();
|
||||
readonly MouseMoveEventArgs MouseMoveArgs = new MouseMoveEventArgs();
|
||||
readonly MouseWheelEventArgs MouseWheelArgs = new MouseWheelEventArgs();
|
||||
|
||||
readonly protected KeyboardKeyEventArgs KeyDownArgs = new KeyboardKeyEventArgs();
|
||||
readonly protected KeyboardKeyEventArgs KeyUpArgs = new KeyboardKeyEventArgs();
|
||||
readonly protected KeyPressEventArgs KeyPressArgs = new KeyPressEventArgs((char)0);
|
||||
protected readonly KeyboardKeyEventArgs KeyDownArgs = new KeyboardKeyEventArgs();
|
||||
protected readonly KeyboardKeyEventArgs KeyUpArgs = new KeyboardKeyEventArgs();
|
||||
protected readonly KeyPressEventArgs KeyPressArgs = new KeyPressEventArgs((char)0);
|
||||
|
||||
// In order to simplify mouse event implementation,
|
||||
// we can store the current mouse state here.
|
||||
protected MouseState MouseState = new MouseState();
|
||||
MouseState PreviousMouseState = new MouseState();
|
||||
|
||||
internal NativeWindowBase()
|
||||
{
|
||||
LegacyInputDriver = new LegacyInputDriver(this);
|
||||
MouseState.SetIsConnected(true);
|
||||
PreviousMouseState.SetIsConnected(true);
|
||||
}
|
||||
|
||||
#region Protected Members
|
||||
|
@ -140,23 +143,75 @@ namespace OpenTK.Platform
|
|||
MouseEnter(this, e);
|
||||
}
|
||||
|
||||
protected void OnMouseDown(MouseButtonEventArgs e)
|
||||
protected void OnMouseDown()
|
||||
{
|
||||
MouseDown(this, e);
|
||||
var e = MouseDownArgs;
|
||||
e.Mouse = MouseState;
|
||||
|
||||
// Find which button caused this event
|
||||
for (MouseButton b = MouseButton.Left; b < MouseButton.LastButton; b++)
|
||||
{
|
||||
if (!PreviousMouseState[b] && MouseState[b])
|
||||
{
|
||||
e.Button = b;
|
||||
PreviousMouseState = MouseState;
|
||||
MouseDown(this, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.WriteLine("OnMouseDown called without pressing a button");
|
||||
}
|
||||
|
||||
protected void OnMouseUp(MouseButtonEventArgs e)
|
||||
protected void OnMouseUp()
|
||||
{
|
||||
MouseUp(this, e);
|
||||
var e = MouseUpArgs;
|
||||
e.Mouse = MouseState;
|
||||
|
||||
// Find which button caused this event
|
||||
for (MouseButton b = MouseButton.Left; b < MouseButton.LastButton; b++)
|
||||
{
|
||||
if (PreviousMouseState[b] && !MouseState[b])
|
||||
{
|
||||
e.Button = b;
|
||||
PreviousMouseState = MouseState;
|
||||
MouseUp(this, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.WriteLine("OnMouseUp called without pressing a button");
|
||||
}
|
||||
|
||||
protected void OnMouseMove(MouseMoveEventArgs e)
|
||||
protected void OnMouseMove()
|
||||
{
|
||||
var e = MouseMoveArgs;
|
||||
e.Mouse = MouseState;
|
||||
e.XDelta = MouseState.X - PreviousMouseState.X;
|
||||
e.YDelta = MouseState.Y - PreviousMouseState.Y;
|
||||
|
||||
if (e.XDelta == 0 && e.YDelta == 0)
|
||||
{
|
||||
Debug.WriteLine("OnMouseMove called without moving the mouse");
|
||||
}
|
||||
|
||||
PreviousMouseState = MouseState;
|
||||
MouseMove(this, e);
|
||||
}
|
||||
|
||||
protected void OnMouseWheel(MouseWheelEventArgs e)
|
||||
protected void OnMouseWheel()
|
||||
{
|
||||
var e = MouseWheelArgs;
|
||||
e.Mouse = MouseState;
|
||||
e.ValuePrecise = MouseState.Scroll.Y;
|
||||
e.DeltaPrecise = MouseState.Scroll.Y - PreviousMouseState.Scroll.Y;
|
||||
|
||||
if (e.DeltaPrecise == 0)
|
||||
{
|
||||
Debug.WriteLine("OnMouseWheel called without moving the mouse wheel.");
|
||||
}
|
||||
|
||||
PreviousMouseState = MouseState;
|
||||
MouseWheel(this, e);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace OpenTK.Platform.SDL2
|
|||
|
||||
public void ProcessWheelEvent(MouseWheelEvent wheel)
|
||||
{
|
||||
state.WheelPrecise += wheel.Y;
|
||||
state.SetScrollRelative(0, wheel.Y);
|
||||
}
|
||||
|
||||
public void ProcessMouseEvent(MouseMotionEvent motion)
|
||||
|
|
|
@ -221,21 +221,17 @@ namespace OpenTK.Platform.SDL2
|
|||
button_pressed ? true : false);
|
||||
}
|
||||
|
||||
var e = button_pressed ? window.MouseDownArgs : window.MouseUpArgs;
|
||||
e.Button = Sdl2Mouse.TranslateButton(ev.Button);
|
||||
e.IsPressed = button_pressed;
|
||||
e.X = ev.X;
|
||||
e.Y = ev.Y;
|
||||
e.Wheel.X = window.MouseWheelArgs.Wheel.X;
|
||||
e.Wheel.Y = window.MouseWheelArgs.Wheel.Y;
|
||||
window.MouseState[Sdl2Mouse.TranslateButton(ev.Button)] = button_pressed;
|
||||
window.MouseState.X = ev.X;
|
||||
window.MouseState.Y = ev.Y;
|
||||
|
||||
if (button_pressed)
|
||||
{
|
||||
window.OnMouseDown(e);
|
||||
window.OnMouseDown();
|
||||
}
|
||||
else
|
||||
{
|
||||
window.OnMouseUp(e);
|
||||
window.OnMouseUp();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,29 +289,15 @@ namespace OpenTK.Platform.SDL2
|
|||
static void ProcessMouseMotionEvent(Sdl2NativeWindow window, MouseMotionEvent ev)
|
||||
{
|
||||
//float scale = window.ClientSize.Width / (float)window.Size.Width;
|
||||
var e = window.MouseMoveArgs;
|
||||
e.X = ev.X;
|
||||
e.Y = ev.Y;
|
||||
SetMouseButtons(e, ev.State);
|
||||
window.OnMouseMove(e);
|
||||
}
|
||||
|
||||
static void SetMouseButtons(MouseEventArgs e, ButtonFlags buttons)
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
// Note: OpenTK MouseButton is identical to SDL2 Button
|
||||
bool pressed = ((int)buttons & (1 << i)) != 0;
|
||||
e.SetButton((MouseButton)i, pressed ? ButtonState.Pressed : ButtonState.Released);
|
||||
}
|
||||
window.MouseState.X = ev.X;
|
||||
window.MouseState.Y = ev.Y;
|
||||
window.OnMouseMove();
|
||||
}
|
||||
|
||||
static void ProcessMouseWheelEvent(Sdl2NativeWindow window, MouseWheelEvent ev)
|
||||
{
|
||||
var e = window.MouseWheelArgs;
|
||||
e.Wheel.Y = ev.Y;
|
||||
e.Wheel.X = ev.X;
|
||||
window.OnMouseWheel(e);
|
||||
window.MouseState.SetScrollRelative(ev.X, ev.Y);
|
||||
window.OnMouseWheel();
|
||||
}
|
||||
|
||||
static void ProcessWindowEvent(Sdl2NativeWindow window, WindowEvent e)
|
||||
|
|
|
@ -3591,7 +3591,8 @@ namespace OpenTK.Platform.Windows
|
|||
BUTTON_5_DOWN = 0x0100,
|
||||
BUTTON_5_UP = 0x0200,
|
||||
|
||||
WHEEL = 0x0400
|
||||
WHEEL = 0x0400,
|
||||
HWHEEL = 0x0800,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -437,8 +437,9 @@ namespace OpenTK.Platform.Windows
|
|||
if (points == 0 || (points == -1 && lastError == Constants.ERROR_POINT_NOT_FOUND))
|
||||
{
|
||||
// Just use the mouse move position
|
||||
MouseMoveArgs.Position = point;
|
||||
OnMouseMove(MouseMoveArgs);
|
||||
MouseState.X = point.X;
|
||||
MouseState.Y = point.Y;
|
||||
OnMouseMove();
|
||||
}
|
||||
else if (points == -1)
|
||||
{
|
||||
|
@ -476,8 +477,9 @@ namespace OpenTK.Platform.Windows
|
|||
position.Y -= 65536;
|
||||
}
|
||||
Functions.ScreenToClient(handle, ref position);
|
||||
MouseMoveArgs.Position = position;
|
||||
OnMouseMove(MouseMoveArgs);
|
||||
MouseState.X = position.X;
|
||||
MouseState.Y = position.Y;
|
||||
OnMouseMove();
|
||||
}
|
||||
}
|
||||
mouse_last_timestamp = timestamp;
|
||||
|
@ -506,40 +508,37 @@ namespace OpenTK.Platform.Windows
|
|||
{
|
||||
// This is due to inconsistent behavior of the WParam value on 64bit arch, whese
|
||||
// wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000
|
||||
MouseWheelArgs.Wheel.Y += ((long)wParam << 32 >> 48) / 120.0f;
|
||||
OnMouseWheel(MouseWheelArgs);
|
||||
MouseState.SetScrollRelative(0, ((long)wParam << 32 >> 48) / 120.0f);
|
||||
OnMouseWheel();
|
||||
}
|
||||
|
||||
void HandleMouseHWheel(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
// This is due to inconsistent behavior of the WParam value on 64bit arch, whese
|
||||
// wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000
|
||||
MouseWheelArgs.Wheel.X += ((long)wParam << 32 >> 48) / 120.0f;
|
||||
OnMouseWheel(MouseWheelArgs);
|
||||
MouseState.SetScrollRelative(((long)wParam << 32 >> 48) / 120.0f, 0);
|
||||
OnMouseWheel();
|
||||
}
|
||||
|
||||
void HandleLButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
Functions.SetCapture(window.Handle);
|
||||
MouseDownArgs.Button = MouseButton.Left;
|
||||
MouseDownArgs.IsPressed = true;
|
||||
OnMouseDown(MouseDownArgs);
|
||||
MouseState[MouseButton.Left] = true;
|
||||
OnMouseDown();
|
||||
}
|
||||
|
||||
void HandleMButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
Functions.SetCapture(window.Handle);
|
||||
MouseDownArgs.Button = MouseButton.Middle;
|
||||
MouseDownArgs.IsPressed = true;
|
||||
OnMouseDown(MouseDownArgs);
|
||||
MouseState[MouseButton.Middle] = true;
|
||||
OnMouseDown();
|
||||
}
|
||||
|
||||
void HandleRButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
Functions.SetCapture(window.Handle);
|
||||
MouseDownArgs.Button = MouseButton.Right;
|
||||
MouseDownArgs.IsPressed = true;
|
||||
OnMouseDown(MouseDownArgs);
|
||||
MouseState[MouseButton.Right] = true;
|
||||
OnMouseDown();
|
||||
}
|
||||
|
||||
void HandleXButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
|
@ -548,33 +547,29 @@ namespace OpenTK.Platform.Windows
|
|||
MouseButton button =
|
||||
((wParam.ToInt32() & 0xFFFF0000) >> 16) == 1 ?
|
||||
MouseButton.Button1 : MouseButton.Button2;
|
||||
MouseDownArgs.Button = button;
|
||||
MouseDownArgs.IsPressed = true;
|
||||
OnMouseDown(MouseDownArgs);
|
||||
MouseState[button] = true;
|
||||
OnMouseDown();
|
||||
}
|
||||
|
||||
void HandleLButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
Functions.ReleaseCapture();
|
||||
MouseDownArgs.Button = MouseButton.Left;
|
||||
MouseDownArgs.IsPressed = false;
|
||||
OnMouseUp(MouseUpArgs);
|
||||
MouseState[MouseButton.Left] = false;
|
||||
OnMouseUp();
|
||||
}
|
||||
|
||||
void HandleMButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
Functions.ReleaseCapture();
|
||||
MouseDownArgs.Button = MouseButton.Middle;
|
||||
MouseDownArgs.IsPressed = false;
|
||||
OnMouseUp(MouseUpArgs);
|
||||
MouseState[MouseButton.Middle] = false;
|
||||
OnMouseUp();
|
||||
}
|
||||
|
||||
void HandleRButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
Functions.ReleaseCapture();
|
||||
MouseDownArgs.Button = MouseButton.Right;
|
||||
MouseDownArgs.IsPressed = false;
|
||||
OnMouseUp(MouseUpArgs);
|
||||
MouseState[MouseButton.Right] = false;
|
||||
OnMouseUp();
|
||||
}
|
||||
|
||||
void HandleXButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
|
@ -583,9 +578,8 @@ namespace OpenTK.Platform.Windows
|
|||
MouseButton button =
|
||||
((wParam.ToInt32() & 0xFFFF0000) >> 16) == 1 ?
|
||||
MouseButton.Button1 : MouseButton.Button2;
|
||||
MouseDownArgs.Button = button;
|
||||
MouseDownArgs.IsPressed = false;
|
||||
OnMouseUp(MouseUpArgs);
|
||||
MouseState[button] = false;
|
||||
OnMouseUp();
|
||||
}
|
||||
|
||||
void HandleKeyboard(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
|
|
|
@ -227,7 +227,10 @@ namespace OpenTK.Platform.Windows
|
|||
}
|
||||
|
||||
if ((raw.ButtonFlags & RawInputMouseState.WHEEL) != 0)
|
||||
mouse.WheelPrecise += (short)raw.ButtonData / 120.0f;
|
||||
mouse.SetScrollRelative(0, (short)raw.ButtonData / 120.0f);
|
||||
|
||||
if ((raw.ButtonFlags & RawInputMouseState.HWHEEL) != 0)
|
||||
mouse.SetScrollRelative((short)raw.ButtonData / 120.0f, 0);
|
||||
|
||||
if ((raw.Flags & RawMouseFlags.MOUSE_MOVE_ABSOLUTE) != 0)
|
||||
{
|
||||
|
|
|
@ -204,8 +204,8 @@ namespace OpenTK.Platform.X11
|
|||
case 1: state.EnableBit((int)MouseButton.Left); break;
|
||||
case 2: state.EnableBit((int)MouseButton.Middle); break;
|
||||
case 3: state.EnableBit((int)MouseButton.Right); break;
|
||||
case 4: state.WheelPrecise++; break;
|
||||
case 5: state.WheelPrecise--; break;
|
||||
case 4: state.SetScrollRelative(0, 1); break;
|
||||
case 5: state.SetScrollRelative(0, -1); break;
|
||||
case 6: state.EnableBit((int)MouseButton.Button1); break;
|
||||
case 7: state.EnableBit((int)MouseButton.Button2); break;
|
||||
case 8: state.EnableBit((int)MouseButton.Button3); break;
|
||||
|
|
Loading…
Reference in a new issue