qamp/Qrakhen.Qamp.Editor/Controls/LineRenderer.xaml.cs

118 lines
3.6 KiB
C#

using Qrakhen.Qamp.Memory;
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Qrakhen.Qamp.Editor.Controls;
public partial class LineRenderer : UserControl
{
private readonly Typeface _typeface = new(new FontFamily("Consolas"), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
private const double FontSize = 14;
private const double LineHeight = 18;
public Pen Pen { get; set; }
public Brush Highlighter { get; set; }
public LineRenderer()
{
Height = LineHeight;
SnapsToDevicePixels = true;
Highlighter = new SolidColorBrush(Color.FromArgb(0xff, 0x24, 0x92, 0x72));
Pen = new Pen(Highlighter, 2);
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
if (string.IsNullOrEmpty(LineBuffer.Cached))
return;
var formattedText = TextHelper.GetText(
LineBuffer.Cached,
FontSize,
Brushes.White,
VisualTreeHelper.GetDpi(this).PixelsPerDip
);
var x = Random.Shared.Next(0, LineBuffer.Tail);
var s = new BufferSpan(x, Random.Shared.Next(x, LineBuffer.Tail));
Selection = s;
var highlighter = TextHelper.GetText(
new string(' ', Selection.Start) + new string('█', Selection.End - Selection.Start),
FontSize,
Highlighter,
VisualTreeHelper.GetDpi(this).PixelsPerDip
);
drawingContext.DrawText(highlighter, new Point(2, 0));
drawingContext.DrawText(formattedText, new Point(2, 0));
}
public static readonly DependencyProperty LineBufferProperty =
DependencyProperty.Register(
nameof(LineBuffer),
typeof(LineBuffer),
typeof(LineRenderer),
new FrameworkPropertyMetadata(null, OnLineBufferChanged));
public LineBuffer LineBuffer {
get => (LineBuffer)GetValue(LineBufferProperty);
set => SetValue(LineBufferProperty, value);
}
private static void OnLineBufferChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is LineRenderer renderer) {
if (e.OldValue is LineBuffer oldBuffer && oldBuffer != null) {
oldBuffer.PropertyChanged -= renderer.OnLineBufferPropertyChanged;
}
if (e.NewValue is LineBuffer newBuffer && newBuffer != null) {
newBuffer.PropertyChanged += renderer.OnLineBufferPropertyChanged;
}
renderer.InvalidateVisual();
}
}
private void OnLineBufferPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(LineBuffer.Cached))
InvalidateVisual();
}
public static readonly DependencyProperty SelectionProperty =
DependencyProperty.Register(
nameof(Selection),
typeof(BufferSpan),
typeof(LineRenderer),
new FrameworkPropertyMetadata(BufferSpan.None, OnSelectionChanged));
public BufferSpan Selection {
get => (BufferSpan)GetValue(SelectionProperty);
set => SetValue(SelectionProperty, value);
}
private static void OnSelectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is LineRenderer renderer) {
if (e.OldValue is LineBuffer oldBuffer && oldBuffer != null) {
oldBuffer.PropertyChanged -= renderer.OnLineBufferPropertyChanged;
}
if (e.NewValue is LineBuffer newBuffer && newBuffer != null) {
newBuffer.PropertyChanged += renderer.OnLineBufferPropertyChanged;
}
renderer.InvalidateVisual();
}
}
}