/// <summary> /// Called when ContextMenuOpening is raised on FlowDocument viewer element. /// </summary> internal static void OnContextMenuOpening(FlowDocument document, Control viewer, ContextMenuEventArgs e) { // Get ContextMenu from TargetElement, if exests. Otherwise get ContextMenu from the viewer. ContextMenu cm = null; if (e.TargetElement != null) { cm = e.TargetElement.GetValue(FrameworkElement.ContextMenuProperty) as ContextMenu; } if (cm == null) { cm = viewer.ContextMenu; } // Add special handling for ContextMenu, if invoked through a hotkey. if (cm != null) { if (document != null) { // A negative offset for e.CursorLeft means the user invoked // the menu with a hotkey (shift-F10). // For this case place the menu relative to Selection.Start, // otherwise do not modify it. if (DoubleUtil.LessThan(e.CursorLeft, 0)) { // Retrieve desired ContextMenu position. If the TextSelection is not empty and visible, // use selection start position. Otherwise prefer TargetElements's start, if provided. ITextContainer textContainer = (ITextContainer)((IServiceProvider)document).GetService(typeof(ITextContainer)); ITextPointer contextMenuPosition = null; if (textContainer.TextSelection != null) { if ((textContainer.TextSelection.IsEmpty || !textContainer.TextSelection.TextEditor.UiScope.IsFocused) && e.TargetElement is TextElement) { contextMenuPosition = ((TextElement)e.TargetElement).ContentStart; } else { // Selection start is always normalized to have backward LogicalDirection. However, if selection starts at the beginning // of a line this will cause the text view to return rectangle on the previous line. So we need to switch logical direction. contextMenuPosition = textContainer.TextSelection.Start.CreatePointer(LogicalDirection.Forward); } } else if (e.TargetElement is TextElement) { contextMenuPosition = ((TextElement)e.TargetElement).ContentStart; } // If ContextMenu position has been found and it is visible, show ContextMenu there. // Otherwise let default ContextMenu handling logic handle this event. ITextView textView = textContainer.TextView; if (contextMenuPosition != null && textView != null && textView.IsValid && textView.Contains(contextMenuPosition)) { Rect positionRect = textView.GetRectangleFromTextPosition(contextMenuPosition); if (positionRect != Rect.Empty) { positionRect = DocumentViewerHelper.CalculateVisibleRect(positionRect, textView.RenderScope); if (positionRect != Rect.Empty) { GeneralTransform transform = textView.RenderScope.TransformToAncestor(viewer); Point contextMenuOffset = transform.Transform(positionRect.BottomLeft); cm.Placement = PlacementMode.Relative; cm.PlacementTarget = viewer; cm.HorizontalOffset = contextMenuOffset.X; cm.VerticalOffset = contextMenuOffset.Y; cm.IsOpen = true; e.Handled = true; } } } } } if (!e.Handled) { // Since we are not handling ContextMenu, clear all the values that // could be set through explicit handling. cm.ClearValue(ContextMenu.PlacementProperty); cm.ClearValue(ContextMenu.PlacementTargetProperty); cm.ClearValue(ContextMenu.HorizontalOffsetProperty); cm.ClearValue(ContextMenu.VerticalOffsetProperty); } } }
// Token: 0x06006FD7 RID: 28631 RVA: 0x00202514 File Offset: 0x00200714 internal static void OnContextMenuOpening(FlowDocument document, Control viewer, ContextMenuEventArgs e) { ContextMenu contextMenu = null; if (e.TargetElement != null) { contextMenu = (e.TargetElement.GetValue(FrameworkElement.ContextMenuProperty) as ContextMenu); } if (contextMenu == null) { contextMenu = viewer.ContextMenu; } if (contextMenu != null) { if (document != null && DoubleUtil.LessThan(e.CursorLeft, 0.0)) { ITextContainer textContainer = (ITextContainer)((IServiceProvider)document).GetService(typeof(ITextContainer)); ITextPointer textPointer = null; if (textContainer.TextSelection != null) { if ((textContainer.TextSelection.IsEmpty || !textContainer.TextSelection.TextEditor.UiScope.IsFocused) && e.TargetElement is TextElement) { textPointer = ((TextElement)e.TargetElement).ContentStart; } else { textPointer = textContainer.TextSelection.Start.CreatePointer(LogicalDirection.Forward); } } else if (e.TargetElement is TextElement) { textPointer = ((TextElement)e.TargetElement).ContentStart; } ITextView textView = textContainer.TextView; if (textPointer != null && textView != null && textView.IsValid && textView.Contains(textPointer)) { Rect rect = textView.GetRectangleFromTextPosition(textPointer); if (rect != Rect.Empty) { rect = DocumentViewerHelper.CalculateVisibleRect(rect, textView.RenderScope); if (rect != Rect.Empty) { GeneralTransform generalTransform = textView.RenderScope.TransformToAncestor(viewer); Point point = generalTransform.Transform(rect.BottomLeft); contextMenu.Placement = PlacementMode.Relative; contextMenu.PlacementTarget = viewer; contextMenu.HorizontalOffset = point.X; contextMenu.VerticalOffset = point.Y; contextMenu.IsOpen = true; e.Handled = true; } } } } if (!e.Handled) { contextMenu.ClearValue(ContextMenu.PlacementProperty); contextMenu.ClearValue(ContextMenu.PlacementTargetProperty); contextMenu.ClearValue(ContextMenu.HorizontalOffsetProperty); contextMenu.ClearValue(ContextMenu.VerticalOffsetProperty); } } }