using System.Windows; using System.Windows.Media; using AxCopilot.SDK; using AxCopilot.Services; using AxCopilot.Themes; namespace AxCopilot.Handlers; /// /// L14-4: 시스템 폰트 목록·검색 핸들러. "font" 프리픽스로 사용합니다. /// /// 예: font → 설치된 폰트 전체 목록 /// font 맑은 → "맑은" 포함 폰트 검색 /// font malgun → 영문 이름으로 검색 /// font mono → "mono" 포함 폰트 목록 /// font nanum → 나눔 폰트 목록 /// Enter → 폰트 이름을 클립보드에 복사. /// public class FontHandler : IActionHandler { public string? Prefix => "font"; public PluginMetadata Metadata => new( "Font", "시스템 폰트 목록 — 검색 · 이름 복사", "1.0", "AX"); // 폰트 목록 캐시 (최초 1회 로드) private static List? _fontCache; private static readonly object _lock = new(); private static List GetFonts() { if (_fontCache != null) return _fontCache; lock (_lock) { if (_fontCache != null) return _fontCache; try { _fontCache = Fonts.SystemFontFamilies .Select(f => f.Source) .OrderBy(n => n, StringComparer.OrdinalIgnoreCase) .ToList(); } catch { _fontCache = new List(); } return _fontCache; } } // 주목할 만한 폰트 그룹 키워드 private static readonly (string Label, string Keyword)[] FontGroups = [ ("한글 폰트", "malgun"), ("나눔 폰트", "nanum"), ("코딩용 폰트", "mono"), ("Arial 계열", "arial"), ("Times 계열", "times"), ("Consolas", "consolas"), ]; public Task> GetItemsAsync(string query, CancellationToken ct) { var q = query.Trim(); var items = new List(); var fonts = GetFonts(); if (string.IsNullOrWhiteSpace(q)) { items.Add(new LauncherItem( $"설치된 폰트 {fonts.Count}개", "font <검색어> 로 필터링", null, null, Symbol: "\uE8D2")); // 그룹 힌트 foreach (var (label, kw) in FontGroups) { var cnt = fonts.Count(f => f.Contains(kw, StringComparison.OrdinalIgnoreCase)); if (cnt > 0) items.Add(new LauncherItem(label, $"{cnt}개 · font {kw}", null, null, Symbol: "\uE8D2")); } // 첫 15개 표시 foreach (var f in fonts.Take(15)) items.Add(MakeFontItem(f)); return Task.FromResult>(items); } // 검색 var filtered = fonts .Where(f => f.Contains(q, StringComparison.OrdinalIgnoreCase)) .ToList(); if (filtered.Count == 0) { items.Add(new LauncherItem("결과 없음", $"'{q}' 포함 폰트가 없습니다", null, null, Symbol: "\uE946")); } else { items.Add(new LauncherItem( $"'{q}' 검색 결과 {filtered.Count}개", "전체 복사: 첫 항목 Enter", null, ("copy", string.Join("\n", filtered)), Symbol: "\uE8D2")); foreach (var f in filtered.Take(30)) items.Add(MakeFontItem(f)); } return Task.FromResult>(items); } public Task ExecuteAsync(LauncherItem item, CancellationToken ct) { if (item.Data is ("copy", string text)) { try { System.Windows.Application.Current.Dispatcher.Invoke( () => Clipboard.SetText(text)); NotificationService.Notify("Font", "클립보드에 복사했습니다."); } catch { /* 비핵심 */ } } return Task.CompletedTask; } private static LauncherItem MakeFontItem(string fontName) => new(fontName, "폰트 이름 · Enter 복사", null, ("copy", fontName), Symbol: "\uE8D2"); }