Browse Source

Extend Light/Dark brushes to window, panes, menus, and input controls

Build on the editor / toolbar scaffolding so the rest of the visible
surface area swings with the active theme variant.

Add brush pairs for the surfaces that previously inherited Simple's
Light-only defaults or hardcoded fills:

  WindowBackground / WindowForeground -- the canvas behind everything
  PaneBackground                       -- the assembly tree DataGrid
  ChromeBorder                         -- the hairline borders in the
                                          options pages
  MenuBackground / MenuForeground      -- inline menu bar, dropdowns,
                                          context menus, flyouts
  InputBackground / InputForeground /  -- TextBox, ComboBox, ListBox
  InputBorder                             used across the Options
                                          dialogs and side panes
  SecondaryForeground                  -- the dimmed location / assembly
                                          labels in search results
  TreeAutoloadedForeground             -- SteelBlue (autoloaded marker)
  TreeNonPublicForeground              -- gray (non-public API marker)

Wire them in via Style selectors against Window, DataGrid, Menu,
MenuItem, ContextMenu, MenuFlyoutPresenter, TextBox, ComboBox /
ComboBoxItem, and ListBox / ListBoxItem in App.axaml, plus the three
remaining hardcoded BorderBrushes in OptionsPageView, DisplaySettings
panel and the Foreground="Gray" instances in SearchPane.

Three deliberate gaps remain on Dark:
- Dock chrome (tab strip, splitters) -- needs Dock-specific theme
  brush keys which are a separate vendor surface.
- Button / CheckBox / RadioButton fills -- Simple's defaults are
  legible against the new dark canvas; revisit if they look out of
  place in actual use.
- The warning banner (UpdatePanel) keeps its yellow palette in both
  variants because the colour is semantic, not chrome.

Dark palette continues the VS-style line:
  window      #252526   pane    #1E1E1E   chrome border #3F3F46
  menu        #2D2D30   menu fg #DCDCDC
  input bg    #3C3C3C   input border #555555

Assisted-by: Claude:claude-opus-4-7:Claude Code
pull/3755/head
Siegfried Pammer 1 month ago
parent
commit
3174b8ee5f
  1. 146
      ILSpy/App.axaml
  2. 4
      ILSpy/AssemblyTree/AssemblyListPane.axaml
  3. 2
      ILSpy/Options/DisplaySettingsPanel.axaml
  4. 2
      ILSpy/Options/OptionsPageView.axaml
  5. 4
      ILSpy/Search/SearchPane.axaml

146
ILSpy/App.axaml

@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
xmlns:metaViews="using:ILSpy.Views"
xmlns:dockTheme="using:Dock.Avalonia.Themes.Simple"
xmlns:dockControls="using:Dock.Avalonia.Controls"
xmlns:aeFolding="using:AvaloniaEdit.Folding"
xmlns:recycling="using:Avalonia.Controls.Recycling"
xmlns:docking="using:ILSpy.Docking"
xmlns:controls="using:ILSpy.Controls"
@ -41,6 +42,28 @@ @@ -41,6 +42,28 @@
<SolidColorBrush x:Key="ILSpy.TooltipBackground" Color="#FFFFE1" />
<SolidColorBrush x:Key="ILSpy.TooltipForeground" Color="Black" />
<SolidColorBrush x:Key="ILSpy.TooltipBorder" Color="#FF767676" />
<SolidColorBrush x:Key="ILSpy.WindowBackground" Color="#F0F0F0" />
<SolidColorBrush x:Key="ILSpy.WindowForeground" Color="Black" />
<SolidColorBrush x:Key="ILSpy.PaneBackground" Color="White" />
<SolidColorBrush x:Key="ILSpy.TreeAutoloadedForeground" Color="SteelBlue" />
<SolidColorBrush x:Key="ILSpy.TreeNonPublicForeground" Color="Gray" />
<SolidColorBrush x:Key="ILSpy.ChromeBorder" Color="#FFC8CDD3" />
<SolidColorBrush x:Key="ILSpy.SecondaryForeground" Color="Gray" />
<SolidColorBrush x:Key="ILSpy.MenuBackground" Color="White" />
<SolidColorBrush x:Key="ILSpy.MenuForeground" Color="Black" />
<SolidColorBrush x:Key="ILSpy.InputBackground" Color="White" />
<SolidColorBrush x:Key="ILSpy.InputForeground" Color="Black" />
<SolidColorBrush x:Key="ILSpy.InputBorder" Color="#ABADB3" />
<SolidColorBrush x:Key="ILSpy.DockTabStripBackground" Color="#ECECEC" />
<SolidColorBrush x:Key="ILSpy.DockTabItemBackground" Color="#ECECEC" />
<SolidColorBrush x:Key="ILSpy.DockTabItemForeground" Color="Black" />
<SolidColorBrush x:Key="ILSpy.DockTabItemSelectedBackground" Color="White" />
<SolidColorBrush x:Key="ILSpy.DockTabItemActiveBackground" Color="#007ACC" />
<SolidColorBrush x:Key="ILSpy.DockTabItemActiveForeground" Color="White" />
<SolidColorBrush x:Key="ILSpy.FoldingMarkerBackground" Color="#FFFFE1" />
<SolidColorBrush x:Key="ILSpy.FoldingMarkerForeground" Color="#808080" />
<SolidColorBrush x:Key="ILSpy.FoldingMarkerSelectedBackground" Color="White" />
<SolidColorBrush x:Key="ILSpy.FoldingMarkerSelectedForeground" Color="Black" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="ILSpy.EditorBackground" Color="#1E1E1E" />
@ -56,6 +79,28 @@ @@ -56,6 +79,28 @@
<SolidColorBrush x:Key="ILSpy.TooltipBackground" Color="#252526" />
<SolidColorBrush x:Key="ILSpy.TooltipForeground" Color="#DCDCDC" />
<SolidColorBrush x:Key="ILSpy.TooltipBorder" Color="#3F3F46" />
<SolidColorBrush x:Key="ILSpy.WindowBackground" Color="#252526" />
<SolidColorBrush x:Key="ILSpy.WindowForeground" Color="#DCDCDC" />
<SolidColorBrush x:Key="ILSpy.PaneBackground" Color="#1E1E1E" />
<SolidColorBrush x:Key="ILSpy.TreeAutoloadedForeground" Color="#6FA8DC" />
<SolidColorBrush x:Key="ILSpy.TreeNonPublicForeground" Color="#9AA0A6" />
<SolidColorBrush x:Key="ILSpy.ChromeBorder" Color="#3F3F46" />
<SolidColorBrush x:Key="ILSpy.SecondaryForeground" Color="#A0A0A0" />
<SolidColorBrush x:Key="ILSpy.MenuBackground" Color="#2D2D30" />
<SolidColorBrush x:Key="ILSpy.MenuForeground" Color="#DCDCDC" />
<SolidColorBrush x:Key="ILSpy.InputBackground" Color="#3C3C3C" />
<SolidColorBrush x:Key="ILSpy.InputForeground" Color="#DCDCDC" />
<SolidColorBrush x:Key="ILSpy.InputBorder" Color="#555555" />
<SolidColorBrush x:Key="ILSpy.DockTabStripBackground" Color="#252526" />
<SolidColorBrush x:Key="ILSpy.DockTabItemBackground" Color="#2D2D30" />
<SolidColorBrush x:Key="ILSpy.DockTabItemForeground" Color="#DCDCDC" />
<SolidColorBrush x:Key="ILSpy.DockTabItemSelectedBackground" Color="#1E1E1E" />
<SolidColorBrush x:Key="ILSpy.DockTabItemActiveBackground" Color="#007ACC" />
<SolidColorBrush x:Key="ILSpy.DockTabItemActiveForeground" Color="White" />
<SolidColorBrush x:Key="ILSpy.FoldingMarkerBackground" Color="#1E1E1E" />
<SolidColorBrush x:Key="ILSpy.FoldingMarkerForeground" Color="#A0A0A0" />
<SolidColorBrush x:Key="ILSpy.FoldingMarkerSelectedBackground" Color="#2D2D30" />
<SolidColorBrush x:Key="ILSpy.FoldingMarkerSelectedForeground" Color="#DCDCDC" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
@ -118,6 +163,107 @@ @@ -118,6 +163,107 @@
<Setter Property="BorderThickness" Value="1" />
</Style>
<!-- Window-level chrome: every top-level window picks up these brushes for the
canvas behind the menu / toolbar / dock area. Foreground propagates by
inheritance so default-styled text inside the window goes light on dark. -->
<Style Selector="Window">
<Setter Property="Background" Value="{DynamicResource ILSpy.WindowBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.WindowForeground}" />
</Style>
<!-- Pane-level surfaces (assembly tree DataGrid, search results, etc.). The grid's
own row fills come from the Simple theme; we override the canvas behind the
rows so the dark pane reads as a coherent block rather than a light island. -->
<Style Selector="DataGrid">
<Setter Property="Background" Value="{DynamicResource ILSpy.PaneBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.WindowForeground}" />
</Style>
<!-- Menu surfaces: the inline NativeMenuBar on Linux / Windows, plus every dropdown,
flyout, and context menu. macOS uses the native AppKit menu bar so these
selectors only affect the in-window menus there. -->
<Style Selector="Menu">
<Setter Property="Background" Value="{DynamicResource ILSpy.MenuBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.MenuForeground}" />
</Style>
<!-- Menu items stay transparent so they show whatever surface hosts them: the
NativeMenuBar at the top, or the flyout/context-menu background in dropdowns.
A solid background here paints lighter rectangles over the menu bar. -->
<Style Selector="MenuItem">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.MenuForeground}" />
</Style>
<Style Selector="ContextMenu">
<Setter Property="Background" Value="{DynamicResource ILSpy.MenuBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.MenuForeground}" />
</Style>
<Style Selector="MenuFlyoutPresenter">
<Setter Property="Background" Value="{DynamicResource ILSpy.MenuBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.MenuForeground}" />
</Style>
<!-- Input controls used across dialogs (Options, Open from GAC, Manage Assembly
Lists). The Simple theme paints these with white-on-light fills; route them
through theme-aware brushes so dark mode doesn't leave glaring rectangles. -->
<Style Selector="TextBox">
<Setter Property="Background" Value="{DynamicResource ILSpy.InputBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.InputForeground}" />
<Setter Property="BorderBrush" Value="{DynamicResource ILSpy.InputBorder}" />
</Style>
<Style Selector="ComboBox">
<Setter Property="Background" Value="{DynamicResource ILSpy.InputBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.InputForeground}" />
<Setter Property="BorderBrush" Value="{DynamicResource ILSpy.InputBorder}" />
</Style>
<Style Selector="ComboBoxItem">
<Setter Property="Background" Value="{DynamicResource ILSpy.InputBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.InputForeground}" />
</Style>
<Style Selector="ListBox">
<Setter Property="Background" Value="{DynamicResource ILSpy.InputBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.InputForeground}" />
</Style>
<Style Selector="ListBoxItem">
<Setter Property="Background" Value="{DynamicResource ILSpy.InputBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.InputForeground}" />
</Style>
<!-- Dock chrome: tab strips for the document area and tool panes, plus the
selected-tab content area. Without this Simple paints the strip white,
which clashes against a dark document background. -->
<Style Selector="dockControls|DocumentTabStrip, dockControls|ToolTabStrip">
<Setter Property="Background" Value="{DynamicResource ILSpy.DockTabStripBackground}" />
</Style>
<Style Selector="dockControls|DocumentTabStripItem, dockControls|ToolTabStripItem">
<Setter Property="Background" Value="{DynamicResource ILSpy.DockTabItemBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.DockTabItemForeground}" />
</Style>
<!-- A merely-selected (but not focused) tab gets the seam-matching fill. The active
tab keeps Dock's accent highlight (see below). Splitting the two states is
required: an application-level Style outranks Dock's DocumentTabStripItem
ControlTheme, so a plain :selected setter here would also clobber Dock's
^:active:selected accent fill, flattening the active tab to the seam color. -->
<Style Selector="dockControls|DocumentTabStripItem:selected:not(:active), dockControls|ToolTabStripItem:selected:not(:active)">
<Setter Property="Background" Value="{DynamicResource ILSpy.DockTabItemSelectedBackground}" />
</Style>
<!-- Active (focused-dock) selected tab: re-assert Dock's accent fill at app level,
since our base DocumentTabStripItem style would otherwise win over the theme. -->
<Style Selector="dockControls|DocumentTabStripItem:selected:active, dockControls|ToolTabStripItem:selected:active">
<Setter Property="Background" Value="{DynamicResource ILSpy.DockTabItemActiveBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.DockTabItemActiveForeground}" />
</Style>
<!-- AvaloniaEdit folding margin: the +/- toggle squares are painted by FoldingMargin
with its own brush properties (Background, Marker, plus selected variants for
pointer-over). Default Light values are hardcoded white-on-gray; route them
through our theme so the gutter goes dark with the editor. -->
<Style Selector="aeFolding|FoldingMargin">
<Setter Property="FoldingMarkerBackgroundBrush" Value="{DynamicResource ILSpy.FoldingMarkerBackground}" />
<Setter Property="FoldingMarkerBrush" Value="{DynamicResource ILSpy.FoldingMarkerForeground}" />
<Setter Property="SelectedFoldingMarkerBackgroundBrush" Value="{DynamicResource ILSpy.FoldingMarkerSelectedBackground}" />
<Setter Property="SelectedFoldingMarkerBrush" Value="{DynamicResource ILSpy.FoldingMarkerSelectedForeground}" />
</Style>
<!-- Suppress the column header's hover / pressed fill while the user is interacting
with content INSIDE the header (e.g. typing into a per-column filter TextBox).
Without this, clicking the TextBox briefly flashes the header background blue —

4
ILSpy/AssemblyTree/AssemblyListPane.axaml

@ -8,13 +8,13 @@ @@ -8,13 +8,13 @@
x:DataType="tree:AssemblyTreeModel">
<UserControl.Styles>
<Style Selector="TextBlock.autoloaded">
<Setter Property="Foreground" Value="SteelBlue" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.TreeAutoloadedForeground}" />
</Style>
<!-- Non-public members (private / internal / etc.) read in gray so the visible API
surface stands out at a glance. The class is applied via Classes.nonPublicAPI
binding on the cell-template TextBlock. -->
<Style Selector="TextBlock.nonPublicAPI">
<Setter Property="Foreground" Value="Gray" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.TreeNonPublicForeground}" />
</Style>
</UserControl.Styles>

2
ILSpy/Options/DisplaySettingsPanel.axaml

@ -25,7 +25,7 @@ @@ -25,7 +25,7 @@
Minimum="6" Maximum="72" Increment="1"
Value="{Binding Settings.SelectedFontSize, Mode=TwoWay}" />
<Border Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"
BorderBrush="#FFCCCEDB" BorderThickness="1" Padding="6" Margin="0,2,0,0">
BorderBrush="{DynamicResource ILSpy.ChromeBorder}" BorderThickness="1" Padding="6" Margin="0,2,0,0">
<!-- FontFamily binds to a derived FontFamily property because Avalonia's
runtime binding pipeline doesn't coerce string → FontFamily (the
implicit conversion only fires at XAML parse time). The viewmodel

2
ILSpy/Options/OptionsPageView.axaml

@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
<!-- Reset rolls the currently-selected panel back to its built-in defaults.
No Apply button — panel edits are live, applied immediately to the live
SettingsService instances. XML persistence rides on app-exit Save. -->
<Border DockPanel.Dock="Bottom" BorderBrush="#FFC8CDD3" BorderThickness="0,1,0,0" Padding="8">
<Border DockPanel.Dock="Bottom" BorderBrush="{DynamicResource ILSpy.ChromeBorder}" BorderThickness="0,1,0,0" Padding="8">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Spacing="6">
<Button Content="{x:Static res:Resources.ResetToDefaults}"
Command="{Binding ResetCurrentPageCommand}" />

4
ILSpy/Search/SearchPane.axaml

@ -75,14 +75,14 @@ @@ -75,14 +75,14 @@
<Grid Grid.Column="2" ColumnDefinitions="Auto,4,*">
<Image Grid.Column="0" Source="{Binding LocationImage}" Width="16" Height="16"
VerticalAlignment="Center" />
<TextBlock Grid.Column="2" Text="{Binding Location}" Foreground="Gray"
<TextBlock Grid.Column="2" Text="{Binding Location}" Foreground="{DynamicResource ILSpy.SecondaryForeground}"
VerticalAlignment="Center"
TextTrimming="CharacterEllipsis" />
</Grid>
<Grid Grid.Column="4" ColumnDefinitions="Auto,4,*">
<Image Grid.Column="0" Source="{Binding AssemblyImage}" Width="16" Height="16"
VerticalAlignment="Center" />
<TextBlock Grid.Column="2" Text="{Binding Assembly}" Foreground="Gray"
<TextBlock Grid.Column="2" Text="{Binding Assembly}" Foreground="{DynamicResource ILSpy.SecondaryForeground}"
VerticalAlignment="Center"
TextTrimming="CharacterEllipsis" />
</Grid>

Loading…
Cancel
Save