[v2.0.0] AgentSettingsPanel 기능 완성 — 서비스·모델·작업폴더·MCP
AgentSettingsPanel.xaml.cs: - BtnServiceSelector_Click: ServiceSelectorRequested 콜백 실행 (ChatWindow 위임) - BtnModelSelector_Click: ModelSelectorRequested 콜백 실행 (ChatWindow 위임) - ServiceSelectorRequested / ModelSelectorRequested / WorkFolderBrowseRequested Action 추가 - LoadFromSettings: UpdateWorkFolder() + BuildMcpServerList() 호출 추가 - LoadFromSettings: PanelWorkFolder 가시성 제어 추가 - UpdateActiveTab: PanelWorkFolder 가시성 제어 추가 - BtnWorkFolderBrowse_Click, UpdateWorkFolder, BuildMcpServerList, McpToggle_Changed 추가 - using System.Linq / using AxCopilot.Models 추가 AgentSettingsPanel.xaml: - PanelWorkFolder 섹션 추가 (Code 탭 전용 — 폴더 표시 + 탐색 버튼) - PanelMcpServers 섹션 추가 (도구 관리 뒤, 고급 앞) ChatWindow.MoodMenu.cs: - ToggleSettingsPanel(): 패널 열 때 ServiceSelector/ModelSelector/WorkFolder 콜백 연결 빌드: 경고 0, 오류 0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -447,6 +447,10 @@ public partial class ChatWindow
|
||||
SettingsPanel.CloseRequested += OnSettingsPanelClose;
|
||||
SettingsPanel.SettingsChanged -= OnSettingsPanelChanged;
|
||||
SettingsPanel.SettingsChanged += OnSettingsPanelChanged;
|
||||
// 콜백 연결 — ChatWindow 기존 구현에 위임
|
||||
SettingsPanel.ServiceSelectorRequested = () => BtnModelSelector_Click(BtnModelSelector, new System.Windows.RoutedEventArgs());
|
||||
SettingsPanel.ModelSelectorRequested = () => BtnModelSelector_Click(BtnModelSelector, new System.Windows.RoutedEventArgs());
|
||||
SettingsPanel.WorkFolderBrowseRequested = () => BrowseWorkFolder();
|
||||
SettingsPanel.IsOpen = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,6 +291,44 @@
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 작업 폴더 (Code 탭 전용) -->
|
||||
<StackPanel x:Name="PanelWorkFolder" Visibility="Collapsed" Margin="0,8,0,0">
|
||||
<Grid Margin="0,0,0,6">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="작업 폴더" Foreground="{DynamicResource SecondaryText}" FontSize="12"
|
||||
VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
<Grid Margin="0,0,0,8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Background="{DynamicResource HintBackground}" CornerRadius="6" Padding="8,5">
|
||||
<TextBlock x:Name="TxtWorkFolder" Text="(미지정)" FontSize="11"
|
||||
Foreground="{DynamicResource SecondaryText}"
|
||||
TextTrimming="CharacterEllipsis" MaxWidth="170"/>
|
||||
</Border>
|
||||
<Border Grid.Column="1" CornerRadius="6" Padding="10,5" Margin="6,0,0,0" Cursor="Hand"
|
||||
MouseLeftButtonUp="BtnWorkFolderBrowse_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>
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="12"
|
||||
Foreground="#FFB74D" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
|
||||
|
||||
<!-- ═══ 도구 관리 ═══ -->
|
||||
@@ -303,6 +341,16 @@
|
||||
|
||||
<Border Height="1" Background="{DynamicResource BorderColor}" Margin="0,8,0,16"/>
|
||||
|
||||
<!-- ═══ MCP 서버 ═══ -->
|
||||
<TextBlock Text="MCP 서버" FontSize="13" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource PrimaryText}" Margin="0,0,0,8"/>
|
||||
|
||||
<StackPanel x:Name="PanelMcpServers" Margin="0,0,0,8">
|
||||
<!-- 코드비하인드에서 동적 생성 -->
|
||||
</StackPanel>
|
||||
|
||||
<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"/>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using AxCopilot.Models;
|
||||
using AxCopilot.Services;
|
||||
|
||||
namespace AxCopilot.Views.Controls;
|
||||
@@ -18,6 +20,15 @@ public partial class AgentSettingsPanel : UserControl
|
||||
private bool _isOpen;
|
||||
private bool _isLoading = true; // 초기 로드 중 이벤트 발생 방지
|
||||
|
||||
/// <summary>서비스 선택 요청 콜백 (ChatWindow.BtnModelSelector_Click으로 위임).</summary>
|
||||
public Action? ServiceSelectorRequested;
|
||||
|
||||
/// <summary>모델 선택 요청 콜백 (ChatWindow.BtnModelSelector_Click으로 위임).</summary>
|
||||
public Action? ModelSelectorRequested;
|
||||
|
||||
/// <summary>작업 폴더 탐색 요청 콜백 (ChatWindow.BrowseWorkFolder로 위임).</summary>
|
||||
public Action? WorkFolderBrowseRequested;
|
||||
|
||||
/// <summary>설정 패널 열림/닫힘 상태.</summary>
|
||||
public bool IsOpen
|
||||
{
|
||||
@@ -78,6 +89,7 @@ public partial class AgentSettingsPanel : UserControl
|
||||
// 탭별 설정 표시
|
||||
PanelCoworkSettings.Visibility = activeTab == "Cowork" ? Visibility.Visible : Visibility.Collapsed;
|
||||
PanelCodeSettings.Visibility = activeTab == "Code" ? Visibility.Visible : Visibility.Collapsed;
|
||||
PanelWorkFolder.Visibility = activeTab == "Code" ? Visibility.Visible : Visibility.Collapsed;
|
||||
|
||||
if (activeTab == "Cowork")
|
||||
{
|
||||
@@ -92,6 +104,11 @@ public partial class AgentSettingsPanel : UserControl
|
||||
// 도구 토글 동적 생성
|
||||
BuildToolToggles(settings, toolRegistry);
|
||||
|
||||
// 작업 폴더 표시 (Code 탭)
|
||||
UpdateWorkFolder(settings);
|
||||
// MCP 서버 목록 표시
|
||||
BuildMcpServerList(settings);
|
||||
|
||||
_isLoading = false;
|
||||
}
|
||||
|
||||
@@ -100,7 +117,8 @@ public partial class AgentSettingsPanel : UserControl
|
||||
{
|
||||
TxtCurrentTab.Text = tab;
|
||||
PanelCoworkSettings.Visibility = tab == "Cowork" ? Visibility.Visible : Visibility.Collapsed;
|
||||
PanelCodeSettings.Visibility = tab == "Code" ? Visibility.Visible : Visibility.Collapsed;
|
||||
PanelCodeSettings.Visibility = tab == "Code" ? Visibility.Visible : Visibility.Collapsed;
|
||||
PanelWorkFolder.Visibility = tab == "Code" ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private void BuildToolToggles(SettingsService settings,
|
||||
@@ -159,12 +177,105 @@ public partial class AgentSettingsPanel : UserControl
|
||||
|
||||
private void BtnServiceSelector_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
// TODO: 서비스 선택 팝업 (Ollama/vLLM/Gemini/Claude)
|
||||
ServiceSelectorRequested?.Invoke();
|
||||
}
|
||||
|
||||
private void BtnModelSelector_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
// TODO: 모델 선택 팝업 — ChatWindow의 기존 모델 선택 로직 재사용
|
||||
ModelSelectorRequested?.Invoke();
|
||||
}
|
||||
|
||||
private void BtnWorkFolderBrowse_Click(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||
{
|
||||
WorkFolderBrowseRequested?.Invoke();
|
||||
}
|
||||
|
||||
private void UpdateWorkFolder(SettingsService settings)
|
||||
{
|
||||
var folder = settings.Settings.Llm.WorkFolder;
|
||||
if (TxtWorkFolder == null) return;
|
||||
TxtWorkFolder.Text = string.IsNullOrWhiteSpace(folder)
|
||||
? "(미지정)"
|
||||
: System.IO.Path.GetFileName(folder) is { Length: > 0 } name ? name : folder;
|
||||
TxtWorkFolder.ToolTip = folder;
|
||||
}
|
||||
|
||||
private void BuildMcpServerList(SettingsService settings)
|
||||
{
|
||||
if (PanelMcpServers == null) return;
|
||||
PanelMcpServers.Children.Clear();
|
||||
|
||||
var servers = settings.Settings.Llm.McpServers;
|
||||
if (servers == null || servers.Count == 0)
|
||||
{
|
||||
PanelMcpServers.Children.Add(new TextBlock
|
||||
{
|
||||
Text = "등록된 MCP 서버 없음",
|
||||
FontSize = 11,
|
||||
Foreground = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray,
|
||||
Margin = new Thickness(0, 0, 0, 4),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var server in servers)
|
||||
{
|
||||
var grid = new System.Windows.Controls.Grid { Margin = new Thickness(0, 0, 0, 6) };
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(8) });
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
|
||||
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
|
||||
|
||||
var dot = new System.Windows.Shapes.Ellipse
|
||||
{
|
||||
Width = 6, Height = 6,
|
||||
Fill = server.Enabled
|
||||
? new SolidColorBrush(Color.FromRgb(0x38, 0xA1, 0x69))
|
||||
: new SolidColorBrush(Color.FromRgb(0x9E, 0x9E, 0x9E)),
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
Grid.SetColumn(dot, 0);
|
||||
|
||||
var nameLabel = new TextBlock
|
||||
{
|
||||
Text = server.Name,
|
||||
FontSize = 11,
|
||||
Foreground = TryFindResource("PrimaryText") as Brush ?? Brushes.White,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Margin = new Thickness(6, 0, 0, 0),
|
||||
TextTrimming = System.Windows.TextTrimming.CharacterEllipsis,
|
||||
};
|
||||
Grid.SetColumn(nameLabel, 1);
|
||||
|
||||
var chk = new CheckBox
|
||||
{
|
||||
IsChecked = server.Enabled,
|
||||
Tag = server.Name,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
if (TryFindResource("ToggleSwitch") is Style toggleStyle)
|
||||
chk.Style = toggleStyle;
|
||||
chk.Checked += McpToggle_Changed;
|
||||
chk.Unchecked += McpToggle_Changed;
|
||||
Grid.SetColumn(chk, 2);
|
||||
|
||||
grid.Children.Add(dot);
|
||||
grid.Children.Add(nameLabel);
|
||||
grid.Children.Add(chk);
|
||||
PanelMcpServers.Children.Add(grid);
|
||||
}
|
||||
}
|
||||
|
||||
private void McpToggle_Changed(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_isLoading || sender is not CheckBox chk || chk.Tag is not string name) return;
|
||||
var app = System.Windows.Application.Current as App;
|
||||
var settings = app?.SettingsService;
|
||||
if (settings == null) return;
|
||||
var server = settings.Settings.Llm.McpServers?.FirstOrDefault(s => s.Name == name);
|
||||
if (server == null) return;
|
||||
server.Enabled = chk.IsChecked == true;
|
||||
settings.Save();
|
||||
SettingsChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void TxtApiEndpoint_LostFocus(object sender, RoutedEventArgs e)
|
||||
|
||||
Reference in New Issue
Block a user