[Phase L3-9 + 버그] AX Agent 오류 수정 + 런처 미니 위젯 4종 구현
AX Agent 오류 수정: - AgentSettingsPanel.xaml에 <UserControl.Resources> 추가 - ToggleSwitch 스타일 자체 정의 (SettingsWindow 리소스 미접근 문제 해결) - 원인: XamlParseException — 'ToggleSwitch' 리소스 찾을 수 없음 (CS 로그 확인) PerformanceMonitorService.cs (신규, 138줄): - GetSystemTimes P/Invoke → CPU% (이전/현재 샘플 델타 계산) - GlobalMemoryStatusEx P/Invoke → RAM% + "6.1/16GB" 형식 텍스트 - DriveInfo → C: 드라이브 사용률/용량 텍스트 - 2초 폴링, StartPolling/StopPolling 제어 PomodoroService.cs (신규, 179줄): - 집중(25분)/휴식(5분) 타이머, 상태: Idle/Focus/Break - pomodoro.json 영속성 (경과 시간 자동 보정) - StateChanged 이벤트 → 위젯 실시간 갱신 ServerStatusService.cs (신규, 124줄): - Ollama(/api/version), LLM API, 첫 번째 MCP 서버 15초 주기 핑 - HttpClient 1.5초 타임아웃, StatusChanged 이벤트 PomoHandler.cs (신규, 130줄): - pomo prefix: 상태보기/start/break/stop/reset - PomodoroService 직접 연동 LauncherViewModel.Widgets.cs (신규, 81줄): - Widget_PerfText, Widget_PomoText, Widget_PomoRunning - Widget_NoteText, Widget_OllamaOnline, Widget_LlmOnline, Widget_McpOnline - UpdateWidgets() — 5틱마다 메모 건수 갱신 (파일 I/O 최소화) LauncherWindow.Widgets.cs (신규, 143줄): - IsVisibleChanged 이벤트로 위젯 자동 시작/중지 - DispatcherTimer 1초마다 UpdateWidgets + 서버 상태 dot 색상 직접 갱신 - 위젯 클릭 → 해당 prefix 자동 입력 (perf→info, pomo→pomo, note→note, server→port) LauncherWindow.xaml: - RowDefinition 6개 → 7개 - Row 6: 위젯 바 (시스템모니터/뽀모도로/메모/서버 4열) 빌드: 경고 0, 오류 0
This commit is contained in:
143
src/AxCopilot/Views/LauncherWindow.Widgets.cs
Normal file
143
src/AxCopilot/Views/LauncherWindow.Widgets.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using AxCopilot.Services;
|
||||
|
||||
namespace AxCopilot.Views;
|
||||
|
||||
/// <summary>
|
||||
/// Phase L3-9: 런처 하단 미니 위젯 바 로직.
|
||||
/// 타이머로 1초마다 ViewModel 갱신 + 서버 상태 dot 색상 직접 업데이트.
|
||||
/// </summary>
|
||||
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));
|
||||
|
||||
/// <summary>LauncherWindow.xaml.cs의 Show()에서 최초 1회 호출 — IsVisibleChanged로 자동 관리.</summary>
|
||||
internal void InitWidgets()
|
||||
{
|
||||
IsVisibleChanged -= OnLauncherVisibleChanged;
|
||||
IsVisibleChanged += OnLauncherVisibleChanged;
|
||||
}
|
||||
|
||||
private void OnLauncherVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if ((bool)e.NewValue) StartWidgetUpdates();
|
||||
else StopWidgetUpdates();
|
||||
}
|
||||
|
||||
/// <summary>런처가 표시될 때 위젯 업데이트 시작.</summary>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>런처가 숨겨질 때 타이머 중지 (뽀모도로는 계속 실행).</summary>
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user