Skip to content

Commit

Permalink
feat: ✨ added start and end time to be display on timeline for day an…
Browse files Browse the repository at this point in the history
…d week view #267
  • Loading branch information
apurva010 committed May 10, 2024
1 parent 7bc4c2b commit cb6b9bd
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
- Fixed issue when adding full-day events to WeekView, event is not display at correct date. [#259](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/259)
- Added support for onLongPress of event in day, week and month view. [#342](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/pull/342)
- Added check to keep hour in timeline (in day and week view) if LiveTimeIndicator time or backgroundView dosen't overlap. [#336](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/336)
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,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
keepScrollOffset: true, // To maintain scroll offset when the page changes
);
Expand Down Expand Up @@ -221,6 +223,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
fullDayHeaderTitle: 'All day', // To set full day events header title
fullDayHeaderTextConfig: FullDayHeaderTextConfig(
Expand Down
90 changes: 76 additions & 14 deletions lib/src/components/_internal_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,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,
Expand All @@ -180,6 +189,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
Expand Down Expand Up @@ -216,6 +228,10 @@ class _TimeLineState extends State<TimeLine> {

@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(
Expand All @@ -226,15 +242,59 @@ class _TimeLineState extends State<TimeLine> {
),
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(
Expand All @@ -247,27 +307,29 @@ class _TimeLineState extends State<TimeLine> {
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,
),

/// 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,
Expand Down
3 changes: 3 additions & 0 deletions lib/src/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
17 changes: 17 additions & 0 deletions lib/src/day_view/_internal_day_view_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -133,6 +134,12 @@ class InternalDayViewPage<T extends Object?> extends StatefulWidget {
/// Flag to keep scrollOffset of pages on page change
final bool keepScrollOffset;

/// 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,
Expand Down Expand Up @@ -173,6 +180,8 @@ class InternalDayViewPage<T extends Object?> extends StatefulWidget {
required this.emulateVerticalOffsetBy,
required this.onTileDoubleTap,
this.keepScrollOffset = false,
required this.showInitialTime,
required this.showEndTime,
}) : super(key: key);

@override
Expand Down Expand Up @@ -223,6 +232,10 @@ class _InternalDayViewPageState<T extends Object?>
controller: widget.keepScrollOffset
? scrollController
: widget.dayViewScrollController,
padding: EdgeInsets.only(
top: widget.showInitialTime ? Constants.initialTimeSpacing : 0,
bottom: widget.showEndTime ? Constants.initialTimeSpacing : 0,
),
child: SizedBox(
height: widget.height,
width: widget.width,
Expand All @@ -245,6 +258,8 @@ class _InternalDayViewPageState<T extends Object?>
emulateVerticalOffsetBy: widget.emulateVerticalOffsetBy,
startHour: widget.startHour,
endHour: widget.endHour,
showInitialTime: widget.showInitialTime,
showEndTime: widget.showEndTime,
),
),
if (widget.showHalfHours)
Expand Down Expand Up @@ -326,6 +341,8 @@ class _InternalDayViewPageState<T extends Object?>
key: ValueKey(widget.heightPerMinute),
liveTimeIndicatorSettings:
widget.liveTimeIndicatorSettings,
showInitialTime: widget.showInitialTime,
showEndTime: widget.showEndTime,
),
if (widget.showLiveLine &&
widget.liveTimeIndicatorSettings.height > 0)
Expand Down
15 changes: 15 additions & 0 deletions lib/src/day_view/day_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ class DayView<T extends Object?> extends StatefulWidget {
/// Flag to keep scrollOffset of pages on page change
final bool keepScrollOffset;

/// 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,
Expand Down Expand Up @@ -279,6 +285,8 @@ class DayView<T extends Object?> extends StatefulWidget {
this.onEventDoubleTap,
this.endHour = Constants.hoursADay,
this.keepScrollOffset = false,
this.showInitialTime = false,
this.showEndTime = false,
}) : assert(!(onHeaderTitleTap != null && dayTitleBuilder != null),
"can't use [onHeaderTitleTap] & [dayTitleBuilder] simultaneously"),
assert(timeLineOffset >= 0,
Expand Down Expand Up @@ -504,6 +512,8 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
dayViewScrollController: _scrollController,
scrollListener: _scrollPageListener,
keepScrollOffset: widget.keepScrollOffset,
showInitialTime: widget.showInitialTime,
showEndTime: widget.showEndTime,
),
);
},
Expand Down Expand Up @@ -586,6 +596,9 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
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() {
Expand Down Expand Up @@ -741,6 +754,8 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
emulateVerticalOffsetBy: emulateVerticalOffsetBy,
startHour: startHour,
endHour: endHour,
showInitialTime: widget.showInitialTime,
showEndTime: widget.showEndTime,
);
}

Expand Down
36 changes: 31 additions & 5 deletions lib/src/painters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand All @@ -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) {
Expand All @@ -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);
}
}
}
Expand Down
14 changes: 14 additions & 0 deletions lib/src/week_view/_internal_week_view_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ class InternalWeekViewPage<T extends Object?> extends StatefulWidget {
/// Flag to keep scrollOffset of pages on page change
final bool keepScrollOffset;

/// 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,
Expand Down Expand Up @@ -208,6 +214,8 @@ class InternalWeekViewPage<T extends Object?> extends StatefulWidget {
required this.weekViewScrollController,
this.lastScrollOffset = 0.0,
this.keepScrollOffset = false,
required this.showInitialTime,
required this.showEndTime,
}) : super(key: key);

@override
Expand Down Expand Up @@ -351,6 +359,9 @@ class _InternalWeekViewPageState<T extends Object?>
startHour: widget.startHour,
emulateVerticalOffsetBy: widget.emulateVerticalOffsetBy,
endHour: widget.endHour,
showInitialTime: widget.showInitialTime,
showEndTime: widget.showEndTime,
setDisplayHoursForWeek: true,
),
),
if (widget.showHalfHours)
Expand Down Expand Up @@ -460,6 +471,9 @@ class _InternalWeekViewPageState<T extends Object?>
liveTimeIndicatorSettings:
widget.liveTimeIndicatorSettings,
endHour: widget.endHour,
showInitialTime: widget.showInitialTime,
setDisplayHoursForWeek: true,
showEndTime: widget.showEndTime,
),
if (widget.showLiveLine &&
widget.liveTimeIndicatorSettings.height > 0)
Expand Down
Loading

0 comments on commit cb6b9bd

Please sign in to comment.