using System.Linq; using System.Text.RegularExpressions; 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 CustomMoodDialog : Window { private readonly TextBox _keyBox; private readonly TextBox _labelBox; private readonly TextBox _iconBox; private readonly TextBox _descBox; private readonly TextBox _cssBox; private readonly bool _isEdit; private const string CssExample = "body {\n font-family: 'Pretendard', 'Noto Sans KR', sans-serif;\n max-width: 900px;\n margin: 0 auto;\n padding: 40px;\n color: #1a1a2e;\n background: #f8f9fc;\n line-height: 1.8;\n}\nh1 { color: #2d3748; border-bottom: 2px solid #4a90d9; padding-bottom: 8px; }\nh2 { color: #4a5568; margin-top: 2em; }\ntable { width: 100%; border-collapse: collapse; margin: 1.5em 0; }\nth { background: #4a90d9; color: white; padding: 10px; text-align: left; }\ntd { padding: 8px 10px; border-bottom: 1px solid #e2e8f0; }\ntr:nth-child(even) { background: #f0f4f8; }\n"; public string MoodKey => _keyBox.Text.Trim().ToLowerInvariant(); public string MoodLabel => _labelBox.Text.Trim(); public string MoodIcon => _iconBox.Text.Trim(); public string MoodDescription => _descBox.Text.Trim(); public string MoodCss => _cssBox.Text; public CustomMoodDialog(string existingKey = "", string existingLabel = "", string existingIcon = "\ud83c\udfaf", string existingDesc = "", string existingCss = "") { _isEdit = !string.IsNullOrEmpty(existingKey); base.Title = (_isEdit ? "무드 편집" : "무드 추가"); base.Width = 560.0; base.SizeToContent = SizeToContent.Height; base.WindowStartupLocation = WindowStartupLocation.CenterOwner; base.ResizeMode = ResizeMode.NoResize; base.WindowStyle = WindowStyle.None; base.AllowsTransparency = true; base.Background = Brushes.Transparent; 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 brush2 = (Application.Current.TryFindResource("SecondaryText") as Brush) ?? Brushes.Gray; Brush brush3 = (Application.Current.TryFindResource("AccentColor") as Brush) ?? Brushes.Blue; Brush bg = (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 = 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 = "\ue771", FontFamily = new FontFamily("Segoe MDL2 Assets"), FontSize = 18.0, Foreground = brush3, VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(0.0, 0.0, 10.0, 0.0) }); stackPanel2.Children.Add(new TextBlock { Text = (_isEdit ? "디자인 무드 편집" : "새 커스텀 디자인 무드"), FontSize = 17.0, FontWeight = FontWeights.Bold, Foreground = brush, VerticalAlignment = VerticalAlignment.Center }); stackPanel.Children.Add(stackPanel2); StackPanel stackPanel3 = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0.0, 0.0, 0.0, 8.0) }; StackPanel stackPanel4 = new StackPanel { Margin = new Thickness(0.0, 0.0, 12.0, 0.0) }; AddLabel(stackPanel4, "키 (영문)", brush); _keyBox = CreateTextBox(existingKey, brush, bg, brush3, brush4); _keyBox.Width = 140.0; _keyBox.IsEnabled = !_isEdit; stackPanel4.Children.Add(new Border { CornerRadius = new CornerRadius(8.0), ClipToBounds = true, Child = _keyBox }); stackPanel3.Children.Add(stackPanel4); StackPanel stackPanel5 = new StackPanel { Margin = new Thickness(0.0, 0.0, 12.0, 0.0) }; AddLabel(stackPanel5, "이름", brush); _labelBox = CreateTextBox(existingLabel, brush, bg, brush3, brush4); _labelBox.Width = 180.0; stackPanel5.Children.Add(new Border { CornerRadius = new CornerRadius(8.0), ClipToBounds = true, Child = _labelBox }); stackPanel3.Children.Add(stackPanel5); StackPanel stackPanel6 = new StackPanel(); AddLabel(stackPanel6, "아이콘", brush); _iconBox = CreateTextBox(existingIcon, brush, bg, brush3, brush4); _iconBox.Width = 60.0; _iconBox.TextAlignment = TextAlignment.Center; stackPanel6.Children.Add(new Border { CornerRadius = new CornerRadius(8.0), ClipToBounds = true, Child = _iconBox }); stackPanel3.Children.Add(stackPanel6); stackPanel.Children.Add(stackPanel3); AddLabel(stackPanel, "설명", brush); _descBox = CreateTextBox(existingDesc, brush, bg, brush3, brush4); stackPanel.Children.Add(new Border { CornerRadius = new CornerRadius(8.0), ClipToBounds = true, Child = _descBox, Margin = new Thickness(0.0, 0.0, 0.0, 8.0) }); AddSeparator(stackPanel, brush4); AddLabel(stackPanel, "CSS 스타일", brush); AddHint(stackPanel, "문서에 적용될 CSS입니다. body, h1~h6, table, .callout 등의 스타일을 정의하세요.", brush2); _cssBox = CreateTextBox(existingCss, brush, bg, brush3, brush4, multiline: true, 200); _cssBox.FontFamily = new FontFamily("Consolas, Courier New, monospace"); _cssBox.FontSize = 12.0; stackPanel.Children.Add(new Border { CornerRadius = new CornerRadius(8.0), ClipToBounds = true, Child = _cssBox }); TextBlock textBlock = new TextBlock { Text = "CSS 예시 보기", FontSize = 11.0, Foreground = brush3, Cursor = Cursors.Hand, Margin = new Thickness(0.0, 6.0, 0.0, 0.0), TextDecorations = TextDecorations.Underline }; textBlock.MouseLeftButtonDown += delegate { if (string.IsNullOrWhiteSpace(_cssBox.Text)) { _cssBox.Text = "body {\n font-family: 'Pretendard', 'Noto Sans KR', sans-serif;\n max-width: 900px;\n margin: 0 auto;\n padding: 40px;\n color: #1a1a2e;\n background: #f8f9fc;\n line-height: 1.8;\n}\nh1 { color: #2d3748; border-bottom: 2px solid #4a90d9; padding-bottom: 8px; }\nh2 { color: #4a5568; margin-top: 2em; }\ntable { width: 100%; border-collapse: collapse; margin: 1.5em 0; }\nth { background: #4a90d9; color: white; padding: 10px; text-align: left; }\ntd { padding: 8px 10px; border-bottom: 1px solid #e2e8f0; }\ntr:nth-child(even) { background: #f0f4f8; }\n"; } }; stackPanel.Children.Add(textBlock); StackPanel stackPanel7 = 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 = brush2, BorderBrush = brush4, BorderThickness = new Thickness(1.0), Cursor = Cursors.Hand, FontSize = 13.0 }; button.Click += delegate { base.DialogResult = false; Close(); }; stackPanel7.Children.Add(button); Button button2 = new Button { Content = (_isEdit ? "저장" : "추가"), Width = 80.0, Padding = new Thickness(0.0, 8.0, 0.0, 8.0), Background = brush3, Foreground = Brushes.White, BorderThickness = new Thickness(0.0), Cursor = Cursors.Hand, FontSize = 13.0, FontWeight = FontWeights.SemiBold }; button2.Click += delegate { Validate(); }; stackPanel7.Children.Add(button2); stackPanel.Children.Add(stackPanel7); 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 { (_isEdit ? _labelBox : _keyBox).Focus(); }; border.MouseLeftButtonDown += delegate(object _, MouseButtonEventArgs me) { if (me.LeftButton == MouseButtonState.Pressed) { try { DragMove(); } catch { } } }; } private void Validate() { if (string.IsNullOrWhiteSpace(_keyBox.Text)) { CustomMessageBox.Show("키를 입력하세요 (영문 소문자).", "입력 오류", MessageBoxButton.OK, MessageBoxImage.Exclamation); _keyBox.Focus(); return; } if (!Regex.IsMatch(_keyBox.Text.Trim(), "^[a-z][a-z0-9_]{1,20}$")) { CustomMessageBox.Show("키는 영문 소문자로 시작하며, 소문자/숫자/밑줄만 허용됩니다 (2~21자).", "입력 오류", MessageBoxButton.OK, MessageBoxImage.Exclamation); _keyBox.Focus(); return; } if (string.IsNullOrWhiteSpace(_labelBox.Text)) { CustomMessageBox.Show("이름을 입력하세요.", "입력 오류", MessageBoxButton.OK, MessageBoxImage.Exclamation); _labelBox.Focus(); return; } if (!_isEdit) { string[] source = new string[10] { "modern", "professional", "creative", "minimal", "elegant", "dark", "colorful", "corporate", "magazine", "dashboard" }; if (source.Contains(_keyBox.Text.Trim().ToLowerInvariant())) { CustomMessageBox.Show("내장 무드와 동일한 키는 사용할 수 없습니다.", "입력 오류", MessageBoxButton.OK, MessageBoxImage.Exclamation); _keyBox.Focus(); return; } } base.DialogResult = true; Close(); } 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, 8.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, int height = 100) { 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.AcceptsTab = true; textBox.TextWrapping = TextWrapping.Wrap; textBox.MinHeight = height; textBox.MaxHeight = height + 100; textBox.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; } return textBox; } }