AX Agent 작업 유형 카드 정리 및 hover 설명 라벨 적용
Some checks failed
Release Gate / gate (push) Has been cancelled

- 작업 유형 카드 하단 상시 설명을 제거하고 모든 카드 크기를 동일 규격으로 통일함
- 카드 hover 시 확대 애니메이션을 제거하고 하단 설명 라벨과 배경/테두리 반응만 남겨 안정적으로 정리함
- 기타/프리셋 추가 카드도 같은 hover 규칙과 설명 노출 방식으로 통일함
- EmptyState 제목/설명 폰트를 키워 현재 화면 전반의 글자 크기를 보정함
- README 및 DEVELOPMENT 문서에 2026-04-05 19:02 (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 16:20:55 +09:00
parent a4d21ecc0b
commit c3e1422b02
4 changed files with 180 additions and 119 deletions

View File

@@ -1211,13 +1211,13 @@
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<TextBlock x:Name="EmptyStateTitle" Text="작업을 시작하세요" FontSize="16" FontWeight="SemiBold"
<TextBlock x:Name="EmptyStateTitle" Text="작업을 시작하세요" FontSize="18" FontWeight="SemiBold"
Foreground="{DynamicResource PrimaryText}" HorizontalAlignment="Center"/>
<TextBlock x:Name="EmptyStateDesc" Text="프롬프트를 입력하거나 아래 작업 유형을 선택하면 됩니다"
FontSize="11" Foreground="{DynamicResource SecondaryText}"
FontSize="12.5" Foreground="{DynamicResource SecondaryText}"
HorizontalAlignment="Center"
TextAlignment="Center"
Width="340"
Width="380"
Margin="0,5,0,0"/>
</StackPanel>

View File

@@ -12094,6 +12094,34 @@ public partial class ChatWindow : Window
}
var presets = Services.PresetService.GetByTabWithCustom(_activeTab, _settings.Settings.Llm.CustomPresets);
var cardBackground = TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent;
var cardHoverBackground = TryFindResource("ItemHoverBackground") as Brush ?? Brushes.Transparent;
var cardBorder = TryFindResource("BorderColor") as Brush ?? BrushFromHex("#E5E7EB");
var primaryText = TryFindResource("PrimaryText") as Brush ?? Brushes.White;
var secondaryText = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
void AttachTopicCardHover(Border card, Border hoverLabel, Brush normalBackground, Brush hoverBackground)
{
card.MouseEnter += (s, _) =>
{
if (s is Border b)
{
b.Background = hoverBackground;
b.BorderBrush = TryFindResource("AccentColor") as Brush ?? cardBorder;
}
hoverLabel.Visibility = Visibility.Visible;
hoverLabel.Opacity = 1;
};
card.MouseLeave += (s, _) =>
{
if (s is Border b)
{
b.Background = normalBackground;
b.BorderBrush = cardBorder;
}
hoverLabel.Visibility = Visibility.Collapsed;
};
}
foreach (var preset in presets)
{
@@ -12102,34 +12130,38 @@ public partial class ChatWindow : Window
var border = new Border
{
Background = TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent,
Background = cardBackground,
BorderBrush = cardBorder,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(14),
Padding = new Thickness(14, 14, 14, 14),
Margin = new Thickness(6, 6, 6, 10),
Padding = new Thickness(14, 14, 14, 12),
Margin = new Thickness(6, 6, 6, 8),
Cursor = Cursors.Hand,
Width = 124,
Height = 116,
Width = 132,
Height = 110,
ClipToBounds = true,
RenderTransformOrigin = new Point(0.5, 0.5),
RenderTransform = new ScaleTransform(1, 1),
};
var stack = new StackPanel { HorizontalAlignment = HorizontalAlignment.Center };
var contentGrid = new Grid();
var stack = new StackPanel
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
// 아이콘 컨테이너 (원형 배경 + 펄스 애니메이션)
var iconCircle = new Border
{
Width = 40, Height = 40,
CornerRadius = new CornerRadius(20),
Width = 42, Height = 42,
CornerRadius = new CornerRadius(21),
Background = new SolidColorBrush(((SolidColorBrush)btnColor).Color) { Opacity = 0.15 },
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness(0, 0, 0, 12),
Margin = new Thickness(0, 0, 0, 10),
};
var iconTb = new TextBlock
{
Text = preset.Symbol,
FontFamily = new FontFamily("Segoe MDL2 Assets"),
FontSize = 18,
FontSize = 18.5,
Foreground = btnColor,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
@@ -12137,33 +12169,46 @@ public partial class ChatWindow : Window
iconCircle.Child = iconTb;
stack.Children.Add(iconCircle);
// 제목
stack.Children.Add(new TextBlock
{
Text = preset.Label,
FontSize = 13, FontWeight = FontWeights.SemiBold,
Foreground = TryFindResource("PrimaryText") as Brush ?? Brushes.White,
FontSize = 14,
FontWeight = FontWeights.SemiBold,
Foreground = primaryText,
HorizontalAlignment = HorizontalAlignment.Center,
TextAlignment = TextAlignment.Center,
TextWrapping = TextWrapping.Wrap,
MaxWidth = 98,
});
// 설명
stack.Children.Add(new TextBlock
var hoverLabel = new Border
{
Text = preset.Description,
FontSize = 9, TextWrapping = TextWrapping.Wrap,
TextTrimming = TextTrimming.CharacterEllipsis,
MaxHeight = 32,
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness(0, 2, 0, 0),
TextAlignment = TextAlignment.Center,
});
Background = TryFindResource("LauncherBackground") as Brush ?? Brushes.White,
BorderBrush = cardBorder,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(8),
Padding = new Thickness(8, 4, 8, 4),
Margin = new Thickness(8, 0, 8, 6),
VerticalAlignment = VerticalAlignment.Bottom,
HorizontalAlignment = HorizontalAlignment.Stretch,
Visibility = Visibility.Collapsed,
IsHitTestVisible = false,
Child = new TextBlock
{
Text = preset.Description,
FontSize = 10.5,
TextWrapping = TextWrapping.Wrap,
TextTrimming = TextTrimming.CharacterEllipsis,
MaxHeight = 30,
Foreground = secondaryText,
TextAlignment = TextAlignment.Center,
}
};
// 커스텀 프리셋: 좌측 상단 뱃지
if (capturedPreset.IsCustom)
{
var grid = new Grid();
grid.Children.Add(stack);
contentGrid.Children.Add(stack);
var badge = new Border
{
Width = 16, Height = 16,
@@ -12183,33 +12228,17 @@ public partial class ChatWindow : Window
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
grid.Children.Add(badge);
border.Child = grid;
contentGrid.Children.Add(badge);
}
else
{
border.Child = stack;
contentGrid.Children.Add(stack);
}
// 호버 애니메이션 — 스케일 1.05x + 밝기 변경
var hoverBg = TryFindResource("ItemHoverBackground") as Brush ?? Brushes.Transparent;
var normalBg = TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent;
border.MouseEnter += (s, _) =>
{
if (s is Border b && b.RenderTransform is ScaleTransform st)
{
st.ScaleX = 1.03; st.ScaleY = 1.03;
b.Background = hoverBg;
}
};
border.MouseLeave += (s, _) =>
{
if (s is Border b && b.RenderTransform is ScaleTransform st)
{
st.ScaleX = 1.0; st.ScaleY = 1.0;
b.Background = normalBg;
}
};
contentGrid.Children.Add(hoverLabel);
border.Child = contentGrid;
border.ToolTip = preset.Description;
AttachTopicCardHover(border, hoverLabel, cardBackground, cardHoverBackground);
// 클릭 → 해당 주제로 새 대화 시작
border.MouseLeftButtonDown += (_, _) => SelectTopic(capturedPreset);
@@ -12232,33 +12261,38 @@ public partial class ChatWindow : Window
var etcColor = BrushFromHex("#6B7280"); // 회색
var etcBorder = new Border
{
Background = TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent,
Background = cardBackground,
BorderBrush = cardBorder,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(14),
Padding = new Thickness(14, 14, 14, 14),
Margin = new Thickness(6, 6, 6, 10),
Padding = new Thickness(14, 14, 14, 12),
Margin = new Thickness(6, 6, 6, 8),
Cursor = Cursors.Hand,
Width = 124,
Height = 116,
Width = 132,
Height = 110,
ClipToBounds = true,
RenderTransformOrigin = new Point(0.5, 0.5),
RenderTransform = new ScaleTransform(1, 1),
};
var etcStack = new StackPanel { HorizontalAlignment = HorizontalAlignment.Center };
var etcGrid = new Grid();
var etcStack = new StackPanel
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
var etcIconCircle = new Border
{
Width = 40, Height = 40,
CornerRadius = new CornerRadius(20),
Width = 42, Height = 42,
CornerRadius = new CornerRadius(21),
Background = new SolidColorBrush(((SolidColorBrush)etcColor).Color) { Opacity = 0.15 },
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness(0, 0, 0, 12),
Margin = new Thickness(0, 0, 0, 10),
};
etcIconCircle.Child = new TextBlock
{
Text = "\uE70F", // Edit 아이콘
FontFamily = new FontFamily("Segoe MDL2 Assets"),
FontSize = 18,
FontSize = 18.5,
Foreground = etcColor,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
@@ -12268,37 +12302,42 @@ public partial class ChatWindow : Window
etcStack.Children.Add(new TextBlock
{
Text = "기타",
FontSize = 13, FontWeight = FontWeights.SemiBold,
Foreground = TryFindResource("PrimaryText") as Brush ?? Brushes.White,
FontSize = 14,
FontWeight = FontWeights.SemiBold,
Foreground = primaryText,
HorizontalAlignment = HorizontalAlignment.Center,
});
etcStack.Children.Add(new TextBlock
{
Text = "프리셋 없이 자유롭게 대화합니다",
FontSize = 9, TextWrapping = TextWrapping.Wrap,
TextTrimming = TextTrimming.CharacterEllipsis,
MaxHeight = 32,
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness(0, 2, 0, 0),
TextAlignment = TextAlignment.Center,
});
etcBorder.Child = etcStack;
var hoverBg2 = TryFindResource("ItemHoverBackground") as Brush ?? Brushes.Transparent;
var normalBg2 = TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent;
etcBorder.MouseEnter += (s, _) =>
var etcHoverLabel = new Border
{
if (s is Border b && b.RenderTransform is ScaleTransform st)
{ st.ScaleX = 1.03; st.ScaleY = 1.03; b.Background = hoverBg2; }
};
etcBorder.MouseLeave += (s, _) =>
{
if (s is Border b && b.RenderTransform is ScaleTransform st)
{ st.ScaleX = 1.0; st.ScaleY = 1.0; b.Background = normalBg2; }
Background = TryFindResource("LauncherBackground") as Brush ?? Brushes.White,
BorderBrush = cardBorder,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(8),
Padding = new Thickness(8, 4, 8, 4),
Margin = new Thickness(8, 0, 8, 6),
VerticalAlignment = VerticalAlignment.Bottom,
HorizontalAlignment = HorizontalAlignment.Stretch,
Visibility = Visibility.Collapsed,
IsHitTestVisible = false,
Child = new TextBlock
{
Text = "프리셋 없이 자유롭게 대화합니다",
FontSize = 10.5,
TextWrapping = TextWrapping.Wrap,
TextTrimming = TextTrimming.CharacterEllipsis,
MaxHeight = 30,
Foreground = secondaryText,
TextAlignment = TextAlignment.Center,
}
};
etcGrid.Children.Add(etcStack);
etcGrid.Children.Add(etcHoverLabel);
etcBorder.Child = etcGrid;
etcBorder.ToolTip = "프리셋 없이 자유롭게 대화합니다";
AttachTopicCardHover(etcBorder, etcHoverLabel, cardBackground, cardHoverBackground);
etcBorder.MouseLeftButtonDown += (_, _) =>
{
EmptyState.Visibility = Visibility.Collapsed;
@@ -12313,23 +12352,18 @@ public partial class ChatWindow : Window
var addBorder = new Border
{
Background = Brushes.Transparent,
BorderBrush = cardBorder,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(14),
Padding = new Thickness(14, 14, 14, 14),
Margin = new Thickness(6, 6, 6, 10),
Padding = new Thickness(14, 14, 14, 12),
Margin = new Thickness(6, 6, 6, 8),
Cursor = Cursors.Hand,
Width = 124, Height = 116,
Width = 132,
Height = 110,
ClipToBounds = true,
BorderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.Gray,
BorderThickness = new Thickness(1.5),
RenderTransformOrigin = new Point(0.5, 0.5),
RenderTransform = new ScaleTransform(1, 1),
};
// 점선 효과를 위한 Dashes
if (addBorder.BorderBrush is SolidColorBrush scb)
{
var dashPen = new Pen(scb, 1.5) { DashStyle = DashStyles.Dash };
}
var addGrid = new Grid();
var addStack = new StackPanel { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center };
// + 아이콘
@@ -12338,33 +12372,50 @@ public partial class ChatWindow : Window
Text = "\uE710",
FontFamily = new FontFamily("Segoe MDL2 Assets"),
FontSize = 24,
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
Foreground = secondaryText,
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness(0, 8, 0, 8),
Margin = new Thickness(0, 10, 0, 8),
};
addStack.Children.Add(plusIcon);
addStack.Children.Add(new TextBlock
{
Text = "프리셋 추가",
FontSize = 12,
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
FontSize = 13,
FontWeight = FontWeights.SemiBold,
Foreground = secondaryText,
HorizontalAlignment = HorizontalAlignment.Center,
});
addBorder.Child = addStack;
var addHoverLabel = new Border
{
Background = TryFindResource("LauncherBackground") as Brush ?? Brushes.White,
BorderBrush = cardBorder,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(8),
Padding = new Thickness(8, 4, 8, 4),
Margin = new Thickness(8, 0, 8, 6),
VerticalAlignment = VerticalAlignment.Bottom,
HorizontalAlignment = HorizontalAlignment.Stretch,
Visibility = Visibility.Collapsed,
IsHitTestVisible = false,
Child = new TextBlock
{
Text = "새 작업 유형 카드를 직접 추가합니다",
FontSize = 10.5,
TextWrapping = TextWrapping.Wrap,
TextTrimming = TextTrimming.CharacterEllipsis,
MaxHeight = 30,
Foreground = secondaryText,
TextAlignment = TextAlignment.Center,
}
};
var hoverBg3 = TryFindResource("ItemHoverBackground") as Brush ?? Brushes.Transparent;
addBorder.MouseEnter += (s, _) =>
{
if (s is Border b && b.RenderTransform is ScaleTransform st)
{ st.ScaleX = 1.03; st.ScaleY = 1.03; b.Background = hoverBg3; }
};
addBorder.MouseLeave += (s, _) =>
{
if (s is Border b && b.RenderTransform is ScaleTransform st)
{ st.ScaleX = 1.0; st.ScaleY = 1.0; b.Background = Brushes.Transparent; }
};
addGrid.Children.Add(addStack);
addGrid.Children.Add(addHoverLabel);
addBorder.Child = addGrid;
addBorder.ToolTip = "새 작업 유형 카드를 직접 추가합니다";
AttachTopicCardHover(addBorder, addHoverLabel, Brushes.Transparent, cardHoverBackground);
addBorder.MouseLeftButtonDown += (_, _) => ShowCustomPresetDialog();
TopicButtonPanel.Children.Add(addBorder);
}