Improves tab completion in chat.
Pressing tab after completion now cycles to the next candidate.
This commit is contained in:
@@ -298,6 +298,7 @@
|
||||
<Compile Include="Warheads\CreateResourceWarhead.cs" />
|
||||
<Compile Include="Warheads\LeaveSmudgeWarhead.cs" />
|
||||
<Compile Include="RemoveOnConditions.cs" />
|
||||
<Compile Include="Widgets\Logic\TabCompletionLogic.cs" />
|
||||
<Compile Include="World\RadarPings.cs" />
|
||||
<Compile Include="Player\TechTree.cs" />
|
||||
<Compile Include="PrimaryBuilding.cs" />
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
@@ -31,8 +30,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
|
||||
readonly List<INotifyChat> chatTraits;
|
||||
|
||||
readonly List<string> commandNames;
|
||||
readonly List<string> playerNames;
|
||||
readonly TabCompletionLogic tabCompletion = new TabCompletionLogic();
|
||||
|
||||
bool teamChat;
|
||||
|
||||
@@ -47,8 +45,8 @@ 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 = orderManager.LobbyInfo.Clients.Select(c => c.Name).ToList();
|
||||
tabCompletion.Commands = chatTraits.OfType<ChatCommands>().SelectMany(x => x.Commands.Keys).ToList();
|
||||
tabCompletion.Names = orderManager.LobbyInfo.Clients.Select(c => c.Name).Distinct().ToList();
|
||||
|
||||
var chatPanel = (ContainerWidget)widget;
|
||||
chatOverlay = chatPanel.Get<ContainerWidget>("CHAT_OVERLAY");
|
||||
@@ -87,7 +85,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
CloseChat();
|
||||
return true;
|
||||
};
|
||||
chatText.OnTabKey = AutoCompleteText;
|
||||
chatText.OnTabKey = () =>
|
||||
{
|
||||
chatText.Text = tabCompletion.Complete(chatText.Text);
|
||||
chatText.CursorPosition = chatText.Text.Length;
|
||||
return true;
|
||||
};
|
||||
|
||||
chatText.OnEscKey = () => { CloseChat(); return true; };
|
||||
|
||||
@@ -178,43 +181,5 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
|
||||
Sound.PlayNotification(modRules, null, "Sounds", "ChatLine", null);
|
||||
}
|
||||
|
||||
bool AutoCompleteText()
|
||||
{
|
||||
if (string.IsNullOrEmpty(chatText.Text))
|
||||
return false;
|
||||
|
||||
if (chatText.Text.LastOrDefault() == ' ')
|
||||
return false;
|
||||
|
||||
var suggestion = "";
|
||||
|
||||
if (chatText.Text.StartsWith("/"))
|
||||
{
|
||||
suggestion = commandNames.FirstOrDefault(x => x.StartsWith(chatText.Text));
|
||||
if (suggestion == null)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var oneWord = !chatText.Text.Contains(' ');
|
||||
var toComplete = oneWord
|
||||
? chatText.Text
|
||||
: chatText.Text.Substring(chatText.Text.LastIndexOf(' ') + 1);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
|
||||
readonly ColorPreviewManagerWidget colorPreview;
|
||||
|
||||
List<string> playerNames;
|
||||
readonly TabCompletionLogic tabCompletion = new TabCompletionLogic();
|
||||
|
||||
// Listen for connection failures
|
||||
void ConnectionStateChanged(OrderManager om)
|
||||
@@ -509,7 +509,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
chatLabel.Text = teamChat ? "Team:" : "Chat:";
|
||||
return true;
|
||||
};
|
||||
chatTextField.OnTabKey = AutoCompleteText;
|
||||
chatTextField.OnTabKey = () =>
|
||||
{
|
||||
chatTextField.Text = tabCompletion.Complete(chatTextField.Text);
|
||||
chatTextField.CursorPosition = chatTextField.Text.Length;
|
||||
return true;
|
||||
};
|
||||
|
||||
chatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
|
||||
chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
|
||||
@@ -770,7 +775,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
while (players.Children.Count > idx)
|
||||
players.RemoveChild(players.Children[idx]);
|
||||
|
||||
playerNames = orderManager.LobbyInfo.Clients.Select(c => c.Name).ToList();
|
||||
tabCompletion.Names = orderManager.LobbyInfo.Clients.Select(c => c.Name).Distinct().ToList();
|
||||
}
|
||||
|
||||
void OnGameStart()
|
||||
@@ -779,35 +784,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
onStart();
|
||||
}
|
||||
|
||||
bool AutoCompleteText()
|
||||
{
|
||||
var chatText = lobby.Get<TextFieldWidget>("CHAT_TEXTFIELD");
|
||||
if (chatText == null || string.IsNullOrEmpty(chatText.Text))
|
||||
return false;
|
||||
|
||||
if (chatText.Text.LastOrDefault() == ' ')
|
||||
return false;
|
||||
|
||||
var suggestion = "";
|
||||
var oneWord = !chatText.Text.Contains(' ');
|
||||
var toComplete = oneWord
|
||||
? chatText.Text
|
||||
: chatText.Text.Substring(chatText.Text.LastIndexOf(' ') + 1);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
class DropDownOption
|
||||
{
|
||||
public string Title;
|
||||
|
||||
77
OpenRA.Mods.RA/Widgets/Logic/TabCompletionLogic.cs
Normal file
77
OpenRA.Mods.RA/Widgets/Logic/TabCompletionLogic.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2014 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA.Mods.RA.Widgets.Logic
|
||||
{
|
||||
class TabCompletionLogic
|
||||
{
|
||||
IList<string> candidates = new List<string>();
|
||||
int currentCandidateIndex = 0;
|
||||
string lastCompleted;
|
||||
string prefix;
|
||||
string suffix;
|
||||
|
||||
public IList<string> Commands { get; set; }
|
||||
|
||||
public IList<string> Names { get; set; }
|
||||
|
||||
public string Complete(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return text;
|
||||
|
||||
if (lastCompleted == text)
|
||||
{
|
||||
lastCompleted = prefix + candidates[++currentCandidateIndex % candidates.Count] + suffix;
|
||||
return lastCompleted;
|
||||
}
|
||||
|
||||
var toComplete = "";
|
||||
if (text.StartsWith("/") && Commands != null)
|
||||
{
|
||||
prefix = "/";
|
||||
suffix = "";
|
||||
toComplete = text.Substring(1);
|
||||
candidates = Commands.Where(x => x.StartsWith(toComplete, StringComparison.InvariantCultureIgnoreCase)).ToList();
|
||||
}
|
||||
else if (Names != null)
|
||||
{
|
||||
var oneWord = text.Contains(' ');
|
||||
if (oneWord)
|
||||
{
|
||||
prefix = text.Substring(0, text.LastIndexOf(' ') + 1);
|
||||
suffix = "";
|
||||
toComplete = text.Substring(prefix.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = "";
|
||||
suffix = ": ";
|
||||
toComplete = text;
|
||||
}
|
||||
candidates = Names.Where(x => x.StartsWith(toComplete, StringComparison.InvariantCultureIgnoreCase)).ToList();
|
||||
}
|
||||
else
|
||||
return text;
|
||||
|
||||
currentCandidateIndex = 0;
|
||||
|
||||
if (candidates.Count == 0)
|
||||
return text;
|
||||
|
||||
lastCompleted = prefix + candidates[currentCandidateIndex] + suffix;
|
||||
return lastCompleted;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user