Merge pull request #3969 from pchote/hotkeys

Improved hotkey support
This commit is contained in:
Matthias Mailänder
2013-10-21 13:53:43 -07:00
24 changed files with 841 additions and 105 deletions

View File

@@ -148,23 +148,23 @@ namespace OpenRA.GameRules
public class KeySettings
{
public string CycleBaseKey = "backspace";
public string ToLastEventKey = "space";
public string ToSelectionKey = "home";
public Hotkey CycleBaseKey = new Hotkey(Keycode.BACKSPACE, Modifiers.None);
public Hotkey ToLastEventKey = new Hotkey(Keycode.SPACE, Modifiers.None);
public Hotkey ToSelectionKey = new Hotkey(Keycode.HOME, Modifiers.None);
public string PauseKey = "f9";
public string SellKey = "f10";
public string PowerDownKey = "f11";
public string RepairKey = "f12";
public Hotkey PauseKey = new Hotkey(Keycode.F9, Modifiers.None);
public Hotkey SellKey = new Hotkey(Keycode.F10, Modifiers.None);
public Hotkey PowerDownKey = new Hotkey(Keycode.F11, Modifiers.None);
public Hotkey RepairKey = new Hotkey(Keycode.F12, Modifiers.None);
public string AttackMoveKey = "a";
public string StopKey = "s";
public string ScatterKey = "x";
public string DeployKey = "f";
public string StanceCycleKey = "z";
public string GuardKey = "d";
public Hotkey AttackMoveKey = new Hotkey(Keycode.A, Modifiers.None);
public Hotkey StopKey = new Hotkey(Keycode.S, Modifiers.None);
public Hotkey ScatterKey = new Hotkey(Keycode.X, Modifiers.None);
public Hotkey DeployKey = new Hotkey(Keycode.F, Modifiers.None);
public Hotkey StanceCycleKey = new Hotkey(Keycode.Z, Modifiers.None);
public Hotkey GuardKey = new Hotkey(Keycode.D, Modifiers.None);
public string CycleTabsKey = "tab";
public Hotkey CycleTabsKey = new Hotkey(Keycode.TAB, Modifiers.None);
}
public class IrcSettings

View File

@@ -236,6 +236,7 @@
<Compile Include="Traits\Player\PlayerHighlightPalette.cs" />
<Compile Include="Traits\World\ScreenMap.cs" />
<Compile Include="Traits\World\ActorMap.cs" />
<Compile Include="Widgets\HotkeyEntryWidget.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -18,8 +18,8 @@ namespace OpenRA.Widgets
{
public class ButtonWidget : Widget
{
public Func<ButtonWidget, string> GetKey = _ => null;
public string Key
public Func<ButtonWidget, Hotkey> GetKey = _ => Hotkey.Invalid;
public Hotkey Key
{
get { return GetKey(this); }
set { GetKey = _ => value; }
@@ -91,7 +91,7 @@ namespace OpenRA.Widgets
public override bool HandleKeyPress(KeyInput e)
{
if (e.KeyName != Key || e.Event != KeyInputEvent.Down)
if (Hotkey.FromKeyInput(e) != Key || e.Event != KeyInputEvent.Down)
return false;
if (!IsDisabled())

View File

@@ -49,7 +49,7 @@ namespace OpenRA.Widgets
{
if (e.Event == KeyInputEvent.Up) return false;
if (e.KeyName == "return" || e.KeyName == "enter" )
if (e.Key == Keycode.RETURN || e.Key == Keycode.KP_ENTER)
{
if (composing)
{
@@ -79,14 +79,14 @@ namespace OpenRA.Widgets
if (composing)
{
if (e.KeyName == "escape")
if (e.Key == Keycode.ESCAPE)
{
composing = false;
content = "";
YieldKeyboardFocus();
return true;
}
else if (e.KeyName == "backspace")
else if (e.Key == Keycode.BACKSPACE)
{
if (content.Length > 0)
content = content.Remove(content.Length - 1);

View File

@@ -0,0 +1,122 @@
#region Copyright & License Information
/*
* Copyright 2007-2013 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 COPYING.
*/
#endregion
using System;
using System.Drawing;
using System.Linq;
using OpenRA.Traits;
using OpenRA.Graphics;
namespace OpenRA.Widgets
{
public class HotkeyEntryWidget : Widget
{
public Hotkey Key;
public int VisualHeight = 1;
public int LeftMargin = 5;
public int RightMargin = 5;
public Action OnLoseFocus = () => { };
public Func<bool> IsDisabled = () => false;
public Color TextColor = Color.White;
public Color DisabledColor = Color.Gray;
public string Font = "Regular";
public HotkeyEntryWidget() : base() {}
protected HotkeyEntryWidget(HotkeyEntryWidget widget)
: base(widget)
{
Font = widget.Font;
TextColor = widget.TextColor;
DisabledColor = widget.DisabledColor;
VisualHeight = widget.VisualHeight;
}
public override bool YieldKeyboardFocus()
{
OnLoseFocus();
return base.YieldKeyboardFocus();
}
public override bool HandleMouseInput(MouseInput mi)
{
if (IsDisabled())
return false;
if (mi.Event != MouseInputEvent.Down)
return false;
// Attempt to take keyboard focus
if (!RenderBounds.Contains(mi.Location) || !TakeKeyboardFocus())
return false;
return true;
}
static readonly Keycode[] IgnoreKeys = new Keycode[]
{
Keycode.RSHIFT, Keycode.LSHIFT,
Keycode.RCTRL, Keycode.LCTRL,
Keycode.RALT, Keycode.LALT,
Keycode.RMETA, Keycode.LMETA
};
public override bool HandleKeyPress(KeyInput e)
{
if (IsDisabled() || e.Event == KeyInputEvent.Up)
return false;
if (!HasKeyboardFocus || IgnoreKeys.Contains(e.Key))
return false;
Key = Hotkey.FromKeyInput(e);
return true;
}
public override void Draw()
{
var apparentText = Key.DisplayString();
var font = Game.Renderer.Fonts[Font];
var pos = RenderOrigin;
var textSize = font.Measure(apparentText);
var disabled = IsDisabled();
var state = disabled ? "textfield-disabled" :
HasKeyboardFocus ? "textfield-focused" :
Ui.MouseOverWidget == this ? "textfield-hover" :
"textfield";
WidgetUtils.DrawPanel(state, RenderBounds);
// Inset text by the margin and center vertically
var textPos = pos + new int2(LeftMargin, (Bounds.Height - textSize.Y) / 2 - VisualHeight);
// Scissor when the text overflows
if (textSize.X > Bounds.Width - LeftMargin - RightMargin)
{
Game.Renderer.EnableScissor(pos.X + LeftMargin, pos.Y,
Bounds.Width - LeftMargin - RightMargin, Bounds.Bottom);
}
var color = disabled ? DisabledColor : TextColor;
font.DrawText(apparentText, textPos, color);
if (textSize.X > Bounds.Width - LeftMargin - RightMargin)
Game.Renderer.DisableScissor();
}
public override Widget Clone() { return new HotkeyEntryWidget(this); }
}
}

View File

@@ -110,16 +110,16 @@ namespace OpenRA.Widgets
if (!HasKeyboardFocus)
return false;
if ((e.KeyName == "return" || e.KeyName == "enter") && OnEnterKey())
if ((e.Key == Keycode.RETURN || e.Key == Keycode.KP_ENTER) && OnEnterKey())
return true;
if (e.KeyName == "tab" && OnTabKey())
if (e.Key == Keycode.TAB && OnTabKey())
return true;
if (e.KeyName == "escape" && OnEscKey())
if (e.Key == Keycode.ESCAPE && OnEscKey())
return true;
if (e.KeyName == "left")
if (e.Key == Keycode.LEFT)
{
if (CursorPosition > 0)
CursorPosition--;
@@ -127,7 +127,7 @@ namespace OpenRA.Widgets
return true;
}
if (e.KeyName == "right")
if (e.Key == Keycode.RIGHT)
{
if (CursorPosition <= Text.Length-1)
CursorPosition++;
@@ -135,19 +135,19 @@ namespace OpenRA.Widgets
return true;
}
if (e.KeyName == "home")
if (e.Key == Keycode.HOME)
{
CursorPosition = 0;
return true;
}
if (e.KeyName == "end")
if (e.Key == Keycode.END)
{
CursorPosition = Text.Length;
return true;
}
if (e.KeyName == "delete")
if (e.Key == Keycode.DELETE)
{
if (CursorPosition < Text.Length)
Text = Text.Remove(CursorPosition, 1);
@@ -160,7 +160,7 @@ namespace OpenRA.Widgets
public void TypeChar(KeyInput key)
{
if (key.KeyName == "backspace" && CursorPosition > 0)
if (key.Key == Keycode.BACKSPACE && CursorPosition > 0)
{
CursorPosition--;
Text = Text.Remove(CursorPosition, 1);

View File

@@ -167,12 +167,12 @@ namespace OpenRA.Widgets
public override bool HandleKeyPress(KeyInput e)
{
switch (e.KeyName)
switch (e.Key)
{
case "up": keyboardDirections = keyboardDirections.Set(ScrollDirection.Up, e.Event == KeyInputEvent.Down); return true;
case "down": keyboardDirections = keyboardDirections.Set(ScrollDirection.Down, e.Event == KeyInputEvent.Down); return true;
case "left": keyboardDirections = keyboardDirections.Set(ScrollDirection.Left, e.Event == KeyInputEvent.Down); return true;
case "right": keyboardDirections = keyboardDirections.Set(ScrollDirection.Right, e.Event == KeyInputEvent.Down); return true;
case Keycode.UP: keyboardDirections = keyboardDirections.Set(ScrollDirection.Up, e.Event == KeyInputEvent.Down); return true;
case Keycode.DOWN: keyboardDirections = keyboardDirections.Set(ScrollDirection.Down, e.Event == KeyInputEvent.Down); return true;
case Keycode.LEFT: keyboardDirections = keyboardDirections.Set(ScrollDirection.Left, e.Event == KeyInputEvent.Down); return true;
case Keycode.RIGHT: keyboardDirections = keyboardDirections.Set(ScrollDirection.Right, e.Event == KeyInputEvent.Down); return true;
}
return false;

View File

@@ -108,7 +108,7 @@ namespace OpenRA.Widgets
{
if (e.Event == KeyInputEvent.Down)
{
if (e.KeyName == "escape")
if (e.Key == Keycode.ESCAPE)
{
Stop();
return true;

View File

@@ -169,14 +169,15 @@ namespace OpenRA.Widgets
{
if (e.Event == KeyInputEvent.Down)
{
if (e.KeyName.Length == 1 && char.IsDigit(e.KeyName[0]))
if (e.Key >= Keycode.NUMBER_0 && e.Key <= Keycode.NUMBER_9)
{
world.Selection.DoControlGroup(world, worldRenderer, e.KeyName[0] - '0', e.Modifiers, e.MultiTapCount);
var group = (int)e.Key - (int)Keycode.NUMBER_0;
world.Selection.DoControlGroup(world, worldRenderer, group, e.Modifiers, e.MultiTapCount);
return true;
}
// Disable pausing for spectators
else if (e.KeyName == Game.Settings.Keys.PauseKey && world.LocalPlayer != null)
else if (Hotkey.FromKeyInput(e) == Game.Settings.Keys.PauseKey && world.LocalPlayer != null)
world.SetPauseState(!world.Paused);
}
return false;