[v2.0.0] AgentSettingsPanel 프리셋 섹션 추가
AgentSettingsPanel.xaml (+46줄): - 프리셋 섹션 신규 추가 (MCP 서버 ↔ 고급 사이) - "새 프리셋 저장" 버튼 (BtnPresetSave, 보라 아이콘) - "프리셋 관리 →" 버튼 (BtnPresetManage, 화살표 아이콘) - 호버 스타일 DynamicResource 적용 AgentSettingsPanel.xaml.cs (+10줄): - PresetSaveRequested / PresetManageRequested Action 콜백 프로퍼티 추가 - BtnPresetSave_Click / BtnPresetManage_Click 핸들러 추가 ChatWindow.CustomPresets.cs (+110줄): - ShowPresetManagePopup() 메서드 신규 구현 · 현재 탭의 커스텀 프리셋 목록을 Popup으로 표시 · 각 항목에 편집(✏)·삭제(🗑) 아이콘 인라인 배치 · "새 프리셋 추가" 단축 버튼 하단 고정 · PlacementMode.Left로 설정 패널 왼쪽에 앵커 ChatWindow.MoodMenu.cs (+2줄): - ToggleSettingsPanel() 내 PresetSaveRequested·PresetManageRequested 콜백 연결 빌드: 경고 0, 오류 0
This commit is contained in:
@@ -156,6 +156,173 @@ public partial class ChatWindow
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>현재 탭의 커스텀 프리셋 목록 팝업을 표시합니다.</summary>
|
||||||
|
internal void ShowPresetManagePopup()
|
||||||
|
{
|
||||||
|
var customPresets = Llm.CustomPresets
|
||||||
|
.Where(c => c.Tab.Equals(_activeTab, StringComparison.OrdinalIgnoreCase))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var primaryText = ThemeResourceHelper.Primary(this);
|
||||||
|
var secondaryText = ThemeResourceHelper.Secondary(this);
|
||||||
|
var menuBg = ThemeResourceHelper.Background(this);
|
||||||
|
var borderBrush = ThemeResourceHelper.Border(this);
|
||||||
|
var hoverBg = ThemeResourceHelper.HoverBg(this);
|
||||||
|
|
||||||
|
var popup = new Popup
|
||||||
|
{
|
||||||
|
PlacementTarget = SettingsPanel,
|
||||||
|
Placement = PlacementMode.Left,
|
||||||
|
VerticalOffset = -40,
|
||||||
|
StaysOpen = false,
|
||||||
|
AllowsTransparency = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
var outer = new Border
|
||||||
|
{
|
||||||
|
Background = menuBg,
|
||||||
|
CornerRadius = new CornerRadius(12),
|
||||||
|
BorderBrush = borderBrush,
|
||||||
|
BorderThickness = new Thickness(1),
|
||||||
|
Padding = new Thickness(4),
|
||||||
|
MinWidth = 230,
|
||||||
|
MaxHeight = 340,
|
||||||
|
Effect = new System.Windows.Media.Effects.DropShadowEffect
|
||||||
|
{
|
||||||
|
BlurRadius = 16, ShadowDepth = 2, Opacity = 0.35, Color = Colors.Black,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var sv = new ScrollViewer
|
||||||
|
{
|
||||||
|
VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
|
||||||
|
HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
|
||||||
|
};
|
||||||
|
|
||||||
|
var stack = new StackPanel { Margin = new Thickness(4) };
|
||||||
|
|
||||||
|
// 헤더
|
||||||
|
stack.Children.Add(new TextBlock
|
||||||
|
{
|
||||||
|
Text = $"{_activeTab} 탭 프리셋 ({customPresets.Count}개)",
|
||||||
|
FontSize = 12,
|
||||||
|
FontWeight = FontWeights.SemiBold,
|
||||||
|
Foreground = primaryText,
|
||||||
|
Margin = new Thickness(8, 8, 8, 6),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (customPresets.Count == 0)
|
||||||
|
{
|
||||||
|
stack.Children.Add(new TextBlock
|
||||||
|
{
|
||||||
|
Text = "커스텀 프리셋이 없습니다.",
|
||||||
|
FontSize = 12,
|
||||||
|
Foreground = secondaryText,
|
||||||
|
Margin = new Thickness(8, 0, 8, 8),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var cp in customPresets)
|
||||||
|
{
|
||||||
|
var capturedCp = cp;
|
||||||
|
|
||||||
|
var row = new Border
|
||||||
|
{
|
||||||
|
Background = Brushes.Transparent,
|
||||||
|
CornerRadius = new CornerRadius(6),
|
||||||
|
Padding = new Thickness(6, 5, 6, 5),
|
||||||
|
Cursor = Cursors.Hand,
|
||||||
|
};
|
||||||
|
row.MouseEnter += (s, _) => { if (s is Border b) b.Background = hoverBg; };
|
||||||
|
row.MouseLeave += (s, _) => { if (s is Border b) b.Background = Brushes.Transparent; };
|
||||||
|
|
||||||
|
var rowGrid = new Grid();
|
||||||
|
rowGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||||
|
rowGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||||
|
rowGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||||
|
|
||||||
|
rowGrid.Children.Add(new TextBlock
|
||||||
|
{
|
||||||
|
Text = capturedCp.Label,
|
||||||
|
FontSize = 12,
|
||||||
|
Foreground = primaryText,
|
||||||
|
VerticalAlignment = VerticalAlignment.Center,
|
||||||
|
TextTrimming = TextTrimming.CharacterEllipsis,
|
||||||
|
});
|
||||||
|
|
||||||
|
var editIcon = new TextBlock
|
||||||
|
{
|
||||||
|
Text = "\uE70F",
|
||||||
|
FontFamily = ThemeResourceHelper.SegoeMdl2,
|
||||||
|
FontSize = 12,
|
||||||
|
Foreground = secondaryText,
|
||||||
|
VerticalAlignment = VerticalAlignment.Center,
|
||||||
|
Cursor = Cursors.Hand,
|
||||||
|
Margin = new Thickness(8, 0, 4, 0),
|
||||||
|
};
|
||||||
|
Grid.SetColumn(editIcon, 1);
|
||||||
|
editIcon.MouseLeftButtonDown += (_, _) =>
|
||||||
|
{
|
||||||
|
popup.IsOpen = false;
|
||||||
|
var entry = Llm.CustomPresets.FirstOrDefault(c => c.Id == capturedCp.Id);
|
||||||
|
if (entry != null) ShowCustomPresetDialog(entry);
|
||||||
|
};
|
||||||
|
|
||||||
|
var delIcon = new TextBlock
|
||||||
|
{
|
||||||
|
Text = "\uE74D",
|
||||||
|
FontFamily = ThemeResourceHelper.SegoeMdl2,
|
||||||
|
FontSize = 12,
|
||||||
|
Foreground = new SolidColorBrush(Color.FromRgb(0xEF, 0x44, 0x44)),
|
||||||
|
VerticalAlignment = VerticalAlignment.Center,
|
||||||
|
Cursor = Cursors.Hand,
|
||||||
|
Margin = new Thickness(4, 0, 0, 0),
|
||||||
|
};
|
||||||
|
Grid.SetColumn(delIcon, 2);
|
||||||
|
delIcon.MouseLeftButtonDown += (_, _) =>
|
||||||
|
{
|
||||||
|
popup.IsOpen = false;
|
||||||
|
var result = CustomMessageBox.Show(
|
||||||
|
$"'{capturedCp.Label}' 프리셋을 삭제하시겠습니까?",
|
||||||
|
"프리셋 삭제", MessageBoxButton.YesNo, MessageBoxImage.Question);
|
||||||
|
if (result == MessageBoxResult.Yes)
|
||||||
|
{
|
||||||
|
Llm.CustomPresets.RemoveAll(c => c.Id == capturedCp.Id);
|
||||||
|
_settings.Save();
|
||||||
|
BuildTopicButtons();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
rowGrid.Children.Add(editIcon);
|
||||||
|
rowGrid.Children.Add(delIcon);
|
||||||
|
row.Child = rowGrid;
|
||||||
|
stack.Children.Add(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 구분선 + 새 프리셋 추가
|
||||||
|
stack.Children.Add(new Border
|
||||||
|
{
|
||||||
|
Height = 1,
|
||||||
|
Background = borderBrush,
|
||||||
|
Margin = new Thickness(4, 4, 4, 4),
|
||||||
|
});
|
||||||
|
|
||||||
|
var addItem = CreateContextMenuItem("\uE710", "새 프리셋 추가", primaryText, secondaryText);
|
||||||
|
addItem.MouseLeftButtonDown += (_, _) =>
|
||||||
|
{
|
||||||
|
popup.IsOpen = false;
|
||||||
|
ShowCustomPresetDialog(null);
|
||||||
|
};
|
||||||
|
stack.Children.Add(addItem);
|
||||||
|
|
||||||
|
sv.Content = stack;
|
||||||
|
outer.Child = sv;
|
||||||
|
popup.Child = outer;
|
||||||
|
popup.IsOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>대화 주제 선택 — 프리셋 시스템 프롬프트 + 카테고리 적용.</summary>
|
/// <summary>대화 주제 선택 — 프리셋 시스템 프롬프트 + 카테고리 적용.</summary>
|
||||||
private void SelectTopic(Services.TopicPreset preset)
|
private void SelectTopic(Services.TopicPreset preset)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -451,6 +451,8 @@ public partial class ChatWindow
|
|||||||
SettingsPanel.ServiceSelectorRequested = () => BtnModelSelector_Click(BtnModelSelector, new System.Windows.RoutedEventArgs());
|
SettingsPanel.ServiceSelectorRequested = () => BtnModelSelector_Click(BtnModelSelector, new System.Windows.RoutedEventArgs());
|
||||||
SettingsPanel.ModelSelectorRequested = () => BtnModelSelector_Click(BtnModelSelector, new System.Windows.RoutedEventArgs());
|
SettingsPanel.ModelSelectorRequested = () => BtnModelSelector_Click(BtnModelSelector, new System.Windows.RoutedEventArgs());
|
||||||
SettingsPanel.WorkFolderBrowseRequested = () => BrowseWorkFolder();
|
SettingsPanel.WorkFolderBrowseRequested = () => BrowseWorkFolder();
|
||||||
|
SettingsPanel.PresetSaveRequested = () => ShowCustomPresetDialog(null);
|
||||||
|
SettingsPanel.PresetManageRequested = () => ShowPresetManagePopup();
|
||||||
SettingsPanel.IsOpen = true;
|
SettingsPanel.IsOpen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -351,6 +351,63 @@
|
|||||||
|
|
||||||
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
|
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
|
||||||
|
|
||||||
|
<!-- ═══ 프리셋 ═══ -->
|
||||||
|
<TextBlock Text="프리셋" FontSize="13" FontWeight="SemiBold"
|
||||||
|
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
|
||||||
|
|
||||||
|
<!-- 새 프리셋 저장 -->
|
||||||
|
<Border x:Name="BtnPresetSave"
|
||||||
|
CornerRadius="8" Padding="10,8" Margin="0,0,0,6" Cursor="Hand"
|
||||||
|
MouseLeftButtonUp="BtnPresetSave_Click">
|
||||||
|
<Border.Style>
|
||||||
|
<Style TargetType="Border">
|
||||||
|
<Setter Property="Background" Value="{DynamicResource ItemBackground}"/>
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter Property="Background" Value="{DynamicResource ItemHoverBackground}"/>
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</Border.Style>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="13"
|
||||||
|
Foreground="#6366F1" VerticalAlignment="Center"/>
|
||||||
|
<TextBlock Text=" 새 프리셋 저장" FontSize="12"
|
||||||
|
Foreground="{DynamicResource PrimaryText}" VerticalAlignment="Center"
|
||||||
|
Margin="6,0,0,0"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<!-- 프리셋 관리 -->
|
||||||
|
<Border x:Name="BtnPresetManage"
|
||||||
|
CornerRadius="8" Padding="10,8" Margin="0,0,0,8" Cursor="Hand"
|
||||||
|
MouseLeftButtonUp="BtnPresetManage_Click">
|
||||||
|
<Border.Style>
|
||||||
|
<Style TargetType="Border">
|
||||||
|
<Setter Property="Background" Value="{DynamicResource ItemBackground}"/>
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter Property="Background" Value="{DynamicResource ItemHoverBackground}"/>
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</Border.Style>
|
||||||
|
<Grid>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="13"
|
||||||
|
Foreground="{DynamicResource SecondaryText}" VerticalAlignment="Center"/>
|
||||||
|
<TextBlock Text=" 프리셋 관리" FontSize="12"
|
||||||
|
Foreground="{DynamicResource PrimaryText}" VerticalAlignment="Center"
|
||||||
|
Margin="6,0,0,0"/>
|
||||||
|
</StackPanel>
|
||||||
|
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="11"
|
||||||
|
Foreground="{DynamicResource SecondaryText}"
|
||||||
|
HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
|
||||||
|
|
||||||
<!-- ═══ 고급 ═══ -->
|
<!-- ═══ 고급 ═══ -->
|
||||||
<TextBlock Text="고급" FontSize="13" FontWeight="SemiBold"
|
<TextBlock Text="고급" FontSize="13" FontWeight="SemiBold"
|
||||||
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
|
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ public partial class AgentSettingsPanel : UserControl
|
|||||||
/// <summary>작업 폴더 탐색 요청 콜백 (ChatWindow.BrowseWorkFolder로 위임).</summary>
|
/// <summary>작업 폴더 탐색 요청 콜백 (ChatWindow.BrowseWorkFolder로 위임).</summary>
|
||||||
public Action? WorkFolderBrowseRequested;
|
public Action? WorkFolderBrowseRequested;
|
||||||
|
|
||||||
|
/// <summary>새 프리셋 저장 요청 콜백 (ChatWindow.ShowCustomPresetDialog(null)로 위임).</summary>
|
||||||
|
public Action? PresetSaveRequested;
|
||||||
|
|
||||||
|
/// <summary>프리셋 관리 요청 콜백 (ChatWindow.ShowPresetManagePopup()으로 위임).</summary>
|
||||||
|
public Action? PresetManageRequested;
|
||||||
|
|
||||||
/// <summary>설정 패널 열림/닫힘 상태.</summary>
|
/// <summary>설정 패널 열림/닫힘 상태.</summary>
|
||||||
public bool IsOpen
|
public bool IsOpen
|
||||||
{
|
{
|
||||||
@@ -190,6 +196,12 @@ public partial class AgentSettingsPanel : UserControl
|
|||||||
WorkFolderBrowseRequested?.Invoke();
|
WorkFolderBrowseRequested?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void BtnPresetSave_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||||
|
=> PresetSaveRequested?.Invoke();
|
||||||
|
|
||||||
|
private void BtnPresetManage_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||||
|
=> PresetManageRequested?.Invoke();
|
||||||
|
|
||||||
private void UpdateWorkFolder(SettingsService settings)
|
private void UpdateWorkFolder(SettingsService settings)
|
||||||
{
|
{
|
||||||
var folder = settings.Settings.Llm.WorkFolder;
|
var folder = settings.Settings.Llm.WorkFolder;
|
||||||
|
|||||||
Reference in New Issue
Block a user