From 080f1697e97e13461ec6df4d31c8924d01257a1b Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Tue, 9 Apr 2019 01:47:48 +0300 Subject: MERGE --- .../Editing/TextAreaInputHandler.cs | 242 +++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/TextAreaInputHandler.cs (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/TextAreaInputHandler.cs') diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/TextAreaInputHandler.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/TextAreaInputHandler.cs new file mode 100644 index 000000000..3256875be --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/TextAreaInputHandler.cs @@ -0,0 +1,242 @@ +// 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 Tango.Scripting.Editors.Utils; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Windows.Input; + +namespace Tango.Scripting.Editors.Editing +{ + /// + /// A set of input bindings and event handlers for the text area. + /// + /// + /// + /// There is one active input handler per text area (), plus + /// a number of active stacked input handlers. + /// + /// + /// The text area also stores a reference to a default input handler, but that is not necessarily active. + /// + /// + /// Stacked input handlers work in addition to the set of currently active handlers (without detaching them). + /// They are detached in the reverse order of being attached. + /// + /// + public interface ITextAreaInputHandler + { + /// + /// Gets the text area that the input handler belongs to. + /// + TextArea TextArea { + get; + } + + /// + /// Attaches an input handler to the text area. + /// + void Attach(); + + /// + /// Detaches the input handler from the text area. + /// + void Detach(); + } + + /// + /// Stacked input handler. + /// Uses OnEvent-methods instead of registering event handlers to ensure that the events are handled in the correct order. + /// + public abstract class TextAreaStackedInputHandler : ITextAreaInputHandler + { + readonly TextArea textArea; + + /// + public TextArea TextArea { + get { return textArea; } + } + + /// + /// Creates a new TextAreaInputHandler. + /// + protected TextAreaStackedInputHandler(TextArea textArea) + { + if (textArea == null) + throw new ArgumentNullException("textArea"); + this.textArea = textArea; + } + + /// + public virtual void Attach() + { + } + + /// + public virtual void Detach() + { + } + + /// + /// Called for the PreviewKeyDown event. + /// + public virtual void OnPreviewKeyDown(KeyEventArgs e) + { + } + + /// + /// Called for the PreviewKeyUp event. + /// + public virtual void OnPreviewKeyUp(KeyEventArgs e) + { + } + } + + /// + /// Default-implementation of . + /// + /// + public class TextAreaInputHandler : ITextAreaInputHandler + { + readonly ObserveAddRemoveCollection commandBindings; + readonly ObserveAddRemoveCollection inputBindings; + readonly ObserveAddRemoveCollection nestedInputHandlers; + readonly TextArea textArea; + bool isAttached; + + /// + /// Creates a new TextAreaInputHandler. + /// + public TextAreaInputHandler(TextArea textArea) + { + if (textArea == null) + throw new ArgumentNullException("textArea"); + this.textArea = textArea; + commandBindings = new ObserveAddRemoveCollection(CommandBinding_Added, CommandBinding_Removed); + inputBindings = new ObserveAddRemoveCollection(InputBinding_Added, InputBinding_Removed); + nestedInputHandlers = new ObserveAddRemoveCollection(NestedInputHandler_Added, NestedInputHandler_Removed); + } + + /// + public TextArea TextArea { + get { return textArea; } + } + + /// + /// Gets whether the input handler is currently attached to the text area. + /// + public bool IsAttached { + get { return isAttached; } + } + + #region CommandBindings / InputBindings + /// + /// Gets the command bindings of this input handler. + /// + public ICollection CommandBindings { + get { return commandBindings; } + } + + void CommandBinding_Added(CommandBinding commandBinding) + { + if (isAttached) + textArea.CommandBindings.Add(commandBinding); + } + + void CommandBinding_Removed(CommandBinding commandBinding) + { + if (isAttached) + textArea.CommandBindings.Remove(commandBinding); + } + + /// + /// Gets the input bindings of this input handler. + /// + public ICollection InputBindings { + get { return inputBindings; } + } + + void InputBinding_Added(InputBinding inputBinding) + { + if (isAttached) + textArea.InputBindings.Add(inputBinding); + } + + void InputBinding_Removed(InputBinding inputBinding) + { + if (isAttached) + textArea.InputBindings.Remove(inputBinding); + } + + /// + /// Adds a command and input binding. + /// + /// The command ID. + /// The modifiers of the keyboard shortcut. + /// The key of the keyboard shortcut. + /// The event handler to run when the command is executed. + public void AddBinding(ICommand command, ModifierKeys modifiers, Key key, ExecutedRoutedEventHandler handler) + { + this.CommandBindings.Add(new CommandBinding(command, handler)); + this.InputBindings.Add(new KeyBinding(command, key, modifiers)); + } + #endregion + + #region NestedInputHandlers + /// + /// Gets the collection of nested input handlers. NestedInputHandlers are activated and deactivated + /// together with this input handler. + /// + public ICollection NestedInputHandlers { + get { return nestedInputHandlers; } + } + + void NestedInputHandler_Added(ITextAreaInputHandler handler) + { + if (handler == null) + throw new ArgumentNullException("handler"); + if (handler.TextArea != textArea) + throw new ArgumentException("The nested handler must be working for the same text area!"); + if (isAttached) + handler.Attach(); + } + + void NestedInputHandler_Removed(ITextAreaInputHandler handler) + { + if (isAttached) + handler.Detach(); + } + #endregion + + #region Attach/Detach + /// + public virtual void Attach() + { + if (isAttached) + throw new InvalidOperationException("Input handler is already attached"); + isAttached = true; + + textArea.CommandBindings.AddRange(commandBindings); + textArea.InputBindings.AddRange(inputBindings); + foreach (ITextAreaInputHandler handler in nestedInputHandlers) + handler.Attach(); + } + + /// + public virtual void Detach() + { + if (!isAttached) + throw new InvalidOperationException("Input handler is not attached"); + isAttached = false; + + foreach (CommandBinding b in commandBindings) + textArea.CommandBindings.Remove(b); + foreach (InputBinding b in inputBindings) + textArea.InputBindings.Remove(b); + foreach (ITextAreaInputHandler handler in nestedInputHandlers) + handler.Detach(); + } + #endregion + } +} -- cgit v1.3.1