AX Agent 좌측 패널과 컨텍스트 사용량 UI를 Codex 기준으로 재정렬\n\n- 좌측 사이드바 폭과 새 대화/검색/필터/탭 메뉴 타이포를 키워 레퍼런스와 더 비슷한 밀도로 조정\n- Cowork 작업 유형 카드 크기와 제목/hover 설명 라벨 폰트를 확대해 가독성 보정\n- 하단 컨텍스트 사용량 카드를 작은 원형 심볼로 축소하고 hover 전용 커스텀 팝업으로 상세 정보 분리\n- README와 DEVELOPMENT 문서에 변경 이력 및 검증 결과 즉시 반영\n\n검증 결과\n- dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\\n- 경고 0 / 오류 0
Some checks failed
Release Gate / gate (push) Has been cancelled
Some checks failed
Release Gate / gate (push) Has been cancelled
This commit is contained in:
@@ -87,6 +87,7 @@ public partial class ChatWindow : Window
|
||||
private readonly DispatcherTimer _taskSummaryRefreshTimer;
|
||||
private readonly DispatcherTimer _conversationPersistTimer;
|
||||
private readonly DispatcherTimer _agentUiEventTimer;
|
||||
private readonly DispatcherTimer _tokenUsagePopupCloseTimer;
|
||||
private CancellationTokenSource? _gitStatusRefreshCts;
|
||||
private int _displayedLength; // 현재 화면에 표시된 글자 수
|
||||
private ResourceDictionary? _agentThemeDictionary;
|
||||
@@ -270,6 +271,13 @@ public partial class ChatWindow : Window
|
||||
_agentUiEventTimer.Stop();
|
||||
FlushPendingAgentUiEvent();
|
||||
};
|
||||
_tokenUsagePopupCloseTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(140) };
|
||||
_tokenUsagePopupCloseTimer.Tick += (_, _) =>
|
||||
{
|
||||
_tokenUsagePopupCloseTimer.Stop();
|
||||
if (TokenUsagePopup != null)
|
||||
TokenUsagePopup.IsOpen = false;
|
||||
};
|
||||
|
||||
KeyDown += ChatWindow_KeyDown;
|
||||
UpdateConversationFailureFilterUi();
|
||||
@@ -12113,8 +12121,8 @@ public partial class ChatWindow : Window
|
||||
Padding = new Thickness(14, 14, 14, 12),
|
||||
Margin = new Thickness(6, 6, 6, 8),
|
||||
Cursor = Cursors.Hand,
|
||||
Width = 132,
|
||||
Height = 110,
|
||||
Width = 148,
|
||||
Height = 124,
|
||||
ClipToBounds = true,
|
||||
};
|
||||
|
||||
@@ -12127,17 +12135,17 @@ public partial class ChatWindow : Window
|
||||
|
||||
var iconCircle = new Border
|
||||
{
|
||||
Width = 42, Height = 42,
|
||||
CornerRadius = new CornerRadius(21),
|
||||
Width = 46, Height = 46,
|
||||
CornerRadius = new CornerRadius(23),
|
||||
Background = new SolidColorBrush(((SolidColorBrush)btnColor).Color) { Opacity = 0.15 },
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
Margin = new Thickness(0, 0, 0, 10),
|
||||
Margin = new Thickness(0, 0, 0, 12),
|
||||
};
|
||||
var iconTb = new TextBlock
|
||||
{
|
||||
Text = preset.Symbol,
|
||||
FontFamily = new FontFamily("Segoe MDL2 Assets"),
|
||||
FontSize = 18.5,
|
||||
FontSize = 20,
|
||||
Foreground = btnColor,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
@@ -12148,13 +12156,13 @@ public partial class ChatWindow : Window
|
||||
stack.Children.Add(new TextBlock
|
||||
{
|
||||
Text = preset.Label,
|
||||
FontSize = 14,
|
||||
FontSize = 15.5,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Foreground = primaryText,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
TextAlignment = TextAlignment.Center,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
MaxWidth = 98,
|
||||
MaxWidth = 112,
|
||||
});
|
||||
|
||||
var hoverLabel = new Border
|
||||
@@ -12172,10 +12180,10 @@ public partial class ChatWindow : Window
|
||||
Child = new TextBlock
|
||||
{
|
||||
Text = preset.Description,
|
||||
FontSize = 10.5,
|
||||
FontSize = 11.5,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
TextTrimming = TextTrimming.CharacterEllipsis,
|
||||
MaxHeight = 30,
|
||||
MaxHeight = 34,
|
||||
Foreground = secondaryText,
|
||||
TextAlignment = TextAlignment.Center,
|
||||
}
|
||||
@@ -12244,8 +12252,8 @@ public partial class ChatWindow : Window
|
||||
Padding = new Thickness(14, 14, 14, 12),
|
||||
Margin = new Thickness(6, 6, 6, 8),
|
||||
Cursor = Cursors.Hand,
|
||||
Width = 132,
|
||||
Height = 110,
|
||||
Width = 148,
|
||||
Height = 124,
|
||||
ClipToBounds = true,
|
||||
};
|
||||
|
||||
@@ -12258,17 +12266,17 @@ public partial class ChatWindow : Window
|
||||
|
||||
var etcIconCircle = new Border
|
||||
{
|
||||
Width = 42, Height = 42,
|
||||
CornerRadius = new CornerRadius(21),
|
||||
Width = 46, Height = 46,
|
||||
CornerRadius = new CornerRadius(23),
|
||||
Background = new SolidColorBrush(((SolidColorBrush)etcColor).Color) { Opacity = 0.15 },
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
Margin = new Thickness(0, 0, 0, 10),
|
||||
Margin = new Thickness(0, 0, 0, 12),
|
||||
};
|
||||
etcIconCircle.Child = new TextBlock
|
||||
{
|
||||
Text = "\uE70F", // Edit 아이콘
|
||||
FontFamily = new FontFamily("Segoe MDL2 Assets"),
|
||||
FontSize = 18.5,
|
||||
FontSize = 20,
|
||||
Foreground = etcColor,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
@@ -12278,7 +12286,7 @@ public partial class ChatWindow : Window
|
||||
etcStack.Children.Add(new TextBlock
|
||||
{
|
||||
Text = "기타",
|
||||
FontSize = 14,
|
||||
FontSize = 15.5,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Foreground = primaryText,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
@@ -12299,10 +12307,10 @@ public partial class ChatWindow : Window
|
||||
Child = new TextBlock
|
||||
{
|
||||
Text = "프리셋 없이 자유롭게 대화합니다",
|
||||
FontSize = 10.5,
|
||||
FontSize = 11.5,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
TextTrimming = TextTrimming.CharacterEllipsis,
|
||||
MaxHeight = 30,
|
||||
MaxHeight = 34,
|
||||
Foreground = secondaryText,
|
||||
TextAlignment = TextAlignment.Center,
|
||||
}
|
||||
@@ -12334,8 +12342,8 @@ public partial class ChatWindow : Window
|
||||
Padding = new Thickness(14, 14, 14, 12),
|
||||
Margin = new Thickness(6, 6, 6, 8),
|
||||
Cursor = Cursors.Hand,
|
||||
Width = 132,
|
||||
Height = 110,
|
||||
Width = 148,
|
||||
Height = 124,
|
||||
ClipToBounds = true,
|
||||
};
|
||||
|
||||
@@ -12347,17 +12355,17 @@ public partial class ChatWindow : Window
|
||||
{
|
||||
Text = "\uE710",
|
||||
FontFamily = new FontFamily("Segoe MDL2 Assets"),
|
||||
FontSize = 24,
|
||||
FontSize = 26,
|
||||
Foreground = secondaryText,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
Margin = new Thickness(0, 10, 0, 8),
|
||||
Margin = new Thickness(0, 12, 0, 10),
|
||||
};
|
||||
addStack.Children.Add(plusIcon);
|
||||
|
||||
addStack.Children.Add(new TextBlock
|
||||
{
|
||||
Text = "프리셋 추가",
|
||||
FontSize = 13,
|
||||
FontSize = 14.5,
|
||||
FontWeight = FontWeights.SemiBold,
|
||||
Foreground = secondaryText,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
@@ -12378,10 +12386,10 @@ public partial class ChatWindow : Window
|
||||
Child = new TextBlock
|
||||
{
|
||||
Text = "새 작업 유형 카드를 직접 추가합니다",
|
||||
FontSize = 10.5,
|
||||
FontSize = 11.5,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
TextTrimming = TextTrimming.CharacterEllipsis,
|
||||
MaxHeight = 30,
|
||||
MaxHeight = 34,
|
||||
Foreground = secondaryText,
|
||||
TextAlignment = TextAlignment.Center,
|
||||
}
|
||||
@@ -18702,10 +18710,59 @@ private static (string icon, string label, string bgHex, string fgHex) GetDecisi
|
||||
postCompactionUsage +
|
||||
pendingPostCompaction;
|
||||
|
||||
if (TokenUsagePopupTitle != null)
|
||||
TokenUsagePopupTitle.Text = $"컨텍스트 창 {percentText}";
|
||||
if (TokenUsagePopupUsage != null)
|
||||
TokenUsagePopupUsage.Text = $"{Services.TokenEstimator.Format(currentTokens)}/{Services.TokenEstimator.Format(maxContextTokens)}";
|
||||
if (TokenUsagePopupDetail != null)
|
||||
{
|
||||
TokenUsagePopupDetail.Text = currentModelTotalTokens > 0
|
||||
? $"오늘 {currentService} · {currentModel} 사용량 {FormatTokenCount(currentModelTotalTokens)}"
|
||||
: $"{summary} · 자동 압축 시작 {triggerPercent}%";
|
||||
}
|
||||
if (TokenUsagePopupCompact != null)
|
||||
{
|
||||
var compactText = compactLabel switch
|
||||
{
|
||||
"지금 압축" => "지금 압축이 필요합니다",
|
||||
"압축 권장" => "곧 자동 압축이 시작됩니다",
|
||||
"미리 압축" => "여유가 있을 때 먼저 압축할 수 있습니다",
|
||||
_ => "AX Agent가 컨텍스트를 자동으로 관리합니다",
|
||||
};
|
||||
TokenUsagePopupCompact.Text = compactText;
|
||||
}
|
||||
TokenUsageCard.ToolTip = null;
|
||||
|
||||
UpdateCircularUsageArc(TokenUsageArc, usageRatio, 18, 18, 14);
|
||||
PositionThresholdMarker(TokenUsageThresholdMarker, triggerRatio, 18, 18, 14, 3);
|
||||
}
|
||||
|
||||
private void TokenUsageCard_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
_tokenUsagePopupCloseTimer.Stop();
|
||||
if (TokenUsagePopup != null && TokenUsageCard?.Visibility == Visibility.Visible)
|
||||
TokenUsagePopup.IsOpen = true;
|
||||
}
|
||||
|
||||
private void TokenUsageCard_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
_tokenUsagePopupCloseTimer.Stop();
|
||||
_tokenUsagePopupCloseTimer.Start();
|
||||
}
|
||||
|
||||
private void TokenUsagePopup_MouseEnter(object sender, MouseEventArgs e)
|
||||
{
|
||||
_tokenUsagePopupCloseTimer.Stop();
|
||||
if (TokenUsagePopup != null)
|
||||
TokenUsagePopup.IsOpen = true;
|
||||
}
|
||||
|
||||
private void TokenUsagePopup_MouseLeave(object sender, MouseEventArgs e)
|
||||
{
|
||||
_tokenUsagePopupCloseTimer.Stop();
|
||||
_tokenUsagePopupCloseTimer.Start();
|
||||
}
|
||||
|
||||
private static string BuildUsageModelKey(string? service, string? model)
|
||||
{
|
||||
var normalizedService = (service ?? "").Trim().ToLowerInvariant();
|
||||
|
||||
Reference in New Issue
Block a user