From fa0bad2db0b52c0b2b6bb1f630e61bac6a2190f9 Mon Sep 17 00:00:00 2001 From: Mahdi Hosseini Date: Sun, 15 Dec 2024 14:00:45 +0330 Subject: [PATCH] Add ProgressButton --- README.md | 4 + .../Controls/ProgressButton.cs | 153 ++++++++ dev/DevWinUI.Controls/Themes/Generic.xaml | 212 +++++++++++ .../Styles/Controls/ProgressButton.xaml | 359 ++++++++++++++++++ .../Assets/Fluent/ToggleButton.png | Bin 0 -> 3627 bytes .../Assets/NavViewMenu/AppData.json | 7 + .../T4Templates/NavigationPageMappings.cs | 1 + .../Pages/Features/ProgressButtonPage.xaml | 72 ++++ .../Pages/Features/ProgressButtonPage.xaml.cs | 28 ++ 9 files changed, 836 insertions(+) create mode 100644 dev/DevWinUI.Controls/Controls/ProgressButton.cs create mode 100644 dev/DevWinUI.Controls/Themes/Styles/Controls/ProgressButton.xaml create mode 100644 dev/DevWinUI.Gallery/Assets/Fluent/ToggleButton.png create mode 100644 dev/DevWinUI.Gallery/Views/Pages/Features/ProgressButtonPage.xaml create mode 100644 dev/DevWinUI.Gallery/Views/Pages/Features/ProgressButtonPage.xaml.cs diff --git a/README.md b/README.md index 4f6cacb..ec46e72 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ Install-Package DevWinUI ## 🔥 DevWinUI.Controls 🔥 ### ⚡ What’s Inside? ⚡ +- ✨ ProgressButton - ✨ TextBox - ✨ BreadcrumbNavigator - ✨ PinBox @@ -246,6 +247,9 @@ Install-Package DevWinUI.ContextMenu ## 🕰️ History 🕰️ +### ProgressButton +![DevWinUI](https://raw.githubusercontent.com/ghost1372/DevWinUI-Resources/refs/heads/main/DevWinUI-Docs/ProgressButton.png) + ### TextBox ![DevWinUI](https://raw.githubusercontent.com/ghost1372/DevWinUI-Resources/refs/heads/main/DevWinUI-Docs/TextBox.png) diff --git a/dev/DevWinUI.Controls/Controls/ProgressButton.cs b/dev/DevWinUI.Controls/Controls/ProgressButton.cs new file mode 100644 index 0000000..326b0e7 --- /dev/null +++ b/dev/DevWinUI.Controls/Controls/ProgressButton.cs @@ -0,0 +1,153 @@ +using Microsoft.UI.Xaml.Controls.Primitives; + +namespace DevWinUI; + +[TemplatePart(Name = nameof(PART_ProgressBar), Type = typeof(ProgressBar))] +public partial class ProgressButton : ToggleButton +{ + private readonly string PART_ProgressBar = "PART_ProgressBar"; + private ProgressBar progressBar; + + public SolidColorBrush ProgressBackground + { + get { return (SolidColorBrush)GetValue(ProgressBackgroundProperty); } + set { SetValue(ProgressBackgroundProperty, value); } + } + + public static readonly DependencyProperty ProgressBackgroundProperty = + DependencyProperty.Register(nameof(ProgressBackground), typeof(SolidColorBrush), typeof(ProgressButton), new PropertyMetadata(null)); + + public SolidColorBrush ProgressForeground + { + get { return (SolidColorBrush)GetValue(ProgressForegroundProperty); } + set { SetValue(ProgressForegroundProperty, value); } + } + + public static readonly DependencyProperty ProgressForegroundProperty = + DependencyProperty.Register(nameof(ProgressForeground), typeof(SolidColorBrush), typeof(ProgressButton), new PropertyMetadata(null)); + + public HorizontalAlignment ProgressRingHorizontalAlignment + { + get { return (HorizontalAlignment)GetValue(ProgressRingHorizontalAlignmentProperty); } + set { SetValue(ProgressRingHorizontalAlignmentProperty, value); } + } + + public static readonly DependencyProperty ProgressRingHorizontalAlignmentProperty = + DependencyProperty.Register(nameof(ProgressRingHorizontalAlignment), typeof(HorizontalAlignment), typeof(ProgressButton), new PropertyMetadata(HorizontalAlignment.Right)); + + public double ProgressRingSize + { + get { return (double)GetValue(ProgressRingSizeProperty); } + set { SetValue(ProgressRingSizeProperty, value); } + } + + public static readonly DependencyProperty ProgressRingSizeProperty = + DependencyProperty.Register(nameof(ProgressRingSize), typeof(double), typeof(ProgressButton), new PropertyMetadata(24.0)); + + public Visibility ProgressRingVisibility + { + get { return (Visibility)GetValue(ProgressRingVisibilityProperty); } + set { SetValue(ProgressRingVisibilityProperty, value); } + } + + public static readonly DependencyProperty ProgressRingVisibilityProperty = + DependencyProperty.Register(nameof(ProgressRingVisibility), typeof(Visibility), typeof(ProgressButton), new PropertyMetadata(Visibility.Collapsed)); + + public bool IsIndeterminateProgressRing + { + get { return (bool)GetValue(IsIndeterminateProgressRingProperty); } + set { SetValue(IsIndeterminateProgressRingProperty, value); } + } + + public static readonly DependencyProperty IsIndeterminateProgressRingProperty = + DependencyProperty.Register(nameof(IsIndeterminateProgressRing), typeof(bool), typeof(ProgressButton), new PropertyMetadata(true)); + + public Style ProgressRingStyle + { + get => (Style)GetValue(ProgressRingStyleProperty); + set => SetValue(ProgressRingStyleProperty, value); + } + + public static readonly DependencyProperty ProgressRingStyleProperty = DependencyProperty.Register( + nameof(ProgressRingStyle), typeof(Style), typeof(ProgressButton), new PropertyMetadata(default(Style))); + + public double Progress + { + get { return (double)GetValue(ProgressProperty); } + set { SetValue(ProgressProperty, value); } + } + + public static readonly DependencyProperty ProgressProperty = + DependencyProperty.Register(nameof(Progress), typeof(double), typeof(ProgressButton), new PropertyMetadata(0.0)); + + public object CheckedContent + { + get { return (object)GetValue(CheckedContentProperty); } + set { SetValue(CheckedContentProperty, value); } + } + + public static readonly DependencyProperty CheckedContentProperty = + DependencyProperty.Register(nameof(CheckedContent), typeof(object), typeof(ProgressButton), new PropertyMetadata(default(object))); + + public bool ShowError + { + get { return (bool)GetValue(ShowErrorProperty); } + set { SetValue(ShowErrorProperty, value); } + } + + public static readonly DependencyProperty ShowErrorProperty = + DependencyProperty.Register(nameof(ShowError), typeof(bool), typeof(ProgressButton), new PropertyMetadata(false)); + + public bool ShowPaused + { + get { return (bool)GetValue(ShowPausedProperty); } + set { SetValue(ShowPausedProperty, value); } + } + + public static readonly DependencyProperty ShowPausedProperty = + DependencyProperty.Register(nameof(ShowPaused), typeof(bool), typeof(ProgressButton), new PropertyMetadata(false)); + + public bool IsIndeterminate + { + get { return (bool)GetValue(IsIndeterminateProperty); } + set { SetValue(IsIndeterminateProperty, value); } + } + + public static readonly DependencyProperty IsIndeterminateProperty = + DependencyProperty.Register(nameof(IsIndeterminate), typeof(bool), typeof(ProgressButton), new PropertyMetadata(false)); + + protected override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + SizeChanged += ProgressButton_SizeChanged; + progressBar = GetTemplateChild(nameof(PART_ProgressBar)) as ProgressBar; + if (progressBar != null) + { + progressBar.MinHeight = ActualHeight; + progressBar.Loaded += ProgressBar_Loaded; + } + } + + private void ProgressBar_Loaded(object sender, RoutedEventArgs e) + { + if (progressBar != null) + { + progressBar.ApplyTemplate(); + var track = progressBar.FindDescendant("ProgressBarTrack"); + if (track != null) + { + track.VerticalAlignment = VerticalAlignment.Stretch; + track.Height = double.NaN; + } + } + } + + private void ProgressButton_SizeChanged(object sender, SizeChangedEventArgs e) + { + if (progressBar != null) + { + progressBar.MinHeight = ActualHeight; + } + } +} diff --git a/dev/DevWinUI.Controls/Themes/Generic.xaml b/dev/DevWinUI.Controls/Themes/Generic.xaml index 4499cf7..ce9b928 100644 --- a/dev/DevWinUI.Controls/Themes/Generic.xaml +++ b/dev/DevWinUI.Controls/Themes/Generic.xaml @@ -27,6 +27,7 @@ Themes\Styles\Controls\LoadingIndicator.xaml Themes\Styles\Controls\LongShadowTextBlock.xaml Themes\Styles\Controls\OptionsPageControl.xaml Themes\Styles\Controls\PinBox.xaml +Themes\Styles\Controls\ProgressButton.xaml Themes\Styles\Controls\ProgressRing.xaml Themes\Styles\Controls\RedirectVisualView.xaml Themes\Styles\Controls\SelectorBarSegmented.xaml @@ -86,6 +87,7 @@ Themes\Styles\Win2D\Watermark.xaml + @@ -149,6 +151,7 @@ Themes\Styles\Win2D\Watermark.xaml + @@ -209,6 +212,7 @@ Themes\Styles\Win2D\Watermark.xaml + @@ -3332,6 +3336,214 @@ Themes\Styles\Win2D\Watermark.xaml + + diff --git a/dev/DevWinUI.Gallery/Assets/Fluent/ToggleButton.png b/dev/DevWinUI.Gallery/Assets/Fluent/ToggleButton.png new file mode 100644 index 0000000000000000000000000000000000000000..52682aa065ca4a87566c620981f0125742a0b5a3 GIT binary patch literal 3627 zcmV+`4%G39P)*?Y@Ss�aKp#Y+UK)-8|&BVE%q!z)7E)= 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 + + + + + + + + <dev:ProgressButton CheckedContent="Downloading..." Content="Click Here" IsIndeterminateProgressRing="true" ProgressRingVisibility="Visible" /> + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/DevWinUI.Gallery/Views/Pages/Features/ProgressButtonPage.xaml.cs b/dev/DevWinUI.Gallery/Views/Pages/Features/ProgressButtonPage.xaml.cs new file mode 100644 index 0000000..4747b5e --- /dev/null +++ b/dev/DevWinUI.Gallery/Views/Pages/Features/ProgressButtonPage.xaml.cs @@ -0,0 +1,28 @@ +namespace DevWinUIGallery.Views; + +public sealed partial class ProgressButtonPage : Page +{ + public ProgressButtonPage() + { + this.InitializeComponent(); + } + + private async void ProgressButton_Checked(object sender, RoutedEventArgs e) + { + var pb = sender as ProgressButton; + if (pb.IsChecked.Value && !pb.IsIndeterminate) + { + pb.Progress = 0; + while (true) + { + pb.Progress += 1; + await Task.Delay(50); + if (pb.Progress == 100) + { + pb.IsChecked = false; + break; + } + } + } + } +}