using Qrakhen.Qamp.Editor.Primitives; using Qrakhen.Qamp.Editor.ViewModel; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; namespace Qrakhen.Qamp.Editor.Controls; public partial class EditorFrame : UserControl { public Caret Caret { get; private set; } public EditorFrame() { InitializeComponent(); Loaded += OnLoaded; PreviewKeyDown += OnKeyDown; } private void OnKeyDown(object sender, KeyEventArgs e) { if (DataContext is EditorFrameViewModel vm) { CursorPosition position = e.Key switch { Key.Right => new(0, 1), Key.Left => new(0, -1), Key.Up => new(-1, 0), Key.Down => new(1, 0), _ => new(0, 0) }; if (vm.MoveCaretCommand.CanExecute(position)) { vm.MoveCaretCommand.Execute(position); e.Handled = true; } } } private void OnLoaded(object sender, RoutedEventArgs e) { Focus(); AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this); if (adornerLayer != null) { Caret = new Caret(this, 18); adornerLayer.Add(Caret); } else { System.Diagnostics.Debug.WriteLine("AdornerLayer still null. Check parent hierarchy."); } Loaded -= OnLoaded; } private Point CalculateCaretPosition(int line, int index, double scrollY, double scrollX) { return new Point(10 * index + scrollX, line * 18 + scrollY); } private void MoveCaret(Point point) { Caret?.UpdatePosition(point); } private void UpdateCaret() { int line = CursorPosition.Line; int charIndex = CursorPosition.Column; double scrollY = ScrollView.VerticalOffset; double scrollX = ScrollView.HorizontalOffset; MoveCaret( CalculateCaretPosition( line, charIndex, scrollY, scrollX)); } public CursorPosition CursorPosition { get => (CursorPosition)GetValue(CursorPositionProperty); set => SetValue(CursorPositionProperty, value); } public static readonly DependencyProperty CursorPositionProperty = DependencyProperty.Register( nameof(CursorPosition), typeof(CursorPosition), typeof(EditorFrame), new PropertyMetadata(CursorPosition.Void, OnCursorPositionChanged)); private static void OnCursorPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var frame = (EditorFrame)d; frame.UpdateCaret(); } }