From 7cb4485dfb98973ccd77e7ec74c585526313afdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro?= Date: Sun, 1 Oct 2017 13:27:44 +0100 Subject: [PATCH 1/3] Added Orientation and IsIndeterminate properties to ProgressBar. Moved the Orientation enum to a separate file. --- samples/ControlCatalog/ControlCatalog.csproj | 6 + samples/ControlCatalog/MainView.xaml | 1 + .../ControlCatalog/Pages/ProgressBarPage.xaml | 24 ++++ .../Pages/ProgressBarPage.xaml.cs | 18 +++ src/Avalonia.Controls/Orientation.cs | 21 ++++ src/Avalonia.Controls/Primitives/ScrollBar.cs | 2 +- src/Avalonia.Controls/ProgressBar.cs | 104 +++++++++++++++++- src/Avalonia.Controls/StackPanel.cs | 18 +-- src/Avalonia.Themes.Default/ProgressBar.xaml | 5 +- 9 files changed, 174 insertions(+), 25 deletions(-) create mode 100644 samples/ControlCatalog/Pages/ProgressBarPage.xaml create mode 100644 samples/ControlCatalog/Pages/ProgressBarPage.xaml.cs create mode 100644 src/Avalonia.Controls/Orientation.cs diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index 340905a7f7..11ff531514 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -69,6 +69,9 @@ Designer + + Designer + Designer @@ -131,6 +134,9 @@ MenuPage.xaml + + ProgressBarPage.xaml + RadioButtonPage.xaml diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml index 6c432a90ac..0940316ce9 100644 --- a/samples/ControlCatalog/MainView.xaml +++ b/samples/ControlCatalog/MainView.xaml @@ -16,6 +16,7 @@ + diff --git a/samples/ControlCatalog/Pages/ProgressBarPage.xaml b/samples/ControlCatalog/Pages/ProgressBarPage.xaml new file mode 100644 index 0000000000..bf40e68630 --- /dev/null +++ b/samples/ControlCatalog/Pages/ProgressBarPage.xaml @@ -0,0 +1,24 @@ + + + ProgressBar + A progress bar control + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/ControlCatalog/Pages/ProgressBarPage.xaml.cs b/samples/ControlCatalog/Pages/ProgressBarPage.xaml.cs new file mode 100644 index 0000000000..56792b3908 --- /dev/null +++ b/samples/ControlCatalog/Pages/ProgressBarPage.xaml.cs @@ -0,0 +1,18 @@ +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace ControlCatalog.Pages +{ + public class ProgressBarPage : UserControl + { + public ProgressBarPage() + { + this.InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + } +} diff --git a/src/Avalonia.Controls/Orientation.cs b/src/Avalonia.Controls/Orientation.cs new file mode 100644 index 0000000000..fe998c024a --- /dev/null +++ b/src/Avalonia.Controls/Orientation.cs @@ -0,0 +1,21 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +namespace Avalonia.Controls +{ + /// + /// Defines vertical or horizontal orientation. + /// + public enum Orientation + { + /// + /// Horizontal orientation. + /// + Horizontal, + + /// + /// Vertical orientation. + /// + Vertical, + } +} diff --git a/src/Avalonia.Controls/Primitives/ScrollBar.cs b/src/Avalonia.Controls/Primitives/ScrollBar.cs index 0f69e4e5bc..009e1d0ab8 100644 --- a/src/Avalonia.Controls/Primitives/ScrollBar.cs +++ b/src/Avalonia.Controls/Primitives/ScrollBar.cs @@ -30,7 +30,7 @@ namespace Avalonia.Controls.Primitives /// Defines the property. /// public static readonly StyledProperty OrientationProperty = - AvaloniaProperty.Register(nameof(Orientation)); + AvaloniaProperty.Register(nameof(Orientation), Orientation.Vertical); private Button _lineUpButton; private Button _lineDownButton; diff --git a/src/Avalonia.Controls/ProgressBar.cs b/src/Avalonia.Controls/ProgressBar.cs index a31a27ddfe..015b0a6e96 100644 --- a/src/Avalonia.Controls/ProgressBar.cs +++ b/src/Avalonia.Controls/ProgressBar.cs @@ -1,8 +1,12 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System; +using System.Reactive.Linq; + +using Avalonia.Animation; using Avalonia.Controls.Primitives; -using Avalonia.Controls.Templates; +using Avalonia.Layout; namespace Avalonia.Controls { @@ -11,11 +15,41 @@ namespace Avalonia.Controls /// public class ProgressBar : RangeBase { + public static readonly StyledProperty IsIndeterminateProperty = + AvaloniaProperty.Register(nameof(IsIndeterminate)); + + public static readonly StyledProperty OrientationProperty = + AvaloniaProperty.Register(nameof(Orientation), Orientation.Horizontal); + private Border _indicator; + private IDisposable _indeterminateBindSubscription; static ProgressBar() { ValueProperty.Changed.AddClassHandler(x => x.ValueChanged); + + HorizontalAlignmentProperty.OverrideDefaultValue(HorizontalAlignment.Left); + VerticalAlignmentProperty.OverrideDefaultValue(VerticalAlignment.Top); + } + + public bool IsIndeterminate + { + get => GetValue(IsIndeterminateProperty); + set + { + SetValue(IsIndeterminateProperty, value); + UpdateIsIndeterminate(value); + } + } + + public Orientation Orientation + { + get => GetValue(OrientationProperty); + set + { + SetValue(OrientationProperty, value); + UpdateOrientation(value); + } } /// @@ -29,18 +63,82 @@ namespace Avalonia.Controls protected override void OnTemplateApplied(TemplateAppliedEventArgs e) { _indicator = e.NameScope.Get("PART_Indicator"); + UpdateIndicator(Bounds.Size); + UpdateOrientation(Orientation); + UpdateIsIndeterminate(IsIndeterminate); } private void UpdateIndicator(Size bounds) { if (_indicator != null) { - double percent = Maximum == Minimum ? 1.0 : (Value - Minimum) / (Maximum - Minimum); - _indicator.Width = bounds.Width * percent; + if (IsIndeterminate) + { + if (Orientation == Orientation.Horizontal) + _indicator.Width = bounds.Width / 5.0; + else + _indicator.Height = bounds.Height / 5.0; + } + else + { + double percent = Maximum == Minimum ? 1.0 : (Value - Minimum) / (Maximum - Minimum); + + if (Orientation == Orientation.Horizontal) + _indicator.Width = bounds.Width * percent; + else + _indicator.Height = bounds.Height * percent; + } } } + private void UpdateOrientation(Orientation orientation) + { + if (orientation == Orientation.Horizontal) + { + MinHeight = 14; + MinWidth = 200; + + _indicator.HorizontalAlignment = HorizontalAlignment.Left; + _indicator.VerticalAlignment = VerticalAlignment.Stretch; + } + else + { + MinHeight = 200; + MinWidth = 14; + + _indicator.HorizontalAlignment = HorizontalAlignment.Stretch; + _indicator.VerticalAlignment = VerticalAlignment.Bottom; + } + } + + private void UpdateIsIndeterminate(bool isIndeterminate) + { + if (isIndeterminate) + { + var start = Animate.Stopwatch.Elapsed; + + if (Orientation == Orientation.Horizontal) + { + _indeterminateBindSubscription = Animate.Timer.TakeWhile(x => (x - start).TotalSeconds <= 4.0) + .Select(x => new Rect(-_indicator.Width - 5 + (x - start).TotalSeconds / 4.0 * (Bounds.Width + _indicator.Width + 10), 0, _indicator.Bounds.Width, _indicator.Bounds.Height)) + .Finally(() => start = Animate.Stopwatch.Elapsed) + .Repeat() + .Subscribe(x => _indicator.Arrange(x)); + } + else + { + _indeterminateBindSubscription = Animate.Timer.TakeWhile(x => (x - start).TotalSeconds <= 4.0) + .Select(x => new Rect(0, Bounds.Height + 5 - (x - start).TotalSeconds / 4.0 * (Bounds.Height + _indicator.Height + 10), _indicator.Bounds.Width, _indicator.Bounds.Height)) + .Finally(() => start = Animate.Stopwatch.Elapsed) + .Repeat() + .Subscribe(x => _indicator.Arrange(x)); + } + } + else + _indeterminateBindSubscription?.Dispose(); + } + private void ValueChanged(AvaloniaPropertyChangedEventArgs e) { UpdateIndicator(Bounds.Size); diff --git a/src/Avalonia.Controls/StackPanel.cs b/src/Avalonia.Controls/StackPanel.cs index 26a755e5f1..0e12fb3283 100644 --- a/src/Avalonia.Controls/StackPanel.cs +++ b/src/Avalonia.Controls/StackPanel.cs @@ -6,22 +6,6 @@ using Avalonia.Input; namespace Avalonia.Controls { - /// - /// Defines vertical or horizontal orientation. - /// - public enum Orientation - { - /// - /// Vertical orientation. - /// - Vertical, - - /// - /// Horizontal orientation. - /// - Horizontal, - } - /// /// A panel which lays out its children horizontally or vertically. /// @@ -37,7 +21,7 @@ namespace Avalonia.Controls /// Defines the property. /// public static readonly StyledProperty OrientationProperty = - AvaloniaProperty.Register(nameof(Orientation)); + AvaloniaProperty.Register(nameof(Orientation), Orientation.Vertical); /// /// Initializes static members of the class. diff --git a/src/Avalonia.Themes.Default/ProgressBar.xaml b/src/Avalonia.Themes.Default/ProgressBar.xaml index 4acff26537..82f385e16b 100644 --- a/src/Avalonia.Themes.Default/ProgressBar.xaml +++ b/src/Avalonia.Themes.Default/ProgressBar.xaml @@ -1,8 +1,6 @@