qamp/Qrakhen.Qamp.Editor/ViewModel/EditorFrameViewModel.cs

124 lines
3.5 KiB
C#

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<LineBuffer> 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);
}
}