/// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="block">Block for which MBP properties are retrieved.</param>
 private MbpInfo(TextElement block)
 {
     _margin  = (Thickness)block.GetValue(Block.MarginProperty);
     _border  = (Thickness)block.GetValue(Block.BorderThicknessProperty);
     _padding = (Thickness)block.GetValue(Block.PaddingProperty);
     _borderBrush = (Brush)block.GetValue(Block.BorderBrushProperty);
 }
Exemple #2
0
        internal static void OnContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            TextEditor textEditor = TextEditor._GetTextEditor(sender);

            if (textEditor == null || textEditor.TextView == null)
            {
                return;
            }
            Point       position    = Mouse.GetPosition(textEditor.TextView.RenderScope);
            ContextMenu contextMenu = null;
            bool        flag        = false;

            if (textEditor.IsReadOnly)
            {
                if ((e.CursorLeft != -1.0 && !textEditor.Selection.Contains(position)) || (e.CursorLeft == -1.0 && textEditor.Selection.IsEmpty))
                {
                    return;
                }
            }
            else if ((textEditor.Selection.IsEmpty || e.TargetElement is TextElement) && e.TargetElement != null)
            {
                contextMenu = (ContextMenu)e.TargetElement.GetValue(FrameworkElement.ContextMenuProperty);
            }
            else if (e.CursorLeft == -1.0)
            {
                TextPointer textPointer = TextEditorContextMenu.GetContentPosition(textEditor.Selection.Start) as TextPointer;
                if (textPointer != null)
                {
                    for (TextElement textElement = textPointer.Parent as TextElement; textElement != null; textElement = (textElement.Parent as TextElement))
                    {
                        contextMenu = (ContextMenu)textElement.GetValue(FrameworkElement.ContextMenuProperty);
                        if (contextMenu != null)
                        {
                            flag = true;
                            break;
                        }
                    }
                }
            }
            if (e.CursorLeft != -1.0)
            {
                if (!TextEditorMouse.IsPointWithinInteractiveArea(textEditor, Mouse.GetPosition(textEditor.UiScope)))
                {
                    return;
                }
                if (contextMenu == null || !(e.TargetElement is UIElement))
                {
                    using (textEditor.Selection.DeclareChangeBlock())
                    {
                        if (!textEditor.Selection.Contains(position))
                        {
                            TextEditorMouse.SetCaretPositionOnMouseEvent(textEditor, position, MouseButton.Right, 1);
                        }
                    }
                }
            }
            if (contextMenu == null)
            {
                if (textEditor.UiScope.ReadLocalValue(FrameworkElement.ContextMenuProperty) == null)
                {
                    return;
                }
                contextMenu = textEditor.UiScope.ContextMenu;
            }
            textEditor.IsContextMenuOpen = true;
            if (contextMenu != null && !flag)
            {
                contextMenu.HorizontalOffset = 0.0;
                contextMenu.VerticalOffset   = 0.0;
                contextMenu.Closed          += TextEditorContextMenu.OnContextMenuClosed;
                return;
            }
            textEditor.CompleteComposition();
            if (contextMenu == null)
            {
                contextMenu = new TextEditorContextMenu.EditorContextMenu();
                ((TextEditorContextMenu.EditorContextMenu)contextMenu).AddMenuItems(textEditor, e.UserInitiated);
            }
            contextMenu.Placement       = PlacementMode.RelativePoint;
            contextMenu.PlacementTarget = textEditor.UiScope;
            ITextPointer     textPointer2  = null;
            SpellingError    spellingError = (contextMenu is TextEditorContextMenu.EditorContextMenu) ? textEditor.GetSpellingErrorAtSelection() : null;
            LogicalDirection logicalDirection;

            if (spellingError != null)
            {
                textPointer2     = spellingError.End;
                logicalDirection = LogicalDirection.Backward;
            }
            else if (e.CursorLeft == -1.0)
            {
                textPointer2     = textEditor.Selection.Start;
                logicalDirection = LogicalDirection.Forward;
            }
            else
            {
                logicalDirection = LogicalDirection.Forward;
            }
            if (textPointer2 != null && textPointer2.CreatePointer(logicalDirection).HasValidLayout)
            {
                double horizontalOffset;
                double verticalOffset;
                TextEditorContextMenu.GetClippedPositionOffsets(textEditor, textPointer2, logicalDirection, out horizontalOffset, out verticalOffset);
                contextMenu.HorizontalOffset = horizontalOffset;
                contextMenu.VerticalOffset   = verticalOffset;
            }
            else
            {
                Point position2 = Mouse.GetPosition(textEditor.UiScope);
                contextMenu.HorizontalOffset = position2.X;
                contextMenu.VerticalOffset   = position2.Y;
            }
            contextMenu.Closed += TextEditorContextMenu.OnContextMenuClosed;
            contextMenu.IsOpen  = true;
            e.Handled           = true;
        }
Exemple #3
0
        internal static void OnContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            TextEditor   This = TextEditor._GetTextEditor(sender);
            const double KeyboardInvokedSentinel = -1.0; // e.CursorLeft has this value when the menu is invoked with the keyboard.

            if (This == null || This.TextView == null)
            {
                return;
            }

            // Get the mouse position that base on RenderScope which we will set
            // the caret on the RenderScope.
            Point       renderScopeMouseDownPoint = Mouse.GetPosition(This.TextView.RenderScope);
            ContextMenu contextMenu = null;
            bool        startPositionCustomElementMenu = false;

            if (This.IsReadOnly)
            {
                // If the TextEditor is ReadOnly, only take action if
                // 1. The selection is non-empty AND
                // 2. The user clicked inside the selection.
                if ((e.CursorLeft != KeyboardInvokedSentinel && !This.Selection.Contains(renderScopeMouseDownPoint)) ||
                    (e.CursorLeft == KeyboardInvokedSentinel && This.Selection.IsEmpty))
                {
                    return;
                }
            }
            else if ((This.Selection.IsEmpty || e.TargetElement is TextElement) &&
                     e.TargetElement != null)
            {
                // Targeted element has its own ContextMenu, don't override it.
                contextMenu = (ContextMenu)e.TargetElement.GetValue(FrameworkElement.ContextMenuProperty);
            }
            else if (e.CursorLeft == KeyboardInvokedSentinel)
            {
                // If the menu was invoked from the keyboard, walk up the tree
                // from the selection.Start looking for a custom menu.
                TextPointer start = GetContentPosition(This.Selection.Start) as TextPointer;
                if (start != null)
                {
                    TextElement element = start.Parent as TextElement;

                    while (element != null)
                    {
                        contextMenu = (ContextMenu)element.GetValue(FrameworkElement.ContextMenuProperty);
                        if (contextMenu != null)
                        {
                            startPositionCustomElementMenu = true;
                            break;
                        }
                        element = element.Parent as TextElement;
                    }
                }
            }

            // Update the selection caret.
            //
            // A negative offset for e.CursorLeft means the user invoked
            // the menu with a hotkey (shift-F10).  Don't mess with the caret
            // unless the user right-clicked.
            if (e.CursorLeft != KeyboardInvokedSentinel)
            {
                if (!TextEditorMouse.IsPointWithinInteractiveArea(This, Mouse.GetPosition(This.UiScope)))
                {
                    // Don't bring up a context menu if the user clicked on non-editable space.
                    return;
                }

                // Don't update the selection caret if we're bringing up a custom UIElement
                // ContextMenu.
                if (contextMenu == null || !(e.TargetElement is UIElement))
                {
                    using (This.Selection.DeclareChangeBlock()) // NB: This raises a PUBLIC EVENT.
                    {
                        // If we're not over the selection, move the caret.
                        if (!This.Selection.Contains(renderScopeMouseDownPoint))
                        {
                            TextEditorMouse.SetCaretPositionOnMouseEvent(This, renderScopeMouseDownPoint, MouseButton.Right, 1 /* clickCount */);
                        }
                    }
                }
            }

            if (contextMenu == null)
            {
                // If someone explicitly set it null -- don't mess with it.
                if (This.UiScope.ReadLocalValue(FrameworkElement.ContextMenuProperty) == null)
                {
                    return;
                }

                // Grab whatever's set to the UiScope's ContextMenu property.
                contextMenu = This.UiScope.ContextMenu;
            }

            // If we are here, it means that either a custom context menu or our default context menu will be opened.
            // Setting this flag ensures that we dont loose selection highlight while the context menu is open.
            This.IsContextMenuOpen = true;

            // If it's not null, someone's overriding our default -- don't mess with it.
            if (contextMenu != null && !startPositionCustomElementMenu)
            {
                // If the user previously raised the ContextMenu with the keyboard,
                // we've left h/v offsets non-zero, and they need to be cleared now
                // for mouse placement to work.
                contextMenu.HorizontalOffset = 0;
                contextMenu.VerticalOffset   = 0;

                // Since ContextMenuService doesn't open the menu, it won't fire a ContextMenuClosing event.
                // We need to listen to the Closed event of the ContextMenu itself so we can clear the
                // IsContextMenuOpen flag.  We also do this for the default menu later in this method.
                contextMenu.Closed += new RoutedEventHandler(OnContextMenuClosed);
                return;
            }

            // Complete the composition before creating the editor context menu.
            This.CompleteComposition();

            if (contextMenu == null)
            {
                // It's a default null, so spin up a temporary ContextMenu now.
                contextMenu = new EditorContextMenu();
                ((EditorContextMenu)contextMenu).AddMenuItems(This, e.UserInitiated);
            }
            contextMenu.Placement       = PlacementMode.RelativePoint;
            contextMenu.PlacementTarget = This.UiScope;

            ITextPointer     position = null;
            LogicalDirection direction;

            // Position the ContextMenu.

            SpellingError spellingError = (contextMenu is EditorContextMenu) ? This.GetSpellingErrorAtSelection() : null;

            if (spellingError != null)
            {
                // If we have a matching speller error at the selection
                // start, position relative to the end of the error.
                position  = spellingError.End;
                direction = LogicalDirection.Backward;
            }
            else if (e.CursorLeft == KeyboardInvokedSentinel)
            {
                // A negative offset for e.CursorLeft means the user invoked
                // the menu with a hotkey (shift-F10).  Place the menu
                // relative to Selection.Start.
                position  = This.Selection.Start;
                direction = LogicalDirection.Forward;
            }
            else
            {
                direction = LogicalDirection.Forward;
            }

            // Calculate coordinats for the ContextMenu.
            // They must be set relative to UIScope - as EditorContextMenu constructor assumes.
            if (position != null && position.CreatePointer(direction).HasValidLayout)
            {
                double horizontalOffset;
                double verticalOffset;

                GetClippedPositionOffsets(This, position, direction, out horizontalOffset, out verticalOffset);

                contextMenu.HorizontalOffset = horizontalOffset;
                contextMenu.VerticalOffset   = verticalOffset;
            }
            else
            {
                Point uiScopeMouseDownPoint = Mouse.GetPosition(This.UiScope);

                contextMenu.HorizontalOffset = uiScopeMouseDownPoint.X;
                contextMenu.VerticalOffset   = uiScopeMouseDownPoint.Y;
            }

            // Since ContextMenuService doesn't open the menu, it won't fire a ContextMenuClosing event.
            // We need to listen to the Closed event of the ContextMenu itself so we can clear the
            // IsContextMenuOpen flag.
            contextMenu.Closed += new RoutedEventHandler(OnContextMenuClosed);

            // This line raises a public event.
            contextMenu.IsOpen = true;

            e.Handled = true;
        }
Exemple #4
0
        // Helper to set property value on element. 
        private static void SetPropertyValue(TextElement element, DependencyProperty property, object currentValue, object newValue) 
        {
            if (!TextSchema.ValuesAreEqual(newValue, currentValue)) 
            {
                // first clear and see if it will do
                element.ClearValue(property);
 
                // if still need it, set it
                if (!TextSchema.ValuesAreEqual(newValue, element.GetValue(property))) 
                { 
                    element.SetValue(property, newValue);
                } 
            }
        }