From 0cce9c7a2d6b995fa68c10efc4fa1b3af4772220 Mon Sep 17 00:00:00 2001 From: Samuel <68549184+Mayb3Nots@users.noreply.github.com> Date: Wed, 11 May 2022 23:34:04 +0800 Subject: [PATCH 1/7] added headerBackground color and made it use themeData.colorScheme instead of themeData.primaryColor --- example/pubspec.lock | 9 +- lib/src/time-range-dialog.dart | 179 ++++++++++++++++----------------- pubspec.lock | 9 +- 3 files changed, 103 insertions(+), 94 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index 1e1839e..208ba18 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -74,6 +74,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -134,7 +141,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.7" + version: "0.4.8" time_range_picker: dependency: "direct main" description: diff --git a/lib/src/time-range-dialog.dart b/lib/src/time-range-dialog.dart index 847986a..2585279 100644 --- a/lib/src/time-range-dialog.dart +++ b/lib/src/time-range-dialog.dart @@ -5,124 +5,126 @@ import 'package:time_range_picker/src/clock-gesture-recognizer.dart'; import 'package:time_range_picker/src/clock-painter.dart'; import 'package:time_range_picker/src/utils.dart'; -showTimeRangePicker({ - required BuildContext context, +showTimeRangePicker( + {required BuildContext context, - /// preselected start time - TimeOfDay? start, + /// preselected start time + TimeOfDay? start, - /// preselected end time - TimeOfDay? end, + /// preselected end time + TimeOfDay? end, - /// disabled time range (this time cannot be selected) - TimeRange? disabledTime, + /// disabled time range (this time cannot be selected) + TimeRange? disabledTime, - /// the color for the disabled section - Color? disabledColor, + /// the color for the disabled section + Color? disabledColor, - /// Style of the arc (filled or stroke) - PaintingStyle paintingStyle = PaintingStyle.stroke, + /// Style of the arc (filled or stroke) + PaintingStyle paintingStyle = PaintingStyle.stroke, - /// if start time changed - void Function(TimeOfDay)? onStartChange, + /// if start time changed + void Function(TimeOfDay)? onStartChange, - /// if end time changed - void Function(TimeOfDay)? onEndChange, + /// if end time changed + void Function(TimeOfDay)? onEndChange, - /// Minimum time steps that can be selected - Duration interval = const Duration(minutes: 5), + /// Minimum time steps that can be selected + Duration interval = const Duration(minutes: 5), - /// label for start time - String fromText = "From", + /// label for start time + String fromText = "From", - /// label for end time - String toText = "To", + /// label for end time + String toText = "To", - /// use 24 hours or am / pm - bool use24HourFormat = true, + /// use 24 hours or am / pm + bool use24HourFormat = true, - /// the padding of the ring - double padding = 36, + /// the padding of the ring + double padding = 36, - /// the thickness of the ring - double strokeWidth = 12, + /// the thickness of the ring + double strokeWidth = 12, - /// the color of the active arc from start time to end time - Color? strokeColor, + /// the color of the active arc from start time to end time + Color? strokeColor, - /// the radius of the handler to drag the arc - double handlerRadius = 12, + /// the radius of the handler to drag the arc + double handlerRadius = 12, - /// the color of a handler - Color? handlerColor, + /// the color of a handler + Color? handlerColor, - /// the color of a selected handler - Color? selectedColor, + /// the color of a selected handler + Color? selectedColor, - /// the color of the circle outline - Color? backgroundColor, + /// the color of the circle outline + Color? backgroundColor, - /// a widget displayed in the background, use e.g. an image - Widget? backgroundWidget, + /// a widget displayed in the background, use e.g. an image + Widget? backgroundWidget, - /// number of ticks displayed - int ticks = 0, + /// number of ticks displayed + int ticks = 0, - /// the offset for ticks - double ticksOffset = 0, + /// the offset for ticks + double ticksOffset = 0, - /// ticks length - double? ticksLength, + /// ticks length + double? ticksLength, - /// ticks thickness - double ticksWidth = 1, + /// ticks thickness + double ticksWidth = 1, - /// Color of ticks - Color ticksColor = Colors.white, + /// Color of ticks + Color ticksColor = Colors.white, - /// Snap time bar to interval - bool snap = false, + /// Snap time bar to interval + bool snap = false, - /// Show labels around the circle (start at 0 hours) - List? labels, + /// Show labels around the circle (start at 0 hours) + List? labels, - /// Offset of the labels - double labelOffset = 20, + /// Offset of the labels + double labelOffset = 20, - /// rotate labels - bool rotateLabels = true, + /// rotate labels + bool rotateLabels = true, - /// flip labels if the angle woulb be upside down (only if rotate labels is active) - bool autoAdjustLabels = true, + /// flip labels if the angle woulb be upside down (only if rotate labels is active) + bool autoAdjustLabels = true, - /// Style of the labels - TextStyle? labelStyle, + /// Style of the labels + TextStyle? labelStyle, - /// TextStyle of the time texts - TextStyle? timeTextStyle, + /// TextStyle of the time texts + TextStyle? timeTextStyle, - /// TextStyle of the currently moving time text - TextStyle? activeTimeTextStyle, + /// TextStyle of the currently moving time text + TextStyle? activeTimeTextStyle, - /// hide the time texts - bool hideTimes = false, + /// hide the time texts + bool hideTimes = false, - /// hide the button bar - bool hideButtons = false, + /// hide the button bar + bool hideButtons = false, - /// rotate the clock by angle - double clockRotation = 0, + /// rotate the clock by angle + double clockRotation = 0, - /// maximum selectable duration - Duration? maxDuration, - Duration minDuration = const Duration(minutes: 30), - TransitionBuilder? builder, - bool useRootNavigator = true, - RouteSettings? routeSettings, + /// maximum selectable duration + Duration? maxDuration, + Duration minDuration = const Duration(minutes: 30), + TransitionBuilder? builder, + bool useRootNavigator = true, + RouteSettings? routeSettings, - /// barrierDismissible false = user must tap button! - bool barrierDismissible = true, -}) async { + /// barrierDismissible false = user must tap button! + bool barrierDismissible = true, + + /// Changes the header's background color + Color? headerBackgroundColor}) async { assert(debugCheckHasMaterialLocalizations(context)); final Widget dialog = Dialog( @@ -229,7 +231,7 @@ class TimeRangePicker extends StatefulWidget { final double clockRotation; final Duration? maxDuration; final Duration minDuration; - + final Color? headerBackgroundColor; TimeRangePicker({ Key? key, this.start, @@ -269,6 +271,7 @@ class TimeRangePicker extends StatefulWidget { this.use24HourFormat = true, this.hideTimes = false, this.hideButtons = false, + this.headerBackgroundColor, }) : ticksLength = ticksLength == null ? strokeWidth : 12, assert(interval.inSeconds <= minDuration.inSeconds, "interval must be smaller or same as min duration - adjust either one"), @@ -724,16 +727,8 @@ class _TimeRangePickerState extends State Widget buildHeader(bool landscape) { final ThemeData themeData = Theme.of(context); - Color backgroundColor; - switch (themeData.brightness) { - case Brightness.light: - backgroundColor = themeData.primaryColor; - break; - case Brightness.dark: - backgroundColor = themeData.backgroundColor; - break; - } - + Color backgroundColor = + widget.headerBackgroundColor ?? themeData.colorScheme.primary; Color activeColor; Color inactiveColor; switch (ThemeData.estimateBrightnessForColor(themeData.primaryColor)) { diff --git a/pubspec.lock b/pubspec.lock index 967f00f..3317f5f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -67,6 +67,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -127,7 +134,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.7" + version: "0.4.8" typed_data: dependency: transitive description: From 9ae95d74d4e5e811fd29fd6b7204b32a5d367590 Mon Sep 17 00:00:00 2001 From: Samuel <68549184+Mayb3Nots@users.noreply.github.com> Date: Wed, 11 May 2022 23:49:44 +0800 Subject: [PATCH 2/7] add return type --- lib/src/time-range-dialog.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/time-range-dialog.dart b/lib/src/time-range-dialog.dart index 2585279..cd1bb21 100644 --- a/lib/src/time-range-dialog.dart +++ b/lib/src/time-range-dialog.dart @@ -5,7 +5,7 @@ import 'package:time_range_picker/src/clock-gesture-recognizer.dart'; import 'package:time_range_picker/src/clock-painter.dart'; import 'package:time_range_picker/src/utils.dart'; -showTimeRangePicker( +Future showTimeRangePicker( {required BuildContext context, /// preselected start time From f777864e2da67eeef250bc41e0b462774450fe17 Mon Sep 17 00:00:00 2001 From: Samuel <68549184+Mayb3Nots@users.noreply.github.com> Date: Thu, 12 May 2022 00:06:17 +0800 Subject: [PATCH 3/7] made to-from text color follow background onPrimary color --- lib/src/time-range-dialog.dart | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/lib/src/time-range-dialog.dart b/lib/src/time-range-dialog.dart index cd1bb21..587aa4e 100644 --- a/lib/src/time-range-dialog.dart +++ b/lib/src/time-range-dialog.dart @@ -729,20 +729,11 @@ class _TimeRangePickerState extends State Color backgroundColor = widget.headerBackgroundColor ?? themeData.colorScheme.primary; - Color activeColor; - Color inactiveColor; - switch (ThemeData.estimateBrightnessForColor(themeData.primaryColor)) { - case Brightness.light: - activeColor = Colors.black87; - inactiveColor = Colors.black54; - break; - case Brightness.dark: - activeColor = Colors.white; - inactiveColor = Colors.white70; - break; - } + + final onPrimary = themeData.colorScheme.onPrimary; return Container( + clipBehavior: Clip.antiAlias, color: backgroundColor, padding: EdgeInsets.all(24), child: Flex( @@ -751,38 +742,38 @@ class _TimeRangePickerState extends State children: [ Column( children: [ - Text(widget.fromText, style: TextStyle(color: activeColor)), + Text(widget.fromText, style: TextStyle(color: onPrimary)), Text( MaterialLocalizations.of(context).formatTimeOfDay(_startTime, alwaysUse24HourFormat: widget.use24HourFormat), style: _activeTime == ActiveTime.Start ? widget.activeTimeTextStyle ?? TextStyle( - color: activeColor, + color: onPrimary, fontSize: 28, fontWeight: FontWeight.bold) : widget.timeTextStyle ?? TextStyle( - color: inactiveColor, + color: onPrimary, fontSize: 28, fontWeight: FontWeight.bold), ), ], ), Column(children: [ - Text(widget.toText, style: TextStyle(color: activeColor)), + Text(widget.toText, style: TextStyle(color: onPrimary)), Text( MaterialLocalizations.of(context).formatTimeOfDay(_endTime, alwaysUse24HourFormat: widget.use24HourFormat), style: _activeTime == ActiveTime.End ? widget.activeTimeTextStyle ?? TextStyle( - color: activeColor, + color: onPrimary, fontSize: 28, fontWeight: FontWeight.bold) : widget.timeTextStyle ?? TextStyle( - color: inactiveColor, + color: onPrimary, fontSize: 28, fontWeight: FontWeight.bold), ), From f9ad955e74d93419934af86e2ddb3f7778cb1d3f Mon Sep 17 00:00:00 2001 From: Samuel <68549184+Mayb3Nots@users.noreply.github.com> Date: Thu, 12 May 2022 00:10:17 +0800 Subject: [PATCH 4/7] fixed bug --- lib/src/time-range-dialog.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/src/time-range-dialog.dart b/lib/src/time-range-dialog.dart index 587aa4e..f2f058c 100644 --- a/lib/src/time-range-dialog.dart +++ b/lib/src/time-range-dialog.dart @@ -734,7 +734,9 @@ class _TimeRangePickerState extends State return Container( clipBehavior: Clip.antiAlias, - color: backgroundColor, + decoration: BoxDecoration( + color: backgroundColor, + ), padding: EdgeInsets.all(24), child: Flex( direction: landscape ? Axis.vertical : Axis.horizontal, From 8de50fd6bde6a9feacd2f31d3baf9ac33bd15df8 Mon Sep 17 00:00:00 2001 From: Samuel <68549184+Mayb3Nots@users.noreply.github.com> Date: Sat, 14 May 2022 18:11:20 +0800 Subject: [PATCH 5/7] upgraded to flutter 3.0 --- lib/src/time-range-dialog.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/time-range-dialog.dart b/lib/src/time-range-dialog.dart index f2f058c..c7b0390 100644 --- a/lib/src/time-range-dialog.dart +++ b/lib/src/time-range-dialog.dart @@ -306,7 +306,7 @@ class _TimeRangePickerState extends State void initState() { _offsetRad = (widget.clockRotation * pi / 180); - WidgetsBinding.instance!.addObserver(this); + WidgetsBinding.instance.addObserver(this); var startTime = widget.start ?? TimeOfDay.now(); var endTime = widget.end ?? startTime.replacing( @@ -334,21 +334,21 @@ class _TimeRangePickerState extends State timeToAngle(widget.disabledTime!.startTime, _offsetRad); _disabledEndAngle = timeToAngle(widget.disabledTime!.endTime, _offsetRad); } - WidgetsBinding.instance!.addPostFrameCallback((_) => setRadius()); + WidgetsBinding.instance.addPostFrameCallback((_) => setRadius()); super.initState(); } @override void dispose() { - WidgetsBinding.instance!.removeObserver(this); + WidgetsBinding.instance.removeObserver(this); super.dispose(); } @override void didChangeMetrics() { super.didChangeMetrics(); - WidgetsBinding.instance!.addPostFrameCallback((_) => setRadius()); + WidgetsBinding.instance.addPostFrameCallback((_) => setRadius()); } setRadius() { From 06ee5f31a9b13a10c1a3e151600faefee9270ca6 Mon Sep 17 00:00:00 2001 From: Samuel <68549184+Mayb3Nots@users.noreply.github.com> Date: Thu, 26 May 2022 10:56:25 +0800 Subject: [PATCH 6/7] fixes curves not showing for top corners --- lib/src/time-range-dialog.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/time-range-dialog.dart b/lib/src/time-range-dialog.dart index c7b0390..cea8eb2 100644 --- a/lib/src/time-range-dialog.dart +++ b/lib/src/time-range-dialog.dart @@ -128,6 +128,7 @@ Future showTimeRangePicker( assert(debugCheckHasMaterialLocalizations(context)); final Widget dialog = Dialog( + clipBehavior: Clip.antiAlias, elevation: 12, child: TimeRangePicker( start: start, From 662e4bc1ce93738b1339b2cf1bbb0b130f910e4b Mon Sep 17 00:00:00 2001 From: Samuel Ong Date: Fri, 28 Jun 2024 00:12:53 +0800 Subject: [PATCH 7/7] fix: Import correct file path for main.dart in widget_test.dart --- example/lib/main.dart | 143 ++++++++++-------------------- example/test/widget_test.dart | 2 +- lib/src/time-range-dialog.dart | 156 +++++++++++---------------------- pubspec.lock | 132 ++++++++++++++++++---------- 4 files changed, 181 insertions(+), 252 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 8c99645..7afb27d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,6 +1,6 @@ import 'package:flutter/cupertino.dart'; -import 'package:time_range_picker/time_range_picker.dart'; import 'package:flutter/material.dart'; +import 'package:time_range_picker/time_range_picker.dart'; void main() { runApp(MyApp()); @@ -93,24 +93,14 @@ class _MyHomePageState extends State { ticks: 12, ticksColor: Colors.white, snap: true, - labels: [ - "12 am", - "3 am", - "6 am", - "9 am", - "12 pm", - "3 pm", - "6 pm", - "9 pm" - ].asMap().entries.map((e) { - return ClockLabel.fromIndex( - idx: e.key, length: 8, text: e.value); + labels: ["12 am", "3 am", "6 am", "9 am", "12 pm", "3 pm", "6 pm", "9 pm"] + .asMap() + .entries + .map((e) { + return ClockLabel.fromIndex(idx: e.key, length: 8, text: e.value); }).toList(), labelOffset: -30, - labelStyle: TextStyle( - fontSize: 22, - color: Colors.grey, - fontWeight: FontWeight.bold), + labelStyle: TextStyle(fontSize: 22, color: Colors.grey, fontWeight: FontWeight.bold), timeTextStyle: TextStyle( color: Colors.orange[700], fontSize: 24, @@ -140,18 +130,11 @@ class _MyHomePageState extends State { ticksOffset: -7, ticksLength: 15, ticksColor: Colors.grey, - labels: [ - "12 am", - "3 am", - "6 am", - "9 am", - "12 pm", - "3 pm", - "6 pm", - "9 pm" - ].asMap().entries.map((e) { - return ClockLabel.fromIndex( - idx: e.key, length: 8, text: e.value); + labels: ["12 am", "3 am", "6 am", "9 am", "12 pm", "3 pm", "6 pm", "9 pm"] + .asMap() + .entries + .map((e) { + return ClockLabel.fromIndex(idx: e.key, length: 8, text: e.value); }).toList(), labelOffset: 35, rotateLabels: false, @@ -168,10 +151,8 @@ class _MyHomePageState extends State { paintingStyle: PaintingStyle.fill, backgroundColor: Colors.grey.withOpacity(0.2), labels: [ - ClockLabel.fromTime( - time: TimeOfDay(hour: 7, minute: 0), text: "Start Work"), - ClockLabel.fromTime( - time: TimeOfDay(hour: 18, minute: 0), text: "Go Home") + ClockLabel.fromTime(time: TimeOfDay(hour: 7, minute: 0), text: "Start Work"), + ClockLabel.fromTime(time: TimeOfDay(hour: 18, minute: 0), text: "Go Home") ], start: TimeOfDay(hour: 10, minute: 0), end: TimeOfDay(hour: 13, minute: 0), @@ -205,21 +186,13 @@ class _MyHomePageState extends State { width: 200, ), labels: [ - ClockLabel.fromTime( - time: TimeOfDay(hour: 6, minute: 0), text: "Get up"), - ClockLabel.fromTime( - time: TimeOfDay(hour: 9, minute: 0), text: "Coffee time"), - ClockLabel.fromTime( - time: TimeOfDay(hour: 15, minute: 0), text: "Afternoon"), - ClockLabel.fromTime( - time: TimeOfDay(hour: 18, minute: 0), - text: "Time for a beer"), - ClockLabel.fromTime( - time: TimeOfDay(hour: 22, minute: 0), text: "Go to Sleep"), - ClockLabel.fromTime( - time: TimeOfDay(hour: 2, minute: 0), text: "Go for a pee"), - ClockLabel.fromTime( - time: TimeOfDay(hour: 12, minute: 0), text: "Lunchtime!") + ClockLabel.fromTime(time: TimeOfDay(hour: 6, minute: 0), text: "Get up"), + ClockLabel.fromTime(time: TimeOfDay(hour: 9, minute: 0), text: "Coffee time"), + ClockLabel.fromTime(time: TimeOfDay(hour: 15, minute: 0), text: "Afternoon"), + ClockLabel.fromTime(time: TimeOfDay(hour: 18, minute: 0), text: "Time for a beer"), + ClockLabel.fromTime(time: TimeOfDay(hour: 22, minute: 0), text: "Go to Sleep"), + ClockLabel.fromTime(time: TimeOfDay(hour: 2, minute: 0), text: "Go for a pee"), + ClockLabel.fromTime(time: TimeOfDay(hour: 12, minute: 0), text: "Lunchtime!") ], ticksColor: Colors.black, labelOffset: 40, @@ -242,18 +215,11 @@ class _MyHomePageState extends State { handlerRadius: 8, ticksColor: Colors.grey, rotateLabels: false, - labels: [ - "24 h", - "3 h", - "6 h", - "9 h", - "12 h", - "15 h", - "18 h", - "21 h" - ].asMap().entries.map((e) { - return ClockLabel.fromIndex( - idx: e.key, length: 8, text: e.value); + labels: ["24 h", "3 h", "6 h", "9 h", "12 h", "15 h", "18 h", "21 h"] + .asMap() + .entries + .map((e) { + return ClockLabel.fromIndex(idx: e.key, length: 8, text: e.value); }).toList(), labelOffset: 30, padding: 55, @@ -278,18 +244,11 @@ class _MyHomePageState extends State { ticks: 12, ticksColor: Colors.grey, ticksOffset: -12, - labels: [ - "24 h", - "3 h", - "6 h", - "9 h", - "12 h", - "15 h", - "18 h", - "21 h" - ].asMap().entries.map((e) { - return ClockLabel.fromIndex( - idx: e.key, length: 8, text: e.value); + labels: ["24 h", "3 h", "6 h", "9 h", "12 h", "15 h", "18 h", "21 h"] + .asMap() + .entries + .map((e) { + return ClockLabel.fromIndex(idx: e.key, length: 8, text: e.value); }).toList(), labelOffset: -30, padding: 55, @@ -314,18 +273,11 @@ class _MyHomePageState extends State { ticks: 12, ticksColor: Colors.grey, ticksOffset: -12, - labels: [ - "24 h", - "3 h", - "6 h", - "9 h", - "12 h", - "15 h", - "18 h", - "21 h" - ].asMap().entries.map((e) { - return ClockLabel.fromIndex( - idx: e.key, length: 8, text: e.value); + labels: ["24 h", "3 h", "6 h", "9 h", "12 h", "15 h", "18 h", "21 h"] + .asMap() + .entries + .map((e) { + return ClockLabel.fromIndex(idx: e.key, length: 8, text: e.value); }).toList(), labelOffset: -30, padding: 55, @@ -344,8 +296,8 @@ class _MyHomePageState extends State { ), ElevatedButton( onPressed: () async { - TimeRange? result = await showTimeRangePicker( - context: context, barrierDismissible: false); + TimeRange? result = + await showTimeRangePicker(context: context, barrierDismissible: false); print("result " + result.toString()); }, @@ -354,7 +306,7 @@ class _MyHomePageState extends State { Divider(), Text( 'As a regular widget:', - style: Theme.of(context).textTheme.headline6, + style: Theme.of(context).textTheme.headlineMedium, textAlign: TextAlign.center, ), Container( @@ -366,10 +318,8 @@ class _MyHomePageState extends State { paintingStyle: PaintingStyle.fill, backgroundColor: Colors.grey.withOpacity(0.2), labels: [ - ClockLabel.fromTime( - time: TimeOfDay(hour: 7, minute: 0), text: "Start Work"), - ClockLabel.fromTime( - time: TimeOfDay(hour: 18, minute: 0), text: "Go Home") + ClockLabel.fromTime(time: TimeOfDay(hour: 7, minute: 0), text: "Start Work"), + ClockLabel.fromTime(time: TimeOfDay(hour: 18, minute: 0), text: "Go Home") ], start: TimeOfDay(hour: 10, minute: 0), end: TimeOfDay(hour: 13, minute: 0), @@ -379,8 +329,7 @@ class _MyHomePageState extends State { labelOffset: 15, padding: 60, disabledTime: TimeRange( - startTime: TimeOfDay(hour: 18, minute: 0), - endTime: TimeOfDay(hour: 7, minute: 0)), + startTime: TimeOfDay(hour: 18, minute: 0), endTime: TimeOfDay(hour: 7, minute: 0)), disabledColor: Colors.red.withOpacity(0.5), ), ), @@ -420,8 +369,8 @@ class _MyHomePageState extends State { TextButton( child: Text('My custom ok'), onPressed: () { - Navigator.of(context).pop(TimeRange( - startTime: _startTime, endTime: _endTime)); + Navigator.of(context) + .pop(TimeRange(startTime: _startTime, endTime: _endTime)); }, ), ], @@ -454,9 +403,7 @@ class _MyHomePageState extends State { strokeWidth: 4, ticks: 12, activeTimeTextStyle: TextStyle( - fontWeight: FontWeight.normal, - fontSize: 22, - color: Colors.white), + fontWeight: FontWeight.normal, fontSize: 22, color: Colors.white), timeTextStyle: TextStyle( fontWeight: FontWeight.normal, fontSize: 22, diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index 747db1d..6db856c 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:example/main.dart'; +import '../lib/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { diff --git a/lib/src/time-range-dialog.dart b/lib/src/time-range-dialog.dart index cea8eb2..694637d 100644 --- a/lib/src/time-range-dialog.dart +++ b/lib/src/time-range-dialog.dart @@ -276,10 +276,8 @@ class TimeRangePicker extends StatefulWidget { }) : ticksLength = ticksLength == null ? strokeWidth : 12, assert(interval.inSeconds <= minDuration.inSeconds, "interval must be smaller or same as min duration - adjust either one"), - assert( - interval.inSeconds < 24 * 60 * 60, "interval must be smaller 24h"), - assert(minDuration.inSeconds < 24 * 60 * 60, - " min duration must be smaller 24h"), + assert(interval.inSeconds < 24 * 60 * 60, "interval must be smaller 24h"), + assert(minDuration.inSeconds < 24 * 60 * 60, " min duration must be smaller 24h"), super(key: key); @override @@ -310,9 +308,7 @@ class _TimeRangePickerState extends State WidgetsBinding.instance.addObserver(this); var startTime = widget.start ?? TimeOfDay.now(); var endTime = widget.end ?? - startTime.replacing( - hour: - startTime.hour < 21 ? startTime.hour + 3 : startTime.hour - 21); + startTime.replacing(hour: startTime.hour < 21 ? startTime.hour + 3 : startTime.hour - 21); _startTime = _roundMinutes(startTime.hour * 60 + startTime.minute * 1.0); _startAngle = timeToAngle(_startTime, _offsetRad); @@ -331,8 +327,7 @@ class _TimeRangePickerState extends State _endAngle = timeToAngle(_endTime, _offsetRad); if (widget.disabledTime != null) { - _disabledStartAngle = - timeToAngle(widget.disabledTime!.startTime, _offsetRad); + _disabledStartAngle = timeToAngle(widget.disabledTime!.startTime, _offsetRad); _disabledEndAngle = timeToAngle(widget.disabledTime!.endTime, _offsetRad); } WidgetsBinding.instance.addPostFrameCallback((_) => setRadius()); @@ -353,12 +348,10 @@ class _TimeRangePickerState extends State } setRadius() { - RenderBox? wrapper = - _wrapperKey.currentContext?.findRenderObject() as RenderBox?; + RenderBox? wrapper = _wrapperKey.currentContext?.findRenderObject() as RenderBox?; if (wrapper != null) { setState(() { - _radius = - min(wrapper.size.width, wrapper.size.height) / 2 - (widget.padding); + _radius = min(wrapper.size.width, wrapper.size.height) / 2 - (widget.padding); }); } } @@ -371,8 +364,7 @@ class _TimeRangePickerState extends State } TimeOfDay _roundMinutes(double min) { - int roundedMin = - ((min / widget.interval.inMinutes).round() * widget.interval.inMinutes); + int roundedMin = ((min / widget.interval.inMinutes).round() * widget.interval.inMinutes); int hours = (roundedMin / 60).floor(); int minutes = (roundedMin % 60).round(); @@ -383,8 +375,7 @@ class _TimeRangePickerState extends State bool isHandler = false; var globalPoint = ev.position; var snap = widget.handlerRadius * 2.5; - RenderBox circle = - _circleKey.currentContext!.findRenderObject() as RenderBox; + RenderBox circle = _circleKey.currentContext!.findRenderObject() as RenderBox; CustomPaint customPaint = _circleKey.currentWidget as CustomPaint; ClockPainter _clockPainter = customPaint.painter as ClockPainter; @@ -396,8 +387,7 @@ class _TimeRangePickerState extends State return false; } - Offset globalStartOffset = - circle.localToGlobal(_clockPainter.startHandlerPosition); + Offset globalStartOffset = circle.localToGlobal(_clockPainter.startHandlerPosition); if (globalPoint.dx < globalStartOffset.dx + snap && globalPoint.dx > globalStartOffset.dx - snap && globalPoint.dy < globalStartOffset.dy + snap && @@ -415,8 +405,7 @@ class _TimeRangePickerState extends State return false; } - Offset globalEndOffset = - circle.localToGlobal(_clockPainter.endHandlerPosition); + Offset globalEndOffset = circle.localToGlobal(_clockPainter.endHandlerPosition); if (globalPoint.dx < globalEndOffset.dx + snap && globalPoint.dx > globalEndOffset.dx - snap && @@ -433,32 +422,27 @@ class _TimeRangePickerState extends State void _panUpdate(PointerMoveEvent ev) { if (_activeTime == null) return; - RenderBox circle = - _circleKey.currentContext!.findRenderObject() as RenderBox; + RenderBox circle = _circleKey.currentContext!.findRenderObject() as RenderBox; final center = circle.size.center(Offset.zero); final point = circle.globalToLocal(ev.position); final touchPositionFromCenter = point - center; var dir = normalizeAngle(touchPositionFromCenter.direction); var minDurationSigned = durationToAngle(widget.minDuration); - var minDurationAngle = - minDurationSigned < 0 ? 2 * pi + minDurationSigned : minDurationSigned; + var minDurationAngle = minDurationSigned < 0 ? 2 * pi + minDurationSigned : minDurationSigned; //print("min duration angle " + (minDurationAngle * 180 / pi).toString()); if (_activeTime == ActiveTime.Start) { var angleToEndSigned = signedAngle(_endAngle, dir); - var angleToEnd = - angleToEndSigned < 0 ? 2 * pi + angleToEndSigned : angleToEndSigned; + var angleToEnd = angleToEndSigned < 0 ? 2 * pi + angleToEndSigned : angleToEndSigned; //check if hitting disabled if (widget.disabledTime != null) { var angleToDisabledStart = signedAngle(_disabledStartAngle!, dir); var angleToDisabledEnd = signedAngle(_disabledEndAngle!, dir); - var disabledAngleSigned = - signedAngle(_disabledEndAngle!, _disabledStartAngle!); - var disabledDiff = disabledAngleSigned < 0 - ? 2 * pi + disabledAngleSigned - : disabledAngleSigned; + var disabledAngleSigned = signedAngle(_disabledEndAngle!, _disabledStartAngle!); + var disabledDiff = + disabledAngleSigned < 0 ? 2 * pi + disabledAngleSigned : disabledAngleSigned; //print("to disabled start " + (angleToDisabledStart * 180 / pi).toString()); // print("to disabled end " + (angleToDisabledEnd * 180 / pi).toString()); @@ -467,8 +451,7 @@ class _TimeRangePickerState extends State angleToDisabledStart > -disabledDiff / 2) { dir = _disabledStartAngle! - minDurationAngle; _updateTimeAndSnapAngle(ActiveTime.End, _disabledStartAngle!); - } else if (angleToDisabledEnd > 0 && - angleToDisabledEnd < disabledDiff / 2) { + } else if (angleToDisabledEnd > 0 && angleToDisabledEnd < disabledDiff / 2) { dir = _disabledEndAngle!; } } @@ -492,28 +475,23 @@ class _TimeRangePickerState extends State } } else { var angleToStartSigned = signedAngle(dir, _startAngle); - var angleToStart = angleToStartSigned < 0 - ? 2 * pi + angleToStartSigned - : angleToStartSigned; + var angleToStart = angleToStartSigned < 0 ? 2 * pi + angleToStartSigned : angleToStartSigned; //check if hitting disabled if (widget.disabledTime != null) { var angleToDisabledStart = signedAngle(_disabledStartAngle!, dir); var angleToDisabledEnd = signedAngle(_disabledEndAngle!, dir); - var disabledAngleSigned = - signedAngle(_disabledEndAngle!, _disabledStartAngle!); - var disabledDiff = disabledAngleSigned < 0 - ? 2 * pi + disabledAngleSigned - : disabledAngleSigned; + var disabledAngleSigned = signedAngle(_disabledEndAngle!, _disabledStartAngle!); + var disabledDiff = + disabledAngleSigned < 0 ? 2 * pi + disabledAngleSigned : disabledAngleSigned; //print("to disabled start " + (angleToDisabledStart * 180 / pi).toString()); //print("to disabled end " + (angleToDisabledEnd * 180 / pi).toString()); //print("disabled diff " + (disabledDiff * 180 / pi).toString()); - if (angleToDisabledStart < 0 && - angleToDisabledStart > -disabledDiff / 2) { + if (angleToDisabledStart < 0 && angleToDisabledStart > -disabledDiff / 2) { dir = _disabledStartAngle!; } else if (angleToDisabledEnd + minDurationAngle > 0 && angleToDisabledEnd < disabledDiff / 2) { @@ -551,8 +529,7 @@ class _TimeRangePickerState extends State if (time.hour == 24) time = TimeOfDay(hour: 0, minute: time.minute); // snap to interval - final snapped = - widget.snap == true ? timeToAngle(time, -_offsetRad) : angle; + final snapped = widget.snap == true ? timeToAngle(time, -_offsetRad) : angle; if (type == ActiveTime.Start) { setState(() { @@ -576,11 +553,9 @@ class _TimeRangePickerState extends State bool isBetweenAngle(double min, double max, double targetAngle) { var normalisedMin = min >= 0 ? min : 2 * pi + min; var normalisedMax = max >= 0 ? max : 2 * pi + max; - var normalisedTarget = - targetAngle >= 0 ? targetAngle : 2 * pi + targetAngle; + var normalisedTarget = targetAngle >= 0 ? targetAngle : 2 * pi + targetAngle; - return normalisedMin <= normalisedTarget && - normalisedTarget <= normalisedMax; + return normalisedMin <= normalisedTarget && normalisedTarget <= normalisedMax; } void _panEnd(PointerUpEvent ev) { @@ -590,8 +565,7 @@ class _TimeRangePickerState extends State } _submit() { - Navigator.of(context) - .pop(TimeRange(startTime: _startTime, endTime: _endTime)); + Navigator.of(context).pop(TimeRange(startTime: _startTime, endTime: _endTime)); } _cancel() { @@ -600,8 +574,7 @@ class _TimeRangePickerState extends State @override Widget build(BuildContext context) { - final MaterialLocalizations localizations = - MaterialLocalizations.of(context); + final MaterialLocalizations localizations = MaterialLocalizations.of(context); final ThemeData themeData = Theme.of(context); return OrientationBuilder( @@ -617,13 +590,10 @@ class _TimeRangePickerState extends State //fit: StackFit.loose, alignment: Alignment.center, children: [ - if (widget.backgroundWidget != null) - widget.backgroundWidget!, - buildTimeRange( - localizations: localizations, themeData: themeData) + if (widget.backgroundWidget != null) widget.backgroundWidget!, + buildTimeRange(localizations: localizations, themeData: themeData) ]), - if (!widget.hideButtons) - buildButtonBar(localizations: localizations) + if (!widget.hideButtons) buildButtonBar(localizations: localizations) ], ) : Row( @@ -637,16 +607,12 @@ class _TimeRangePickerState extends State key: _wrapperKey, width: double.infinity, child: Stack(alignment: Alignment.center, children: [ - if (widget.backgroundWidget != null) - widget.backgroundWidget!, - buildTimeRange( - localizations: localizations, - themeData: themeData) + if (widget.backgroundWidget != null) widget.backgroundWidget!, + buildTimeRange(localizations: localizations, themeData: themeData) ]), ), ), - if (!widget.hideButtons) - buildButtonBar(localizations: localizations) + if (!widget.hideButtons) buildButtonBar(localizations: localizations) ], ), ), @@ -655,8 +621,7 @@ class _TimeRangePickerState extends State ); } - Widget buildButtonBar({required MaterialLocalizations localizations}) => - ButtonBar( + Widget buildButtonBar({required MaterialLocalizations localizations}) => ButtonBar( children: [ TextButton( child: Text(localizations.cancelButtonLabel), @@ -670,14 +635,12 @@ class _TimeRangePickerState extends State ); Widget buildTimeRange( - {required MaterialLocalizations localizations, - required ThemeData themeData}) => + {required MaterialLocalizations localizations, required ThemeData themeData}) => RawGestureDetector( gestures: { - ClockGestureRecognizer: - GestureRecognizerFactoryWithHandlers( - () => ClockGestureRecognizer( - panStart: _panStart, panUpdate: _panUpdate, panEnd: _panEnd), + ClockGestureRecognizer: GestureRecognizerFactoryWithHandlers( + () => + ClockGestureRecognizer(panStart: _panStart, panUpdate: _panUpdate, panEnd: _panEnd), (ClockGestureRecognizer instance) {}, ), }, @@ -699,12 +662,9 @@ class _TimeRangePickerState extends State handlerRadius: widget.handlerRadius, strokeColor: widget.strokeColor ?? themeData.primaryColor, handlerColor: widget.handlerColor ?? themeData.primaryColor, - selectedColor: - widget.selectedColor ?? themeData.primaryColorLight, - backgroundColor: - widget.backgroundColor ?? Colors.grey.withOpacity(0.3), - disabledColor: - widget.disabledColor ?? Colors.red.withOpacity(0.5), + selectedColor: widget.selectedColor ?? themeData.primaryColorLight, + backgroundColor: widget.backgroundColor ?? Colors.grey.withOpacity(0.3), + disabledColor: widget.disabledColor ?? Colors.red.withOpacity(0.5), paintingStyle: widget.paintingStyle, ticks: widget.ticks, ticksColor: widget.ticksColor, @@ -712,8 +672,7 @@ class _TimeRangePickerState extends State ticksWidth: widget.ticksWidth, ticksOffset: widget.ticksOffset, labels: widget.labels ?? new List.empty(), - labelStyle: - widget.labelStyle ?? themeData.textTheme.bodyText1, + labelStyle: widget.labelStyle ?? themeData.textTheme.bodyMedium, labelOffset: widget.labelOffset, rotateLabels: widget.rotateLabels, autoAdjustLabels: widget.autoAdjustLabels, @@ -728,8 +687,7 @@ class _TimeRangePickerState extends State Widget buildHeader(bool landscape) { final ThemeData themeData = Theme.of(context); - Color backgroundColor = - widget.headerBackgroundColor ?? themeData.colorScheme.primary; + Color backgroundColor = widget.headerBackgroundColor ?? themeData.colorScheme.primary; final onPrimary = themeData.colorScheme.onPrimary; @@ -747,38 +705,26 @@ class _TimeRangePickerState extends State children: [ Text(widget.fromText, style: TextStyle(color: onPrimary)), Text( - MaterialLocalizations.of(context).formatTimeOfDay(_startTime, - alwaysUse24HourFormat: widget.use24HourFormat), + MaterialLocalizations.of(context) + .formatTimeOfDay(_startTime, alwaysUse24HourFormat: widget.use24HourFormat), style: _activeTime == ActiveTime.Start ? widget.activeTimeTextStyle ?? - TextStyle( - color: onPrimary, - fontSize: 28, - fontWeight: FontWeight.bold) + TextStyle(color: onPrimary, fontSize: 28, fontWeight: FontWeight.bold) : widget.timeTextStyle ?? - TextStyle( - color: onPrimary, - fontSize: 28, - fontWeight: FontWeight.bold), + TextStyle(color: onPrimary, fontSize: 28, fontWeight: FontWeight.bold), ), ], ), Column(children: [ Text(widget.toText, style: TextStyle(color: onPrimary)), Text( - MaterialLocalizations.of(context).formatTimeOfDay(_endTime, - alwaysUse24HourFormat: widget.use24HourFormat), + MaterialLocalizations.of(context) + .formatTimeOfDay(_endTime, alwaysUse24HourFormat: widget.use24HourFormat), style: _activeTime == ActiveTime.End ? widget.activeTimeTextStyle ?? - TextStyle( - color: onPrimary, - fontSize: 28, - fontWeight: FontWeight.bold) + TextStyle(color: onPrimary, fontSize: 28, fontWeight: FontWeight.bold) : widget.timeTextStyle ?? - TextStyle( - color: onPrimary, - fontSize: 28, - fontWeight: FontWeight.bold), + TextStyle(color: onPrimary, fontSize: 28, fontWeight: FontWeight.bold), ), ]) ], diff --git a/pubspec.lock b/pubspec.lock index 3317f5f..203ecd5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,51 +5,50 @@ packages: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" source: hosted - version: "2.8.2" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" source: hosted - version: "1.2.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "1.3.0" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.18.0" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.1" flutter: dependency: "direct main" description: flutter @@ -60,34 +59,62 @@ packages: description: flutter source: sdk version: "0.0.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + url: "https://pub.dev" + source: hosted + version: "10.0.4" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + url: "https://pub.dev" + source: hosted + version: "3.0.3" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" source: hosted - version: "0.12.11" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + url: "https://pub.dev" source: hosted - version: "0.1.3" + version: "0.8.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + url: "https://pub.dev" source: hosted - version: "1.7.0" + version: "1.12.0" path: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.0" sky_engine: dependency: transitive description: flutter @@ -97,57 +124,66 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" source: hosted - version: "1.8.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.2" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + url: "https://pub.dev" source: hosted - version: "0.4.8" - typed_data: + version: "0.7.0" + vector_math: dependency: transitive description: - name: typed_data - url: "https://pub.dartlang.org" + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "1.3.0" - vector_math: + version: "2.1.4" + vm_service: dependency: transitive description: - name: vector_math - url: "https://pub.dartlang.org" + name: vm_service + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "14.2.1" sdks: - dart: ">=2.14.0 <3.0.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54"