feat: inherit font properties.

This commit is contained in:
rabbitism
2024-02-17 15:53:42 +08:00
parent e7b99842bc
commit 40454bcfe0
3 changed files with 56 additions and 31 deletions

View File

@@ -1,17 +1,23 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="Ursa.Demo.Pages.NumberDisplayerDemo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns="https://github.com/avaloniaui"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:u="https://irihi.tech/ursa" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="using:Ursa.Demo.ViewModels" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:DataType="vm:NumberDisplayerDemoViewModel" xmlns:u="https://irihi.tech/ursa"
x:CompileBindings="True" xmlns:vm="using:Ursa.Demo.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" d:DesignHeight="450"
x:Class="Ursa.Demo.Pages.NumberDisplayerDemo"> d:DesignWidth="800"
x:CompileBindings="True"
x:DataType="vm:NumberDisplayerDemoViewModel"
mc:Ignorable="d">
<StackPanel HorizontalAlignment="Left"> <StackPanel HorizontalAlignment="Left">
<Button Command="{Binding IncreaseCommand}" >Change</Button> <Button Command="{Binding IncreaseCommand}">Change</Button>
<u:Int32Displayer Value="{Binding Value}"></u:Int32Displayer> <u:Int32Displayer Value="{Binding Value}" />
<u:DoubleDisplayer Value="{Binding DoubleValue}" StringFormat="N2"></u:DoubleDisplayer> <u:DoubleDisplayer StringFormat="N2" Value="{Binding DoubleValue}" />
<u:DateDisplay Value="{Binding DateValue}" StringFormat="yyyy-MM-dd"></u:DateDisplay> <u:DateDisplay
FontSize="30"
StringFormat="yyyy-MM-dd"
Value="{Binding DateValue}" />
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View File

@@ -8,7 +8,16 @@
<Setter Property="Duration" Value="0:0:0.2" /> <Setter Property="Duration" Value="0:0:0.2" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate TargetType="u:NumberDisplayerBase"> <ControlTemplate TargetType="u:NumberDisplayerBase">
<TextBlock Text="{TemplateBinding InternalText, Mode=OneWay}" /> <TextBlock
FontSize="{TemplateBinding FontSize}"
Foreground="{TemplateBinding Foreground}"
FontFamily="{TemplateBinding FontFamily}"
Background="{TemplateBinding Background}"
FontWeight="{TemplateBinding FontWeight}"
FontStyle="{TemplateBinding FontSize}"
FontStretch="{TemplateBinding FontStretch}"
Text="{TemplateBinding InternalText,
Mode=OneWay}" />
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
</ControlTheme> </ControlTheme>

View File

@@ -1,8 +1,10 @@
using Avalonia; using Avalonia;
using Avalonia.Animation; using Avalonia.Animation;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Documents;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Media;
using Avalonia.Styling; using Avalonia.Styling;
namespace Ursa.Controls; namespace Ursa.Controls;
@@ -13,7 +15,7 @@ public abstract class NumberDisplayerBase : TemplatedControl
nameof(InternalText), o => o.InternalText, (o, v) => o.InternalText = v); nameof(InternalText), o => o.InternalText, (o, v) => o.InternalText = v);
private string _internalText; private string _internalText;
public string InternalText internal string InternalText
{ {
get => _internalText; get => _internalText;
set => SetAndRaise(InternalTextProperty, ref _internalText, value); set => SetAndRaise(InternalTextProperty, ref _internalText, value);
@@ -51,11 +53,11 @@ public abstract class NumberDisplayer<T>: NumberDisplayerBase
get => GetValue(ValueProperty); get => GetValue(ValueProperty);
set => SetValue(ValueProperty, value); set => SetValue(ValueProperty, value);
} }
public static readonly StyledProperty<T?> InternalValueProperty = AvaloniaProperty.Register<NumberDisplayer<T>, T?>(
nameof(InternalValue));
public T? InternalValue private static readonly StyledProperty<T?> InternalValueProperty = AvaloniaProperty.Register<NumberDisplayer<T>, T?>(
nameof(InternalValue), defaultBindingMode:BindingMode.TwoWay);
private T? InternalValue
{ {
get => GetValue(InternalValueProperty); get => GetValue(InternalValueProperty);
set => SetValue(InternalValueProperty, value); set => SetValue(InternalValueProperty, value);
@@ -73,13 +75,15 @@ public abstract class NumberDisplayer<T>: NumberDisplayerBase
}); });
DurationProperty.Changed.AddClassHandler<NumberDisplayer<T>, TimeSpan>((item, args) =>item.OnDurationChanged(args)); DurationProperty.Changed.AddClassHandler<NumberDisplayer<T>, TimeSpan>((item, args) =>item.OnDurationChanged(args));
} }
protected override void OnInitialized() protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{ {
base.OnInitialized(); base.OnApplyTemplate(e);
_animation = new Animation(); _animation = new Animation
_animation.Duration = Duration; {
_animation.FillMode = FillMode.Forward; Duration = Duration,
FillMode = FillMode.Forward
};
_animation.Children.Add(new KeyFrame() _animation.Children.Add(new KeyFrame()
{ {
Cue = new Cue(0.0), Cue = new Cue(0.0),
@@ -92,7 +96,9 @@ public abstract class NumberDisplayer<T>: NumberDisplayerBase
}); });
Animation.SetAnimator(_animation.Children[0].Setters[0], GetAnimator()); Animation.SetAnimator(_animation.Children[0].Setters[0], GetAnimator());
Animation.SetAnimator(_animation.Children[1].Setters[0], GetAnimator()); Animation.SetAnimator(_animation.Children[1].Setters[0], GetAnimator());
InternalValue = Value;
// Display value directly to text on initialization in case value equals to default.
SetCurrentValue(InternalTextProperty, this.GetString(Value));
} }
private void OnDurationChanged(AvaloniaPropertyChangedEventArgs<TimeSpan> args) private void OnDurationChanged(AvaloniaPropertyChangedEventArgs<TimeSpan> args)
@@ -101,9 +107,13 @@ public abstract class NumberDisplayer<T>: NumberDisplayerBase
_animation.Duration = args.NewValue.Value; _animation.Duration = args.NewValue.Value;
} }
protected virtual void OnValueChanged(T? oldValue, T? newValue) private void OnValueChanged(T? oldValue, T? newValue)
{ {
if (_animation is null) return; if (_animation is null)
{
SetCurrentValue(InternalValueProperty, newValue);
return;
}
_cts.Cancel(); _cts.Cancel();
_cts = new CancellationTokenSource(); _cts = new CancellationTokenSource();
(_animation.Children[0].Setters[0] as Setter)!.Value = oldValue; (_animation.Children[0].Setters[0] as Setter)!.Value = oldValue;
@@ -119,7 +129,6 @@ public abstract class NumberDisplayer<T>: NumberDisplayerBase
public class Int32Displayer : NumberDisplayer<int> public class Int32Displayer : NumberDisplayer<int>
{ {
protected override Type StyleKeyOverride { get; } = typeof(NumberDisplayerBase); protected override Type StyleKeyOverride { get; } = typeof(NumberDisplayerBase);
protected override InterpolatingAnimator<int> GetAnimator() protected override InterpolatingAnimator<int> GetAnimator()
{ {
@@ -176,7 +185,8 @@ public class DateDisplay : NumberDisplayer<DateTime>
{ {
public override DateTime Interpolate(double progress, DateTime oldValue, DateTime newValue) public override DateTime Interpolate(double progress, DateTime oldValue, DateTime newValue)
{ {
return oldValue + TimeSpan.FromTicks((long)((newValue - oldValue).Ticks * progress)); var diff = (newValue - oldValue).TotalSeconds;
return oldValue + TimeSpan.FromSeconds(diff * progress);
} }
} }