From 4c759f161d8237b57d86591ec1b3ff1fc17ba259 Mon Sep 17 00:00:00 2001 From: Apurva Kanthraviya Date: Mon, 6 May 2024 18:11:15 +0530 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20added=20start=20and=20end?= =?UTF-8?q?=20time=20to=20be=20display=20on=20timeline=20for=20day=20and?= =?UTF-8?q?=20week=20view=20#267?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + README.md | 4 + lib/src/components/_internal_components.dart | 90 ++++++++++++++++--- lib/src/constants.dart | 3 + lib/src/day_view/_internal_day_view_page.dart | 17 ++++ lib/src/day_view/day_view.dart | 15 ++++ lib/src/painters.dart | 36 ++++++-- .../week_view/_internal_week_view_page.dart | 14 +++ lib/src/week_view/week_view.dart | 13 +++ 9 files changed, 174 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d5531f5..f830ef97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ - # [1.1.1] (UnReleased) +- Added support for start and end hour to be display on timeline for day and week view. [#267](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/267) - 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) diff --git a/README.md b/README.md index 62659155..9cd00f7f 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,8 @@ DayView( hourLinePainter: (lineColor, lineHeight, offset, minuteHeight, showVerticalLine, verticalLineOffset) { return //Your custom painter. }, + showInitialTime:false, // To show startHour or initial time on timeline + showEndTime:true, // To show endHour or end time on timeline dayTitleBuilder: DayHeader.hidden // To Hide day header ); ``` @@ -218,6 +220,8 @@ WeekView( hourLinePainter: (lineColor, lineHeight, offset, minuteHeight, showVerticalLine, verticalLineOffset) { return //Your custom painter. }, + showInitialTime:false, // To show startHour or initial time on timeline + showEndTime:true, // To show endHour or end time on timeline weekPageHeaderBuilder: WeekHeader.hidden // To hide week header ); ``` diff --git a/lib/src/components/_internal_components.dart b/lib/src/components/_internal_components.dart index 48ce19b3..55ca6c66 100644 --- a/lib/src/components/_internal_components.dart +++ b/lib/src/components/_internal_components.dart @@ -164,6 +164,15 @@ class TimeLine extends StatefulWidget { /// This field will be used to set end hour for day and week view final int endHour; + /// Flag for displaying initial hour on timeline + final bool showInitialTime; + + /// Flag for setting first hour index on timeline for week view only + final bool setDisplayHoursForWeek; + + /// Flag for displaying end hour on timeline + final bool showEndTime; + /// Time line to display time at left side of day or week view. const TimeLine({ Key? key, @@ -177,6 +186,9 @@ class TimeLine extends StatefulWidget { this.showQuarterHours = false, required this.liveTimeIndicatorSettings, this.endHour = Constants.hoursADay, + this.showInitialTime = false, + this.setDisplayHoursForWeek = false, + this.showEndTime = false, }) : super(key: key); @override @@ -213,6 +225,10 @@ class _TimeLineState extends State { @override Widget build(BuildContext context) { + final displayStartHour = + widget.showInitialTime ? widget.startHour : widget.startHour + 1; + final displayEndHour = + widget.showEndTime ? Constants.hoursADay + 1 : Constants.hoursADay; return ConstrainedBox( key: ValueKey(widget.hourHeight), constraints: BoxConstraints( @@ -223,15 +239,59 @@ class _TimeLineState extends State { ), child: Stack( children: [ - for (int i = widget.startHour + 1; i < widget.endHour; i++) - _timelinePositioned( - topPosition: widget.hourHeight * (i - widget.startHour) - - widget.timeLineOffset, - bottomPosition: widget.height - - (widget.hourHeight * (i - widget.startHour + 1)) + - widget.timeLineOffset, - hour: i, - ), + for (int i = displayStartHour; i < displayEndHour; i++) ...{ + /// Display initial time on timeline for week + if (i == widget.startHour && + widget.showInitialTime && + widget.setDisplayHoursForWeek) ...{ + /// Here we are changing the top-position for the first index + /// hour with [Constants.initialTimeSpacing] for the WeekView only. + _timelinePositioned( + topPosition: widget.hourHeight * (i - widget.startHour) - + widget.timeLineOffset + + Constants.initialTimeSpacing, + bottomPosition: widget.height - + (widget.hourHeight * (i - widget.startHour + 1)) + + widget.timeLineOffset, + hour: i, + ), + } + + /// Here we are changing end Hour's top position + /// Display end time on timeline for weekView only + else if (i == Constants.hoursADay && + widget.showEndTime && + widget.setDisplayHoursForWeek) ...{ + _timelinePositioned( + topPosition: widget.hourHeight * (i - widget.startHour) - + widget.timeLineOffset - + Constants.initialTimeSpacing, + bottomPosition: widget.height - + (widget.hourHeight * (i - widget.startHour + 1)) + + widget.timeLineOffset, + hour: i, + ), + } + + /// Display rest of time on timeline for day and week + else ...{ + /// Added initialTimeSpacing to topPosition for rest of time to display hours + /// on timeline properly from top position for day view only + _timelinePositioned( + topPosition: widget.hourHeight * (i - widget.startHour) - + widget.timeLineOffset + + (widget.showInitialTime && !widget.setDisplayHoursForWeek + ? Constants.initialTimeSpacing + : 0), + bottomPosition: widget.height - + (widget.hourHeight * (i - widget.startHour + 1)) + + widget.timeLineOffset, + hour: i, + ), + } + }, + + /// Display half hours on timeline for day and week if (widget.showHalfHours) for (int i = widget.startHour; i < widget.endHour; i++) _timelinePositioned( @@ -244,15 +304,17 @@ class _TimeLineState extends State { hour: i, minutes: 30, ), + + /// Display quarter hours on timeline for day and week if (widget.showQuarterHours) - for (int i = 0; i < widget.endHour; i++) ...[ + for (int i = widget.startHour; i < widget.endHour; i++) ...[ /// this is for 15 minutes _timelinePositioned( - topPosition: widget.hourHeight * i - + topPosition: widget.hourHeight * (i - widget.startHour) - widget.timeLineOffset + widget.hourHeight * 0.25, bottomPosition: widget.height - - (widget.hourHeight * (i + 1)) + + (widget.hourHeight * (i - widget.startHour + 1)) + widget.timeLineOffset, hour: i, minutes: 15, @@ -260,11 +322,11 @@ class _TimeLineState extends State { /// this is for 45 minutes _timelinePositioned( - topPosition: widget.hourHeight * i - + topPosition: widget.hourHeight * (i - widget.startHour) - widget.timeLineOffset + widget.hourHeight * 0.75, bottomPosition: widget.height - - (widget.hourHeight * (i + 1)) + + (widget.hourHeight * (i - widget.startHour + 1)) + widget.timeLineOffset, hour: i, minutes: 45, diff --git a/lib/src/constants.dart b/lib/src/constants.dart index 158379c8..6a84fb55 100644 --- a/lib/src/constants.dart +++ b/lib/src/constants.dart @@ -23,6 +23,9 @@ class Constants { static const Color offWhite = Color(0xfff0f0f0); static const Color headerBackground = Color(0xFFDCF0FF); + /// Time spacing for displaying initial and end time for day and week view + static const double initialTimeSpacing = 10; + static Color get randomColor { return Color.fromRGBO(_random.nextInt(_maxColor), _random.nextInt(_maxColor), _random.nextInt(_maxColor), 1); diff --git a/lib/src/day_view/_internal_day_view_page.dart b/lib/src/day_view/_internal_day_view_page.dart index d7c9607e..d18a5691 100644 --- a/lib/src/day_view/_internal_day_view_page.dart +++ b/lib/src/day_view/_internal_day_view_page.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import '../components/_internal_components.dart'; import '../components/event_scroll_notifier.dart'; +import '../constants.dart'; import '../enumerations.dart'; import '../event_arrangers/event_arrangers.dart'; import '../event_controller.dart'; @@ -124,6 +125,12 @@ class InternalDayViewPage extends StatelessWidget { /// This field will be used to set end hour for day view final int endHour; + /// Flag for displaying initial hour on timeline + final bool showInitialTime; + + /// Flag for displaying end hour on timeline + final bool showEndTime; + /// Defines a single day page. const InternalDayViewPage({ Key? key, @@ -161,6 +168,8 @@ class InternalDayViewPage extends StatelessWidget { required this.quarterHourIndicatorSettings, required this.emulateVerticalOffsetBy, required this.onTileDoubleTap, + required this.showInitialTime, + required this.showEndTime, }) : super(key: key); @override @@ -177,6 +186,10 @@ class InternalDayViewPage extends StatelessWidget { Expanded( child: SingleChildScrollView( controller: scrollController, + padding: EdgeInsets.only( + top: showInitialTime ? Constants.initialTimeSpacing : 0, + bottom: showEndTime ? Constants.initialTimeSpacing : 0, + ), child: SizedBox( height: height, width: width, @@ -197,6 +210,8 @@ class InternalDayViewPage extends StatelessWidget { emulateVerticalOffsetBy: emulateVerticalOffsetBy, startHour: startHour, endHour: endHour, + showInitialTime: showInitialTime, + showEndTime: showEndTime, ), ), if (showHalfHours) @@ -274,6 +289,8 @@ class InternalDayViewPage extends StatelessWidget { showQuarterHours: showQuarterHours, key: ValueKey(heightPerMinute), liveTimeIndicatorSettings: liveTimeIndicatorSettings, + showInitialTime: showInitialTime, + showEndTime: showEndTime, ), if (showLiveLine && liveTimeIndicatorSettings.height > 0) IgnorePointer( diff --git a/lib/src/day_view/day_view.dart b/lib/src/day_view/day_view.dart index 7f73c989..827465e1 100644 --- a/lib/src/day_view/day_view.dart +++ b/lib/src/day_view/day_view.dart @@ -226,6 +226,12 @@ class DayView extends StatefulWidget { /// This field will be used to set end hour for day view final int endHour; + /// Flag for displaying initial hour on timeline + final bool showInitialTime; + + /// Flag for displaying end hour on timeline + final bool showEndTime; + /// Main widget for day view. const DayView({ Key? key, @@ -275,6 +281,8 @@ class DayView extends StatefulWidget { this.emulateVerticalOffsetBy = 0, this.onEventDoubleTap, this.endHour = Constants.hoursADay, + this.showInitialTime = false, + this.showEndTime = false, }) : assert(!(onHeaderTitleTap != null && dayTitleBuilder != null), "can't use [onHeaderTitleTap] & [dayTitleBuilder] simultaneously"), assert(timeLineOffset >= 0, @@ -495,6 +503,8 @@ class DayViewState extends State> { _quarterHourIndicatorSettings, emulateVerticalOffsetBy: widget.emulateVerticalOffsetBy, + showInitialTime: widget.showInitialTime, + showEndTime: widget.showEndTime, ), ); }, @@ -577,6 +587,9 @@ class DayViewState extends State> { void _calculateHeights() { _hourHeight = widget.heightPerMinute * 60; _height = _hourHeight * (widget.endHour - widget.startHour); + + /// Adding extra height for end hour to be display on timeline + _height += widget.showEndTime ? (_hourHeight * 0.16) : 0; } void _assignBuilders() { @@ -726,6 +739,8 @@ class DayViewState extends State> { emulateVerticalOffsetBy: emulateVerticalOffsetBy, startHour: startHour, endHour: endHour, + showInitialTime: widget.showInitialTime, + showEndTime: widget.showEndTime, ); } diff --git a/lib/src/painters.dart b/lib/src/painters.dart index 4498bfb3..09e51209 100644 --- a/lib/src/painters.dart +++ b/lib/src/painters.dart @@ -47,6 +47,15 @@ class HourLinePainter extends CustomPainter { /// This field will be used to set end hour for day and week view final int endHour; + /// Flag for displaying initial hour on timeline + final bool showInitialTime; + + /// Flag for setting first hour index on timeline for week view only + final bool setDisplayHoursForWeek; + + /// Flag for displaying end hour on timeline + final bool showEndTime; + /// Paints 24 hour lines. HourLinePainter({ required this.lineColor, @@ -61,6 +70,9 @@ class HourLinePainter extends CustomPainter { this.lineStyle = LineStyle.solid, this.dashWidth = 4, this.dashSpaceWidth = 4, + this.showInitialTime = false, + this.setDisplayHoursForWeek = false, + this.showEndTime = false, }); @override @@ -70,8 +82,16 @@ class HourLinePainter extends CustomPainter { ..color = lineColor ..strokeWidth = lineHeight; - for (var i = startHour + 1; i < endHour; i++) { - final dy = (i - startHour) * minuteHeight * 60; + final displayStartHour = + showInitialTime || showEndTime ? startHour : startHour + 1; + + for (var i = displayStartHour; i < endHour + 1; i++) { + /// Added initialTimeSpacing to calculate from where line starts to + /// display to display hours lines align to hours tag for day view only + final dy = (i - displayStartHour) * minuteHeight * 60 + + (showInitialTime && !setDisplayHoursForWeek + ? Constants.initialTimeSpacing + : 0); if (lineStyle == LineStyle.dashed) { var startX = dx; while (startX < size.width) { @@ -86,15 +106,21 @@ class HourLinePainter extends CustomPainter { if (showVerticalLine) { if (lineStyle == LineStyle.dashed) { - var startY = 0.0; + var startY = showInitialTime ? -Constants.initialTimeSpacing : 0.0; while (startY < size.height) { canvas.drawLine(Offset(offset + verticalLineOffset, startY), Offset(offset + verticalLineOffset, startY + dashWidth), paint); startY += dashWidth + dashSpaceWidth; } } else { - canvas.drawLine(Offset(offset + verticalLineOffset, 0), - Offset(offset + verticalLineOffset, size.height), paint); + canvas.drawLine( + Offset( + offset + verticalLineOffset, + showInitialTime ? -Constants.initialTimeSpacing : 0.0, + ), + Offset(offset + verticalLineOffset, + size.height + (showEndTime ? Constants.initialTimeSpacing : 0)), + paint); } } } diff --git a/lib/src/week_view/_internal_week_view_page.dart b/lib/src/week_view/_internal_week_view_page.dart index 52a46056..84164199 100644 --- a/lib/src/week_view/_internal_week_view_page.dart +++ b/lib/src/week_view/_internal_week_view_page.dart @@ -144,6 +144,12 @@ class InternalWeekViewPage extends StatelessWidget { /// This field will be used to set end hour for week view final int endHour; + /// Flag for displaying initial hour on timeline + final bool showInitialTime; + + /// Flag for displaying end hour on timeline + final bool showEndTime; + /// A single page for week view. const InternalWeekViewPage({ Key? key, @@ -187,6 +193,8 @@ class InternalWeekViewPage extends StatelessWidget { required this.emulateVerticalOffsetBy, required this.onTileDoubleTap, required this.endHour, + required this.showInitialTime, + required this.showEndTime, }) : super(key: key); @override @@ -270,6 +278,9 @@ class InternalWeekViewPage extends StatelessWidget { startHour: startHour, emulateVerticalOffsetBy: emulateVerticalOffsetBy, endHour: endHour, + showInitialTime: showInitialTime, + showEndTime: showEndTime, + setDisplayHoursForWeek: true, ), ), if (showHalfHours) @@ -372,6 +383,9 @@ class InternalWeekViewPage extends StatelessWidget { showQuarterHours: showQuarterHours, liveTimeIndicatorSettings: liveTimeIndicatorSettings, endHour: endHour, + showInitialTime: showInitialTime, + setDisplayHoursForWeek: true, + showEndTime: showEndTime, ), if (showLiveLine && liveTimeIndicatorSettings.height > 0) LiveTimeIndicator( diff --git a/lib/src/week_view/week_view.dart b/lib/src/week_view/week_view.dart index a7d45f71..02d19076 100644 --- a/lib/src/week_view/week_view.dart +++ b/lib/src/week_view/week_view.dart @@ -231,6 +231,12 @@ class WeekView extends StatefulWidget { /// This can be used to disable the horizontal scroll of a page. final ScrollPhysics? pageViewPhysics; + /// Flag for displaying initial hour on timeline + final bool showInitialTime; + + /// Flag for displaying end hour on timeline + final bool showEndTime; + /// Main widget for week view. const WeekView({ Key? key, @@ -286,6 +292,8 @@ class WeekView extends StatefulWidget { this.pageViewPhysics, this.onEventDoubleTap, this.endHour = Constants.hoursADay, + this.showInitialTime = false, + this.showEndTime = false, }) : assert(!(onHeaderTitleTap != null && weekPageHeaderBuilder != null), "can't use [onHeaderTitleTap] & [weekPageHeaderBuilder] simultaneously"), assert((timeLineOffset) >= 0, @@ -533,6 +541,8 @@ class WeekViewState extends State> { widget.emulateVerticalOffsetBy, showWeekDayAtBottom: widget.showWeekDayAtBottom, endHour: _endHour, + showInitialTime: widget.showInitialTime, + showEndTime: widget.showEndTime, ), ); }, @@ -831,6 +841,9 @@ class WeekViewState extends State> { emulateVerticalOffsetBy: emulateVerticalOffsetBy, startHour: startHour, endHour: endHour, + showInitialTime: widget.showInitialTime, + showEndTime: widget.showEndTime, + setDisplayHoursForWeek: true, ); }