Files
AX-Copilot-Codex/src/AxCopilot/Views/InputDialog.cs

192 lines
7.7 KiB
C#

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;
/// <summary>테마에 맞는 커스텀 텍스트 입력 다이얼로그.</summary>
internal sealed class InputDialog : Window
{
private readonly TextBox _textBox;
public string ResponseText => _textBox.Text;
public InputDialog(string title, string prompt, string defaultValue = "", string placeholder = "")
{
WindowStartupLocation = WindowStartupLocation.CenterOwner;
ResizeMode = ResizeMode.NoResize;
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
Background = Brushes.Transparent;
Width = 400;
SizeToContent = SizeToContent.Height;
var bg = Application.Current.TryFindResource("LauncherBackground") as Brush
?? new SolidColorBrush(Color.FromRgb(0x1A, 0x1B, 0x2E));
var borderBrush = Application.Current.TryFindResource("BorderColor") as Brush ?? Brushes.Gray;
var primaryText = Application.Current.TryFindResource("PrimaryText") as Brush ?? Brushes.White;
var secondaryText = Application.Current.TryFindResource("SecondaryText") as Brush ?? Brushes.Gray;
var accentBrush = Application.Current.TryFindResource("AccentColor") as Brush ?? Brushes.CornflowerBlue;
var itemBg = Application.Current.TryFindResource("ItemBackground") as Brush
?? new SolidColorBrush(Color.FromRgb(0x2A, 0x2B, 0x3E));
// 외부 컨테이너 (그림자 + 둥근 모서리)
var outerBorder = new Border
{
Background = bg,
BorderBrush = borderBrush,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(14),
Margin = new Thickness(16),
Effect = new DropShadowEffect
{
BlurRadius = 24, ShadowDepth = 6, Opacity = 0.35,
Color = Colors.Black, Direction = 270,
},
};
var stack = new StackPanel { Margin = new Thickness(24, 20, 24, 20) };
// 타이틀 행 (아이콘 + 제목)
var titlePanel = new StackPanel { Orientation = Orientation.Horizontal, Margin = new Thickness(0, 0, 0, 16) };
titlePanel.Children.Add(new TextBlock
{
Text = "\uE8AC", // 편집 아이콘
FontFamily = new FontFamily("Segoe MDL2 Assets"),
FontSize = 16, Foreground = accentBrush,
VerticalAlignment = VerticalAlignment.Center,
Margin = new Thickness(0, 0, 10, 0),
});
titlePanel.Children.Add(new TextBlock
{
Text = title, FontSize = 15, FontWeight = FontWeights.SemiBold,
Foreground = primaryText, VerticalAlignment = VerticalAlignment.Center,
});
stack.Children.Add(titlePanel);
// 프롬프트
stack.Children.Add(new TextBlock
{
Text = prompt, FontSize = 12.5, Foreground = secondaryText,
Margin = new Thickness(0, 0, 0, 8),
});
// 텍스트 입력 (둥근 테두리 + 플레이스홀더)
_textBox = new TextBox
{
Text = defaultValue,
FontSize = 13,
Padding = new Thickness(14, 8, 14, 8),
Foreground = primaryText,
Background = Brushes.Transparent,
CaretBrush = accentBrush,
BorderThickness = new Thickness(0),
BorderBrush = Brushes.Transparent,
};
_textBox.KeyDown += (_, e) =>
{
if (e.Key == Key.Enter) { DialogResult = true; Close(); }
if (e.Key == Key.Escape) { DialogResult = false; Close(); }
};
// 플레이스홀더 오버레이
var placeholderBlock = new TextBlock
{
Text = placeholder,
FontSize = 13,
Foreground = secondaryText,
Opacity = 0.5,
IsHitTestVisible = false,
VerticalAlignment = VerticalAlignment.Center,
Padding = new Thickness(14, 8, 14, 8),
Visibility = string.IsNullOrEmpty(defaultValue) && !string.IsNullOrEmpty(placeholder)
? Visibility.Visible : Visibility.Collapsed,
};
_textBox.TextChanged += (_, _) =>
placeholderBlock.Visibility = string.IsNullOrEmpty(_textBox.Text) ? Visibility.Visible : Visibility.Collapsed;
var inputGrid = new Grid();
inputGrid.Children.Add(_textBox);
inputGrid.Children.Add(placeholderBlock);
var inputBorder = new Border
{
CornerRadius = new CornerRadius(10),
BorderBrush = borderBrush,
BorderThickness = new Thickness(1),
Background = itemBg,
Child = inputGrid,
};
// 포커스 시 액센트 테두리
_textBox.GotFocus += (_, _) => inputBorder.BorderBrush = accentBrush;
_textBox.LostFocus += (_, _) => inputBorder.BorderBrush = borderBrush;
stack.Children.Add(inputBorder);
// 버튼 패널
var btnPanel = new StackPanel
{
Orientation = Orientation.Horizontal,
HorizontalAlignment = HorizontalAlignment.Right,
Margin = new Thickness(0, 18, 0, 0),
};
var cancelBtn = CreateButton("취소", Brushes.Transparent, secondaryText, borderBrush);
cancelBtn.Click += (_, _) => { DialogResult = false; Close(); };
btnPanel.Children.Add(cancelBtn);
var okBtn = CreateButton("확인", accentBrush, Brushes.White, null);
okBtn.Click += (_, _) => { DialogResult = true; Close(); };
btnPanel.Children.Add(okBtn);
stack.Children.Add(btnPanel);
outerBorder.Child = stack;
Content = outerBorder;
// 드래그 이동 (제목 영역)
titlePanel.MouseLeftButtonDown += (_, e) => { if (e.ClickCount == 1) DragMove(); };
Loaded += (_, _) => { _textBox.Focus(); _textBox.SelectAll(); };
}
private static Button CreateButton(string text, Brush background, Brush foreground, Brush? borderBrush)
{
var btn = new Button
{
Cursor = Cursors.Hand,
Margin = new Thickness(0, 0, 0, 0),
};
if (text == "취소") btn.Margin = new Thickness(0, 0, 8, 0);
// 커스텀 템플릿 (둥근 버튼)
var template = new ControlTemplate(typeof(Button));
var bdFactory = new FrameworkElementFactory(typeof(Border));
bdFactory.SetValue(Border.BackgroundProperty, background);
bdFactory.SetValue(Border.CornerRadiusProperty, new CornerRadius(8));
bdFactory.SetValue(Border.PaddingProperty, new Thickness(20, 8, 20, 8));
bdFactory.Name = "Bd";
if (borderBrush != null)
{
bdFactory.SetValue(Border.BorderBrushProperty, borderBrush);
bdFactory.SetValue(Border.BorderThicknessProperty, new Thickness(1));
}
var cpFactory = new FrameworkElementFactory(typeof(ContentPresenter));
cpFactory.SetValue(ContentPresenter.HorizontalAlignmentProperty, HorizontalAlignment.Center);
cpFactory.SetValue(ContentPresenter.VerticalAlignmentProperty, VerticalAlignment.Center);
bdFactory.AppendChild(cpFactory);
template.VisualTree = bdFactory;
var hoverTrigger = new Trigger { Property = UIElement.IsMouseOverProperty, Value = true };
hoverTrigger.Setters.Add(new Setter(UIElement.OpacityProperty, 0.85));
template.Triggers.Add(hoverTrigger);
btn.Template = template;
btn.Content = new TextBlock
{
Text = text, FontSize = 13, Foreground = foreground,
};
return btn;
}
}