// Token: 0x06003889 RID: 14473 RVA: 0x000FDB54 File Offset: 0x000FBD54
        private static UIElement GetUIElementWhenMouseOver(TextEditor This, Point mouseMovePoint)
        {
            ITextPointer textPositionFromPoint = This.TextView.GetTextPositionFromPoint(mouseMovePoint, false);

            if (textPositionFromPoint == null)
            {
                return(null);
            }
            if (textPositionFromPoint.GetPointerContext(textPositionFromPoint.LogicalDirection) != TextPointerContext.EmbeddedElement)
            {
                return(null);
            }
            ITextPointer     textPointer = textPositionFromPoint.GetNextContextPosition(textPositionFromPoint.LogicalDirection);
            LogicalDirection gravity     = (textPositionFromPoint.LogicalDirection == LogicalDirection.Forward) ? LogicalDirection.Backward : LogicalDirection.Forward;

            textPointer = textPointer.CreatePointer(0, gravity);
            Rect rectangleFromTextPosition  = This.TextView.GetRectangleFromTextPosition(textPositionFromPoint);
            Rect rectangleFromTextPosition2 = This.TextView.GetRectangleFromTextPosition(textPointer);
            Rect rect = rectangleFromTextPosition;

            rect.Union(rectangleFromTextPosition2);
            if (!rect.Contains(mouseMovePoint))
            {
                return(null);
            }
            return(textPositionFromPoint.GetAdjacentElement(textPositionFromPoint.LogicalDirection) as UIElement);
        }
Exemplo n.º 2
0
 // Token: 0x0600384C RID: 14412 RVA: 0x000FB73C File Offset: 0x000F993C
 private static ITextPointer GetContentPosition(ITextPointer position)
 {
     while (position.GetAdjacentElement(LogicalDirection.Forward) is Inline)
     {
         position = position.GetNextContextPosition(LogicalDirection.Forward);
     }
     return(position);
 }
Exemplo n.º 3
0
        // Return a UIElement when mouseMovePoint is within the ui element's bounding Rect. Null otherwise.
        private static UIElement GetUIElementWhenMouseOver(TextEditor This, Point mouseMovePoint)
        {
            ITextPointer mouseMovePosition = This.TextView.GetTextPositionFromPoint(mouseMovePoint, /*snapToText:*/ false);

            if (mouseMovePosition == null)
            {
                return(null);
            }

            if (!(mouseMovePosition.GetPointerContext(mouseMovePosition.LogicalDirection) == TextPointerContext.EmbeddedElement))
            {
                return(null);
            }

            // Find out if mouseMovePoint is within the bounding Rect of UIElement, we need to do this check explicitly
            // because even when snapToText is false, textview returns a first/last position on a line when point is in
            // an area before/after line start/end. This is by-design behavior for textview.

            // Need to get Rect from TextView, since Rect returned by TextPointer.GetCharacterRect()
            // is transformed to UiScope coordinates and we want RenderScope coordinates here.

            ITextPointer     otherEdgePosition  = mouseMovePosition.GetNextContextPosition(mouseMovePosition.LogicalDirection);
            LogicalDirection otherEdgeDirection = (mouseMovePosition.LogicalDirection == LogicalDirection.Forward) ?
                                                  LogicalDirection.Backward : LogicalDirection.Forward;

            // Normalize with correct gravity
            otherEdgePosition = otherEdgePosition.CreatePointer(0, otherEdgeDirection);

            Rect uiElementFirstEdgeRect  = This.TextView.GetRectangleFromTextPosition(mouseMovePosition);
            Rect uiElementSecondEdgeRect = This.TextView.GetRectangleFromTextPosition(otherEdgePosition);

            Rect boundingRect = uiElementFirstEdgeRect;

            boundingRect.Union(uiElementSecondEdgeRect);
            if (!boundingRect.Contains(mouseMovePoint))
            {
                return(null);
            }

            return(mouseMovePosition.GetAdjacentElement(mouseMovePosition.LogicalDirection) as UIElement);
        }
        // -------------------------------------------------------------
        //
        // Private Methods
        //
        // -------------------------------------------------------------

        #region Private Methods

        // .............................................................
        //
        // Serialization
        //
        // .............................................................

        /// <summary>
        /// This function serializes text segment formed by rangeStart and rangeEnd to valid xml using xmlWriter.
        /// </summary>        
        /// <SecurityNote>
        /// To mask the security exception from XamlWriter.Save in partial trust case, 
        /// this function checks if the current call stack has the all clipboard permission.
        /// </SecurityNote>
        private static void WriteXamlTextSegment(XmlWriter xmlWriter, ITextPointer rangeStart, ITextPointer rangeEnd, XamlTypeMapper xamlTypeMapper, ref int elementLevel, WpfPayload wpfPayload, bool ignoreWriteHyperlinkEnd, List<int> ignoreList, bool preserveTextElements)
        {
            // Special case for pure text selection - we need a Run wrapper for it.
            if (elementLevel == EmptyDocumentDepth && typeof(Run).IsAssignableFrom(rangeStart.ParentType))
            {
                elementLevel++;
                xmlWriter.WriteStartElement(typeof(Run).Name);
            }

            // Create text navigator for reading the range's content
            ITextPointer textReader = rangeStart.CreatePointer();

            // Exclude last opening tag from serialization - we don't need to create extra element
            // is cases when we have whole paragraphs/cells selected.
            // NOTE: We do this slightly differently than in TextRangeEdit.AdjustRangeEnd, where we use normalization for adjusted position.
            // In this case normalized position does not work, because we need to keep information about crossed paragraph boundary.
            while (rangeEnd.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart)
            {
                rangeEnd = rangeEnd.GetNextContextPosition(LogicalDirection.Backward);
            }

            // Write the range internal contents
            while (textReader.CompareTo(rangeEnd) < 0)
            {
                TextPointerContext runType = textReader.GetPointerContext(LogicalDirection.Forward);

                switch (runType)
                {
                    case TextPointerContext.ElementStart:
                        TextElement nextElement = (TextElement)textReader.GetAdjacentElement(LogicalDirection.Forward);
                        if (nextElement is Hyperlink)
                        {
                            // Don't write Hyperlink start element if Hyperlink is invalid
                            // in case of having a UiElement except Image or stated the range end
                            // position before the end position of the Hyperlink.
                            if (IsHyperlinkInvalid(textReader, rangeEnd))
                            {
                                ignoreWriteHyperlinkEnd = true;
                                textReader.MoveToNextContextPosition(LogicalDirection.Forward);

                                continue;
                            }
                        }
                        else if (nextElement != null)
                        {
                            // 

                            
                            TextElementEditingBehaviorAttribute att = (TextElementEditingBehaviorAttribute)Attribute.GetCustomAttribute(nextElement.GetType(), typeof(TextElementEditingBehaviorAttribute));
                            if (att != null && !att.IsTypographicOnly)
                            {
                                if (IsPartialNonTypographic(textReader, rangeEnd))
                                {
                                    // Add pointer to ignore list
                                    ITextPointer ptr = textReader.CreatePointer();
                                    ptr.MoveToElementEdge(ElementEdge.BeforeEnd);
                                    ignoreList.Add(ptr.Offset);

                                    textReader.MoveToNextContextPosition(LogicalDirection.Forward);

                                    continue;
                                }
                            }
                        }

                        elementLevel++;
                        textReader.MoveToNextContextPosition(LogicalDirection.Forward);
                        WriteStartXamlElement(/*range:*/null, textReader, xmlWriter, xamlTypeMapper, /*reduceElement:*/wpfPayload == null, preserveTextElements);

                        break;

                    case TextPointerContext.ElementEnd:
                        // Don't write Hyperlink end element if Hyperlink include the invalid
                        // in case of having a UiElement except Image or stated the range end
                        // before the end position of the Hyperlink or Hyperlink opening tag is 
                        // skipped from WriteOpeningTags by selecting of the partial of Hyperlink.
                        if (ignoreWriteHyperlinkEnd && (textReader.GetAdjacentElement(LogicalDirection.Forward) is Hyperlink))
                        {
                            // Reset the flag to keep walk up the next Hyperlink tag
                            ignoreWriteHyperlinkEnd = false;
                            textReader.MoveToNextContextPosition(LogicalDirection.Forward);
                            
                            continue;
                        }

                        // Check the ignore list
                        ITextPointer endPointer = textReader.CreatePointer();
                        endPointer.MoveToElementEdge(ElementEdge.BeforeEnd);  // 
                        if (ignoreList.Contains(endPointer.Offset))
                        {
                            ignoreList.Remove(endPointer.Offset);
                            textReader.MoveToNextContextPosition(LogicalDirection.Forward);

                            continue;
                        }

                        elementLevel--;
                        if (TextSchema.IsBreak(textReader.ParentType))
                        {
                            // For LineBreak, etc. use empty element syntax
                            xmlWriter.WriteEndElement();
                        }
                        else
                        {   // 
                            // For all other textelements use explicit closing tag.
                            xmlWriter.WriteFullEndElement();
                        }
                        textReader.MoveToNextContextPosition(LogicalDirection.Forward);
                        break;

                    case TextPointerContext.Text:
                        int textLength = textReader.GetTextRunLength(LogicalDirection.Forward);
                        char[] text = new Char[textLength];

                        textLength = TextPointerBase.GetTextWithLimit(textReader, LogicalDirection.Forward, text, 0, textLength, rangeEnd);

                        // XmlWriter will throw an ArgumentException if text contains
                        // any invalid surrogates, so strip them out now.
                        textLength = StripInvalidSurrogateChars(text, textLength);

                        xmlWriter.WriteChars(text, 0, textLength);
                        textReader.MoveToNextContextPosition(LogicalDirection.Forward);
                        break;

                    case TextPointerContext.EmbeddedElement:
                        object embeddedObject = textReader.GetAdjacentElement(LogicalDirection.Forward);
                        textReader.MoveToNextContextPosition(LogicalDirection.Forward);

                        WriteEmbeddedObject(embeddedObject, xmlWriter, wpfPayload);
                        break;

                    default:
                        Invariant.Assert(false, "unexpected value of runType");
                        textReader.MoveToNextContextPosition(LogicalDirection.Forward);
                        break;
                }
            }
        }
Exemplo n.º 5
0
        //......................................................
        //
        //  Selection Building With Mouse
        //
        //......................................................

        // Moves the selection to the mouse cursor position.
        // If the cursor is facing a UIElement, select the UIElement.
        // Sets new selection anchor to a given cursorPosition.
        private void MoveSelectionByMouse(ITextPointer cursorPosition, Point cursorMousePoint)
        {
            ITextSelection thisSelection = (ITextSelection)this;

            if (this.TextView == null)
            {
                return;
            }
            Invariant.Assert(this.TextView.IsValid); // We just checked RenderScope. We'll use TextView below

            ITextPointer movingPosition = null;

            if (cursorPosition.GetPointerContext(cursorPosition.LogicalDirection) == TextPointerContext.EmbeddedElement)
            {
                Rect objectEdgeRect = this.TextView.GetRectangleFromTextPosition(cursorPosition);

                // Check for embedded object.
                // If the click happend inside of it we need to select it as a whole, when content is not read-only.
                if (!_textEditor.IsReadOnly && ShouldSelectEmbeddedObject(cursorPosition, cursorMousePoint, objectEdgeRect))
                {
                    movingPosition = cursorPosition.GetNextContextPosition(cursorPosition.LogicalDirection);
                }
            }

            // Move selection to this position
            if (movingPosition == null)
            {
                thisSelection.SetCaretToPosition(cursorPosition, cursorPosition.LogicalDirection, /*allowStopAtLineEnd:*/true, /*allowStopNearSpace:*/false);
            }
            else
            {
                thisSelection.Select(cursorPosition, movingPosition);
            }
        }
        // Returns true if pointer is at the start of a paragraph.
        internal static bool IsAtParagraphOrBlockUIContainerStart(ITextPointer pointer)
        {
            // Is pointer at a potential paragraph position?
            if (IsAtPotentialParagraphPosition(pointer))
            {
                return true;
            }

            // Can you find a <Paragraph> start tag looking backwards? 
            // Loop to skip multiple formatting opening tags, never crossing parent element boundary.
            while (pointer.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart)
            {
                if (TextSchema.IsParagraphOrBlockUIContainer(pointer.ParentType))
                {
                    return true;
                }
                pointer = pointer.GetNextContextPosition(LogicalDirection.Backward);
            }
            return false;
        }
        private static ITextPointer RestrictWithinBlock(ITextPointer position, ITextPointer limit, LogicalDirection direction)
        {
            Invariant.Assert(!(direction == LogicalDirection.Backward) || position.CompareTo(limit) >= 0, "for backward direction position must be >= than limit");
            Invariant.Assert(!(direction == LogicalDirection.Forward) || position.CompareTo(limit) <= 0, "for forward direcion position must be <= than linit");

            while (direction == LogicalDirection.Backward ? position.CompareTo(limit) > 0 : position.CompareTo(limit) < 0)
            {
                TextPointerContext context = position.GetPointerContext(direction);
                if (context == TextPointerContext.ElementStart || context == TextPointerContext.ElementEnd)
                {
                    Type elementType = position.GetElementType(direction);
                    if (!typeof(Inline).IsAssignableFrom(elementType))
                    {
                        limit = position;
                        break;
                    }
                }
                else if (context == TextPointerContext.EmbeddedElement)
                {
                    limit = position;
                    break;
                }
                position = position.GetNextContextPosition(direction);
            }

            // Return normalized position - in the direction towards a center position.
            return limit.GetInsertionPosition(direction == LogicalDirection.Backward ? LogicalDirection.Forward : LogicalDirection.Backward);
        }
        // Returns true if the position is adjacent to a LineBreak or Paragraph element,
        // ignoring any intermediate formatting elements.
        //
        // If lineBreakType is null, any line break element is considered valid.
        private static bool IsNextToRichBreak(ITextPointer thisPosition, LogicalDirection direction, Type lineBreakType)
        {
            Invariant.Assert(lineBreakType == null || lineBreakType == typeof(LineBreak) || lineBreakType == typeof(Paragraph));

            bool result = false;

            while (true)
            {
                Type neighbor = thisPosition.GetElementType(direction);

                if (lineBreakType == null)
                {
                    if (typeof(LineBreak).IsAssignableFrom(neighbor) ||
                        typeof(Paragraph).IsAssignableFrom(neighbor))
                    {
                        result = true;
                        break;
                    }
                }
                else if (lineBreakType.IsAssignableFrom(neighbor))
                {
                    result = true;
                    break;
                }

                if (!TextSchema.IsFormattingType(neighbor))
                    break;

                thisPosition = thisPosition.GetNextContextPosition(direction);
            }

            return result;
        }
        // Returns a position ajacent to the supplied position, skipping any
        // intermediate Inlines.
        // This is useful for sliding inside the context of adjacent Hyperlinks,
        // Spans, etc.
        private static ITextPointer GetContentPosition(ITextPointer position)
        {
            while (position.GetAdjacentElement(LogicalDirection.Forward) is Inline)
            {
                position = position.GetNextContextPosition(LogicalDirection.Forward);
            }

            return position;
        }
Exemplo n.º 10
0
        // Tests if the position is at the beginning of some list item - 
        // to allow Backspace to delete the bullet.
        private static bool IsAtListItemStart(ITextPointer position) 
        { 
            // Check for empty ListItem case
            if (typeof(ListItem).IsAssignableFrom(position.ParentType) && 
                position.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart &&
                position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd)
            {
                return true; 
            }
 
            while (position.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart) 
            {
                Type parentType = position.ParentType; 
                if (TextSchema.IsBlock(parentType))
                {
                    if (TextSchema.IsParagraphOrBlockUIContainer(parentType))
                    { 
                        position = position.GetNextContextPosition(LogicalDirection.Backward);
                        if (position.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart && 
                            typeof(ListItem).IsAssignableFrom(position.ParentType)) 
                        {
                            return true; 
                        }
                    }
                    return false;
                } 
                position = position.GetNextContextPosition(LogicalDirection.Backward);
            } 
            return false; 
        }