Client LuaCsForBarotrauma
ChatManager.cs
1 using System.Collections.Generic;
2 using System.Linq;
4 using Microsoft.Xna.Framework.Input;
5 
6 namespace Barotrauma
7 {
8  // TODO decide what folder this falls under. Utils? GUI? or just leave where it is. Also probably a better class name name [<- no need to create a separate namespace, maybe a folder?]
13  public class ChatManager
14  {
15  private readonly bool loop;
16 
17  // Maximum items we want to store in the history
18  private readonly short maxCount = 10;
19 
20  // List of previously stored messages
21  private readonly List<string> messageList = new List<string> { string.Empty };
22 
27  private readonly List<GUITextBox> registers = new List<GUITextBox>();
28 
29  // Selector index
30  private int index;
31 
32  // Local changes we've made into previously stored messages
33  private string[] localChanges;
34 
35  public ChatManager(bool loop, short maxCount)
36  {
37  this.loop = loop;
38  this.maxCount = maxCount;
39  localChanges = new string[maxCount];
40  }
41 
42  public ChatManager()
43  {
44  localChanges = new string[maxCount];
45  }
46 
47 
53  public static void RegisterKeys(GUITextBox element, ChatManager manager)
54  {
55  // If already registered then don't register it again
56  if (manager.registers.Any(p => element == p)) { return; }
57  element.OnKeyHit += (sender, key) =>
58  {
59  switch (key)
60  {
61  // Up/Down Arrow key history action
62  case Keys.Up:
63  case Keys.Down:
64  {
65  // Up arrow key? go up. Down arrow key? go down. Everything else gets binned
66  Direction direction = key == Keys.Up ? Direction.Up : (key == Keys.Down ? Direction.Down : Direction.Other);
67 
68  string newMessage = manager.SelectMessage(direction, element.Text);
69  // Don't do anything if we didn't find anything
70  if (newMessage == null) { return; }
71 
72  element.Text = newMessage;
73  break;
74  }
75  case Keys.Tab:
76  // TODO tab completion behavior, maybe?
77  break;
78  }
79  };
80  manager.registers.Add(element);
81  }
82 
83  // Store a new message
84  public void Store(string message)
85  {
86  Clear();
87  var strip = StripMessage(message);
88  if (string.IsNullOrWhiteSpace(strip)) { return; }
89 
90  if (messageList.Count > 1 && messageList[1] == message) { return; }
91 
92  // insert to the second position as the first position is reserved for the original message if any
93  messageList.Insert(1, message);
94  // we don't want to add too many messages
95  if (messageList.Count > maxCount)
96  {
97  messageList.RemoveAt(messageList.Count - 1);
98  }
99 
100  // [It's also possible to lambdas too in short methods, if you like: string StripMessage(string text) => ChatMessage.GetChatMessageCommand(text, out string msg);]
101  static string StripMessage(string text)
102  {
103  ChatMessage.GetChatMessageCommand(text, out string msg);
104  return msg;
105  }
106  }
107 
112  public void Clear()
113  {
114  index = 0;
115  localChanges = new string[maxCount];
116  }
117 
124  private string SelectMessage(Direction direction, string original)
125  {
126  var originalIndex = index;
127  while (true)
128  {
129  if (direction == Direction.Other)
130  {
131  return null;
132  }
133 
134  // temporarily save our changes in case we fat-finger and want to go back
135  localChanges[index] = original;
136 
137  var dir = (int) direction;
138 
139  var nextIndex = (index + dir);
140 
141  if (loop && messageList.Count > 1)
142  {
143  nextIndex = LoopAround(nextIndex);
144  }
145  else
146  {
147  if (nextIndex > messageList.Count - 1)
148  {
149  return null;
150  }
151  }
152 
153  if (nextIndex >= 0 && EntryAt(nextIndex) == original && nextIndex != originalIndex && originalIndex != 0)
154  {
155  index = nextIndex;
156  continue;
157  }
158 
159  return nextIndex < 0 ? localChanges.FirstOrDefault() : EntryAt(index = nextIndex);
160 
161  string EntryAt(int i)
162  {
163  // if we've previously edited the entry then give us that, else give us the original message
164  return localChanges[i] ?? messageList[i];
165  }
166 
167  int LoopAround(int next)
168  {
169  if (next > (messageList.Count - 1))
170  {
171  return 1;
172  }
173 
174  if (next < 1)
175  {
176  return messageList.Count - 1;
177  }
178 
179  return next;
180  }
181  }
182  }
183 
184  // Used for Up/Down arrow key action
185  private enum Direction
186  {
187  Up = 1,
188  Down = -1,
189  Other = 0
190  }
191  }
192 }
A class used for handling special key actions in chat boxes. For example tab completion or up/down ar...
Definition: ChatManager.cs:14
static void RegisterKeys(GUITextBox element, ChatManager manager)
Registers special input actions to the selected input field
Definition: ChatManager.cs:53
void Store(string message)
Definition: ChatManager.cs:84
void Clear()
Call this function whenever we should stop doing special stuff and return normal behavior....
Definition: ChatManager.cs:112
ChatManager(bool loop, short maxCount)
Definition: ChatManager.cs:35
TextBoxEvent OnKeyHit
Definition: GUITextBox.cs:31
static string GetChatMessageCommand(string message, out string messageWithoutCommand)