Files
AX-Copilot-Codex/src/AxCopilot/Views/ChatWindow.PopupPresentation.cs
lacvet b4d69f5db3
Some checks failed
Release Gate / gate (push) Has been cancelled
AX Agent popup 시각 언어 통일 및 선택 surface 후속 정리
- 공통 popup factory가 surface visual helper를 사용하도록 정리
- worktree 선택과 권한 모드 row의 border/hover/selected 규칙을 같은 visual language로 통일
- README와 DEVELOPMENT 문서에 2026-04-06 11:27 (KST) 기준 popup polish 누적 범위 반영
- dotnet build 검증 경고 0, 오류 0 확인
2026-04-06 12:12:44 +09:00

114 lines
3.8 KiB
C#

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
namespace AxCopilot.Views;
public partial class ChatWindow
{
private Popup? _sharedContextPopup;
private (Popup Popup, StackPanel Panel) CreateThemedPopupMenu(
UIElement? placementTarget = null,
PlacementMode placement = PlacementMode.MousePoint,
double minWidth = 200)
{
_sharedContextPopup?.SetCurrentValue(Popup.IsOpenProperty, false);
var panel = new StackPanel { Margin = new Thickness(2) };
var container = CreateSurfacePopupContainer(panel, minWidth, new Thickness(6));
var popup = new Popup
{
Child = container,
StaysOpen = false,
AllowsTransparency = true,
PopupAnimation = PopupAnimation.Fade,
Placement = placement,
PlacementTarget = placementTarget,
};
_sharedContextPopup = popup;
return (popup, panel);
}
private Border CreatePopupMenuItem(
Popup popup,
string icon,
string label,
Brush iconBrush,
Brush labelBrush,
Brush hoverBrush,
Action action)
{
var item = CreateSurfacePopupMenuItem(icon, iconBrush, label, () =>
{
popup.SetCurrentValue(Popup.IsOpenProperty, false);
action();
}, labelBrush);
item.MouseEnter += (s, _) => { if (s is Border b) b.Background = hoverBrush; };
item.MouseLeave += (s, _) => { if (s is Border b) b.Background = Brushes.Transparent; };
return item;
}
private static void AddPopupMenuSeparator(Panel panel, Brush brush)
{
panel.Children.Add(new Border
{
Height = 1,
Margin = new Thickness(10, 4, 10, 4),
Background = brush,
Opacity = 0.35,
});
}
/// <summary>최근 폴더 항목 우클릭 컨텍스트 메뉴를 표시합니다.</summary>
private void ShowRecentFolderContextMenu(string folderPath)
{
var primaryText = TryFindResource("PrimaryText") as Brush ?? Brushes.White;
var secondaryText = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
var borderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.Gray;
var hoverBg = TryFindResource("ItemHoverBackground") as Brush ?? Brushes.Transparent;
var warningBrush = new SolidColorBrush(Color.FromRgb(0xEF, 0x44, 0x44));
var (popup, panel) = CreateThemedPopupMenu();
panel.Children.Add(CreatePopupMenuItem(popup, "\uED25", "폴더 열기", secondaryText, primaryText, hoverBg, () =>
{
try
{
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
FileName = folderPath,
UseShellExecute = true,
});
}
catch
{
}
}));
panel.Children.Add(CreatePopupMenuItem(popup, "\uE8C8", "경로 복사", secondaryText, primaryText, hoverBg, () =>
{
try { Clipboard.SetText(folderPath); } catch { }
}));
AddPopupMenuSeparator(panel, borderBrush);
panel.Children.Add(CreatePopupMenuItem(popup, "\uE74D", "목록에서 삭제", warningBrush, warningBrush, hoverBg, () =>
{
_settings.Settings.Llm.RecentWorkFolders.RemoveAll(
p => p.Equals(folderPath, StringComparison.OrdinalIgnoreCase));
_settings.Save();
if (FolderMenuPopup.IsOpen)
ShowFolderMenu();
}));
Dispatcher.BeginInvoke(() => { popup.IsOpen = true; }, DispatcherPriority.Input);
}
}