diff --git a/src/SheetMe.Designer/Controls/LucideIcons.cs b/src/SheetMe.Designer/Controls/LucideIcons.cs
index 77e548c..521ac4d 100644
--- a/src/SheetMe.Designer/Controls/LucideIcons.cs
+++ b/src/SheetMe.Designer/Controls/LucideIcons.cs
@@ -116,20 +116,58 @@ public static class LucideIcons
}
public static FrameworkElement Icon(string name, double size = 16, Brush? color = null)
+ => Build(name, size, color, brushKey: null);
+
+ ///
+ /// 아이콘 — 색을 리소스 키로 지정한다(테마 전환 추종).
+ ///
+ /// Brush 인스턴스를 대입하면 그 시점 값으로 굳어, ThemeManager 가 토큰 사전을 통째로 갈아끼워도
+ /// 이미 만들어진 아이콘은 옛 색을 유지한다(실측: 라이트 전환 후 플로팅 바 도구 아이콘이 다크의
+ /// B.Ink #EDEDED 를 유지해 흰 배경에서 사라졌다). SetResourceReference 는 XAML 의
+ /// DynamicResource 와 동등해 교체를 따라간다.
+ ///
+ public static FrameworkElement Icon(string name, double size, string brushKey)
+ => Build(name, size, color: null, brushKey: brushKey);
+
+ private static FrameworkElement Build(string name, double size, Brush? color, string? brushKey)
{
- color ??= Brushes.Black;
var canvas = new Canvas { Width = 24, Height = 24 };
if (Data.TryGetValue(name, out var markup))
{
var (stroke, fill) = Parse(markup);
if (stroke.Children.Count > 0)
- canvas.Children.Add(new Path { Data = stroke, Stroke = color, StrokeThickness = 2, StrokeStartLineCap = PenLineCap.Round, StrokeEndLineCap = PenLineCap.Round, StrokeLineJoin = PenLineJoin.Round });
+ {
+ var path = new Path
+ {
+ Data = stroke,
+ StrokeThickness = 2,
+ StrokeStartLineCap = PenLineCap.Round,
+ StrokeEndLineCap = PenLineCap.Round,
+ StrokeLineJoin = PenLineJoin.Round,
+ };
+ Paint(path, Path.StrokeProperty, color, brushKey);
+ canvas.Children.Add(path);
+ }
if (fill.Children.Count > 0)
- canvas.Children.Add(new Path { Data = fill, Fill = color });
+ {
+ var path = new Path { Data = fill };
+ Paint(path, Path.FillProperty, color, brushKey);
+ canvas.Children.Add(path);
+ }
}
return new Viewbox { Width = size, Height = size, Child = canvas, Stretch = Stretch.Uniform, SnapsToDevicePixels = true };
}
+ private static void Paint(Path path, DependencyProperty property, Brush? color, string? brushKey)
+ {
+ if (brushKey is not null)
+ {
+ path.SetResourceReference(property, brushKey);
+ return;
+ }
+ path.SetValue(property, color ?? Brushes.Black);
+ }
+
private static (GeometryGroup Stroke, GeometryGroup Fill) Parse(string markup)
{
var stroke = new GeometryGroup();
diff --git a/src/SheetMe.Designer/Controls/PaletteIconCatalog.cs b/src/SheetMe.Designer/Controls/PaletteIconCatalog.cs
index 8714946..f0c3073 100644
--- a/src/SheetMe.Designer/Controls/PaletteIconCatalog.cs
+++ b/src/SheetMe.Designer/Controls/PaletteIconCatalog.cs
@@ -45,12 +45,15 @@ public static class PaletteIconCatalog
///
/// 아이콘 컨버터 공용 파라미터 해석 — "크기" 또는 "크기|브러시키".
///
-/// 브러시 키를 생략하면 종전처럼 B.Muted 를 쓴다(하위호환). 색을 인자로 받을 수 있어야
-/// 활성 문서 탭 아이콘을 강조색으로, 레이어 타입 아이콘을 본문색으로 굽는 것이 가능해진다.
+/// 브러시 키를 생략하면 B.Muted 를 쓴다(하위호환). 색을 인자로 받을 수 있어야
+/// 활성 문서 탭 아이콘을 강조색으로, 레이어 타입 아이콘을 본문색으로 칠할 수 있다.
+///
+/// Brush 인스턴스가 아니라 키를 그대로 돌려준다 — 여기서 TryFindResource 로 브러시를 꺼내
+/// 대입하면 그 시점 값으로 굳어 테마 전환을 따라가지 못한다.
///
internal static class IconParam
{
- public static (double Size, Brush Brush) Parse(object? parameter, double defaultSize)
+ public static (double Size, string BrushKey) Parse(object? parameter, double defaultSize)
{
var size = defaultSize;
var key = "B.Muted";
@@ -69,8 +72,7 @@ internal static class IconParam
}
}
- var brush = System.Windows.Application.Current?.TryFindResource(key) as Brush ?? Brushes.Gray;
- return (size, brush);
+ return (size, key);
}
}
@@ -83,8 +85,8 @@ public sealed class TypeToIconConverter : IValueConverter
{
return null;
}
- var (size, brush) = IconParam.Parse(parameter, 18);
- return LucideIcons.Icon(PaletteIconCatalog.IconOf(type), size, brush);
+ var (size, brushKey) = IconParam.Parse(parameter, 18);
+ return LucideIcons.Icon(PaletteIconCatalog.IconOf(type), size, brushKey);
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
@@ -124,8 +126,8 @@ public sealed class IconNameToVisualConverter : IValueConverter
{
return null;
}
- var (size, brush) = IconParam.Parse(parameter, 14);
- return LucideIcons.Icon(name, size, brush);
+ var (size, brushKey) = IconParam.Parse(parameter, 14);
+ return LucideIcons.Icon(name, size, brushKey);
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
diff --git a/src/SheetMe.Designer/Themes/DesignerTheme.xaml b/src/SheetMe.Designer/Themes/DesignerTheme.xaml
index 3b3f695..0d6c9d5 100644
--- a/src/SheetMe.Designer/Themes/DesignerTheme.xaml
+++ b/src/SheetMe.Designer/Themes/DesignerTheme.xaml
@@ -69,9 +69,10 @@
@@ -106,8 +107,10 @@
+
-
+
@@ -193,6 +196,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -777,10 +895,10 @@
막대 최소 길이는 MinThumbTrack 이 보장한다. 기본 WPF Track 은 Thumb.MinHeight 를 무시해
항목이 많은 목록에서 막대가 실처럼 가늘어진다. -->
-
-
-
-
+
+
+
+