editor line numbers

This commit is contained in:
Qrakhen 2025-11-23 00:14:56 +01:00
parent b3385c0860
commit 2f10015229
5 changed files with 65 additions and 14 deletions

View File

@ -3,6 +3,10 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Qrakhen.Qamp.Editor"> xmlns:local="clr-namespace:Qrakhen.Qamp.Editor">
<Application.Resources> <Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Converters/Converters.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources> </Application.Resources>
</Application> </Application>

View File

@ -4,11 +4,12 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Qrakhen.Qamp.Editor.Controls" xmlns:local="clr-namespace:Qrakhen.Qamp.Editor.Controls"
xmlns:converters="clr-namespace:Qrakhen.Qamp.Editor.Converters"
mc:Ignorable="d" mc:Ignorable="d"
Background="#161718" Background="#222324"
Focusable="True" Focusable="True"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Style> <UserControl.Style>
<Style TargetType="{x:Type local:EditorFrame}"> <Style TargetType="{x:Type local:EditorFrame}">
<Setter Property="CursorPosition" Value="{Binding CursorPosition}" /> <Setter Property="CursorPosition" Value="{Binding CursorPosition}" />
@ -21,20 +22,35 @@
HorizontalScrollBarVisibility="Auto"> HorizontalScrollBarVisibility="Auto">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="32" /> <ColumnDefinition Width="48" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ListBox x:Name="LinesList" <ListBox x:Name="LineNumbers"
Grid.Column="0" Grid.Column="0"
ItemsSource="{Binding Lines.Count}" ItemsSource="{Binding Lines.Count, Converter={StaticResource LineCountConverter}}"
IsHitTestVisible="False" IsHitTestVisible="False"
Background="#121314" Background="#101112"
Foreground="#969696" Foreground="#92989f"
BorderThickness="0" BorderThickness="0"
Padding="0,0,5,0" Padding="0"
Margin="0,-2,0,0"
VerticalContentAlignment="Top" VerticalContentAlignment="Top"
HorizontalContentAlignment="Right"/> HorizontalContentAlignment="Right">
<ItemsControl ItemsSource="{Binding Lines}" <ListBox.ItemTemplate>
<ItemContainerTemplate>
<TextBlock Height="14"
LineHeight="18"
Margin="0"
Padding="0"
FontFamily="Consolas"
FontSize="14"
Text="{Binding}"></TextBlock>
</ItemContainerTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ItemsControl x:Name="LineList"
Padding="3,0,0,0"
ItemsSource="{Binding Lines}"
Grid.Column="1"> Grid.Column="1">
<ItemsControl.ItemsPanel> <ItemsControl.ItemsPanel>
<ItemsPanelTemplate> <ItemsPanelTemplate>

View File

@ -84,7 +84,7 @@ public partial class EditorFrame : UserControl
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(LineList, 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.");
@ -95,13 +95,13 @@ public partial class EditorFrame : UserControl
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 - 34) / ft.Width)); return new BufferPosition((int)(point.Y / TextHelper.LineHeight), (int)((point.X - 2) / 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); var ft = TextHelper.GetText(new string('_', index), 14, null, VisualTreeHelper.GetDpi(this).PixelsPerDip);
return new Point(ft.Width - scrollX + 34, line * TextHelper.LineHeight - scrollY); return new Point(ft.Width + 2, line * TextHelper.LineHeight);
} }
private void MoveCaret(Point point) private void MoveCaret(Point point)

View File

@ -0,0 +1,5 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Qrakhen.Qamp.Editor.Converters">
<local:LineCountConverter x:Key="LineCountConverter" />
</ResourceDictionary>

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Windows.Data;
namespace Qrakhen.Qamp.Editor.Converters;
public class LineCountConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is int count) {
var counts = new int[count];
for (int i = 0; ++i <= count;)
counts[i - 1] = i;
return counts;
}
return new int[0];
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}