qamp/Qrakhen.Qamp.Editor/Controls/Caret.cs

87 lines
2.3 KiB
C#

using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Threading;
namespace Qrakhen.Qamp.Editor.Controls;
public class Caret : Adorner
{
private readonly Pen _pen;
private readonly double _height;
private readonly Brush _brush;
private bool _blink;
private bool _enabled;
private Point _cursorPosition;
private Point _targetPosition;
private (Point from, Point to)[] _lines = [];
private DispatcherTimer _blinkTimer;
private DispatcherTimer _moveTimer;
public Caret(UIElement adornedElement, Brush brush, double height = 18, double thickness = 1.72) : base(adornedElement)
{
IsHitTestVisible = false;
_enabled = true;
_height = height;
_brush = brush;
_pen = new Pen(brush, 1.92);
_blinkTimer = new DispatcherTimer();
_blinkTimer.Interval = TimeSpan.FromMilliseconds(324);
_blinkTimer.Tick += new EventHandler((s, e) => {
Toggle(_blink = !_blink);
});
_blinkTimer.Start();
_moveTimer = new DispatcherTimer();
_moveTimer.Interval = TimeSpan.FromMilliseconds(12);
_moveTimer.Tick += new EventHandler((s, e) => {
var delta = _targetPosition - _cursorPosition;
if (delta.Length > 2.4)
_cursorPosition += delta * .84;
else {
_cursorPosition = _targetPosition;
_moveTimer.Stop();
_blinkTimer.Start();
}
InvalidateVisual();
});
}
public void Toggle(bool hide)
{
_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)
{
_lines = lines;
InvalidateVisual();
}
public void UpdatePosition(Point newPosition)
{
_cursorPosition = _targetPosition = newPosition;
_enabled = true;
Toggle(_blink = false);
_blinkTimer.Start();
}
protected override void OnRender(DrawingContext drawingContext)
{
Point startPoint = new(_cursorPosition.X, _cursorPosition.Y);
Point endPoint = new(_cursorPosition.X, _cursorPosition.Y + _height);
drawingContext.DrawLine(_pen, startPoint, endPoint);
}
}