AX Agent 채팅창 반응형 폭 계산 적용
Some checks failed
Release Gate / gate (push) Has been cancelled

- ChatWindow의 ComposerShell 고정폭을 제거하고 실제 본문 영역 폭 기준으로 MessagePanel, EmptyState, ComposerShell을 함께 재계산하도록 정리함

- 창 크기 변경 시 메시지 축과 입력창이 자연스럽게 함께 줄고 늘어나도록 Loaded와 SizeChanged에 반응형 레이아웃 갱신을 연결함

- README와 DEVELOPMENT 문서에 2026-04-05 14:16 (KST) 기준 작업 이력을 반영하고 Release 빌드 경고 0 오류 0을 확인함
This commit is contained in:
2026-04-05 13:13:15 +09:00
parent 382c78e32f
commit b24afba2d8
4 changed files with 68 additions and 9 deletions

View File

@@ -124,6 +124,8 @@ public partial class ChatWindow : Window
private readonly Dictionary<string, ChatConversation> _pendingConversationPersists = new(StringComparer.OrdinalIgnoreCase);
private readonly HashSet<string> _expandedDraftQueueTabs = new(StringComparer.OrdinalIgnoreCase);
private AgentEvent? _pendingAgentUiEvent;
private double _lastResponsiveComposerWidth;
private double _lastResponsiveMessageWidth;
private void ApplyQuickActionVisual(Button button, bool active, string activeBg, string activeFg)
{
if (button?.Content is not string text)
@@ -288,6 +290,7 @@ public partial class ChatWindow : Window
UpdateSidebarModeMenu();
RefreshContextUsageVisual();
UpdateTopicPresetScrollMode();
UpdateResponsiveChatLayout();
UpdateInputBoxHeight();
InputBox.Focus();
MessageScroll.ScrollChanged += MessageScroll_ScrollChanged;
@@ -299,6 +302,7 @@ public partial class ChatWindow : Window
BuildTopicButtons();
RestoreLastConversations();
RefreshConversationList();
UpdateResponsiveChatLayout();
UpdateTaskSummaryIndicators();
ScheduleGitBranchRefresh();
@@ -369,7 +373,12 @@ public partial class ChatWindow : Window
ApplyHoverScaleAnimation(BtnSend, 1.12);
ApplyHoverScaleAnimation(BtnStop, 1.12);
};
SizeChanged += (_, _) => UpdateTopicPresetScrollMode();
SizeChanged += (_, _) =>
{
UpdateTopicPresetScrollMode();
if (UpdateResponsiveChatLayout())
RenderMessages(preserveViewport: true);
};
Closed += (_, _) =>
{
_settings.SettingsChanged -= Settings_SettingsChanged;
@@ -11045,15 +11054,61 @@ public partial class ChatWindow : Window
/// <summary>채팅 본문 폭을 세 탭에서 동일한 기준으로 맞춥니다.</summary>
private double GetMessageMaxWidth()
{
var hostWidth = ComposerShell?.ActualWidth ?? 0;
var hostWidth = _lastResponsiveComposerWidth;
if (hostWidth < 100)
hostWidth = ComposerShell?.ActualWidth ?? 0;
if (hostWidth < 100)
hostWidth = MessageScroll?.ActualWidth ?? 0;
if (hostWidth < 100)
hostWidth = 1120; // 초기화 전 기준 폭
hostWidth = 1120;
// 컴포저와 메시지 버블이 같은 레이아웃 축을 쓰도록 여백만 제외한 폭을 공통 적용
var maxW = hostWidth - 44;
return Math.Clamp(maxW, 320, 720);
return Math.Clamp(maxW, 320, 760);
}
private bool UpdateResponsiveChatLayout()
{
var viewportWidth = MessageScroll?.ActualWidth ?? 0;
if (viewportWidth < 200)
viewportWidth = ActualWidth;
if (viewportWidth < 200)
return false;
// claw-code처럼 창이 줄어들면 메시지 축과 컴포저가 함께 자연스럽게 줄어들도록,
// 남는 본문 폭을 기준으로 상한만 두고 반응형 폭을 다시 계산합니다.
var contentWidth = Math.Max(360, viewportWidth - 48);
var messageWidth = Math.Clamp(contentWidth * 0.9, 360, 920);
var composerWidth = Math.Clamp(contentWidth * 0.82, 360, 820);
if (contentWidth < 760)
{
messageWidth = Math.Clamp(contentWidth - 8, 340, 820);
composerWidth = Math.Clamp(contentWidth - 28, 332, 760);
}
var changed = false;
if (Math.Abs(_lastResponsiveMessageWidth - messageWidth) > 1)
{
_lastResponsiveMessageWidth = messageWidth;
if (MessagePanel != null)
MessagePanel.MaxWidth = messageWidth;
if (EmptyState != null)
EmptyState.MaxWidth = messageWidth;
changed = true;
}
if (Math.Abs(_lastResponsiveComposerWidth - composerWidth) > 1)
{
_lastResponsiveComposerWidth = composerWidth;
if (ComposerShell != null)
{
ComposerShell.Width = composerWidth;
ComposerShell.MaxWidth = composerWidth;
}
changed = true;
}
return changed;
}
private StackPanel CreateStreamingContainer(out TextBlock streamText)