using System.Windows; using System.Windows.Media; using System.Windows.Threading; using AxCopilot.Services; namespace AxCopilot.Views; /// /// Phase L3-9: 런처 하단 미니 위젯 바 로직. /// 타이머로 1초마다 ViewModel 갱신 + 서버 상태 dot 색상 직접 업데이트. /// public partial class LauncherWindow { private DispatcherTimer? _widgetTimer; private static readonly SolidColorBrush _dotOnline = new(Color.FromRgb(0x10, 0xB9, 0x81)); private static readonly SolidColorBrush _dotOffline = new(Color.FromRgb(0x9E, 0x9E, 0x9E)); /// LauncherWindow.xaml.cs의 Show()에서 최초 1회 호출 — IsVisibleChanged로 자동 관리. internal void InitWidgets() { IsVisibleChanged -= OnLauncherVisibleChanged; IsVisibleChanged += OnLauncherVisibleChanged; } private void OnLauncherVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { if ((bool)e.NewValue) StartWidgetUpdates(); else StopWidgetUpdates(); } /// 런처가 표시될 때 위젯 업데이트 시작. internal void StartWidgetUpdates() { var settings = CurrentApp?.SettingsService?.Settings; // 서비스 시작 PerformanceMonitorService.Instance.StartPolling(); ServerStatusService.Instance.Start(settings); PomodoroService.Instance.StateChanged -= OnPomoStateChanged; PomodoroService.Instance.StateChanged += OnPomoStateChanged; ServerStatusService.Instance.StatusChanged -= OnServerStatusChanged; ServerStatusService.Instance.StatusChanged += OnServerStatusChanged; // 메모 건수 즉시 갱신 (최초 1회) _vm.UpdateWidgets(); UpdateServerDots(); // 1초 타이머 if (_widgetTimer == null) { _widgetTimer = new DispatcherTimer(DispatcherPriority.Background) { Interval = TimeSpan.FromSeconds(1) }; _widgetTimer.Tick += (_, _) => { _vm.UpdateWidgets(); UpdateServerDots(); }; } _widgetTimer.Start(); // 뽀모도로 실행 중이면 위젯 색상 강조 UpdatePomoWidgetStyle(); } /// 런처가 숨겨질 때 타이머 중지 (뽀모도로는 계속 실행). internal void StopWidgetUpdates() { _widgetTimer?.Stop(); PerformanceMonitorService.Instance.StopPolling(); PomodoroService.Instance.StateChanged -= OnPomoStateChanged; ServerStatusService.Instance.StatusChanged -= OnServerStatusChanged; } // ─── 이벤트 핸들러 ────────────────────────────────────────────────────── private void OnPomoStateChanged(object? sender, EventArgs e) { Dispatcher.InvokeAsync(() => { _vm.UpdateWidgets(); UpdatePomoWidgetStyle(); }); } private void OnServerStatusChanged(object? sender, EventArgs e) { Dispatcher.InvokeAsync(UpdateServerDots); } // ─── UI 업데이트 ──────────────────────────────────────────────────────── private void UpdateServerDots() { var srv = ServerStatusService.Instance; if (OllamaStatusDot != null) OllamaStatusDot.Fill = srv.OllamaOnline ? _dotOnline : _dotOffline; if (LlmStatusDot != null) LlmStatusDot.Fill = srv.LlmOnline ? _dotOnline : _dotOffline; if (McpStatusDot != null) McpStatusDot.Fill = srv.McpOnline ? _dotOnline : _dotOffline; } private void UpdatePomoWidgetStyle() { if (WgtPomo == null) return; var running = PomodoroService.Instance.IsRunning; WgtPomo.Background = running ? new SolidColorBrush(Color.FromArgb(0x1E, 0xF5, 0x9E, 0x0B)) : new SolidColorBrush(Color.FromArgb(0x0D, 0xF5, 0x9E, 0x0B)); } // ─── 위젯 클릭 핸들러 ─────────────────────────────────────────────────── private void WgtPerf_Click(object sender, System.Windows.Input.MouseButtonEventArgs e) { _vm.InputText = "info "; InputBox?.Focus(); } private void WgtPomo_Click(object sender, System.Windows.Input.MouseButtonEventArgs e) { _vm.InputText = "pomo "; InputBox?.Focus(); } private void WgtNote_Click(object sender, System.Windows.Input.MouseButtonEventArgs e) { _vm.InputText = "note "; InputBox?.Focus(); } private void WgtServer_Click(object sender, System.Windows.Input.MouseButtonEventArgs e) { // 서버 상태 강제 새로고침 var settings = CurrentApp?.SettingsService?.Settings; ServerStatusService.Instance.Refresh(settings); _vm.InputText = "port"; InputBox?.Focus(); } }