346 lines
11 KiB
C#
346 lines
11 KiB
C#
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;
|
|
}
|
|
}
|