using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using AxCopilot.Models;
using AxCopilot.Services;
using AxCopilot.Services.Agent;
namespace AxCopilot.Views;
public partial class ChatWindow
{
// ─── 커스텀 프리셋 관리 ─────────────────────────────────────────────
/// 커스텀 프리셋 추가 다이얼로그를 표시합니다.
private void ShowCustomPresetDialog(Models.CustomPresetEntry? existing = null)
{
bool isEdit = existing != null;
var dlg = new CustomPresetDialog(
existingName: existing?.Label ?? "",
existingDesc: existing?.Description ?? "",
existingPrompt: existing?.SystemPrompt ?? "",
existingColor: existing?.Color ?? "#6366F1",
existingSymbol: existing?.Symbol ?? "\uE713",
existingTab: existing?.Tab ?? _activeTab)
{
Owner = this,
};
if (dlg.ShowDialog() == true)
{
if (isEdit)
{
existing!.Label = dlg.PresetName;
existing.Description = dlg.PresetDescription;
existing.SystemPrompt = dlg.PresetSystemPrompt;
existing.Color = dlg.PresetColor;
existing.Symbol = dlg.PresetSymbol;
existing.Tab = dlg.PresetTab;
}
else
{
Llm.CustomPresets.Add(new Models.CustomPresetEntry
{
Label = dlg.PresetName,
Description = dlg.PresetDescription,
SystemPrompt = dlg.PresetSystemPrompt,
Color = dlg.PresetColor,
Symbol = dlg.PresetSymbol,
Tab = dlg.PresetTab,
});
}
_settings.Save();
BuildTopicButtons();
}
}
/// 커스텀 프리셋 우클릭 컨텍스트 메뉴를 표시합니다.
private void ShowCustomPresetContextMenu(Border? anchor, Services.TopicPreset preset)
{
if (anchor == null || preset.CustomId == null) return;
var popup = new System.Windows.Controls.Primitives.Popup
{
PlacementTarget = anchor,
Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom,
StaysOpen = false,
AllowsTransparency = true,
};
var menuBg = ThemeResourceHelper.Background(this);
var primaryText = ThemeResourceHelper.Primary(this);
var secondaryText = ThemeResourceHelper.Secondary(this);
var borderBrush = ThemeResourceHelper.Border(this);
var menuBorder = new Border
{
Background = menuBg,
CornerRadius = new CornerRadius(10),
BorderBrush = borderBrush,
BorderThickness = new Thickness(1),
Padding = new Thickness(4),
MinWidth = 120,
Effect = new System.Windows.Media.Effects.DropShadowEffect
{
BlurRadius = 12, ShadowDepth = 2, Opacity = 0.3, Color = Colors.Black,
},
};
var stack = new StackPanel();
// 편집 버튼
var editItem = CreateContextMenuItem("\uE70F", "편집", primaryText, secondaryText);
editItem.MouseLeftButtonDown += (_, _) =>
{
popup.IsOpen = false;
var entry = Llm.CustomPresets.FirstOrDefault(c => c.Id == preset.CustomId);
if (entry != null) ShowCustomPresetDialog(entry);
};
stack.Children.Add(editItem);
// 삭제 버튼
var deleteItem = CreateContextMenuItem("\uE74D", "삭제", new SolidColorBrush(Color.FromRgb(0xEF, 0x44, 0x44)), secondaryText);
deleteItem.MouseLeftButtonDown += (_, _) =>
{
popup.IsOpen = false;
var result = CustomMessageBox.Show(
$"'{preset.Label}' 프리셋을 삭제하시겠습니까?",
"프리셋 삭제", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
Llm.CustomPresets.RemoveAll(c => c.Id == preset.CustomId);
_settings.Save();
BuildTopicButtons();
}
};
stack.Children.Add(deleteItem);
menuBorder.Child = stack;
popup.Child = menuBorder;
popup.IsOpen = true;
}
/// 컨텍스트 메뉴 항목을 생성합니다.
private Border CreateContextMenuItem(string icon, string label, Brush fg, Brush secondaryFg)
{
var item = new Border
{
Background = Brushes.Transparent,
CornerRadius = new CornerRadius(6),
Padding = new Thickness(10, 6, 14, 6),
Cursor = Cursors.Hand,
};
var sp = new StackPanel { Orientation = Orientation.Horizontal };
sp.Children.Add(new TextBlock
{
Text = icon,
FontFamily = ThemeResourceHelper.SegoeMdl2,
FontSize = 13, Foreground = fg,
VerticalAlignment = VerticalAlignment.Center,
Margin = new Thickness(0, 0, 8, 0),
});
sp.Children.Add(new TextBlock
{
Text = label, FontSize = 13, Foreground = fg,
VerticalAlignment = VerticalAlignment.Center,
});
item.Child = sp;
var hoverBg = ThemeResourceHelper.HoverBg(this);
item.MouseEnter += (s, _) => { if (s is Border b) b.Background = hoverBg; };
item.MouseLeave += (s, _) => { if (s is Border b) b.Background = Brushes.Transparent; };
return item;
}
/// 대화 주제 선택 — 프리셋 시스템 프롬프트 + 카테고리 적용.
private void SelectTopic(Services.TopicPreset preset)
{
bool hasMessages;
lock (_convLock) hasMessages = _currentConversation?.Messages.Count > 0;
// 입력란에 텍스트가 있으면 기존 대화를 유지 (입력 내용 보존)
bool hasInput = !string.IsNullOrEmpty(InputBox.Text);
bool keepConversation = hasMessages || hasInput;
if (!keepConversation)
{
// 메시지도 입력 텍스트도 없으면 새 대화 시작
StartNewConversation();
}
// 프리셋 적용 (기존 대화에도 프리셋 변경 가능)
lock (_convLock)
{
if (_currentConversation != null)
{
_currentConversation.SystemCommand = preset.SystemPrompt;
_currentConversation.Category = preset.Category;
}
}
if (!keepConversation)
EmptyState.Visibility = Visibility.Collapsed;
InputBox.Focus();
if (!string.IsNullOrEmpty(preset.Placeholder))
{
_promptCardPlaceholder = preset.Placeholder;
if (!keepConversation) ShowPlaceholder();
}
if (keepConversation)
ShowToast($"프리셋 변경: {preset.Label}");
// Cowork 탭: 하단 바 갱신
if (_activeTab == "Cowork")
BuildBottomBar();
}
}