Skip to content

Commit

Permalink
:feat adds support for startHour. (SimformSolutionsPvtLtd#319)
Browse files Browse the repository at this point in the history
* Add 'startHour' parameter to Several Components

Still need to handle how events are placed in the calendar, components
modified :
- WeekView
- DayView
- InternalDayView
- InternalWeekView
- TimeLine
- HourLinePainter
- HalfHourLinePainter
- PressDetector

* Modify EventArrangers + DayView

Modifications on EventArrangers so they are placing events in function
of 'startHour' argument.

Widgets Modified :

- EventArrangers
- MergeEventArrangers
- SideEventArrangers

+ Modifications on DayView, so we can pass it the 'startHour' argument

* Update doc + format code

* Fix hour above 24 causing negative height

* Fix hour above 24 causing negative height

* Reset example default view to 'month'

* startHour added on needed constructors

* format

* tests fixed

* format

* conflict resolved

* format

---------

Co-authored-by: MAEL KEHL <[email protected]>
Co-authored-by: Maël <[email protected]>
  • Loading branch information
3 people authored Feb 21, 2024
1 parent c003d1b commit ed7288e
Show file tree
Hide file tree
Showing 13 changed files with 276 additions and 201 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ DayView(
eventArranger: SideEventArranger(), // To define how simultaneous events will be arranged.
onEventTap: (events, date) => print(events),
onDateLongPress: (date) => print(date),
startHour: 5 // To set the first hour displayed (ex: 05:00)
hourLinePainter: (lineColor, lineHeight, offset, minuteHeight, showVerticalLine, verticalLineOffset) {
return //Your custom painter.
}
Expand Down Expand Up @@ -203,6 +204,7 @@ WeekView(
onEventTap: (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)
showVerticalLines: false, // Show the vertical line between days.
hourLinePainter: (lineColor, lineHeight, offset, minuteHeight, showVerticalLine, verticalLineOffset) {
return //Your custom painter.
Expand Down
38 changes: 26 additions & 12 deletions lib/src/components/_internal_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ class TimeLine extends StatefulWidget {
/// Flag to display half hours.
final bool showHalfHours;

/// First hour displayed in the layout
final int startHour;

/// Flag to display quarter hours.
final bool showQuarterHours;

Expand All @@ -146,6 +149,7 @@ class TimeLine extends StatefulWidget {
required this.height,
required this.timeLineOffset,
required this.timeLineBuilder,
required this.startHour,
this.showHalfHours = false,
this.showQuarterHours = false,
required this.liveTimeIndicatorSettings,
Expand Down Expand Up @@ -195,22 +199,23 @@ class _TimeLineState extends State<TimeLine> {
),
child: Stack(
children: [
for (int i = 1; i < Constants.hoursADay; i++)
for (int i = widget.startHour + 1; i < Constants.hoursADay; i++)
_timelinePositioned(
topPosition: widget.hourHeight * i - widget.timeLineOffset,
topPosition: widget.hourHeight * (i - widget.startHour) -
widget.timeLineOffset,
bottomPosition: widget.height -
(widget.hourHeight * (i + 1)) +
(widget.hourHeight * (i - widget.startHour + 1)) +
widget.timeLineOffset,
hour: i,
),
if (widget.showHalfHours)
for (int i = 0; i < Constants.hoursADay; i++)
for (int i = widget.startHour; i < Constants.hoursADay; i++)
_timelinePositioned(
topPosition: widget.hourHeight * i -
topPosition: widget.hourHeight * (i - widget.startHour) -
widget.timeLineOffset +
widget._halfHourHeight,
bottomPosition: widget.height -
(widget.hourHeight * (i + 1)) +
(widget.hourHeight * (i - widget.startHour + 1)) +
widget.timeLineOffset,
hour: i,
minutes: 30,
Expand Down Expand Up @@ -304,6 +309,9 @@ class EventGenerator<T extends Object?> extends StatelessWidget {
/// Defines date for which events will be displayed in given display area.
final DateTime date;

/// First hour displayed in the layout
final int startHour;

/// Called when user taps on event tile.
final CellTapCallback<T>? onTileTap;

Expand All @@ -317,6 +325,7 @@ class EventGenerator<T extends Object?> extends StatelessWidget {
required this.events,
required this.heightPerMinute,
required this.eventArranger,
required this.startHour,
required this.eventTileBuilder,
required this.date,
required this.onTileTap,
Expand All @@ -328,11 +337,11 @@ class EventGenerator<T extends Object?> extends StatelessWidget {
/// of events and [eventTileBuilder] to display events.
List<Widget> _generateEvents(BuildContext context) {
final events = eventArranger.arrange(
events: this.events,
height: height,
width: width,
heightPerMinute: heightPerMinute,
);
events: this.events,
height: height,
width: width,
heightPerMinute: heightPerMinute,
startHour: startHour);

return List.generate(events.length, (index) {
return Positioned(
Expand Down Expand Up @@ -429,6 +438,9 @@ class PressDetector extends StatelessWidget {
/// where events are not available.
final MinuteSlotSize minuteSlotSize;

/// First hour displayed in the layout
final int startHour;

/// A widget that display event tiles in day/week view.
const PressDetector({
Key? key,
Expand All @@ -439,12 +451,14 @@ class PressDetector extends StatelessWidget {
required this.onDateLongPress,
required this.onDateTap,
required this.minuteSlotSize,
required this.startHour,
}) : super(key: key);

@override
Widget build(BuildContext context) {
final heightPerSlot = minuteSlotSize.minutes * heightPerMinute;
final slots = (Constants.hoursADay * 60) ~/ minuteSlotSize.minutes;
final slots =
((Constants.hoursADay - startHour) * 60) ~/ minuteSlotSize.minutes;

return Container(
height: height,
Expand Down
31 changes: 19 additions & 12 deletions lib/src/day_view/_internal_day_view_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ class InternalDayViewPage<T extends Object?> extends StatelessWidget {
/// Settings for half hour indicator lines.
final HourIndicatorSettings halfHourIndicatorSettings;

/// First hour displayed in the layout
final int startHour;

/// Settings for half hour indicator lines.
final HourIndicatorSettings quarterHourIndicatorSettings;

Expand Down Expand Up @@ -143,6 +146,7 @@ class InternalDayViewPage<T extends Object?> extends StatelessWidget {
required this.showHalfHours,
required this.showQuarterHours,
required this.halfHourIndicatorSettings,
required this.startHour,
required this.quarterHourIndicatorSettings,
required this.emulateVerticalOffsetBy,
}) : super(key: key);
Expand All @@ -168,18 +172,18 @@ class InternalDayViewPage<T extends Object?> extends StatelessWidget {
children: [
CustomPaint(
size: Size(width, height),
painter: hourLinePainter(
hourIndicatorSettings.color,
hourIndicatorSettings.height,
timeLineWidth + hourIndicatorSettings.offset,
heightPerMinute,
showVerticalLine,
verticalLineOffset,
hourIndicatorSettings.lineStyle,
hourIndicatorSettings.dashWidth,
hourIndicatorSettings.dashSpaceWidth,
emulateVerticalOffsetBy,
),
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),
),
if (showHalfHours)
CustomPaint(
Expand All @@ -194,6 +198,7 @@ class InternalDayViewPage<T extends Object?> extends StatelessWidget {
dashWidth: halfHourIndicatorSettings.dashWidth,
dashSpaceWidth:
halfHourIndicatorSettings.dashSpaceWidth,
startHour: startHour,
),
),
if (showQuarterHours)
Expand Down Expand Up @@ -232,6 +237,7 @@ class InternalDayViewPage<T extends Object?> extends StatelessWidget {
heightPerMinute: heightPerMinute,
eventTileBuilder: eventTileBuilder,
scrollNotifier: scrollNotifier,
startHour: startHour,
width: width -
timeLineWidth -
hourIndicatorSettings.offset -
Expand All @@ -245,6 +251,7 @@ class InternalDayViewPage<T extends Object?> extends StatelessWidget {
timeLineOffset: timeLineOffset,
timeLineWidth: timeLineWidth,
showHalfHours: showHalfHours,
startHour: startHour,
showQuarterHours: showQuarterHours,
key: ValueKey(heightPerMinute),
liveTimeIndicatorSettings: liveTimeIndicatorSettings,
Expand Down
55 changes: 32 additions & 23 deletions lib/src/day_view/day_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ class DayView<T extends Object?> extends StatefulWidget {
/// Display full day event builder.
final FullDayEventBuilder<T>? fullDayEventBuilder;

/// First hour displayed in the layout, goes from 0 to 24
final int? startHour;

/// Show half hour indicator
final bool showHalfHours;

Expand Down Expand Up @@ -254,6 +257,7 @@ class DayView<T extends Object?> extends StatefulWidget {
this.showHalfHours = false,
this.showQuarterHours = false,
this.halfHourIndicatorSettings,
this.startHour,
this.quarterHourIndicatorSettings,
this.startDuration = const Duration(hours: 0),
this.onHeaderTitleTap,
Expand Down Expand Up @@ -289,6 +293,7 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
late DateTime _minDate;
late int _totalDays;
late int _currentIndex;
late int _startHour;

late EventArranger<T> _eventArranger;

Expand Down Expand Up @@ -325,6 +330,9 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
void initState() {
super.initState();

_startHour = widget.startHour ?? 0;
if (_startHour > 24) _startHour = 0;

_reloadCallback = _reload;
_setDateRange();

Expand Down Expand Up @@ -462,6 +470,7 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
showQuarterHours: widget.showQuarterHours,
halfHourIndicatorSettings:
_halfHourIndicatorSettings,
startHour: _startHour,
quarterHourIndicatorSettings:
_quarterHourIndicatorSettings,
emulateVerticalOffsetBy:
Expand Down Expand Up @@ -547,7 +556,7 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {

void _calculateHeights() {
_hourHeight = widget.heightPerMinute * 60;
_height = _hourHeight * Constants.hoursADay;
_height = _hourHeight * (Constants.hoursADay - _startHour);
}

void _assignBuilders() {
Expand Down Expand Up @@ -710,29 +719,29 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
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,
) {
Color lineColor,
double lineHeight,
double offset,
double minuteHeight,
bool showVerticalLine,
double verticalLineOffset,
LineStyle lineStyle,
double dashWidth,
double dashSpaceWidth,
double emulateVerticalOffsetBy,
int startHour) {
return HourLinePainter(
lineColor: lineColor,
lineHeight: lineHeight,
offset: offset,
minuteHeight: minuteHeight,
verticalLineOffset: verticalLineOffset,
showVerticalLine: showVerticalLine,
lineStyle: lineStyle,
dashWidth: dashWidth,
dashSpaceWidth: dashSpaceWidth,
emulateVerticalOffsetBy: emulateVerticalOffsetBy,
);
lineColor: lineColor,
lineHeight: lineHeight,
offset: offset,
minuteHeight: minuteHeight,
verticalLineOffset: verticalLineOffset,
showVerticalLine: showVerticalLine,
lineStyle: lineStyle,
dashWidth: dashWidth,
dashSpaceWidth: dashSpaceWidth,
emulateVerticalOffsetBy: emulateVerticalOffsetBy,
startHour: startHour);
}

/// Called when user change page using any gesture or inbuilt functions.
Expand Down
1 change: 1 addition & 0 deletions lib/src/event_arrangers/event_arrangers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ abstract class EventArranger<T extends Object?> {
required double height,
required double width,
required double heightPerMinute,
required int startHour,
});
}

Expand Down
13 changes: 9 additions & 4 deletions lib/src/event_arrangers/merge_event_arranger.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ class MergeEventArranger<T extends Object?> extends EventArranger<T> {
required double height,
required double width,
required double heightPerMinute,
required int startHour,
}) {
// TODO: Right now all the events that are passed in this function must be
// sorted in ascending order of the start time.
//
final arrangedEvents = <OrganizedCalendarEventData<T>>[];

//Checking if startTime and endTime are correct
for (final event in events) {
// Checks if an event has valid start and end time.
if (event.startTime == null ||
Expand All @@ -62,10 +64,13 @@ class MergeEventArranger<T extends Object?> extends EventArranger<T> {
final startTime = event.startTime!;
final endTime = event.endTime!;

final eventStart = startTime.getTotalMinutes;
final eventEnd = endTime.getTotalMinutes == 0
? Constants.minutesADay
: endTime.getTotalMinutes;
// startTime.getTotalMinutes returns the number of minutes from 00h00 to the beginning of the event
// But the first hour to be displayed (startHour) could be 06h00, so we have to substract
// The number of minutes from 00h00 to startHour which is equal to startHour * 60
final eventStart = startTime.getTotalMinutes - (startHour * 60);
final eventEnd = endTime.getTotalMinutes - (startHour * 60) == 0
? Constants.minutesADay - (startHour * 60)
: endTime.getTotalMinutes - (startHour * 60);

final arrangeEventLen = arrangedEvents.length;

Expand Down
19 changes: 15 additions & 4 deletions lib/src/event_arrangers/side_event_arranger.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class SideEventArranger<T extends Object?> extends EventArranger<T> {
required double height,
required double width,
required double heightPerMinute,
required int startHour,
}) {
final mergedEvents = MergeEventArranger<T>(
includeEdges: includeEdges,
Expand All @@ -37,6 +38,7 @@ class SideEventArranger<T extends Object?> extends EventArranger<T> {
height: height,
width: width,
heightPerMinute: heightPerMinute,
startHour: startHour,
);

final arrangedEvents = <OrganizedCalendarEventData<T>>[];
Expand Down Expand Up @@ -100,15 +102,24 @@ class SideEventArranger<T extends Object?> extends EventArranger<T> {

final startTime = sideEvent.event.startTime!;
final endTime = sideEvent.event.endTime!;

// startTime.getTotalMinutes returns the number of minutes from 00h00 to the beginning hour of the event
// But the first hour to be displayed (startHour) could be 06h00, so we have to substract
// The number of minutes from 00h00 to startHour which is equal to startHour * 60

final bottom = height -
(endTime.getTotalMinutes == 0
? Constants.minutesADay
: endTime.getTotalMinutes) *
(endTime.getTotalMinutes - (startHour * 60) == 0
? Constants.minutesADay - (startHour * 60)
: endTime.getTotalMinutes - (startHour * 60)) *
heightPerMinute;

final top =
(startTime.getTotalMinutes - (startHour * 60)) * heightPerMinute;

arrangedEvents.add(OrganizedCalendarEventData<T>(
left: slotWidth * (sideEvent.column - 1),
right: slotWidth * (column - sideEvent.column),
top: startTime.getTotalMinutes * heightPerMinute,
top: top,
bottom: bottom,
startDuration: startTime,
endDuration: endTime,
Expand Down
Loading

0 comments on commit ed7288e

Please sign in to comment.