Refactor existing hodgepodge of hardcoded mouse/keyboard events into DefaultInputController.

This commit is contained in:
Paul Chote
2010-07-25 18:12:02 +12:00
parent 2248320af7
commit eac49ca641
10 changed files with 115 additions and 118 deletions

View File

@@ -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<BaseBuilding>().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);
}
}
}

View File

@@ -54,11 +54,6 @@ namespace OpenRA
static bool mapChangePending;
static Pair<Assembly, string>[] ModAssemblies;
static internal bool scrollUp = false;
static internal bool scrollDown = false;
static internal bool scrollLeft = false;
static internal bool scrollRight = false;
static void LoadModPackages()
{
FileSystem.UnmountAll();
@@ -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,32 +417,19 @@ 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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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));

View File

@@ -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)

View File

@@ -9,7 +9,9 @@
#endregion
using System;
using System.Linq;
using OpenRA.Orders;
using OpenRA.Traits;
namespace OpenRA.Widgets
{
@@ -19,6 +21,11 @@ namespace OpenRA.Widgets
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;
@@ -46,6 +53,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<BaseBuilding>().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); }
}
}

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;
}
}