static ExecutedRoutedEventHandler OnMoveCaretExtendSelection(CaretMovementType direction)
        {
            return((target, args) =>
            {
                TextArea textArea = GetTextArea(target);
                if (textArea != null && textArea.Document != null)
                {
                    args.Handled = true;
                    var oldPosition = textArea.Caret.Position;
                    MoveCaret(textArea, direction);

                    if (direction < CaretMovementType.MultyLeft)
                    {
                        textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
                    }
                    else
                    {
                        if (textArea.Selection is RectangleSelection)
                        {
                            textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
                        }
                        else
                        {
                            textArea.Selection = new RectangleSelection(textArea, oldPosition, textArea.Caret.Position);
                        }
                    }

                    textArea.Caret.BringCaretToView();
                }
            });
        }
Example #2
0
        internal static void MoveCaret(TextArea textArea, CaretMovementType direction)
        {
            double desiredXPos = textArea.Caret.DesiredXPos;

            if (textArea.FlowDirection == FlowDirection.RightToLeft)
            {
                if (direction == CaretMovementType.CharLeft)
                {
                    direction = CaretMovementType.CharRight;
                }
                else if (direction == CaretMovementType.CharRight)
                {
                    direction = CaretMovementType.CharLeft;
                }
                else if (direction == CaretMovementType.WordRight)
                {
                    direction = CaretMovementType.WordLeft;
                }
                else if (direction == CaretMovementType.WordLeft)
                {
                    direction = CaretMovementType.WordRight;
                }
            }

            textArea.Caret.Position    = GetNewCaretPosition(textArea.TextView, textArea.Caret.Position, direction, textArea.Selection.EnableVirtualSpace, ref desiredXPos);
            textArea.Caret.DesiredXPos = desiredXPos;
        }
Example #3
0
 static ExecutedRoutedEventHandler OnMoveCaretExtendSelection(CaretMovementType direction)
 {
     return((target, args) =>
     {
         TextArea textArea = GetTextArea(target);
         if (textArea != null && textArea.Document != null)
         {
             switch (direction)
             {
             case CaretMovementType.LineUp:
             case CaretMovementType.LineDown:
                 if (textArea.IsCodeCompleteMode)
                 {
                     return;
                 }
                 break;
             }
             args.Handled = true;
             TextViewPosition oldPosition = textArea.Caret.Position;
             MoveCaret(textArea, direction);
             textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
             if (!textArea.Document.IsInUpdate) // if we're inside a larger update (e.g. called by EditingCommandHandler.OnDelete()), avoid calculating the caret rectangle now
             {
                 textArea.Caret.BringCaretToView();
             }
         }
     });
 }
        internal static void MoveCaret(TextArea textArea, CaretMovementType direction)
        {
            double desiredXPos = textArea.Caret.DesiredXPos;

            textArea.Caret.Position    = GetNewCaretPosition(textArea.TextView, textArea.Caret.Position, direction, textArea.Selection.EnableVirtualSpace, ref desiredXPos);
            textArea.Caret.DesiredXPos = desiredXPos;
        }
 static ExecutedRoutedEventHandler OnMoveCaretBoxSelection(CaretMovementType direction)
 {
     return((target, args) => {
         TextArea textArea = GetTextArea(target);
         if (textArea != null && textArea.Document != null)
         {
             args.Handled = true;
             // First, convert the selection into a rectangle selection
             // (this is required so that virtual space gets enabled for the caret movement)
             if (textArea.Options.EnableRectangularSelection && !(textArea.Selection is RectangleSelection))
             {
                 if (textArea.Selection.IsEmpty)
                 {
                     textArea.Selection = new RectangleSelection(textArea, textArea.Caret.Position, textArea.Caret.Position);
                 }
                 else
                 {
                     // Convert normal selection to rectangle selection
                     textArea.Selection = new RectangleSelection(textArea, textArea.Selection.StartPosition, textArea.Caret.Position);
                 }
             }
             // Now move the caret and extend the selection
             TextViewPosition oldPosition = textArea.Caret.Position;
             MoveCaret(textArea, direction);
             textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
             textArea.Caret.BringCaretToView();
         }
     });
 }
Example #6
0
        static void MoveCaret(TextArea textArea, CaretMovementType direction)
        {
            DocumentLine     caretLine     = textArea.Document.GetLineByNumber(textArea.Caret.Line);
            VisualLine       visualLine    = textArea.TextView.GetOrConstructVisualLine(caretLine);
            TextViewPosition caretPosition = textArea.Caret.Position;
            TextLine         textLine      = visualLine.GetTextLine(caretPosition.VisualColumn);

            switch (direction)
            {
            case CaretMovementType.CharLeft:
                MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.Normal);
                break;

            case CaretMovementType.CharRight:
                MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.Normal);
                break;

            case CaretMovementType.WordLeft:
                MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart);
                break;

            case CaretMovementType.WordRight:
                MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart);
                break;

            case CaretMovementType.LineUp:
            case CaretMovementType.LineDown:
            case CaretMovementType.PageUp:
            case CaretMovementType.PageDown:
                MoveCaretUpDown(textArea, direction, visualLine, textLine, caretPosition.VisualColumn);
                break;

            case CaretMovementType.DocumentStart:
                SetCaretPosition(textArea, 0, 0);
                break;

            case CaretMovementType.DocumentEnd:
                SetCaretPosition(textArea, -1, textArea.Document.TextLength);
                break;

            case CaretMovementType.LineStart:
                MoveCaretToStartOfLine(textArea, visualLine);
                break;

            case CaretMovementType.LineEnd:
                MoveCaretToEndOfLine(textArea, visualLine);
                break;

            default:
                throw new NotSupportedException(direction.ToString());
            }
        }
Example #7
0
 static ExecutedRoutedEventHandler OnMoveCaret(CaretMovementType direction)
 {
     return((target, args) => {
         TextArea textArea = GetTextArea(target);
         if (textArea != null && textArea.Document != null)
         {
             args.Handled = true;
             textArea.Selection = Selection.Empty;
             MoveCaret(textArea, direction);
             textArea.Caret.BringCaretToView();
         }
     });
 }
Example #8
0
 private static EventHandler <ExecutedRoutedEventArgs> OnMoveCaret(CaretMovementType direction)
 {
     return((target, args) =>
     {
         var textArea = GetTextArea(target);
         if (textArea?.Document != null)
         {
             args.Handled = true;
             textArea.ClearSelection();
             MoveCaret(textArea, direction);
             textArea.Caret.BringCaretToView();
         }
     });
 }
Example #9
0
 static ExecutedRoutedEventHandler OnMoveCaretExtendSelection(CaretMovementType direction)
 {
     return((target, args) => {
         TextArea textArea = GetTextArea(target);
         if (textArea != null && textArea.Document != null)
         {
             args.Handled = true;
             int oldOffset = textArea.Caret.Offset;
             MoveCaret(textArea, direction);
             textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldOffset, textArea.Caret.Offset);
             textArea.Caret.BringCaretToView();
         }
     });
 }
Example #10
0
 private static ExecutedRoutedEventHandler CaretHandler(CaretMovementType caretMovementType, Boolean doSelect)
 {
     return((sender, e) =>
     {
         if (e.Handled)
         {
             return;
         }
         EditView editor = sender as EditView;
         editor.MoveCaret(caretMovementType, doSelect);
         editor.Redraw();
         e.Handled = true;
     });
 }
Example #11
0
 private static EventHandler <ExecutedRoutedEventArgs> OnDelete(CaretMovementType caretMovement)
 {
     return((target, args) =>
     {
         var textArea = GetTextArea(target);
         if (textArea?.Document != null)
         {
             if (textArea.Selection.IsEmpty)
             {
                 var startPos = textArea.Caret.Position;
                 var enableVirtualSpace = textArea.Options.EnableVirtualSpace;
                 // When pressing delete; don't move the caret further into virtual space - instead delete the newline
                 if (caretMovement == CaretMovementType.CharRight)
                 {
                     enableVirtualSpace = false;
                 }
                 var desiredXPos = textArea.Caret.DesiredXPos;
                 var endPos = CaretNavigationCommandHandler.GetNewCaretPosition(
                     textArea.TextView, startPos, caretMovement, enableVirtualSpace, ref desiredXPos);
                 // GetNewCaretPosition may return (0,0) as new position,
                 // thus we need to validate endPos before using it in the selection.
                 if (endPos.Line < 1 || endPos.Column < 1)
                 {
                     endPos = new TextViewPosition(Math.Max(endPos.Line, 1), Math.Max(endPos.Column, 1));
                 }
                 // Don't do anything if the number of lines of a rectangular selection would be changed by the deletion.
                 if (textArea.Selection is RectangleSelection && startPos.Line != endPos.Line)
                 {
                     return;
                 }
                 // Don't select the text to be deleted; just reuse the ReplaceSelectionWithText logic
                 // Reuse the existing selection, so that we continue using the same logic
                 textArea.Selection.StartSelectionOrSetEndpoint(startPos, endPos)
                 .ReplaceSelectionWithText(string.Empty);
             }
             else
             {
                 textArea.RemoveSelectedText();
             }
             textArea.Caret.BringCaretToView();
             args.Handled = true;
         }
     });
 }
 private static EventHandler <ExecutedRoutedEventArgs> OnDelete(CaretMovementType caretMovement)
 {
     return((target, args) =>
     {
         var textArea = GetTextArea(target);
         if (textArea?.Document != null)
         {
             if (textArea.Selection.IsEmpty)
             {
                 var startPos = textArea.Caret.Position;
                 var enableVirtualSpace = textArea.Options.EnableVirtualSpace;
                 // When pressing delete; don't move the caret further into virtual space - instead delete the newline
                 if (caretMovement == CaretMovementType.CharRight)
                 {
                     enableVirtualSpace = false;
                 }
                 var desiredXPos = textArea.Caret.DesiredXPos;
                 var endPos = CaretNavigationCommandHandler.GetNewCaretPosition(
                     textArea.TextView, startPos, caretMovement, enableVirtualSpace, ref desiredXPos);
                 // GetNewCaretPosition may return (0,0) as new position,
                 // thus we need to validate endPos before using it in the selection.
                 if (endPos.Line < 1 || endPos.Column < 1)
                 {
                     endPos = new TextViewPosition(Math.Max(endPos.Line, 1), Math.Max(endPos.Column, 1));
                 }
                 // Don't select the text to be deleted; just reuse the ReplaceSelectionWithText logic
                 var sel = new SimpleSelection(textArea, startPos, endPos);
                 sel.ReplaceSelectionWithText(string.Empty);
             }
             else
             {
                 textArea.RemoveSelectedText();
             }
             textArea.Caret.BringCaretToView();
             args.Handled = true;
         }
     });
 }
Example #13
0
 static ExecutedRoutedEventHandler OnMoveCaret(CaretMovementType direction)
 {
     return((target, args) =>
     {
         TextArea textArea = GetTextArea(target);
         if (textArea != null && textArea.Document != null)
         {
             switch (direction)
             {
             case CaretMovementType.LineUp:
             case CaretMovementType.LineDown:
                 if (textArea.IsCodeCompleteMode)
                 {
                     return;
                 }
                 break;
             }
             args.Handled = true;
             textArea.ClearSelection();
             MoveCaret(textArea, direction);
             textArea.Caret.BringCaretToView();
         }
     });
 }
		static ExecutedRoutedEventHandler OnMoveCaretBoxSelection(CaretMovementType direction)
		{
			return (target, args) => {
				TextArea textArea = GetTextArea(target);
				if (textArea != null && textArea.Document != null) {
					args.Handled = true;
					// First, convert the selection into a rectangle selection
					// (this is required so that virtual space gets enabled for the caret movement)
					if (textArea.Options.EnableRectangularSelection && !(textArea.Selection is RectangleSelection)) {
						if (textArea.Selection.IsEmpty) {
							textArea.Selection = new RectangleSelection(textArea, textArea.Caret.Position, textArea.Caret.Position);
						} else {
							// Convert normal selection to rectangle selection
							textArea.Selection = new RectangleSelection(textArea, textArea.Selection.StartPosition, textArea.Caret.Position);
						}
					}
					// Now move the caret and extend the selection
					TextViewPosition oldPosition = textArea.Caret.Position;
					MoveCaret(textArea, direction);
					textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
					textArea.Caret.BringCaretToView();
				}
			};
		}
		internal static void MoveCaret(TextArea textArea, CaretMovementType direction)
		{
			double desiredXPos = textArea.Caret.DesiredXPos;
			textArea.Caret.Position = GetNewCaretPosition(textArea.TextView, textArea.Caret.Position, direction, textArea.Selection.EnableVirtualSpace, ref desiredXPos);
			textArea.Caret.DesiredXPos = desiredXPos;
		}
		internal static TextViewPosition GetNewCaretPosition(TextView textView, TextViewPosition caretPosition, CaretMovementType direction, bool enableVirtualSpace, ref double desiredXPos)
		{
			switch (direction) {
				case CaretMovementType.None:
					return caretPosition;
				case CaretMovementType.DocumentStart:
					desiredXPos = double.NaN;
					return new TextViewPosition(0, 0);
				case CaretMovementType.DocumentEnd:
					desiredXPos = double.NaN;
					return new TextViewPosition(textView.Document.GetLocation(textView.Document.TextLength));
			}
			DocumentLine caretLine = textView.Document.GetLineByNumber(caretPosition.Line);
			VisualLine visualLine = textView.GetOrConstructVisualLine(caretLine);
			TextLine textLine = visualLine.GetTextLine(caretPosition.VisualColumn, caretPosition.IsAtEndOfLine);
			switch (direction) {
				case CaretMovementType.CharLeft:
					desiredXPos = double.NaN;
					return GetPrevCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.Normal, enableVirtualSpace);
				case CaretMovementType.Backspace:
					desiredXPos = double.NaN;
					return GetPrevCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.EveryCodepoint, enableVirtualSpace);
				case CaretMovementType.CharRight:
					desiredXPos = double.NaN;
					return GetNextCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.Normal, enableVirtualSpace);
				case CaretMovementType.WordLeft:
					desiredXPos = double.NaN;
					return GetPrevCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.WordStart, enableVirtualSpace);
				case CaretMovementType.WordRight:
					desiredXPos = double.NaN;
					return GetNextCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.WordStart, enableVirtualSpace);
				case CaretMovementType.LineUp:
				case CaretMovementType.LineDown:
				case CaretMovementType.PageUp:
				case CaretMovementType.PageDown:
					return GetUpDownCaretPosition(textView, caretPosition, direction, visualLine, textLine, enableVirtualSpace, ref desiredXPos);
				case CaretMovementType.LineStart:
					desiredXPos = double.NaN;
					return GetStartOfLineCaretPosition(caretPosition.VisualColumn, visualLine, textLine, enableVirtualSpace);
				case CaretMovementType.LineEnd:
					desiredXPos = double.NaN;
					return GetEndOfLineCaretPosition(visualLine, textLine);
				default:
					throw new NotSupportedException(direction.ToString());
			}
		}
		static TextViewPosition GetUpDownCaretPosition(TextView textView, TextViewPosition caretPosition, CaretMovementType direction, VisualLine visualLine, TextLine textLine, bool enableVirtualSpace, ref double xPos)
		{
			// moving up/down happens using the desired visual X position
			if (double.IsNaN(xPos))
				xPos = visualLine.GetTextLineVisualXPosition(textLine, caretPosition.VisualColumn);
			// now find the TextLine+VisualLine where the caret will end up in
			VisualLine targetVisualLine = visualLine;
			TextLine targetLine;
			int textLineIndex = visualLine.TextLines.IndexOf(textLine);
			switch (direction) {
				case CaretMovementType.LineUp:
					{
						// Move up: move to the previous TextLine in the same visual line
						// or move to the last TextLine of the previous visual line
						int prevLineNumber = visualLine.FirstDocumentLine.LineNumber - 1;
						if (textLineIndex > 0) {
							targetLine = visualLine.TextLines[textLineIndex - 1];
						} else if (prevLineNumber >= 1) {
							DocumentLine prevLine = textView.Document.GetLineByNumber(prevLineNumber);
							targetVisualLine = textView.GetOrConstructVisualLine(prevLine);
							targetLine = targetVisualLine.TextLines[targetVisualLine.TextLines.Count - 1];
						} else {
							targetLine = null;
						}
						break;
					}
				case CaretMovementType.LineDown:
					{
						// Move down: move to the next TextLine in the same visual line
						// or move to the first TextLine of the next visual line
						int nextLineNumber = visualLine.LastDocumentLine.LineNumber + 1;
						if (textLineIndex < visualLine.TextLines.Count - 1) {
							targetLine = visualLine.TextLines[textLineIndex + 1];
						} else if (nextLineNumber <= textView.Document.LineCount) {
							DocumentLine nextLine = textView.Document.GetLineByNumber(nextLineNumber);
							targetVisualLine = textView.GetOrConstructVisualLine(nextLine);
							targetLine = targetVisualLine.TextLines[0];
						} else {
							targetLine = null;
						}
						break;
					}
				case CaretMovementType.PageUp:
				case CaretMovementType.PageDown:
					{
						// Page up/down: find the target line using its visual position
						double yPos = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.LineMiddle);
						if (direction == CaretMovementType.PageUp)
							yPos -= textView.RenderSize.Height;
						else
							yPos += textView.RenderSize.Height;
						DocumentLine newLine = textView.GetDocumentLineByVisualTop(yPos);
						targetVisualLine = textView.GetOrConstructVisualLine(newLine);
						targetLine = targetVisualLine.GetTextLineByVisualYPosition(yPos);
						break;
					}
				default:
					throw new NotSupportedException(direction.ToString());
			}
			if (targetLine != null) {
				double yPos = targetVisualLine.GetTextLineVisualYPosition(targetLine, VisualYPosition.LineMiddle);
				int newVisualColumn = targetVisualLine.GetVisualColumn(new Point(xPos, yPos), enableVirtualSpace);
				
				// prevent wrapping to the next line; TODO: could 'IsAtEnd' help here?
				int targetLineStartCol = targetVisualLine.GetTextLineVisualStartColumn(targetLine);
				if (newVisualColumn >= targetLineStartCol + targetLine.Length) {
					if (newVisualColumn <= targetVisualLine.VisualLength)
						newVisualColumn = targetLineStartCol + targetLine.Length - 1;
				}
				return targetVisualLine.GetTextViewPosition(newVisualColumn);
			} else {
				return caretPosition;
			}
		}
Example #18
0
		static ExecutedRoutedEventHandler OnDelete(CaretMovementType caretMovement)
		{
			return (target, args) => {
				TextArea textArea = GetTextArea(target);
				if (textArea != null && textArea.Document != null) {
					if (textArea.Selection.IsEmpty) {
						TextViewPosition startPos = textArea.Caret.Position;
						bool enableVirtualSpace = textArea.Options.EnableVirtualSpace;
						// When pressing delete; don't move the caret further into virtual space - instead delete the newline
						if (caretMovement == CaretMovementType.CharRight)
							enableVirtualSpace = false;
						double desiredXPos = textArea.Caret.DesiredXPos;
						TextViewPosition endPos = CaretNavigationCommandHandler.GetNewCaretPosition(
							textArea.TextView, startPos, caretMovement, enableVirtualSpace, ref desiredXPos);
						// GetNewCaretPosition may return (0,0) as new position,
						// thus we need to validate endPos before using it in the selection.
						if (endPos.Line < 1 || endPos.Column < 1)
							endPos = new TextViewPosition(Math.Max(endPos.Line, 1), Math.Max(endPos.Column, 1));
						// Don't select the text to be deleted; just reuse the ReplaceSelectionWithText logic
						var sel = new SimpleSelection(textArea, startPos, endPos);
						sel.ReplaceSelectionWithText(string.Empty);
					} else {
						textArea.RemoveSelectedText();
					}
					textArea.Caret.BringCaretToView();
					args.Handled = true;
				}
			};
		}
        static TextViewPosition GetUpDownCaretPosition(TextView textView, TextViewPosition caretPosition, CaretMovementType direction, VisualLine visualLine, TextLine textLine, bool enableVirtualSpace, ref double xPos)
        {
            // moving up/down happens using the desired visual X position
            if (double.IsNaN(xPos))
            {
                xPos = visualLine.GetTextLineVisualXPosition(textLine, caretPosition.VisualColumn);
            }
            // now find the TextLine+VisualLine where the caret will end up in
            VisualLine targetVisualLine = visualLine;
            TextLine   targetLine;
            int        textLineIndex = visualLine.TextLines.IndexOf(textLine);

            switch (direction)
            {
            case CaretMovementType.LineUp:
            {
                // Move up: move to the previous TextLine in the same visual line
                // or move to the last TextLine of the previous visual line
                int prevLineNumber = visualLine.FirstDocumentLine.LineNumber - 1;
                if (textLineIndex > 0)
                {
                    targetLine = visualLine.TextLines[textLineIndex - 1];
                }
                else if (prevLineNumber >= 1)
                {
                    DocumentLine prevLine = textView.Document.GetLineByNumber(prevLineNumber);
                    targetVisualLine = textView.GetOrConstructVisualLine(prevLine);
                    targetLine       = targetVisualLine.TextLines[targetVisualLine.TextLines.Count - 1];
                }
                else
                {
                    targetLine = null;
                }
                break;
            }

            case CaretMovementType.LineDown:
            {
                // Move down: move to the next TextLine in the same visual line
                // or move to the first TextLine of the next visual line
                int nextLineNumber = visualLine.LastDocumentLine.LineNumber + 1;
                if (textLineIndex < visualLine.TextLines.Count - 1)
                {
                    targetLine = visualLine.TextLines[textLineIndex + 1];
                }
                else if (nextLineNumber <= textView.Document.LineCount)
                {
                    DocumentLine nextLine = textView.Document.GetLineByNumber(nextLineNumber);
                    targetVisualLine = textView.GetOrConstructVisualLine(nextLine);
                    targetLine       = targetVisualLine.TextLines[0];
                }
                else
                {
                    targetLine = null;
                }
                break;
            }

            case CaretMovementType.PageUp:
            case CaretMovementType.PageDown:
            {
                // Page up/down: find the target line using its visual position
                double yPos = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.LineMiddle);
                if (direction == CaretMovementType.PageUp)
                {
                    yPos -= textView.RenderSize.Height;
                }
                else
                {
                    yPos += textView.RenderSize.Height;
                }
                DocumentLine newLine = textView.GetDocumentLineByVisualTop(yPos);
                targetVisualLine = textView.GetOrConstructVisualLine(newLine);
                targetLine       = targetVisualLine.GetTextLineByVisualYPosition(yPos);
                break;
            }

            default:
                throw new NotSupportedException(direction.ToString());
            }
            if (targetLine != null)
            {
                double yPos            = targetVisualLine.GetTextLineVisualYPosition(targetLine, VisualYPosition.LineMiddle);
                int    newVisualColumn = targetVisualLine.GetVisualColumn(new Point(xPos, yPos), enableVirtualSpace);

                // prevent wrapping to the next line; TODO: could 'IsAtEnd' help here?
                int targetLineStartCol = targetVisualLine.GetTextLineVisualStartColumn(targetLine);
                if (newVisualColumn >= targetLineStartCol + targetLine.Length)
                {
                    if (newVisualColumn <= targetVisualLine.VisualLength)
                    {
                        newVisualColumn = targetLineStartCol + targetLine.Length - 1;
                    }
                }
                return(targetVisualLine.GetTextViewPosition(newVisualColumn));
            }
            else
            {
                return(caretPosition);
            }
        }
        private static void MoveCaret(TextArea textArea, CaretMovementType direction)
        {
            var caretLine     = textArea.Document.GetLineByNumber(textArea.Caret.Line);
            var visualLine    = textArea.TextView.GetOrConstructVisualLine(caretLine);
            var caretPosition = textArea.Caret.Position;
            var textLine      = visualLine.GetTextLine(caretPosition.VisualColumn);

            switch (direction)
            {
                case CaretMovementType.CharLeft:
                    MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.Normal);
                    break;

                case CaretMovementType.CharRight:
                    MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.Normal);
                    break;

                case CaretMovementType.WordLeft:
                    MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart);
                    break;

                case CaretMovementType.WordRight:
                    MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart);
                    break;

                case CaretMovementType.LineUp:
                case CaretMovementType.LineDown:
                case CaretMovementType.PageUp:
                case CaretMovementType.PageDown:
                    MoveCaretUpDown(textArea, direction, visualLine, textLine, caretPosition.VisualColumn);
                    break;

                case CaretMovementType.DocumentStart:
                    SetCaretPosition(textArea, 0, 0);
                    break;

                case CaretMovementType.DocumentEnd:
                    SetCaretPosition(textArea, -1, textArea.Document.TextLength);
                    break;

                case CaretMovementType.LineStart:
                    MoveCaretToStartOfLine(textArea, visualLine);
                    break;

                case CaretMovementType.LineEnd:
                    MoveCaretToEndOfLine(textArea, visualLine);
                    break;

                case CaretMovementType.MultyLeft:
                    textArea.Caret.Position = new TextViewPosition(caretPosition.Line, caretPosition.Column-1);
                    textArea.Caret.DesiredXPos = double.NaN;
                    break;
                case CaretMovementType.MultyUp:
                    textArea.Caret.Position = new TextViewPosition(caretPosition.Line-1, caretPosition.Column);
                    textArea.Caret.DesiredXPos = double.NaN;
                    break;
                case CaretMovementType.MultyRight:
                    textArea.Caret.Position = new TextViewPosition(caretPosition.Line, caretPosition.Column+1);
                    textArea.Caret.DesiredXPos = double.NaN;
                    break;
                case CaretMovementType.MultyDown:
                    textArea.Caret.Position = new TextViewPosition(caretPosition.Line+1, caretPosition.Column);
                    textArea.Caret.DesiredXPos = double.NaN;
                    break;

                default:
                    throw new NotSupportedException(direction.ToString());
            }
        }
Example #21
0
 private static EventHandler <ExecutedRoutedEventArgs> OnMoveCaretExtendSelection(CaretMovementType direction)
 {
     return((target, args) =>
     {
         var textArea = GetTextArea(target);
         if (textArea?.Document != null)
         {
             args.Handled = true;
             var oldPosition = textArea.Caret.Position;
             MoveCaret(textArea, direction);
             textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
             textArea.Caret.BringCaretToView();
         }
     });
 }
 static ExecutedRoutedEventHandler OnMoveCaretExtendSelection(CaretMovementType direction)
 {
     return (target, args) => {
         TextArea textArea = GetTextArea(target);
         if (textArea != null && textArea.Document != null) {
             args.Handled = true;
             int oldOffset = textArea.Caret.Offset;
             MoveCaret(textArea, direction);
             textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldOffset, textArea.Caret.Offset);
             textArea.Caret.BringCaretToView();
         }
     };
 }
 static ExecutedRoutedEventHandler OnMoveCaret(CaretMovementType direction)
 {
     return (target, args) => {
         TextArea textArea = GetTextArea(target);
         if (textArea != null && textArea.Document != null) {
             args.Handled = true;
             textArea.Selection = Selection.Empty;
             MoveCaret(textArea, direction);
             textArea.Caret.BringCaretToView();
         }
     };
 }
 static void MoveCaretUpDown(TextArea textArea, CaretMovementType direction, VisualLine visualLine, TextLine textLine, int caretVisualColumn)
 {
     // moving up/down happens using the desired visual X position
     double xPos = textArea.Caret.DesiredXPos;
     if (double.IsNaN(xPos))
         xPos = textLine.GetDistanceFromCharacterHit(new CharacterHit(caretVisualColumn, 0));
     // now find the TextLine+VisualLine where the caret will end up in
     VisualLine targetVisualLine = visualLine;
     TextLine targetLine;
     int textLineIndex = visualLine.TextLines.IndexOf(textLine);
     switch (direction) {
         case CaretMovementType.LineUp:
             {
                 // Move up: move to the previous TextLine in the same visual line
                 // or move to the last TextLine of the previous visual line
                 int prevLineNumber = visualLine.FirstDocumentLine.LineNumber - 1;
                 if (textLineIndex > 0) {
                     targetLine = visualLine.TextLines[textLineIndex - 1];
                 } else if (prevLineNumber >= 1) {
                     DocumentLine prevLine = textArea.Document.GetLineByNumber(prevLineNumber);
                     targetVisualLine = textArea.TextView.GetOrConstructVisualLine(prevLine);
                     targetLine = targetVisualLine.TextLines[targetVisualLine.TextLines.Count - 1];
                 } else {
                     targetLine = null;
                 }
                 break;
             }
         case CaretMovementType.LineDown:
             {
                 // Move down: move to the next TextLine in the same visual line
                 // or move to the first TextLine of the next visual line
                 int nextLineNumber = visualLine.LastDocumentLine.LineNumber + 1;
                 if (textLineIndex < visualLine.TextLines.Count - 1) {
                     targetLine = visualLine.TextLines[textLineIndex + 1];
                 } else if (nextLineNumber <= textArea.Document.LineCount) {
                     DocumentLine nextLine = textArea.Document.GetLineByNumber(nextLineNumber);
                     targetVisualLine = textArea.TextView.GetOrConstructVisualLine(nextLine);
                     targetLine = targetVisualLine.TextLines[0];
                 } else {
                     targetLine = null;
                 }
                 break;
             }
         case CaretMovementType.PageUp:
         case CaretMovementType.PageDown:
             {
                 // Page up/down: find the target line using its visual position
                 double yPos = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.LineMiddle);
                 if (direction == CaretMovementType.PageUp)
                     yPos -= textArea.TextView.RenderSize.Height;
                 else
                     yPos += textArea.TextView.RenderSize.Height;
                 DocumentLine newLine = textArea.TextView.GetDocumentLineByVisualTop(yPos);
                 targetVisualLine = textArea.TextView.GetOrConstructVisualLine(newLine);
                 targetLine = targetVisualLine.GetTextLineByVisualYPosition(yPos);
                 break;
             }
         default:
             throw new NotSupportedException(direction.ToString());
     }
     if (targetLine != null) {
         CharacterHit ch = targetLine.GetCharacterHitFromDistance(xPos);
         SetCaretPosition(textArea, targetVisualLine, targetLine, ch, false);
         textArea.Caret.DesiredXPos = xPos;
     }
 }
 static void MoveCaret(TextArea textArea, CaretMovementType direction)
 {
     DocumentLine caretLine = textArea.Document.GetLineByNumber(textArea.Caret.Line);
     VisualLine visualLine = textArea.TextView.GetOrConstructVisualLine(caretLine);
     TextViewPosition caretPosition = textArea.Caret.Position;
     TextLine textLine = visualLine.GetTextLine(caretPosition.VisualColumn);
     switch (direction) {
         case CaretMovementType.CharLeft:
             MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.Normal);
             break;
         case CaretMovementType.CharRight:
             MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.Normal);
             break;
         case CaretMovementType.WordLeft:
             MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart);
             break;
         case CaretMovementType.WordRight:
             MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart);
             break;
         case CaretMovementType.LineUp:
         case CaretMovementType.LineDown:
         case CaretMovementType.PageUp:
         case CaretMovementType.PageDown:
             MoveCaretUpDown(textArea, direction, visualLine, textLine, caretPosition.VisualColumn);
             break;
         case CaretMovementType.DocumentStart:
             SetCaretPosition(textArea, 0, 0);
             break;
         case CaretMovementType.DocumentEnd:
             SetCaretPosition(textArea, -1, textArea.Document.TextLength);
             break;
         case CaretMovementType.LineStart:
             MoveCaretToStartOfLine(textArea, visualLine);
             break;
         case CaretMovementType.LineEnd:
             MoveCaretToEndOfLine(textArea, visualLine);
             break;
         default:
             throw new NotSupportedException(direction.ToString());
     }
 }
		static ExecutedRoutedEventHandler OnMoveCaretExtendSelection(CaretMovementType direction)
		{
			return (target, args) => {
				TextArea textArea = GetTextArea(target);
				if (textArea != null && textArea.Document != null) {
					args.Handled = true;
					TextViewPosition oldPosition = textArea.Caret.Position;
					MoveCaret(textArea, direction);
					textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
					if (!textArea.Document.IsInUpdate) // if we're inside a larger update (e.g. called by EditingCommandHandler.OnDelete()), avoid calculating the caret rectangle now
						textArea.Caret.BringCaretToView();
				}
			};
		}
        private static ExecutedRoutedEventHandler OnMoveCaretExtendSelection(CaretMovementType direction)
        {
            return (target, args) =>
            {
                TextArea textArea = GetTextArea(target);
                if (textArea != null && textArea.Document != null)
                {
                    args.Handled = true;
                    var oldPosition = textArea.Caret.Position;
                    MoveCaret(textArea, direction);

                    if (direction < CaretMovementType.MultyLeft)
                        textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
                    else
                    {
                        if (textArea.Selection is RectangleSelection)
                            textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
                        else
                            textArea.Selection = new RectangleSelection(textArea, oldPosition, textArea.Caret.Position);
                    }

                    textArea.Caret.BringCaretToView();
                }
            };
        }
Example #28
0
        static void MoveCaretUpDown(TextArea textArea, CaretMovementType direction, VisualLine visualLine, TextLine textLine, int caretVisualColumn)
        {
            // moving up/down happens using the desired visual X position
            double xPos = textArea.Caret.DesiredXPos;

            if (double.IsNaN(xPos))
            {
                xPos = textLine.GetDistanceFromCharacterHit(new CharacterHit(caretVisualColumn, 0));
            }
            // now find the TextLine+VisualLine where the caret will end up in
            VisualLine targetVisualLine = visualLine;
            TextLine   targetLine;
            int        textLineIndex = visualLine.TextLines.IndexOf(textLine);

            switch (direction)
            {
            case CaretMovementType.LineUp:
            {
                // Move up: move to the previous TextLine in the same visual line
                // or move to the last TextLine of the previous visual line
                int prevLineNumber = visualLine.FirstDocumentLine.LineNumber - 1;
                if (textLineIndex > 0)
                {
                    targetLine = visualLine.TextLines[textLineIndex - 1];
                }
                else if (prevLineNumber >= 1)
                {
                    DocumentLine prevLine = textArea.Document.GetLineByNumber(prevLineNumber);
                    targetVisualLine = textArea.TextView.GetOrConstructVisualLine(prevLine);
                    targetLine       = targetVisualLine.TextLines[targetVisualLine.TextLines.Count - 1];
                }
                else
                {
                    targetLine = null;
                }
                break;
            }

            case CaretMovementType.LineDown:
            {
                // Move down: move to the next TextLine in the same visual line
                // or move to the first TextLine of the next visual line
                int nextLineNumber = visualLine.LastDocumentLine.LineNumber + 1;
                if (textLineIndex < visualLine.TextLines.Count - 1)
                {
                    targetLine = visualLine.TextLines[textLineIndex + 1];
                }
                else if (nextLineNumber <= textArea.Document.LineCount)
                {
                    DocumentLine nextLine = textArea.Document.GetLineByNumber(nextLineNumber);
                    targetVisualLine = textArea.TextView.GetOrConstructVisualLine(nextLine);
                    targetLine       = targetVisualLine.TextLines[0];
                }
                else
                {
                    targetLine = null;
                }
                break;
            }

            case CaretMovementType.PageUp:
            case CaretMovementType.PageDown:
            {
                // Page up/down: find the target line using its visual position
                double yPos = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.LineMiddle);
                if (direction == CaretMovementType.PageUp)
                {
                    yPos -= textArea.TextView.RenderSize.Height;
                }
                else
                {
                    yPos += textArea.TextView.RenderSize.Height;
                }
                DocumentLine newLine = textArea.TextView.GetDocumentLineByVisualTop(yPos);
                targetVisualLine = textArea.TextView.GetOrConstructVisualLine(newLine);
                targetLine       = targetVisualLine.GetTextLineByVisualYPosition(yPos);
                break;
            }

            default:
                throw new NotSupportedException(direction.ToString());
            }
            if (targetLine != null)
            {
                CharacterHit ch = targetLine.GetCharacterHitFromDistance(xPos);
                SetCaretPosition(textArea, targetVisualLine, targetLine, ch, false);
                textArea.Caret.DesiredXPos = xPos;
            }
        }
Example #29
0
        private static ExecutedRoutedEventHandler OnDelete(CaretMovementType caretMovement)
        {
            return((target, args) =>
            {
                TextArea textArea = GetTextArea(target);
                if (textArea != null && textArea.Document != null)
                {
                    if (textArea.Selection.IsEmpty)
                    {
                        TextViewPosition startPos = textArea.Caret.Position;
                        bool enableVirtualSpace = textArea.Options.EnableVirtualSpace;
                        // When pressing delete; don't move the caret further into virtual space - instead delete the newline
                        if (caretMovement == CaretMovementType.CharRight)
                        {
                            enableVirtualSpace = false;
                        }
                        double desiredXPos = textArea.Caret.DesiredXPos;
                        TextViewPosition endPos = CaretNavigationCommandHandler.GetNewCaretPosition(
                            textArea.TextView, startPos, caretMovement, enableVirtualSpace, ref desiredXPos);
                        // GetNewCaretPosition may return (0,0) as new position,
                        // thus we need to validate endPos before using it in the selection.
                        if (endPos.Line < 1 || endPos.Column < 1)
                        {
                            endPos = new TextViewPosition(Math.Max(endPos.Line, 1), Math.Max(endPos.Column, 1));
                        }
                        // Don't select the text to be deleted; just reuse the ReplaceSelectionWithText logic
                        if (endPos.Column == 1)
                        {
                            var a = textArea.Document.GetLineByNumber(textArea.Caret.Line);

                            var b = a.PreviousLine;
                            if (b != null)
                            {
                                var c = b.PreviousLine;
                                if (b.obs != null)
                                {
                                    var obs = c.obs;
                                    var sa = textArea.Document.Text.Substring(a.Offset, a.Length + a.DelimiterLength);
                                    var bs = textArea.Document.Text.Substring(b.Offset, b.Length + b.DelimiterLength);
                                    var cs = textArea.Document.Text.Substring(c.Offset, c.Length + c.DelimiterLength);
                                    textArea.Document.Remove(c.Offset + c.Length, bs.Length + sa.Length /* + c.DelimiterLength*//* + a.DelimiterLength + b.DelimiterLength*/);
                                    textArea.Document.Insert(c.Offset + c.Length, sa);
                                }
                                else
                                {
                                    var sel = new SimpleSelection(textArea, startPos, endPos);
                                    sel.ReplaceSelectionWithText(string.Empty);
                                }
                            }
                            else
                            {
                                var sel = new SimpleSelection(textArea, startPos, endPos);
                                sel.ReplaceSelectionWithText(string.Empty);
                            }
                        }
                        else
                        {
                            var sel = new SimpleSelection(textArea, startPos, endPos);
                            sel.ReplaceSelectionWithText(string.Empty);
                        }
                    }
                    else
                    {
                        textArea.RemoveSelectedText();
                    }
                }
                textArea.Caret.BringCaretToView();
                args.Handled = true;
            });
        }
        internal static TextViewPosition GetNewCaretPosition(TextView textView, TextViewPosition caretPosition, CaretMovementType direction, bool enableVirtualSpace, ref double desiredXPos)
        {
            switch (direction)
            {
            case CaretMovementType.None:
                return(caretPosition);

            case CaretMovementType.DocumentStart:
                desiredXPos = double.NaN;
                return(new TextViewPosition(0, 0));

            case CaretMovementType.DocumentEnd:
                desiredXPos = double.NaN;
                return(new TextViewPosition(textView.Document.GetLocation(textView.Document.TextLength)));
            }
            DocumentLine caretLine  = textView.Document.GetLineByNumber(caretPosition.Line);
            VisualLine   visualLine = textView.GetOrConstructVisualLine(caretLine);
            TextLine     textLine   = visualLine.GetTextLine(caretPosition.VisualColumn, caretPosition.IsAtEndOfLine);

            switch (direction)
            {
            case CaretMovementType.CharLeft:
                desiredXPos = double.NaN;
                return(GetPrevCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.Normal, enableVirtualSpace));

            case CaretMovementType.Backspace:
                desiredXPos = double.NaN;
                return(GetPrevCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.EveryCodepoint, enableVirtualSpace));

            case CaretMovementType.CharRight:
                desiredXPos = double.NaN;
                return(GetNextCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.Normal, enableVirtualSpace));

            case CaretMovementType.WordLeft:
                desiredXPos = double.NaN;
                return(GetPrevCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.WordStart, enableVirtualSpace));

            case CaretMovementType.WordRight:
                desiredXPos = double.NaN;
                return(GetNextCaretPosition(textView, caretPosition, visualLine, CaretPositioningMode.WordStart, enableVirtualSpace));

            case CaretMovementType.LineUp:
            case CaretMovementType.LineDown:
            case CaretMovementType.PageUp:
            case CaretMovementType.PageDown:
                return(GetUpDownCaretPosition(textView, caretPosition, direction, visualLine, textLine, enableVirtualSpace, ref desiredXPos));

            case CaretMovementType.LineStart:
                desiredXPos = double.NaN;
                return(GetStartOfLineCaretPosition(caretPosition.VisualColumn, visualLine, textLine, enableVirtualSpace));

            case CaretMovementType.LineEnd:
                desiredXPos = double.NaN;
                return(GetEndOfLineCaretPosition(visualLine, textLine));

            default:
                throw new NotSupportedException(direction.ToString());
            }
        }