flutter_flutter/packages/flutter/lib/src/material/progress_indicator.dart
Hixie f2cc43a483 Lots of trivial warning fixes
Add type annotations in many places.
Fix some identifiers to have more lint-satisfying names.
Make all operator==s consistent in style.
Reorder some functions for consistency.
Make ParentData no longer dynamic, and fix all the code around that.
2015-10-12 16:31:20 -07:00

164 lines
5.4 KiB
Dart

// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' as ui;
import 'package:flutter/animation.dart';
import 'package:flutter/widgets.dart';
import 'theme.dart';
const double _kLinearProgressIndicatorHeight = 6.0;
const double _kMinCircularProgressIndicatorSize = 15.0;
const double _kCircularProgressIndicatorStrokeWidth = 3.0;
abstract class ProgressIndicator extends StatefulComponent {
ProgressIndicator({
Key key,
this.value,
this.bufferValue
}) : super(key: key);
final double value; // Null for non-determinate progress indicator.
final double bufferValue; // TODO(hansmuller) implement the support for this.
Color _getBackgroundColor(BuildContext context) => Theme.of(context).primarySwatch[200];
Color _getValueColor(BuildContext context) => Theme.of(context).primaryColor;
Object _getCustomPaintToken(double performanceValue) => value != null ? value : performanceValue;
Widget _buildIndicator(BuildContext context, double performanceValue);
_ProgressIndicatorState createState() => new _ProgressIndicatorState();
}
class _ProgressIndicatorState extends State<ProgressIndicator> {
ValuePerformance<double> _performance;
void initState() {
super.initState();
_performance = new ValuePerformance<double>(
variable: new AnimatedValue<double>(0.0, end: 1.0, curve: ease),
duration: const Duration(milliseconds: 1500)
);
_performance.addStatusListener((PerformanceStatus status) {
if (status == PerformanceStatus.completed)
_restartAnimation();
});
_performance.play();
}
void _restartAnimation() {
_performance.progress = 0.0;
_performance.play();
}
Widget build(BuildContext context) {
if (config.value != null)
return config._buildIndicator(context, _performance.value);
return new BuilderTransition(
variables: <AnimatedValue<double>>[_performance.variable],
performance: _performance.view,
builder: (BuildContext context) {
return config._buildIndicator(context, _performance.value);
}
);
}
}
class LinearProgressIndicator extends ProgressIndicator {
LinearProgressIndicator({
Key key,
double value,
double bufferValue
}) : super(key: key, value: value, bufferValue: bufferValue);
void _paint(BuildContext context, double performanceValue, ui.Canvas canvas, Size size) {
Paint paint = new Paint()
..color = _getBackgroundColor(context)
..setStyle(ui.PaintingStyle.fill);
canvas.drawRect(Point.origin & size, paint);
paint.color = _getValueColor(context);
if (value != null) {
double width = value.clamp(0.0, 1.0) * size.width;
canvas.drawRect(Point.origin & new Size(width, size.height), paint);
} else {
double startX = size.width * (1.5 * performanceValue - 0.5);
double endX = startX + 0.5 * size.width;
double x = startX.clamp(0.0, size.width);
double width = endX.clamp(0.0, size.width) - x;
canvas.drawRect(new Point(x, 0.0) & new Size(width, size.height), paint);
}
}
Widget _buildIndicator(BuildContext context, double performanceValue) {
return new Container(
constraints: new BoxConstraints.tightFor(
width: double.INFINITY,
height: _kLinearProgressIndicatorHeight
),
child: new CustomPaint(
token: _getCustomPaintToken(performanceValue),
callback: (ui.Canvas canvas, Size size) {
_paint(context, performanceValue, canvas, size);
}
)
);
}
}
class CircularProgressIndicator extends ProgressIndicator {
static const _kTwoPI = math.PI * 2.0;
static const _kEpsilon = .0000001;
// Canavs.drawArc(r, 0, 2*PI) doesn't draw anything, so just get close.
static const _kSweep = _kTwoPI - _kEpsilon;
static const _kStartAngle = -math.PI / 2.0;
CircularProgressIndicator({
Key key,
double value,
double bufferValue
}) : super(key: key, value: value, bufferValue: bufferValue);
void _paint(BuildContext context, double performanceValue, ui.Canvas canvas, Size size) {
Paint paint = new Paint()
..color = _getValueColor(context)
..strokeWidth = _kCircularProgressIndicatorStrokeWidth
..setStyle(ui.PaintingStyle.stroke);
if (value != null) {
double angle = value.clamp(0.0, 1.0) * _kSweep;
ui.Path path = new ui.Path()
..arcTo(Point.origin & size, _kStartAngle, angle, false);
canvas.drawPath(path, paint);
} else {
double startAngle = _kTwoPI * (1.75 * performanceValue - 0.75);
double endAngle = startAngle + _kTwoPI * 0.75;
double arcAngle = startAngle.clamp(0.0, _kTwoPI);
double arcSweep = endAngle.clamp(0.0, _kTwoPI) - arcAngle;
ui.Path path = new ui.Path()
..arcTo(Point.origin & size, _kStartAngle + arcAngle, arcSweep, false);
canvas.drawPath(path, paint);
}
}
Widget _buildIndicator(BuildContext context, double performanceValue) {
return new Container(
constraints: new BoxConstraints(
minWidth: _kMinCircularProgressIndicatorSize,
minHeight: _kMinCircularProgressIndicatorSize
),
child: new CustomPaint(
token: _getCustomPaintToken(performanceValue),
callback: (ui.Canvas canvas, Size size) {
_paint(context, performanceValue, canvas, size);
}
)
);
}
}