Browse Source

Added CaretBlinkInterval to TextPresenter (#13685)

* Added CaretBlinkInterval to TextPresenter

* TextPresenter CaretBlinkInterval property exposed through TextBox

* Added PropertyChanged handler for CaretBlinkInterval

* CaretBlinkInterval datatype changed from int to TimeSpan

* Added CaretBlinkInterval comments

* TextBox.CaretBlinkInterval comment changed to inherit from TextPresenter.CaretBlinkInterval

* AddOwner given to CaretBlinkInterval in TextPresenter

---------

Co-authored-by: Benedikt Stebner <Gillibald@users.noreply.github.com>
pull/13795/head
Samuel Turner-Lill 3 years ago
committed by GitHub
parent
commit
d220487073
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 76
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  2. 13
      src/Avalonia.Controls/TextBox.cs
  3. 1
      src/Avalonia.Themes.Fluent/Controls/TextBox.xaml
  4. 1
      src/Avalonia.Themes.Simple/Controls/TextBox.xaml

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

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data;
using Avalonia.Controls.Documents;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
@ -34,6 +35,9 @@ namespace Avalonia.Controls.Presenters
public static readonly StyledProperty<IBrush?> CaretBrushProperty =
AvaloniaProperty.Register<TextPresenter, IBrush?>(nameof(CaretBrush));
public static readonly StyledProperty<TimeSpan> CaretBlinkIntervalProperty =
TextBox.CaretBlinkIntervalProperty.AddOwner<TextPresenter>();
public static readonly StyledProperty<int> SelectionStartProperty =
TextBox.SelectionStartProperty.AddOwner<TextPresenter>(new(coerce: TextBox.CoerceCaretIndex));
@ -88,7 +92,7 @@ namespace Avalonia.Controls.Presenters
public static readonly StyledProperty<IBrush?> BackgroundProperty =
Border.BackgroundProperty.AddOwner<TextPresenter>();
private readonly DispatcherTimer _caretTimer;
private DispatcherTimer? _caretTimer;
private bool _caretBlink;
private TextLayout? _textLayout;
private Size _constraint;
@ -104,10 +108,7 @@ namespace Avalonia.Controls.Presenters
AffectsRender<TextPresenter>(CaretBrushProperty, SelectionBrushProperty, TextElement.ForegroundProperty);
}
public TextPresenter()
{
_caretTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(500) };
}
public TextPresenter() { }
public event EventHandler? CaretBoundsChanged;
@ -288,6 +289,15 @@ namespace Avalonia.Controls.Presenters
set => SetValue(CaretBrushProperty, value);
}
/// <summary>
/// Gets or sets the caret blink rate
/// </summary>
public TimeSpan CaretBlinkInterval
{
get => GetValue(CaretBlinkIntervalProperty);
set => SetValue(CaretBlinkIntervalProperty, value);
}
public int SelectionStart
{
get => GetValue(SelectionStartProperty);
@ -443,7 +453,7 @@ namespace Avalonia.Controls.Presenters
public void ShowCaret()
{
_caretBlink = true;
_caretTimer.Start();
_caretTimer?.Start();
InvalidateVisual();
}
@ -454,7 +464,7 @@ namespace Avalonia.Controls.Presenters
{
TextSelectionHandleCanvas.ShowHandles = false;
}
_caretTimer.Stop();
_caretTimer?.Stop();
InvalidateVisual();
}
@ -465,18 +475,18 @@ namespace Avalonia.Controls.Presenters
return;
}
if (_caretTimer.IsEnabled)
if (_caretTimer?.IsEnabled ?? false)
{
_caretBlink = true;
_caretTimer.Stop();
_caretTimer.Start();
_caretTimer?.Stop();
_caretTimer?.Start();
InvalidateVisual();
}
else
{
_caretTimer.Start();
_caretTimer?.Start();
InvalidateVisual();
_caretTimer.Stop();
_caretTimer?.Stop();
}
if (IsMeasureValid)
@ -716,6 +726,33 @@ namespace Avalonia.Controls.Presenters
CaretChanged();
}
private void ResetCaretTimer()
{
bool isEnabled = false;
if (_caretTimer != null)
{
_caretTimer.Tick -= CaretTimerTick;
if (_caretTimer.IsEnabled)
{
_caretTimer.Stop();
isEnabled = true;
}
_caretTimer = null;
}
if (CaretBlinkInterval.TotalMilliseconds > 0)
{
_caretTimer = new DispatcherTimer { Interval = CaretBlinkInterval };
_caretTimer.Tick += CaretTimerTick;
if (isEnabled)
_caretTimer.Start();
}
}
public CharacterHit GetNextCharacterHit(LogicalDirection direction = LogicalDirection.Forward)
{
if (Text is null)
@ -855,7 +892,7 @@ namespace Avalonia.Controls.Presenters
{
base.OnAttachedToVisualTree(e);
_caretTimer.Tick += CaretTimerTick;
ResetCaretTimer();
if (TextSelectionHandleCanvas is { } canvas && _layer != null && !_layer.Children.Contains(canvas))
_layer?.Add(TextSelectionHandleCanvas);
@ -882,9 +919,11 @@ namespace Avalonia.Controls.Presenters
c.SetPresenter(null);
}
_caretTimer.Stop();
_caretTimer.Tick -= CaretTimerTick;
if (_caretTimer != null)
{
_caretTimer.Stop();
_caretTimer.Tick -= CaretTimerTick;
}
}
private void OnPreeditChanged(string? preeditText, int? cursorPosition)
@ -939,6 +978,11 @@ namespace Avalonia.Controls.Presenters
}
}
if (change.Property == CaretBlinkIntervalProperty)
{
ResetCaretTimer();
}
switch (change.Property.Name)
{
case nameof(PreeditText):

13
src/Avalonia.Controls/TextBox.cs

@ -92,6 +92,12 @@ namespace Avalonia.Controls
public static readonly StyledProperty<IBrush?> CaretBrushProperty =
AvaloniaProperty.Register<TextBox, IBrush?>(nameof(CaretBrush));
/// <summary>
/// Defines the <see cref="CaretBlinkInterval"/> property
/// </summary>
public static readonly StyledProperty<TimeSpan> CaretBlinkIntervalProperty =
AvaloniaProperty.Register<TextBox, TimeSpan>(nameof(CaretBlinkInterval), defaultValue: TimeSpan.FromMilliseconds(500));
/// <summary>
/// Defines the <see cref="SelectionStart"/> property
/// </summary>
@ -443,6 +449,13 @@ namespace Avalonia.Controls
set => SetValue(CaretBrushProperty, value);
}
/// <inheritdoc cref="TextPresenter.CaretBlinkInterval"/>
public TimeSpan CaretBlinkInterval
{
get => GetValue(CaretBlinkIntervalProperty);
set => SetValue(CaretBlinkIntervalProperty, value);
}
/// <summary>
/// Gets or sets the starting position of the text selected in the TextBox
/// </summary>

1
src/Avalonia.Themes.Fluent/Controls/TextBox.xaml

@ -155,6 +155,7 @@
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<TextPresenter Name="PART_TextPresenter"
Text="{TemplateBinding Text, Mode=TwoWay}"
CaretBlinkInterval="{TemplateBinding CaretBlinkInterval}"
CaretIndex="{TemplateBinding CaretIndex}"
SelectionStart="{TemplateBinding SelectionStart}"
SelectionEnd="{TemplateBinding SelectionEnd}"

1
src/Avalonia.Themes.Simple/Controls/TextBox.xaml

@ -143,6 +143,7 @@
TextAlignment="{TemplateBinding TextAlignment}"
TextWrapping="{TemplateBinding TextWrapping}" />
<TextPresenter Name="PART_TextPresenter"
CaretBlinkInterval="{TemplateBinding CaretBlinkInterval}"
CaretBrush="{TemplateBinding CaretBrush}"
CaretIndex="{TemplateBinding CaretIndex}"
LineHeight="{TemplateBinding LineHeight}"

Loading…
Cancel
Save