mirror of
https://gitee.com/chinware/atomui.git
synced 2024-12-02 03:47:52 +08:00
完成step类型的圆形进度条
This commit is contained in:
parent
d6af986747
commit
d3440d5f40
@ -136,5 +136,26 @@
|
||||
StepsStrokeBrush="{Binding StepsChunkBrushes}"/>
|
||||
</StackPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
|
||||
<showcase:ShowCaseItem
|
||||
Title="Circular progress bar whit steps"
|
||||
Description="A circular progress bar that support steps and color segments, default gap is 2px.">
|
||||
<StackPanel Orientation="Vertical" Spacing="5">
|
||||
<WrapPanel Orientation="Horizontal">
|
||||
<atom:CircleProgress Value="50" Minimum="0" Maximum="100" StepCount="4" StepGap="8" IndicatorThickness="20"/>
|
||||
<atom:CircleProgress Value="100" Minimum="0" Maximum="100" StepCount="10" StepGap="8" IndicatorThickness="20"/>
|
||||
<atom:CircleProgress Value="77" Minimum="0" Maximum="100" StepCount="8" StepGap="10" IndicatorThickness="20" Status="Exception"/>
|
||||
<atom:CircleProgress Value="77" Minimum="0" Maximum="100" StepCount="8" StepGap="10" IndicatorThickness="20"
|
||||
SuccessThreshold="30"/>
|
||||
</WrapPanel>
|
||||
<WrapPanel Orientation="Horizontal">
|
||||
<atom:DashboardProgress Value="50" Minimum="0" Maximum="100" StepCount="4" StepGap="8" IndicatorThickness="20"/>
|
||||
<atom:DashboardProgress Value="70" Minimum="0" Maximum="100" StepCount="10" StepGap="8" IndicatorThickness="20"/>
|
||||
<atom:DashboardProgress Value="77" Minimum="0" Maximum="100" StepCount="8" StepGap="10" IndicatorThickness="20" Status="Exception"/>
|
||||
<atom:DashboardProgress Value="77" Minimum="0" Maximum="100" StepCount="8" StepGap="10" IndicatorThickness="20"
|
||||
SuccessThreshold="30"/>
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
</showcase:ShowCaseItem>
|
||||
</showcase:ShowCasePanel>
|
||||
</UserControl>
|
@ -14,13 +14,33 @@ public abstract partial class AbstractCircleProgress : AbstractProgressBar
|
||||
protected const double SMALL_CIRCLE_SIZE = 60;
|
||||
protected const double CIRCLE_MIN_STROKE_THICKNESS = 3;
|
||||
|
||||
public static readonly StyledProperty<int> StepCountProperty =
|
||||
AvaloniaProperty.Register<ProgressBar, int>(nameof(StepCount), 0, coerce:(o, v) => Math.Max(v, 0));
|
||||
|
||||
public static readonly StyledProperty<double> StepGapProperty =
|
||||
AvaloniaProperty.Register<ProgressBar, double>(nameof(StepGap), 2, coerce:(o, v) => Math.Max(v, 0));
|
||||
|
||||
public int StepCount
|
||||
{
|
||||
get => GetValue(StepCountProperty);
|
||||
set => SetValue(StepCountProperty, value);
|
||||
}
|
||||
|
||||
public double StepGap
|
||||
{
|
||||
get => GetValue(StepGapProperty);
|
||||
set => SetValue(StepGapProperty, value);
|
||||
}
|
||||
|
||||
internal Dictionary<SizeType, double> _sizeTypeThresholdValue;
|
||||
|
||||
static AbstractCircleProgress()
|
||||
{
|
||||
HorizontalAlignmentProperty.OverrideDefaultValue<AbstractCircleProgress>(HorizontalAlignment.Left);
|
||||
VerticalAlignmentProperty.OverrideDefaultValue<AbstractCircleProgress>(VerticalAlignment.Top);
|
||||
AffectsRender<AbstractCircleProgress>(IndicatorAngleProperty);
|
||||
AffectsRender<AbstractCircleProgress>(IndicatorAngleProperty,
|
||||
StepCountProperty,
|
||||
StepGapProperty);
|
||||
}
|
||||
|
||||
public AbstractCircleProgress()
|
||||
|
@ -13,11 +13,43 @@ public class CircleProgress : AbstractCircleProgress
|
||||
_currentGrooveRect = GetProgressBarRect(controlRect).Deflate(StrokeThickness / 2);
|
||||
_currentGrooveRect = new Rect(_currentGrooveRect.Position, new Size(Math.Floor(_currentGrooveRect.Size.Width),
|
||||
Math.Floor(_currentGrooveRect.Size.Height)));
|
||||
if (StepCount > 0 && StepGap > 0) {
|
||||
DrawGrooveStep(context);
|
||||
} else {
|
||||
DrawGrooveNormal(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawGrooveNormal(DrawingContext context)
|
||||
{
|
||||
var pen = new Pen(GrooveBrush, StrokeThickness);
|
||||
context.DrawEllipse(null, pen, _currentGrooveRect);
|
||||
}
|
||||
|
||||
private void DrawGrooveStep(DrawingContext context)
|
||||
{
|
||||
var pen = new Pen(GrooveBrush, StrokeThickness)
|
||||
{
|
||||
LineCap = PenLineCap.Flat
|
||||
};
|
||||
var spanAngle = (360 - StepGap * StepCount) / StepCount;
|
||||
var startAngle = -90d;
|
||||
for (int i = 0; i < StepCount; ++i) {
|
||||
context.DrawArc(pen, _currentGrooveRect, startAngle, spanAngle);
|
||||
startAngle += StepGap + spanAngle;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RenderIndicatorBar(DrawingContext context)
|
||||
{
|
||||
if (StepCount > 0 && StepGap > 0) {
|
||||
DrawIndicatorBarStep(context);
|
||||
} else {
|
||||
DrawIndicatorBarNormal(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawIndicatorBarNormal(DrawingContext context)
|
||||
{
|
||||
var pen = new Pen(IndicatorBarBrush, StrokeThickness)
|
||||
{
|
||||
@ -34,7 +66,41 @@ public class CircleProgress : AbstractCircleProgress
|
||||
context.DrawArc(successPen, _currentGrooveRect, startAngle, CalculateAngle(SuccessThreshold));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawIndicatorBarStep(DrawingContext context)
|
||||
{
|
||||
var pen = new Pen(IndicatorBarBrush, StrokeThickness)
|
||||
{
|
||||
LineCap = PenLineCap.Flat
|
||||
};
|
||||
|
||||
var filledSteps = (int)Math.Round(StepCount * Percentage / 100);
|
||||
int? successSteps = null;
|
||||
IPen? successPen = null;
|
||||
|
||||
if (!double.IsNaN(SuccessThreshold)) {
|
||||
successPen = new Pen(SuccessThresholdBrush, StrokeThickness)
|
||||
{
|
||||
LineCap = PenLineCap.Flat
|
||||
};
|
||||
successSteps = (int)Math.Round(StepCount * SuccessThreshold / (Maximum - Minimum));
|
||||
}
|
||||
|
||||
var spanAngle = (360 - StepGap * StepCount) / StepCount;
|
||||
var startAngle = -90d;
|
||||
IPen? currentPen;
|
||||
for (int i = 0; i < filledSteps; ++i) {
|
||||
currentPen = pen;
|
||||
if (successSteps.HasValue) {
|
||||
if (i < successSteps) {
|
||||
currentPen = successPen;
|
||||
}
|
||||
}
|
||||
context.DrawArc(currentPen, _currentGrooveRect, startAngle, spanAngle);
|
||||
startAngle += StepGap + spanAngle;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void NotifyUpdateProgress()
|
||||
{
|
||||
base.NotifyUpdateProgress();
|
||||
|
@ -53,16 +53,48 @@ public class DashboardProgress : AbstractCircleProgress
|
||||
{
|
||||
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)));
|
||||
if (StepCount > 0 && StepGap > 0) {
|
||||
DrawGrooveStep(context);
|
||||
} else {
|
||||
DrawGrooveNormal(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawGrooveNormal(DrawingContext context)
|
||||
{
|
||||
var pen = new Pen(GrooveBrush, StrokeThickness)
|
||||
{
|
||||
LineCap = StrokeLineCap
|
||||
};
|
||||
_currentGrooveRect = new Rect(_currentGrooveRect.Position, new Size(Math.Floor(_currentGrooveRect.Size.Width),
|
||||
Math.Floor(_currentGrooveRect.Size.Height)));
|
||||
context.DrawArc(pen, _currentGrooveRect, _anglePair.Item1, _anglePair.Item2);
|
||||
}
|
||||
|
||||
private void DrawGrooveStep(DrawingContext context)
|
||||
{
|
||||
var pen = new Pen(GrooveBrush, StrokeThickness)
|
||||
{
|
||||
LineCap = PenLineCap.Flat
|
||||
};
|
||||
var spanAngle = (360 - GapDegree - StepGap * StepCount) / StepCount;
|
||||
var startAngle = _anglePair.Item1;
|
||||
for (int i = 0; i < StepCount; ++i) {
|
||||
context.DrawArc(pen, _currentGrooveRect, startAngle, spanAngle);
|
||||
startAngle += StepGap + spanAngle;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RenderIndicatorBar(DrawingContext context)
|
||||
{
|
||||
if (StepCount > 0 && StepGap > 0) {
|
||||
DrawIndicatorBarStep(context);
|
||||
} else {
|
||||
DrawIndicatorBarNormal(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawIndicatorBarNormal(DrawingContext context)
|
||||
{
|
||||
var pen = new Pen(IndicatorBarBrush, StrokeThickness)
|
||||
{
|
||||
@ -79,6 +111,40 @@ public class DashboardProgress : AbstractCircleProgress
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawIndicatorBarStep(DrawingContext context)
|
||||
{
|
||||
var pen = new Pen(IndicatorBarBrush, StrokeThickness)
|
||||
{
|
||||
LineCap = PenLineCap.Flat
|
||||
};
|
||||
var spanAngle = (360 - GapDegree - StepGap * StepCount) / StepCount;
|
||||
var startAngle = _anglePair.Item1;
|
||||
|
||||
var filledSteps = (int)Math.Round(StepCount * Percentage / 100);
|
||||
int? successSteps = null;
|
||||
IPen? successPen = null;
|
||||
|
||||
if (!double.IsNaN(SuccessThreshold)) {
|
||||
successPen = new Pen(SuccessThresholdBrush, StrokeThickness)
|
||||
{
|
||||
LineCap = PenLineCap.Flat
|
||||
};
|
||||
successSteps = (int)Math.Round(StepCount * SuccessThreshold / (Maximum - Minimum));
|
||||
}
|
||||
|
||||
IPen? currentPen;
|
||||
for (int i = 0; i < filledSteps; ++i) {
|
||||
currentPen = pen;
|
||||
if (successSteps.HasValue) {
|
||||
if (i < successSteps) {
|
||||
currentPen = successPen;
|
||||
}
|
||||
}
|
||||
context.DrawArc(currentPen, _currentGrooveRect, startAngle, spanAngle);
|
||||
startAngle += StepGap + spanAngle;
|
||||
}
|
||||
}
|
||||
|
||||
private (double, double) CalculateAngle(DashboardGapPosition position, double gapDegree)
|
||||
{
|
||||
double startAngle = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user