diff --git a/OpenRA.Game/Controller.cs b/OpenRA.Game/Controller.cs index 28f34a362b..f1c8ac60c1 100644 --- a/OpenRA.Game/Controller.cs +++ b/OpenRA.Game/Controller.cs @@ -76,23 +76,5 @@ namespace OpenRA public void SetModifiers(Modifiers mods) { modifiers = mods; } public Modifiers GetModifiers() { return modifiers; } - - public void GotoNextBase() - { - var bases = Game.world.Queries.OwnedBy[Game.world.LocalPlayer].WithTrait().ToArray(); - if (!bases.Any()) return; - - var next = bases - .Select( b => b.Actor ) - .SkipWhile(b => Game.controller.selection.Actors.Contains(b)) - .Skip(1) - .FirstOrDefault(); - - if (next == null) - next = bases.Select(b => b.Actor).First(); - - Game.controller.selection.Combine(Game.world, new Actor[] { next }, false, true); - Game.viewport.Center(Game.controller.selection.Actors); - } } } diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index f7c0ea5f90..6b76243d02 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -53,11 +53,6 @@ namespace OpenRA static bool packageChangePending; static bool mapChangePending; static Pair[] ModAssemblies; - - static internal bool scrollUp = false; - static internal bool scrollDown = false; - static internal bool scrollLeft = false; - static internal bool scrollRight = false; static void LoadModPackages() { @@ -304,15 +299,6 @@ namespace OpenRA } } - if (scrollUp == true) - viewport.Scroll(new float2(0, -10)); - if (scrollRight == true) - viewport.Scroll(new float2(10, 0)); - if (scrollDown == true) - viewport.Scroll(new float2(0, 10)); - if (scrollLeft == true) - viewport.Scroll(new float2(-10, 0)); - using (new PerfSample("render")) { ++RenderFrame; @@ -431,33 +417,20 @@ namespace OpenRA return LobbyInfo.Clients.Single(c => c.Index == p.Index); } - static int2 lastPos; public static void DispatchMouseInput(MouseInputEvent ev, MouseEventArgs e, Modifiers modifierKeys) { int sync = world.SyncHash(); var initialWorld = world; - if (ev == MouseInputEvent.Down) - lastPos = new int2(e.Location); - - if (ev == MouseInputEvent.Move && - (e.Button == MouseButtons.Middle || - e.Button == (MouseButtons.Left | MouseButtons.Right))) + var mi = new MouseInput { - var p = new int2(e.Location); - viewport.Scroll(lastPos - p); - lastPos = p; - } - - viewport.DispatchMouseInput(world, - new MouseInput - { - Button = (MouseButton)(int)e.Button, - Event = ev, - Location = new int2(e.Location), - Modifiers = modifierKeys, - }); - + Button = (MouseButton)(int)e.Button, + Event = ev, + Location = new int2(e.Location), + Modifiers = modifierKeys, + }; + Widget.HandleInput(world, mi); + if (sync != world.SyncHash() && world == initialWorld) throw new InvalidOperationException("Desync in DispatchMouseInput"); } @@ -472,62 +445,17 @@ namespace OpenRA get { return LobbyInfo.Clients.FirstOrDefault(c => c.Index == orderManager.Connection.LocalClientId); } } - public static void HandleKeyDown(KeyInput e) + public static void HandleKeyEvent(KeyInput e) { int sync = world.SyncHash(); if (Widget.HandleKeyPress(e)) return; - switch (e.KeyName) - { - case "up": scrollUp = true; break; - case "down": scrollDown = true; break; - case "left": scrollLeft = true; break; - case "right": scrollRight = true; break; - } - - if (e.KeyName.Length == 1 && char.IsDigit(e.KeyName[0])) - Game.controller.selection.DoControlGroup(world, e.KeyName[0] - '0', e.Modifiers); - - if (e.KeyChar == 08) - Game.controller.GotoNextBase(); - if (sync != Game.world.SyncHash()) throw new InvalidOperationException("Desync in OnKeyPress"); } - public static void HandleKeyUp(KeyInput e) - { - switch (e.KeyName) - { - case "up": scrollUp = false; break; - case "down": scrollDown = false; break; - case "left": scrollLeft = false; break; - case "right": scrollRight = false; break; - } - } - - public static void HandleArrowKeyScroll(String k, Boolean pressed) - { - if (k == "up") - { - scrollUp = pressed; - } - if (k == "left") - { - scrollLeft = pressed; - } - if (k == "down") - { - scrollDown = pressed; - } - if (k == "right") - { - scrollRight = pressed; - } - } - public static void HandleModifierKeys(Modifiers mods) { controller.SetModifiers(mods); diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index 3b7adbe3d9..014d2d28cf 100644 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -28,7 +28,6 @@ namespace OpenRA.Graphics public int Width { get { return (int)screenSize.X; } } public int Height { get { return (int)screenSize.Y; } } - int2 mousePos; float cursorFrame = 0f; public void Scroll(float2 delta) @@ -61,9 +60,9 @@ namespace OpenRA.Graphics Widget.DoDraw(world); Timer.Time( "widgets: {0}" ); - var cursorName = Widget.RootWidget.GetCursorOuter(mousePos) ?? "default"; + var cursorName = Widget.RootWidget.GetCursorOuter(Widget.LastMousePos) ?? "default"; var c = new Cursor(cursorName); - c.Draw((int)cursorFrame, mousePos + Location); + c.Draw((int)cursorFrame, Widget.LastMousePos + Location); Timer.Time( "cursors: {0}" ); renderer.RgbaSpriteRenderer.Flush(); @@ -79,14 +78,6 @@ namespace OpenRA.Graphics cursorFrame += 0.5f; } - public void DispatchMouseInput(World world, MouseInput mi) - { - if (mi.Event == MouseInputEvent.Move) - mousePos = mi.Location; - - Widget.HandleInput(world, mi); - } - public float2 ViewToWorld(MouseInput mi) { return (1f / Game.CellSize) * (new float2(mi.Location.X, mi.Location.Y) + Location); diff --git a/OpenRA.Game/MainWindow.cs b/OpenRA.Game/MainWindow.cs index a7a4543f62..2a0990f0d5 100755 --- a/OpenRA.Game/MainWindow.cs +++ b/OpenRA.Game/MainWindow.cs @@ -41,8 +41,10 @@ namespace OpenRA Ctrl = (int)Keys.Control, } + public enum KeyInputEvent { Down, Up }; public struct KeyInput { + public KeyInputEvent Event; public char KeyChar; public string KeyName; public Modifiers Modifiers; diff --git a/OpenRA.Game/Widgets/BuildPaletteWidget.cs b/OpenRA.Game/Widgets/BuildPaletteWidget.cs index 59d2085c88..26c883e248 100644 --- a/OpenRA.Game/Widgets/BuildPaletteWidget.cs +++ b/OpenRA.Game/Widgets/BuildPaletteWidget.cs @@ -140,6 +140,8 @@ namespace OpenRA.Widgets public override bool HandleKeyPressInner(KeyInput e) { + if (e.Event == KeyInputEvent.Up) return false; + if (e.KeyChar == '\t') { TabChange(e.Modifiers.HasModifier(Modifiers.Shift)); diff --git a/OpenRA.Game/Widgets/ChatEntryWidget.cs b/OpenRA.Game/Widgets/ChatEntryWidget.cs index d2f5176adf..d0cdfc163d 100644 --- a/OpenRA.Game/Widgets/ChatEntryWidget.cs +++ b/OpenRA.Game/Widgets/ChatEntryWidget.cs @@ -48,6 +48,8 @@ namespace OpenRA.Widgets public override bool HandleKeyPressInner(KeyInput e) { + if (e.Event == KeyInputEvent.Up) return false; + if (e.KeyChar == '\r') { if (composing) diff --git a/OpenRA.Game/Widgets/DefaultInputControllerWidget.cs b/OpenRA.Game/Widgets/DefaultInputControllerWidget.cs index 893a461517..6b5ee831a7 100644 --- a/OpenRA.Game/Widgets/DefaultInputControllerWidget.cs +++ b/OpenRA.Game/Widgets/DefaultInputControllerWidget.cs @@ -9,7 +9,9 @@ #endregion using System; +using System.Linq; using OpenRA.Orders; +using OpenRA.Traits; namespace OpenRA.Widgets { @@ -18,7 +20,12 @@ namespace OpenRA.Widgets public DefaultInputControllerWidget() : base() {} protected DefaultInputControllerWidget(DefaultInputControllerWidget widget) : base(widget) {} public override void DrawInner( World world ) { } - + + 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; @@ -45,6 +52,11 @@ 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; @@ -82,6 +94,79 @@ 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; break; + case "down": scrollDown = true; break; + case "left": scrollLeft = true; break; + case "right": scrollRight = true; break; + } + + if (e.KeyName.Length == 1 && char.IsDigit(e.KeyName[0])) + Game.controller.selection.DoControlGroup(Game.world, e.KeyName[0] - '0', e.Modifiers); + + if (e.KeyChar == 08) + GotoNextBase(); + } + else + { + switch (e.KeyName) + { + case "up": scrollUp = false; break; + case "down": scrollDown = false; break; + case "left": scrollLeft = false; break; + case "right": scrollRight = false; break; + } + } + + return true; + } + + 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 bases = Game.world.Queries.OwnedBy[Game.world.LocalPlayer].WithTrait().ToArray(); + if (!bases.Any()) return; + + var next = bases + .Select( b => b.Actor ) + .SkipWhile(b => Game.controller.selection.Actors.Contains(b)) + .Skip(1) + .FirstOrDefault(); + + if (next == null) + next = bases.Select(b => b.Actor).First(); + + Game.controller.selection.Combine(Game.world, new Actor[] { next }, false, true); + Game.viewport.Center(Game.controller.selection.Actors); + } + public override Widget Clone() { return new DefaultInputControllerWidget(this); } } } \ No newline at end of file diff --git a/OpenRA.Game/Widgets/TextFieldWidget.cs b/OpenRA.Game/Widgets/TextFieldWidget.cs index 6b3d78b566..1710881825 100644 --- a/OpenRA.Game/Widgets/TextFieldWidget.cs +++ b/OpenRA.Game/Widgets/TextFieldWidget.cs @@ -63,6 +63,8 @@ namespace OpenRA.Widgets public override bool HandleKeyPressInner(KeyInput e) { + if (e.Event == KeyInputEvent.Up) return false; + // Only take input if we are focused if (!Focused) return false; diff --git a/OpenRA.Game/Widgets/Widget.cs b/OpenRA.Game/Widgets/Widget.cs index d40033f289..c3f97bbddd 100644 --- a/OpenRA.Game/Widgets/Widget.cs +++ b/OpenRA.Game/Widgets/Widget.cs @@ -207,18 +207,19 @@ namespace OpenRA.Widgets public static int2 LastMousePos; public static bool HandleInput(World world, MouseInput mi) { + bool handled = false; if (SelectedWidget != null && SelectedWidget.HandleMouseInputOuter(mi)) - return true; + handled = true; - if (RootWidget.HandleMouseInputOuter(mi)) - return true; + if (!handled && RootWidget.HandleMouseInputOuter(mi)) + handled = true; if (mi.Event == MouseInputEvent.Move) { LastMousePos = mi.Location; TicksSinceLastMove = 0; } - return false; + return handled; } public bool HandleMouseInputOuter(MouseInput mi) diff --git a/OpenRA.Gl/GraphicsDevice.cs b/OpenRA.Gl/GraphicsDevice.cs index 6bdfc29cf2..385690a608 100644 --- a/OpenRA.Gl/GraphicsDevice.cs +++ b/OpenRA.Gl/GraphicsDevice.cs @@ -215,6 +215,7 @@ namespace OpenRA.GlRenderer { var keyEvent = new KeyInput { + Event = KeyInputEvent.Down, Modifiers = mods, KeyChar = (char) e.key.keysym.unicode, KeyName = Sdl.SDL_GetKeyName( e.key.keysym.sym ), @@ -222,20 +223,21 @@ namespace OpenRA.GlRenderer }; if (!HandleSpecialKey(keyEvent)) - Game.HandleKeyDown(keyEvent); + Game.HandleKeyEvent(keyEvent); } break; case Sdl.SDL_KEYUP: { var keyEvent = new KeyInput { + Event = KeyInputEvent.Up, Modifiers = mods, KeyChar = (char) e.key.keysym.unicode, KeyName = Sdl.SDL_GetKeyName( e.key.keysym.sym ), VirtKey = e.key.keysym.sym }; - - Game.HandleKeyUp(keyEvent); + + Game.HandleKeyEvent(keyEvent); } break; } }