// 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.ComponentModel; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media.TextFormatting; using System.Windows.Threading; using Tango.Scripting.Editors.Document; using Tango.Scripting.Editors.Rendering; using Tango.Scripting.Editors.Utils; namespace Tango.Scripting.Editors.Editing { /// /// Handles selection of text using the mouse. /// sealed class SelectionMouseHandler : ITextAreaInputHandler { #region enum SelectionMode enum SelectionMode { /// /// no selection (no mouse button down) /// None, /// /// left mouse button down on selection, might be normal click /// or might be drag'n'drop /// PossibleDragStart, /// /// dragging text /// Drag, /// /// normal selection (click+drag) /// Normal, /// /// whole-word selection (double click+drag or ctrl+click+drag) /// WholeWord, /// /// whole-line selection (triple click+drag) /// WholeLine, /// /// rectangular selection (alt+click+drag) /// Rectangular } #endregion readonly TextArea textArea; SelectionMode mode; AnchorSegment startWord; Point possibleDragStartMousePos; #region Constructor + Attach + Detach public SelectionMouseHandler(TextArea textArea) { if (textArea == null) throw new ArgumentNullException("textArea"); this.textArea = textArea; } public TextArea TextArea { get { return textArea; } } public void Attach() { textArea.MouseLeftButtonDown += textArea_MouseLeftButtonDown; textArea.MouseMove += textArea_MouseMove; textArea.MouseLeftButtonUp += textArea_MouseLeftButtonUp; textArea.QueryCursor += textArea_QueryCursor; textArea.OptionChanged += textArea_OptionChanged; enableTextDragDrop = textArea.Options.EnableTextDragDrop; if (enableTextDragDrop) { AttachDragDrop(); } } public void Detach() { mode = SelectionMode.None; textArea.MouseLeftButtonDown -= textArea_MouseLeftButtonDown; textArea.MouseMove -= textArea_MouseMove; textArea.MouseLeftButtonUp -= textArea_MouseLeftButtonUp; textArea.QueryCursor -= textArea_QueryCursor; textArea.OptionChanged -= textArea_OptionChanged; if (enableTextDragDrop) { DetachDragDrop(); } } void AttachDragDrop() { textArea.AllowDrop = true; textArea.GiveFeedback += textArea_GiveFeedback; textArea.QueryContinueDrag += textArea_QueryContinueDrag; textArea.DragEnter += textArea_DragEnter; textArea.DragOver += textArea_DragOver; textArea.DragLeave += textArea_DragLeave; textArea.Drop += textArea_Drop; } void DetachDragDrop() { textArea.AllowDrop = false; textArea.GiveFeedback -= textArea_GiveFeedback; textArea.QueryContinueDrag -= textArea_QueryContinueDrag; textArea.DragEnter -= textArea_DragEnter; textArea.DragOver -= textArea_DragOver; textArea.DragLeave -= textArea_DragLeave; textArea.Drop -= textArea_Drop; } bool enableTextDragDrop; void textArea_OptionChanged(object sender, PropertyChangedEventArgs e) { bool newEnableTextDragDrop = textArea.Options.EnableTextDragDrop; if (newEnableTextDragDrop != enableTextDragDrop) { enableTextDragDrop = newEnableTextDragDrop; if (newEnableTextDragDrop) AttachDragDrop(); else DetachDragDrop(); } } #endregion #region Dropping text [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] void textArea_DragEnter(object sender, DragEventArgs e) { try { e.Effects = GetEffect(e); textArea.Caret.Show(); } catch (Exception ex) { OnDragException(ex); } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] void textArea_DragOver(object sender, DragEventArgs e) { try { e.Effects = GetEffect(e); } catch (Exception ex) { OnDragException(ex); } } DragDropEffects GetEffect(DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.UnicodeText, true)) { e.Handled = true; int visualColumn; int offset = GetOffsetFromMousePosition(e.GetPosition(textArea.TextView), out visualColumn); if (offset >= 0) { textArea.Caret.Position = new TextViewPosition(textArea.Document.GetLocation(offset), visualColumn); textArea.Caret.DesiredXPos = double.NaN; if (textArea.ReadOnlySectionProvider.CanInsert(offset)) { if ((e.AllowedEffects & DragDropEffects.Move) == DragDropEffects.Move && (e.KeyStates & DragDropKeyStates.ControlKey) != DragDropKeyStates.ControlKey) { return DragDropEffects.Move; } else { return e.AllowedEffects & DragDropEffects.Copy; } } } } return DragDropEffects.None; } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] void textArea_DragLeave(object sender, DragEventArgs e) { try { e.Handled = true; if (!textArea.IsKeyboardFocusWithin) textArea.Caret.Hide(); } catch (Exception ex) { OnDragException(ex); } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] void textArea_Drop(object sender, DragEventArgs e) { try { DragDropEffects effect = GetEffect(e); e.Effects = effect; if (effect != DragDropEffects.None) { string text = e.Data.GetData(DataFormats.UnicodeTex
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Core.Commands;
using Tango.MachineStudio.Synchronization.Navigation;
using Tango.SharedUI;

namespace Tango.MachineStudio.Synchronization.ViewModels
{
    /// <summary>
    /// Represents the synchronization module main menu view, view model.
    /// </summary>
    /// <seealso cref="Tango.SharedUI.ViewModel" />
    public class MenuViewVM : ViewModel
    {
        private SyncNavigationManager _navigation;

        /// <summary>
        /// Initializes a new instance of the <see cref="MenuViewVM"/> class.
        /// </summary>
        /// <param name="navigation">The navigation.</param>
        public MenuViewVM(SyncNavigationManager navigation)
        {
            _navigation = navigation;

            StartLocalSyncCommand = new RelayCommand(() => { _navigation.NavigateTo(NavigationView.LocalSynchronizationView); });
            StartRemoteSyncCommand = new RelayCommand(() => { _navigation.NavigateTo(NavigationView.RemoteSynchronizationView); });
            StartDirectRemoteSyncCommand = new RelayCommand(() => { _navigation.NavigateTo(NavigationView.DirectSynchronizationView); });
        }

        /// <summary>
        /// Gets or sets the start local synchronize command.
        /// </summary>
        public RelayCommand StartLocalSyncCommand { get; set; }

        /// <summary>
        /// Gets or sets the start remote synchronize command.
        /// </summary>
        public RelayCommand StartRemoteSyncCommand { get; set; }

        /// <summary>
        /// Gets or sets the start direct remote synchronize command.
        /// </summary>
        public RelayCommand StartDirectRemoteSyncCommand { get; set; }
    }
}
else if (mode == SelectionMode.PossibleDragStart) { e.Handled = true; Vector mouseMovement = e.GetPosition(textArea) - possibleDragStartMousePos; if (Math.Abs(mouseMovement.X) > SystemParameters.MinimumHorizontalDragDistance || Math.Abs(mouseMovement.Y) > SystemParameters.MinimumVerticalDragDistance) { StartDrag(); } } } #endregion #region ExtendSelection void SetCaretOffsetToMousePosition(MouseEventArgs e) { SetCaretOffsetToMousePosition(e, null); } void SetCaretOffsetToMousePosition(MouseEventArgs e, ISegment allowedSegment) { int visualColumn; int offset; if (mode == SelectionMode.Rectangular) offset = GetOffsetFromMousePositionFirstTextLineOnly(e.GetPosition(textArea.TextView), out visualColumn); else offset = GetOffsetFromMousePosition(e, out visualColumn); if (allowedSegment != null) { offset = offset.CoerceValue(allowedSegment.Offset, allowedSegment.EndOffset); } if (offset >= 0) { textArea.Caret.Position = new TextViewPosition(textArea.Document.GetLocation(offset), visualColumn); textArea.Caret.DesiredXPos = double.NaN; } } void ExtendSelectionToMouse(MouseEventArgs e) { TextViewPosition oldPosition = textArea.Caret.Position; if (mode == SelectionMode.Normal || mode == SelectionMode.Rectangular) { SetCaretOffsetToMousePosition(e); if (mode == SelectionMode.Normal && textArea.Selection is RectangleSelection) textArea.Selection = new SimpleSelection(textArea, oldPosition, textArea.Caret.Position); else if (mode == SelectionMode.Rectangular && !(textArea.Selection is RectangleSelection)) textArea.Selection = new RectangleSelection(textArea, oldPosition, textArea.Caret.Position); else textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position); } else if (mode == SelectionMode.WholeWord || mode == SelectionMode.WholeLine) { var newWord = (mode == SelectionMode.WholeLine) ? GetLineAtMousePosition(e) : GetWordAtMousePosition(e); if (newWord != SimpleSegment.Invalid) { textArea.Selection = Selection.Create(textArea, Math.Min(newWord.Offset, startWord.Offset), Math.Max(newWord.EndOffset, startWord.EndOffset)); // Set caret offset, but limit the caret to stay inside the selection. // in whole-word selection, it's otherwise possible that we get the caret outside the // selection - but the TextArea doesn't like that and will reset the selection, causing // flickering. SetCaretOffsetToMousePosition(e, textArea.Selection.SurroundingSegment); } } textArea.Caret.BringCaretToView(5.0); } #endregion #region MouseLeftButtonUp void textArea_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (mode == SelectionMode.None || e.Handled) return; e.Handled = true; if (mode == SelectionMode.PossibleDragStart) { // -> this was not a drag start (mouse didn't move after mousedown) SetCaretOffsetToMousePosition(e); textArea.ClearSelection(); } else if (mode == SelectionMode.Normal || mode == SelectionMode.WholeWord || mode == SelectionMode.WholeLine || mode == SelectionMode.Rectangular) { ExtendSelectionToMouse(e); } mode = SelectionMode.None; textArea.ReleaseMouseCapture(); } #endregion } }