diff --git a/Samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml b/Samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml
index 252d6e1..8ae0f80 100644
--- a/Samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml
+++ b/Samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml
@@ -63,6 +63,19 @@
+
+
+
+
+
+ Sub
+ Add
+
+
+
+
@@ -86,8 +99,8 @@
+ Title="Progress bar with success segment"
+ Description="Show several parts of progress with different status.">
@@ -277,5 +290,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml.cs b/Samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml.cs
index a7edcd0..d1dac16 100644
--- a/Samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml.cs
+++ b/Samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml.cs
@@ -1,6 +1,8 @@
using AtomUI.Controls;
+using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
+using CommunityToolkit.Mvvm.ComponentModel;
namespace AtomUI.Demo.Desktop.ShowCase;
@@ -19,6 +21,33 @@ public partial class ProgressBarShowCase : UserControl
public PercentPosition OutterStartPercentPosition { get; set; }
public PercentPosition OutterCenterPercentPosition { get; set; }
public PercentPosition OutterEndPercentPosition { get; set; }
+
+ public static readonly StyledProperty ProgressValueProperty =
+ AvaloniaProperty.Register(nameof(ProgressValue), 30);
+
+ public static readonly StyledProperty ToggleDisabledTextProperty =
+ AvaloniaProperty.Register(nameof(ToggleDisabledText), "Disable");
+
+ public static readonly StyledProperty ToggleStatusProperty =
+ AvaloniaProperty.Register(nameof(ToggleStatus), true);
+
+ public double ProgressValue
+ {
+ get => GetValue(ProgressValueProperty);
+ set => SetValue(ProgressValueProperty, value);
+ }
+
+ public string ToggleDisabledText
+ {
+ get => GetValue(ToggleDisabledTextProperty);
+ set => SetValue(ToggleDisabledTextProperty, value);
+ }
+
+ public bool ToggleStatus
+ {
+ get => GetValue(ToggleStatusProperty);
+ set => SetValue(ToggleStatusProperty, value);
+ }
public ProgressBarShowCase()
{
@@ -81,4 +110,28 @@ public partial class ProgressBarShowCase : UserControl
Alignment = LinePercentAlignment.End
};
}
+
+ public void AddProgressValue()
+ {
+ var value = ProgressValue;
+ value += 10;
+ ProgressValue = Math.Min(value, 100);
+ }
+
+ public void SubProgressValue()
+ {
+ var value = ProgressValue;
+ value -= 10;
+ ProgressValue = Math.Max(value, 0);
+ }
+
+ public void ToggleEnabledStatus()
+ {
+ ToggleStatus = !ToggleStatus;
+ if (ToggleStatus) {
+ ToggleDisabledText = "Disable";
+ } else {
+ ToggleDisabledText = "Enable";
+ }
+ }
}
\ No newline at end of file
diff --git a/src/AtomUI.Controls/Buttons/ButtonStyle.cs b/src/AtomUI.Controls/Buttons/ButtonStyle.cs
index cb35937..b6d3014 100644
--- a/src/AtomUI.Controls/Buttons/ButtonStyle.cs
+++ b/src/AtomUI.Controls/Buttons/ButtonStyle.cs
@@ -25,6 +25,8 @@ public partial class Button : IWaveAdornerInfoProvider, IControlCustomStyle
void IControlCustomStyle.SetupUi()
{
+ HorizontalAlignment = HorizontalAlignment.Left;
+ VerticalAlignment = VerticalAlignment.Bottom;
Cursor = new Cursor(StandardCursorType.Hand);
_customStyle.CollectStyleState();
CreateMainLayout();
diff --git a/src/AtomUI.Controls/ProgressBar/AbstractCircleProgress.cs b/src/AtomUI.Controls/ProgressBar/AbstractCircleProgress.cs
index 01466e2..bfb1833 100644
--- a/src/AtomUI.Controls/ProgressBar/AbstractCircleProgress.cs
+++ b/src/AtomUI.Controls/ProgressBar/AbstractCircleProgress.cs
@@ -39,8 +39,7 @@ public abstract partial class AbstractCircleProgress : AbstractProgressBar
{
HorizontalAlignmentProperty.OverrideDefaultValue(HorizontalAlignment.Left);
VerticalAlignmentProperty.OverrideDefaultValue(VerticalAlignment.Top);
- AffectsRender(IndicatorAngleProperty,
- StepCountProperty,
+ AffectsMeasure(StepCountProperty,
StepGapProperty);
}
@@ -106,7 +105,6 @@ public abstract partial class AbstractCircleProgress : AbstractProgressBar
if (ShowProgressInfo) {
_percentageLabel!.Measure(availableSize);
}
-
return new Size(targetSize, targetSize);
}
diff --git a/src/AtomUI.Controls/ProgressBar/AbstractLineProgress.cs b/src/AtomUI.Controls/ProgressBar/AbstractLineProgress.cs
index 57238e8..554be79 100644
--- a/src/AtomUI.Controls/ProgressBar/AbstractLineProgress.cs
+++ b/src/AtomUI.Controls/ProgressBar/AbstractLineProgress.cs
@@ -87,9 +87,7 @@ public abstract partial class AbstractLineProgress : AbstractProgressBar
EffectiveSizeType = CalculateEffectiveSizeType(sizeValue);
}
- if (_extraInfoSize == Size.Infinity) {
- _extraInfoSize = CalculateExtraInfoSize(FontSize);
- }
+ _extraInfoSize = CalculateExtraInfoSize(FontSize);
SetupAlignment();
NotifyOrientationChanged();
}
@@ -112,9 +110,7 @@ public abstract partial class AbstractLineProgress : AbstractProgressBar
EffectiveSizeType = CalculateEffectiveSizeType(e.GetNewValue());
CalculateStrokeThickness();
} else if (e.Property == EffectiveSizeTypeProperty) {
- if (_extraInfoSize == Size.Infinity) {
- _extraInfoSize = CalculateExtraInfoSize(FontSize);
- }
+ _extraInfoSize = CalculateExtraInfoSize(FontSize);
} else if (e.Property == OrientationProperty) {
NotifyOrientationChanged();
}
@@ -187,4 +183,21 @@ public abstract partial class AbstractLineProgress : AbstractProgressBar
}
protected virtual void NotifyOrientationChanged() {}
+ private bool _lastCompletedStatus = false;
+ protected override void NotifyHandleExtraInfoVisibility()
+ {
+ base.NotifyHandleExtraInfoVisibility();
+ var currentStatus = false;
+ if (NumberUtils.FuzzyEqual(Value, Maximum)) {
+ currentStatus = true;
+
+ } else {
+ currentStatus = false;
+ }
+
+ if (currentStatus != _lastCompletedStatus) {
+ _lastCompletedStatus = currentStatus;
+ _extraInfoSize = CalculateExtraInfoSize(FontSize);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/AtomUI.Controls/ProgressBar/AbstractProgressBar.cs b/src/AtomUI.Controls/ProgressBar/AbstractProgressBar.cs
index 1b02432..a9ab997 100644
--- a/src/AtomUI.Controls/ProgressBar/AbstractProgressBar.cs
+++ b/src/AtomUI.Controls/ProgressBar/AbstractProgressBar.cs
@@ -7,6 +7,7 @@ using Avalonia.Controls.Primitives;
using Avalonia.Layout;
using Avalonia.LogicalTree;
using Avalonia.Media;
+using Avalonia.Threading;
namespace AtomUI.Controls;
@@ -138,7 +139,7 @@ public abstract partial class AbstractProgressBar : RangeBaseControl, ISizeTypeA
get => GetValue(StatusProperty);
set => SetValue(StatusProperty, value);
}
-
+
protected double _percentage;
///
@@ -204,7 +205,8 @@ public abstract partial class AbstractProgressBar : RangeBaseControl, ISizeTypeA
TrailColorProperty,
StrokeThicknessProperty,
SuccessThresholdBrushProperty,
- SuccessThresholdProperty);
+ SuccessThresholdProperty,
+ ValueProperty);
}
public AbstractProgressBar()
@@ -246,6 +248,7 @@ public abstract partial class AbstractProgressBar : RangeBaseControl, ISizeTypeA
Padding = new Thickness(0),
VerticalContentAlignment = VerticalAlignment.Center,
};
+ BindUtils.RelayBind(this, "IsEnabled", _percentageLabel);
}
return _percentageLabel;
@@ -282,7 +285,6 @@ public abstract partial class AbstractProgressBar : RangeBaseControl, ISizeTypeA
_exceptionCompletedIcon.IsVisible = true;
_successCompletedIcon.IsVisible = false;
} else {
- _percentageLabel.Content = string.Format(ProgressTextFormat, _percentage);
if (NumberUtils.FuzzyEqual(100, Percentage)) {
_percentageLabel.IsVisible = false;
_successCompletedIcon.IsVisible = true;
@@ -291,11 +293,12 @@ public abstract partial class AbstractProgressBar : RangeBaseControl, ISizeTypeA
_exceptionCompletedIcon.IsVisible = false;
_percentageLabel.IsVisible = true;
}
+ _percentageLabel.Content = string.Format(ProgressTextFormat, _percentage);
}
NotifyHandleExtraInfoVisibility();
}
}
- protected virtual void NotifyHandleExtraInfoVisibility() {}
+ protected virtual void NotifyHandleExtraInfoVisibility() { }
}
\ No newline at end of file
diff --git a/src/AtomUI.Controls/ProgressBar/AbstractProgressBarStyle.cs b/src/AtomUI.Controls/ProgressBar/AbstractProgressBarStyle.cs
index 9545885..e609619 100644
--- a/src/AtomUI.Controls/ProgressBar/AbstractProgressBarStyle.cs
+++ b/src/AtomUI.Controls/ProgressBar/AbstractProgressBarStyle.cs
@@ -1,9 +1,13 @@
using AtomUI.Data;
+using AtomUI.Icon;
+using AtomUI.Media;
using AtomUI.Styling;
using AtomUI.Utils;
using Avalonia;
using Avalonia.Animation;
+using Avalonia.Animation.Easings;
using Avalonia.Controls;
+using Avalonia.Data;
using Avalonia.Media;
namespace AtomUI.Controls;
@@ -46,6 +50,10 @@ public partial class AbstractProgressBar : IControlCustomStyle
void IControlCustomStyle.SetupTransitions()
{
var transitions = new Transitions();
+
+ transitions.Add(AnimationUtils.CreateTransition(ValueProperty, GlobalResourceKey.MotionDurationVerySlow, new ExponentialEaseOut()));
+ transitions.Add(AnimationUtils.CreateTransition(IndicatorBarBrushProperty, GlobalResourceKey.MotionDurationFast));
+
NotifySetupTransitions(ref transitions);
Transitions = transitions;
}
@@ -121,15 +129,28 @@ public partial class AbstractProgressBar : IControlCustomStyle
} else {
_tokenResourceBinder.AddBinding(GrooveBrushProperty, ProgressBarResourceKey.RemainingColor);
}
- _tokenResourceBinder.AddBinding(IndicatorBarBrushProperty, ProgressBarResourceKey.DefaultColor);
+
if (Status == ProgressStatus.Success || NumberUtils.FuzzyEqual(Value, Maximum)) {
_tokenResourceBinder.AddBinding(IndicatorBarBrushProperty, GlobalResourceKey.ColorSuccess);
} else if (Status == ProgressStatus.Exception) {
_tokenResourceBinder.AddBinding(IndicatorBarBrushProperty, GlobalResourceKey.ColorError);
+ } else {
+ _tokenResourceBinder.AddBinding(IndicatorBarBrushProperty, ProgressBarResourceKey.DefaultColor);
}
+ _tokenResourceBinder.AddBinding(ForegroundProperty, GlobalResourceKey.ColorTextLabel);
+ if (_initialized) {
+ _exceptionCompletedIcon!.IconMode = IconMode.Normal;
+ _successCompletedIcon!.IconMode = IconMode.Normal;
+ }
+
} else {
_tokenResourceBinder.AddBinding(GrooveBrushProperty, GlobalResourceKey.ColorBgContainerDisabled);
_tokenResourceBinder.AddBinding(IndicatorBarBrushProperty, GlobalResourceKey.ControlItemBgActiveDisabled);
+ _tokenResourceBinder.AddBinding(ForegroundProperty, GlobalResourceKey.ColorTextDisabled);
+ if (_initialized) {
+ _exceptionCompletedIcon!.IconMode = IconMode.Disabled;
+ _successCompletedIcon!.IconMode = IconMode.Disabled;
+ }
}
}
diff --git a/src/AtomUI.Controls/ProgressBar/CircleProgress.cs b/src/AtomUI.Controls/ProgressBar/CircleProgress.cs
index 66ba106..a350530 100644
--- a/src/AtomUI.Controls/ProgressBar/CircleProgress.cs
+++ b/src/AtomUI.Controls/ProgressBar/CircleProgress.cs
@@ -10,6 +10,7 @@ public class CircleProgress : AbstractCircleProgress
protected override void RenderGroove(DrawingContext context)
{
var controlRect = new Rect(new Point(0, 0), DesiredSize);
+
_currentGrooveRect = GetProgressBarRect(controlRect).Deflate(StrokeThickness / 2);
_currentGrooveRect = new Rect(_currentGrooveRect.Position, new Size(Math.Floor(_currentGrooveRect.Size.Width),
Math.Floor(_currentGrooveRect.Size.Height)));
@@ -55,6 +56,7 @@ public class CircleProgress : AbstractCircleProgress
{
LineCap = StrokeLineCap
};
+
double startAngle = -90;
context.DrawArc(pen, _currentGrooveRect, startAngle, IndicatorAngle);
diff --git a/src/AtomUI.Controls/ProgressBar/ProgressBar.cs b/src/AtomUI.Controls/ProgressBar/ProgressBar.cs
index a5ecac2..5b19fce 100644
--- a/src/AtomUI.Controls/ProgressBar/ProgressBar.cs
+++ b/src/AtomUI.Controls/ProgressBar/ProgressBar.cs
@@ -280,7 +280,7 @@ public partial class ProgressBar : AbstractLineProgress
} else if (PercentPosition.Alignment == LinePercentAlignment.Center) {
deflateBottom = percentLabelHeight;
} else if (PercentPosition.Alignment == LinePercentAlignment.End) {
- deflateRight = percentLabelWidth + _lineExtraInfoMargin;;
+ deflateRight = percentLabelWidth + _lineExtraInfoMargin;
}
}
}
@@ -537,6 +537,7 @@ public partial class ProgressBar : AbstractLineProgress
protected override void NotifyHandleExtraInfoVisibility()
{
+ base.NotifyHandleExtraInfoVisibility();
if (PercentPosition.IsInner) {
_exceptionCompletedIcon!.IsVisible = false;
_successCompletedIcon!.IsVisible = false;
diff --git a/src/AtomUI.Controls/RangeBaseControl.cs b/src/AtomUI.Controls/RangeBaseControl.cs
index e9c1515..ac1f948 100644
--- a/src/AtomUI.Controls/RangeBaseControl.cs
+++ b/src/AtomUI.Controls/RangeBaseControl.cs
@@ -31,7 +31,7 @@ public abstract class RangeBaseControl : StyledControl
///
public static readonly StyledProperty ValueProperty =
AvaloniaProperty.Register(nameof(Value),
- defaultBindingMode: BindingMode.TwoWay,
+ defaultBindingMode: BindingMode.OneWay,
coerce: CoerceValue);
///
diff --git a/src/AtomUI/Utils/AnimationUtils.cs b/src/AtomUI/Utils/AnimationUtils.cs
index 86c1464..d01195d 100644
--- a/src/AtomUI/Utils/AnimationUtils.cs
+++ b/src/AtomUI/Utils/AnimationUtils.cs
@@ -1,4 +1,5 @@
using AtomUI.ColorSystem;
+using AtomUI.Media;
using AtomUI.Styling;
using Avalonia;
using Avalonia.Animation;
@@ -94,7 +95,8 @@ public static class AnimationUtils
var transition = new T()
{
Property = targetProperty,
- Easing = easing
+ Easing = easing,
+
};
var application = Application.Current;
if (application is not null) {