Browse Source

Author manual Light/Dark brushes for the surfaces ILSpy paints itself

Simple theme ships no Dark resource dictionary, so flipping
RequestedThemeVariant alone is a no-op against any surface whose
brushes are hardcoded or pulled from a Simple key. We can't swap
themes (Simple is the deliberate visual identity), but we can layer
our own ThemeDictionaries on top so the surfaces ILSpy owns directly
respond to View > Theme.

Introduce a single block of Light / Dark brush pairs under
Application.Resources.ThemeDictionaries (App.axaml), then route the
hardcoded brushes in the editor view, the toolbar, the zoom overlay,
and tooltips through DynamicResource lookups against those keys.

Surfaces wired:
- Decompiler text view background and wait-adorner overlay.
- Main toolbar background, bottom border, separator hairlines,
  combobox border, and the disabled-button content fills.
- Zoom-buttons overlay background and border.
- Tooltips (background, foreground, border) via a Style selector
  since Simple paints them via hardcoded setters that don't expose
  a brush key.

Simple-themed chrome (menu, tree, scrollbars, status bar, dock
splitters) remains Light in both variants. That's partial dark mode
by design -- covering it requires either swapping to Fluent (which
costs the Simple visual identity, and a separate test showed the
chrome regressing under Fluent) or redeclaring every Simple resource
key per variant, which is a much larger effort. Follow-ups will
extend coverage one surface at a time.

Light values match what each file shipped (no visible diff in the
default theme). Dark values follow the VS-style palette:
  editor       #1E1E1E
  toolbar      #2D2D30  border  #3F3F46
  tooltip      #252526  border  #3F3F46  foreground #DCDCDC
  zoom overlay #E01E1E1E with translucent gray border

Assisted-by: Claude:claude-opus-4-7:Claude Code
pull/3755/head
Siegfried Pammer 1 month ago
parent
commit
7c7c17ca77
  1. 105
      ILSpy/App.axaml
  2. 4
      ILSpy/TextView/DecompilerTextView.axaml
  3. 4
      ILSpy/TextView/ZoomButtons.axaml
  4. 12
      ILSpy/Views/MainToolBar.axaml

105
ILSpy/App.axaml

@ -19,33 +19,74 @@ @@ -19,33 +19,74 @@
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
<Application.Resources>
<!-- Every dockable owns its view (IDockableViewOwner): the dock chrome must render one
view per dockable identity, not one per slot, or two panes sharing a ToolDock slot
(e.g. Analyzer + Debug Steps both Bottom-aligned) render each other's content. This
resolver hands back the dockable's own view instead of pinning views in a global,
never-evicting cache (a leak for transient document tabs). Wired to every DockControl
via the style below. -->
<docking:DockableViewRecycling x:Key="ControlRecyclingKey" />
<!-- Override ProDataGrid's hierarchical expander to a classic Windows-Explorer-sized 9x9 box,
plus 4px of left padding (so the ToggleButton itself is 13x9). -->
<x:Double x:Key="DataGridHierarchicalExpanderSize">13</x:Double>
<x:Double x:Key="DataGridHierarchicalExpanderGlyphSize">5</x:Double>
<!-- Suppress the cell focus rectangle — selected rows already get the highlight background. -->
<SolidColorBrush x:Key="DataGridCellFocusVisualPrimaryBrush" Color="Transparent" />
<SolidColorBrush x:Key="DataGridCellFocusVisualSecondaryBrush" Color="Transparent" />
<!-- Suppress the gray pointer-over highlight on rows and cells. -->
<SolidColorBrush x:Key="DataGridRowHoveredBackgroundBrush" Color="Transparent" />
<SolidColorBrush x:Key="DataGridCellHoveredBackgroundBrush" Color="Transparent" />
<!-- Replace the Simple theme's saturated dark fill on column-header hover/press
with the toolbar accent palette (#330078D7 hover, #660078D7 pressed). The
default makes header text unreadable while sorting / resizing; the lighter
translucent accent matches MainToolBar.axaml's button hover treatment. -->
<SolidColorBrush x:Key="DataGridColumnHeaderHoveredBackgroundBrush" Color="#330078D7" />
<SolidColorBrush x:Key="DataGridColumnHeaderPressedBackgroundBrush" Color="#660078D7" />
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<!-- Light / Dark variant brushes for the surfaces ILSpy paints directly
(the editor canvas and the toolbar chrome). The Simple theme itself
ships no Dark resource dictionary, so chrome painted by Simple (menu,
scrollbars, tree, status bar) stays Light regardless of the user's
theme choice. Intentional, partial dark mode targeting only the
surfaces a reader spends most time looking at. -->
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="ILSpy.EditorBackground" Color="#FFFFE1" />
<SolidColorBrush x:Key="ILSpy.EditorWaitAdornerBackground" Color="#80FFFFFF" />
<SolidColorBrush x:Key="ILSpy.ToolbarBackground" Color="White" />
<SolidColorBrush x:Key="ILSpy.ToolbarBorder" Color="#FFA9B0B7" />
<SolidColorBrush x:Key="ILSpy.ToolbarSeparator" Color="#FFC8CDD3" />
<SolidColorBrush x:Key="ILSpy.ToolbarComboBoxBorder" Color="#FFCCCEDB" />
<SolidColorBrush x:Key="ILSpy.ToolbarDisabledFill" Color="#22000000" />
<SolidColorBrush x:Key="ILSpy.ToolbarDisabledBorder" Color="#33000000" />
<SolidColorBrush x:Key="ILSpy.ZoomButtonsBackground" Color="#E0FFFFE1" />
<SolidColorBrush x:Key="ILSpy.ZoomButtonsBorder" Color="#80808080" />
<SolidColorBrush x:Key="ILSpy.TooltipBackground" Color="#FFFFE1" />
<SolidColorBrush x:Key="ILSpy.TooltipForeground" Color="Black" />
<SolidColorBrush x:Key="ILSpy.TooltipBorder" Color="#FF767676" />
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="ILSpy.EditorBackground" Color="#1E1E1E" />
<SolidColorBrush x:Key="ILSpy.EditorWaitAdornerBackground" Color="#A0000000" />
<SolidColorBrush x:Key="ILSpy.ToolbarBackground" Color="#2D2D30" />
<SolidColorBrush x:Key="ILSpy.ToolbarBorder" Color="#3F3F46" />
<SolidColorBrush x:Key="ILSpy.ToolbarSeparator" Color="#3F3F46" />
<SolidColorBrush x:Key="ILSpy.ToolbarComboBoxBorder" Color="#3F3F46" />
<SolidColorBrush x:Key="ILSpy.ToolbarDisabledFill" Color="#22FFFFFF" />
<SolidColorBrush x:Key="ILSpy.ToolbarDisabledBorder" Color="#33FFFFFF" />
<SolidColorBrush x:Key="ILSpy.ZoomButtonsBackground" Color="#E01E1E1E" />
<SolidColorBrush x:Key="ILSpy.ZoomButtonsBorder" Color="#80A0A0A0" />
<SolidColorBrush x:Key="ILSpy.TooltipBackground" Color="#252526" />
<SolidColorBrush x:Key="ILSpy.TooltipForeground" Color="#DCDCDC" />
<SolidColorBrush x:Key="ILSpy.TooltipBorder" Color="#3F3F46" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<!-- Every dockable owns its view (IDockableViewOwner): the dock chrome must render one
view per dockable identity, not one per slot, or two panes sharing a ToolDock slot
(e.g. Analyzer + Debug Steps both Bottom-aligned) render each other's content. This
resolver hands back the dockable's own view instead of pinning views in a global,
never-evicting cache (a leak for transient document tabs). Wired to every DockControl
via the style below. -->
<docking:DockableViewRecycling x:Key="ControlRecyclingKey" />
<!-- Override ProDataGrid's hierarchical expander to a classic Windows-Explorer-sized 9x9 box,
plus 4px of left padding (so the ToggleButton itself is 13x9). -->
<x:Double x:Key="DataGridHierarchicalExpanderSize">13</x:Double>
<x:Double x:Key="DataGridHierarchicalExpanderGlyphSize">5</x:Double>
<!-- Suppress the cell focus rectangle — selected rows already get the highlight background. -->
<SolidColorBrush x:Key="DataGridCellFocusVisualPrimaryBrush" Color="Transparent" />
<SolidColorBrush x:Key="DataGridCellFocusVisualSecondaryBrush" Color="Transparent" />
<!-- Suppress the gray pointer-over highlight on rows and cells. -->
<SolidColorBrush x:Key="DataGridRowHoveredBackgroundBrush" Color="Transparent" />
<SolidColorBrush x:Key="DataGridCellHoveredBackgroundBrush" Color="Transparent" />
<!-- Replace the Simple theme's saturated dark fill on column-header hover/press
with the toolbar accent palette (#330078D7 hover, #660078D7 pressed). The
default makes header text unreadable while sorting / resizing; the lighter
translucent accent matches MainToolBar.axaml's button hover treatment. -->
<SolidColorBrush x:Key="DataGridColumnHeaderHoveredBackgroundBrush" Color="#330078D7" />
<SolidColorBrush x:Key="DataGridColumnHeaderPressedBackgroundBrush" Color="#660078D7" />
</ResourceDictionary>
</Application.Resources>
<Application.DataTemplates>
@ -67,6 +108,16 @@ @@ -67,6 +108,16 @@
<Setter Property="(recycling:ControlRecyclingDataTemplate.ControlRecycling)" Value="{StaticResource ControlRecyclingKey}" />
</Style>
<!-- Tooltips: Simple theme paints them with hardcoded fills that don't respond to
RequestedThemeVariant. Restyle ToolTip so background, foreground, and border
route through our ILSpy.Tooltip* brushes and swap with the active theme. -->
<Style Selector="ToolTip">
<Setter Property="Background" Value="{DynamicResource ILSpy.TooltipBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ILSpy.TooltipForeground}" />
<Setter Property="BorderBrush" Value="{DynamicResource ILSpy.TooltipBorder}" />
<Setter Property="BorderThickness" Value="1" />
</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/TextView/DecompilerTextView.axaml

@ -17,11 +17,11 @@ @@ -17,11 +17,11 @@
<textView:DecompilerTextEditor Name="Editor"
IsReadOnly="True"
ShowLineNumbers="True"
Background="#FFFFE1"
Background="{DynamicResource ILSpy.EditorBackground}"
FontFamily="Consolas, Menlo, Monospace"
FontSize="13" />
<Border Name="WaitAdorner"
Background="#80FFFFFF"
Background="{DynamicResource ILSpy.EditorWaitAdornerBackground}"
IsVisible="{Binding IsDecompiling}">
<Grid ColumnDefinitions="*,Auto,*">
<StackPanel Grid.Column="1"

4
ILSpy/TextView/ZoomButtons.axaml

@ -3,7 +3,9 @@ @@ -3,7 +3,9 @@
x:Class="ILSpy.TextView.ZoomButtons"
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Margin="0,0,12,12">
<Border Background="#E0FFFFE1" BorderBrush="#80808080" BorderThickness="1"
<Border Background="{DynamicResource ILSpy.ZoomButtonsBackground}"
BorderBrush="{DynamicResource ILSpy.ZoomButtonsBorder}"
BorderThickness="1"
CornerRadius="3" Padding="2">
<StackPanel Orientation="Horizontal" Spacing="2">
<Button Name="MinusButton" Content="&#8722;" Width="22" Height="22"

12
ILSpy/Views/MainToolBar.axaml

@ -97,8 +97,8 @@ @@ -97,8 +97,8 @@
<Setter Property="Cursor" Value="Arrow" />
</Style>
<Style Selector="StackPanel#ToolbarRoot > Button:disabled /template/ ContentPresenter, StackPanel#ToolbarRoot > ToggleButton:disabled /template/ ContentPresenter">
<Setter Property="Background" Value="#22000000" />
<Setter Property="BorderBrush" Value="#33000000" />
<Setter Property="Background" Value="{DynamicResource ILSpy.ToolbarDisabledFill}" />
<Setter Property="BorderBrush" Value="{DynamicResource ILSpy.ToolbarDisabledBorder}" />
</Style>
<!-- Default Fluent SplitButton paints both halves with an opaque dark fill on press
(looks black against our white toolbar). Replace with the toolbar accent palette
@ -125,7 +125,7 @@ @@ -125,7 +125,7 @@
<Setter Property="Width" Value="1" />
<Setter Property="Height" Value="18" />
<Setter Property="Margin" Value="4,3" />
<Setter Property="Background" Value="#FFC8CDD3" />
<Setter Property="Background" Value="{DynamicResource ILSpy.ToolbarSeparator}" />
</Style>
<!-- Keep the combos flush with the buttons; soften the default border so it sits
@ -136,7 +136,7 @@ @@ -136,7 +136,7 @@
<Setter Property="MinHeight" Value="22" />
<Setter Property="Padding" Value="6,1" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="BorderBrush" Value="#FFCCCEDB" />
<Setter Property="BorderBrush" Value="{DynamicResource ILSpy.ToolbarComboBoxBorder}" />
</Style>
<!-- The Simple theme's ComboBox template (this project uses Avalonia.Themes.Simple,
not Fluent) places a separate ToggleButton named "toggle" in the chevron column
@ -168,9 +168,9 @@ @@ -168,9 +168,9 @@
</Style>
</UserControl.Styles>
<Border BorderThickness="0,0,0,1" BorderBrush="#FFA9B0B7"
<Border BorderThickness="0,0,0,1" BorderBrush="{DynamicResource ILSpy.ToolbarBorder}"
MinHeight="29" Padding="3"
Background="White">
Background="{DynamicResource ILSpy.ToolbarBackground}">
<StackPanel Name="ToolbarRoot" Orientation="Horizontal">
<!-- Navigation: Back / Forward as web-browser-style split buttons. The primary half
navigates one step; the chevron drops a menu of recent history entries built on

Loading…
Cancel
Save