Skip to content

Commit

Permalink
Horizontal scroll (MonoGame#5735)
Browse files Browse the repository at this point in the history
* Horizontal Scroll Wheel Value

This change adds a HorizontalScrollWheelValue property to the MouseState and sets it for the UI systems mentioned below.

- WinForms
- SDL
- Win8/Universal

* HorizontalScrollWheelValue for MacOS

* Fixing Horizontal Mouse Wheel based on PR review

- Declaring and using a _horzontalScrollWheelValue as backing field
- No longer delegating MouseState constructor with this
- Removing functions that mimicked Microsoft macros since they are simply casts and bitwise operations used once
  • Loading branch information
gsfreema authored and KonajuGames committed Jul 8, 2017
1 parent 16e2dc7 commit 47a47c9
Show file tree
Hide file tree
Showing 11 changed files with 194 additions and 57 deletions.
3 changes: 3 additions & 0 deletions Build/Projects/MonoGame.Framework.definition
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,9 @@


<!-- Windows Desktop Platfom -->
<Compile Include="Windows\HorizontalMouseWheelEventArgs.cs">
<Platforms>Windows</Platforms>
</Compile>
<Compile Include="Windows\WinFormsGameForm.cs">
<Platforms>Windows</Platforms>
</Compile>
Expand Down
2 changes: 2 additions & 0 deletions MonoGame.Framework/Input/Mouse.MacOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public static partial class Mouse
#endif

internal static GameWindow Window;
internal static float HorizontalScrollWheelValue;
internal static float ScrollWheelValue;

private static IntPtr PlatformGetHandle()
Expand All @@ -44,6 +45,7 @@ private static IntPtr PlatformGetHandle()
private static MouseState PlatformGetState(GameWindow window)
{
//We need to maintain precision...
window.MouseState.HorizontalScrollWheelValue = (int)HorizontalScrollWheelValue;
window.MouseState.ScrollWheelValue = (int)ScrollWheelValue;

return window.MouseState;
Expand Down
2 changes: 2 additions & 0 deletions MonoGame.Framework/Input/Mouse.SDL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Microsoft.Xna.Framework.Input
{
public static partial class Mouse
{
internal static int ScrollX;
internal static int ScrollY;

private static IntPtr PlatformGetHandle()
Expand All @@ -32,6 +33,7 @@ private static MouseState PlatformGetState(GameWindow window)
window.MouseState.XButton1 = (state & Sdl.Mouse.Button.X1Mask) != 0 ? ButtonState.Pressed : ButtonState.Released;
window.MouseState.XButton2 = (state & Sdl.Mouse.Button.X2Mask) != 0 ? ButtonState.Pressed : ButtonState.Released;

window.MouseState.HorizontalScrollWheelValue = ScrollX;
window.MouseState.ScrollWheelValue = ScrollY;
}

Expand Down
111 changes: 80 additions & 31 deletions MonoGame.Framework/Input/MouseState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@
// file 'LICENSE.txt', which is part of this source code package.

namespace Microsoft.Xna.Framework.Input
{
{
/// <summary>
/// Represents a mouse state with cursor position and button press information.
/// </summary>
public struct MouseState
{
int _x, _y;
int _scrollWheelValue;
ButtonState _leftButton;
ButtonState _rightButton;
ButtonState _middleButton;
public struct MouseState
{
int _x, _y;
int _scrollWheelValue;
ButtonState _leftButton;
ButtonState _rightButton;
ButtonState _middleButton;
ButtonState _xButton1;
ButtonState _xButton2;

ButtonState _xButton2;
int _horizontalScrollWheelValue;

/// <summary>
/// Initializes a new instance of the MouseState.
/// </summary>
Expand All @@ -29,25 +30,61 @@ public struct MouseState
/// <param name="xButton1">XBUTTON1's state.</param>
/// <param name="xButton2">XBUTTON2's state.</param>
/// <remarks>Normally <see cref="Mouse.GetState()"/> should be used to get mouse current state. The constructor is provided for simulating mouse input.</remarks>
public MouseState (
int x,
int y,
int scrollWheel,
ButtonState leftButton,
ButtonState middleButton,
ButtonState rightButton,
ButtonState xButton1,
ButtonState xButton2)
{
_x = x;
_y = y;
_scrollWheelValue = scrollWheel;
_leftButton = leftButton;
_middleButton = middleButton;
_rightButton = rightButton;
public MouseState(
int x,
int y,
int scrollWheel,
ButtonState leftButton,
ButtonState middleButton,
ButtonState rightButton,
ButtonState xButton1,
ButtonState xButton2)
{
_x = x;
_y = y;
_scrollWheelValue = scrollWheel;
_leftButton = leftButton;
_middleButton = middleButton;
_rightButton = rightButton;
_xButton1 = xButton1;
_xButton2 = xButton2;
}
_xButton2 = xButton2;
_horizontalScrollWheelValue = 0;
}

/// <summary>
/// Initializes a new instance of the MouseState.
/// </summary>
/// <param name="x">Horizontal position of the mouse in relation to the window.</param>
/// <param name="y">Vertical position of the mouse in relation to the window.</param>
/// <param name="scrollWheel">Mouse scroll wheel's value.</param>
/// <param name="leftButton">Left mouse button's state.</param>
/// <param name="middleButton">Middle mouse button's state.</param>
/// <param name="rightButton">Right mouse button's state.</param>
/// <param name="xButton1">XBUTTON1's state.</param>
/// <param name="xButton2">XBUTTON2's state.</param>
/// <param name="horizontalScrollWheel">Mouse horizontal scroll wheel's value.</param>
/// <remarks>Normally <see cref="Mouse.GetState()"/> should be used to get mouse current state. The constructor is provided for simulating mouse input.</remarks>
public MouseState(
int x,
int y,
int scrollWheel,
ButtonState leftButton,
ButtonState middleButton,
ButtonState rightButton,
ButtonState xButton1,
ButtonState xButton2,
int horizontalScrollWheel)
{
_x = x;
_y = y;
_scrollWheelValue = scrollWheel;
_leftButton = leftButton;
_middleButton = middleButton;
_rightButton = rightButton;
_xButton1 = xButton1;
_xButton2 = xButton2;
_horizontalScrollWheelValue = horizontalScrollWheel;
}

/// <summary>
/// Compares whether two MouseState instances are equal.
Expand All @@ -62,7 +99,8 @@ public MouseState (
left._leftButton == right._leftButton &&
left._middleButton == right._middleButton &&
left._rightButton == right._rightButton &&
left._scrollWheelValue == right._scrollWheelValue &&
left._scrollWheelValue == right._scrollWheelValue &&
left._horizontalScrollWheelValue == right._horizontalScrollWheelValue &&
left._xButton1 == right._xButton1 &&
left._xButton2 == right._xButton2;
}
Expand Down Expand Up @@ -100,7 +138,8 @@ public override int GetHashCode()
{
var hashCode = _x;
hashCode = (hashCode*397) ^ _y;
hashCode = (hashCode*397) ^ _scrollWheelValue;
hashCode = (hashCode*397) ^ _scrollWheelValue;
hashCode = (hashCode*397) ^ _horizontalScrollWheelValue;
hashCode = (hashCode*397) ^ (int) _leftButton;
hashCode = (hashCode*397) ^ (int) _rightButton;
hashCode = (hashCode*397) ^ (int) _middleButton;
Expand Down Expand Up @@ -179,7 +218,17 @@ public int ScrollWheelValue {
return _scrollWheelValue;
}
internal set { _scrollWheelValue = value; }
}
}

/// <summary>
/// Returns the cumulative horizontal scroll wheel value since the game start
/// </summary>
public int HorizontalScrollWheelValue {
get {
return _horizontalScrollWheelValue;
}
internal set { _horizontalScrollWheelValue = value; }
}

/// <summary>
/// Gets state of the XButton1.
Expand Down
30 changes: 18 additions & 12 deletions MonoGame.Framework/MacOS/GameWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -693,22 +693,28 @@ public override void ScrollWheel (NSEvent theEvent)
UpdateMousePosition (loc);
switch (theEvent.Type)
{
case NSEventType.ScrollWheel:
if (theEvent.ScrollingDeltaY != 0)
{
if (theEvent.ScrollingDeltaY > 0)
{
Mouse.ScrollWheelValue += (float)(theEvent.ScrollingDeltaY * 0.1f + 0.09f) * 1200;
}
else
{
Mouse.ScrollWheelValue += (float)(theEvent.ScrollingDeltaY * 0.1f - 0.09f) * 1200;
}
}
case NSEventType.ScrollWheel:
Mouse.HorizontalScrollWheelValue += CalculateScrollWheelValue(theEvent.ScrollingDeltaX);
Mouse.ScrollWheelValue += CalculateScrollWheelValue(theEvent.ScrollingDeltaY);
break;
}
}

private static float CalculateScrollWheelValue(nfloat delta)
{
var scrollWheelValue = 0.0f;

if (delta != 0)
{
if (delta > 0)
scrollWheelValue += (float)(delta * 0.1f + 0.09f) * 1200;
else
scrollWheelValue += (float)(delta * 0.1f - 0.09f) * 1200;
}

return scrollWheelValue;
}

public override void MouseMoved (NSEvent theEvent)
{
PointF loc = theEvent.LocationInWindow;
Expand Down
9 changes: 6 additions & 3 deletions MonoGame.Framework/SDL/SDLGamePlatform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,12 @@ private void SdlRunLoop()
else if (ev.Type == Sdl.EventType.ControllerDeviceRemoved)
GamePad.RemoveDevice(ev.ControllerDevice.Which);
else if (ev.Type == Sdl.EventType.JoyDeviceRemoved)
Joystick.RemoveDevice(ev.JoystickDevice.Which);
else if (ev.Type == Sdl.EventType.MouseWheel)
Mouse.ScrollY += ev.Wheel.Y * 120;
Joystick.RemoveDevice(ev.JoystickDevice.Which);
else if (ev.Type == Sdl.EventType.MouseWheel) {
const int wheelDelta = 120;
Mouse.ScrollY += ev.Wheel.Y * wheelDelta;
Mouse.ScrollX += ev.Wheel.X * wheelDelta;
}
else if (ev.Type == Sdl.EventType.KeyDown) {
var key = KeyboardUtil.ToXna (ev.Key.Keysym.Sym);
if (!_keys.Contains (key))
Expand Down
14 changes: 14 additions & 0 deletions MonoGame.Framework/Windows/HorizontalMouseWheelEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;

namespace Microsoft.Xna.Framework.Windows
{
internal class HorizontalMouseWheelEventArgs : EventArgs
{
internal int Delta { get; private set; }

internal HorizontalMouseWheelEventArgs(int delta)
{
Delta = delta;
}
}
}
16 changes: 16 additions & 0 deletions MonoGame.Framework/Windows/WinFormsGameForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public static System.Drawing.Point GetPointerLocation(this Message msg)
internal class WinFormsGameForm : Form
{
GameWindow _window;
public const int WM_MOUSEHWHEEL = 0x020E;
public const int WM_POINTERUP = 0x0247;
public const int WM_POINTERDOWN = 0x0246;
public const int WM_POINTERUPDATE = 0x0245;
Expand All @@ -42,6 +43,12 @@ internal class WinFormsGameForm : Form

public bool AllowAltF4 = true;

#region Events

public event EventHandler<HorizontalMouseWheelEventArgs> MouseHorizontalWheel;

#endregion

public WinFormsGameForm(GameWindow window)
{
_window = window;
Expand Down Expand Up @@ -122,6 +129,15 @@ protected override void WndProc(ref Message m)
case WM_POINTERUPDATE:
state = TouchLocationState.Moved;
break;

case WM_MOUSEHWHEEL:
var delta = (short)(((ulong)m.WParam >> 16) & 0xffff); ;
var handler = MouseHorizontalWheel;

if (handler != null)
handler(this, new HorizontalMouseWheelEventArgs(delta));

break;
}

if (state != TouchLocationState.Invalid)
Expand Down
6 changes: 6 additions & 0 deletions MonoGame.Framework/Windows/WinFormsGameWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ internal WinFormsGameWindow(WinFormsGamePlatform platform)

// Capture mouse events.
Form.MouseWheel += OnMouseScroll;
Form.MouseHorizontalWheel += OnMouseHorizontalScroll;
Form.MouseEnter += OnMouseEnter;
Form.MouseLeave += OnMouseLeave;

Expand Down Expand Up @@ -222,6 +223,11 @@ private void OnMouseScroll(object sender, MouseEventArgs mouseEventArgs)
MouseState.ScrollWheelValue += mouseEventArgs.Delta;
}

private void OnMouseHorizontalScroll(object sender, HorizontalMouseWheelEventArgs mouseEventArgs)
{
MouseState.HorizontalScrollWheelValue += mouseEventArgs.Delta;
}

private void UpdateMouseState()
{
// If we call the form client functions before the form has
Expand Down
15 changes: 12 additions & 3 deletions MonoGame.Framework/Windows8/InputEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,13 +216,22 @@ private static void UpdateMouse(PointerPoint point)

var state = point.Properties;

Mouse.PrimaryWindow.MouseState = new MouseState(x, y,
Mouse.PrimaryWindow.MouseState.ScrollWheelValue + state.MouseWheelDelta,
int verticalScrollDelta = 0;
int horizontalScrollDelta = 0;

if (state.IsHorizontalMouseWheel)
horizontalScrollDelta = state.MouseWheelDelta;
else
verticalScrollDelta = state.MouseWheelDelta;

Mouse.PrimaryWindow.MouseState = new MouseState(x, y,
Mouse.PrimaryWindow.MouseState.ScrollWheelValue + verticalScrollDelta,
state.IsLeftButtonPressed ? ButtonState.Pressed : ButtonState.Released,
state.IsMiddleButtonPressed ? ButtonState.Pressed : ButtonState.Released,
state.IsRightButtonPressed ? ButtonState.Pressed : ButtonState.Released,
state.IsXButton1Pressed ? ButtonState.Pressed : ButtonState.Released,
state.IsXButton2Pressed ? ButtonState.Pressed : ButtonState.Released);
state.IsXButton2Pressed ? ButtonState.Pressed : ButtonState.Released,
Mouse.PrimaryWindow.MouseState.HorizontalScrollWheelValue + horizontalScrollDelta);
}

public void UpdateState()
Expand Down
Loading

0 comments on commit 47a47c9

Please sign in to comment.