diff --git a/ILSpy.Tests/Options/ApiVisibilityFilterTests.cs b/ILSpy.Tests/Options/ApiVisibilityFilterTests.cs index 69817ea1c..3bb95b141 100644 --- a/ILSpy.Tests/Options/ApiVisibilityFilterTests.cs +++ b/ILSpy.Tests/Options/ApiVisibilityFilterTests.cs @@ -22,6 +22,7 @@ using System.Xml.Linq; using Avalonia.Controls; using Avalonia.Controls.DataGridHierarchical; +using Avalonia.Controls.Primitives; using Avalonia.Headless.NUnit; using Avalonia.VisualTree; @@ -194,6 +195,42 @@ public class ApiVisibilityFilterTests "flipping ShowApiLevel must rebind the HierarchicalModel so the grid re-evaluates child visibility"); } + [AvaloniaTest] + public async Task Toolbar_Has_Three_ApiVisibility_Toggle_Buttons_Bound_To_LanguageSettings() + { + // Mirrors the View-menu radios as toolbar ToggleButtons. Each button two-way binds to a + // mutually-exclusive bool projection on LanguageSettings, so checking one auto-unchecks + // the others. + + // Arrange — boot. + var window = AppComposition.Current.GetExport(); + window.Show(); + var toggles = window.GetVisualDescendants().OfType() + .Where(t => t.Name is "ShowPublicOnlyButton" or "ShowPrivateInternalButton" or "ShowAllButton") + .ToDictionary(t => t.Name!); + var settings = AppComposition.Current.GetExport().SessionSettings.LanguageSettings; + + // Assert — all three toolbar buttons exist. + toggles.Should().HaveCount(3, + "toolbar should expose ShowPublicOnly, ShowPrivateInternal, and ShowAll ToggleButtons"); + + // Act + Assert — click ShowPublicOnly. The setting flips, the other two unckeck. + settings.ShowApiLevel = ApiVisibility.PublicAndInternal; + toggles["ShowPrivateInternalButton"].IsChecked.Should().BeTrue("baseline before click"); + + toggles["ShowPublicOnlyButton"].IsChecked = true; + settings.ShowApiLevel.Should().Be(ApiVisibility.PublicOnly); + toggles["ShowPrivateInternalButton"].IsChecked.Should().BeFalse( + "flipping ShowPublicOnly must propagate-cancel ShowPrivateInternal via OnPropertyChanged"); + toggles["ShowAllButton"].IsChecked.Should().BeFalse(); + + // Act + Assert — same but flipping the All button. + toggles["ShowAllButton"].IsChecked = true; + settings.ShowApiLevel.Should().Be(ApiVisibility.All); + toggles["ShowPublicOnlyButton"].IsChecked.Should().BeFalse(); + toggles["ShowPrivateInternalButton"].IsChecked.Should().BeFalse(); + } + static int CountVisibleMethods(TypeTreeNode type, LanguageSettings settings) => type.Children.OfType() .Count(m => m.Filter(settings) != FilterResult.Hidden); diff --git a/ILSpy/Assets/Icons/ShowAll.svg b/ILSpy/Assets/Icons/ShowAll.svg new file mode 100644 index 000000000..1d7c4fc4c --- /dev/null +++ b/ILSpy/Assets/Icons/ShowAll.svg @@ -0,0 +1,142 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ILSpy/Assets/Icons/ShowPrivateInternal.svg b/ILSpy/Assets/Icons/ShowPrivateInternal.svg new file mode 100644 index 000000000..e43bd4360 --- /dev/null +++ b/ILSpy/Assets/Icons/ShowPrivateInternal.svg @@ -0,0 +1,101 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/ILSpy/Assets/Icons/ShowPublicOnly.svg b/ILSpy/Assets/Icons/ShowPublicOnly.svg new file mode 100644 index 000000000..24baa490d --- /dev/null +++ b/ILSpy/Assets/Icons/ShowPublicOnly.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ILSpy/Images.cs b/ILSpy/Images.cs index 94ee6ca4b..803d3d646 100644 --- a/ILSpy/Images.cs +++ b/ILSpy/Images.cs @@ -74,6 +74,9 @@ namespace ILSpy.Images public static readonly IImage Forward = LoadSvg(nameof(Forward)); public static readonly IImage Open = LoadSvg(nameof(Open)); public static readonly IImage Save = LoadSvg(nameof(Save)); + public static readonly IImage ShowPublicOnly = LoadSvg(nameof(ShowPublicOnly)); + public static readonly IImage ShowPrivateInternal = LoadSvg(nameof(ShowPrivateInternal)); + public static readonly IImage ShowAll = LoadSvg(nameof(ShowAll)); // Containers public static readonly IImage Namespace = LoadSvg(nameof(Namespace)); diff --git a/ILSpy/ViewModels/MainWindowViewModel.cs b/ILSpy/ViewModels/MainWindowViewModel.cs index 9af70f83f..7117107e7 100644 --- a/ILSpy/ViewModels/MainWindowViewModel.cs +++ b/ILSpy/ViewModels/MainWindowViewModel.cs @@ -37,6 +37,8 @@ namespace ILSpy.ViewModels public DockWorkspace DockWorkspace { get; } + public LanguageSettings LanguageSettings { get; } + public IFactory DockFactory => DockWorkspace.Factory; public IRootDock DockLayout => DockWorkspace.Layout; @@ -46,11 +48,16 @@ namespace ILSpy.ViewModels public string Title => "ILSpy"; [ImportingConstructor] - public MainWindowViewModel(AssemblyTreeModel assemblyTreeModel, LanguageService languageService, DockWorkspace dockWorkspace) + public MainWindowViewModel( + AssemblyTreeModel assemblyTreeModel, + LanguageService languageService, + DockWorkspace dockWorkspace, + SettingsService settingsService) { AssemblyTreeModel = assemblyTreeModel; LanguageService = languageService; DockWorkspace = dockWorkspace; + LanguageSettings = settingsService.SessionSettings.LanguageSettings; } } } diff --git a/ILSpy/Views/MainToolBar.axaml b/ILSpy/Views/MainToolBar.axaml index 81f335998..091dc61f1 100644 --- a/ILSpy/Views/MainToolBar.axaml +++ b/ILSpy/Views/MainToolBar.axaml @@ -152,6 +152,25 @@ + + + + + + + + + + +