Browse Source

Navigate visible history

pull/3591/head
Jan Kučera 3 months ago
parent
commit
a8def5bf85
  1. 5
      ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs
  2. 23
      ILSpy/AssemblyTree/AssemblyTreeModel.cs
  3. 13
      ILSpy/Commands/BrowseBackCommand.cs
  4. 11
      ILSpy/Commands/BrowseForwardCommand.cs
  5. 7
      ILSpy/Commands/SimpleCommand.cs
  6. 89
      ILSpy/Controls/MainToolBar.xaml.cs
  7. 2
      ILSpy/Metadata/MetadataTreeNode.cs
  8. 3
      ILSpy/NavigationHistory.cs
  9. 18
      ILSpy/NavigationState.cs
  10. 6
      ILSpy/Themes/ThemeManager.cs
  11. 2
      ILSpy/TreeNodes/BaseTypesTreeNode.cs
  12. 2
      ILSpy/TreeNodes/DerivedTypesTreeNode.cs
  13. 6
      ILSpy/TreeNodes/EventTreeNode.cs
  14. 6
      ILSpy/TreeNodes/FieldTreeNode.cs
  15. 6
      ILSpy/TreeNodes/MethodTreeNode.cs
  16. 6
      ILSpy/TreeNodes/PropertyTreeNode.cs
  17. 2
      ILSpy/TreeNodes/ReferenceFolderTreeNode.cs
  18. 2
      ILSpy/TreeNodes/ResourceListTreeNode.cs
  19. 3
      ILSpy/TreeNodes/TypeTreeNode.cs

5
ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs

@ -126,6 +126,11 @@ namespace ICSharpCode.ILSpyX.TreeView @@ -126,6 +126,11 @@ namespace ICSharpCode.ILSpyX.TreeView
get { return null; }
}
public virtual object? NavigationText
{
get { return Text; }
}
public virtual object? Icon {
get { return null; }
}

23
ILSpy/AssemblyTree/AssemblyTreeModel.cs

@ -853,15 +853,24 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -853,15 +853,24 @@ namespace ICSharpCode.ILSpy.AssemblyTree
#endregion
public void NavigateHistory(bool forward)
public void NavigateHistory(bool forward, NavigationState? toState = null)
{
try
{
TabPageModel tabPage = DockWorkspace.ActiveTabPage;
var state = tabPage.GetState();
if (state != null)
history.UpdateCurrent(new NavigationState(tabPage, state));
var newState = forward ? history.GoForward() : history.GoBack();
TabPageModel tabPage = DockWorkspace.ActiveTabPage;
var currentState = tabPage.GetState();
if (currentState != null)
history.UpdateCurrent(new NavigationState(tabPage, currentState));
NavigationState newState;
do
{
newState = forward ? history.GoForward() : history.GoBack();
} while (newState != null && toState != null && toState != newState);
if (newState == null)
return;
navigatingToState = newState;
TabPageModel activeTabPage = newState.TabPage;
@ -884,6 +893,8 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -884,6 +893,8 @@ namespace ICSharpCode.ILSpy.AssemblyTree
}
}
public NavigationState[] GetNavigateHistory(bool forward) => forward ? history.ForwardList : history.BackList;
public bool CanNavigateBack => history.CanNavigateBack;
public bool CanNavigateForward => history.CanNavigateForward;

13
ILSpy/Commands/BrowseBackCommand.cs

@ -16,7 +16,9 @@ @@ -16,7 +16,9 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Collections;
using System.Composition;
using System.Linq;
using System.Windows.Input;
using ICSharpCode.ILSpy.AssemblyTree;
@ -26,7 +28,7 @@ namespace ICSharpCode.ILSpy @@ -26,7 +28,7 @@ namespace ICSharpCode.ILSpy
{
[ExportToolbarCommand(ToolTip = nameof(Resources.Back), ToolbarIcon = "Images/Back", ToolbarCategory = nameof(Resources.Navigation), ToolbarOrder = 0)]
[Shared]
sealed class BrowseBackCommand : CommandWrapper
sealed class BrowseBackCommand : CommandWrapper, IProvideParameterList
{
readonly AssemblyTreeModel assemblyTreeModel;
@ -49,8 +51,15 @@ namespace ICSharpCode.ILSpy @@ -49,8 +51,15 @@ namespace ICSharpCode.ILSpy
if (assemblyTreeModel.CanNavigateBack)
{
e.Handled = true;
assemblyTreeModel.NavigateHistory(false);
assemblyTreeModel.NavigateHistory(false, e.Parameter as NavigationState);
}
}
public IEnumerable ParameterList => assemblyTreeModel.GetNavigateHistory(false).Reverse();
public object GetParamaterText(object parameter)
{
return (parameter as NavigationState)?.NavigationText;
}
}
}

11
ILSpy/Commands/BrowseForwardCommand.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Collections;
using System.Composition;
using System.Windows.Input;
@ -26,7 +27,7 @@ namespace ICSharpCode.ILSpy @@ -26,7 +27,7 @@ namespace ICSharpCode.ILSpy
{
[ExportToolbarCommand(ToolTip = nameof(Resources.Forward), ToolbarIcon = "Images/Forward", ToolbarCategory = nameof(Resources.Navigation), ToolbarOrder = 1)]
[Shared]
sealed class BrowseForwardCommand : CommandWrapper
sealed class BrowseForwardCommand : CommandWrapper, IProvideParameterList
{
private readonly AssemblyTreeModel assemblyTreeModel;
@ -49,9 +50,15 @@ namespace ICSharpCode.ILSpy @@ -49,9 +50,15 @@ namespace ICSharpCode.ILSpy
if (assemblyTreeModel.CanNavigateForward)
{
e.Handled = true;
assemblyTreeModel.NavigateHistory(true);
assemblyTreeModel.NavigateHistory(true, e.Parameter as NavigationState);
}
}
public IEnumerable ParameterList => assemblyTreeModel.GetNavigateHistory(true);
public object GetParamaterText(object parameter)
{
return (parameter as NavigationState)?.NavigationText;
}
}
}

7
ILSpy/Commands/SimpleCommand.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections;
using System.Windows.Data;
using System.Windows.Input;
@ -41,4 +42,10 @@ namespace ICSharpCode.ILSpy @@ -41,4 +42,10 @@ namespace ICSharpCode.ILSpy
{
Binding ParameterBinding { get; }
}
public interface IProvideParameterList
{
IEnumerable ParameterList { get; }
object GetParamaterText(object parameter);
}
}

89
ILSpy/Controls/MainToolBar.xaml.cs

@ -23,9 +23,11 @@ using System.Windows.Controls; @@ -23,9 +23,11 @@ using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.ILSpy.Themes;
using ICSharpCode.ILSpyX.TreeView;
using TomsToolbox.Composition;
@ -85,7 +87,8 @@ namespace ICSharpCode.ILSpy.Controls @@ -85,7 +87,8 @@ namespace ICSharpCode.ILSpy.Controls
}
}
static Button CreateToolbarItem(IExport<ICommand, IToolbarCommandMetadata> commandExport)
static UIElement CreateToolbarItem(IExport<ICommand, IToolbarCommandMetadata> commandExport)
{
var command = commandExport.Value;
@ -108,9 +111,93 @@ namespace ICSharpCode.ILSpy.Controls @@ -108,9 +111,93 @@ namespace ICSharpCode.ILSpy.Controls
parameterBinding.ParameterBinding);
}
if (command is IProvideParameterList parameterList)
{
toolbarItem.Margin = new Thickness(2, 0, 0, 0);
var dropDownPanel = new StackPanel { Orientation = Orientation.Horizontal };
var contextMenu = new ContextMenu {
PlacementTarget = dropDownPanel,
Tag = command
};
ContextMenuService.SetPlacement(toolbarItem, PlacementMode.Bottom);
toolbarItem.ContextMenu = contextMenu;
toolbarItem.ContextMenuOpening += (_, _) =>
PrepareParameterList(contextMenu);
var dropDownToggle = new ToggleButton {
Style = ThemeManager.Current.CreateToolBarToggleButtonStyle(),
Content = "▾",
Padding = new Thickness(0),
MinWidth = 0,
Margin = new Thickness(0, 0, 2, 0)
};
dropDownToggle.Checked += (_, _) => {
PrepareParameterList(contextMenu);
contextMenu.Placement = PlacementMode.Bottom;
contextMenu.SetCurrentValue(ContextMenu.IsOpenProperty, true);
};
BindingOperations.SetBinding(dropDownToggle, ToggleButton.IsCheckedProperty,
new Binding(nameof(contextMenu.IsOpen)) { Source = contextMenu });
BindingOperations.SetBinding(dropDownToggle, IsEnabledProperty,
new Binding(nameof(IsEnabled)) { Source = toolbarItem });
dropDownPanel.Children.Add(toolbarItem);
dropDownPanel.Children.Add(dropDownToggle);
return dropDownPanel;
}
return toolbarItem;
}
static void PrepareParameterList(ContextMenu menu)
{
const int maximumParameterListCount = 20;
var command = (ICommand)menu.Tag;
var parameterList = (IProvideParameterList)command;
menu.Items.Clear();
foreach (var parameter in parameterList.ParameterList)
{
MenuItem parameterItem = new MenuItem();
parameterItem.Command = CommandWrapper.Unwrap(command);
parameterItem.CommandParameter = parameter;
parameterItem.CommandTarget = menu.PlacementTarget;
parameterItem.InputGestureText = " ";
var headerPresenter = new ContentPresenter { RecognizesAccessKey = false };
parameterItem.Header = headerPresenter;
var header = parameterList.GetParamaterText(parameter);
switch (header)
{
case SharpTreeNode node:
headerPresenter.Content = node.NavigationText;
if (node.Icon is ImageSource icon)
parameterItem.Icon = new Image {
Width = 16,
Height = 16,
Source = icon
};
break;
default:
headerPresenter.Content = header;
break;
}
menu.Items.Add(parameterItem);
if (menu.Items.Count >= maximumParameterListCount)
break;
}
}
void MainWindow_KeyDown(object sender, KeyEventArgs e)
{
if (e.Handled || e.KeyboardDevice.Modifiers != ModifierKeys.Alt || e.Key != Key.System)

2
ILSpy/Metadata/MetadataTreeNode.cs

@ -45,6 +45,8 @@ namespace ICSharpCode.ILSpy.Metadata @@ -45,6 +45,8 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Text => title;
public override object NavigationText => metadataFile.Name + " " + Text;
public override object Icon => Images.Metadata;
public override bool View(TabPageModel tabPage)

3
ILSpy/NavigationHistory.cs

@ -34,6 +34,9 @@ namespace ICSharpCode.ILSpy @@ -34,6 +34,9 @@ namespace ICSharpCode.ILSpy
List<T> back = new List<T>();
List<T> forward = new List<T>();
public T[] BackList => back.ToArray();
public T[] ForwardList => forward.ToArray();
public bool CanNavigateBack {
get { return back.Count > 0; }
}

18
ILSpy/NavigationState.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.ViewModels;
@ -62,5 +63,22 @@ namespace ICSharpCode.ILSpy @@ -62,5 +63,22 @@ namespace ICSharpCode.ILSpy
return this.ViewState.Equals(other.ViewState);
}
public object NavigationText
{
get
{
if (this.treeNodes.Count == 1)
return this.treeNodes.First();
if (this.treeNodes.Count > 0)
return string.Join(", ", treeNodes.Select(tn => tn.NavigationText));
if (this.ViewState?.ViewedUri is Uri uri)
return uri;
return ToString();
}
}
}
}

6
ILSpy/Themes/ThemeManager.cs

@ -24,6 +24,7 @@ using System.ComponentModel; @@ -24,6 +24,7 @@ using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Highlighting;
@ -81,6 +82,11 @@ namespace ICSharpCode.ILSpy.Themes @@ -81,6 +82,11 @@ namespace ICSharpCode.ILSpy.Themes
return new Style(typeof(Button), (Style)Application.Current.FindResource(ToolBar.ButtonStyleKey));
}
public Style CreateToolBarToggleButtonStyle()
{
return new Style(typeof(ToggleButton), (Style)Application.Current.FindResource(ToolBar.ToggleButtonStyleKey));
}
public void ApplyHighlightingColors(IHighlightingDefinition highlightingDefinition)
{
// Make sure all color values are taken from the theme

2
ILSpy/TreeNodes/BaseTypesTreeNode.cs

@ -46,6 +46,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -46,6 +46,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override object Text => Properties.Resources.BaseTypes;
public override object NavigationText => this.Language.TypeToString(type, includeNamespace: true) + " " + Text;
public override object Icon => Images.SuperTypes;
protected override void LoadChildren()

2
ILSpy/TreeNodes/DerivedTypesTreeNode.cs

@ -47,6 +47,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -47,6 +47,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override object Text => Resources.DerivedTypes;
public override object NavigationText => this.Language.TypeToString(type, includeNamespace: true) + " " + Text;
public override object Icon => Images.SubTypes;
protected override void LoadChildren()

6
ILSpy/TreeNodes/EventTreeNode.cs

@ -49,6 +49,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -49,6 +49,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override object Text => GetText(GetEventDefinition(), this.Language) + GetSuffixString(EventDefinition);
public override object NavigationText => GetText(GetEventDefinition(), Language, includeDeclaringTypeName: true);
private IEvent GetEventDefinition()
{
return ((MetadataModule)EventDefinition.ParentModule?.MetadataFile
@ -56,9 +58,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -56,9 +58,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
?.MainModule)?.GetDefinition((EventDefinitionHandle)EventDefinition.MetadataToken) ?? EventDefinition;
}
public static object GetText(IEvent ev, Language language)
public static object GetText(IEvent ev, Language language, bool includeDeclaringTypeName = false)
{
return language.EventToString(ev, false, false, false);
return language.EventToString(ev, includeDeclaringTypeName, false, false);
}
public override object Icon => GetIcon(GetEventDefinition());

6
ILSpy/TreeNodes/FieldTreeNode.cs

@ -41,6 +41,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -41,6 +41,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override object Text => GetText(GetFieldDefinition(), Language) + GetSuffixString(FieldDefinition);
public override object NavigationText => GetText(GetFieldDefinition(), Language, includeDeclaringTypeName: true);
private IField GetFieldDefinition()
{
return ((MetadataModule)FieldDefinition.ParentModule?.MetadataFile
@ -48,9 +50,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -48,9 +50,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
?.MainModule)?.GetDefinition((FieldDefinitionHandle)FieldDefinition.MetadataToken) ?? FieldDefinition;
}
public static object GetText(IField field, Language language)
public static object GetText(IField field, Language language, bool includeDeclaringTypeName = false)
{
return language.FieldToString(field, includeDeclaringTypeName: false, includeNamespace: false, includeNamespaceOfDeclaringTypeName: false);
return language.FieldToString(field, includeDeclaringTypeName, includeNamespace: false, includeNamespaceOfDeclaringTypeName: false);
}
public override object Icon => GetIcon(GetFieldDefinition());

6
ILSpy/TreeNodes/MethodTreeNode.cs

@ -41,6 +41,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -41,6 +41,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override object Text => GetText(GetMethodDefinition(), Language) + GetSuffixString(MethodDefinition);
public override object NavigationText => GetText(GetMethodDefinition(), Language, includeDeclaringTypeName: true);
private IMethod GetMethodDefinition()
{
return ((MetadataModule)MethodDefinition.ParentModule?.MetadataFile
@ -48,9 +50,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -48,9 +50,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
?.MainModule)?.GetDefinition((MethodDefinitionHandle)MethodDefinition.MetadataToken) ?? MethodDefinition;
}
public static object GetText(IMethod method, Language language)
public static object GetText(IMethod method, Language language, bool includeDeclaringTypeName = false)
{
return language.MethodToString(method, false, false, false);
return language.MethodToString(method, includeDeclaringTypeName, false, false);
}
public override object Icon => GetIcon(GetMethodDefinition());

6
ILSpy/TreeNodes/PropertyTreeNode.cs

@ -51,6 +51,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -51,6 +51,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override object Text => GetText(GetPropertyDefinition(), Language) + GetSuffixString(PropertyDefinition);
public override object NavigationText => GetText(GetPropertyDefinition(), Language, includeDeclaringTypeName: true);
private IProperty GetPropertyDefinition()
{
return ((MetadataModule)PropertyDefinition.ParentModule?.MetadataFile
@ -58,9 +60,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -58,9 +60,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
?.MainModule)?.GetDefinition((PropertyDefinitionHandle)PropertyDefinition.MetadataToken) ?? PropertyDefinition;
}
public static object GetText(IProperty property, Language language)
public static object GetText(IProperty property, Language language, bool includeDeclaringTypeName = false)
{
return language.PropertyToString(property, false, false, false);
return language.PropertyToString(property, includeDeclaringTypeName, false, false);
}
public override object Icon => GetIcon(GetPropertyDefinition());

2
ILSpy/TreeNodes/ReferenceFolderTreeNode.cs

@ -44,6 +44,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -44,6 +44,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override object Text => Resources.References;
public override object NavigationText => module.Name + " " + Text;
public override object Icon => Images.ReferenceFolder;
protected override void LoadChildren()

2
ILSpy/TreeNodes/ResourceListTreeNode.cs

@ -41,6 +41,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -41,6 +41,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override object Text => Resources._Resources;
public override object NavigationText => module.Name + " " + Text;
public override object Icon => Images.FolderClosed;
public override object ExpandedIcon => Images.FolderOpen;

3
ILSpy/TreeNodes/TypeTreeNode.cs

@ -45,6 +45,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -45,6 +45,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override object Text => this.Language.TypeToString(GetTypeDefinition(), includeNamespace: false)
+ GetSuffixString(TypeDefinition.MetadataToken);
public override object NavigationText => this.Language.TypeToString(GetTypeDefinition(), includeNamespace: true)
+ GetSuffixString(TypeDefinition.MetadataToken);
private ITypeDefinition GetTypeDefinition()
{
return ((MetadataModule)ParentAssemblyNode.LoadedAssembly

Loading…
Cancel
Save