Commit f8f50ae7 authored by Ian Hickson's avatar Ian Hickson

Merge pull request #1804 from Hixie/progress-nits

Clean-up around progress indicators.
parents d2c32750 2c69f242
...@@ -109,11 +109,15 @@ class RectTween extends Tween<Rect> { ...@@ -109,11 +109,15 @@ class RectTween extends Tween<Rect> {
Rect lerp(double t) => Rect.lerp(begin, end, t); Rect lerp(double t) => Rect.lerp(begin, end, t);
} }
/// An interpolation between two integers. /// An interpolation between two integers that rounds.
/// ///
/// This class specializes the interpolation of Tween<int> to be /// This class specializes the interpolation of Tween<int> to be
/// appropriate for integers by interpolating between the given begin and end /// appropriate for integers by interpolating between the given begin
/// values and then rounding the result to the nearest integer. /// and end values and then rounding the result to the nearest
/// integer.
///
/// This is the closest approximation to a linear tween that is
/// possible with an integer. Compare to [StepTween].
class IntTween extends Tween<int> { class IntTween extends Tween<int> {
IntTween({ int begin, int end }) : super(begin: begin, end: end); IntTween({ int begin, int end }) : super(begin: begin, end: end);
...@@ -122,6 +126,23 @@ class IntTween extends Tween<int> { ...@@ -122,6 +126,23 @@ class IntTween extends Tween<int> {
int lerp(double t) => (begin + (end - begin) * t).round(); int lerp(double t) => (begin + (end - begin) * t).round();
} }
/// An interpolation between two integers that floors.
///
/// This class specializes the interpolation of Tween<int> to be
/// appropriate for integers by interpolating between the given begin
/// and end values and then using [int.floor()] to return the current
/// integer component, dropping the fractional component.
///
/// This results in a value that is never greater than the equivalent
/// value from a linear double interpolation. Compare to [IntTween].
class StepTween extends Tween<int> {
StepTween({ int begin, int end }) : super(begin: begin, end: end);
// The inherited lerp() function doesn't work with ints because it multiplies
// the begin and end types by a double, and int * double returns a double.
int lerp(double t) => (begin + (end - begin) * t).floor();
}
/// Transforms the value of the given animation by the given curve. /// Transforms the value of the given animation by the given curve.
/// ///
/// This class differs from [CurvedAnimation] in that [CurvedAnimation] applies /// This class differs from [CurvedAnimation] in that [CurvedAnimation] applies
......
...@@ -12,7 +12,7 @@ const double _kLinearProgressIndicatorHeight = 6.0; ...@@ -12,7 +12,7 @@ const double _kLinearProgressIndicatorHeight = 6.0;
const double _kMinCircularProgressIndicatorSize = 36.0; const double _kMinCircularProgressIndicatorSize = 36.0;
const double _kCircularProgressIndicatorStrokeWidth = 4.0; const double _kCircularProgressIndicatorStrokeWidth = 4.0;
// TODO(hansmuller) implement the support for buffer indicator // TODO(hansmuller): implement the support for buffer indicator
abstract class ProgressIndicator extends StatefulComponent { abstract class ProgressIndicator extends StatefulComponent {
ProgressIndicator({ ProgressIndicator({
...@@ -78,23 +78,6 @@ class LinearProgressIndicator extends ProgressIndicator { ...@@ -78,23 +78,6 @@ class LinearProgressIndicator extends ProgressIndicator {
}) : super(key: key, value: value); }) : super(key: key, value: value);
_LinearProgressIndicatorState createState() => new _LinearProgressIndicatorState(); _LinearProgressIndicatorState createState() => new _LinearProgressIndicatorState();
Widget _buildIndicator(BuildContext context, double animationValue) {
return new Container(
constraints: new BoxConstraints.tightFor(
width: double.INFINITY,
height: _kLinearProgressIndicatorHeight
),
child: new CustomPaint(
painter: new _LinearProgressIndicatorPainter(
backgroundColor: _getBackgroundColor(context),
valueColor: _getValueColor(context),
value: value,
animationValue: animationValue
)
)
);
}
} }
class _LinearProgressIndicatorState extends State<LinearProgressIndicator> { class _LinearProgressIndicatorState extends State<LinearProgressIndicator> {
...@@ -109,14 +92,31 @@ class _LinearProgressIndicatorState extends State<LinearProgressIndicator> { ...@@ -109,14 +92,31 @@ class _LinearProgressIndicatorState extends State<LinearProgressIndicator> {
_animation = new CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn); _animation = new CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn);
} }
Widget _buildIndicator(BuildContext context, double animationValue) {
return new Container(
constraints: new BoxConstraints.tightFor(
width: double.INFINITY,
height: _kLinearProgressIndicatorHeight
),
child: new CustomPaint(
painter: new _LinearProgressIndicatorPainter(
backgroundColor: config._getBackgroundColor(context),
valueColor: config._getValueColor(context),
value: config.value, // may be null
animationValue: animationValue // ignored if config.value is not null
)
)
);
}
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (config.value != null) if (config.value != null)
return config._buildIndicator(context, _animation.value); return _buildIndicator(context, _animation.value);
return new AnimatedBuilder( return new AnimatedBuilder(
animation: _animation, animation: _animation,
builder: (BuildContext context, Widget child) { builder: (BuildContext context, Widget child) {
return config._buildIndicator(context, _animation.value); return _buildIndicator(context, _animation.value);
} }
); );
} }
...@@ -152,14 +152,14 @@ class _CircularProgressIndicatorPainter extends CustomPainter { ...@@ -152,14 +152,14 @@ class _CircularProgressIndicatorPainter extends CustomPainter {
..style = PaintingStyle.stroke; ..style = PaintingStyle.stroke;
if (value != null) { if (value != null) {
// Determinite // Determinate
double angle = value.clamp(0.0, 1.0) * _kSweep; double angle = value.clamp(0.0, 1.0) * _kSweep;
Path path = new Path() Path path = new Path()
..arcTo(Point.origin & size, _kStartAngle, angle, false); ..arcTo(Point.origin & size, _kStartAngle, angle, false);
canvas.drawPath(path, paint); canvas.drawPath(path, paint);
} else { } else {
// Non-determinite // Non-determinate
paint.strokeCap = StrokeCap.square; paint.strokeCap = StrokeCap.square;
double arcSweep = math.max(headValue * 3 / 2 * math.PI - tailValue * 3 / 2 * math.PI, _kEpsilon); double arcSweep = math.max(headValue * 3 / 2 * math.PI - tailValue * 3 / 2 * math.PI, _kEpsilon);
...@@ -189,28 +189,9 @@ class CircularProgressIndicator extends ProgressIndicator { ...@@ -189,28 +189,9 @@ class CircularProgressIndicator extends ProgressIndicator {
}) : super(key: key, value: value); }) : super(key: key, value: value);
_CircularProgressIndicatorState createState() => new _CircularProgressIndicatorState(); _CircularProgressIndicatorState createState() => new _CircularProgressIndicatorState();
Widget _buildIndicator(BuildContext context, double headValue, double tailValue, int stepValue, double rotationValue) {
return new Container(
constraints: new BoxConstraints(
minWidth: _kMinCircularProgressIndicatorSize,
minHeight: _kMinCircularProgressIndicatorSize
),
child: new CustomPaint(
painter: new _CircularProgressIndicatorPainter(
valueColor: _getValueColor(context),
value: value,
headValue: headValue,
tailValue: tailValue,
stepValue: stepValue,
rotationValue: rotationValue
)
)
);
}
} }
// TODO(jestelle) This should probably go somewhere else? And maybe be more
// general? // This class assumes that the incoming animation is a linear 0.0..1.0.
class _RepeatingCurveTween extends Animatable<double> { class _RepeatingCurveTween extends Animatable<double> {
_RepeatingCurveTween({ this.curve, this.repeats }); _RepeatingCurveTween({ this.curve, this.repeats });
...@@ -229,31 +210,23 @@ class _RepeatingCurveTween extends Animatable<double> { ...@@ -229,31 +210,23 @@ class _RepeatingCurveTween extends Animatable<double> {
} }
} }
// TODO(jestelle) This should probably go somewhere else? And maybe be more
// general? Or maybe the IntTween should actually work this way?
class _StepTween extends Tween<int> {
_StepTween({ int begin, int end }) : super(begin: begin, end: end);
// The inherited lerp() function doesn't work with ints because it multiplies
// the begin and end types by a double, and int * double returns a double.
int lerp(double t) => (begin + (end - begin) * t).floor();
}
// Tweens used by circular progress indicator // Tweens used by circular progress indicator
final _RepeatingCurveTween _kStrokeHeadTween = final _RepeatingCurveTween _kStrokeHeadTween = new _RepeatingCurveTween(
new _RepeatingCurveTween( curve: new Interval(0.0, 0.5, curve: Curves.fastOutSlowIn),
curve:new Interval(0.0, 0.5, curve: Curves.fastOutSlowIn), repeats: 5
repeats:5); );
final _RepeatingCurveTween _kStrokeTailTween = final _RepeatingCurveTween _kStrokeTailTween = new _RepeatingCurveTween(
new _RepeatingCurveTween( curve: new Interval(0.5, 1.0, curve: Curves.fastOutSlowIn),
curve:new Interval(0.5, 1.0, curve: Curves.fastOutSlowIn), repeats: 5
repeats:5); );
final _StepTween _kStepTween = new _StepTween(begin:0, end:5); final StepTween _kStepTween = new StepTween(begin: 0, end: 5);
final _RepeatingCurveTween _kRotationTween = final _RepeatingCurveTween _kRotationTween = new _RepeatingCurveTween(
new _RepeatingCurveTween(curve:Curves.linear, repeats:5); curve: Curves.linear,
repeats: 5
);
class _CircularProgressIndicatorState extends State<CircularProgressIndicator> { class _CircularProgressIndicatorState extends State<CircularProgressIndicator> {
AnimationController _animationController; AnimationController _animationController;
...@@ -265,18 +238,39 @@ class _CircularProgressIndicatorState extends State<CircularProgressIndicator> { ...@@ -265,18 +238,39 @@ class _CircularProgressIndicatorState extends State<CircularProgressIndicator> {
)..repeat(); )..repeat();
} }
Widget _buildIndicator(BuildContext context, double headValue, double tailValue, int stepValue, double rotationValue) {
return new Container(
constraints: new BoxConstraints(
minWidth: _kMinCircularProgressIndicatorSize,
minHeight: _kMinCircularProgressIndicatorSize
),
child: new CustomPaint(
painter: new _CircularProgressIndicatorPainter(
valueColor: config._getValueColor(context),
value: config.value, // may be null
headValue: headValue, // remaining arguments are ignored if config.value is not null
tailValue: tailValue,
stepValue: stepValue,
rotationValue: rotationValue
)
)
);
}
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (config.value != null) if (config.value != null)
return config._buildIndicator(context, 0.0, 0.0, 0, 0.0); return _buildIndicator(context, 0.0, 0.0, 0, 0.0);
return new AnimatedBuilder( return new AnimatedBuilder(
animation: _animationController, animation: _animationController,
builder: (BuildContext context, Widget child) { builder: (BuildContext context, Widget child) {
return config._buildIndicator(context, return _buildIndicator(
context,
_kStrokeHeadTween.evaluate(_animationController), _kStrokeHeadTween.evaluate(_animationController),
_kStrokeTailTween.evaluate(_animationController), _kStrokeTailTween.evaluate(_animationController),
_kStepTween.evaluate(_animationController), _kStepTween.evaluate(_animationController),
_kRotationTween.evaluate(_animationController)); _kRotationTween.evaluate(_animationController)
);
} }
); );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment