Added tab completion to in-game chat.

Both player names and chat commands can be completed.
Names of local players and bots are not candidates for completion.
If a completed name is the first word ": " is appended to the end.
The hotkey for toggling team/all chat has been moved to left Alt.
This commit is contained in:
Alexander Fast
2014-08-19 17:10:04 +02:00
parent 520df8242d
commit 034625c2ea
2 changed files with 57 additions and 2 deletions

View File

@@ -30,6 +30,7 @@ namespace OpenRA.Widgets
public Func<bool> OnEnterKey = () => false;
public Func<bool> OnTabKey = () => false;
public Func<bool> OnEscKey = () => false;
public Func<bool> OnAltKey = () => false;
public Action OnLoseFocus = () => { };
public Action OnTextEdited = () => { };
public int CursorPosition { get; set; }
@@ -121,6 +122,9 @@ namespace OpenRA.Widgets
if (e.Key == Keycode.ESCAPE && OnEscKey())
return true;
if (e.Key == Keycode.LALT && OnAltKey())
return true;
if (e.Key == Keycode.LEFT)
{
if (CursorPosition > 0)

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
@@ -30,6 +31,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic
readonly List<INotifyChat> chatTraits;
readonly List<string> commandNames;
readonly List<string> playerNames;
bool teamChat;
[ObjectCreator.UseCtor]
@@ -43,6 +47,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic
var disableTeamChat = world.LocalPlayer == null || world.LobbyInfo.IsSinglePlayer || !players.Any(p => p.IsAlliedWith(world.LocalPlayer));
teamChat = !disableTeamChat;
commandNames = chatTraits.OfType<ChatCommands>().SelectMany(x => x.Commands.Keys).Select(x => "/" + x).ToList();
playerNames = players.Select(x => x.PlayerName).ToList();
var chatPanel = (ContainerWidget)widget;
chatOverlay = chatPanel.Get<ContainerWidget>("CHAT_OVERLAY");
chatOverlayDisplay = chatOverlay.Get<ChatDisplayWidget>("CHAT_DISPLAY");
@@ -57,7 +64,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
chatMode.IsDisabled = () => disableTeamChat;
chatText = chatChrome.Get<TextFieldWidget>("CHAT_TEXTFIELD");
chatText.OnTabKey = () =>
chatText.OnAltKey = () =>
{
if (!disableTeamChat)
teamChat ^= true;
@@ -76,6 +83,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
CloseChat();
return true;
};
chatText.OnTabKey = () => AutoCompleteText();
chatText.OnEscKey = () => { CloseChat(); return true; };
@@ -166,5 +174,48 @@ namespace OpenRA.Mods.RA.Widgets.Logic
Sound.PlayNotification(modRules, null, "Sounds", "ChatLine", null);
}
bool AutoCompleteText()
{
if (string.IsNullOrEmpty(chatText.Text))
return false;
string suggestion;
if (chatText.Text.StartsWith("/"))
{
suggestion = commandNames.FirstOrDefault(x => x.StartsWith(chatText.Text));
if (suggestion == null)
return false;
}
else
{
string toComplete;
bool oneWord;
if (chatText.Text.Contains(' '))
{
toComplete = chatText.Text.Substring(chatText.Text.LastIndexOf(' ') + 1);
oneWord = false;
}
else
{
toComplete = chatText.Text;
oneWord = true;
}
suggestion = playerNames.FirstOrDefault(x => x.StartsWith(toComplete, StringComparison.InvariantCultureIgnoreCase));
if (suggestion == null)
return false;
if (oneWord)
suggestion += ": ";
else
suggestion = chatText.Text.Substring(0, chatText.Text.Length - toComplete.Length) + suggestion;
}
chatText.Text = suggestion;
chatText.CursorPosition = chatText.Text.Length;
return true;
}
}
}
}