Browse Source

Fix TextBox invalidation

pull/3879/head
Benedikt Schroeder 6 years ago
parent
commit
6f3a1db9a6
  1. 46
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  2. 6
      src/Avalonia.Visuals/Media/FormattedText.cs
  3. 12
      src/Skia/Avalonia.Skia/FormattedTextImpl.cs

46
src/Avalonia.Controls/Presenters/TextPresenter.cs

@ -74,16 +74,15 @@ namespace Avalonia.Controls.Presenters
static TextPresenter()
{
AffectsRender<TextPresenter>(PasswordCharProperty,
SelectionBrushProperty, SelectionForegroundBrushProperty,
SelectionStartProperty, SelectionEndProperty);
AffectsRender<TextPresenter>(SelectionBrushProperty);
Observable.Merge(
TextProperty.Changed,
SelectionStartProperty.Changed,
SelectionEndProperty.Changed,
PasswordCharProperty.Changed
).AddClassHandler<TextPresenter>((x,_) => x.InvalidateFormattedText());
Observable.Merge(TextProperty.Changed, TextBlock.ForegroundProperty.Changed,
TextAlignmentProperty.Changed, TextWrappingProperty.Changed,
TextBlock.FontSizeProperty.Changed, TextBlock.FontStyleProperty.Changed,
TextBlock.FontWeightProperty.Changed, TextBlock.FontFamilyProperty.Changed,
SelectionStartProperty.Changed, SelectionEndProperty.Changed,
SelectionForegroundBrushProperty.Changed
).AddClassHandler<TextPresenter>((x, _) => x.InvalidateFormattedText());
CaretIndexProperty.Changed.AddClassHandler<TextPresenter>((x, e) => x.CaretIndexChanged((int)e.NewValue));
}
@ -184,7 +183,7 @@ namespace Avalonia.Controls.Presenters
{
get
{
return _formattedText ?? (_formattedText = CreateFormattedText(Bounds.Size, Text));
return _formattedText ?? (_formattedText = CreateFormattedText());
}
}
@ -219,7 +218,7 @@ namespace Avalonia.Controls.Presenters
get => GetValue(SelectionForegroundBrushProperty);
set => SetValue(SelectionForegroundBrushProperty, value);
}
public IBrush CaretBrush
{
get => GetValue(CaretBrushProperty);
@ -284,13 +283,9 @@ namespace Avalonia.Controls.Presenters
/// </summary>
protected void InvalidateFormattedText()
{
if (_formattedText != null)
{
_constraint = _formattedText.Constraint;
_formattedText = null;
}
_formattedText = null;
InvalidateVisual();
InvalidateMeasure();
}
/// <summary>
@ -307,6 +302,7 @@ namespace Avalonia.Controls.Presenters
}
FormattedText.Constraint = Bounds.Size;
context.DrawText(Foreground, new Point(), FormattedText);
}
@ -424,20 +420,20 @@ namespace Avalonia.Controls.Presenters
/// <summary>
/// Creates the <see cref="FormattedText"/> used to render the text.
/// </summary>
/// <param name="constraint">The constraint of the text.</param>
/// <param name="text">The text to generated the <see cref="FormattedText"/> for.</param>
/// <returns>A <see cref="FormattedText"/> object.</returns>
protected virtual FormattedText CreateFormattedText(Size constraint, string text)
protected virtual FormattedText CreateFormattedText()
{
FormattedText result = null;
var text = Text;
if (PasswordChar != default(char))
{
result = CreateFormattedTextInternal(constraint, new string(PasswordChar, text?.Length ?? 0));
result = CreateFormattedTextInternal(_constraint, new string(PasswordChar, text?.Length ?? 0));
}
else
{
result = CreateFormattedTextInternal(constraint, text);
result = CreateFormattedTextInternal(_constraint, text);
}
var selectionStart = SelectionStart;
@ -467,13 +463,15 @@ namespace Avalonia.Controls.Presenters
{
if (TextWrapping == TextWrapping.Wrap)
{
FormattedText.Constraint = new Size(availableSize.Width, double.PositiveInfinity);
_constraint = new Size(availableSize.Width, double.PositiveInfinity);
}
else
{
FormattedText.Constraint = Size.Infinity;
_constraint = Size.Infinity;
}
_formattedText = null;
return FormattedText.Bounds.Size;
}

6
src/Avalonia.Visuals/Media/FormattedText.cs

@ -200,7 +200,13 @@ namespace Avalonia.Media
private void Set<T>(ref T field, T value)
{
if (field != null && field.Equals(value))
{
return;
}
field = value;
_platformImpl = null;
}
}

12
src/Skia/Avalonia.Skia/FormattedTextImpl.cs

@ -149,7 +149,17 @@ namespace Avalonia.Skia
if (index >= Text.Length || index < 0)
{
var r = rects.LastOrDefault();
return new Rect(r.X + r.Width, r.Y, 0, _lineHeight);
var c = Text[Text.Length - 1];
switch (c)
{
case '\n':
case '\r':
return new Rect(r.X, r.Y, 0, _lineHeight);
default:
return new Rect(r.X + r.Width, r.Y, 0, _lineHeight);
}
}
return rects[index];
}

Loading…
Cancel
Save