diff --git a/src/SheetMe.Designer/Controls/LucideIcons.cs b/src/SheetMe.Designer/Controls/LucideIcons.cs index 0e6cb9f..46f30d0 100644 --- a/src/SheetMe.Designer/Controls/LucideIcons.cs +++ b/src/SheetMe.Designer/Controls/LucideIcons.cs @@ -168,6 +168,15 @@ public static class LucideIcons return new Viewbox { Width = size, Height = size, Child = canvas, Stretch = Stretch.Uniform, SnapsToDevicePixels = true }; } + /// + /// 아이콘 색 칠하기 — 키가 있으면 리소스 참조(테마 추종), 없으면 넘겨받은 브러시. + /// + /// 둘 다 없으면 검정이 아니라 B.Muted 다. 전에는 Brushes.Black 으로 떨어졌는데, + /// 그건 다크 테마에서 아이콘을 보이지 않게 만드는 기본값이다. + /// 실제로 제목줄의 환자 아이콘이 그 경로로 혼자만 까맣게 묻혀 있었고, + /// 컴파일러가 CS8604 로 그 자리를 계속 가리키고 있었는데도 오래 남아 있었다. + /// 기본값을 테마 토큰으로 두면 어느 호출부도 같은 함정에 빠질 수 없다. + /// private static void Paint(Path path, DependencyProperty property, Brush? color, string? brushKey) { if (brushKey is not null) @@ -175,7 +184,12 @@ public static class LucideIcons path.SetResourceReference(property, brushKey); return; } - path.SetValue(property, color ?? Brushes.Black); + if (color is not null) + { + path.SetValue(property, color); + return; + } + path.SetResourceReference(property, "B.Muted"); } private static (GeometryGroup Stroke, GeometryGroup Fill) Parse(string markup) diff --git a/src/SheetMe.Designer/Diagnostics/EditSmoke.cs b/src/SheetMe.Designer/Diagnostics/EditSmoke.cs index 1f04387..2800a6f 100644 --- a/src/SheetMe.Designer/Diagnostics/EditSmoke.cs +++ b/src/SheetMe.Designer/Diagnostics/EditSmoke.cs @@ -36,6 +36,23 @@ public static class EditSmoke /// 종이에 실제로 그려진 글자를 모은다 — 값이 찍혔는지는 시각 트리에서 확인해야 한다. /// VM 속성만 보면 템플릿이 그 값을 쓰는지 알 수 없다(배선과 결과는 다른 문제다). /// + /// 시각 트리에서 Path 를 전부 모은다 — 아이콘 색 검사에 쓴다 + private static IEnumerable FindPaths(System.Windows.DependencyObject node) + { + if (node is System.Windows.Shapes.Path path) + { + yield return path; + } + // 아이콘은 Viewbox → Canvas → Path 라 논리 자식을 훑어야 한다(시각 트리는 아직 안 만들어졌다) + foreach (var child in System.Windows.LogicalTreeHelper.GetChildren(node).OfType()) + { + foreach (var found in FindPaths(child)) + { + yield return found; + } + } + } + private static string CollectText(System.Windows.DependencyObject node) { var text = node is System.Windows.Controls.TextBlock block ? block.Text + "\n" : string.Empty; @@ -1095,6 +1112,22 @@ public static class EditSmoke $"ValueText='{choiceRow.ValueText}' IsMixed={choiceRow.IsMixed}"); } + // 15-a00) 아이콘 기본색이 검정으로 떨어지지 않는다. + // + // 색도 리소스 키도 안 준 아이콘이 Brushes.Black 으로 칠해지고 있었다. + // 다크 테마에서 그건 안 보이는 아이콘이라는 뜻이다 — 제목줄의 환자 아이콘이 + // 정확히 그 상태로, 옆 아이콘들이 B.Muted 로 밝게 그려지는 사이에서 혼자 까맸다. + // 컴파일러가 CS8604 로 그 자리를 가리키고 있었는데도 오래 남아 있었다. + { + var iconVisual = Controls.LucideIcons.Icon("user", 16, (System.Windows.Media.Brush?)null); + var painted = FindPaths(iconVisual).ToList(); + Check("아이콘: 기본색이 하드코딩 검정이 아니다", + painted.Count > 0 && painted.All(p => + !ReferenceEquals(p.Stroke, System.Windows.Media.Brushes.Black) + && !ReferenceEquals(p.Fill, System.Windows.Media.Brushes.Black)), + $"경로 {painted.Count}개"); + } + // 15-a0) 선택 확장 — 정렬·간격 명령이 전제하는 '올바른 선택'을 만드는 수단. // // 마퀴는 교차 판정이라 행 띠를 스치는 것이 전부 딸려 온다(실측 787건: diff --git a/src/SheetMe.Designer/Views/MainView.xaml.cs b/src/SheetMe.Designer/Views/MainView.xaml.cs index 57fb1b9..4616360 100644 --- a/src/SheetMe.Designer/Views/MainView.xaml.cs +++ b/src/SheetMe.Designer/Views/MainView.xaml.cs @@ -136,7 +136,11 @@ public partial class MainView : Window return; } var on = PatientSession.HasPatient; - PatientIconButton.Content = Controls.LucideIcons.Icon("user", 16, on ? "B.Accent" : null); + // 안 고른 상태의 색은 B.Muted 다 — 옆 아이콘들(복사·삭제·테마·저장)이 XAML 컨버터의 + // 기본값으로 쓰는 바로 그 키다. 전에는 null 을 넘겼고, 그러면 아이콘이 테마 토큰이 아니라 + // 하드코딩 검정으로 칠해져 어두운 제목줄에서 혼자만 까맣게 묻혔다. + // (컴파일러가 CS8604 로 계속 경고하고 있었는데 그 경고가 가리키던 것이 이것이다.) + PatientIconButton.Content = Controls.LucideIcons.Icon("user", 16, on ? "B.Accent" : "B.Muted"); PatientIconButton.ToolTip = on ? $"환자: {PatientSession.Label}\n누르면 바꾸기·해제" : "환자 선택 — 태그와 MDataTable 에 실제 값이 들어갑니다(앱 전체 적용)";