using Qrakhen.Qamp.Editor.Commands; using Qrakhen.Qamp.Editor.Primitives; using Qrakhen.Qamp.Memory; using System.Collections.ObjectModel; using System.Windows.Input; namespace Qrakhen.Qamp.Editor.ViewModel; public class EditorFrameViewModel : ObservableObject { private BufferPosition _cursorPosition; public BufferPosition CursorPosition { get => _cursorPosition; set => SetProperty(ref _cursorPosition, value); } public int CursorLine => _cursorPosition.Line; public int CursorColumn => _cursorPosition.Column; public LineBuffer CurrentLineBuffer => Lines[CursorLine]; public ICommand MoveCaretCommand { get; } public ICommand MoveBlockCommand { get; } public ICommand InsertCommand { get; } public ICommand DeleteCommand { get; } public ICommand ClipBoardCommand { get; } public ObservableCollection Lines { get; private set; } = new() { new LineBuffer("test"), new LineBuffer(" is very good;"), new LineBuffer(" jaja();"), new LineBuffer("}") }; public EditorFrameViewModel() { MoveCaretCommand = new RelayCommand(ExecuteMoveCaret); MoveBlockCommand = new RelayCommand(ExecuteMoveBlock); InsertCommand = new RelayCommand(ExecuteInsert); DeleteCommand = new RelayCommand(ExecuteDelete); ClipBoardCommand = new RelayCommand(() => { }); } private BufferPosition AlignBufferPosition(BufferPosition position) { int line = Math.Max(0, Math.Min(position.Line, Lines.Count - 1)); LineBuffer buffer = Lines[line]; int column = Math.Max(0, Math.Min(position.Column, buffer.Tail)); return new BufferPosition(line, column); } public void SetCursor(BufferPosition position) { CursorPosition = AlignBufferPosition(position); OnPropertyChanged(nameof(CurrentLineBuffer)); } public void MoveCursor(BufferPosition relative) { SetCursor(CursorPosition + relative); OnPropertyChanged(nameof(CurrentLineBuffer)); } public void Delete(BufferRegion region, bool follow = true) { if (follow) SetCursor(new BufferPosition(region.From.Line, region.From.Column)); for (int line = region.From.Line; line < region.To.Line; line++) { } } public void Delete(int count = 1, bool follow = true) { if (follow) MoveCursor(new BufferPosition(0, -count)); CurrentLineBuffer.Delete(CursorColumn, count); } public void Insert(string data, bool follow = true) { CurrentLineBuffer.Insert(CursorColumn, data); int newLine = data.IndexOf(Environment.NewLine); if (newLine > -1) { int position = CursorColumn - (data.Length - newLine + 1); LineBuffer split = new LineBuffer(CurrentLineBuffer.Slice(position), CurrentLineBuffer.Encoding); Lines.Insert(CursorLine, split); SetCursor(new BufferPosition(CursorLine + 1, split.Tail)); } else { if (follow) MoveCursor(new BufferPosition(0, data.Length)); } } private void ExecuteMoveCaret(object? parameter) { if (parameter is BufferPosition relative) MoveCursor(relative); } private void ExecuteMoveBlock(object? parameter) { if (parameter is BufferPosition relative) MoveCursor(relative); } private void ExecuteInsert(object? parameter) { if (parameter is string str) Insert(str, true); } private void ExecuteDelete(object? parameter) { if (parameter is int count) Delete(Math.Abs(count), count < 0); if (parameter is BufferRegion region) Delete(region); } }