diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj
index 49444845f1..a304e758a9 100755
--- a/OpenRA.Game/OpenRA.Game.csproj
+++ b/OpenRA.Game/OpenRA.Game.csproj
@@ -229,6 +229,7 @@
+
diff --git a/OpenRA.Game/Widgets/DefaultInputControllerWidget.cs b/OpenRA.Game/Widgets/DefaultInputControllerWidget.cs
index aff6487804..908512d8a3 100644
--- a/OpenRA.Game/Widgets/DefaultInputControllerWidget.cs
+++ b/OpenRA.Game/Widgets/DefaultInputControllerWidget.cs
@@ -43,13 +43,6 @@ namespace OpenRA.Widgets
Game.Renderer.LineRenderer.Flush();
}
- static internal bool scrollUp = false;
- static internal bool scrollDown = false;
- static internal bool scrollLeft = false;
- static internal bool scrollRight = false;
-
- // TODO: need a mechanism to say "i'll only handle this info if NOTHING else has"
- // For now, ensure that this widget recieves the input last or it will eat it
float2 dragStart, dragEnd;
public override bool HandleInputInner(MouseInput mi)
{
@@ -74,11 +67,6 @@ namespace OpenRA.Widgets
dragStart = dragEnd = xy;
}
-
- if (mi.Event == MouseInputEvent.Move &&
- (mi.Button == MouseButton.Middle || mi.Button == (MouseButton.Left | MouseButton.Right)))
- Game.viewport.Scroll(Widget.LastMousePos - mi.Location);
-
if (mi.Button == MouseButton.None && mi.Event == MouseInputEvent.Move)
dragStart = dragEnd = xy;
@@ -145,28 +133,10 @@ namespace OpenRA.Widgets
}
}
- public override bool LoseFocus (MouseInput mi)
- {
- scrollUp = scrollDown = scrollLeft = scrollRight = false;
- return base.LoseFocus(mi);
- }
-
public override bool HandleKeyPressInner(KeyInput e)
{
- // Take the input if *nothing* else is focused
- if (!Focused && Widget.SelectedWidget != null)
- return false;
-
if (e.Event == KeyInputEvent.Down)
- {
- switch (e.KeyName)
- {
- case "up": scrollUp = true; return true;
- case "down": scrollDown = true; return true;
- case "left": scrollLeft = true; return true;
- case "right": scrollRight = true; return true;
- }
-
+ {
if (e.KeyName.Length == 1 && char.IsDigit(e.KeyName[0]))
{
Game.world.Selection.DoControlGroup(Game.world, e.KeyName[0] - '0', e.Modifiers);
@@ -179,33 +149,9 @@ namespace OpenRA.Widgets
return true;
}
}
- else
- {
- switch (e.KeyName)
- {
- case "up": scrollUp = false; return true;
- case "down": scrollDown = false; return true;
- case "left": scrollLeft = false; return true;
- case "right": scrollRight = false; return true;
- }
- }
-
return false;
}
- public override void Tick(World world)
- {
-
- if (scrollUp == true)
- Game.viewport.Scroll(new float2(0, -10));
- if (scrollRight == true)
- Game.viewport.Scroll(new float2(10, 0));
- if (scrollDown == true)
- Game.viewport.Scroll(new float2(0, 10));
- if (scrollLeft == true)
- Game.viewport.Scroll(new float2(-10, 0));
- }
-
public void GotoNextBase()
{
var world = Game.world;
diff --git a/OpenRA.Game/Widgets/ViewportScrollControllerWidget.cs b/OpenRA.Game/Widgets/ViewportScrollControllerWidget.cs
new file mode 100644
index 0000000000..515da901ec
--- /dev/null
+++ b/OpenRA.Game/Widgets/ViewportScrollControllerWidget.cs
@@ -0,0 +1,105 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
+ * This file is part of OpenRA, which is free software. It is made
+ * available to you under the terms of the GNU General Public License
+ * as published by the Free Software Foundation. For more information,
+ * see LICENSE.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using OpenRA.Orders;
+using OpenRA.Traits;
+using OpenRA.FileFormats;
+
+namespace OpenRA.Widgets
+{
+ [Flags]
+ public enum ScrollDirection
+ {
+ None = 0,
+ Up = 1,
+ Left = 2,
+ Down = 4,
+ Right = 8
+ }
+
+ class ViewportScrollControllerWidget : Widget
+ {
+ public ViewportScrollControllerWidget() : base() {}
+ protected ViewportScrollControllerWidget(ViewportScrollControllerWidget widget) : base(widget) {}
+
+ public override void DrawInner( World world ) {}
+
+
+ ScrollDirection Scroll;
+ public override bool HandleInputInner(MouseInput mi)
+ {
+ if (mi.Event == MouseInputEvent.Move &&
+ (mi.Button == MouseButton.Middle || mi.Button == (MouseButton.Left | MouseButton.Right)))
+ {
+ Game.viewport.Scroll(Widget.LastMousePos - mi.Location);
+ return true;
+ }
+ return false;
+ }
+
+ public override string GetCursor(int2 pos)
+ {
+ return null;
+ }
+
+ public override bool LoseFocus (MouseInput mi)
+ {
+ Scroll = ScrollDirection.None;
+ return base.LoseFocus(mi);
+ }
+
+ public override bool HandleKeyPressInner(KeyInput e)
+ {
+
+ switch (e.KeyName)
+ {
+ case "up": Scroll = Scroll.Set(ScrollDirection.Up, (e.Event == KeyInputEvent.Down)); return true;
+ case "down": Scroll = Scroll.Set(ScrollDirection.Down, (e.Event == KeyInputEvent.Down)); return true;
+ case "left": Scroll = Scroll.Set(ScrollDirection.Left, (e.Event == KeyInputEvent.Down)); return true;
+ case "right": Scroll = Scroll.Set(ScrollDirection.Right, (e.Event == KeyInputEvent.Down)); return true;
+ }
+ return false;
+ }
+
+ public override void Tick(World world)
+ {
+ var scroll = new float2(0,0);
+ if (Scroll.Includes(ScrollDirection.Up))
+ scroll += new float2(0, -10);
+ if (Scroll.Includes(ScrollDirection.Right))
+ scroll += new float2(10, 0);
+ if (Scroll.Includes(ScrollDirection.Down))
+ scroll += new float2(0, 10);
+ if (Scroll.Includes(ScrollDirection.Left))
+ scroll += new float2(-10, 0);
+
+ Game.viewport.Scroll(scroll);
+ }
+
+ public override Widget Clone() { return new ViewportScrollControllerWidget(this); }
+ }
+
+ public static class ViewportExts
+ {
+ public static bool Includes(this ScrollDirection d, ScrollDirection s)
+ {
+ return (d & s) == s;
+ }
+
+ public static ScrollDirection Set(this ScrollDirection d, ScrollDirection s, bool val)
+ {
+ return (d.Includes(s) != val) ? d ^ s : d;
+ }
+ }
+}
\ No newline at end of file
diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml
index 6915fc8a54..de1bcc6a98 100644
--- a/mods/cnc/chrome/ingame.yaml
+++ b/mods/cnc/chrome/ingame.yaml
@@ -10,6 +10,11 @@ Container@ROOT:
Y:0
Width:WINDOW_RIGHT
Height:WINDOW_BOTTOM
+ ViewportScrollController:
+ X:0
+ Y:0
+ Width:WINDOW_RIGHT
+ Height:WINDOW_BOTTOM
Timer@GAME_TIMER:
Id:GAME_TIMER
X: WINDOW_RIGHT/2
diff --git a/mods/ra/chrome/ingame.yaml b/mods/ra/chrome/ingame.yaml
index 69aa7455be..9d0b3f48cb 100644
--- a/mods/ra/chrome/ingame.yaml
+++ b/mods/ra/chrome/ingame.yaml
@@ -10,6 +10,11 @@ Container@ROOT:
Y:0
Width:WINDOW_RIGHT
Height:WINDOW_BOTTOM
+ ViewportScrollController:
+ X:0
+ Y:0
+ Width:WINDOW_RIGHT
+ Height:WINDOW_BOTTOM
Timer@GAME_TIMER:
Id:GAME_TIMER
X: WINDOW_RIGHT/2