This commit is contained in:
Qrakhen 2025-11-22 17:34:27 +01:00
parent e2022ef80e
commit b3385c0860
6 changed files with 269 additions and 185 deletions

View File

@ -7,26 +7,28 @@ namespace Qrakhen.Qamp.Editor.Controls;
public class Caret : Adorner public class Caret : Adorner
{ {
private readonly Pen _pen; private readonly Pen _pen;
private readonly double _height; private readonly double _height;
private readonly Brush _brush; private readonly Brush _brush;
private bool _blink; private bool _blink;
private Point _cursorPosition; private bool _enabled;
private Point _targetPosition; private Point _cursorPosition;
private Point _targetPosition;
private (Point from, Point to)[] _lines = []; private (Point from, Point to)[] _lines = [];
private DispatcherTimer _blinkTimer; private DispatcherTimer _blinkTimer;
private DispatcherTimer _moveTimer; private DispatcherTimer _moveTimer;
public Caret(UIElement adornedElement, Brush brush, double height = 18, double thickness = 1.72) : base(adornedElement) public Caret(UIElement adornedElement, Brush brush, double height = 18, double thickness = 1.72) : base(adornedElement)
{ {
IsHitTestVisible = false; IsHitTestVisible = false;
_enabled = true;
_height = height; _height = height;
_brush = brush; _brush = brush;
_pen = new Pen(brush, 1.92); _pen = new Pen(brush, 1.92);
_blinkTimer = new DispatcherTimer(); _blinkTimer = new DispatcherTimer();
_blinkTimer.Interval = TimeSpan.FromMilliseconds(428); _blinkTimer.Interval = TimeSpan.FromMilliseconds(324);
_blinkTimer.Tick += new EventHandler((s, e) => { _blinkTimer.Tick += new EventHandler((s, e) => {
Toggle(_blink = !_blink); Toggle(_blink = !_blink);
}); });
@ -50,22 +52,30 @@ public class Caret : Adorner
public void Toggle(bool hide) public void Toggle(bool hide)
{ {
_pen.Brush = hide ? Brushes.Transparent : _brush; _pen.Brush = hide ? Brushes.Transparent : _brush;
InvalidateVisual();
} }
public void Disable()
{
_blinkTimer?.Stop();
_enabled = false;
Toggle(true);
InvalidateVisual();
}
public void UpdateSelection((Point from, Point to)[] lines) public void UpdateSelection((Point from, Point to)[] lines)
{ {
_lines = lines; _lines = lines;
InvalidateVisual(); InvalidateVisual();
} }
public void UpdatePosition(Point newPosition) public void UpdatePosition(Point newPosition)
{ {
_cursorPosition = _targetPosition = newPosition; _cursorPosition = _targetPosition = newPosition;
Toggle(_blink = false); _enabled = true;
//_blinkTimer.Stop(); Toggle(_blink = false);
//_moveTimer.Start(); _blinkTimer.Start();
InvalidateVisual(); }
}
protected override void OnRender(DrawingContext drawingContext) protected override void OnRender(DrawingContext drawingContext)
{ {

View File

@ -15,26 +15,40 @@
<Setter Property="CurrentSelection" Value="{Binding CurrentSelection}" /> <Setter Property="CurrentSelection" Value="{Binding CurrentSelection}" />
<Setter Property="CurrentLineBuffer" Value="{Binding CurrentLineBuffer}" /> <Setter Property="CurrentLineBuffer" Value="{Binding CurrentLineBuffer}" />
</Style> </Style>
</UserControl.Style> </UserControl.Style>
<ScrollViewer x:Name="ScrollView"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListBox x:Name="LinesList"
Grid.Column="0"
ItemsSource="{Binding Lines.Count}"
IsHitTestVisible="False"
Background="#121314"
Foreground="#969696"
BorderThickness="0"
Padding="0,0,5,0"
VerticalContentAlignment="Top"
HorizontalContentAlignment="Right"/>
<ItemsControl ItemsSource="{Binding Lines}"
Grid.Column="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:LineRenderer LineBuffer="{Binding Buffer}"
Selection="{Binding Selection}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ScrollViewer x:Name="ScrollView" </ItemsControl>
VerticalScrollBarVisibility="Auto" </Grid>
HorizontalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Lines}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:LineRenderer LineBuffer="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer> </ScrollViewer>
</UserControl> </UserControl>

View File

@ -3,26 +3,32 @@ using Qrakhen.Qamp.Editor.Input;
using Qrakhen.Qamp.Editor.Primitives; using Qrakhen.Qamp.Editor.Primitives;
using Qrakhen.Qamp.Editor.ViewModel; using Qrakhen.Qamp.Editor.ViewModel;
using Qrakhen.Qamp.Memory; using Qrakhen.Qamp.Memory;
using System.Diagnostics.Eventing.Reader;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Shapes;
namespace Qrakhen.Qamp.Editor.Controls; namespace Qrakhen.Qamp.Editor.Controls;
public partial class EditorFrame : UserControl public partial class EditorFrame : UserControl
{ {
public Caret Caret { get; private set; } public Caret Caret { get; private set; }
public EditorFrame() public EditorFrame()
{ {
InitializeComponent(); InitializeComponent();
Loaded += OnLoaded; Loaded += OnLoaded;
PreviewKeyDown += OnKeyDown; PreviewKeyDown += OnKeyDown;
PreviewMouseDown += OnMouseDown; PreviewMouseDown += OnMouseDown;
} ScrollView.ScrollChanged += OnScroll;
}
private void OnScroll(object sender, ScrollChangedEventArgs e)
{
UpdateCaret(false);
}
protected void OnMouseDown(object sender, MouseButtonEventArgs e) protected void OnMouseDown(object sender, MouseButtonEventArgs e)
{ {
@ -30,133 +36,151 @@ public partial class EditorFrame : UserControl
if (DataContext is EditorFrameViewModel vm) { if (DataContext is EditorFrameViewModel vm) {
vm.MoveCaretCommand.Execute( vm.MoveCaretCommand.Execute(
new MoveCaretOptions( new MoveCaretOptions(
CalculateCursorPosition(e.GetPosition(this), 0, 0), CalculateCursorPosition(e.GetPosition(this), 0, 0),
false, false,
false)); false));
} }
} }
} }
private void OnKeyDown(object sender, KeyEventArgs e) private void OnKeyDown(object sender, KeyEventArgs e)
{ {
if (DataContext is EditorFrameViewModel vm) { if (DataContext is EditorFrameViewModel vm) {
BufferPosition position = e.Key switch { BufferPosition position = e.Key switch {
Key.Right => new(0, 1), Key.Right => new(0, 1),
Key.Left => new(0, -1), Key.Left => new(0, -1),
Key.Up => new(-1, 0), Key.Up => new(-1, 0),
Key.Down => new(1, 0), Key.Down => new(1, 0),
_ => new(0, 0) _ => new(0, 0)
}; };
if (position != BufferPosition.Initial) if (position != BufferPosition.Initial)
vm.MoveCaretCommand.Execute( vm.MoveCaretCommand.Execute(
new MoveCaretOptions( new MoveCaretOptions(
position, position,
true, true,
InputService.CtrlHeld)); InputService.CtrlHeld));
else if (e.Key == Key.Back) else if (e.Key == Key.Back)
vm.DeleteCommand.Execute(-1); vm.DeleteCommand.Execute(-1);
else if (e.Key == Key.Delete) else if (e.Key == Key.Delete)
vm.DeleteCommand.Execute(1); vm.DeleteCommand.Execute(1);
else if (e.Key == Key.Enter) else if (e.Key == Key.Enter)
vm.InsertCommand.Execute(Environment.NewLine); vm.InsertCommand.Execute(Environment.NewLine);
else if (e.Key == Key.Delete) else if (e.Key == Key.Delete)
vm.DeleteCommand.Execute(1); vm.DeleteCommand.Execute(1);
else { else {
char c = KeyHelper.Get(e.Key, char c = KeyHelper.Get(e.Key,
InputService.ShiftHeld ? 1 : InputService.ShiftHeld ? 1 :
(InputService.CtrlHeld && InputService.AltHeld) ? 2 : 0); (InputService.CtrlHeld && InputService.AltHeld) ? 2 : 0);
if (c != 0) if (c != 0)
vm.InsertCommand.Execute(c); vm.InsertCommand.Execute(c);
} }
e.Handled = true; e.Handled = true;
} }
} }
private void OnLoaded(object sender, RoutedEventArgs e) private void OnLoaded(object sender, RoutedEventArgs e)
{ {
Focus(); Focus();
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this); AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
if (adornerLayer != null) { if (adornerLayer != null) {
Caret = new Caret(this, Brushes.LimeGreen); Caret = new Caret(this, Brushes.LimeGreen);
adornerLayer.Add(Caret); adornerLayer.Add(Caret);
} else { } else {
System.Diagnostics.Debug.WriteLine("AdornerLayer still null. Check parent hierarchy."); System.Diagnostics.Debug.WriteLine("AdornerLayer still null. Check parent hierarchy.");
} }
Loaded -= OnLoaded; Loaded -= OnLoaded;
} }
private BufferPosition CalculateCursorPosition(Point point, double scrollY, double scrollX) private BufferPosition CalculateCursorPosition(Point point, double scrollY, double scrollX)
{ {
var ft = TextHelper.GetText(new string('_', 1), 14, null, VisualTreeHelper.GetDpi(this).PixelsPerDip); var ft = TextHelper.GetText(new string('_', 1), 14, null, VisualTreeHelper.GetDpi(this).PixelsPerDip);
return new BufferPosition((int)(point.Y / TextHelper.LineHeight), (int)(point.X / ft.Width)); return new BufferPosition((int)(point.Y / TextHelper.LineHeight), (int)((point.X - 34) / ft.Width));
} }
private Point CalculateCaretPosition(int line, int index, double scrollY, double scrollX) private Point CalculateCaretPosition(int line, int index, double scrollY, double scrollX)
{
var ft = TextHelper.GetText(new string('_', index), 14, null, VisualTreeHelper.GetDpi(this).PixelsPerDip);
return new Point(ft.Width + scrollX + 2, line * TextHelper.LineHeight + scrollY);
}
private void MoveCaret(Point point)
{
Caret?.UpdatePosition(point);
}
private void SelectRegion((Point from, Point to)[] lines)
{ {
Caret?.UpdateSelection(lines); var ft = TextHelper.GetText(new string('_', index), 14, null, VisualTreeHelper.GetDpi(this).PixelsPerDip);
return new Point(ft.Width - scrollX + 34, line * TextHelper.LineHeight - scrollY);
} }
private void UpdateCaret() private void MoveCaret(Point point)
{ {
int line = CursorPosition.Line; Caret?.UpdatePosition(point);
int charIndex = CursorPosition.Column; }
double scrollY = ScrollView.VerticalOffset; private void HideCaret()
double scrollX = ScrollView.HorizontalOffset; {
Caret?.Disable();
}
MoveCaret( private void AutoScroll(Point point)
CalculateCaretPosition( {
line, MoveCaret(point);
charIndex, }
scrollY,
scrollX)); private void UpdateCaret(bool autoScroll = true)
{
int line = CursorPosition.Line;
int charIndex = CursorPosition.Column;
double scrollY = ScrollView.VerticalOffset;
double scrollX = ScrollView.HorizontalOffset;
Point position = CalculateCaretPosition(
line,
charIndex,
scrollY,
scrollX);
Point offset = ScrollView.TranslatePoint(position, ScrollView);
if (offset.X < 0 ||
offset.Y < 0 ||
offset.X >= ScrollView.ActualWidth ||
offset.Y >= ScrollView.ActualHeight) {
if (autoScroll)
AutoScroll(offset);
else
HideCaret();
}
else
MoveCaret(position);
if (!CurrentSelection.IsVoid) { if (!CurrentSelection.IsVoid) {
} }
} }
public LineBuffer CurrentLineBuffer { public LineBuffer CurrentLineBuffer {
get => (LineBuffer)GetValue(CurrentLineBufferProperty); get => (LineBuffer)GetValue(CurrentLineBufferProperty);
set => SetValue(CurrentLineBufferProperty, value); set => SetValue(CurrentLineBufferProperty, value);
} }
public static readonly DependencyProperty CurrentLineBufferProperty = public static readonly DependencyProperty CurrentLineBufferProperty =
DependencyProperty.Register( DependencyProperty.Register(
nameof(CurrentLineBuffer), nameof(CurrentLineBuffer),
typeof(LineBuffer), typeof(LineBuffer),
typeof(EditorFrame), typeof(EditorFrame),
new PropertyMetadata(null)); new PropertyMetadata(null));
public BufferPosition CursorPosition { public BufferPosition CursorPosition {
get => (BufferPosition)GetValue(CursorPositionProperty); get => (BufferPosition)GetValue(CursorPositionProperty);
set => SetValue(CursorPositionProperty, value); set => SetValue(CursorPositionProperty, value);
} }
public static readonly DependencyProperty CursorPositionProperty = public static readonly DependencyProperty CursorPositionProperty =
DependencyProperty.Register( DependencyProperty.Register(
nameof(CursorPosition), nameof(CursorPosition),
typeof(BufferPosition), typeof(BufferPosition),
typeof(EditorFrame), typeof(EditorFrame),
new PropertyMetadata(BufferPosition.Initial, OnCursorPositionChanged)); new PropertyMetadata(BufferPosition.Initial, OnCursorPositionChanged));
private static void OnCursorPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) private static void OnCursorPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{ {
var frame = (EditorFrame)d; var frame = (EditorFrame)d;
frame.UpdateCaret(); frame.UpdateCaret();
} }
public BufferRegion CurrentSelection { public BufferRegion CurrentSelection {
get => (BufferRegion)GetValue(CurrentSelectionProperty); get => (BufferRegion)GetValue(CurrentSelectionProperty);

View File

@ -1,13 +1,8 @@
using Qrakhen.Qamp.Memory; using Qrakhen.Qamp.Memory;
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
namespace Qrakhen.Qamp.Editor.Controls; namespace Qrakhen.Qamp.Editor.Controls;

View File

@ -7,39 +7,74 @@
xmlns:vm="clr-namespace:Qrakhen.Qamp.Editor.ViewModel" xmlns:vm="clr-namespace:Qrakhen.Qamp.Editor.ViewModel"
xmlns:controls="clr-namespace:Qrakhen.Qamp.Editor.Controls" xmlns:controls="clr-namespace:Qrakhen.Qamp.Editor.Controls"
mc:Ignorable="d" mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=vm:FileViewModel}" Background="#161718"
Title="MainWindow" Height="450" Width="800"> d:DataContext="{d:DesignInstance Type=vm:MainViewModel}"
Title="MainWindow" Height="640" Width="920">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.RowDefinitions>
<ColumnDefinition Width="*" /> <RowDefinition Height="32" />
<ColumnDefinition Width="5*" /> <RowDefinition Height="*" />
</Grid.ColumnDefinitions> <RowDefinition Height="18" />
<Grid Grid.Column="1"> </Grid.RowDefinitions>
<Grid.RowDefinitions> <Grid Grid.Row="0"
<RowDefinition Height="5*" /> Background="#202122">
<RowDefinition Height="*" /> <Menu Background="#202122"
</Grid.RowDefinitions> VerticalAlignment="Stretch"
<Grid Grid.Row="0"> VerticalContentAlignment="Center"
<Grid.ColumnDefinitions> Height="32">
<ColumnDefinition Width="32" /> <MenuItem Header="File"
<ColumnDefinition Width="*" /> Height="32"
</Grid.ColumnDefinitions> Foreground="#fefefe">
<MenuItem></MenuItem>
<MenuItem></MenuItem>
<MenuItem></MenuItem>
<MenuItem></MenuItem>
<MenuItem></MenuItem>
</MenuItem>
<MenuItem Header="Fun" Foreground="#fefefe">
<ListBox Grid.Column="0" </MenuItem>
ItemsSource="{Binding Lines.Count}" <MenuItem Header="Run" Foreground="#fefefe">
IsHitTestVisible="False"
Background="#242628"
Foreground="#969696"
BorderThickness="0"
Padding="0,0,5,0"
VerticalContentAlignment="Top"
HorizontalContentAlignment="Right"/>
<controls:EditorFrame Grid.Column="1" /> </MenuItem>
</Menu>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="#242526">
</Grid> </Grid>
<Grid Grid.Row="1" Background="#161718"> <GridSplitter Grid.Column="0"
ResizeDirection="Columns"
Width="1"
Background="#40fefefe" />
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="5*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<controls:EditorFrame />
</Grid>
<GridSplitter Grid.Row="0"
ResizeDirection="Rows"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Height="1"
Background="#40fefefe" />
<Grid Grid.Row="1" Background="#1e1f20">
</Grid>
</Grid> </Grid>
</Grid> </Grid>
<Grid Grid.Row="2"
Background="#141516">
<Label Foreground="#80efefef"
FontSize="10"
Padding="2">Fun &amp; Status</Label>
</Grid>
</Grid> </Grid>
</Window> </Window>

View File

@ -8,6 +8,12 @@ using System.Windows.Input;
namespace Qrakhen.Qamp.Editor.ViewModel; namespace Qrakhen.Qamp.Editor.ViewModel;
public class SelectableLineBuffer(LineBuffer buffer)
{
public LineBuffer Buffer { get; private set; } = buffer;
public BufferRegion Selection { get; private set; } = new();
}
public class EditorFrameViewModel : ObservableObject public class EditorFrameViewModel : ObservableObject
{ {
private BufferPosition _cursorPosition; private BufferPosition _cursorPosition;
@ -26,7 +32,7 @@ public class EditorFrameViewModel : ObservableObject
public int CursorColumn => _cursorPosition.Column; public int CursorColumn => _cursorPosition.Column;
public LineBuffer CurrentLineBuffer => Lines[CursorLine]; public SelectableLineBuffer CurrentLine => Lines[CursorLine];
public ICommand MoveCaretCommand { get; } public ICommand MoveCaretCommand { get; }
public ICommand MoveBlockCommand { get; } public ICommand MoveBlockCommand { get; }
@ -34,11 +40,11 @@ public class EditorFrameViewModel : ObservableObject
public ICommand DeleteCommand { get; } public ICommand DeleteCommand { get; }
public ICommand ClipBoardCommand { get; } public ICommand ClipBoardCommand { get; }
public ObservableCollection<LineBuffer> Lines { get; private set; } = new() { public ObservableCollection<SelectableLineBuffer> Lines { get; private set; } = new() {
new LineBuffer("test"), new SelectableLineBuffer(new LineBuffer("test {")),
new LineBuffer(" is very good;"), new SelectableLineBuffer(new LineBuffer(" is very good;")),
new LineBuffer(" jaja();"), new SelectableLineBuffer(new LineBuffer(" jaja();")),
new LineBuffer("}") new SelectableLineBuffer(new LineBuffer("}"))
}; };
public EditorFrameViewModel() public EditorFrameViewModel()
@ -56,14 +62,14 @@ public class EditorFrameViewModel : ObservableObject
public void SetCursor(BufferPosition position) public void SetCursor(BufferPosition position)
{ {
CursorPosition = AlignBufferPosition(position); CursorPosition = AlignBufferPosition(position);
OnPropertyChanged(nameof(CurrentLineBuffer)); OnPropertyChanged(nameof(CurrentLine));
} }
public void MoveCursor(int lines, int columns) => MoveCursor(new BufferPosition(lines, columns)); public void MoveCursor(int lines, int columns) => MoveCursor(new BufferPosition(lines, columns));
public void MoveCursor(BufferPosition relative, bool jump = false) public void MoveCursor(BufferPosition relative, bool jump = false)
{ {
SetCursor(CursorPosition + relative); SetCursor(CursorPosition + relative);
OnPropertyChanged(nameof(CurrentLineBuffer)); OnPropertyChanged(nameof(CurrentLine));
} }
public void Delete(BufferRegion region, bool follow = true) public void Delete(BufferRegion region, bool follow = true)
@ -83,25 +89,25 @@ public class EditorFrameViewModel : ObservableObject
if (follow) { if (follow) {
// remove newline // remove newline
if (CursorColumn - count < 0 && CursorLine > 0) { if (CursorColumn - count < 0 && CursorLine > 0) {
int position = Lines[CursorLine - 1].Tail; int position = Lines[CursorLine - 1].Buffer.Tail;
Lines[CursorLine - 1].Insert( Lines[CursorLine - 1].Buffer.Insert(
position, position,
CurrentLineBuffer.Slice(0)); CurrentLine.Buffer.Slice(0));
Lines.RemoveAt(CursorLine); Lines.RemoveAt(CursorLine);
SetCursor(CursorLine - 1, position); SetCursor(CursorLine - 1, position);
} else { } else {
MoveCursor(0, -count); MoveCursor(0, -count);
CurrentLineBuffer.Delete(CursorColumn, count); CurrentLine.Buffer.Delete(CursorColumn, count);
} }
} else { } else {
if (CursorColumn + count > CurrentLineBuffer.Tail && if (CursorColumn + count > CurrentLine.Buffer.Tail &&
CursorLine < Lines.Count - 1) { CursorLine < Lines.Count - 1) {
CurrentLineBuffer.Insert( CurrentLine.Buffer.Insert(
CurrentLineBuffer.Tail, CurrentLine.Buffer.Tail,
Lines[CursorLine + 1].Slice(0)); Lines[CursorLine + 1].Buffer.Slice(0));
Lines.RemoveAt(CursorLine + 1); Lines.RemoveAt(CursorLine + 1);
} }
CurrentLineBuffer.Delete(CursorColumn, count); CurrentLine.Buffer.Delete(CursorColumn, count);
} }
} }
@ -123,12 +129,12 @@ public class EditorFrameViewModel : ObservableObject
for (int i = 0; i < lines.Length; i++) { for (int i = 0; i < lines.Length; i++) {
if (i > 0) { if (i > 0) {
LineBuffer split = new LineBuffer( LineBuffer split = new LineBuffer(
CurrentLineBuffer.Slice(CursorColumn), CurrentLine.Buffer.Slice(CursorColumn),
CurrentLineBuffer.Encoding); CurrentLine.Buffer.Encoding);
Lines.Insert(CursorLine + 1, split); Lines.Insert(CursorLine + 1, new SelectableLineBuffer(split));
SetCursor(new BufferPosition(CursorLine + 1, 0)); SetCursor(new BufferPosition(CursorLine + 1, 0));
} }
CurrentLineBuffer.Insert(CursorColumn, lines[i]); CurrentLine.Buffer.Insert(CursorColumn, lines[i]);
if (follow) if (follow)
MoveCursor(new BufferPosition(0, lines[i].Length)); MoveCursor(new BufferPosition(0, lines[i].Length));
} }
@ -137,7 +143,7 @@ public class EditorFrameViewModel : ObservableObject
private BufferPosition AlignBufferPosition(BufferPosition position) private BufferPosition AlignBufferPosition(BufferPosition position)
{ {
int line = Math.Max(0, Math.Min(position.Line, Lines.Count - 1)); int line = Math.Max(0, Math.Min(position.Line, Lines.Count - 1));
LineBuffer buffer = Lines[line]; LineBuffer buffer = Lines[line].Buffer;
int column = Math.Max(0, Math.Min(position.Column, buffer.Tail)); int column = Math.Max(0, Math.Min(position.Column, buffer.Tail));
return new BufferPosition(line, column); return new BufferPosition(line, column);
} }