Browse Source

Avoid using mouse position to find already known elements.

pull/3274/head
tom-englert 10 months ago committed by tom-englert
parent
commit
29026f4df4
  1. 72
      ILSpy/ContextMenuEntry.cs
  2. 6
      ILSpy/Controls/TreeView/SharpTreeView.cs
  3. 22
      ILSpy/Metadata/GoToTokenCommand.cs

72
ILSpy/ContextMenuEntry.cs

@ -19,12 +19,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit;
using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.TextView;
@ -88,36 +85,40 @@ namespace ICSharpCode.ILSpy
/// </summary> /// </summary>
public TextViewPosition? Position { get; private set; } public TextViewPosition? Position { get; private set; }
public Point MousePosition { get; private set; } /// <summary>
/// Returns the original source of the context menu event.
/// </summary>
public DependencyObject OriginalSource { get; private set; }
public static TextViewContext Create(SharpTreeView treeView = null, DecompilerTextView textView = null, ListBox listBox = null, DataGrid dataGrid = null) public static TextViewContext Create(ContextMenuEventArgs eventArgs, SharpTreeView treeView = null, DecompilerTextView textView = null, ListBox listBox = null, DataGrid dataGrid = null)
{ {
ReferenceSegment reference; ReferenceSegment reference;
if (textView != null)
if (textView is not null)
{
reference = textView.GetReferenceSegmentAtMousePosition(); reference = textView.GetReferenceSegmentAtMousePosition();
else if (listBox?.SelectedItem is SearchResult result) }
reference = new ReferenceSegment { Reference = result.Reference };
else if (listBox?.SelectedItem is TreeNodes.IMemberTreeNode provider)
reference = new ReferenceSegment { Reference = provider.Member };
else if (listBox?.SelectedItem != null)
reference = new ReferenceSegment { Reference = listBox.SelectedItem };
else if (dataGrid?.SelectedItem is TreeNodes.IMemberTreeNode provider2)
reference = new ReferenceSegment { Reference = provider2.Member };
else if (dataGrid?.SelectedItem != null)
reference = new ReferenceSegment { Reference = dataGrid.SelectedItem };
else else
reference = null; {
var position = textView != null ? textView.GetPositionFromMousePosition() : null; reference = (listBox?.SelectedItem ?? dataGrid?.SelectedItem) switch {
var selectedTreeNodes = treeView != null ? treeView.GetTopLevelSelection().ToArray() : null; SearchResult searchResult => new() { Reference = searchResult.Reference },
return new TextViewContext { TreeNodes.IMemberTreeNode treeNode => new() { Reference = treeNode.Member }, { } value => new() { Reference = value },
_ => null
};
}
var position = textView?.GetPositionFromMousePosition();
var selectedTreeNodes = treeView?.GetTopLevelSelection().ToArray();
return new() {
ListBox = listBox, ListBox = listBox,
DataGrid = dataGrid, DataGrid = dataGrid,
TreeView = treeView, TreeView = treeView,
SelectedTreeNodes = selectedTreeNodes,
TextView = textView, TextView = textView,
SelectedTreeNodes = selectedTreeNodes,
Reference = reference, Reference = reference,
Position = position, Position = position,
MousePosition = ((Visual)textView ?? treeView ?? (Visual)listBox ?? dataGrid).PointToScreen(Mouse.GetPosition((IInputElement)textView ?? treeView ?? (IInputElement)listBox ?? dataGrid)) OriginalSource = eventArgs.OriginalSource as DependencyObject
}; };
} }
} }
@ -252,14 +253,14 @@ namespace ICSharpCode.ILSpy
void treeView_ContextMenuOpening(object sender, ContextMenuEventArgs e) void treeView_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{ {
TextViewContext context = TextViewContext.Create(treeView); var context = TextViewContext.Create(e, treeView: treeView);
if (context.SelectedTreeNodes.Length == 0) if (context.SelectedTreeNodes.Length == 0)
{ {
e.Handled = true; // don't show the menu e.Handled = true; // don't show the menu
return; return;
} }
ContextMenu menu;
if (ShowContextMenu(context, out menu)) if (ShowContextMenu(context, out var menu))
treeView.ContextMenu = menu; treeView.ContextMenu = menu;
else else
// hide the context menu. // hide the context menu.
@ -268,9 +269,8 @@ namespace ICSharpCode.ILSpy
void textView_ContextMenuOpening(object sender, ContextMenuEventArgs e) void textView_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{ {
TextViewContext context = TextViewContext.Create(textView: textView); var context = TextViewContext.Create(e, textView: textView);
ContextMenu menu; if (ShowContextMenu(context, out var menu))
if (ShowContextMenu(context, out menu))
textView.ContextMenu = menu; textView.ContextMenu = menu;
else else
// hide the context menu. // hide the context menu.
@ -279,9 +279,8 @@ namespace ICSharpCode.ILSpy
void listBox_ContextMenuOpening(object sender, ContextMenuEventArgs e) void listBox_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{ {
TextViewContext context = TextViewContext.Create(listBox: listBox); var context = TextViewContext.Create(e, listBox: listBox);
ContextMenu menu; if (ShowContextMenu(context, out var menu))
if (ShowContextMenu(context, out menu))
listBox.ContextMenu = menu; listBox.ContextMenu = menu;
else else
// hide the context menu. // hide the context menu.
@ -290,9 +289,8 @@ namespace ICSharpCode.ILSpy
void dataGrid_ContextMenuOpening(object sender, ContextMenuEventArgs e) void dataGrid_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{ {
TextViewContext context = TextViewContext.Create(dataGrid: dataGrid); var context = TextViewContext.Create(e, dataGrid: dataGrid);
ContextMenu menu; if (ShowContextMenu(context, out var menu))
if (ShowContextMenu(context, out menu))
dataGrid.ContextMenu = menu; dataGrid.ContextMenu = menu;
else else
// hide the context menu. // hide the context menu.
@ -333,10 +331,10 @@ namespace ICSharpCode.ILSpy
{ {
foreach (var category in menuGroup.GroupBy(c => c.Metadata.Category)) foreach (var category in menuGroup.GroupBy(c => c.Metadata.Category))
{ {
bool needSeparatorForCategory = parent.Count > 0; var needSeparatorForCategory = parent.Count > 0;
foreach (var entryPair in category) foreach (var entryPair in category)
{ {
IContextMenuEntry entry = entryPair.Value; var entry = entryPair.Value;
if (entry.IsVisible(context)) if (entry.IsVisible(context))
{ {
if (needSeparatorForCategory) if (needSeparatorForCategory)
@ -344,7 +342,7 @@ namespace ICSharpCode.ILSpy
parent.Add(new Separator()); parent.Add(new Separator());
needSeparatorForCategory = false; needSeparatorForCategory = false;
} }
MenuItem menuItem = new MenuItem(); var menuItem = new MenuItem();
menuItem.Header = ResourceHelper.GetString(entryPair.Metadata.Header); menuItem.Header = ResourceHelper.GetString(entryPair.Metadata.Header);
menuItem.InputGestureText = entryPair.Metadata.InputGestureText; menuItem.InputGestureText = entryPair.Metadata.InputGestureText;
if (!string.IsNullOrEmpty(entryPair.Metadata.Icon)) if (!string.IsNullOrEmpty(entryPair.Metadata.Icon))

6
ILSpy/Controls/TreeView/SharpTreeView.cs

@ -819,9 +819,9 @@ namespace ICSharpCode.ILSpy.Controls.TreeView
/// </summary> /// </summary>
public IEnumerable<SharpTreeNode> GetTopLevelSelection() public IEnumerable<SharpTreeNode> GetTopLevelSelection()
{ {
var selection = this.SelectedItems.OfType<SharpTreeNode>(); var selection = this.SelectedItems.OfType<SharpTreeNode>().ToHashSet();
var selectionHash = new HashSet<SharpTreeNode>(selection);
return selection.Where(item => item.Ancestors().All(a => !selectionHash.Contains(a))); return selection.Where(item => item.Ancestors().All(a => !selection.Contains(a)));
} }
#endregion #endregion

22
ILSpy/Metadata/GoToTokenCommand.cs

@ -23,12 +23,13 @@ using System.Reflection;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Metadata; using ICSharpCode.ILSpy.Metadata;
using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpy.Properties;
using TomsToolbox.Wpf;
namespace ICSharpCode.ILSpy.Commands namespace ICSharpCode.ILSpy.Commands
{ {
[ExportContextMenuEntry(Header = nameof(Resources.GoToToken), Order = 10)] [ExportContextMenuEntry(Header = nameof(Resources.GoToToken), Order = 10)]
@ -75,7 +76,7 @@ namespace ICSharpCode.ILSpy.Commands
{ {
public void Execute(TextViewContext context) public void Execute(TextViewContext context)
{ {
string content = GetSelectedCellContent(context.DataGrid, context.MousePosition); string content = GetSelectedCellContent(context.OriginalSource);
Clipboard.SetText(content); Clipboard.SetText(content);
} }
@ -87,21 +88,14 @@ namespace ICSharpCode.ILSpy.Commands
public bool IsVisible(TextViewContext context) public bool IsVisible(TextViewContext context)
{ {
return context.DataGrid?.Name == "MetadataView" return context.DataGrid?.Name == "MetadataView"
&& GetSelectedCellContent(context.DataGrid, context.MousePosition) != null; && GetSelectedCellContent(context.OriginalSource) != null;
} }
private string GetSelectedCellContent(DataGrid grid, Point position) private static string GetSelectedCellContent(DependencyObject originalSource)
{ {
position = grid.PointFromScreen(position); var cell = originalSource.AncestorsAndSelf().OfType<DataGridCell>().FirstOrDefault();
var hit = VisualTreeHelper.HitTest(grid, position);
if (hit == null) return cell?.Column.OnCopyingCellClipboardContent(cell.DataContext).ToString();
return null;
var cell = hit.VisualHit.GetParent<DataGridCell>();
if (cell == null)
return null;
return cell.DataContext.GetType()
.GetProperty(cell.Column.Header.ToString(), BindingFlags.Instance | BindingFlags.Public)
.GetValue(cell.DataContext).ToString();
} }
} }
} }

Loading…
Cancel
Save