Browse Source

Give the preview tab a purple snowflake instead of a blue pin

The freeze affordance was a pushpin, and the preview-tab accent stripe was the
same blue as the selection highlight -- so a selected preview tab read as just
'selected'. Swap the glyph for a snowflake (matches the Freeze verb) and the
accent to purple (#9B59B6), keeping the One visually distinct from a
blue-highlighted selected tab. The snowflake is a stroked vector Path with its
Stroke bound to the tab Foreground (theme-inherited), six spokes + tip barbs,
no rotation.

Assisted-by: Claude:claude-opus-4-8:Claude Code
pull/3755/head
Siegfried Pammer 1 month ago
parent
commit
e4fe6e79ec
  1. 5
      ILSpy.Tests/Docking/PreviewTabPromotionTests.cs
  2. 8
      ILSpy/Themes/BoolToBrushConverter.cs
  3. 25
      ILSpy/Themes/PreviewTabFreezeButtonBehavior.cs

5
ILSpy.Tests/Docking/PreviewTabPromotionTests.cs

@ -210,6 +210,11 @@ public class PreviewTabPromotionTests @@ -210,6 +210,11 @@ public class PreviewTabPromotionTests
"the preview MainTab must carry the accent BorderBrush");
mainTabItem.BorderThickness.Should().Be(new global::Avalonia.Thickness(3, 0, 0, 0),
"the preview MainTab must carry the left-only 3px accent stripe");
// The accent is purple (#9B59B6) -- deliberately not the selection/toolbar blue, so the
// One stays distinct from a blue-highlighted selected tab.
(mainTabItem.BorderBrush as global::Avalonia.Media.ISolidColorBrush)!.Color
.Should().Be(global::Avalonia.Media.Color.FromRgb(0x9B, 0x59, 0xB6),
"the preview accent stripe must be purple, not blue");
}
[AvaloniaTest]

8
ILSpy/Themes/BoolToBrushConverter.cs

@ -33,10 +33,12 @@ namespace ILSpy.Themes @@ -33,10 +33,12 @@ namespace ILSpy.Themes
/// </summary>
public sealed class BoolToBrushConverter : IValueConverter
{
/// <summary>Static accent for the preview-tab left-edge stripe — matches the
/// toolbar accent palette (#0078D7).</summary>
/// <summary>Static accent for the preview-tab left-edge stripe. Purple (#9B59B6),
/// deliberately NOT the selection/toolbar blue — so the One preview tab stays visually
/// distinct from a blue-highlighted *selected* tab even when it is itself selected. Reads
/// against both light and dark tab-strip backgrounds.</summary>
public static readonly BoolToBrushConverter PreviewAccent = new() {
TrueBrush = new ImmutableSolidColorBrush(Color.FromRgb(0x00, 0x78, 0xD7)),
TrueBrush = new ImmutableSolidColorBrush(Color.FromRgb(0x9B, 0x59, 0xB6)),
};
public IBrush? TrueBrush { get; init; }

25
ILSpy/Themes/PreviewTabFreezeButtonBehavior.cs

@ -102,24 +102,27 @@ namespace ILSpy.Themes @@ -102,24 +102,27 @@ namespace ILSpy.Themes
// paint on top of it.
titleStack.ClipToBounds = true;
// Tilted-pushpin silhouette matching the Visual Studio preview-tab affordance.
// Vector path (not a font glyph): the previous Segoe Fluent Icons U+E718
// fallback was Windows-only and rendered as a tofu box on Linux / macOS.
// Path with bound Fill is what restores per-tab Foreground inheritance that
// the intermediate SVG-image variant lost - Avalonia.Svg.Skia honors the
// asset's literal fill, not the consuming control's theme color. RotateTransform
// at -45 deg orients the upright pin path so its tip points to the lower-left.
// Snowflake glyph for "freeze". A STROKED vector Path (not a font glyph): the
// previous Segoe Fluent fallback was Windows-only and rendered as tofu on Linux /
// macOS. Six spokes + tip barbs in a 16x16 box (inset so the stroke isn't clipped
// at the tips). Stroke (not Fill) is bound to the tab's Foreground so the glyph
// inherits the per-tab theme colour.
var glyph = new Path {
Data = StreamGeometry.Parse("M5 2h6v1h-1v4l2 2v1H9v3l-1 2-1-2v-3H4V9l2-2V3H5z"),
Data = StreamGeometry.Parse(
"M8,1.5 L8,14.5 M2.37,4.75 L13.63,11.25 M2.37,11.25 L13.63,4.75 " +
"M8,4.2 L6.6,2.9 M8,4.2 L9.4,2.9 M8,11.8 L6.6,13.1 M8,11.8 L9.4,13.1 " +
"M5.0,5.9 L3.4,5.5 M5.0,5.9 L4.6,7.5 M11.0,10.1 L12.6,10.5 M11.0,10.1 L11.4,8.5 " +
"M5.0,10.1 L3.4,10.5 M5.0,10.1 L4.6,8.5 M11.0,5.9 L12.6,5.5 M11.0,5.9 L11.4,7.5"),
Stretch = Stretch.Uniform,
StrokeThickness = 1.3,
StrokeLineCap = PenLineCap.Round,
StrokeJoin = PenLineJoin.Round,
Width = 12,
Height = 12,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
RenderTransform = new RotateTransform(45),
RenderTransformOrigin = RelativePoint.Center,
};
glyph.Bind(Shape.FillProperty, new Binding(nameof(TemplatedControl.Foreground)) {
glyph.Bind(Shape.StrokeProperty, new Binding(nameof(TemplatedControl.Foreground)) {
Source = item,
Mode = BindingMode.OneWay,
});

Loading…
Cancel
Save