diff --git a/CHANGELOG.md b/CHANGELOG.md index f2c885f7..7d5531f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ - # [1.1.1] (UnReleased) - Added support for double tapping gestures on any event in day, week, and month view. [#195](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/195) +- Added support to set end time of day and week view. [#298](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/298) - Added support for horizontal scroll physics of week and month view page. [#314](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/314) - Fixed issue related to the live time indicator is that it is not in the correct position when startHour is set for the week and day view. [#346](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/346) - Fixed issue of onDateTap returns wrong date when startHour is set for week and day view. [#341](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/341) diff --git a/README.md b/README.md index 40a3c135..62659155 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,7 @@ DayView( onEventLongTap: (events, date) => print(events), onDateLongPress: (date) => print(date), startHour: 5 // To set the first hour displayed (ex: 05:00) + endHour:20, // To set the end hour displayed hourLinePainter: (lineColor, lineHeight, offset, minuteHeight, showVerticalLine, verticalLineOffset) { return //Your custom painter. }, @@ -211,7 +212,8 @@ WeekView( onEventDoubleTap: (events, date) => print(events), onDateLongPress: (date) => print(date), startDay: WeekDays.sunday, // To change the first day of the week. - startHour: 5 // To set the first hour displayed (ex: 05:00) + startHour: 5, // To set the first hour displayed (ex: 05:00) + endHour:20, // To set the end hour displayed showVerticalLines: false, // Show the vertical line between days. hourLinePainter: (lineColor, lineHeight, offset, minuteHeight, showVerticalLine, verticalLineOffset) { return //Your custom painter. diff --git a/lib/src/components/_internal_components.dart b/lib/src/components/_internal_components.dart index 55a69cdb..48ce19b3 100644 --- a/lib/src/components/_internal_components.dart +++ b/lib/src/components/_internal_components.dart @@ -38,6 +38,9 @@ class LiveTimeIndicator extends StatefulWidget { /// First hour displayed in the layout, goes from 0 to 24 final int startHour; + /// This field will be used to set end hour for day and week view + final int endHour; + /// Widget to display tile line according to current time. const LiveTimeIndicator({ Key? key, @@ -47,6 +50,7 @@ class LiveTimeIndicator extends StatefulWidget { required this.liveTimeIndicatorSettings, required this.heightPerMinute, required this.startHour, + this.endHour = Constants.hoursADay, }) : super(key: key); @override @@ -93,6 +97,13 @@ class _LiveTimeIndicatorState extends State { /// remove startHour minute from [_currentTime.getTotalMinutes] /// to set dy offset of live time indicator final startMinutes = widget.startHour * 60; + + /// Check if live time is not between startHour and endHour then + /// don't show live time indicator + if (_currentTime.hour > widget.startHour || + widget.endHour < _currentTime.hour) { + return SizedBox.shrink(); + } return CustomPaint( size: Size(widget.width, widget.liveTimeIndicatorSettings.height), painter: CurrentTimeLinePainter( @@ -150,6 +161,9 @@ class TimeLine extends StatefulWidget { double get _halfHourHeight => hourHeight / 2; + /// This field will be used to set end hour for day and week view + final int endHour; + /// Time line to display time at left side of day or week view. const TimeLine({ Key? key, @@ -162,6 +176,7 @@ class TimeLine extends StatefulWidget { this.showHalfHours = false, this.showQuarterHours = false, required this.liveTimeIndicatorSettings, + this.endHour = Constants.hoursADay, }) : super(key: key); @override @@ -208,7 +223,7 @@ class _TimeLineState extends State { ), child: Stack( children: [ - for (int i = widget.startHour + 1; i < Constants.hoursADay; i++) + for (int i = widget.startHour + 1; i < widget.endHour; i++) _timelinePositioned( topPosition: widget.hourHeight * (i - widget.startHour) - widget.timeLineOffset, @@ -218,7 +233,7 @@ class _TimeLineState extends State { hour: i, ), if (widget.showHalfHours) - for (int i = widget.startHour; i < Constants.hoursADay; i++) + for (int i = widget.startHour; i < widget.endHour; i++) _timelinePositioned( topPosition: widget.hourHeight * (i - widget.startHour) - widget.timeLineOffset + @@ -230,7 +245,7 @@ class _TimeLineState extends State { minutes: 30, ), if (widget.showQuarterHours) - for (int i = 0; i < Constants.hoursADay; i++) ...[ + for (int i = 0; i < widget.endHour; i++) ...[ /// this is for 15 minutes _timelinePositioned( topPosition: widget.hourHeight * i - @@ -334,6 +349,9 @@ class EventGenerator extends StatelessWidget { final EventScrollConfiguration scrollNotifier; + /// This field will be used to set end hour for day and week view + final int endHour; + /// A widget that display event tiles in day/week view. const EventGenerator({ Key? key, @@ -349,6 +367,7 @@ class EventGenerator extends StatelessWidget { required this.onTileLongTap, required this.scrollNotifier, required this.onTileDoubleTap, + this.endHour = Constants.hoursADay, }) : super(key: key); /// Arrange events and returns list of [Widget] that displays event diff --git a/lib/src/day_view/_internal_day_view_page.dart b/lib/src/day_view/_internal_day_view_page.dart index 0faafa0e..d7c9607e 100644 --- a/lib/src/day_view/_internal_day_view_page.dart +++ b/lib/src/day_view/_internal_day_view_page.dart @@ -121,6 +121,9 @@ class InternalDayViewPage extends StatelessWidget { /// Emulate vertical line offset from hour line starts. final double emulateVerticalOffsetBy; + /// This field will be used to set end hour for day view + final int endHour; + /// Defines a single day page. const InternalDayViewPage({ Key? key, @@ -154,6 +157,7 @@ class InternalDayViewPage extends StatelessWidget { required this.showQuarterHours, required this.halfHourIndicatorSettings, required this.startHour, + required this.endHour, required this.quarterHourIndicatorSettings, required this.emulateVerticalOffsetBy, required this.onTileDoubleTap, @@ -181,17 +185,19 @@ class InternalDayViewPage extends StatelessWidget { CustomPaint( size: Size(width, height), painter: HourLinePainter( - lineColor: hourIndicatorSettings.color, - lineHeight: hourIndicatorSettings.height, - offset: timeLineWidth + hourIndicatorSettings.offset, - minuteHeight: heightPerMinute, - verticalLineOffset: verticalLineOffset, - showVerticalLine: showVerticalLine, - lineStyle: hourIndicatorSettings.lineStyle, - dashWidth: hourIndicatorSettings.dashWidth, - dashSpaceWidth: hourIndicatorSettings.dashSpaceWidth, - emulateVerticalOffsetBy: emulateVerticalOffsetBy, - startHour: startHour), + lineColor: hourIndicatorSettings.color, + lineHeight: hourIndicatorSettings.height, + offset: timeLineWidth + hourIndicatorSettings.offset, + minuteHeight: heightPerMinute, + verticalLineOffset: verticalLineOffset, + showVerticalLine: showVerticalLine, + lineStyle: hourIndicatorSettings.lineStyle, + dashWidth: hourIndicatorSettings.dashWidth, + dashSpaceWidth: hourIndicatorSettings.dashSpaceWidth, + emulateVerticalOffsetBy: emulateVerticalOffsetBy, + startHour: startHour, + endHour: endHour, + ), ), if (showHalfHours) CustomPaint( @@ -207,6 +213,7 @@ class InternalDayViewPage extends StatelessWidget { dashSpaceWidth: halfHourIndicatorSettings.dashSpaceWidth, startHour: startHour, + endHour: endHour, ), ), if (showQuarterHours) @@ -248,6 +255,7 @@ class InternalDayViewPage extends StatelessWidget { eventTileBuilder: eventTileBuilder, scrollNotifier: scrollNotifier, startHour: startHour, + endHour: endHour, width: width - timeLineWidth - hourIndicatorSettings.offset - @@ -262,6 +270,7 @@ class InternalDayViewPage extends StatelessWidget { timeLineWidth: timeLineWidth, showHalfHours: showHalfHours, startHour: startHour, + endHour: endHour, showQuarterHours: showQuarterHours, key: ValueKey(heightPerMinute), liveTimeIndicatorSettings: liveTimeIndicatorSettings, @@ -275,6 +284,7 @@ class InternalDayViewPage extends StatelessWidget { heightPerMinute: heightPerMinute, timeLineWidth: timeLineWidth, startHour: startHour, + endHour: endHour, ), ), ], diff --git a/lib/src/day_view/day_view.dart b/lib/src/day_view/day_view.dart index ffe045c0..7f73c989 100644 --- a/lib/src/day_view/day_view.dart +++ b/lib/src/day_view/day_view.dart @@ -205,7 +205,7 @@ class DayView extends StatefulWidget { final FullDayEventBuilder? fullDayEventBuilder; /// First hour displayed in the layout, goes from 0 to 24 - final int? startHour; + final int startHour; /// Show half hour indicator final bool showHalfHours; @@ -223,6 +223,9 @@ class DayView extends StatefulWidget { /// Emulate vertical line offset from hour line starts. final double emulateVerticalOffsetBy; + /// This field will be used to set end hour for day view + final int endHour; + /// Main widget for day view. const DayView({ Key? key, @@ -265,12 +268,13 @@ class DayView extends StatefulWidget { this.showHalfHours = false, this.showQuarterHours = false, this.halfHourIndicatorSettings, - this.startHour, + this.startHour = 0, this.quarterHourIndicatorSettings, this.startDuration = const Duration(hours: 0), this.onHeaderTitleTap, this.emulateVerticalOffsetBy = 0, this.onEventDoubleTap, + this.endHour = Constants.hoursADay, }) : assert(!(onHeaderTitleTap != null && dayTitleBuilder != null), "can't use [onHeaderTitleTap] & [dayTitleBuilder] simultaneously"), assert(timeLineOffset >= 0, @@ -286,6 +290,14 @@ class DayView extends StatefulWidget { """If you use [dayPressDetectorBuilder] do not provide [onDateLongPress]""", ), + assert( + startHour <= 0 || startHour != endHour, + "startHour must be greater than 0 or startHour should not equal to endHour", + ), + assert( + endHour <= Constants.hoursADay || endHour < startHour, + "End hour must be less than 24 or startHour must be less than endHour", + ), super(key: key); @override @@ -302,7 +314,6 @@ class DayViewState extends State> { late DateTime _minDate; late int _totalDays; late int _currentIndex; - late int _startHour; late EventArranger _eventArranger; @@ -339,9 +350,6 @@ class DayViewState extends State> { void initState() { super.initState(); - _startHour = widget.startHour ?? 0; - if (_startHour > 24) _startHour = 0; - _reloadCallback = _reload; _setDateRange(); @@ -481,7 +489,8 @@ class DayViewState extends State> { showQuarterHours: widget.showQuarterHours, halfHourIndicatorSettings: _halfHourIndicatorSettings, - startHour: _startHour, + startHour: widget.startHour, + endHour: widget.endHour, quarterHourIndicatorSettings: _quarterHourIndicatorSettings, emulateVerticalOffsetBy: @@ -567,7 +576,7 @@ class DayViewState extends State> { void _calculateHeights() { _hourHeight = widget.heightPerMinute * 60; - _height = _hourHeight * (Constants.hoursADay - _startHour); + _height = _hourHeight * (widget.endHour - widget.startHour); } void _assignBuilders() { @@ -631,7 +640,7 @@ class DayViewState extends State> { minuteSlotSize: minuteSlotSize, onDateTap: widget.onDateTap, onDateLongPress: widget.onDateLongPress, - startHour: _startHour, + startHour: widget.startHour, ); /// Default timeline builder this builder will be used if @@ -691,29 +700,33 @@ class DayViewState extends State> { FullDayEventView(events: events, date: date); HourLinePainter _defaultHourLinePainter( - Color lineColor, - double lineHeight, - double offset, - double minuteHeight, - bool showVerticalLine, - double verticalLineOffset, - LineStyle lineStyle, - double dashWidth, - double dashSpaceWidth, - double emulateVerticalOffsetBy, - int startHour) { + Color lineColor, + double lineHeight, + double offset, + double minuteHeight, + bool showVerticalLine, + double verticalLineOffset, + LineStyle lineStyle, + double dashWidth, + double dashSpaceWidth, + double emulateVerticalOffsetBy, + int startHour, + int endHour, + ) { return HourLinePainter( - lineColor: lineColor, - lineHeight: lineHeight, - offset: offset, - minuteHeight: minuteHeight, - verticalLineOffset: verticalLineOffset, - showVerticalLine: showVerticalLine, - lineStyle: lineStyle, - dashWidth: dashWidth, - dashSpaceWidth: dashSpaceWidth, - emulateVerticalOffsetBy: emulateVerticalOffsetBy, - startHour: startHour); + lineColor: lineColor, + lineHeight: lineHeight, + offset: offset, + minuteHeight: minuteHeight, + verticalLineOffset: verticalLineOffset, + showVerticalLine: showVerticalLine, + lineStyle: lineStyle, + dashWidth: dashWidth, + dashSpaceWidth: dashSpaceWidth, + emulateVerticalOffsetBy: emulateVerticalOffsetBy, + startHour: startHour, + endHour: endHour, + ); } /// Called when user change page using any gesture or inbuilt functions. diff --git a/lib/src/painters.dart b/lib/src/painters.dart index a0a7e0d1..4498bfb3 100644 --- a/lib/src/painters.dart +++ b/lib/src/painters.dart @@ -44,6 +44,9 @@ class HourLinePainter extends CustomPainter { /// Emulates offset of vertical line from hour line starts. final double emulateVerticalOffsetBy; + /// This field will be used to set end hour for day and week view + final int endHour; + /// Paints 24 hour lines. HourLinePainter({ required this.lineColor, @@ -53,6 +56,7 @@ class HourLinePainter extends CustomPainter { required this.showVerticalLine, required this.startHour, required this.emulateVerticalOffsetBy, + this.endHour = Constants.hoursADay, this.verticalLineOffset = 10, this.lineStyle = LineStyle.solid, this.dashWidth = 4, @@ -66,7 +70,7 @@ class HourLinePainter extends CustomPainter { ..color = lineColor ..strokeWidth = lineHeight; - for (var i = startHour + 1; i < Constants.hoursADay; i++) { + for (var i = startHour + 1; i < endHour; i++) { final dy = (i - startHour) * minuteHeight * 60; if (lineStyle == LineStyle.dashed) { var startX = dx; @@ -131,6 +135,9 @@ class HalfHourLinePainter extends CustomPainter { /// First hour displayed in the layout final int startHour; + /// This field will be used to set end hour for day and week view + final int endHour; + /// Paint half hour lines HalfHourLinePainter({ required this.lineColor, @@ -141,6 +148,7 @@ class HalfHourLinePainter extends CustomPainter { required this.startHour, this.dashWidth = 4, this.dashSpaceWidth = 4, + this.endHour = Constants.hoursADay, }); @override @@ -149,7 +157,7 @@ class HalfHourLinePainter extends CustomPainter { ..color = lineColor ..strokeWidth = lineHeight; - for (var i = startHour; i < Constants.hoursADay; i++) { + for (var i = startHour; i < endHour; i++) { final dy = (i - startHour) * minuteHeight * 60 + (minuteHeight * 30); if (lineStyle == LineStyle.dashed) { var startX = offset; diff --git a/lib/src/typedefs.dart b/lib/src/typedefs.dart index cb39db36..35151b86 100644 --- a/lib/src/typedefs.dart +++ b/lib/src/typedefs.dart @@ -77,16 +77,18 @@ typedef EventSorter = int Function( CalendarEventData a, CalendarEventData b); typedef CustomHourLinePainter = CustomPainter Function( - Color lineColor, - double lineHeight, - double offset, - double minuteHeight, - bool showVerticalLine, - double verticalLineOffset, - LineStyle lineStyle, - double dashWidth, - double dashSpaceWidth, - double emulateVerticalOffsetBy, - int startHour); + Color lineColor, + double lineHeight, + double offset, + double minuteHeight, + bool showVerticalLine, + double verticalLineOffset, + LineStyle lineStyle, + double dashWidth, + double dashSpaceWidth, + double emulateVerticalOffsetBy, + int startHour, + int endHour, +); typedef TestPredicate = bool Function(T element); diff --git a/lib/src/week_view/_internal_week_view_page.dart b/lib/src/week_view/_internal_week_view_page.dart index fb5e711b..52a46056 100644 --- a/lib/src/week_view/_internal_week_view_page.dart +++ b/lib/src/week_view/_internal_week_view_page.dart @@ -141,6 +141,9 @@ class InternalWeekViewPage extends StatelessWidget { /// Emulate vertical line offset from hour line starts. final double emulateVerticalOffsetBy; + /// This field will be used to set end hour for week view + final int endHour; + /// A single page for week view. const InternalWeekViewPage({ Key? key, @@ -183,6 +186,7 @@ class InternalWeekViewPage extends StatelessWidget { required this.showQuarterHours, required this.emulateVerticalOffsetBy, required this.onTileDoubleTap, + required this.endHour, }) : super(key: key); @override @@ -255,31 +259,35 @@ class InternalWeekViewPage extends StatelessWidget { child: Stack( children: [ CustomPaint( - size: Size(width, height), - painter: HourLinePainter( - lineColor: hourIndicatorSettings.color, - lineHeight: hourIndicatorSettings.height, - offset: - timeLineWidth + hourIndicatorSettings.offset, - minuteHeight: heightPerMinute, - verticalLineOffset: verticalLineOffset, - showVerticalLine: showVerticalLine, - startHour: startHour, - emulateVerticalOffsetBy: emulateVerticalOffsetBy)), + size: Size(width, height), + painter: HourLinePainter( + lineColor: hourIndicatorSettings.color, + lineHeight: hourIndicatorSettings.height, + offset: timeLineWidth + hourIndicatorSettings.offset, + minuteHeight: heightPerMinute, + verticalLineOffset: verticalLineOffset, + showVerticalLine: showVerticalLine, + startHour: startHour, + emulateVerticalOffsetBy: emulateVerticalOffsetBy, + endHour: endHour, + ), + ), if (showHalfHours) CustomPaint( size: Size(width, height), painter: HalfHourLinePainter( - lineColor: halfHourIndicatorSettings.color, - lineHeight: halfHourIndicatorSettings.height, - offset: timeLineWidth + - halfHourIndicatorSettings.offset, - minuteHeight: heightPerMinute, - lineStyle: halfHourIndicatorSettings.lineStyle, - dashWidth: halfHourIndicatorSettings.dashWidth, - dashSpaceWidth: - halfHourIndicatorSettings.dashSpaceWidth, - startHour: halfHourIndicatorSettings.startHour), + lineColor: halfHourIndicatorSettings.color, + lineHeight: halfHourIndicatorSettings.height, + offset: + timeLineWidth + halfHourIndicatorSettings.offset, + minuteHeight: heightPerMinute, + lineStyle: halfHourIndicatorSettings.lineStyle, + dashWidth: halfHourIndicatorSettings.dashWidth, + dashSpaceWidth: + halfHourIndicatorSettings.dashSpaceWidth, + startHour: halfHourIndicatorSettings.startHour, + endHour: endHour, + ), ), if (showQuarterHours) CustomPaint( @@ -343,6 +351,7 @@ class InternalWeekViewPage extends StatelessWidget { includeFullDayEvents: false, ), heightPerMinute: heightPerMinute, + endHour: endHour, ), ], ), @@ -362,6 +371,7 @@ class InternalWeekViewPage extends StatelessWidget { showHalfHours: showHalfHours, showQuarterHours: showQuarterHours, liveTimeIndicatorSettings: liveTimeIndicatorSettings, + endHour: endHour, ), if (showLiveLine && liveTimeIndicatorSettings.height > 0) LiveTimeIndicator( @@ -371,6 +381,7 @@ class InternalWeekViewPage extends StatelessWidget { heightPerMinute: heightPerMinute, timeLineWidth: timeLineWidth, startHour: startHour, + endHour: endHour, ), ], ), diff --git a/lib/src/week_view/week_view.dart b/lib/src/week_view/week_view.dart index 83b97563..a7d45f71 100644 --- a/lib/src/week_view/week_view.dart +++ b/lib/src/week_view/week_view.dart @@ -206,7 +206,10 @@ class WeekView extends StatefulWidget { final FullDayEventBuilder? fullDayEventBuilder; /// First hour displayed in the layout, goes from 0 to 24 - final int? startHour; + final int startHour; + + /// This field will be used to set end hour for week view + final int endHour; ///Show half hour indicator final bool showHalfHours; @@ -274,7 +277,7 @@ class WeekView extends StatefulWidget { this.headerStyle = const HeaderStyle(), this.safeAreaOption = const SafeAreaOption(), this.fullDayEventBuilder, - this.startHour, + this.startHour = 0, this.onHeaderTitleTap, this.showHalfHours = false, this.showQuarterHours = false, @@ -282,6 +285,7 @@ class WeekView extends StatefulWidget { this.showWeekDayAtBottom = false, this.pageViewPhysics, this.onEventDoubleTap, + this.endHour = Constants.hoursADay, }) : assert(!(onHeaderTitleTap != null && weekPageHeaderBuilder != null), "can't use [onHeaderTitleTap] & [weekPageHeaderBuilder] simultaneously"), assert((timeLineOffset) >= 0, @@ -297,6 +301,14 @@ class WeekView extends StatefulWidget { """If you use [weekPressDetectorBuilder] do not provide [onDateLongPress]""", ), + assert( + startHour <= 0 || startHour != endHour, + "startHour must be greater than 0 or startHour should not equal to endHour", + ), + assert( + endHour <= Constants.hoursADay || endHour < startHour, + "End hour must be less than 24 or startHour must be less than endHour", + ), super(key: key); @override @@ -349,6 +361,7 @@ class WeekViewState extends State> { late List _weekDays; late int _startHour; + late int _endHour; final _scrollConfiguration = EventScrollConfiguration(); @@ -356,9 +369,8 @@ class WeekViewState extends State> { void initState() { super.initState(); - _startHour = widget.startHour ?? 0; - //Security to avoid any height bug - if (_startHour > 24) _startHour = 0; + _startHour = widget.startHour; + _endHour = widget.endHour; _reloadCallback = _reload; @@ -520,6 +532,7 @@ class WeekViewState extends State> { emulateVerticalOffsetBy: widget.emulateVerticalOffsetBy, showWeekDayAtBottom: widget.showWeekDayAtBottom, + endHour: _endHour, ), ); }, @@ -618,7 +631,7 @@ class WeekViewState extends State> { void _calculateHeights() { _hourHeight = widget.heightPerMinute * 60; - _height = _hourHeight * (Constants.hoursADay - _startHour); + _height = _hourHeight * (_endHour - _startHour); } void _assignBuilders() { @@ -792,29 +805,33 @@ class WeekViewState extends State> { } HourLinePainter _defaultHourLinePainter( - Color lineColor, - double lineHeight, - double offset, - double minuteHeight, - bool showVerticalLine, - double verticalLineOffset, - LineStyle lineStyle, - double dashWidth, - double dashSpaceWidth, - double emulateVerticalOffsetBy, - int startHour) { + Color lineColor, + double lineHeight, + double offset, + double minuteHeight, + bool showVerticalLine, + double verticalLineOffset, + LineStyle lineStyle, + double dashWidth, + double dashSpaceWidth, + double emulateVerticalOffsetBy, + int startHour, + int endHour, + ) { return HourLinePainter( - lineColor: lineColor, - lineHeight: lineHeight, - offset: offset, - minuteHeight: minuteHeight, - verticalLineOffset: verticalLineOffset, - showVerticalLine: showVerticalLine, - lineStyle: lineStyle, - dashWidth: dashWidth, - dashSpaceWidth: dashSpaceWidth, - emulateVerticalOffsetBy: emulateVerticalOffsetBy, - startHour: startHour); + lineColor: lineColor, + lineHeight: lineHeight, + offset: offset, + minuteHeight: minuteHeight, + verticalLineOffset: verticalLineOffset, + showVerticalLine: showVerticalLine, + lineStyle: lineStyle, + dashWidth: dashWidth, + dashSpaceWidth: dashSpaceWidth, + emulateVerticalOffsetBy: emulateVerticalOffsetBy, + startHour: startHour, + endHour: endHour, + ); } /// Called when user change page using any gesture or inbuilt functions.