[Platform] Added support for horizontal wheel

This commit is contained in:
thefiddler 2014-05-03 16:47:03 +02:00
parent 842c0499b9
commit e85377c350
8 changed files with 154 additions and 61 deletions

View file

@ -26,6 +26,10 @@ namespace Examples.Tests
bool mouse_in_window = false;
bool viewport_changed = true;
// mouse information
Vector4 mouse_pos;
int mouse_buttons;
// time drift
Stopwatch watch = new Stopwatch();
double update_time, render_time;
@ -57,6 +61,7 @@ namespace Examples.Tests
MouseLeave += delegate { mouse_in_window = false; };
Mouse.Move += MouseMoveHandler;
Mouse.WheelChanged += MouseWheelHandler;
Mouse.ButtonDown += MouseButtonHandler;
Mouse.ButtonUp += MouseButtonHandler;
}
@ -119,6 +124,10 @@ namespace Examples.Tests
void MouseMoveHandler(object sender, MouseMoveEventArgs e)
{
mouse_pos.X = e.X;
mouse_pos.Y = e.Y;
mouse_pos.Z = e.Wheel.X;
mouse_pos.W = e.Wheel.Y;
}
void MouseButtonHandler(object sender, MouseButtonEventArgs e)
@ -127,6 +136,21 @@ namespace Examples.Tests
{
CursorVisible = false;
}
if (e.IsPressed)
{
mouse_buttons |= 1 << (int)e.Button;
}
else
{
mouse_buttons &= ~(1 << (int)e.Button);
}
}
void MouseWheelHandler(object sender, MouseWheelEventArgs e)
{
mouse_pos.Z += e.Wheel.Y;
mouse_pos.W += e.Wheel.X;
}
static int Clamp(int val, int min, int max)
@ -201,6 +225,40 @@ namespace Examples.Tests
return line;
}
int DrawMouseDevice(Graphics gfx, int line)
{
StringBuilder sb = new StringBuilder();
sb.Append("MouseDevice: ");
sb.Append(new Vector3(Mouse.X, Mouse.Y, Mouse.Wheel));
sb.Append(" ");
for (var i = MouseButton.Left; i < MouseButton.LastButton; i++)
{
if (Mouse[i])
{
sb.Append(i);
sb.Append(" ");
}
}
sb.AppendLine();
DrawString(gfx, sb.ToString(), line++);
sb.Remove(0, sb.Length);
sb.Append("Mouse events: ");
sb.Append(mouse_pos);
sb.Append(" ");
for (var i = MouseButton.Left; i < MouseButton.LastButton; i++)
{
if ((mouse_buttons & (1 << (int)i)) != 0)
{
sb.Append(i);
sb.Append(" ");
}
}
sb.AppendLine();
DrawString(gfx, sb.ToString(), line++);
return line;
}
static int DrawLegacyJoysticks(Graphics gfx, IList<JoystickDevice> joysticks, int line)
{
line++;
@ -267,7 +325,8 @@ namespace Examples.Tests
mouse_in_window ? "inside" : "outside",
CursorVisible ? "visible" : "hidden",
Focused ? "Focused" : "Not focused"), line++);
DrawString(gfx, String.Format("Mouse coordinates: {0}", new Vector3(Mouse.X, Mouse.Y, Mouse.WheelPrecise)), line++);
line = DrawMouseDevice(gfx, line);
// Timing information
line++;

View file

@ -362,6 +362,24 @@ 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>
@ -390,6 +408,7 @@ namespace OpenTK.Input
/// </summary>
public MouseEventArgs()
{
Wheel = new MouseWheel();
}
/// <summary>
@ -416,7 +435,7 @@ namespace OpenTK.Input
#region Protected Members
protected internal void SetButton(MouseButton button, ButtonState state)
internal void SetButton(MouseButton button, ButtonState state)
{
if (button < 0 || button > MouseButton.LastButton)
throw new ArgumentOutOfRangeException();
@ -433,7 +452,7 @@ namespace OpenTK.Input
}
}
protected internal ButtonState GetButton(MouseButton button)
internal ButtonState GetButton(MouseButton button)
{
if (button < 0 || button > MouseButton.LastButton)
throw new ArgumentOutOfRangeException();
@ -458,21 +477,9 @@ namespace OpenTK.Input
public int Y { get { return y; } internal set { y = value; } }
/// <summary>
/// Gets the offset of the horizontal wheel, if one exists.
/// Gets the status of the mouse wheel.
/// </summary>
public float WheelX { get; internal set; }
/// <summary>
/// Gets the offset of the vertical wheel, if one exists.
/// </summary>
public float WheelY { get; internal set; }
/// <summary>
/// Gets the offset of the vertical wheel, if one exists.
/// This is an alias to <see cref="MouseEventArgs.WheelY"/>
/// </summary>
/// <value>The wheel.</value>
public float Wheel { get { return WheelY; } internal set { WheelY = value; } }
public MouseWheel Wheel { get; private set; }
/// <summary>
/// Gets the <see cref="ButtonState"/> of the left mouse button.
@ -705,7 +712,7 @@ namespace OpenTK.Input
public MouseWheelEventArgs(int x, int y, int value, int delta)
: base(x, y)
{
WheelY = value;
Wheel.Y = value;
this.delta = delta;
}
@ -726,7 +733,7 @@ namespace OpenTK.Input
/// 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(WheelY, MidpointRounding.AwayFromZero); } }
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.
@ -737,7 +744,7 @@ namespace OpenTK.Input
/// <summary>
/// Gets the precise value of the wheel in floating-point units.
/// </summary>
public float ValuePrecise { get { return WheelY; } internal set { WheelY = value; } }
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.

View file

@ -78,7 +78,7 @@ namespace OpenTK.Platform
window.MouseWheel += (sender, e) =>
{
mouse.WheelPrecise = e.WheelY;
mouse.WheelPrecise = e.Wheel.Y;
};
// Hook keyboard events

View file

@ -49,6 +49,10 @@ namespace OpenTK.Platform
readonly protected KeyboardKeyEventArgs KeyUpArgs = new KeyboardKeyEventArgs();
readonly protected 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();
internal NativeWindowBase()
{
LegacyInputDriver = new LegacyInputDriver(this);

View file

@ -33,28 +33,18 @@ using OpenTK.Input;
namespace OpenTK.Platform.SDL2
{
class Sdl2Mouse : IMouseDriver2, IMouseDriver
class Sdl2Mouse : IMouseDriver2
{
MouseState state;
readonly List<MouseDevice> mice =
new List<MouseDevice>();
readonly IList<MouseDevice> mice_readonly;
public Sdl2Mouse()
{
state.IsConnected = true;
mice.Add(new MouseDevice());
mice[0].Description = "Standard mouse";
mice[0].NumberOfButtons = 3;
mice[0].NumberOfWheels = 1;
mice_readonly = mice.AsReadOnly();
}
#region Private Members
MouseButton TranslateButton(Button button)
static internal MouseButton TranslateButton(Button button)
{
switch (button)
{
@ -98,33 +88,18 @@ namespace OpenTK.Platform.SDL2
public void ProcessWheelEvent(MouseWheelEvent wheel)
{
state.WheelPrecise += wheel.Y;
mice[0].WheelPrecise += wheel.Y;
}
public void ProcessMouseEvent(MouseMotionEvent motion)
{
state.X += motion.Xrel;
state.Y += motion.Yrel;
mice[0].Position = new Point(motion.X, motion.Y);
}
public void ProcessMouseEvent(MouseButtonEvent button)
{
bool pressed = button.State == State.Pressed;
SetButtonState(TranslateButton(button.Button), pressed);
mice[0][TranslateButton(button.Button)] = pressed;
}
#endregion
#region IMouseDriver Members
public IList<MouseDevice> Mouse
{
get
{
return mice_readonly;
}
}
#endregion

View file

@ -175,7 +175,7 @@ namespace OpenTK.Platform.SDL2
case EventType.MOUSEBUTTONUP:
if (windows.TryGetValue(ev.Button.WindowID, out window))
{
ProcessButtonEvent(window, ev);
ProcessMouseButtonEvent(window, ev.Button);
processed = true;
}
break;
@ -183,7 +183,7 @@ namespace OpenTK.Platform.SDL2
case EventType.MOUSEMOTION:
if (windows.TryGetValue(ev.Motion.WindowID, out window))
{
ProcessMotionEvent(window, ev);
ProcessMouseMotionEvent(window, ev.Motion);
processed = true;
}
break;
@ -191,7 +191,7 @@ namespace OpenTK.Platform.SDL2
case EventType.MOUSEWHEEL:
if (windows.TryGetValue(ev.Wheel.WindowID, out window))
{
ProcessWheelEvent(window, ev);
ProcessMouseWheelEvent(window, ev.Wheel);
processed = true;
}
break;
@ -209,9 +209,9 @@ namespace OpenTK.Platform.SDL2
return processed ? 0 : 1;
}
static void ProcessButtonEvent(Sdl2NativeWindow window, Event ev)
static void ProcessMouseButtonEvent(Sdl2NativeWindow window, MouseButtonEvent ev)
{
bool button_pressed = ev.Button.State == State.Pressed;
bool button_pressed = ev.State == State.Pressed;
// We need MouseUp events to be reported even if they occur
// outside the window. SetWindowGrab ensures we get them.
@ -220,6 +220,23 @@ namespace OpenTK.Platform.SDL2
SDL.SetWindowGrab(window.window.Handle,
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;
if (button_pressed)
{
window.OnMouseDown(e);
}
else
{
window.OnMouseUp(e);
}
}
static void ProcessKeyEvent(Sdl2NativeWindow window, Event ev)
@ -273,16 +290,32 @@ namespace OpenTK.Platform.SDL2
}
}
static void ProcessMotionEvent(Sdl2NativeWindow window, Event ev)
static void ProcessMouseMotionEvent(Sdl2NativeWindow window, MouseMotionEvent ev)
{
float scale = window.ClientSize.Width / (float)window.Size.Width;
//window.mouse.Position = new Point(
// (int)(ev.motion.x * scale), (int)(ev.motion.y * scale));
//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 ProcessWheelEvent(Sdl2NativeWindow window, Event ev)
static void SetMouseButtons(MouseEventArgs e, ButtonFlags buttons)
{
//window.mouse.Wheel += ev.wheel.y;
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);
}
}
static void ProcessMouseWheelEvent(Sdl2NativeWindow window, MouseWheelEvent ev)
{
var e = window.MouseWheelArgs;
e.Wheel.Y = ev.Y;
e.Wheel.X = ev.X;
window.OnMouseWheel(e);
}
static void ProcessWindowEvent(Sdl2NativeWindow window, WindowEvent e)

View file

@ -4197,7 +4197,6 @@ namespace OpenTK.Platform.Windows
MBUTTONUP = 0x0208,
MBUTTONDBLCLK = 0x0209,
MOUSEWHEEL = 0x020A,
MOUSELAST = 0x020D,
/// <summary>
/// Windows 2000 and higher only.
/// </summary>
@ -4210,6 +4209,10 @@ namespace OpenTK.Platform.Windows
/// Windows 2000 and higher only.
/// </summary>
XBUTTONDBLCLK = 0x020D,
/// <summary>
/// Windows Vista and higher only.
/// </summary>
MOUSEHWHEEL = 0x020E,
PARENTNOTIFY = 0x0210,
ENTERMENULOOP = 0x0211,
EXITMENULOOP = 0x0212,

View file

@ -506,7 +506,15 @@ 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 += ((long)wParam << 32 >> 48) / 120.0f;
MouseWheelArgs.Wheel.Y += ((long)wParam << 32 >> 48) / 120.0f;
OnMouseWheel(MouseWheelArgs);
}
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);
}
@ -729,6 +737,10 @@ namespace OpenTK.Platform.Windows
HandleMouseWheel(handle, message, wParam, lParam);
break;
case WindowMessage.MOUSEHWHEEL:
HandleMouseHWheel(handle, message, wParam, lParam);
break;
case WindowMessage.LBUTTONDOWN:
HandleLButtonDown(handle, message, wParam, lParam);
break;