diff --git a/src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs b/src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs index fb61ea679c..8ff8088a34 100644 --- a/src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs +++ b/src/Avalonia.Controls/DateTimePickers/DatePickerPresenter.cs @@ -367,11 +367,11 @@ namespace Avalonia.Controls var dt = Date; if (DayVisible) { + _daySelector.FormatDate = dt.Date; var maxDays = _calendar.GetDaysInMonth(dt.Year, dt.Month); _daySelector.MaximumValue = maxDays; _daySelector.MinimumValue = 1; _daySelector.SelectedValue = dt.Day; - _daySelector.FormatDate = dt.Date; } if (MonthVisible) diff --git a/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs b/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs index 8525f025a3..94ee99b019 100644 --- a/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs +++ b/src/Avalonia.Controls/Primitives/LightDismissOverlayLayer.cs @@ -46,13 +46,12 @@ namespace Avalonia.Controls.Primitives return manager?.LightDismissOverlayLayer; } + /// public bool HitTest(Point point) { if (InputPassThroughElement is Visual v) { - var hit = ((Visual?)VisualRoot)?.GetVisualAt(point, x => x != this); - - if (hit is object) + if (VisualRoot is IInputElement ie && ie.InputHitTest(point, x => x != this) is Visual hit) { return !v.IsVisualAncestorOf(hit); } diff --git a/src/Avalonia.Controls/ProgressBar.cs b/src/Avalonia.Controls/ProgressBar.cs index 7dcdaa2f8d..3dad162286 100644 --- a/src/Avalonia.Controls/ProgressBar.cs +++ b/src/Avalonia.Controls/ProgressBar.cs @@ -31,77 +31,157 @@ namespace Avalonia.Controls private double _containerAnimationEndPosition; 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); - + private double _indeterminateStartingOffset; + private double _indeterminateEndingOffset; + + /// + /// Defines the property. + /// + public static readonly DirectProperty + ContainerAnimationStartPositionProperty = + AvaloniaProperty.RegisterDirect( + nameof(ContainerAnimationStartPosition), + p => p.ContainerAnimationStartPosition, + (p, o) => p.ContainerAnimationStartPosition = o); + + /// + /// Defines the property. + /// + public static readonly DirectProperty + ContainerAnimationEndPositionProperty = + AvaloniaProperty.RegisterDirect( + nameof(ContainerAnimationEndPosition), + p => p.ContainerAnimationEndPosition, + (p, o) => p.ContainerAnimationEndPosition = o); + + /// + /// Defines the property. + /// + public static readonly DirectProperty + Container2AnimationStartPositionProperty = + AvaloniaProperty.RegisterDirect( + nameof(Container2AnimationStartPosition), + p => p.Container2AnimationStartPosition, + (p, o) => p.Container2AnimationStartPosition = o); + + /// + /// Defines the property. + /// + public static readonly DirectProperty + Container2AnimationEndPositionProperty = + AvaloniaProperty.RegisterDirect( + nameof(Container2AnimationEndPosition), + 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 DirectProperty IndeterminateStartingOffsetProperty = + AvaloniaProperty.RegisterDirect( + nameof(IndeterminateStartingOffset), + p => p.IndeterminateStartingOffset, + (p, o) => p.IndeterminateStartingOffset = o); + + /// + /// Defines the property. + /// + 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. + /// + 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; - set => SetAndRaise(ContainerAnimationStartPositionProperty, ref _containerAnimationStartPosition, value); + set => SetAndRaise(ContainerAnimationStartPositionProperty, ref _containerAnimationStartPosition, + 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); + set => SetAndRaise(Container2AnimationStartPositionProperty, ref _container2AnimationStartPosition, + value); } - - public double Container2Width + + /// + /// Used by to define the second indeterminate indicator's end position when animated. + /// + public double Container2AnimationEndPosition { - get => _container2Width; - set => SetAndRaise(Container2WidthProperty, ref _container2Width, value); + get => _container2AnimationEndPosition; + set => SetAndRaise(Container2AnimationEndPositionProperty, ref _container2AnimationEndPosition, value); } - public double ContainerWidth + /// + /// Used by to define the starting point of its indeterminate animation. + /// + public double IndeterminateStartingOffset { - get => _containerWidth; - set => SetAndRaise(ContainerWidthProperty, ref _containerWidth, value); + get => _indeterminateStartingOffset; + set => SetAndRaise(IndeterminateStartingOffsetProperty, ref _indeterminateStartingOffset, value); } - - public double Container2AnimationEndPosition + + /// + /// Used by to define the ending point of its indeterminate animation. + /// + public double IndeterminateEndingOffset { - get => _container2AnimationEndPosition; - set => SetAndRaise(Container2AnimationEndPositionProperty, ref _container2AnimationEndPosition, value); + get => _indeterminateEndingOffset; + set => SetAndRaise(IndeterminateEndingOffsetProperty, ref _indeterminateEndingOffset, value); } } @@ -131,7 +211,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 +221,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 /// @@ -162,30 +230,13 @@ namespace Avalonia.Controls /// public double Percentage { - get { return _percentage; } + get => _percentage; 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)); } /// @@ -251,6 +302,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,64 +346,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% - // Remove these properties when we switch to fluent as default and removed the old one. - SetCurrentValue(IndeterminateStartingOffsetProperty,-dim); - SetCurrentValue(IndeterminateEndingOffsetProperty,dim); + TemplateSettings.IndeterminateStartingOffset = -dim; + TemplateSettings.IndeterminateEndingOffset = dim; + } + else + { + var percent = Math.Abs(Maximum - Minimum) < double.Epsilon ? + 1.0 : + (Value - Minimum) / (Maximum - Minimum); - 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) - )); + // 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 { - double percent = Maximum == Minimum ? 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(AvaloniaPropertyChangedEventArgs e) - { - UpdateIndicator(); + + Percentage = percent * 100; + } } private void UpdatePseudoClasses( @@ -355,11 +401,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"> - + - +