From 07273fa666b4aba981b8b09614ab66101cfd9e79 Mon Sep 17 00:00:00 2001 From: Joppy Furr Date: Sun, 4 Oct 2015 02:36:58 +1300 Subject: [PATCH] Add support for Tiberian Sun style right-click-and-drag scrolling This patch introduces support for the right-click-and-drag scrolling that is available in Tiberian Sun and Red Alert 2. It can be enabled by selecting "Joystick" scrolling in the Input settings. The speed of the scroll is proportional to the product of the distance of the drag, and the Scroll Speed selected in the Input settings menu. A side-effect of this is that events previously tied to right clicks on the world are now based on the release of the click rather than the press. The "Middle-Mouse Scrolling:" option is renamed to "Mouse Scrolling Method:" --- OpenRA.Game/Settings.cs | 3 +- .../WorldInteractionControllerWidget.cs | 4 +- .../Widgets/Logic/SettingsLogic.cs | 1 + .../Widgets/ViewportControllerWidget.cs | 60 +++++++++++++++++-- mods/cnc/chrome/settings.yaml | 2 +- mods/ra/chrome/settings.yaml | 2 +- 6 files changed, 62 insertions(+), 10 deletions(-) diff --git a/OpenRA.Game/Settings.cs b/OpenRA.Game/Settings.cs index 535afb6780..04f773e553 100644 --- a/OpenRA.Game/Settings.cs +++ b/OpenRA.Game/Settings.cs @@ -19,7 +19,7 @@ using OpenRA.Traits; namespace OpenRA { - public enum MouseScrollType { Disabled, Standard, Inverted } + public enum MouseScrollType { Disabled, Standard, Inverted, Joystick } public class ServerSettings { @@ -167,6 +167,7 @@ namespace OpenRA public float ViewportEdgeScrollStep = 10f; public float UIScrollSpeed = 50f; public int SelectionDeadzone = 24; + public int JoystickScrollDeadzone = 8; public bool UseClassicMouseStyle = false; public bool AlwaysShowStatusBars = false; diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index ce2d777554..e053d8cba2 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -132,7 +132,7 @@ namespace OpenRA.Widgets YieldMouseFocus(mi); } - if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down) + if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Up) { // Don't do anything while selecting if (!hasBox) @@ -318,4 +318,4 @@ namespace OpenRA.Widgets return true; } } -} \ No newline at end of file +} diff --git a/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs index 5ed8962a32..7c38cd2a4e 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs @@ -588,6 +588,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic { "Disabled", MouseScrollType.Disabled }, { "Standard", MouseScrollType.Standard }, { "Inverted", MouseScrollType.Inverted }, + { "Joystick", MouseScrollType.Joystick }, }; Func setupItem = (o, itemTemplate) => diff --git a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs index 9b9f281aaa..6013d044a1 100644 --- a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs @@ -34,6 +34,8 @@ namespace OpenRA.Mods.Common.Widgets public int EdgeScrollThreshold = 15; public int EdgeCornerScrollThreshold = 35; + int2? joystickScrollStart, joystickScrollEnd; + static readonly Dictionary ScrollCursors = new Dictionary { { ScrollDirection.Up | ScrollDirection.Left, "scroll-tl" }, @@ -87,6 +89,15 @@ namespace OpenRA.Mods.Common.Widgets public override void Draw() { + if (IsJoystickScrolling) + { + // Base the JoystickScrolling speed on the Scroll Speed slider + var rate = 0.01f * Game.Settings.Game.ViewportEdgeScrollStep; + + var scroll = (joystickScrollEnd.Value - joystickScrollStart.Value).ToFloat2() * rate; + worldRenderer.Viewport.Scroll(scroll, false); + } + UpdateMouseover(); base.Draw(); } @@ -147,18 +158,57 @@ namespace OpenRA.Mods.Common.Widgets return null; } + bool IsJoystickScrolling + { + get + { + return joystickScrollStart.HasValue && joystickScrollEnd.HasValue && + (joystickScrollStart.Value - joystickScrollEnd.Value).Length > Game.Settings.Game.JoystickScrollDeadzone; + } + } + public override bool HandleMouseInput(MouseInput mi) { var scrolltype = Game.Settings.Game.MouseScroll; if (scrolltype == MouseScrollType.Disabled) return false; - if (mi.Event == MouseInputEvent.Move && - (mi.Button == MouseButton.Middle || mi.Button == (MouseButton.Left | MouseButton.Right))) + if (scrolltype == MouseScrollType.Standard || scrolltype == MouseScrollType.Inverted) { - var d = scrolltype == MouseScrollType.Inverted ? -1 : 1; - worldRenderer.Viewport.Scroll((Viewport.LastMousePos - mi.Location) * d, false); - return true; + if (mi.Event == MouseInputEvent.Move && + (mi.Button == MouseButton.Middle || mi.Button == (MouseButton.Left | MouseButton.Right))) + { + var d = scrolltype == MouseScrollType.Inverted ? -1 : 1; + worldRenderer.Viewport.Scroll((Viewport.LastMousePos - mi.Location) * d, false); + return true; + } + } + + // Tiberian Sun style right-click-and-drag scrolling + if (scrolltype == MouseScrollType.Joystick) + { + if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Down) + { + if (!TakeMouseFocus(mi)) + return false; + joystickScrollStart = mi.Location; + } + + if (mi.Button == MouseButton.Right && mi.Event == MouseInputEvent.Up) + { + var wasJoystickScrolling = IsJoystickScrolling; + + joystickScrollStart = joystickScrollEnd = null; + YieldMouseFocus(mi); + + if (wasJoystickScrolling) + return true; + } + + if (mi.Event == MouseInputEvent.Move && mi.Button == MouseButton.Right && joystickScrollStart.HasValue) + { + joystickScrollEnd = mi.Location; + } } return false; diff --git a/mods/cnc/chrome/settings.yaml b/mods/cnc/chrome/settings.yaml index b1558b8a18..b48a9d82f5 100644 --- a/mods/cnc/chrome/settings.yaml +++ b/mods/cnc/chrome/settings.yaml @@ -333,7 +333,7 @@ Container@SETTINGS_PANEL: Width: 160 Height: 20 Font: Regular - Text: Middle-Mouse Scrolling: + Text: Mouse Scrolling Method: Align: Right DropDownButton@MOUSE_SCROLL: X: PARENT_RIGHT - WIDTH - 15 diff --git a/mods/ra/chrome/settings.yaml b/mods/ra/chrome/settings.yaml index ae228f33eb..6cb42c5f7a 100644 --- a/mods/ra/chrome/settings.yaml +++ b/mods/ra/chrome/settings.yaml @@ -337,7 +337,7 @@ Background@SETTINGS_PANEL: Width: 160 Height: 20 Font: Regular - Text: Middle-Mouse Scrolling: + Text: Mouse Scrolling Method: Align: Right DropDownButton@MOUSE_SCROLL: X: PARENT_RIGHT - WIDTH - 15