您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

544 行
20 KiB

using System;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.rendering;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Canvas = Unity.UIWidgets.ui.Canvas;
using Color = Unity.UIWidgets.ui.Color;
namespace Unity.UIWidgets.material {
class _ProgressIndicatorContants {
public const float _kLinearProgressIndicatorHeight = 6.0f;
public const float _kMinCircularProgressIndicatorSize = 36.0f;
public const int _kIndeterminateLinearDuration = 1800;
public static readonly Animatable<float> _kStrokeHeadTween = new CurveTween(
curve: new Interval(0.0f, 0.5f, curve: Curves.fastOutSlowIn)
).chain(new CurveTween(
curve: new SawTooth(5)
));
public static readonly Animatable<float> _kStrokeTailTween = new CurveTween(
curve: new Interval(0.5f, 1.0f, curve: Curves.fastOutSlowIn)
).chain(new CurveTween(
curve: new SawTooth(5)
));
public static readonly Animatable<int> _kStepTween = new StepTween(begin: 0, end: 5);
public static readonly Animatable<float> _kRotationTween = new CurveTween(curve: new SawTooth(5));
}
public abstract class ProgressIndicator : StatefulWidget {
public ProgressIndicator(
Key key = null,
float? value = null,
Color backgroundColor = null,
Animation<Color> valueColor = null
) : base(key: key) {
this.value = value;
this.backgroundColor = backgroundColor;
this.valueColor = valueColor;
}
public readonly float? value;
public readonly Color backgroundColor;
public readonly Animation<Color> valueColor;
public Color _getBackgroundColor(BuildContext context) {
return backgroundColor ?? Theme.of(context).backgroundColor;
}
public Color _getValueColor(BuildContext context) {
return valueColor?.value ?? Theme.of(context).accentColor;
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new PercentProperty("value", value ?? 0.0f, showName: false,
ifNull: "<indeterminate>"));
}
}
class _LinearProgressIndicatorPainter : AbstractCustomPainter {
public _LinearProgressIndicatorPainter(
Color backgroundColor = null,
Color valueColor = null,
float? value = null,
float? animationValue = null
) {
this.backgroundColor = backgroundColor;
this.valueColor = valueColor;
this.value = value;
this.animationValue = animationValue;
}
public readonly Color backgroundColor;
public readonly Color valueColor;
public readonly float? value;
public readonly float? animationValue;
static readonly Curve line1Head = new Interval(
0.0f,
750.0f / _ProgressIndicatorContants._kIndeterminateLinearDuration,
curve: new Cubic(0.2f, 0.0f, 0.8f, 1.0f)
);
static readonly Curve line1Tail = new Interval(
333.0f / _ProgressIndicatorContants._kIndeterminateLinearDuration,
(333.0f + 750.0f) / _ProgressIndicatorContants._kIndeterminateLinearDuration,
curve: new Cubic(0.4f, 0.0f, 1.0f, 1.0f)
);
static readonly Curve line2Head = new Interval(
1000.0f / _ProgressIndicatorContants._kIndeterminateLinearDuration,
(1000.0f + 567.0f) / _ProgressIndicatorContants._kIndeterminateLinearDuration,
curve: new Cubic(0.0f, 0.0f, 0.65f, 1.0f)
);
static readonly Curve line2Tail = new Interval(
1267.0f / _ProgressIndicatorContants._kIndeterminateLinearDuration,
(1267.0f + 533.0f) / _ProgressIndicatorContants._kIndeterminateLinearDuration,
curve: new Cubic(0.10f, 0.0f, 0.45f, 1.0f)
);
public override void paint(Canvas canvas, Size size) {
Paint paint = new Paint();
paint.color = backgroundColor;
paint.style = PaintingStyle.fill;
canvas.drawRect(Offset.zero & size, paint);
paint.color = valueColor;
void drawBar(float x, float width) {
if (width <= 0.0f) {
return;
}
float left = x;
canvas.drawRect(new Offset(left, 0.0f) & new Size(width, size.height), paint);
}
if (value != null) {
drawBar(0.0f, value.Value.clamp(0.0f, 1.0f) * size.width);
}
else {
float x1 = size.width * line1Tail.transform(animationValue ?? 0.0f);
float width1 = size.width * line1Head.transform(animationValue ?? 0.0f) - x1;
float x2 = size.width * line2Tail.transform(animationValue ?? 0.0f);
float width2 = size.width * line2Head.transform(animationValue ?? 0.0f) - x2;
drawBar(x1, width1);
drawBar(x2, width2);
}
}
public override bool shouldRepaint(CustomPainter oldPainter) {
D.assert(oldPainter is _LinearProgressIndicatorPainter);
_LinearProgressIndicatorPainter painter = oldPainter as _LinearProgressIndicatorPainter;
return painter.backgroundColor != backgroundColor
|| painter.valueColor != valueColor
|| painter.value != value
|| painter.animationValue != animationValue;
}
}
public class LinearProgressIndicator : ProgressIndicator {
public LinearProgressIndicator(
Key key = null,
float? value = null,
Color backgroundColor = null,
Animation<Color> valueColor = null
) : base(
key: key,
value: value,
backgroundColor: backgroundColor,
valueColor: valueColor
) {
}
public override State createState() {
return new _LinearProgressIndicatorState();
}
}
class _LinearProgressIndicatorState : SingleTickerProviderStateMixin<LinearProgressIndicator> {
AnimationController _controller;
public _LinearProgressIndicatorState() {
}
public override void initState() {
base.initState();
_controller = new AnimationController(
duration: new TimeSpan(0, 0, 0, 0, _ProgressIndicatorContants._kIndeterminateLinearDuration),
vsync: this
);
if (widget.value == null) {
_controller.repeat();
}
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
if (widget.value == null && !_controller.isAnimating) {
_controller.repeat();
}
else if (widget.value != null && _controller.isAnimating) {
_controller.stop();
}
}
public override void dispose() {
_controller.dispose();
base.dispose();
}
Widget _buildIndicator(BuildContext context, float animationValue) {
return new Container(
constraints: new BoxConstraints(
minWidth: float.PositiveInfinity,
minHeight: _ProgressIndicatorContants._kLinearProgressIndicatorHeight
),
child: new CustomPaint(
painter: new _LinearProgressIndicatorPainter(
backgroundColor: widget._getBackgroundColor(context),
valueColor: widget._getValueColor(context),
value: widget.value,
animationValue: animationValue
)
)
);
}
public override Widget build(BuildContext context) {
if (widget.value != null) {
return _buildIndicator(context, _controller.value);
}
return new AnimatedBuilder(
animation: _controller.view,
builder: (BuildContext _context, Widget child) => {
return _buildIndicator(_context, _controller.value);
}
);
}
}
class _CircularProgressIndicatorPainter : AbstractCustomPainter {
public _CircularProgressIndicatorPainter(
Color backgroundColor = null,
Color valueColor = null,
float? value = null,
float? headValue = null,
float? tailValue = null,
int? stepValue = null,
float? rotationValue = null,
float? strokeWidth = null
) {
this.backgroundColor = backgroundColor;
this.valueColor = valueColor;
this.value = value;
this.headValue = headValue;
this.tailValue = tailValue;
this.stepValue = stepValue;
this.rotationValue = rotationValue;
this.strokeWidth = strokeWidth;
arcStart = value != null
? _startAngle
: _startAngle + tailValue * 3 / 2 * Mathf.PI + rotationValue * Mathf.PI * 1.7f -
stepValue * 0.8f * Mathf.PI;
arcSweep = value != null
? value.Value.clamp(0.0f, 1.0f) * _sweep
: Mathf.Max(headValue * 3 / 2 * Mathf.PI - tailValue * 3 / 2 * Mathf.PI ?? 0.0f, _epsilon);
}
public readonly Color backgroundColor;
public readonly Color valueColor;
public readonly float? value;
public readonly float? headValue;
public readonly float? tailValue;
public readonly int? stepValue;
public readonly float? rotationValue;
public readonly float? strokeWidth;
public readonly float? arcStart;
public readonly float? arcSweep;
const float _twoPi = Mathf.PI * 2.0f;
const float _epsilon = .001f;
const float _sweep = _twoPi - _epsilon;
const float _startAngle = -Mathf.PI / 2.0f;
public override void paint(Canvas canvas, Size size) {
Paint paint = new Paint();
paint.color = valueColor;
paint.strokeWidth = strokeWidth ?? 0.0f;
paint.style = PaintingStyle.stroke;
if (backgroundColor != null) {
Paint backgroundPaint = new Paint() {
color = backgroundColor,
strokeWidth = strokeWidth ?? 0.0f,
style = PaintingStyle.stroke
};
canvas.drawArc(Offset.zero & size, 0, _sweep, false, backgroundPaint);
}
if (value == null)
{
paint.strokeCap = StrokeCap.square;
}
canvas.drawArc(Offset.zero & size, arcStart ?? 0.0f, arcSweep ?? 0.0f, false, paint);
}
public override bool shouldRepaint(CustomPainter oldPainter) {
D.assert(oldPainter is _CircularProgressIndicatorPainter);
_CircularProgressIndicatorPainter painter = oldPainter as _CircularProgressIndicatorPainter;
return painter.backgroundColor != backgroundColor
|| painter.valueColor != valueColor
|| painter.value != value
|| painter.headValue != headValue
|| painter.tailValue != tailValue
|| painter.stepValue != stepValue
|| painter.rotationValue != rotationValue
|| painter.strokeWidth != strokeWidth;
}
}
public class CircularProgressIndicator : ProgressIndicator {
public CircularProgressIndicator(
Key key = null,
float? value = null,
Color backgroundColor = null,
Animation<Color> valueColor = null,
float strokeWidth = 4.0f
) : base(
key: key,
value: value,
backgroundColor: backgroundColor,
valueColor: valueColor
) {
this.strokeWidth = strokeWidth;
}
public readonly float? strokeWidth;
public override State createState() {
return new _CircularProgressIndicatorState();
}
}
class _CircularProgressIndicatorState : SingleTickerProviderStateMixin<CircularProgressIndicator> {
protected AnimationController _controller;
public _CircularProgressIndicatorState() {
}
public override void initState() {
base.initState();
_controller = new AnimationController(
duration: new TimeSpan(0, 0, 0, 5),
vsync: this
);
if (widget.value == null) {
_controller.repeat();
}
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
if (widget.value == null && !_controller.isAnimating) {
_controller.repeat();
}
else if (widget.value != null && _controller.isAnimating) {
_controller.stop();
}
}
public override void dispose() {
_controller.dispose();
base.dispose();
}
Widget _buildIndicator(BuildContext context, float headValue, float tailValue, int stepValue,
float rotationValue) {
return new Container(
constraints: new BoxConstraints(
minWidth: _ProgressIndicatorContants._kMinCircularProgressIndicatorSize,
minHeight: _ProgressIndicatorContants._kMinCircularProgressIndicatorSize
),
child: new CustomPaint(
painter: new _CircularProgressIndicatorPainter(
backgroundColor: widget.backgroundColor,
valueColor: widget._getValueColor(context),
value: widget.value,
headValue: headValue,
tailValue: tailValue,
stepValue: stepValue,
rotationValue: rotationValue,
strokeWidth: widget.strokeWidth
)
)
);
}
protected Widget _buildAnimation() {
return new AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) => {
return _buildIndicator(
context,
_ProgressIndicatorContants._kStrokeHeadTween.evaluate(_controller),
_ProgressIndicatorContants._kStrokeTailTween.evaluate(_controller),
_ProgressIndicatorContants._kStepTween.evaluate(_controller),
_ProgressIndicatorContants._kRotationTween.evaluate(_controller)
);
}
);
}
public override Widget build(BuildContext context) {
if (widget.value != null) {
return _buildIndicator(context, 0.0f, 0.0f, 0, 0.0f);
}
return _buildAnimation();
}
}
class _RefreshProgressIndicatorPainter : _CircularProgressIndicatorPainter {
public _RefreshProgressIndicatorPainter(
Color valueColor = null,
float? value = null,
float? headValue = null,
float? tailValue = null,
int? stepValue = null,
float? rotationValue = null,
float? strokeWidth = null,
float? arrowheadScale = null
) : base(
valueColor: valueColor,
value: value,
headValue: headValue,
tailValue: tailValue,
stepValue: stepValue,
rotationValue: rotationValue,
strokeWidth: strokeWidth
) {
this.arrowheadScale = arrowheadScale;
}
public readonly float? arrowheadScale;
void paintArrowhead(Canvas canvas, Size size) {
float arcEnd = arcStart + arcSweep ?? 0.0f;
float ux = Mathf.Cos(arcEnd);
float uy = Mathf.Sin(arcEnd);
D.assert(size.width == size.height);
float radius = size.width / 2.0f;
float? arrowheadPointX = radius + ux * radius + -uy * strokeWidth * 2.0f * arrowheadScale;
float? arrowheadPointY = radius + uy * radius + ux * strokeWidth * 2.0f * arrowheadScale;
float? arrowheadRadius = strokeWidth * 1.5f * arrowheadScale;
float? innerRadius = radius - arrowheadRadius;
float? outerRadius = radius + arrowheadRadius;
Path path = new Path();
path.moveTo(radius + ux * innerRadius ?? 0.0f, radius + uy * innerRadius ?? 0.0f);
path.lineTo(radius + ux * outerRadius ?? 0.0f, radius + uy * outerRadius ?? 0.0f);
path.lineTo(arrowheadPointX ?? 0.0f, arrowheadPointY ?? 0.0f);
path.close();
Paint paint = new Paint();
paint.color = valueColor;
paint.strokeWidth = strokeWidth ?? 0.0f;
paint.style = PaintingStyle.fill;
canvas.drawPath(path, paint);
}
public override void paint(Canvas canvas, Size size) {
base.paint(canvas, size);
if (arrowheadScale > 0.0) {
paintArrowhead(canvas, size);
}
}
}
public class RefreshProgressIndicator : CircularProgressIndicator {
public RefreshProgressIndicator(
Key key = null,
float? value = null,
Color backgroundColor = null,
Animation<Color> valueColor = null,
float strokeWidth = 2.0f
) : base(
key: key,
value: value,
backgroundColor: backgroundColor,
valueColor: valueColor,
strokeWidth: strokeWidth
) {
}
public override State createState() {
return new _RefreshProgressIndicatorState();
}
}
class _RefreshProgressIndicatorState : _CircularProgressIndicatorState {
const float _indicatorSize = 40.0f;
public _RefreshProgressIndicatorState() {
}
public override Widget build(BuildContext context) {
if (widget.value != null) {
_controller.setValue(widget.value / 10.0f ?? 0.0f);
}
else if (!_controller.isAnimating) {
_controller.repeat();
}
return _buildAnimation();
}
Widget _buildIndicator(BuildContext context, float headValue, float tailValue, int stepValue,
float rotationValue) {
float arrowheadScale =
widget.value == null ? 0.0f : (widget.value * 2.0f).Value.clamp(0.0f, 1.0f);
return new Container(
width: _indicatorSize,
height: _indicatorSize,
margin: EdgeInsets.all(4.0f),
child: new Material(
type: MaterialType.circle,
color: widget.backgroundColor ?? Theme.of(context).canvasColor,
elevation: 2.0f,
child: new Padding(
padding: EdgeInsets.all(12.0f),
child: new CustomPaint(
painter: new _RefreshProgressIndicatorPainter(
valueColor: widget._getValueColor(context),
value: null,
headValue: headValue,
tailValue: tailValue,
stepValue: stepValue,
rotationValue: rotationValue,
strokeWidth: widget.strokeWidth,
arrowheadScale: arrowheadScale
)
)
)
)
);
}
}
}