From df22fb29bc5125aee5e9ceb498145eed8ae1036b Mon Sep 17 00:00:00 2001 From: Jumar Macato <16554748+jmacato@users.noreply.github.com> Date: Mon, 29 May 2023 19:39:33 +0800 Subject: [PATCH 1/4] move IndeterminateStarting/EndingOffset to TemplateSettings. --- src/Avalonia.Controls/ProgressBar.cs | 141 ++++++++---------- .../Controls/ProgressBar.xaml | 8 +- 2 files changed, 70 insertions(+), 79 deletions(-) diff --git a/src/Avalonia.Controls/ProgressBar.cs b/src/Avalonia.Controls/ProgressBar.cs index 7dcdaa2f8d..47c51fb839 100644 --- a/src/Avalonia.Controls/ProgressBar.cs +++ b/src/Avalonia.Controls/ProgressBar.cs @@ -32,29 +32,33 @@ namespace Avalonia.Controls private double _container2AnimationStartPosition; private double _container2AnimationEndPosition; - public static readonly DirectProperty ContainerAnimationStartPositionProperty = - AvaloniaProperty.RegisterDirect( - nameof(ContainerAnimationStartPosition), - p => p.ContainerAnimationStartPosition, - (p, o) => p.ContainerAnimationStartPosition = o, 0d); - - public static readonly DirectProperty ContainerAnimationEndPositionProperty = - AvaloniaProperty.RegisterDirect( - nameof(ContainerAnimationEndPosition), - p => p.ContainerAnimationEndPosition, - (p, o) => p.ContainerAnimationEndPosition = o, 0d); - - public static readonly DirectProperty Container2AnimationStartPositionProperty = - AvaloniaProperty.RegisterDirect( - nameof(Container2AnimationStartPosition), - p => p.Container2AnimationStartPosition, - (p, o) => p.Container2AnimationStartPosition = o, 0d); - - public static readonly DirectProperty Container2AnimationEndPositionProperty = - AvaloniaProperty.RegisterDirect( - nameof(Container2AnimationEndPosition), - p => p.Container2AnimationEndPosition, - (p, o) => p.Container2AnimationEndPosition = o); + public static readonly DirectProperty + ContainerAnimationStartPositionProperty = + AvaloniaProperty.RegisterDirect( + nameof(ContainerAnimationStartPosition), + p => p.ContainerAnimationStartPosition, + (p, o) => p.ContainerAnimationStartPosition = o); + + public static readonly DirectProperty + ContainerAnimationEndPositionProperty = + AvaloniaProperty.RegisterDirect( + nameof(ContainerAnimationEndPosition), + p => p.ContainerAnimationEndPosition, + (p, o) => p.ContainerAnimationEndPosition = o); + + public static readonly DirectProperty + Container2AnimationStartPositionProperty = + AvaloniaProperty.RegisterDirect( + nameof(Container2AnimationStartPosition), + p => p.Container2AnimationStartPosition, + (p, o) => p.Container2AnimationStartPosition = o); + + public static readonly DirectProperty + Container2AnimationEndPositionProperty = + AvaloniaProperty.RegisterDirect( + nameof(Container2AnimationEndPosition), + p => p.Container2AnimationEndPosition, + (p, o) => p.Container2AnimationEndPosition = o); public static readonly DirectProperty Container2WidthProperty = AvaloniaProperty.RegisterDirect( @@ -68,10 +72,17 @@ namespace Avalonia.Controls p => p.ContainerWidth, (p, o) => p.ContainerWidth = o); + public static readonly StyledProperty IndeterminateStartingOffsetProperty = + AvaloniaProperty.Register(nameof(IndeterminateStartingOffset)); + + public static readonly StyledProperty IndeterminateEndingOffsetProperty = + AvaloniaProperty.Register(nameof(IndeterminateEndingOffset)); + public double ContainerAnimationStartPosition { get => _containerAnimationStartPosition; - set => SetAndRaise(ContainerAnimationStartPositionProperty, ref _containerAnimationStartPosition, value); + set => SetAndRaise(ContainerAnimationStartPositionProperty, ref _containerAnimationStartPosition, + value); } public double ContainerAnimationEndPosition @@ -83,7 +94,8 @@ namespace Avalonia.Controls public double Container2AnimationStartPosition { get => _container2AnimationStartPosition; - set => SetAndRaise(Container2AnimationStartPositionProperty, ref _container2AnimationStartPosition, value); + set => SetAndRaise(Container2AnimationStartPositionProperty, ref _container2AnimationStartPosition, + value); } public double Container2Width @@ -103,6 +115,18 @@ namespace Avalonia.Controls get => _container2AnimationEndPosition; set => SetAndRaise(Container2AnimationEndPositionProperty, ref _container2AnimationEndPosition, value); } + + public double IndeterminateStartingOffset + { + get => GetValue(IndeterminateStartingOffsetProperty); + set => SetValue(IndeterminateStartingOffsetProperty, value); + } + + public double IndeterminateEndingOffset + { + get => GetValue(IndeterminateEndingOffsetProperty); + set => SetValue(IndeterminateEndingOffsetProperty, value); + } } private double _percentage; @@ -131,7 +155,7 @@ namespace Avalonia.Controls /// Defines the property. /// public static readonly StyledProperty OrientationProperty = - AvaloniaProperty.Register(nameof(Orientation), Orientation.Horizontal); + AvaloniaProperty.Register(nameof(Orientation)); /// /// Defines the property. @@ -141,18 +165,6 @@ namespace Avalonia.Controls nameof(Percentage), o => o.Percentage); - /// - /// Defines the property. - /// - public static readonly StyledProperty IndeterminateStartingOffsetProperty = - AvaloniaProperty.Register(nameof(IndeterminateStartingOffset)); - - /// - /// Defines the property. - /// - public static readonly StyledProperty IndeterminateEndingOffsetProperty = - AvaloniaProperty.Register(nameof(IndeterminateEndingOffset)); - /// /// Gets the overall percentage complete of the progress /// @@ -166,26 +178,14 @@ namespace Avalonia.Controls private set { SetAndRaise(PercentageProperty, ref _percentage, value); } } - public double IndeterminateStartingOffset - { - get => GetValue(IndeterminateStartingOffsetProperty); - set => SetValue(IndeterminateStartingOffsetProperty, value); - } - - public double IndeterminateEndingOffset - { - get => GetValue(IndeterminateEndingOffsetProperty); - set => SetValue(IndeterminateEndingOffsetProperty, value); - } - static ProgressBar() { ValueProperty.OverrideMetadata(new(defaultBindingMode: BindingMode.OneWay)); - ValueProperty.Changed.AddClassHandler((x, e) => x.UpdateIndicatorWhenPropChanged(e)); - MinimumProperty.Changed.AddClassHandler((x, e) => x.UpdateIndicatorWhenPropChanged(e)); - MaximumProperty.Changed.AddClassHandler((x, e) => x.UpdateIndicatorWhenPropChanged(e)); - IsIndeterminateProperty.Changed.AddClassHandler((x, e) => x.UpdateIndicatorWhenPropChanged(e)); - OrientationProperty.Changed.AddClassHandler((x, e) => x.UpdateIndicatorWhenPropChanged(e)); + ValueProperty.Changed.AddClassHandler((x, _) => x.UpdateIndicatorWhenPropChanged()); + MinimumProperty.Changed.AddClassHandler((x, _) => x.UpdateIndicatorWhenPropChanged()); + MaximumProperty.Changed.AddClassHandler((x, _) => x.UpdateIndicatorWhenPropChanged()); + IsIndeterminateProperty.Changed.AddClassHandler((x, _) => x.UpdateIndicatorWhenPropChanged()); + OrientationProperty.Changed.AddClassHandler((x, _) => x.UpdateIndicatorWhenPropChanged()); } /// @@ -305,22 +305,14 @@ namespace Avalonia.Controls TemplateSettings.Container2AnimationStartPosition = barIndicatorWidth2 * -1.5; // Position at -150% TemplateSettings.Container2AnimationEndPosition = barIndicatorWidth2 * 1.66; // Position at 166% - // Remove these properties when we switch to fluent as default and removed the old one. - SetCurrentValue(IndeterminateStartingOffsetProperty,-dim); - SetCurrentValue(IndeterminateEndingOffsetProperty,dim); - - var padding = Padding; - var rectangle = new RectangleGeometry( - new Rect( - padding.Left, - padding.Top, - barSize.Width - (padding.Right + padding.Left), - barSize.Height - (padding.Bottom + padding.Top) - )); + TemplateSettings.IndeterminateStartingOffset = -dim; + TemplateSettings.IndeterminateEndingOffset = dim; } else { - double percent = Maximum == Minimum ? 1.0 : (Value - Minimum) / (Maximum - Minimum); + var percent = Math.Abs(Maximum - Minimum) < double.Epsilon ? + 1.0 : + (Value - Minimum) / (Maximum - Minimum); // When the Orientation changed, the indicator's Width or Height should set to double.NaN. // Indicator size calculation should consider the ProgressBar's Padding property setting @@ -332,7 +324,8 @@ namespace Avalonia.Controls else { _indicator.Width = double.NaN; - _indicator.Height = (barSize.Height - _indicator.Margin.Top - _indicator.Margin.Bottom) * percent; + _indicator.Height = (barSize.Height - _indicator.Margin.Top - _indicator.Margin.Bottom) * + percent; } @@ -341,7 +334,7 @@ namespace Avalonia.Controls } } - private void UpdateIndicatorWhenPropChanged(AvaloniaPropertyChangedEventArgs e) + private void UpdateIndicatorWhenPropChanged() { UpdateIndicator(); } @@ -355,11 +348,9 @@ namespace Avalonia.Controls PseudoClasses.Set(":indeterminate", isIndeterminate.Value); } - if (o.HasValue) - { - PseudoClasses.Set(":vertical", o == Orientation.Vertical); - PseudoClasses.Set(":horizontal", o == Orientation.Horizontal); - } + if (!o.HasValue) return; + PseudoClasses.Set(":vertical", o == Orientation.Vertical); + PseudoClasses.Set(":horizontal", o == Orientation.Horizontal); } } } diff --git a/src/Avalonia.Themes.Simple/Controls/ProgressBar.xaml b/src/Avalonia.Themes.Simple/Controls/ProgressBar.xaml index 4278c7ee28..e7ad33d04e 100644 --- a/src/Avalonia.Themes.Simple/Controls/ProgressBar.xaml +++ b/src/Avalonia.Themes.Simple/Controls/ProgressBar.xaml @@ -87,10 +87,10 @@ IterationCount="Infinite" Duration="0:0:3"> - + - + @@ -102,10 +102,10 @@ IterationCount="Infinite" Duration="0:0:3"> - + - + From 08a01d1fd8059b6faf547c9970c9d341df35579f Mon Sep 17 00:00:00 2001 From: Jumar Macato <16554748+jmacato@users.noreply.github.com> Date: Mon, 29 May 2023 20:36:23 +0800 Subject: [PATCH 2/4] Update ProgressBar.cs --- src/Avalonia.Controls/ProgressBar.cs | 89 ++++++++++++++-------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/src/Avalonia.Controls/ProgressBar.cs b/src/Avalonia.Controls/ProgressBar.cs index 47c51fb839..6bada2c6d8 100644 --- a/src/Avalonia.Controls/ProgressBar.cs +++ b/src/Avalonia.Controls/ProgressBar.cs @@ -174,18 +174,13 @@ namespace Avalonia.Controls /// public double Percentage { - get { return _percentage; } + get => _percentage; private set { SetAndRaise(PercentageProperty, ref _percentage, value); } } static ProgressBar() { ValueProperty.OverrideMetadata(new(defaultBindingMode: BindingMode.OneWay)); - ValueProperty.Changed.AddClassHandler((x, _) => x.UpdateIndicatorWhenPropChanged()); - MinimumProperty.Changed.AddClassHandler((x, _) => x.UpdateIndicatorWhenPropChanged()); - MaximumProperty.Changed.AddClassHandler((x, _) => x.UpdateIndicatorWhenPropChanged()); - IsIndeterminateProperty.Changed.AddClassHandler((x, _) => x.UpdateIndicatorWhenPropChanged()); - OrientationProperty.Changed.AddClassHandler((x, _) => x.UpdateIndicatorWhenPropChanged()); } /// @@ -251,6 +246,15 @@ namespace Avalonia.Controls { base.OnPropertyChanged(change); + if (change.Property == ValueProperty || + change.Property == MinimumProperty || + change.Property == MaximumProperty || + change.Property == IsIndeterminateProperty || + change.Property == OrientationProperty) + { + UpdateIndicator(); + } + if (change.Property == IsIndeterminateProperty) { UpdatePseudoClasses(change.GetNewValue(), null); @@ -286,57 +290,50 @@ namespace Avalonia.Controls // Gets the size of the parent indicator container var barSize = _indicator?.VisualParent?.Bounds.Size ?? Bounds.Size; - if (_indicator != null) + if (_indicator == null) return; + if (IsIndeterminate) { - if (IsIndeterminate) - { - // Pulled from ModernWPF. + // Pulled from ModernWPF. - var dim = Orientation == Orientation.Horizontal ? barSize.Width : barSize.Height; - var barIndicatorWidth = dim * 0.4; // Indicator width at 40% of ProgressBar - var barIndicatorWidth2 = dim * 0.6; // Indicator width at 60% of ProgressBar + var dim = Orientation == Orientation.Horizontal ? barSize.Width : barSize.Height; + var barIndicatorWidth = dim * 0.4; // Indicator width at 40% of ProgressBar + var barIndicatorWidth2 = dim * 0.6; // Indicator width at 60% of ProgressBar - TemplateSettings.ContainerWidth = barIndicatorWidth; - TemplateSettings.Container2Width = barIndicatorWidth2; + TemplateSettings.ContainerWidth = barIndicatorWidth; + TemplateSettings.Container2Width = barIndicatorWidth2; - TemplateSettings.ContainerAnimationStartPosition = barIndicatorWidth * -1.8; // Position at -180% - TemplateSettings.ContainerAnimationEndPosition = barIndicatorWidth * 3.0; // Position at 300% + TemplateSettings.ContainerAnimationStartPosition = barIndicatorWidth * -1.8; // Position at -180% + TemplateSettings.ContainerAnimationEndPosition = barIndicatorWidth * 3.0; // Position at 300% - TemplateSettings.Container2AnimationStartPosition = barIndicatorWidth2 * -1.5; // Position at -150% - TemplateSettings.Container2AnimationEndPosition = barIndicatorWidth2 * 1.66; // Position at 166% + TemplateSettings.Container2AnimationStartPosition = barIndicatorWidth2 * -1.5; // Position at -150% + TemplateSettings.Container2AnimationEndPosition = barIndicatorWidth2 * 1.66; // Position at 166% + + TemplateSettings.IndeterminateStartingOffset = -dim; + TemplateSettings.IndeterminateEndingOffset = dim; + } + else + { + var percent = Math.Abs(Maximum - Minimum) < double.Epsilon ? + 1.0 : + (Value - Minimum) / (Maximum - Minimum); - TemplateSettings.IndeterminateStartingOffset = -dim; - TemplateSettings.IndeterminateEndingOffset = dim; + // When the Orientation changed, the indicator's Width or Height should set to double.NaN. + // Indicator size calculation should consider the ProgressBar's Padding property setting + if (Orientation == Orientation.Horizontal) + { + _indicator.Width = (barSize.Width - _indicator.Margin.Left - _indicator.Margin.Right) * percent; + _indicator.Height = double.NaN; } else { - var percent = Math.Abs(Maximum - Minimum) < double.Epsilon ? - 1.0 : - (Value - Minimum) / (Maximum - Minimum); - - // When the Orientation changed, the indicator's Width or Height should set to double.NaN. - // Indicator size calculation should consider the ProgressBar's Padding property setting - if (Orientation == Orientation.Horizontal) - { - _indicator.Width = (barSize.Width - _indicator.Margin.Left - _indicator.Margin.Right) * percent; - _indicator.Height = double.NaN; - } - else - { - _indicator.Width = double.NaN; - _indicator.Height = (barSize.Height - _indicator.Margin.Top - _indicator.Margin.Bottom) * - percent; - } - - - Percentage = percent * 100; + _indicator.Width = double.NaN; + _indicator.Height = (barSize.Height - _indicator.Margin.Top - _indicator.Margin.Bottom) * + percent; } - } - } - private void UpdateIndicatorWhenPropChanged() - { - UpdateIndicator(); + + Percentage = percent * 100; + } } private void UpdatePseudoClasses( From 5c32f033ee814b84f1be90d2b65bdc1c039fa049 Mon Sep 17 00:00:00 2001 From: Jumar Macato <16554748+jmacato@users.noreply.github.com> Date: Mon, 29 May 2023 21:21:19 +0800 Subject: [PATCH 3/4] Add xml docs to ProgressBarTemplateSettings props --- src/Avalonia.Controls/ProgressBar.cs | 74 +++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 13 deletions(-) diff --git a/src/Avalonia.Controls/ProgressBar.cs b/src/Avalonia.Controls/ProgressBar.cs index 6bada2c6d8..337ec868d0 100644 --- a/src/Avalonia.Controls/ProgressBar.cs +++ b/src/Avalonia.Controls/ProgressBar.cs @@ -32,6 +32,9 @@ namespace Avalonia.Controls private double _container2AnimationStartPosition; private double _container2AnimationEndPosition; + /// + /// Defines the property. + /// public static readonly DirectProperty ContainerAnimationStartPositionProperty = AvaloniaProperty.RegisterDirect( @@ -39,6 +42,9 @@ namespace Avalonia.Controls p => p.ContainerAnimationStartPosition, (p, o) => p.ContainerAnimationStartPosition = o); + /// + /// Defines the property. + /// public static readonly DirectProperty ContainerAnimationEndPositionProperty = AvaloniaProperty.RegisterDirect( @@ -46,6 +52,9 @@ namespace Avalonia.Controls p => p.ContainerAnimationEndPosition, (p, o) => p.ContainerAnimationEndPosition = o); + /// + /// Defines the property. + /// public static readonly DirectProperty Container2AnimationStartPositionProperty = AvaloniaProperty.RegisterDirect( @@ -53,6 +62,9 @@ namespace Avalonia.Controls p => p.Container2AnimationStartPosition, (p, o) => p.Container2AnimationStartPosition = o); + /// + /// Defines the property. + /// public static readonly DirectProperty Container2AnimationEndPositionProperty = AvaloniaProperty.RegisterDirect( @@ -60,24 +72,57 @@ namespace Avalonia.Controls p => p.Container2AnimationEndPosition, (p, o) => p.Container2AnimationEndPosition = o); + /// + /// Defines the property. + /// public static readonly DirectProperty Container2WidthProperty = AvaloniaProperty.RegisterDirect( nameof(Container2Width), p => p.Container2Width, (p, o) => p.Container2Width = o); + /// + /// Defines the property. + /// public static readonly DirectProperty ContainerWidthProperty = AvaloniaProperty.RegisterDirect( nameof(ContainerWidth), p => p.ContainerWidth, (p, o) => p.ContainerWidth = o); + /// + /// Defines the property. + /// public static readonly StyledProperty IndeterminateStartingOffsetProperty = AvaloniaProperty.Register(nameof(IndeterminateStartingOffset)); + /// + /// Defines the property. + /// public static readonly StyledProperty IndeterminateEndingOffsetProperty = AvaloniaProperty.Register(nameof(IndeterminateEndingOffset)); + /// + /// Used by to define the first indeterminate indicator's width. + /// + public double ContainerWidth + { + get => _containerWidth; + set => SetAndRaise(ContainerWidthProperty, ref _containerWidth, value); + } + + /// + /// Used by to define the second indeterminate indicator's width. + /// + public double Container2Width + { + get => _container2Width; + set => SetAndRaise(Container2WidthProperty, ref _container2Width, value); + } + + /// + /// Used by to define the first indeterminate indicator's start position when animated. + /// public double ContainerAnimationStartPosition { get => _containerAnimationStartPosition; @@ -85,43 +130,46 @@ namespace Avalonia.Controls value); } + /// + /// Used by to define the first indeterminate indicator's end position when animated. + /// public double ContainerAnimationEndPosition { get => _containerAnimationEndPosition; set => SetAndRaise(ContainerAnimationEndPositionProperty, ref _containerAnimationEndPosition, value); } + /// + /// Used by to define the second indeterminate indicator's start position when animated. + /// public double Container2AnimationStartPosition { get => _container2AnimationStartPosition; set => SetAndRaise(Container2AnimationStartPositionProperty, ref _container2AnimationStartPosition, value); } - - public double Container2Width - { - get => _container2Width; - set => SetAndRaise(Container2WidthProperty, ref _container2Width, value); - } - - public double ContainerWidth - { - get => _containerWidth; - set => SetAndRaise(ContainerWidthProperty, ref _containerWidth, value); - } - + + /// + /// Used by to define the second indeterminate indicator's end position when animated. + /// public double Container2AnimationEndPosition { get => _container2AnimationEndPosition; set => SetAndRaise(Container2AnimationEndPositionProperty, ref _container2AnimationEndPosition, value); } + /// + /// Used by to define the starting point of its indeterminate animation. + /// public double IndeterminateStartingOffset { get => GetValue(IndeterminateStartingOffsetProperty); set => SetValue(IndeterminateStartingOffsetProperty, value); } + /// + /// Used by to define the ending point of its indeterminate animation. + /// public double IndeterminateEndingOffset { get => GetValue(IndeterminateEndingOffsetProperty); From 4534bb0463ce22f676726e8c4978d31df5b65986 Mon Sep 17 00:00:00 2001 From: Jumar Macato <16554748+jmacato@users.noreply.github.com> Date: Tue, 30 May 2023 00:44:56 +0800 Subject: [PATCH 4/4] make props to direct ones --- src/Avalonia.Controls/ProgressBar.cs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/Avalonia.Controls/ProgressBar.cs b/src/Avalonia.Controls/ProgressBar.cs index 337ec868d0..3dad162286 100644 --- a/src/Avalonia.Controls/ProgressBar.cs +++ b/src/Avalonia.Controls/ProgressBar.cs @@ -31,6 +31,8 @@ namespace Avalonia.Controls private double _containerAnimationEndPosition; private double _container2AnimationStartPosition; private double _container2AnimationEndPosition; + private double _indeterminateStartingOffset; + private double _indeterminateEndingOffset; /// /// Defines the property. @@ -93,14 +95,20 @@ namespace Avalonia.Controls /// /// Defines the property. /// - public static readonly StyledProperty IndeterminateStartingOffsetProperty = - AvaloniaProperty.Register(nameof(IndeterminateStartingOffset)); - + public static readonly DirectProperty IndeterminateStartingOffsetProperty = + AvaloniaProperty.RegisterDirect( + nameof(IndeterminateStartingOffset), + p => p.IndeterminateStartingOffset, + (p, o) => p.IndeterminateStartingOffset = o); + /// /// Defines the property. /// - public static readonly StyledProperty IndeterminateEndingOffsetProperty = - AvaloniaProperty.Register(nameof(IndeterminateEndingOffset)); + public static readonly DirectProperty IndeterminateEndingOffsetProperty = + AvaloniaProperty.RegisterDirect( + nameof(IndeterminateEndingOffset), + p => p.IndeterminateEndingOffset, + (p, o) => p.IndeterminateEndingOffset = o); /// /// Used by to define the first indeterminate indicator's width. @@ -163,17 +171,17 @@ namespace Avalonia.Controls /// public double IndeterminateStartingOffset { - get => GetValue(IndeterminateStartingOffsetProperty); - set => SetValue(IndeterminateStartingOffsetProperty, value); + get => _indeterminateStartingOffset; + set => SetAndRaise(IndeterminateStartingOffsetProperty, ref _indeterminateStartingOffset, value); } - + /// /// Used by to define the ending point of its indeterminate animation. /// public double IndeterminateEndingOffset { - get => GetValue(IndeterminateEndingOffsetProperty); - set => SetValue(IndeterminateEndingOffsetProperty, value); + get => _indeterminateEndingOffset; + set => SetAndRaise(IndeterminateEndingOffsetProperty, ref _indeterminateEndingOffset, value); } }