diff options
Diffstat (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CodeCompletion/CompletionWindow.cs')
| -rw-r--r-- | Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CodeCompletion/CompletionWindow.cs | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CodeCompletion/CompletionWindow.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CodeCompletion/CompletionWindow.cs new file mode 100644 index 000000000..33759e351 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CodeCompletion/CompletionWindow.cs @@ -0,0 +1,196 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Diagnostics; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Controls.Primitives; +using System.Windows.Data; +using System.Windows.Input; +using System.Windows.Threading; +using Tango.Scripting.Editors.Document; +using Tango.Scripting.Editors.Editing; +using System.Windows.Media; + +namespace Tango.Scripting.Editors.CodeCompletion +{ + /// <summary> + /// The code completion window. + /// </summary> + public class CompletionWindow : CompletionWindowBase + { + readonly CompletionList completionList = new CompletionList(); + + public event Action<ICompletionData> InsertionRequest; + + /// <summary> + /// Gets the completion list used in this completion window. + /// </summary> + public CompletionList CompletionList + { + get { return completionList; } + } + + /// <summary> + /// Creates a new code completion window. + /// </summary> + public CompletionWindow(TextArea textArea) : base(textArea) + { + + // keep height automatic + this.CloseAutomatically = true; + this.SizeToContent = SizeToContent.WidthAndHeight; + this.WindowStyle = WindowStyle.None; + this.ResizeMode = ResizeMode.NoResize; + this.Content = completionList; + // prevent user from resizing window to 0x0 + this.MinHeight = 15; + this.MinWidth = 30; + //this.Background = new SolidColorBrush(Color.FromRgb(15, 15, 15)); + this.Foreground = Brushes.Gainsboro; + } + + public override void ShowCompletion() + { + base.ShowCompletion(); + AttachEvents(); + } + + public override void HideCompletion() + { + base.HideCompletion(); + + foreach (var item in completionList.ListBox.Items) + { + var box = completionList.ListBox.ItemContainerGenerator.ContainerFromItem(item) as CompletionListBoxItem; + if (box != null && box.IsSelected) + { + box.toolTip.IsOpen = false; + } + } + } + + void completionList_InsertionRequested(object sender, EventArgs e) + { + HideCompletion(); + // The window must close before Complete() is called. + // If the Complete callback pushes stacked input handlers, we don't want to pop those when the CC window closes. + var item = completionList.SelectedItem; + //if (item != null) + // item.Complete(this.TextArea, new AnchorSegment(this.TextArea.Document, this.StartOffset, this.EndOffset - this.StartOffset), e); + + if (item != null) + { + InsertionRequest?.Invoke(item); + } + + completionList.SelectedItem = null; + } + + void AttachEvents() + { + this.completionList.InsertionRequested += completionList_InsertionRequested; + this.TextArea.Caret.PositionChanged += CaretPositionChanged; + this.TextArea.MouseWheel += textArea_MouseWheel; + this.TextArea.PreviewTextInput += textArea_PreviewTextInput; + } + + /// <inheritdoc/> + protected override void DetachEvents() + { + this.completionList.InsertionRequested -= completionList_InsertionRequested; + this.TextArea.Caret.PositionChanged -= CaretPositionChanged; + this.TextArea.MouseWheel -= textArea_MouseWheel; + this.TextArea.PreviewTextInput -= textArea_PreviewTextInput; + base.DetachEvents(); + } + + /// <inheritdoc/> + protected override void OnKeyDown(KeyEventArgs e) + { + base.OnKeyDown(e); + if (!e.Handled) + { + completionList.HandleKey(e); + } + } + + void textArea_PreviewTextInput(object sender, TextCompositionEventArgs e) + { + e.Handled = RaiseEventPair(this, PreviewTextInputEvent, TextInputEvent, + new TextCompositionEventArgs(e.Device, e.TextComposition)); + + if (e.Text == " ") + { + HideCompletion(); + } + } + + void textArea_MouseWheel(object sender, MouseWheelEventArgs e) + { + e.Handled = RaiseEventPair(GetScrollEventTarget(), + PreviewMouseWheelEvent, MouseWheelEvent, + new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)); + } + + UIElement GetScrollEventTarget() + { + if (completionList == null) + return this; + return completionList.ScrollViewer ?? completionList.ListBox ?? (UIElement)completionList; + } + + /// <summary> + /// Gets/Sets whether the completion window should close automatically. + /// The default value is true. + /// </summary> + public bool CloseAutomatically { get; set; } + + /// <inheritdoc/> + protected override bool CloseOnFocusLost + { + get { return this.CloseAutomatically; } + } + + /// <summary> + /// When this flag is set, code completion closes if the caret moves to the + /// beginning of the allowed range. This is useful in Ctrl+Space and "complete when typing", + /// but not in dot-completion. + /// Has no effect if CloseAutomatically is false. + /// </summary> + public bool CloseWhenCaretAtBeginning { get; set; } + + void CaretPositionChanged(object sender, EventArgs e) + { + int offset = this.TextArea.Caret.Offset; + if (offset == this.StartOffset) + { + if (CloseAutomatically && CloseWhenCaretAtBeginning) + { + HideCompletion(); + } + else + { + completionList.SelectItem(string.Empty); + } + return; + } + if (offset < this.StartOffset || offset > this.EndOffset) + { + if (CloseAutomatically) + { + HideCompletion(); + } + } + else + { + TextDocument document = this.TextArea.Document; + if (document != null) + { + completionList.SelectItem(document.GetText(this.StartOffset, offset - this.StartOffset)); + } + } + } + } +} |
