mirror of
https://gitee.com/chinware/atomui.git
synced 2024-11-30 02:47:45 +08:00
进度条组件完成
This commit is contained in:
parent
f88a6662a6
commit
f8546846bc
@ -63,6 +63,19 @@
|
||||
</WrapPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
|
||||
<showcase:ShowCaseItem
|
||||
Title="Dynamic"
|
||||
Description="A dynamic progress bar is better.">
|
||||
<StackPanel Orientation="Vertical" Spacing="10">
|
||||
<atom:ProgressBar Value="{Binding ProgressValue}" Minimum="0" Maximum="100"/>
|
||||
<atom:CircleProgress Value="{Binding ProgressValue}" Minimum="0" Maximum="100"/>
|
||||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||||
<atom:Button SizeType="Small" Command="{Binding SubProgressValue}">Sub</atom:Button>
|
||||
<atom:Button SizeType="Small" Command="{Binding AddProgressValue}">Add</atom:Button>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
|
||||
<showcase:ShowCaseItem
|
||||
Title="Custom text format"
|
||||
Description="You can set a custom text by setting the format prop.">
|
||||
@ -86,8 +99,8 @@
|
||||
</showcase:ShowCaseItem>
|
||||
|
||||
<showcase:ShowCaseItem
|
||||
Title="Dashboard"
|
||||
Description="By setting type=dashboard, you can get a dashboard style of progress easily. Modify gapDegree to set the degree of gap.">
|
||||
Title="Progress bar with success segment"
|
||||
Description="Show several parts of progress with different status.">
|
||||
<StackPanel Orientation="Vertical" Spacing="10">
|
||||
<atom:ProgressBar Value="60" Minimum="0" Maximum="100" SuccessThreshold="30" />
|
||||
<WrapPanel Orientation="Horizontal">
|
||||
@ -277,5 +290,50 @@
|
||||
</StackPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
|
||||
<showcase:ShowCaseItem
|
||||
Title="Vertical progress bar"
|
||||
Description="Ordinary step progress bar, supports position specification of additional areas">
|
||||
<StackPanel Orientation="Horizontal" Spacing="10" Height="300">
|
||||
<atom:StepsProgressBar Value="100" Minimum="0" Maximum="100" Steps="10" Orientation="Vertical" PercentPosition="End"/>
|
||||
<atom:StepsProgressBar Value="55" Minimum="0" Maximum="100" Steps="5" Orientation="Vertical"/>
|
||||
<atom:StepsProgressBar Value="55" Minimum="0" Maximum="100" Steps="10" Orientation="Vertical" SizeType="Small"/>
|
||||
<atom:StepsProgressBar Value="55" Minimum="0" Maximum="100" Steps="6" Orientation="Vertical" PercentPosition="Start"/>
|
||||
<atom:StepsProgressBar Value="55" Minimum="0" Maximum="100" Steps="6" Orientation="Vertical" PercentPosition="Center"/>
|
||||
<atom:StepsProgressBar Value="100" Minimum="0" Maximum="100" Steps="6" Orientation="Vertical" PercentPosition="Start"/>
|
||||
</StackPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
|
||||
<showcase:ShowCaseItem
|
||||
Title="toggle disabled status"
|
||||
Description="The progress bar is in the disabled state and uses the disabled style.">
|
||||
<StackPanel Orientation="Vertical" Spacing="10">
|
||||
<atom:ProgressBar Value="30" Minimum="0" Maximum="100" IsEnabled="{Binding ToggleStatus}"/>
|
||||
<atom:ProgressBar Value="50" Minimum="0" Maximum="100" IsEnabled="{Binding ToggleStatus}"/>
|
||||
<atom:ProgressBar Value="70" Minimum="0" Maximum="100" Status="Exception" IsEnabled="{Binding ToggleStatus}"/>
|
||||
<atom:ProgressBar Value="100" Minimum="0" Maximum="100" IsEnabled="{Binding ToggleStatus}"/>
|
||||
|
||||
<atom:StepsProgressBar Value="30" Minimum="0" Maximum="100" Steps="10" IsEnabled="{Binding ToggleStatus}"/>
|
||||
<atom:StepsProgressBar Value="50" Minimum="0" Maximum="100" Steps="10" IsEnabled="{Binding ToggleStatus}"/>
|
||||
<atom:StepsProgressBar Value="70" Minimum="0" Maximum="100" Steps="10" Status="Exception" IsEnabled="{Binding ToggleStatus}"/>
|
||||
<atom:StepsProgressBar Value="100" Minimum="0" Maximum="100" Steps="10" IsEnabled="{Binding ToggleStatus}"/>
|
||||
|
||||
<WrapPanel Orientation="Horizontal">
|
||||
<atom:CircleProgress Value="75" Minimum="0" Maximum="100" SizeType="Middle" IsEnabled="{Binding ToggleStatus}"/>
|
||||
<atom:CircleProgress Value="70" Minimum="0" Maximum="100" SizeType="Middle" Status="Exception" IsEnabled="{Binding ToggleStatus}"/>
|
||||
<atom:CircleProgress Value="100" Minimum="0" Maximum="100" SizeType="Middle" IsEnabled="{Binding ToggleStatus}"/>
|
||||
</WrapPanel>
|
||||
|
||||
<WrapPanel Orientation="Horizontal">
|
||||
<atom:DashboardProgress Value="75" Minimum="0" Maximum="100" SizeType="Middle" IsEnabled="{Binding ToggleStatus}"/>
|
||||
<atom:DashboardProgress Value="70" Minimum="0" Maximum="100" SizeType="Middle" Status="Exception" IsEnabled="{Binding ToggleStatus}"/>
|
||||
<atom:DashboardProgress Value="100" Minimum="0" Maximum="100" SizeType="Middle" IsEnabled="{Binding ToggleStatus}"/>
|
||||
</WrapPanel>
|
||||
|
||||
<atom:Button Margin="0, 10, 0, 0"
|
||||
Text="{Binding ToggleDisabledText}"
|
||||
Command="{Binding ToggleEnabledStatus}"/>
|
||||
</StackPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
|
||||
</showcase:ShowCasePanel>
|
||||
</UserControl>
|
@ -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<double> ProgressValueProperty =
|
||||
AvaloniaProperty.Register<ProgressBarShowCase, double>(nameof(ProgressValue), 30);
|
||||
|
||||
public static readonly StyledProperty<string> ToggleDisabledTextProperty =
|
||||
AvaloniaProperty.Register<ProgressBarShowCase, string>(nameof(ToggleDisabledText), "Disable");
|
||||
|
||||
public static readonly StyledProperty<bool> ToggleStatusProperty =
|
||||
AvaloniaProperty.Register<ProgressBarShowCase, bool>(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";
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -39,8 +39,7 @@ public abstract partial class AbstractCircleProgress : AbstractProgressBar
|
||||
{
|
||||
HorizontalAlignmentProperty.OverrideDefaultValue<AbstractCircleProgress>(HorizontalAlignment.Left);
|
||||
VerticalAlignmentProperty.OverrideDefaultValue<AbstractCircleProgress>(VerticalAlignment.Top);
|
||||
AffectsRender<AbstractCircleProgress>(IndicatorAngleProperty,
|
||||
StepCountProperty,
|
||||
AffectsMeasure<AbstractCircleProgress>(StepCountProperty,
|
||||
StepGapProperty);
|
||||
}
|
||||
|
||||
@ -106,7 +105,6 @@ public abstract partial class AbstractCircleProgress : AbstractProgressBar
|
||||
if (ShowProgressInfo) {
|
||||
_percentageLabel!.Measure(availableSize);
|
||||
}
|
||||
|
||||
return new Size(targetSize, targetSize);
|
||||
}
|
||||
|
||||
|
@ -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<double>());
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
/// <summary>
|
||||
@ -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() { }
|
||||
}
|
@ -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<DoubleTransition>(ValueProperty, GlobalResourceKey.MotionDurationVerySlow, new ExponentialEaseOut()));
|
||||
transitions.Add(AnimationUtils.CreateTransition<SolidColorBrushTransition>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -31,7 +31,7 @@ public abstract class RangeBaseControl : StyledControl
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<double> ValueProperty =
|
||||
AvaloniaProperty.Register<RangeBaseControl, double>(nameof(Value),
|
||||
defaultBindingMode: BindingMode.TwoWay,
|
||||
defaultBindingMode: BindingMode.OneWay,
|
||||
coerce: CoerceValue);
|
||||
|
||||
/// <summary>
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user