AX Agent 컨텍스트 토큰 hover 라벨 닫힘 및 정보 표시 정리
Some checks failed
Release Gate / gate (push) Has been cancelled

- 하단 컨텍스트 토큰 popup 닫힘 판정을 IsMouseOver 중심에서 실제 마우스 좌표 기준으로 보강
- 마우스를 떼었는데도 hover 라벨이 남아 있던 문제를 줄이도록 card/popup 경계 검사 로직 정리
- popup 내용에서 모델명 및 오늘 사용량 줄을 제거하고 현재 사용량과 자동 압축 기준만 남겨 정보 밀도 단순화
- README 및 DEVELOPMENT 문서에 2026-04-05 23:38 (KST) 기준 변경 이력 반영

검증
- dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\
- 경고 0 / 오류 0 확인
This commit is contained in:
2026-04-05 20:50:51 +09:00
parent 25031d655d
commit 87c05720ce
3 changed files with 27 additions and 26 deletions

View File

@@ -1057,3 +1057,5 @@ MIT License
- AX Agent 작업 폴더 선택 팝업의 최근 항목 스타일을 레퍼런스처럼 더 단정한 라운드 row 구조로 정리했다. 각 최근 폴더 항목은 개별 카드형 hover/선택 상태를 가지도록 바꾸고, `다른 폴더 선택`도 같은 시각 언어로 맞췄다. 팝업 외곽 radius, 그림자, 여백, 체크 위치, 텍스트 계층도 함께 조정해 더 자연스럽게 보이게 했다.
- 업데이트: 2026-04-05 23:33 (KST)
- AX Agent 빈 상태 상단 심볼과 작업 유형/대화 주제 프리셋 카드 아이콘 비율을 다시 맞췄다. 프리셋 카드 내부 아이콘과 `프리셋 추가` 심볼은 한 단계 줄이고, 상단 중앙 심볼과 제목도 같은 밀도로 재조정해 화면 균형을 정리했다.
- 업데이트: 2026-04-05 23:38 (KST)
- 하단 컨텍스트 토큰 hover 라벨이 마우스를 떼어도 남아 있던 문제를 보정했다. 닫힘 판정을 단순 `IsMouseOver` 대신 실제 마우스 좌표 기준으로 바꾸고, 팝업 내용도 `현재 사용량 + 자동 압축 기준`만 남기도록 단순화했다.

View File

@@ -4807,3 +4807,6 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
- 업데이트: 2026-04-05 23:33 (KST)
- [ChatWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml) 의 빈 상태 상단 심볼 크기를 42 기준으로 다시 맞추고, 제목/설명 폰트도 함께 미세 조정했다.
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) 의 `BuildTopicButtons()`에서 프리셋 카드 아이콘 원형 배경과 아이콘 크기, `기타`/`프리셋 추가` 카드 심볼 크기를 함께 줄여 프리셋 아이콘이 과하게 커 보이지 않도록 균형을 맞췄다.
- 업데이트: 2026-04-05 23:38 (KST)
- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) 의 하단 컨텍스트 토큰 hover 팝업을 더 단순하게 정리했다. 모델명/오늘 사용량 줄은 제거하고 `현재 사용량``자동 압축 시작 기준`만 남겼다.
- 같은 파일의 토큰 팝업 닫힘 판정도 `IsMouseOver`만 보던 방식에서 실제 마우스 좌표 기반으로 바꿔, 마우스를 떼었는데도 라벨이 남아 있는 경우를 줄였다.

View File

@@ -18939,19 +18939,9 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
TokenUsageArc.Stroke = progressBrush;
TokenUsageThresholdMarker.Fill = progressBrush;
var percentText = $"{Math.Round(usageRatio * 100):0}%";
var (currentService, currentModel) = _llm.GetCurrentModelInfo();
var todayUsage = Services.UsageStatisticsService.GetTodaySnapshot();
var currentModelUsageKey = BuildUsageModelKey(currentService, currentModel);
var currentModelPromptTokens = GetUsageValue(todayUsage.ModelPromptTokens, currentModelUsageKey);
var currentModelCompletionTokens = GetUsageValue(todayUsage.ModelCompletionTokens, currentModelUsageKey);
var currentModelTotalTokens = currentModelPromptTokens + currentModelCompletionTokens;
TokenUsagePercentText.Text = percentText;
TokenUsageSummaryText.Text = $"컨텍스트 {percentText}";
TokenUsageHintText.Text =
$"{Services.TokenEstimator.Format(currentTokens)} / {Services.TokenEstimator.Format(maxContextTokens)}" +
(currentModelTotalTokens > 0
? $" · 오늘 {FormatTokenCount(currentModelTotalTokens)}"
: "");
TokenUsageHintText.Text = $"{Services.TokenEstimator.Format(currentTokens)} / {Services.TokenEstimator.Format(maxContextTokens)}";
CompactNowLabel.Text = compactLabel;
if (TokenUsagePopupTitle != null)
@@ -18960,24 +18950,13 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
TokenUsagePopupUsage.Text = $"{Services.TokenEstimator.Format(currentTokens)}/{Services.TokenEstimator.Format(maxContextTokens)}";
if (TokenUsagePopupDetail != null)
{
var usageLine = currentModelTotalTokens > 0
? $"{currentService} · {currentModel} 오늘 {FormatTokenCount(currentModelTotalTokens)}"
: $"{summary} · 오늘 모델 사용량 없음";
var compactLine = _pendingPostCompaction
TokenUsagePopupDetail.Text = _pendingPostCompaction
? "compact 후 첫 응답 대기 중"
: $"자동 압축 시작 {triggerPercent}%";
TokenUsagePopupDetail.Text = $"{usageLine}\n{compactLine}";
}
if (TokenUsagePopupCompact != null)
{
var compactText = compactLabel switch
{
"지금 압축" => "지금 압축이 필요합니다",
"압축 권장" => "곧 자동 압축이 시작됩니다",
"미리 압축" => "여유가 있을 때 먼저 압축할 수 있습니다",
_ => "AX Agent가 컨텍스트를 자동으로 관리합니다",
};
TokenUsagePopupCompact.Text = compactText;
TokenUsagePopupCompact.Text = "AX Agent가 컨텍스트를 자동으로 관리합니다";
}
TokenUsageCard.ToolTip = null;
@@ -19016,12 +18995,29 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
if (TokenUsagePopup == null)
return;
var cardHovered = TokenUsageCard?.IsMouseOver ?? false;
var popupHovered = TokenUsagePopup.Child is FrameworkElement popupChild && popupChild.IsMouseOver;
var cardHovered = IsMouseInsideElement(TokenUsageCard);
var popupHovered = TokenUsagePopup.Child is FrameworkElement popupChild && IsMouseInsideElement(popupChild);
if (!cardHovered && !popupHovered)
TokenUsagePopup.IsOpen = false;
}
private static bool IsMouseInsideElement(FrameworkElement? element)
{
if (element == null || !element.IsVisible || element.ActualWidth <= 0 || element.ActualHeight <= 0)
return false;
try
{
var mouse = System.Windows.Forms.Control.MousePosition;
var point = element.PointFromScreen(new Point(mouse.X, mouse.Y));
return point.X >= 0 && point.Y >= 0 && point.X <= element.ActualWidth && point.Y <= element.ActualHeight;
}
catch
{
return element.IsMouseOver;
}
}
private static string BuildUsageModelKey(string? service, string? model)
{
var normalizedService = (service ?? "").Trim().ToLowerInvariant();