// -----------------------------------------------------------------------
//
// Copyright 2013 MIT Licence. See licence.md for more information.
//
// -----------------------------------------------------------------------
namespace Perspex.Controls
{
using System;
using Perspex.Media;
using Perspex.Platform;
using Perspex.Threading;
using Splat;
internal class TextBoxView : Control
{
private TextBox parent;
private FormattedText formattedText;
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;
}
public FormattedText FormattedText
{
get
{
if (this.formattedText == null)
{
this.formattedText = this.CreateFormattedText();
}
return this.formattedText;
}
}
public new void GotFocus()
{
this.caretBlink = true;
this.caretTimer.Start();
}
public new void LostFocus()
{
this.caretTimer.Stop();
this.InvalidateVisual();
}
public void InvalidateText()
{
this.formattedText = null;
this.InvalidateMeasure();
}
public override void Render(IDrawingContext context)
{
Rect rect = new Rect(this.ActualSize);
context.DrawText(Brushes.Black, rect, this.FormattedText);
if (this.parent.IsFocused)
{
ITextService textService = Locator.Current.GetService();
Point caretPos = textService.GetCaretPosition(
this.formattedText,
this.parent.CaretIndex,
this.ActualSize);
double[] lineHeights = textService.GetLineHeights(this.formattedText, this.ActualSize);
Brush caretBrush = Brushes.Black;
if (this.caretBlink)
{
context.DrawLine(
new Pen(caretBrush, 1),
caretPos,
new Point(caretPos.X, caretPos.Y + lineHeights[0]));
}
}
}
internal void CaretMoved()
{
this.caretBlink = true;
this.caretTimer.Stop();
this.caretTimer.Start();
this.InvalidateVisual();
}
protected override Size MeasureOverride(Size constraint)
{
if (!string.IsNullOrEmpty(this.parent.Text))
{
ITextService textService = Locator.Current.GetService();
return textService.Measure(this.FormattedText, constraint);
}
return new Size();
}
private FormattedText CreateFormattedText()
{
return new FormattedText
{
FontFamilyName = "Segoe UI",
FontSize = this.GetValue(TextBlock.FontSizeProperty),
FontStyle = this.GetValue(TextBlock.FontStyleProperty),
Text = this.parent.Text,
};
}
private void CaretTimerTick(object sender, EventArgs e)
{
this.caretBlink = !this.caretBlink;
this.InvalidateVisual();
}
}
}