using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Effects; using System.Windows.Shapes; namespace AxCopilot.Views; internal sealed class CustomPresetDialog : Window { private readonly TextBox _nameBox; private readonly TextBox _descBox; private readonly TextBox _promptBox; private readonly ComboBox _tabCombo; private string _selectedColor; private string _selectedSymbol; private Border? _iconPreview; private TextBlock? _iconPreviewText; private static readonly (string Label, string Hex)[] Colors = new(string, string)[10] { ("인디고", "#6366F1"), ("블루", "#3B82F6"), ("티일", "#14B8A6"), ("그린", "#22C55E"), ("옐로우", "#EAB308"), ("오렌지", "#F97316"), ("레드", "#EF4444"), ("핑크", "#EC4899"), ("퍼플", "#A855F7"), ("슬레이트", "#64748B") }; private static readonly (string Category, (string Label, string Symbol)[] Icons)[] IconSets = new(string, (string, string)[])[5] { ("업무", new(string, string)[8] { ("일반", "\ue771"), ("문서", "\ue8a5"), ("메일", "\ue715"), ("캘린더", "\ue787"), ("차트", "\ue9d9"), ("발표", "\ue7f4"), ("계산기", "\ue8ef"), ("메모", "\ue70b") }), ("기술", new(string, string)[8] { ("코드", "\ue943"), ("설정", "\ue713"), ("데이터", "\uea86"), ("검색", "\ue721"), ("보안", "\ue72e"), ("서버", "\ue839"), ("버그", "\uebe8"), ("배포", "\ue7f8") }), ("커뮤니케이션", new(string, string)[8] { ("대화", "\ue8bd"), ("사람", "\ue77b"), ("팀", "\ue716"), ("전화", "\ue717"), ("알림", "\uea8f"), ("공유", "\ue72d"), ("피드백", "\ue939"), ("질문", "\ue897") }), ("콘텐츠", new(string, string)[8] { ("사진", "\ue722"), ("동영상", "\ue714"), ("음악", "\ue8d6"), ("글쓰기", "\ue70f"), ("책", "\ue82d"), ("웹", "\ue774"), ("디자인", "\ue790"), ("다운로드", "\ue896") }), ("분석", new(string, string)[8] { ("인사이트", "\ue9d9"), ("대시보드", "\ue809"), ("리포트", "\ue9f9"), ("트렌드", "\ue8a1"), ("필터", "\ue71c"), ("목표", "\ue7c1"), ("비교", "\ue8fd"), ("측정", "\ue7c8") }) }; public string PresetName => _nameBox.Text.Trim(); public string PresetDescription => _descBox.Text.Trim(); public string PresetSystemPrompt => _promptBox.Text.Trim(); public string PresetTab => (_tabCombo.SelectedItem as ComboBoxItem)?.Tag?.ToString() ?? "Chat"; public string PresetColor => _selectedColor; public string PresetSymbol => _selectedSymbol; public CustomPresetDialog(string existingName = "", string existingDesc = "", string existingPrompt = "", string existingColor = "#6366F1", string existingSymbol = "\ue713", string existingTab = "Chat") { bool flag = !string.IsNullOrEmpty(existingName); base.Title = (flag ? "프리셋 편집" : "프리셋 추가"); base.Width = 520.0; base.SizeToContent = SizeToContent.Height; base.WindowStartupLocation = WindowStartupLocation.CenterOwner; base.ResizeMode = ResizeMode.NoResize; base.WindowStyle = WindowStyle.None; base.AllowsTransparency = true; base.Background = Brushes.Transparent; _selectedColor = existingColor; _selectedSymbol = existingSymbol; Brush background = (Application.Current.TryFindResource("LauncherBackground") as Brush) ?? new SolidColorBrush(Color.FromRgb(26, 27, 46)); Brush primaryText = (Application.Current.TryFindResource("PrimaryText") as Brush) ?? Brushes.White; Brush brush = (Application.Current.TryFindResource("SecondaryText") as Brush) ?? Brushes.Gray; Brush brush2 = (Application.Current.TryFindResource("AccentColor") as Brush) ?? Brushes.Blue; Brush brush3 = (Application.Current.TryFindResource("ItemBackground") as Brush) ?? new SolidColorBrush(Color.FromRgb(42, 43, 64)); Brush brush4 = (Application.Current.TryFindResource("BorderColor") as Brush) ?? Brushes.Gray; Border border = new Border { Background = background, CornerRadius = new CornerRadius(16.0), BorderBrush = brush4, BorderThickness = new Thickness(1.0), Padding = new Thickness(28.0, 24.0, 28.0, 24.0), Effect = new DropShadowEffect { BlurRadius = 24.0, ShadowDepth = 4.0, Opacity = 0.3, Color = System.Windows.Media.Colors.Black } }; StackPanel stackPanel = new StackPanel(); StackPanel stackPanel2 = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0.0, 0.0, 0.0, 20.0) }; stackPanel2.Children.Add(new TextBlock { Text = "\ue710", FontFamily = new FontFamily("Segoe MDL2 Assets"), FontSize = 18.0, Foreground = brush2, VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(0.0, 0.0, 10.0, 0.0) }); stackPanel2.Children.Add(new TextBlock { Text = (flag ? "프리셋 편집" : "새 커스텀 프리셋"), FontSize = 17.0, FontWeight = FontWeights.Bold, Foreground = primaryText, VerticalAlignment = VerticalAlignment.Center }); stackPanel.Children.Add(stackPanel2); AddLabel(stackPanel, "프리셋 이름", primaryText); AddHint(stackPanel, "대화 주제 버튼에 표시될 이름입니다", brush); _nameBox = CreateTextBox(existingName, primaryText, brush3, brush2, brush4); stackPanel.Children.Add(new Border { CornerRadius = new CornerRadius(8.0), ClipToBounds = true, Child = _nameBox }); AddSeparator(stackPanel, brush4); AddLabel(stackPanel, "설명", primaryText); AddHint(stackPanel, "프리셋 카드 하단에 표시될 짧은 설명입니다", brush); _descBox = CreateTextBox(existingDesc, primaryText, brush3, brush2, brush4); stackPanel.Children.Add(new Border { CornerRadius = new CornerRadius(8.0), ClipToBounds = true, Child = _descBox }); AddSeparator(stackPanel, brush4); AddLabel(stackPanel, "아이콘 & 배경색", primaryText); StackPanel stackPanel3 = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0.0, 0.0, 0.0, 8.0) }; _iconPreview = new Border { Width = 48.0, Height = 48.0, CornerRadius = new CornerRadius(24.0), Background = new SolidColorBrush(ParseColor(_selectedColor)) { Opacity = 0.2 }, Cursor = Cursors.Hand, Margin = new Thickness(0.0, 0.0, 16.0, 0.0), ToolTip = "아이콘 선택" }; _iconPreviewText = new TextBlock { Text = _selectedSymbol, FontFamily = new FontFamily("Segoe MDL2 Assets"), FontSize = 20.0, Foreground = BrushFromHex(_selectedColor), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; _iconPreview.Child = _iconPreviewText; _iconPreview.MouseLeftButtonDown += delegate { ShowIconPickerPopup(); }; stackPanel3.Children.Add(_iconPreview); StackPanel stackPanel4 = new StackPanel { Margin = new Thickness(0.0, 0.0, 16.0, 0.0) }; stackPanel4.Children.Add(new TextBlock { Text = "탭", FontSize = 11.0, Foreground = brush, Margin = new Thickness(0.0, 0.0, 0.0, 4.0) }); _tabCombo = new ComboBox { Width = 100.0, FontSize = 12.0, Foreground = primaryText, Background = brush3, BorderBrush = brush4, BorderThickness = new Thickness(1.0), Padding = new Thickness(6.0, 4.0, 6.0, 4.0) }; _tabCombo.Items.Add(new ComboBoxItem { Content = "Chat", Tag = "Chat", IsSelected = (existingTab == "Chat") }); _tabCombo.Items.Add(new ComboBoxItem { Content = "Cowork", Tag = "Cowork", IsSelected = (existingTab == "Cowork") }); stackPanel4.Children.Add(_tabCombo); stackPanel3.Children.Add(stackPanel4); StackPanel stackPanel5 = new StackPanel { Children = { (UIElement)new TextBlock { Text = "배경색", FontSize = 11.0, Foreground = brush, Margin = new Thickness(0.0, 0.0, 0.0, 4.0) } } }; WrapPanel colorPanel = new WrapPanel(); (string, string)[] colors = Colors; for (int num = 0; num < colors.Length; num++) { (string, string) tuple = colors[num]; string item = tuple.Item1; string item2 = tuple.Item2; string colorHex = item2; Border border2 = new Border { Width = 22.0, Height = 22.0, CornerRadius = new CornerRadius(11.0), Background = BrushFromHex(item2), Margin = new Thickness(0.0, 0.0, 5.0, 4.0), Cursor = Cursors.Hand, BorderThickness = new Thickness(2.0), BorderBrush = ((item2 == _selectedColor) ? primaryText : Brushes.Transparent), ToolTip = item }; border2.MouseLeftButtonDown += delegate(object s, MouseButtonEventArgs _) { _selectedColor = colorHex; foreach (object child in colorPanel.Children) { if (child is Border border3) { border3.BorderBrush = Brushes.Transparent; } } if (s is Border border4) { border4.BorderBrush = primaryText; } UpdateIconPreview(); }; colorPanel.Children.Add(border2); } stackPanel5.Children.Add(colorPanel); stackPanel3.Children.Add(stackPanel5); stackPanel.Children.Add(stackPanel3); AddSeparator(stackPanel, brush4); AddLabel(stackPanel, "시스템 프롬프트", primaryText); AddHint(stackPanel, "AI가 이 프리셋에서 따를 지침입니다. 비워두면 기본 프롬프트가 사용됩니다.", brush); _promptBox = CreateTextBox(existingPrompt, primaryText, brush3, brush2, brush4, multiline: true); stackPanel.Children.Add(new Border { CornerRadius = new CornerRadius(8.0), ClipToBounds = true, Child = _promptBox }); TextBlock charCount = new TextBlock { FontSize = 10.5, Foreground = brush, Margin = new Thickness(0.0, 6.0, 0.0, 0.0), HorizontalAlignment = HorizontalAlignment.Right }; UpdateCharCount(charCount); _promptBox.TextChanged += delegate { UpdateCharCount(charCount); }; stackPanel.Children.Add(charCount); StackPanel stackPanel6 = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0.0, 20.0, 0.0, 0.0) }; Button button = new Button { Content = "취소", Width = 80.0, Padding = new Thickness(0.0, 8.0, 0.0, 8.0), Margin = new Thickness(0.0, 0.0, 10.0, 0.0), Background = Brushes.Transparent, Foreground = brush, BorderBrush = brush4, BorderThickness = new Thickness(1.0), Cursor = Cursors.Hand, FontSize = 13.0 }; button.Click += delegate { base.DialogResult = false; Close(); }; stackPanel6.Children.Add(button); Button button2 = new Button { Content = (flag ? "저장" : "추가"), Width = 80.0, Padding = new Thickness(0.0, 8.0, 0.0, 8.0), Background = brush2, Foreground = Brushes.White, BorderThickness = new Thickness(0.0), Cursor = Cursors.Hand, FontSize = 13.0, FontWeight = FontWeights.SemiBold }; button2.Click += delegate { if (string.IsNullOrWhiteSpace(_nameBox.Text)) { CustomMessageBox.Show("프리셋 이름을 입력하세요.", "입력 오류", MessageBoxButton.OK, MessageBoxImage.Exclamation); _nameBox.Focus(); } else { base.DialogResult = true; Close(); } }; stackPanel6.Children.Add(button2); stackPanel.Children.Add(stackPanel6); border.Child = stackPanel; base.Content = border; base.KeyDown += delegate(object _, KeyEventArgs ke) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if ((int)ke.Key == 13) { base.DialogResult = false; Close(); } }; base.Loaded += delegate { _nameBox.Focus(); _nameBox.SelectAll(); }; border.MouseLeftButtonDown += delegate(object _, MouseButtonEventArgs me) { if (me.LeftButton == MouseButtonState.Pressed) { try { DragMove(); } catch { } } }; } private void UpdateIconPreview() { if (_iconPreview != null && _iconPreviewText != null) { _iconPreview.Background = new SolidColorBrush(ParseColor(_selectedColor)) { Opacity = 0.2 }; _iconPreviewText.Text = _selectedSymbol; _iconPreviewText.Foreground = BrushFromHex(_selectedColor); } } private void ShowIconPickerPopup() { Brush background = (Application.Current.TryFindResource("LauncherBackground") as Brush) ?? new SolidColorBrush(Color.FromRgb(26, 27, 46)); Brush brush = (Application.Current.TryFindResource("PrimaryText") as Brush) ?? Brushes.White; Brush foreground = (Application.Current.TryFindResource("SecondaryText") as Brush) ?? Brushes.Gray; Brush borderBrush = (Application.Current.TryFindResource("BorderColor") as Brush) ?? Brushes.Gray; Brush hoverBg = (Application.Current.TryFindResource("ItemHoverBackground") as Brush) ?? Brushes.Transparent; Brush brush2 = (Application.Current.TryFindResource("AccentColor") as Brush) ?? Brushes.Blue; Window pickerWin = new Window { Title = "아이콘 선택", Width = 340.0, SizeToContent = SizeToContent.Height, WindowStartupLocation = WindowStartupLocation.CenterOwner, Owner = this, ResizeMode = ResizeMode.NoResize, WindowStyle = WindowStyle.None, AllowsTransparency = true, Background = Brushes.Transparent }; Border border = new Border { Background = background, CornerRadius = new CornerRadius(12.0), BorderBrush = borderBrush, BorderThickness = new Thickness(1.0), Padding = new Thickness(12.0), Effect = new DropShadowEffect { BlurRadius = 16.0, ShadowDepth = 3.0, Opacity = 0.3, Color = System.Windows.Media.Colors.Black } }; StackPanel stackPanel = new StackPanel(); Grid grid = new Grid(); grid.Children.Add(new TextBlock { Text = "아이콘 선택", FontSize = 14.0, FontWeight = FontWeights.SemiBold, Foreground = brush, Margin = new Thickness(0.0, 0.0, 0.0, 10.0), HorizontalAlignment = HorizontalAlignment.Left }); TextBlock textBlock = new TextBlock { Text = "\ue711", FontFamily = new FontFamily("Segoe MDL2 Assets"), FontSize = 12.0, Foreground = foreground, Cursor = Cursors.Hand, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Top }; textBlock.MouseLeftButtonDown += delegate { pickerWin.Close(); }; grid.Children.Add(textBlock); stackPanel.Children.Add(grid); border.MouseLeftButtonDown += delegate { try { pickerWin.DragMove(); } catch { } }; (string, (string, string)[])[] iconSets = IconSets; for (int num = 0; num < iconSets.Length; num++) { var (text, array) = iconSets[num]; stackPanel.Children.Add(new TextBlock { Text = text, FontSize = 11.0, FontWeight = FontWeights.SemiBold, Foreground = foreground, Margin = new Thickness(0.0, 6.0, 0.0, 4.0) }); WrapPanel wrapPanel = new WrapPanel(); (string, string)[] array2 = array; for (int num2 = 0; num2 < array2.Length; num2++) { (string, string) tuple2 = array2[num2]; string item = tuple2.Item1; string item2 = tuple2.Item2; string capturedSymbol = item2; bool flag = _selectedSymbol == item2; Border border2 = new Border { Width = 36.0, Height = 36.0, CornerRadius = new CornerRadius(8.0), Background = (flag ? new SolidColorBrush(ParseColor(_selectedColor)) { Opacity = 0.2 } : Brushes.Transparent), BorderBrush = (flag ? brush2 : Brushes.Transparent), BorderThickness = new Thickness(flag ? 1.5 : 0.0), Cursor = Cursors.Hand, Margin = new Thickness(0.0, 0.0, 4.0, 4.0), ToolTip = item }; border2.Child = new TextBlock { Text = item2, FontFamily = new FontFamily("Segoe MDL2 Assets"), FontSize = 16.0, Foreground = (flag ? BrushFromHex(_selectedColor) : brush), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; border2.MouseEnter += delegate(object s, MouseEventArgs _) { if (s is Border border3 && !(_selectedSymbol == capturedSymbol)) { border3.Background = hoverBg; } }; border2.MouseLeave += delegate(object s, MouseEventArgs _) { if (s is Border border3 && !(_selectedSymbol == capturedSymbol)) { border3.Background = Brushes.Transparent; } }; border2.MouseLeftButtonDown += delegate(object _, MouseButtonEventArgs e) { e.Handled = true; _selectedSymbol = capturedSymbol; UpdateIconPreview(); pickerWin.Close(); }; wrapPanel.Children.Add(border2); } stackPanel.Children.Add(wrapPanel); } border.Child = stackPanel; pickerWin.Content = border; pickerWin.ShowDialog(); } private static void AddLabel(StackPanel parent, string text, Brush fg) { parent.Children.Add(new TextBlock { Text = text, FontSize = 12.0, FontWeight = FontWeights.SemiBold, Foreground = fg, Margin = new Thickness(0.0, 0.0, 0.0, 6.0) }); } private static void AddHint(StackPanel parent, string text, Brush fg) { parent.Children.Add(new TextBlock { Text = text, FontSize = 11.0, Foreground = fg, Margin = new Thickness(0.0, 0.0, 0.0, 8.0) }); } private static void AddSeparator(StackPanel parent, Brush color) { parent.Children.Add(new Rectangle { Height = 1.0, Fill = color, Margin = new Thickness(0.0, 12.0, 0.0, 12.0), Opacity = 0.5 }); } private static TextBox CreateTextBox(string text, Brush fg, Brush bg, Brush caret, Brush border, bool multiline = false) { TextBox textBox = new TextBox { Text = text, FontSize = 13.0, Padding = new Thickness(12.0, 8.0, 12.0, 8.0), Foreground = fg, Background = bg, CaretBrush = caret, BorderBrush = border, BorderThickness = new Thickness(1.0) }; if (multiline) { textBox.AcceptsReturn = true; textBox.TextWrapping = TextWrapping.Wrap; textBox.MinHeight = 100.0; textBox.MaxHeight = 200.0; textBox.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; } return textBox; } private void UpdateCharCount(TextBlock tb) { tb.Text = $"{_promptBox.Text.Length}자"; } private static Brush BrushFromHex(string hex) { try { return new SolidColorBrush((Color)ColorConverter.ConvertFromString(hex)); } catch { return Brushes.Gray; } } private static Color ParseColor(string hex) { try { return (Color)ColorConverter.ConvertFromString(hex); } catch { return System.Windows.Media.Colors.Gray; } } }