diff --git a/example/lib/home.dart b/example/lib/home.dart index 19b41578..4ff245a3 100644 --- a/example/lib/home.dart +++ b/example/lib/home.dart @@ -11,7 +11,6 @@ import 'package:zeta_example/pages/components/chip_example.dart'; import 'package:zeta_example/pages/theme/color_example.dart'; import 'package:zeta_example/pages/components/password_input_example.dart'; import 'package:zeta_example/pages/components/progress_example.dart'; - import 'package:zeta_example/pages/assets/icons_example.dart'; import 'package:zeta_example/widgets.dart'; import 'package:zeta_flutter/zeta_flutter.dart'; diff --git a/example/lib/pages/components/progress_example.dart b/example/lib/pages/components/progress_example.dart index 84167758..c5c8c69d 100644 --- a/example/lib/pages/components/progress_example.dart +++ b/example/lib/pages/components/progress_example.dart @@ -20,29 +20,48 @@ class ProgressExampleState extends State { child: SingleChildScrollView( child: SizedBox( width: double.infinity, - child: Column(children: [ - Wrapper( - stepsCompleted: 10, - isThin: true, - ), - SizedBox( - height: 20, - ), - Wrapper( + child: Column( + children: [ + Text('Progress Bars', style: ZetaTextStyles.displayMedium), + SizedBox( + height: 20, + ), + Wrapper( + stepsCompleted: 10, + isThin: true, + ), + SizedBox( + height: 20, + ), + Wrapper( + stepsCompleted: 0, + type: ZetaBarType.standard, + isThin: false, + stateChangeable: true), + SizedBox( + height: 20, + ), + Wrapper( stepsCompleted: 0, - type: ZetaBarType.standard, + type: ZetaBarType.indeterminate, isThin: false, - stateChangeable: true), - SizedBox( - height: 20, - ), - Wrapper( - stepsCompleted: 0, - type: ZetaBarType.indeterminate, - isThin: false, - label: "UPLOADING ...", - ), - ]), + label: "UPLOADING ...", + ), + SizedBox( + height: 20, + ), + Text('Progress CIrcles', style: ZetaTextStyles.displayMedium), + SizedBox( + height: 80, + ), + Wrapper( + stepsCompleted: 0, + circleSize: ZetaCircleSizes.xl, + rounded: false, + isCircle: true, + ), + ], + ), ), ), ), @@ -51,21 +70,26 @@ class ProgressExampleState extends State { } class Wrapper extends StatefulWidget { - const Wrapper( - {super.key, - required this.stepsCompleted, - this.type = ZetaBarType.standard, - this.isThin = false, - this.rounded = true, - this.stateChangeable = false, - this.label}); + const Wrapper({ + super.key, + required this.stepsCompleted, + this.type = ZetaBarType.standard, + this.isThin = false, + this.rounded = true, + this.stateChangeable = false, + this.label, + this.isCircle = false, + this.circleSize, + }); final int stepsCompleted; - final bool rounded; - final ZetaBarType type; - final bool isThin; + final bool? rounded; + final ZetaBarType? type; + final bool? isThin; final String? label; - final bool stateChangeable; + final bool? stateChangeable; + final bool isCircle; + final ZetaCircleSizes? circleSize; @override State createState() => _WrapperState(); @@ -79,7 +103,7 @@ class _WrapperState extends State { @override void initState() { super.initState(); - type = widget.type; + type = widget.type!; stepsCompleted = widget.stepsCompleted; progress = stepsCompleted / 10; } @@ -105,15 +129,22 @@ class _WrapperState extends State { return Column( // Replace with a Column for vertical children: [ - SizedBox( - width: 400, - child: ZetaProgressBar( - progress: progress, - rounded: widget.rounded, - type: type, - isThin: widget.isThin, - label: widget.label), - ), + widget.isCircle + ? Center( + child: ZetaProgressCircle( + progress: progress, + size: widget.circleSize!, + ), + ) + : SizedBox( + width: 400, + child: ZetaProgressBar( + progress: progress, + rounded: widget.rounded!, + type: type, + isThin: widget.isThin!, + label: widget.label), + ), const SizedBox(width: 40), Row( mainAxisAlignment: MainAxisAlignment.center, @@ -123,10 +154,10 @@ class _WrapperState extends State { onPressed: increasePercentage, child: Text("Increase")) : Container(), const SizedBox(width: 40), - widget.stateChangeable + widget.stateChangeable! ? FilledButton( onPressed: setLoading, child: Text("Start Buffering")) - : Container() + : SizedBox.shrink() ], ) ], diff --git a/lib/src/components/progress/progress_circle.dart b/lib/src/components/progress/progress_circle.dart new file mode 100644 index 00000000..3e52667d --- /dev/null +++ b/lib/src/components/progress/progress_circle.dart @@ -0,0 +1,127 @@ +import 'dart:math' as math; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +import '../../../zeta_flutter.dart'; +import 'progress.dart'; + +/// Sizes for [ZetaProgressCircle] +enum ZetaCircleSizes { + ///24 X 24 + xs, + + /// 36 X 36 + s, + + /// 40 x 40 + m, + + /// 48 X 48 + l, + + /// 64 X 64 + xl +} + +///Class definition for [ZetaProgressCircle] +class ZetaProgressCircle extends ZetaProgress { + /// Constructor for [ZetaProgressCircle] + const ZetaProgressCircle({ + super.key, + super.progress = 0, + this.size = ZetaCircleSizes.xl, + this.rounded = true, + }); + + ///Size of [ZetaProgressCircle] + final ZetaCircleSizes size; + + /// Border Type for [ZetaWidgetBorder] + final bool rounded; + + @override + State createState() => ZetaProgressCircleState(); + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(EnumProperty('size', size)) + ..add(DoubleProperty('progress', progress)) + ..add(DiagnosticsProperty('rounded', rounded)); + } +} + +///Class definition for [ZetaProgressCircleState] +class ZetaProgressCircleState extends ZetaProgressState { + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: controller, + builder: (context, child) { + return CustomPaint( + size: _getSize(), + painter: CirclePainter( + progress: animation.value, + rounded: widget.rounded, + ), + ); + }, + ); + } + + Size _getSize() { + switch (widget.size) { + case ZetaCircleSizes.xs: + return const Size(24, 24); + case ZetaCircleSizes.s: + return const Size(36, 36); + case ZetaCircleSizes.m: + return const Size(40, 40); + case ZetaCircleSizes.l: + return const Size(48, 48); + case ZetaCircleSizes.xl: + return const Size(64, 64); + } + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + ..add(DoubleProperty('progress', progress)) + ..add(DiagnosticsProperty('controller', controller)) + ..add(DiagnosticsProperty>('animation', animation)); + } +} + +///Class definition for [CirclePainter] +class CirclePainter extends CustomPainter { + ///Constructor for [CirclePainter] + CirclePainter({this.progress = 0, this.rounded = true}); + + ///Percentage of progress in decimal value, defaults to 0 + final double progress; + + ///Is circle rounded, defaults to true + final bool rounded; + + final _paint = Paint() + ..color = Colors.blue + ..strokeWidth = 4 + ..style = PaintingStyle.stroke; + + @override + void paint(Canvas canvas, Size size) { + if (rounded) _paint.strokeCap = StrokeCap.round; + + const double fullCircle = 2 * math.pi; + + canvas.drawArc(Rect.fromLTRB(0, 0, size.width, size.height), + 3 * math.pi / 2, progress * fullCircle, false, _paint); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/lib/zeta_flutter.dart b/lib/zeta_flutter.dart index 3bffd1dd..ae853ad5 100644 --- a/lib/zeta_flutter.dart +++ b/lib/zeta_flutter.dart @@ -22,6 +22,7 @@ export 'src/components/checkbox/checkbox.dart'; export 'src/components/chips/chip.dart'; export 'src/components/password/password_input.dart'; export 'src/components/progress/progress_bar.dart'; +export 'src/components/progress/progress_circle.dart'; export 'src/theme/color_extensions.dart'; export 'src/theme/color_scheme.dart'; export 'src/theme/color_swatch.dart';