using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
namespace SheetMe.Designer.Controls;
///
/// 팔레트 타입 → (Lucide 아이콘, 카테고리) 매핑 — [200]SheetMe 팔레트 타일 룩 이식.
/// Core(ControlRegistry)는 UI 무관하게 유지하고 표시 계층인 여기서만 매핑한다.
///
public static class PaletteIconCatalog
{
#region Member Fields
private static readonly Dictionary Map = new(StringComparer.Ordinal)
{
["Label"] = ("type", "표시"),
["PictureBox"] = ("image", "표시"),
["Line"] = ("minus", "표시"),
// MaskedTextBox 는 TextBox 와 아이콘이 겹쳐 구분이 안 됐다 — [200] 어휘로 분리
["TextBox"] = ("text-cursor-input", "입력"),
["MaskedTextBox"] = ("type", "입력"),
["ComboBox"] = ("list", "입력"),
["ListBox"] = ("list-checks", "입력"),
["CheckList"] = ("list-checks", "입력"),
["DateTimePicker"] = ("calendar", "입력"),
["CalcBox"] = ("sigma", "입력"),
["CheckBox"] = ("square-check", "선택"),
["RadioButton"] = ("circle-dot", "선택"),
["Panel"] = ("package", "컨테이너"),
["GroupBox"] = ("box", "컨테이너"),
["Button"] = ("mouse-pointer-click", "동작/데이터"),
["DataTable"] = ("table", "동작/데이터"),
};
#endregion
#region Methods
/// 타입의 Lucide 아이콘명(미지정 타입은 square)
public static string IconOf(string type) => Map.TryGetValue(type, out var entry) ? entry.Icon : "square";
/// 타입의 팔레트 카테고리(그룹 헤더)
public static string CategoryOf(string type) => Map.TryGetValue(type, out var entry) ? entry.Category : "기타";
#endregion
}
///
/// 아이콘 컨버터 공용 파라미터 해석 — "크기" 또는 "크기|브러시키".
///
/// 브러시 키를 생략하면 종전처럼 B.Muted 를 쓴다(하위호환). 색을 인자로 받을 수 있어야
/// 활성 문서 탭 아이콘을 강조색으로, 레이어 타입 아이콘을 본문색으로 굽는 것이 가능해진다.
///
internal static class IconParam
{
public static (double Size, Brush Brush) Parse(object? parameter, double defaultSize)
{
var size = defaultSize;
var key = "B.Muted";
if (parameter is string text && text.Length > 0)
{
var bar = text.IndexOf('|');
var sizePart = bar >= 0 ? text[..bar] : text;
if (bar >= 0 && bar + 1 < text.Length)
{
key = text[(bar + 1)..].Trim();
}
if (double.TryParse(sizePart, NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed))
{
size = parsed;
}
}
var brush = System.Windows.Application.Current?.TryFindResource(key) as Brush ?? Brushes.Gray;
return (size, brush);
}
}
/// 팔레트 타입명 → Lucide 아이콘 비주얼(FrameworkElement) 컨버터. parameter="크기" 또는 "크기|브러시키"(기본 18, B.Muted)
public sealed class TypeToIconConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is not string type)
{
return null;
}
var (size, brush) = IconParam.Parse(parameter, 18);
return LucideIcons.Icon(PaletteIconCatalog.IconOf(type), size, brush);
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
=> throw new NotSupportedException();
}
/// 팔레트 타입명 → 카테고리명 컨버터(CollectionViewSource 그룹핑용)
public sealed class TypeToCategoryConverter : IValueConverter
{
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
=> value is string type ? PaletteIconCatalog.CategoryOf(type) : "기타";
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
=> throw new NotSupportedException();
}
/// 불리언 반전 컨버터(선택 도구 토글 = !IsHandTool 표시용)
public sealed class InverseBoolConverter : IValueConverter
{
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
=> value is not true;
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
=> value is not true;
}
///
/// Lucide 아이콘명 → 비주얼 컨버터(문서 탭 file-text, 플로팅 바 layout-grid 등 고정 아이콘용).
/// Binding Source 에 아이콘명 문자열을 넣어 사용 — 항목마다 새 비주얼이 생성되어 공유 부모 충돌이 없다.
/// parameter="크기" 또는 "크기|브러시키"(기본 14, B.Muted).
///
public sealed class IconNameToVisualConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is not string name)
{
return null;
}
var (size, brush) = IconParam.Parse(parameter, 14);
return LucideIcons.Icon(name, size, brush);
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
=> throw new NotSupportedException();
}