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\CreateResourceWarhead.cs" />
|
||||||
<Compile Include="Warheads\LeaveSmudgeWarhead.cs" />
|
<Compile Include="Warheads\LeaveSmudgeWarhead.cs" />
|
||||||
<Compile Include="RemoveOnConditions.cs" />
|
<Compile Include="RemoveOnConditions.cs" />
|
||||||
|
<Compile Include="Widgets\Logic\TabCompletionLogic.cs" />
|
||||||
<Compile Include="World\RadarPings.cs" />
|
<Compile Include="World\RadarPings.cs" />
|
||||||
<Compile Include="Player\TechTree.cs" />
|
<Compile Include="Player\TechTree.cs" />
|
||||||
<Compile Include="PrimaryBuilding.cs" />
|
<Compile Include="PrimaryBuilding.cs" />
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -31,8 +30,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
|
|
||||||
readonly List<INotifyChat> chatTraits;
|
readonly List<INotifyChat> chatTraits;
|
||||||
|
|
||||||
readonly List<string> commandNames;
|
readonly TabCompletionLogic tabCompletion = new TabCompletionLogic();
|
||||||
readonly List<string> playerNames;
|
|
||||||
|
|
||||||
bool teamChat;
|
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));
|
var disableTeamChat = world.LocalPlayer == null || world.LobbyInfo.IsSinglePlayer || !players.Any(p => p.IsAlliedWith(world.LocalPlayer));
|
||||||
teamChat = !disableTeamChat;
|
teamChat = !disableTeamChat;
|
||||||
|
|
||||||
commandNames = chatTraits.OfType<ChatCommands>().SelectMany(x => x.Commands.Keys).Select(x => "/" + x).ToList();
|
tabCompletion.Commands = chatTraits.OfType<ChatCommands>().SelectMany(x => x.Commands.Keys).ToList();
|
||||||
playerNames = orderManager.LobbyInfo.Clients.Select(c => c.Name).ToList();
|
tabCompletion.Names = orderManager.LobbyInfo.Clients.Select(c => c.Name).Distinct().ToList();
|
||||||
|
|
||||||
var chatPanel = (ContainerWidget)widget;
|
var chatPanel = (ContainerWidget)widget;
|
||||||
chatOverlay = chatPanel.Get<ContainerWidget>("CHAT_OVERLAY");
|
chatOverlay = chatPanel.Get<ContainerWidget>("CHAT_OVERLAY");
|
||||||
@@ -87,7 +85,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
CloseChat();
|
CloseChat();
|
||||||
return true;
|
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; };
|
chatText.OnEscKey = () => { CloseChat(); return true; };
|
||||||
|
|
||||||
@@ -178,43 +181,5 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
|
|
||||||
Sound.PlayNotification(modRules, null, "Sounds", "ChatLine", null);
|
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;
|
readonly ColorPreviewManagerWidget colorPreview;
|
||||||
|
|
||||||
List<string> playerNames;
|
readonly TabCompletionLogic tabCompletion = new TabCompletionLogic();
|
||||||
|
|
||||||
// Listen for connection failures
|
// Listen for connection failures
|
||||||
void ConnectionStateChanged(OrderManager om)
|
void ConnectionStateChanged(OrderManager om)
|
||||||
@@ -509,7 +509,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
chatLabel.Text = teamChat ? "Team:" : "Chat:";
|
chatLabel.Text = teamChat ? "Team:" : "Chat:";
|
||||||
return true;
|
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");
|
chatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
|
||||||
chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
|
chatTemplate = chatPanel.Get("CHAT_TEMPLATE");
|
||||||
@@ -770,7 +775,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
while (players.Children.Count > idx)
|
while (players.Children.Count > idx)
|
||||||
players.RemoveChild(players.Children[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()
|
void OnGameStart()
|
||||||
@@ -779,35 +784,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
onStart();
|
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
|
class DropDownOption
|
||||||
{
|
{
|
||||||
public string Title;
|
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