using System.Globalization; using System.Windows; using System.Windows.Data; using System.Windows.Media; namespace AxCopilot.Themes; public class BoolToVisibilityConverter : IValueConverter { public object Convert(object value, Type t, object p, CultureInfo c) => value is true ? Visibility.Visible : Visibility.Collapsed; public object ConvertBack(object v, Type t, object p, CultureInfo c) => v is Visibility.Visible; } public class InverseBoolToVisibilityConverter : IValueConverter { public object Convert(object value, Type t, object p, CultureInfo c) => value is true ? Visibility.Collapsed : Visibility.Visible; public object ConvertBack(object v, Type t, object p, CultureInfo c) => v is not Visibility.Visible; } public class CountToVisibilityConverter : IValueConverter { public object Convert(object value, Type t, object p, CultureInfo c) => value is int count && count > 0 ? Visibility.Visible : Visibility.Collapsed; public object ConvertBack(object v, Type t, object p, CultureInfo c) => throw new NotImplementedException(); } /// /// Segoe MDL2 심볼 코드포인트 → 아이콘 배경 SolidColorBrush. /// 핸들러 타입별로 서로 다른 색상을 반환합니다. /// public class SymbolToBackgroundConverter : IValueConverter { private static readonly Dictionary SymbolColors = new() { { Symbols.Globe, Brush("#0078D4") }, // URL — Microsoft Blue { Symbols.Folder, Brush("#107C10") }, // 폴더 — Green { Symbols.Terminal, Brush("#1B1B1B") }, // 터미널 — Near Black { Symbols.Clipboard, Brush("#8764B8") }, // 클립보드 — Purple { Symbols.Workspace, Brush("#C50F1F") }, // 워크스페이스 — Red { Symbols.Cloud, Brush("#0099BC") }, // API — Teal { Symbols.Plugin, Brush("#C239B3") }, // 플러그인 — Magenta { Symbols.App, Brush("#4B5EFC") }, // 앱 — Accent { Symbols.File, Brush("#605E5C") }, // 파일 — Gray { Symbols.Save, Brush("#107C10") }, // 저장 — Green { Symbols.Delete, Brush("#C50F1F") }, // 삭제 — Red { Symbols.Rename, Brush("#CA5010") }, // 이름변경 — Orange { Symbols.Restore, Brush("#0078D4") }, // 복원 — Blue { Symbols.Info, Brush("#4B5EFC") }, // 정보 — Accent { Symbols.Warning, Brush("#CA5010") }, // 경고 — Orange { Symbols.Error, Brush("#C50F1F") }, // 오류 — Red }; private static readonly SolidColorBrush DefaultBrush = Brush("#4B5EFC"); public object Convert(object value, Type t, object p, CultureInfo c) => value is string symbol && SymbolColors.TryGetValue(symbol, out var brush) ? brush : DefaultBrush; public object ConvertBack(object v, Type t, object p, CultureInfo c) => throw new NotImplementedException(); private static SolidColorBrush Brush(string hex) { var color = (Color)ColorConverter.ConvertFromString(hex); var brush = new SolidColorBrush(color); brush.Freeze(); return brush; } } /// /// 바인딩 값과 파라미터 문자열이 일치하는지 여부를 bool로 반환합니다. /// RadioButton IsChecked 바인딩에 사용합니다. /// public class StringEqualConverter : IValueConverter { public object Convert(object value, Type t, object p, CultureInfo c) => value is string s && p is string param && s == param; public object ConvertBack(object v, Type t, object p, CultureInfo c) => v is true ? p : System.Windows.Data.Binding.DoNothing; } /// /// "#RRGGBB" 헥스 문자열 → WPF Color 변환기 (테마 카드 미리보기용). /// XAML에서 {x:Static converters:HexToColorConverter.Instance} 로 사용합니다. /// public class HexToColorConverter : IValueConverter { public static readonly HexToColorConverter Instance = new(); public object Convert(object value, Type t, object p, CultureInfo c) { if (value is string hex) { try { return (Color)ColorConverter.ConvertFromString(hex); } catch (Exception) { /* 잘못된 값이면 기본 반환 */ } } return Colors.Transparent; } public object ConvertBack(object v, Type t, object p, CultureInfo c) => throw new NotImplementedException(); } /// null 또는 빈 문자열이면 Collapsed, 값이 있으면 Visible. public class NullToCollapsedConverter : IValueConverter { public object Convert(object value, Type t, object p, CultureInfo c) => value is string s && !string.IsNullOrEmpty(s) ? Visibility.Visible : Visibility.Collapsed; public object ConvertBack(object v, Type t, object p, CultureInfo c) => throw new NotImplementedException(); } /// LauncherItem.Data가 ClipboardEntry(이미지)면 썸네일 BitmapSource 반환. public class ClipboardThumbnailConverter : IValueConverter { public object? Convert(object value, Type t, object p, CultureInfo c) { if (value is Services.ClipboardEntry { Image: not null } entry) return entry.Image; return null; } public object ConvertBack(object v, Type t, object p, CultureInfo c) => throw new NotImplementedException(); } /// ClipboardEntry 이미지가 있으면 Visible. public class ClipboardHasImageConverter : IValueConverter { public object Convert(object value, Type t, object p, CultureInfo c) => value is Services.ClipboardEntry { Image: not null } ? Visibility.Visible : Visibility.Collapsed; public object ConvertBack(object v, Type t, object p, CultureInfo c) => throw new NotImplementedException(); } /// Subtitle에 경고 기호(⚠)가 포함되면 Visible, 아니면 Collapsed 반환. public class WarningSubtitleColorConverter : IValueConverter { public object Convert(object value, Type t, object p, CultureInfo c) => value is string s && s.Contains('\u26A0') ? Visibility.Visible : Visibility.Collapsed; public object ConvertBack(object v, Type t, object p, CultureInfo c) => throw new NotImplementedException(); } /// ListViewItem → 1-based 인덱스 문자열. 9 초과 시 빈 문자열. public class IndexToNumberConverter : IValueConverter { public object Convert(object value, Type t, object p, CultureInfo c) { if (value is System.Windows.Controls.ListViewItem item) { var lv = System.Windows.Controls.ItemsControl.ItemsControlFromItemContainer(item); if (lv != null) { var idx = lv.ItemContainerGenerator.IndexFromContainer(item); return idx >= 0 && idx < 9 ? (idx + 1).ToString() : ""; } } return ""; } public object ConvertBack(object v, Type t, object p, CultureInfo c) => throw new NotImplementedException(); }