using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using Microsoft.Xaml.Behaviors;
using SheetMe.Designer.ViewModels;
namespace SheetMe.Designer.Behaviors;
///
/// 캔버스 키보드 단축키 — 텍스트 입력 요소에 포커스가 있으면 통과(입력 보호).
/// 화살표 넛지(Shift=그리드), Del, Ctrl+A/C/V/D/Z/Y, Esc.
///
public sealed class CanvasKeyboardBehavior : Behavior
{
#region Methods
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.PreviewKeyDown += OnPreviewKeyDown;
}
protected override void OnDetaching()
{
AssociatedObject.PreviewKeyDown -= OnPreviewKeyDown;
base.OnDetaching();
}
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
if ((AssociatedObject as FrameworkElement)?.DataContext is not DesignerViewModel designer)
{
return;
}
// 텍스트 입력 보호 — 포커스가 편집 컨트롤이면 단축키 라우팅 안 함
if (Keyboard.FocusedElement is TextBoxBase or ComboBox or PasswordBox)
{
return;
}
var ctrl = Keyboard.Modifiers.HasFlag(ModifierKeys.Control);
var shift = Keyboard.Modifiers.HasFlag(ModifierKeys.Shift);
var step = shift ? designer.Snap.GridSize * 2 : 1;
var handled = true;
switch (e.Key)
{
case Key.Left: designer.NudgeSelection(-step, 0); break;
case Key.Right: designer.NudgeSelection(step, 0); break;
case Key.Up: designer.NudgeSelection(0, -step); break;
case Key.Down: designer.NudgeSelection(0, step); break;
case Key.Delete: designer.DeleteSelection(); break;
case Key.Escape: designer.Interaction.Cancel(); break;
case Key.A when ctrl: designer.SelectAllOnActivePage(); break;
case Key.C when ctrl: designer.CopySelection(); break;
case Key.X when ctrl: designer.CutSelection(); break;
case Key.V when ctrl: designer.Paste(); break;
case Key.D when ctrl: designer.CopySelection(); designer.Paste(); break;
case Key.Z when ctrl: designer.Undo.Undo(); break;
case Key.Y when ctrl: designer.Undo.Redo(); break;
case Key.G when ctrl && shift: designer.UngroupSelection(); break;
case Key.G when ctrl: designer.GroupSelection(); break;
default: handled = false; break;
}
e.Handled = handled;
}
#endregion
}