From 18dafa9e98e171321d3847a208c0af5be6f57ef6 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Fri, 28 Feb 2020 19:46:34 +0200 Subject: Implemented Transport Immediate mode on TCP and SignalR. Implemented Tango.Console components. --- .../Visual_Studio/Tango.Console/ConsoleTextBox.cs | 194 +++++++++++++++++++++ 1 file changed, 194 insertions(+) (limited to 'Software/Visual_Studio/Tango.Console/ConsoleTextBox.cs') diff --git a/Software/Visual_Studio/Tango.Console/ConsoleTextBox.cs b/Software/Visual_Studio/Tango.Console/ConsoleTextBox.cs index e2f1f53c3..905843f81 100644 --- a/Software/Visual_Studio/Tango.Console/ConsoleTextBox.cs +++ b/Software/Visual_Studio/Tango.Console/ConsoleTextBox.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; @@ -18,6 +20,8 @@ namespace Tango.Console public class ConsoleTextBox : TextBox { private Border _caret; + private ListBox _listSuggestions; + private Popup _popup; static ConsoleTextBox() { @@ -32,12 +36,199 @@ namespace Tango.Console public static readonly DependencyProperty CaretBottomBrushProperty = DependencyProperty.Register("CaretBottomBrush", typeof(Brush), typeof(ConsoleTextBox), new PropertyMetadata(null)); + public double CaretPosition + { + get { return (double)GetValue(CaretPositionProperty); } + set { SetValue(CaretPositionProperty, value); } + } + public static readonly DependencyProperty CaretPositionProperty = + DependencyProperty.Register("CaretPosition", typeof(double), typeof(ConsoleTextBox), new PropertyMetadata(0.0)); + + public Visibility SuggestionsVisibility + { + get { return (Visibility)GetValue(SuggestionsVisibilityProperty); } + set { SetValue(SuggestionsVisibilityProperty, value); } + } + public static readonly DependencyProperty SuggestionsVisibilityProperty = + DependencyProperty.Register("SuggestionsVisibility", typeof(Visibility), typeof(ConsoleTextBox), new PropertyMetadata(Visibility.Collapsed)); + + public List FilteredSuggestions + { + get { return (List)GetValue(FilteredSuggestionsProperty); } + set { SetValue(FilteredSuggestionsProperty, value); } + } + public static readonly DependencyProperty FilteredSuggestionsProperty = + DependencyProperty.Register("FilteredSuggestions", typeof(List), typeof(ConsoleTextBox), new PropertyMetadata(null)); + + public IEnumerable Suggestions + { + get { return (IEnumerable)GetValue(SuggestionsProperty); } + set { SetValue(SuggestionsProperty, value); } + } + public static readonly DependencyProperty SuggestionsProperty = + DependencyProperty.Register("Suggestions", typeof(IEnumerable), typeof(ConsoleTextBox), new PropertyMetadata(null)); + + public ConsoleSuggestion SelectedSuggestion + { + get { return (ConsoleSuggestion)GetValue(SelectedSuggestionProperty); } + set { SetValue(SelectedSuggestionProperty, value); } + } + public static readonly DependencyProperty SelectedSuggestionProperty = + DependencyProperty.Register("SelectedSuggestion", typeof(ConsoleSuggestion), typeof(ConsoleTextBox), new PropertyMetadata(null)); + + public int MaxSuggestions + { + get { return (int)GetValue(MaxSuggestionsProperty); } + set { SetValue(MaxSuggestionsProperty, value); } + } + public static readonly DependencyProperty MaxSuggestionsProperty = + DependencyProperty.Register("MaxSuggestions", typeof(int), typeof(ConsoleTextBox), new PropertyMetadata(1000)); + + public Brush SuggestionsBorderBrush + { + get { return (Brush)GetValue(SuggestionsBorderBrushProperty); } + set { SetValue(SuggestionsBorderBrushProperty, value); } + } + public static readonly DependencyProperty SuggestionsBorderBrushProperty = + DependencyProperty.Register("SuggestionsBorderBrush", typeof(Brush), typeof(ConsoleTextBox), new PropertyMetadata(null)); + + public Brush SuggestionsBackground + { + get { return (Brush)GetValue(SuggestionsBackgroundProperty); } + set { SetValue(SuggestionsBackgroundProperty, value); } + } + public static readonly DependencyProperty SuggestionsBackgroundProperty = + DependencyProperty.Register("SuggestionsBackground", typeof(Brush), typeof(ConsoleTextBox), new PropertyMetadata(null)); + + public Brush SuggestionsForeground + { + get { return (Brush)GetValue(SuggestionsForegroundProperty); } + set { SetValue(SuggestionsForegroundProperty, value); } + } + public static readonly DependencyProperty SuggestionsForegroundProperty = + DependencyProperty.Register("SuggestionsForeground", typeof(Brush), typeof(ConsoleTextBox), new PropertyMetadata(null)); + + public ConsoleTextBox() { SelectionChanged += (sender, e) => MoveCustomCaret(); LostFocus += (sender, e) => _caret.Visibility = Visibility.Collapsed; GotKeyboardFocus += (sender, e) => _caret.Visibility = Visibility.Visible; LostKeyboardFocus += (sender, e) => _caret.Visibility = Visibility.Collapsed; + + Suggestions = ConsoleDictionary.GetKnownCommands().Select(x => new ConsoleSuggestion() + { + Name = x.Name, + Description = x.Description + }).ToObservableCollection(); + } + + protected override void OnPreviewKeyDown(KeyEventArgs e) + { + if (SuggestionsVisibility == Visibility.Visible) + { + if (e.Key == Key.Down) + { + if (_listSuggestions.SelectedIndex < _listSuggestions.Items.Count - 1) + { + _listSuggestions.SelectedIndex++; + _listSuggestions.ScrollIntoView(SelectedSuggestion); + + _popup.IsOpen = false; + + if (SelectedSuggestion != null && SelectedSuggestion.Description != null) + { + _popup.IsOpen = FilteredSuggestions.Count > 0; + } + } + + e.Handled = true; + return; + } + else if (e.Key == Key.Up) + { + if (_listSuggestions.SelectedIndex > 0) + { + _listSuggestions.SelectedIndex--; + _listSuggestions.ScrollIntoView(SelectedSuggestion); + + _popup.IsOpen = false; + if (SelectedSuggestion != null && SelectedSuggestion.Description != null) + { + _popup.IsOpen = FilteredSuggestions.Count > 0; + } + } + + e.Handled = true; + return; + } + else if (e.Key == Key.Enter) + { + var selectedItem = (_listSuggestions.SelectedItem as ConsoleSuggestion); + if (selectedItem != null) + { + var words = Text.Split(' ').ToList(); + + if (words.Count > 1) + { + words = words.Take(words.Count - 1).ToList(); + Text = String.Join(" ", words) + " " + selectedItem.Name; + } + else + { + Text = selectedItem.Name; + } + + CaretIndex = Text.Length; + SuggestionsVisibility = Visibility.Collapsed; + e.Handled = true; + return; + } + } + } + + base.OnPreviewKeyDown(e); + } + + protected override void OnTextChanged(TextChangedEventArgs e) + { + base.OnTextChanged(e); + + if (CaretIndex == Text.Length) + { + String lastWord = Text.Split(' ').LastOrDefault(); + lastWord?.Trim(); + + if (Suggestions != null) + { + FilteredSuggestions = Suggestions.Where(x => lastWord.IsNotNullOrEmpty() && x.Name.ToLower().StartsWith(lastWord.ToLower())).OrderBy(x => x.Name).Take(MaxSuggestions).ToList(); + + if (Text.Contains(" ")) + { + FilteredSuggestions = FilteredSuggestions.Where(x => x.Type != ConsoleSuggestionType.Command).ToList(); + } + + SuggestionsVisibility = FilteredSuggestions.Count > 0 ? Visibility.Visible : Visibility.Collapsed; + _popup.IsOpen = false; + _popup.IsOpen = FilteredSuggestions.Count > 0 && SelectedSuggestion != null; + } + } + else + { + SuggestionsVisibility = Visibility.Collapsed; + _popup.IsOpen = false; + } + } + + protected override void OnSelectionChanged(RoutedEventArgs e) + { + base.OnSelectionChanged(e); + + if (CaretIndex < Text.Length) + { + SuggestionsVisibility = Visibility.Collapsed; + _popup.IsOpen = false; + } } public override void OnApplyTemplate() @@ -45,6 +236,8 @@ namespace Tango.Console base.OnApplyTemplate(); _caret = GetTemplateChild("PART_Caret") as Border; + _listSuggestions = GetTemplateChild("PART_listSuggestions") as ListBox; + _popup = GetTemplateChild("PART_popup") as Popup; } private void MoveCustomCaret() @@ -54,6 +247,7 @@ namespace Tango.Console if (!double.IsInfinity(caretLocation.X)) { Canvas.SetLeft(_caret, caretLocation.X); + CaretPosition = caretLocation.X; } } } -- cgit v1.3.1