From f07fb57e98fd6622825995d812e37cf2c2137a16 Mon Sep 17 00:00:00 2001 From: teinarss Date: Mon, 6 May 2019 19:34:03 +0200 Subject: [PATCH] Rework relative mouse events. --- OpenRA.Game/Input/IInputHandler.cs | 6 ++--- OpenRA.Game/Widgets/Widget.cs | 4 +-- .../SupportPowers/SelectDirectionalTarget.cs | 18 ++++++++----- .../Widgets/EditorViewportControllerWidget.cs | 2 +- .../Widgets/ProductionTabsWidget.cs | 2 +- .../Widgets/ScrollPanelWidget.cs | 2 +- .../Widgets/ViewportControllerWidget.cs | 2 +- OpenRA.Platforms.Default/Sdl2Input.cs | 25 +++++++++++-------- .../Sdl2PlatformWindow.cs | 11 +++++--- 9 files changed, 42 insertions(+), 30 deletions(-) diff --git a/OpenRA.Game/Input/IInputHandler.cs b/OpenRA.Game/Input/IInputHandler.cs index b287945282..2809c5c0c2 100644 --- a/OpenRA.Game/Input/IInputHandler.cs +++ b/OpenRA.Game/Input/IInputHandler.cs @@ -26,17 +26,17 @@ namespace OpenRA { public MouseInputEvent Event; public MouseButton Button; - public int ScrollDelta; public int2 Location; + public int2 Delta; public Modifiers Modifiers; public int MultiTapCount; - public MouseInput(MouseInputEvent ev, MouseButton button, int scrollDelta, int2 location, Modifiers mods, int multiTapCount) + public MouseInput(MouseInputEvent ev, MouseButton button, int2 location, int2 delta, Modifiers mods, int multiTapCount) { Event = ev; Button = button; - ScrollDelta = scrollDelta; Location = location; + Delta = delta; Modifiers = mods; MultiTapCount = multiTapCount; } diff --git a/OpenRA.Game/Widgets/Widget.cs b/OpenRA.Game/Widgets/Widget.cs index b1ac4d32db..00b405cc36 100644 --- a/OpenRA.Game/Widgets/Widget.cs +++ b/OpenRA.Game/Widgets/Widget.cs @@ -153,8 +153,8 @@ namespace OpenRA.Widgets public static void ResetTooltips() { // Issue a no-op mouse move to force any tooltips to be recalculated - HandleInput(new MouseInput(MouseInputEvent.Move, MouseButton.None, 0, - Viewport.LastMousePos, Modifiers.None, 0)); + HandleInput(new MouseInput(MouseInputEvent.Move, MouseButton.None, + Viewport.LastMousePos, int2.Zero, Modifiers.None, 0)); } } diff --git a/OpenRA.Mods.Common/Traits/SupportPowers/SelectDirectionalTarget.cs b/OpenRA.Mods.Common/Traits/SupportPowers/SelectDirectionalTarget.cs index a2f0a29b31..68fa467665 100644 --- a/OpenRA.Mods.Common/Traits/SupportPowers/SelectDirectionalTarget.cs +++ b/OpenRA.Mods.Common/Traits/SupportPowers/SelectDirectionalTarget.cs @@ -19,6 +19,9 @@ namespace OpenRA.Mods.Common.Traits { public class SelectDirectionalTarget : IOrderGenerator { + const int MinDragThreshold = 20; + const int MaxDragThreshold = 75; + readonly string order; readonly SupportPowerManager manager; readonly string cursor; @@ -29,7 +32,7 @@ namespace OpenRA.Mods.Common.Traits CPos targetCell; int2 targetLocation; - int2 dragLocation; + float2 dragDirection; bool activated; bool dragStarted; Arrow currentArrow; @@ -72,9 +75,12 @@ namespace OpenRA.Mods.Common.Traits if (mi.Event == MouseInputEvent.Move) { - dragLocation = mi.Location; + dragDirection += mi.Delta; + + var angle = AngleOf(dragDirection); + if (dragDirection.Length > MaxDragThreshold) + dragDirection = -MaxDragThreshold * float2.FromAngle((float)(angle * (Math.PI / 180))); - var angle = AngleBetween(targetLocation, dragLocation); currentArrow = GetArrow(angle); dragStarted = true; } @@ -100,7 +106,7 @@ namespace OpenRA.Mods.Common.Traits bool IsOutsideDragZone { - get { return dragStarted && (dragLocation - targetLocation).Length > 20; } + get { return dragStarted && dragDirection.Length > MinDragThreshold; } } IEnumerable IOrderGenerator.Render(WorldRenderer wr, World world) { yield break; } @@ -130,9 +136,9 @@ namespace OpenRA.Mods.Common.Traits } // Starting at (0, -1) and rotating in CCW - static double AngleBetween(int2 p1, int2 p2) + static double AngleOf(float2 delta) { - var radian = Math.Atan2(p2.Y - p1.Y, p2.X - p1.X); + var radian = Math.Atan2(delta.Y, delta.X); var d = radian * (180 / Math.PI); if (d < 0.0) d += 360.0; diff --git a/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs b/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs index 5d09392c2e..5a0c16a630 100644 --- a/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/EditorViewportControllerWidget.cs @@ -89,7 +89,7 @@ namespace OpenRA.Mods.Common.Widgets if (mi.Event == MouseInputEvent.Scroll && Game.Settings.Game.AllowZoom && mi.Modifiers.HasModifier(Game.Settings.Game.ZoomModifier)) { - Zoom(mi.ScrollDelta); + Zoom(mi.Delta.Y); return true; } diff --git a/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs b/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs index ba0ba6d627..425a73c30a 100644 --- a/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ProductionTabsWidget.cs @@ -257,7 +257,7 @@ namespace OpenRA.Mods.Common.Widgets { if (mi.Event == MouseInputEvent.Scroll) { - Scroll(mi.ScrollDelta); + Scroll(mi.Delta.Y); return true; } diff --git a/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs b/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs index 55e5c9cd00..8e58f34640 100644 --- a/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ScrollPanelWidget.cs @@ -344,7 +344,7 @@ namespace OpenRA.Mods.Common.Widgets { if (mi.Event == MouseInputEvent.Scroll) { - Scroll(mi.ScrollDelta, true); + Scroll(mi.Delta.Y, true); return true; } diff --git a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs index fbd4c05405..4857738403 100644 --- a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs @@ -336,7 +336,7 @@ namespace OpenRA.Mods.Common.Widgets if (mi.Event == MouseInputEvent.Scroll && Game.Settings.Game.AllowZoom && mi.Modifiers.HasModifier(Game.Settings.Game.ZoomModifier)) { - Zoom(mi.ScrollDelta); + Zoom(mi.Delta.Y); return true; } diff --git a/OpenRA.Platforms.Default/Sdl2Input.cs b/OpenRA.Platforms.Default/Sdl2Input.cs index 4835adbbbf..cc66f84a54 100644 --- a/OpenRA.Platforms.Default/Sdl2Input.cs +++ b/OpenRA.Platforms.Default/Sdl2Input.cs @@ -50,10 +50,9 @@ namespace OpenRA.Platforms.Default return new int2(x, y); } - public void PumpInput(Sdl2PlatformWindow device, IInputHandler inputHandler) + public void PumpInput(Sdl2PlatformWindow device, IInputHandler inputHandler, int2? lockedMousePosition) { var mods = MakeModifiers((int)SDL.SDL_GetModState()); - var scrollDelta = 0; inputHandler.ModifierKeys(mods); MouseInput? pendingMotion = null; @@ -98,9 +97,11 @@ namespace OpenRA.Platforms.Default var button = MakeButton(e.button.button); lastButtonBits |= button; - var pos = EventPosition(device, e.button.x, e.button.y); + var input = lockedMousePosition ?? new int2(e.button.x, e.button.y); + var pos = EventPosition(device, input.X, input.Y); + inputHandler.OnMouseInput(new MouseInput( - MouseInputEvent.Down, button, scrollDelta, pos, mods, + MouseInputEvent.Down, button, pos, int2.Zero, mods, MultiTapDetection.DetectFromMouse(e.button.button, pos))); break; @@ -117,9 +118,11 @@ namespace OpenRA.Platforms.Default var button = MakeButton(e.button.button); lastButtonBits &= ~button; - var pos = EventPosition(device, e.button.x, e.button.y); + var input = lockedMousePosition ?? new int2(e.button.x, e.button.y); + var pos = EventPosition(device, input.X, input.Y); + inputHandler.OnMouseInput(new MouseInput( - MouseInputEvent.Up, button, scrollDelta, pos, mods, + MouseInputEvent.Up, button, pos, int2.Zero, mods, MultiTapDetection.InfoFromMouse(e.button.button))); break; @@ -127,10 +130,11 @@ namespace OpenRA.Platforms.Default case SDL.SDL_EventType.SDL_MOUSEMOTION: { - var pos = EventPosition(device, e.motion.x, e.motion.y); + var input = lockedMousePosition ?? new int2(e.motion.x, e.motion.y); + var pos = EventPosition(device, input.X, input.Y); + var delta = EventPosition(device, e.motion.xrel, e.motion.yrel); pendingMotion = new MouseInput( - MouseInputEvent.Move, lastButtonBits, scrollDelta, - pos, mods, 0); + MouseInputEvent.Move, lastButtonBits, pos, delta, mods, 0); break; } @@ -139,8 +143,7 @@ namespace OpenRA.Platforms.Default { int x, y; SDL.SDL_GetMouseState(out x, out y); - scrollDelta = e.wheel.y; - inputHandler.OnMouseInput(new MouseInput(MouseInputEvent.Scroll, MouseButton.None, scrollDelta, new int2(x, y), mods, 0)); + inputHandler.OnMouseInput(new MouseInput(MouseInputEvent.Scroll, MouseButton.None, new int2(x, y), new int2(0, e.wheel.y), mods, 0)); break; } diff --git a/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs b/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs index 652870fffd..945042d145 100644 --- a/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs +++ b/OpenRA.Platforms.Default/Sdl2PlatformWindow.cs @@ -30,7 +30,7 @@ namespace OpenRA.Platforms.Default Size windowSize; Size surfaceSize; float windowScale; - int2 mousePosition; + int2? lockedMousePosition; internal IntPtr Window { @@ -283,13 +283,16 @@ namespace OpenRA.Platforms.Default { int x, y; SDL.SDL_GetMouseState(out x, out y); - mousePosition = new int2(x, y); + lockedMousePosition = new int2(x, y); SDL.SDL_SetRelativeMouseMode(SDL.SDL_bool.SDL_TRUE); } else { SDL.SDL_SetRelativeMouseMode(SDL.SDL_bool.SDL_FALSE); - SDL.SDL_WarpMouseInWindow(window, mousePosition.X, mousePosition.Y); + if (lockedMousePosition.HasValue) + SDL.SDL_WarpMouseInWindow(window, lockedMousePosition.Value.X, lockedMousePosition.Value.Y); + + lockedMousePosition = null; } } @@ -348,7 +351,7 @@ namespace OpenRA.Platforms.Default public void PumpInput(IInputHandler inputHandler) { VerifyThreadAffinity(); - input.PumpInput(this, inputHandler); + input.PumpInput(this, inputHandler, lockedMousePosition); } public string GetClipboardText()