// Token: 0x06007CED RID: 31981 RVA: 0x0023255C File Offset: 0x0023075C private static FlowDirection GetTextFlowDirection(ITextPointer pointer) { Invariant.Assert(pointer != null, "Null pointer passed."); Invariant.Assert(pointer.IsAtInsertionPosition, "Pointer is not an insertion position"); int num = 0; LogicalDirection logicalDirection = pointer.LogicalDirection; TextPointerContext pointerContext = pointer.GetPointerContext(logicalDirection); FlowDirection result; if ((pointerContext == TextPointerContext.ElementEnd || pointerContext == TextPointerContext.ElementStart) && !TextSchema.IsFormattingType(pointer.ParentType)) { result = (FlowDirection)pointer.GetValue(FrameworkElement.FlowDirectionProperty); } else { Rect anchorRectangle = TextSelectionHelper.GetAnchorRectangle(pointer); ITextPointer textPointer = pointer.GetNextInsertionPosition(logicalDirection); if (textPointer != null) { textPointer = textPointer.CreatePointer((logicalDirection == LogicalDirection.Backward) ? LogicalDirection.Forward : LogicalDirection.Backward); if (logicalDirection == LogicalDirection.Forward) { if (pointerContext == TextPointerContext.ElementEnd && textPointer.GetPointerContext(textPointer.LogicalDirection) == TextPointerContext.ElementStart) { return((FlowDirection)pointer.GetValue(FrameworkElement.FlowDirectionProperty)); } } else if (pointerContext == TextPointerContext.ElementStart && textPointer.GetPointerContext(textPointer.LogicalDirection) == TextPointerContext.ElementEnd) { return((FlowDirection)pointer.GetValue(FrameworkElement.FlowDirectionProperty)); } Rect anchorRectangle2 = TextSelectionHelper.GetAnchorRectangle(textPointer); if (anchorRectangle2 != Rect.Empty && anchorRectangle != Rect.Empty) { num = Math.Sign(anchorRectangle2.Left - anchorRectangle.Left); if (logicalDirection == LogicalDirection.Backward) { num = -num; } } } if (num == 0) { result = (FlowDirection)pointer.GetValue(FrameworkElement.FlowDirectionProperty); } else { result = ((num > 0) ? FlowDirection.LeftToRight : FlowDirection.RightToLeft); } } return(result); }
// Returns true iff there is a character in the specificed direction adjacent to a // position which is classified as a separator. This is useful in detecting word breaks. private static bool HasNeighboringSeparatorChar(ITextPointer position, LogicalDirection direction) { ITextPointer nextPosition = position.GetNextInsertionPosition(direction); if (nextPosition == null) { return(true); } if (position.CompareTo(nextPosition) > 0) { ITextPointer temp = position; position = nextPosition; nextPosition = temp; } int maxCharCount = position.GetOffsetToPosition(nextPosition); char[] findText = new char[maxCharCount]; int [] findTextPositionMap = new int[maxCharCount + 1]; int findTextLength; findTextLength = SetFindTextAndFindTextPositionMap( position, nextPosition, position.CreatePointer() /* need unfrozen pointer */, LogicalDirection.Forward, false /* matchLast */, findText, findTextPositionMap); if (findTextLength == 0) { return(true); } bool hasNeighboringSeparatorChar; if (direction == LogicalDirection.Forward) { hasNeighboringSeparatorChar = IsSeparatorChar(findText[0]); } else { hasNeighboringSeparatorChar = IsSeparatorChar(findText[findTextLength - 1]); } return(hasNeighboringSeparatorChar); }
// Token: 0x060039B5 RID: 14773 RVA: 0x00105CE8 File Offset: 0x00103EE8 private static bool HasNeighboringSeparatorChar(ITextPointer position, LogicalDirection direction) { ITextPointer textPointer = position.GetNextInsertionPosition(direction); if (textPointer == null) { return(true); } if (position.CompareTo(textPointer) > 0) { ITextPointer textPointer2 = position; position = textPointer; textPointer = textPointer2; } int offsetToPosition = position.GetOffsetToPosition(textPointer); char[] array = new char[offsetToPosition]; int[] findTextPositionMap = new int[offsetToPosition + 1]; int num = TextFindEngine.SetFindTextAndFindTextPositionMap(position, textPointer, position.CreatePointer(), LogicalDirection.Forward, false, array, findTextPositionMap); if (num == 0) { return(true); } bool result; if (direction == LogicalDirection.Forward) { result = TextFindEngine.IsSeparatorChar(array[0]); } else { result = TextFindEngine.IsSeparatorChar(array[num - 1]); } return(result); }
//----------------------------------------------------- // // Static Methods // //------------------------------------------------------ #region Static Methods /// <summary> /// Determine the flow direction of the character referred to by the TextPointer. /// If the context of the pointer is not text, we use the FlowDirection of the /// containing element. /// </summary> /// <param name="pointer">pointer to get flow direction for</param> /// <returns>positive value means LeftToRight, negative value means RightToLeft</returns> private static FlowDirection GetTextFlowDirection(ITextPointer pointer) { Invariant.Assert(pointer != null, "Null pointer passed."); Invariant.Assert(pointer.IsAtInsertionPosition, "Pointer is not an insertion position"); int sign = 0; FlowDirection flowDirection; LogicalDirection direction = pointer.LogicalDirection; TextPointerContext currentContext = pointer.GetPointerContext(direction); if ((currentContext == TextPointerContext.ElementEnd || currentContext == TextPointerContext.ElementStart) && !TextSchema.IsFormattingType(pointer.ParentType)) { // If the current pointer (with its current direction) is at the start or end of a paragraph, // the next insertion position will be in a separate paragraph. We can't determine direction // based on the pointer rects in that case so we use the direction of the Paragraph. flowDirection = (FlowDirection)pointer.GetValue(FlowDirectionProperty); } else { // We get the rects before and after the character following the current // pointer and determine that character's flow direction based on the x-values // of the rects. Because we use direction when requesting a rect, we should // always get rects that are on the same line (except for the case above) // Forward gravity for leading edge Rect current = TextSelectionHelper.GetAnchorRectangle(pointer); // Get insertion position after the current pointer ITextPointer nextPointer = pointer.GetNextInsertionPosition(direction); // There may be no more insertion positions in this document if (nextPointer != null) { // Backward gravity for trailing edge nextPointer = nextPointer.CreatePointer(direction == LogicalDirection.Backward ? LogicalDirection.Forward : LogicalDirection.Backward); // Special case - for pointers at the end of a paragraph // Actually the pointer is the last insertion position in the paragraph and the next insertion position is the first // in the next paragraph. We handle this by detecting that the two pointers only have markup between them. If the // markup was only formatting, there would also be content (because insertion position would move past a character). if (direction == LogicalDirection.Forward) { if (currentContext == TextPointerContext.ElementEnd && nextPointer.GetPointerContext(nextPointer.LogicalDirection) == TextPointerContext.ElementStart) { return (FlowDirection)pointer.GetValue(FlowDirectionProperty); } } else { if (currentContext == TextPointerContext.ElementStart && nextPointer.GetPointerContext(nextPointer.LogicalDirection) == TextPointerContext.ElementEnd) { return (FlowDirection)pointer.GetValue(FlowDirectionProperty); } } Rect next = TextSelectionHelper.GetAnchorRectangle(nextPointer); // Calculate the difference in x-coordinate between the two rects if (next != Rect.Empty && current != Rect.Empty) { sign = Math.Sign(next.Left - current.Left); // If we are looking at the character before the current pointer, // we swap the difference since "next" was actually before "current" if (direction == LogicalDirection.Backward) { sign = -(sign); } } } // If the rects were at the same x-coordinate or we couldn't get rects // at all, we simply use the FlowDirection at that pointer. if (sign == 0) { flowDirection = (FlowDirection)pointer.GetValue(FlowDirectionProperty); } else { // Positive is left to right, negative is right to left flowDirection = (sign > 0 ? FlowDirection.LeftToRight : FlowDirection.RightToLeft); } } return flowDirection; }
// MouseMoveEvent handler. private static void OnMouseMoveWithFocus(TextEditor This, MouseEventArgs e) { // Ignore the event if it was caused by us capturing the mouse if (This._mouseCapturingInProgress) { return; } // Clear a flag indicating that Shift key was pressed without any following key // This flag is necessary for KeyUp(RightShift/LeftShift) processing. TextEditor._ThreadLocalStore.PureControlShift = false; // Get the mouse move point. Point mouseMovePoint = e.GetPosition(This.TextView.RenderScope); // Update mouse cursor shape TextEditorMouse.UpdateCursor(This, mouseMovePoint); // For Invariant.Assert(This.Selection != null); // We're only interested in moves when the left button is down. if (e.LeftButton != MouseButtonState.Pressed) { return; } // We didn't get the original mouse down event, perhaps a listener // handled it. if (!This.UiScope.IsMouseCaptured) { return; } // Scale back any background layout in progress. This.TextView.ThrottleBackgroundTasksForUserInput(); if (This._tableColResizeInfo != null) { This._tableColResizeInfo.UpdateAdorner(mouseMovePoint); } else { // Consider event handled e.Handled = true; // For Invariant.Assert(This.Selection != null); // Find a text position for this mouse point ITextPointer snappedCursorPosition = This.TextView.GetTextPositionFromPoint(mouseMovePoint, /*snapToText:*/ true); // For Invariant.Assert(This.Selection != null); if (snappedCursorPosition == null) { This.RequestExtendSelection(mouseMovePoint); } else { This.CancelExtendSelection(); // For Invariant.Assert(This.Selection != null); if (!This._dragDropProcess.SourceOnMouseMove(mouseMovePoint)) { // Auto-scrolling behavior during selection guesture - // works when the mouse is outside of scroller's viewport. // In such case we artificially increase coordinates to // get to farther text position - which would speed-up scrolling // in particular direction. FrameworkElement scroller = This._Scroller; if (scroller != null && This.UiScope is TextBoxBase) { ITextPointer acceleratedCursorPosition = null; // cursorPosition corrected to accelerate scrolling Point targetPoint = new Point(mouseMovePoint.X, mouseMovePoint.Y); Point pointScroller = e.GetPosition((IInputElement)scroller); double pageHeight = (double)((TextBoxBase)This.UiScope).ViewportHeight; double slowAreaDelta = ScrollViewer._scrollLineDelta; // Auto scrolling up/down page for the page height if the mouse Y // position is out of viewport. if (pointScroller.Y < 0 - slowAreaDelta) { Rect targetRect = This.TextView.GetRectangleFromTextPosition(snappedCursorPosition); targetPoint = new Point(targetPoint.X, targetRect.Bottom - pageHeight); acceleratedCursorPosition = This.TextView.GetTextPositionFromPoint(targetPoint, /*snapToText:*/ true); } else if (pointScroller.Y > pageHeight + slowAreaDelta) { Rect targetRect = This.TextView.GetRectangleFromTextPosition(snappedCursorPosition); targetPoint = new Point(targetPoint.X, targetRect.Top + pageHeight); acceleratedCursorPosition = This.TextView.GetTextPositionFromPoint(targetPoint, /*snapToText:*/ true); } double pageWidth = (double)((TextBoxBase)This.UiScope).ViewportWidth; // Auto scrolling to left/right scroll delta amount if the mouse X position // is out of viewport area. if (pointScroller.X < 0) { targetPoint = new Point(targetPoint.X - slowAreaDelta, targetPoint.Y); acceleratedCursorPosition = This.TextView.GetTextPositionFromPoint(targetPoint, /*snapToText:*/ true); } else if (pointScroller.X > pageWidth) { targetPoint = new Point(targetPoint.X + slowAreaDelta, targetPoint.Y); acceleratedCursorPosition = This.TextView.GetTextPositionFromPoint(targetPoint, /*snapToText:*/ true); } // Use acceleratedcursorPosition instead of real one to make scrolling reasonable faster if (acceleratedCursorPosition != null) { snappedCursorPosition = acceleratedCursorPosition; } } using (This.Selection.DeclareChangeBlock()) { // Check end-of-container condition if (snappedCursorPosition.GetNextInsertionPosition(LogicalDirection.Forward) == null && snappedCursorPosition.ParentType != null) // { // We are at the end of text container. Check whether mouse is farther than a last character Rect lastCharacterRect = snappedCursorPosition.GetCharacterRect(LogicalDirection.Backward); if (mouseMovePoint.X > lastCharacterRect.X + lastCharacterRect.Width) { snappedCursorPosition = This.TextContainer.End; } } // Move the caret/selection to match the cursor position. This.Selection.ExtendSelectionByMouse(snappedCursorPosition, This._forceWordSelection, This._forceParagraphSelection); } } } } }
// If a position is currently at a Table row end, move it inside // the last cell. // This is useful when trying to navigate by line, because ITextView // cannot handle the special end of row position. private static ITextPointer AdjustPositionAtTableRowEnd(ITextPointer position) { if (TextPointerBase.IsAtRowEnd(position)) { ITextPointer cellEnd = position.GetNextInsertionPosition(LogicalDirection.Backward); if (cellEnd != null) { position = cellEnd; } } return position; }
// Helper for OnSelectDownByLine. Updates the selection moving position // during select down by line. private static void AdjustMovingPositionForSelectDownByLine(TextEditor This, ITextPointer newMovingPosition, ITextPointer originalMovingPosition, double suggestedX) { int newComparedToOld = newMovingPosition.CompareTo(originalMovingPosition); // Note: we compare orientations of equal positions to handle a case // when original position was at the end of line (after its linebreak with backward orientation) // as a result of Shift+End selection; and the new position is in the beginning of the next line, // which is essentially the same position but oriented differently. // In such a case the new position is good enough to go there. // We certainly don't want to go to the end of the document in this case. if (newComparedToOld > 0 || newComparedToOld == 0 && newMovingPosition.LogicalDirection != originalMovingPosition.LogicalDirection) { // We have another line in a given direction; move to it // If the destination exactly preceeds a line break, expand to include // the line break if we haven't reached our desired suggestedX. if (TextPointerBase.IsNextToAnyBreak(newMovingPosition, LogicalDirection.Forward) || newMovingPosition.GetNextInsertionPosition(LogicalDirection.Forward) == null) { double newPositionX = GetAbsoluteXOffset(This.TextView, newMovingPosition); FlowDirection paragraphFlowDirection = GetScopingParagraphFlowDirection(newMovingPosition); FlowDirection controlFlowDirection = This.UiScope.FlowDirection; if ((paragraphFlowDirection == controlFlowDirection && newPositionX < suggestedX) || (paragraphFlowDirection != controlFlowDirection && newPositionX > suggestedX)) { newMovingPosition = newMovingPosition.GetInsertionPosition(LogicalDirection.Forward); newMovingPosition = newMovingPosition.GetNextInsertionPosition(LogicalDirection.Forward); // If we're at the last Paragraph, move to document end to include // the final paragraph break. if (newMovingPosition == null) { newMovingPosition = originalMovingPosition.TextContainer.End; } newMovingPosition = newMovingPosition.GetFrozenPointer(LogicalDirection.Backward); } } ExtendSelectionAndBringIntoView(newMovingPosition, This); } else { // Remember where we were so that we can return if a line up follows. if (This._NextLineAdvanceMovingPosition == null) { This._NextLineAdvanceMovingPosition = originalMovingPosition; This._IsNextLineAdvanceMovingPositionAtDocumentHead = false; } // No more lines in this direction. Move to end of current line. newMovingPosition = GetPositionAtLineEnd(originalMovingPosition); if (newMovingPosition.GetNextInsertionPosition(LogicalDirection.Forward) == null) { // Move to the final implicit line at end-of-doc. newMovingPosition = newMovingPosition.TextContainer.End; } ExtendSelectionAndBringIntoView(newMovingPosition, This); } }
// Returns a pointer of a text range adjusted so it does not affect // the paragraph following the selection. internal static ITextPointer GetAdjustedRangeEnd(ITextPointer rangeStart, ITextPointer rangeEnd) { if (rangeStart.CompareTo(rangeEnd) < 0 && rangeEnd.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart) { rangeEnd = rangeEnd.GetNextInsertionPosition(LogicalDirection.Backward); if (rangeEnd == null) { rangeEnd = rangeStart; // Recover position for container start case - we never return null from this method. } } else if (TextPointerBase.IsAfterLastParagraph(rangeEnd)) { rangeEnd = rangeEnd.GetInsertionPosition(LogicalDirection.Backward); } return rangeEnd; }
// Returns true iff there is a character in the specificed direction adjacent to a // position which is classified as a separator. This is useful in detecting word breaks. private static bool HasNeighboringSeparatorChar(ITextPointer position, LogicalDirection direction) { ITextPointer nextPosition = position.GetNextInsertionPosition(direction); if (nextPosition == null) { return true; } if (position.CompareTo(nextPosition) > 0) { ITextPointer temp = position; position = nextPosition; nextPosition = temp; } int maxCharCount = position.GetOffsetToPosition(nextPosition); char[] findText = new char[maxCharCount]; int []findTextPositionMap = new int[maxCharCount + 1]; int findTextLength; findTextLength = SetFindTextAndFindTextPositionMap( position, nextPosition, position.CreatePointer() /* need unfrozen pointer */, LogicalDirection.Forward, false /* matchLast */, findText, findTextPositionMap); if (findTextLength == 0) { return true; } bool hasNeighboringSeparatorChar; if (direction == LogicalDirection.Forward) { hasNeighboringSeparatorChar = IsSeparatorChar(findText[0]); } else { hasNeighboringSeparatorChar = IsSeparatorChar(findText[findTextLength-1]); } return hasNeighboringSeparatorChar; }
// Token: 0x06003884 RID: 14468 RVA: 0x000FD66C File Offset: 0x000FB86C private static void OnMouseMoveWithFocus(TextEditor This, MouseEventArgs e) { if (This._mouseCapturingInProgress) { return; } TextEditor._ThreadLocalStore.PureControlShift = false; Point position = e.GetPosition(This.TextView.RenderScope); TextEditorMouse.UpdateCursor(This, position); Invariant.Assert(This.Selection != null); if (e.LeftButton != MouseButtonState.Pressed) { return; } if (!This.UiScope.IsMouseCaptured) { return; } This.TextView.ThrottleBackgroundTasksForUserInput(); if (This._tableColResizeInfo != null) { This._tableColResizeInfo.UpdateAdorner(position); return; } e.Handled = true; Invariant.Assert(This.Selection != null); ITextPointer textPointer = This.TextView.GetTextPositionFromPoint(position, true); Invariant.Assert(This.Selection != null); if (textPointer == null) { This.RequestExtendSelection(position); return; } This.CancelExtendSelection(); Invariant.Assert(This.Selection != null); if (!This._dragDropProcess.SourceOnMouseMove(position)) { FrameworkElement scroller = This._Scroller; if (scroller != null && This.UiScope is TextBoxBase) { ITextPointer textPointer2 = null; Point point = new Point(position.X, position.Y); Point position2 = e.GetPosition(scroller); double num = ((TextBoxBase)This.UiScope).ViewportHeight; double num2 = 16.0; if (position2.Y < 0.0 - num2) { Rect rectangleFromTextPosition = This.TextView.GetRectangleFromTextPosition(textPointer); point = new Point(point.X, rectangleFromTextPosition.Bottom - num); textPointer2 = This.TextView.GetTextPositionFromPoint(point, true); } else if (position2.Y > num + num2) { Rect rectangleFromTextPosition2 = This.TextView.GetRectangleFromTextPosition(textPointer); point = new Point(point.X, rectangleFromTextPosition2.Top + num); textPointer2 = This.TextView.GetTextPositionFromPoint(point, true); } double num3 = ((TextBoxBase)This.UiScope).ViewportWidth; if (position2.X < 0.0) { point = new Point(point.X - num2, point.Y); textPointer2 = This.TextView.GetTextPositionFromPoint(point, true); } else if (position2.X > num3) { point = new Point(point.X + num2, point.Y); textPointer2 = This.TextView.GetTextPositionFromPoint(point, true); } if (textPointer2 != null) { textPointer = textPointer2; } } using (This.Selection.DeclareChangeBlock()) { if (textPointer.GetNextInsertionPosition(LogicalDirection.Forward) == null && textPointer.ParentType != null) { Rect characterRect = textPointer.GetCharacterRect(LogicalDirection.Backward); if (position.X > characterRect.X + characterRect.Width) { textPointer = This.TextContainer.End; } } This.Selection.ExtendSelectionByMouse(textPointer, This._forceWordSelection, This._forceParagraphSelection); } } }