PageRenderTime 134ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/Adan.Client/Controls/TextBoxWithHistory.cs

http://mudclient.codeplex.com
C# | 299 lines | 184 code | 39 blank | 76 comment | 31 complexity | d26e6a02d216c26f67de311f5cd88332 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. // --------------------------------------------------------------------------------------------------------------------
  2. // <copyright file="TextBoxWithHistory.cs" company="Adamand MUD">
  3. // Copyright (c) Adamant MUD
  4. // </copyright>
  5. // <summary>
  6. // Interaction logic for TextBoxWithHistory.xaml
  7. // </summary>
  8. // --------------------------------------------------------------------------------------------------------------------
  9. namespace Adan.Client.Controls
  10. {
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Windows.Controls;
  14. using System.Linq;
  15. using System.Globalization;
  16. using Common.Commands;
  17. using Common.Conveyor;
  18. using CSLib.Net.Annotations;
  19. using System.Collections.Specialized;
  20. using Adan.Client.Common.Messages;
  21. /// <summary>
  22. /// Control that enhances basic text box to support input history.
  23. /// </summary>
  24. public class TextBoxWithHistory : TextBox
  25. {
  26. //private const int _queueSize = 20;
  27. //private readonly List<string> _enteredCommandsQueue = new List<string>(_queueSize + 1);
  28. private int _queueSize;
  29. private List<string> _enteredCommandsQueue;
  30. private int _currentQueueElementIndex = -1;
  31. private bool _selfChanges = false;
  32. private string oldText = String.Empty;
  33. private int oldCaretIndex;
  34. private int realCaretIndex = -1;
  35. /// <summary>
  36. /// Initializes a new instance of the <see cref="TextBoxWithHistory"/> class.
  37. /// </summary>
  38. public TextBoxWithHistory()
  39. {
  40. AcceptsReturn = false;
  41. AcceptsTab = false;
  42. var history = SettingsHolder.Instance.CommandsHistory;
  43. _queueSize = SettingsHolder.Instance.HistorySize;
  44. if (history != null)
  45. {
  46. _enteredCommandsQueue = history.Cast<string>().ToList();
  47. if (_enteredCommandsQueue.Count > _queueSize)
  48. _enteredCommandsQueue.RemoveRange(0, _enteredCommandsQueue.Count - _queueSize);
  49. _enteredCommandsQueue.Capacity = _queueSize;
  50. _currentQueueElementIndex = _enteredCommandsQueue.Count;
  51. }
  52. else
  53. {
  54. _enteredCommandsQueue = new List<string>(_queueSize);
  55. }
  56. }
  57. /// <summary>
  58. /// Gets or sets the conveyor.
  59. /// </summary>
  60. [NotNull]
  61. public MessageConveyor Conveyor
  62. {
  63. get;
  64. set;
  65. }
  66. /// <summary>
  67. /// Save current history to settings
  68. /// </summary>
  69. public void SaveCurrentHistory()
  70. {
  71. SettingsHolder.Instance.CommandsHistory.Clear();
  72. SettingsHolder.Instance.CommandsHistory.AddRange(_enteredCommandsQueue.ToArray());
  73. }
  74. /// <summary>
  75. /// Shows the next command.
  76. /// </summary>
  77. public void ShowNextCommand()
  78. {
  79. FindTextInHistoryAndUpdateTextBox(false);
  80. }
  81. /// <summary>
  82. /// Shows the previous command.
  83. /// </summary>
  84. public void ShowPreviousCommand()
  85. {
  86. FindTextInHistoryAndUpdateTextBox(true);
  87. }
  88. /// <summary>
  89. /// Sends the current command.
  90. /// </summary>
  91. public void SendCurrentCommand()
  92. {
  93. var command = Text ?? string.Empty;
  94. //????????? ??????? ?????????? ??????? ??????? ???????
  95. if (_enteredCommandsQueue.Capacity != SettingsHolder.Instance.HistorySize + 1)
  96. {
  97. _queueSize = SettingsHolder.Instance.HistorySize;
  98. if (_enteredCommandsQueue.Count > _queueSize + 1)
  99. _enteredCommandsQueue.RemoveRange(0, _enteredCommandsQueue.Count - _queueSize);
  100. _enteredCommandsQueue.Capacity = _queueSize + 1;
  101. }
  102. if (!string.IsNullOrEmpty(command) && command.Length >= SettingsHolder.Instance.MinLengthHistory)
  103. {
  104. //WTF?
  105. //while (_enteredCommandsQueue.Contains(command))
  106. //{
  107. // _enteredCommandsQueue.Remove(command);
  108. //}
  109. _enteredCommandsQueue.RemoveAll(x => x == command);
  110. _enteredCommandsQueue.Add(command);
  111. if (_enteredCommandsQueue.Count > _queueSize)
  112. {
  113. _enteredCommandsQueue.RemoveAt(0);
  114. }
  115. _currentQueueElementIndex = _enteredCommandsQueue.Count;
  116. }
  117. oldText = String.Empty;
  118. Conveyor.PushCommand(new TextCommand(command));
  119. if (SettingsHolder.Instance.AutoClearInput)
  120. {
  121. _selfChanges = true;
  122. Clear();
  123. }
  124. else
  125. {
  126. SelectAll();
  127. realCaretIndex = Text.Length;
  128. }
  129. }
  130. private void FindTextInHistoryAndUpdateTextBox(bool lookBackWard)
  131. {
  132. // var userTextLength = SelectionStart;
  133. // var userText = Text.Substring(0, userTextLength);
  134. // while (true)
  135. // {
  136. // if (!lookBackWard)
  137. // {
  138. // if (_currentQueueElementIndex >= _enteredCommandsQueue.Count - 1)
  139. // {
  140. // Text = userText;
  141. // _currentQueueElementIndex = _enteredCommandsQueue.Count;
  142. // Select(userText.Length, 0);
  143. // break;
  144. // }
  145. // _currentQueueElementIndex++;
  146. // }
  147. // else
  148. // {
  149. // if (_currentQueueElementIndex <= 0)
  150. // {
  151. // break;
  152. // }
  153. // _currentQueueElementIndex--;
  154. // }
  155. // var newText = _enteredCommandsQueue[_currentQueueElementIndex];
  156. // if (newText.StartsWith(userText, StringComparison.CurrentCultureIgnoreCase))
  157. // {
  158. // Text = newText;
  159. // Select(userTextLength, newText.Length - userTextLength);
  160. // break;
  161. // }
  162. // }
  163. int ind = -1;
  164. if (lookBackWard)
  165. {
  166. if (_currentQueueElementIndex > 0)
  167. {
  168. ind = _enteredCommandsQueue.FindLastIndex(_currentQueueElementIndex - 1, _currentQueueElementIndex,
  169. x => x.StartsWith(oldText));
  170. }
  171. }
  172. else
  173. {
  174. if (_currentQueueElementIndex < _enteredCommandsQueue.Count)
  175. {
  176. ind = _enteredCommandsQueue.FindIndex(_currentQueueElementIndex + 1, _enteredCommandsQueue.Count - (_currentQueueElementIndex + 1),
  177. x => x.StartsWith(oldText));
  178. if (ind == -1)
  179. {
  180. _selfChanges = true;
  181. Text = oldText;
  182. _currentQueueElementIndex = _enteredCommandsQueue.Count;
  183. }
  184. }
  185. }
  186. if(ind >= 0)
  187. {
  188. _selfChanges = true;
  189. Text = _enteredCommandsQueue[ind];
  190. _currentQueueElementIndex = ind;
  191. }
  192. if (SettingsHolder.Instance.CursorPosition == CursorPositionHistory.StartOfLine)
  193. CaretIndex = 0;
  194. else
  195. CaretIndex = Text.Length;
  196. }
  197. /// <summary>
  198. /// Override OnTextChanged method
  199. /// </summary>
  200. /// <param name="e"></param>
  201. protected override void OnTextChanged(TextChangedEventArgs e)
  202. {
  203. if (!_selfChanges)
  204. {
  205. oldText = Text;
  206. _currentQueueElementIndex = _enteredCommandsQueue.Count;
  207. }
  208. else
  209. _selfChanges = false;
  210. base.OnTextChanged(e);
  211. }
  212. /// <summary>
  213. /// ?????????? ????????? ???????.
  214. /// </summary>
  215. /// <param name="e"></param>
  216. protected override void OnSelectionChanged(System.Windows.RoutedEventArgs e)
  217. {
  218. if (SelectionLength > 0)
  219. {
  220. if (oldCaretIndex == CaretIndex)
  221. {
  222. realCaretIndex = CaretIndex + SelectionLength;
  223. }
  224. else
  225. {
  226. realCaretIndex = CaretIndex;
  227. }
  228. }
  229. else
  230. {
  231. if (realCaretIndex != -1)
  232. {
  233. int newCaretIndex = -1;
  234. if (oldCaretIndex == CaretIndex)
  235. {
  236. if (realCaretIndex > 0)
  237. newCaretIndex = realCaretIndex - 1;
  238. else
  239. newCaretIndex = realCaretIndex;
  240. }
  241. else if (oldCaretIndex < CaretIndex)
  242. {
  243. if (realCaretIndex < Text.Length)
  244. newCaretIndex = realCaretIndex + 1;
  245. else
  246. newCaretIndex = realCaretIndex;
  247. }
  248. else
  249. {
  250. Conveyor.PushMessage(new ErrorMessage(string.Format("#??????, ??????? ???????? ??? ?????????????: TextBoxWithHistory: oldCaretIndex = {0}, CaretIndex = {1}", oldCaretIndex, CaretIndex)));
  251. }
  252. realCaretIndex = -1;
  253. CaretIndex = newCaretIndex;
  254. }
  255. }
  256. oldCaretIndex = CaretIndex;
  257. base.OnSelectionChanged(e);
  258. }
  259. }
  260. }