csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
3.2 KiB
104 lines
3.2 KiB
// -----------------------------------------------------------------------
|
|
// <copyright file="TextBoxView.cs" company="Steven Kirk">
|
|
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|
// </copyright>
|
|
// -----------------------------------------------------------------------
|
|
|
|
namespace Perspex.Controls
|
|
{
|
|
using System;
|
|
using System.Reactive.Linq;
|
|
using Perspex.Media;
|
|
using Perspex.Threading;
|
|
|
|
internal class TextBoxView : TextBlock
|
|
{
|
|
private TextBox parent;
|
|
|
|
private DispatcherTimer caretTimer;
|
|
|
|
private bool caretBlink;
|
|
|
|
public TextBoxView(TextBox parent)
|
|
{
|
|
this.caretTimer = new DispatcherTimer();
|
|
this.caretTimer.Interval = TimeSpan.FromMilliseconds(500);
|
|
this.caretTimer.Tick += this.CaretTimerTick;
|
|
this.parent = parent;
|
|
this[!TextProperty] = parent[!TextProperty];
|
|
this[!TextWrappingProperty] = parent[!TextWrappingProperty];
|
|
|
|
Observable.Merge(
|
|
this.parent.GetObservable(TextBox.SelectionStartProperty),
|
|
this.parent.GetObservable(TextBox.SelectionEndProperty))
|
|
.Subscribe(_ => this.InvalidateVisual());
|
|
|
|
parent.GetObservable(TextBox.CaretIndexProperty).Subscribe(_ => this.CaretMoved());
|
|
}
|
|
|
|
public int GetCaretIndex(Point point)
|
|
{
|
|
var hit = this.FormattedText.HitTestPoint(point);
|
|
return hit.TextPosition + (hit.IsTrailing ? 1 : 0);
|
|
}
|
|
|
|
public new void GotFocus()
|
|
{
|
|
this.caretBlink = true;
|
|
this.caretTimer.Start();
|
|
}
|
|
|
|
public new void LostFocus()
|
|
{
|
|
this.caretTimer.Stop();
|
|
this.InvalidateVisual();
|
|
}
|
|
|
|
public override void Render(IDrawingContext context)
|
|
{
|
|
var selectionStart = this.parent.SelectionStart;
|
|
var selectionEnd = this.parent.SelectionEnd;
|
|
|
|
if (selectionStart != selectionEnd)
|
|
{
|
|
var start = Math.Min(selectionStart, selectionEnd);
|
|
var length = Math.Max(selectionStart, selectionEnd) - start;
|
|
var rects = this.FormattedText.HitTestTextRange(start, length);
|
|
|
|
var brush = new SolidColorBrush(0xff086f9e);
|
|
|
|
foreach (var rect in rects)
|
|
{
|
|
context.FillRectange(brush, rect);
|
|
}
|
|
}
|
|
|
|
base.Render(context);
|
|
|
|
if (this.parent.IsFocused)
|
|
{
|
|
var charPos = this.FormattedText.HitTestTextPosition(this.parent.CaretIndex);
|
|
Brush caretBrush = Brushes.Black;
|
|
|
|
if (this.caretBlink)
|
|
{
|
|
context.DrawLine(new Pen(caretBrush, 1), charPos.TopLeft, charPos.BottomLeft);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void CaretMoved()
|
|
{
|
|
this.caretBlink = true;
|
|
this.caretTimer.Stop();
|
|
this.caretTimer.Start();
|
|
this.InvalidateVisual();
|
|
}
|
|
|
|
private void CaretTimerTick(object sender, EventArgs e)
|
|
{
|
|
this.caretBlink = !this.caretBlink;
|
|
this.InvalidateVisual();
|
|
}
|
|
}
|
|
}
|
|
|