From 49ef08c150e316e8214c1e86876415298cd07fae Mon Sep 17 00:00:00 2001 From: suragch Date: Fri, 23 Jul 2021 19:59:34 +0800 Subject: [PATCH] Version 0.6.1 --- CHANGELOG.md | 6 ++ .../contents.xcworkspacedata | 2 +- example/lib/main.dart | 53 ++++++++++- example/pubspec.lock | 4 +- example/pubspec.yaml | 2 +- lib/audio_video_progress_bar.dart | 88 ++++++++++++------- pubspec.yaml | 2 +- test/audio_video_progress_bar_test.dart | 87 ++++++++++++++++++ 8 files changed, 208 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 830a5b0..9f2b056 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [0.6.1] - July 23, 2021 + +* Added `timeLabelPadding` parameter for putting some extra space between the time labels and progress bar. +* Fixed a couple bugs with thumb position +* Added thumb radius and label padding controls to the sample project + ## [0.6.0] - July 20, 2021 * Made the thumb and rounded bar caps stay within bar bounds so that padding is maintained from side text (#13) diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a1..919434a 100644 --- a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/example/lib/main.dart b/example/lib/main.dart index 7f0cb01..dad877f 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -61,6 +61,8 @@ class _HomeWidgetState extends State { var _labelLocation = TimeLabelLocation.below; var _labelType = TimeLabelType.totalTime; TextStyle? _labelStyle; + var _thumbRadius = 10.0; + var _labelPadding = 0.0; @override void initState() { @@ -93,7 +95,6 @@ class _HomeWidgetState extends State { @override Widget build(BuildContext context) { - debugPrint('building app'); return Scaffold( body: SafeArea( child: Padding( @@ -104,6 +105,8 @@ class _HomeWidgetState extends State { _labelLocationButtons(), _labelTypeButtons(), _labelSizeButtons(), + _thumbSizeButtons(), + _paddingSizeButtons(), const Spacer(), _progressBar(), _playButton(), @@ -205,6 +208,52 @@ class _HomeWidgetState extends State { ]); } + Wrap _thumbSizeButtons() { + return Wrap(children: [ + OutlinedButton( + child: const Text('standard thumb radius'), + onPressed: () { + setState(() => _thumbRadius = 10); + }, + ), + OutlinedButton( + child: const Text('large'), + onPressed: () { + setState(() => _thumbRadius = 20); + }, + ), + OutlinedButton( + child: const Text('small'), + onPressed: () { + setState(() => _thumbRadius = 5); + }, + ), + ]); + } + + Wrap _paddingSizeButtons() { + return Wrap(children: [ + OutlinedButton( + child: const Text('standard padding'), + onPressed: () { + setState(() => _labelPadding = 0.0); + }, + ), + OutlinedButton( + child: const Text('10 padding'), + onPressed: () { + setState(() => _labelPadding = 10); + }, + ), + OutlinedButton( + child: const Text('-5 padding'), + onPressed: () { + setState(() => _labelPadding = -5); + }, + ), + ]); + } + StreamBuilder _progressBar() { return StreamBuilder( stream: _durationState, @@ -220,9 +269,11 @@ class _HomeWidgetState extends State { onSeek: (duration) { _player.seek(duration); }, + thumbRadius: _thumbRadius, timeLabelLocation: _labelLocation, timeLabelType: _labelType, timeLabelTextStyle: _labelStyle, + timeLabelPadding: _labelPadding, ); }, ); diff --git a/example/pubspec.lock b/example/pubspec.lock index 3ec837e..dce9a32 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -21,7 +21,7 @@ packages: path: ".." relative: true source: path - version: "0.6.0" + version: "0.6.1" boolean_selector: dependency: transitive description: @@ -120,7 +120,7 @@ packages: name: just_audio url: "https://pub.dartlang.org" source: hosted - version: "0.9.2" + version: "0.9.3" just_audio_platform_interface: dependency: transitive description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 02c76e6..9ae323f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: sdk: flutter audio_video_progress_bar: path: ../ - just_audio: ^0.9.2 + just_audio: ^0.9.3 rxdart: ^0.27.0 dev_dependencies: diff --git a/lib/audio_video_progress_bar.dart b/lib/audio_video_progress_bar.dart index dc40e72..5281979 100644 --- a/lib/audio_video_progress_bar.dart +++ b/lib/audio_video_progress_bar.dart @@ -81,6 +81,7 @@ class ProgressBar extends LeafRenderObjectWidget { this.timeLabelLocation, this.timeLabelType, this.timeLabelTextStyle, + this.timeLabelPadding = 0.0, }) : super(key: key); /// The elapsed playing time of the media. @@ -163,6 +164,12 @@ class ProgressBar extends LeafRenderObjectWidget { /// By default it is [TextTheme.bodyText1]. final TextStyle? timeLabelTextStyle; + /// The extra space between the time labels and the progress bar. + /// + /// The default is 0.0. A positive number will move the labels further from + /// the progress bar and a negative number will move them closer. + final double timeLabelPadding; + @override _RenderProgressBar createRenderObject(BuildContext context) { final theme = Theme.of(context); @@ -185,6 +192,7 @@ class ProgressBar extends LeafRenderObjectWidget { timeLabelLocation: timeLabelLocation ?? TimeLabelLocation.below, timeLabelType: timeLabelType ?? TimeLabelType.totalTime, timeLabelTextStyle: textStyle, + timeLabelPadding: timeLabelPadding, ); } @@ -210,7 +218,8 @@ class ProgressBar extends LeafRenderObjectWidget { ..thumbGlowRadius = thumbGlowRadius ..timeLabelLocation = timeLabelLocation ?? TimeLabelLocation.below ..timeLabelType = timeLabelType ?? TimeLabelType.totalTime - ..timeLabelTextStyle = textStyle; + ..timeLabelTextStyle = textStyle + ..timeLabelPadding = timeLabelPadding; } @override @@ -234,6 +243,7 @@ class ProgressBar extends LeafRenderObjectWidget { properties.add(StringProperty('timeLabelType', timeLabelType.toString())); properties .add(DiagnosticsProperty('timeLabelTextStyle', timeLabelTextStyle)); + properties.add(DoubleProperty('timeLabelPadding', timeLabelPadding)); } } @@ -254,6 +264,7 @@ class _RenderProgressBar extends RenderBox { required TimeLabelLocation timeLabelLocation, required TimeLabelType timeLabelType, TextStyle? timeLabelTextStyle, + double timeLabelPadding = 0.0, }) : _progress = progress, _total = total, _buffered = buffered, @@ -268,7 +279,8 @@ class _RenderProgressBar extends RenderBox { _thumbGlowRadius = thumbGlowRadius, _timeLabelLocation = timeLabelLocation, _timeLabelType = timeLabelType, - _timeLabelTextStyle = timeLabelTextStyle { + _timeLabelTextStyle = timeLabelTextStyle, + _timeLabelPadding = timeLabelPadding { _drag = HorizontalDragGestureRecognizer() ..onStart = _onDragStart ..onUpdate = _onDragUpdate @@ -318,11 +330,15 @@ class _RenderProgressBar extends RenderBox { double barStart; double barEnd; if (_timeLabelLocation == TimeLabelLocation.sides) { - barStart = _leftTimeLabel().width + _thumbRadius; - barEnd = size.width - _rightTimeLabel().width - _thumbRadius; + barStart = + _leftTimeLabel().width + _defaultSidePadding + _timeLabelPadding; + barEnd = size.width - + _rightTimeLabel().width - + _defaultSidePadding - + _timeLabelPadding; } else { - barStart = _thumbRadius; - barEnd = size.width - _thumbRadius; + barStart = 0; + barEnd = size.width; } final barWidth = barEnd - barStart; final position = (dx - barStart).clamp(0.0, barWidth); @@ -507,6 +523,20 @@ class _RenderProgressBar extends RenderBox { markNeedsLayout(); } + /// The length of the radius for the circular thumb. + double get timeLabelPadding => _timeLabelPadding; + double _timeLabelPadding; + set timeLabelPadding(double value) { + if (_timeLabelPadding == value) return; + _timeLabelPadding = value; + markNeedsLayout(); + } + + // This padding is always used between the time labels and the progress bar + // when the time labels are on the sides. Any user defined [timeLabelPadding] + // is in addition to this. + static const _defaultSidePadding = 10; + // The smallest that this widget would ever want to be. static const _minDesiredWidth = 100.0; @@ -561,7 +591,7 @@ class _RenderProgressBar extends RenderBox { } double _heightWhenLabelsAboveOrBelow() { - return _heightWhenNoLabels() + _textHeight(); + return _heightWhenNoLabels() + _textHeight() + _timeLabelPadding; } double _heightWhenLabelsOnSides() { @@ -618,7 +648,7 @@ class _RenderProgressBar extends RenderBox { final isLabelBelow = _timeLabelLocation == TimeLabelLocation.below; // current time label - final labelDy = (isLabelBelow) ? barHeight : 0.0; + final labelDy = (isLabelBelow) ? barHeight + _timeLabelPadding : 0.0; final leftLabelOffset = Offset(0, labelDy); final leftTimeLabel = _leftTimeLabel(); leftTimeLabel.paint(canvas, leftLabelOffset); @@ -630,7 +660,8 @@ class _RenderProgressBar extends RenderBox { _rightTimeLabel().paint(canvas, rightLabelOffset); // progress bar - final barDy = (isLabelBelow) ? 0.0 : leftTimeLabel.height; + final barDy = + (isLabelBelow) ? 0.0 : leftTimeLabel.height + _timeLabelPadding; _drawProgressBar(canvas, Offset(0, barDy), Size(barWidth, barHeight)); } @@ -639,34 +670,30 @@ class _RenderProgressBar extends RenderBox { /// | 01:23 -------O---------------- 05:00 | /// void _drawProgressBarWithLabelsOnSides(Canvas canvas) { - // calculate sizes - const padding = 10; - final barHeight = 2 * _thumbRadius; - - // painters + // left time label final leftTimeLabel = _leftTimeLabel(); - final rightTimeLabel = _rightTimeLabel(); - - // current time label final verticalOffset = size.height / 2 - leftTimeLabel.height / 2; - final currentLabelOffset = Offset(0, verticalOffset); - leftTimeLabel.paint(canvas, currentLabelOffset); + final leftLabelOffset = Offset(0, verticalOffset); + leftTimeLabel.paint(canvas, leftLabelOffset); - // total or remaining time label - final totalLabelDx = size.width - rightTimeLabel.width; + // right time label + final rightTimeLabel = _rightTimeLabel(); + final rightLabelWidth = rightTimeLabel.width; + final totalLabelDx = size.width - rightLabelWidth; final totalLabelOffset = Offset(totalLabelDx, verticalOffset); rightTimeLabel.paint(canvas, totalLabelOffset); // progress bar final leftLabelWidth = leftTimeLabel.width; - final barWidth = - size.width - 2 * padding - leftLabelWidth - rightTimeLabel.width; + final barHeight = 2 * _thumbRadius; + final barWidth = size.width - + 2 * _defaultSidePadding - + 2 * _timeLabelPadding - + leftLabelWidth - + rightLabelWidth; final barDy = size.height / 2 - barHeight / 2; - _drawProgressBar( - canvas, - Offset(padding + leftLabelWidth, barDy), - Size(barWidth, barHeight), - ); + final barDx = leftLabelWidth + _defaultSidePadding + _timeLabelPadding; + _drawProgressBar(canvas, Offset(barDx, barDy), Size(barWidth, barHeight)); } /// Draw the progress bar without labels like this: @@ -735,8 +762,9 @@ class _RenderProgressBar extends RenderBox { void _drawThumb(Canvas canvas, Size localSize) { final thumbPaint = Paint()..color = thumbColor; - final adjustedWidth = localSize.width - 2 * _thumbRadius; - final thumbDx = _thumbValue * adjustedWidth + _thumbRadius; + final width = localSize.width; + final thumbDx = + (_thumbValue * width).clamp(_thumbRadius, width - _thumbRadius); final center = Offset(thumbDx, localSize.height / 2); if (_userIsDraggingThumb) { final thumbGlowPaint = Paint()..color = thumbGlowColor; diff --git a/pubspec.yaml b/pubspec.yaml index b941361..1098f20 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: audio_video_progress_bar description: A progress bar widget to show or change the position of an audio or video stream. -version: 0.6.0 +version: 0.6.1 homepage: https://github.com/suragch/audio_video_progress_bar environment: diff --git a/test/audio_video_progress_bar_test.dart b/test/audio_video_progress_bar_test.dart index 9557b0a..3e95dd9 100644 --- a/test/audio_video_progress_bar_test.dart +++ b/test/audio_video_progress_bar_test.dart @@ -58,6 +58,7 @@ void main() { expect(progressBar.timeLabelType, TimeLabelType.remainingTime); expect(progressBar.timeLabelTextStyle, const TextStyle(color: Color(0x00000000))); + expect(progressBar.timeLabelPadding, 0.0); }); testWidgets('TimeLabelLocation.below size correct', @@ -201,4 +202,90 @@ void main() { expect(baseSize.width, equals(800.0)); expect(baseSize.height, equals(14.0)); }); + + group('timeLabelPadding -', () { + testWidgets('Size with timeLabelPadding is correct when labels below', + (WidgetTester tester) async { + await tester.pumpWidget( + const Center( + child: ProgressBar( + progress: Duration.zero, + total: Duration(minutes: 5), + timeLabelPadding: 10, + timeLabelLocation: TimeLabelLocation.below, + ), + ), + ); + + ProgressBar progressBar = tester.firstWidget(find.byType(ProgressBar)); + expect(progressBar, isNotNull); + + final baseSize = tester.getSize(find.byType(ProgressBar)); + expect(baseSize.width, equals(800.0)); + expect(baseSize.height, equals(44.0)); + }); + + testWidgets('Size with timeLabelPadding is correct when labels above', + (WidgetTester tester) async { + await tester.pumpWidget( + const Center( + child: ProgressBar( + progress: Duration.zero, + total: Duration(minutes: 5), + timeLabelPadding: 10, + timeLabelLocation: TimeLabelLocation.above, + ), + ), + ); + + ProgressBar progressBar = tester.firstWidget(find.byType(ProgressBar)); + expect(progressBar, isNotNull); + + final baseSize = tester.getSize(find.byType(ProgressBar)); + expect(baseSize.width, equals(800.0)); + expect(baseSize.height, equals(44.0)); + }); + + testWidgets('Size with timeLabelPadding is correct when labels on sides', + (WidgetTester tester) async { + await tester.pumpWidget( + const Center( + child: ProgressBar( + progress: Duration.zero, + total: Duration(minutes: 5), + timeLabelPadding: 10, + timeLabelLocation: TimeLabelLocation.sides, + ), + ), + ); + + ProgressBar progressBar = tester.firstWidget(find.byType(ProgressBar)); + expect(progressBar, isNotNull); + + final baseSize = tester.getSize(find.byType(ProgressBar)); + expect(baseSize.width, equals(800.0)); + expect(baseSize.height, equals(20.0)); + }); + + testWidgets('Size with timeLabelPadding is correct when no labels', + (WidgetTester tester) async { + await tester.pumpWidget( + const Center( + child: ProgressBar( + progress: Duration.zero, + total: Duration(minutes: 5), + timeLabelPadding: 10, + timeLabelLocation: TimeLabelLocation.none, + ), + ), + ); + + ProgressBar progressBar = tester.firstWidget(find.byType(ProgressBar)); + expect(progressBar, isNotNull); + + final baseSize = tester.getSize(find.byType(ProgressBar)); + expect(baseSize.width, equals(800.0)); + expect(baseSize.height, equals(20.0)); + }); + }); }