124 lines
3.5 KiB
C#
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);
|
|
}
|
|
}
|