Skip to content

Commit

Permalink
fix: 🐛event tile width and height of day view and week view #238
Browse files Browse the repository at this point in the history
  • Loading branch information
apurva010 committed Jun 6, 2024
1 parent e3c127b commit 4052521
Show file tree
Hide file tree
Showing 16 changed files with 339 additions and 110 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
- # [1.2.1] (UnReleased)
- Fixed width issue of event in day and week view. [#238](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/238)

# [1.2.0 - 10 May 2024](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/tree/1.2.0)

- 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)
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ DayView(
maxDay: DateTime(2050),
initialDay: DateTime(2021),
heightPerMinute: 1, // height occupied by 1 minute time span.
isMinEventTileHeight: true,
eventArranger: SideEventArranger(), // To define how simultaneous events will be arranged.
onEventTap: (events, date) => print(events),
onEventDoubleTap: (events, date) => print(events),
Expand Down Expand Up @@ -218,6 +219,7 @@ WeekView(
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.
isMinEventTileHeight: true,
hourLinePainter: (lineColor, lineHeight, offset, minuteHeight, showVerticalLine, verticalLineOffset) {
return //Your custom painter.
},
Expand Down
33 changes: 30 additions & 3 deletions lib/src/calendar_event_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class CalendarEventData<T extends Object?> {
/// Define style of description.
final TextStyle? descriptionStyle;

final DateTime? newEndTime;

/// {@macro calendar_event_data_doc}
CalendarEventData({
required this.title,
Expand All @@ -56,7 +58,9 @@ class CalendarEventData<T extends Object?> {
this.titleStyle,
this.descriptionStyle,
DateTime? endDate,
}) : _endDate = endDate?.withoutTime,
this.newEndTime,
})
: _endDate = endDate?.withoutTime,
date = date.withoutTime;

DateTime get endDate => _endDate ?? date;
Expand All @@ -65,7 +69,9 @@ class CalendarEventData<T extends Object?> {
/// days and is not a full day event.
///
bool get isRangingEvent {
final diff = endDate.withoutTime.difference(date.withoutTime).inDays;
final diff = endDate.withoutTime
.difference(date.withoutTime)
.inDays;

return diff > 0 && !isFullDayEvent;
}
Expand All @@ -91,9 +97,30 @@ class CalendarEventData<T extends Object?> {
currentDate.isAfter(date.withoutTime));
}

CalendarEventData<T> updateEventTime({
DateTime? newStartTime,
DateTime? newEndTime,
}) {
return CalendarEventData(
title: title,
description: description,
event: event,
color: color,
startTime: newStartTime ?? startTime,
endTime: endTime,
titleStyle: titleStyle,
descriptionStyle: descriptionStyle,
endDate: endDate,
date: date,
newEndTime: newEndTime,
);
}


/// Returns event data in [Map<String, dynamic>] format.
///
Map<String, dynamic> toJson() => {
Map<String, dynamic> toJson() =>
{
"date": date,
"startTime": startTime,
"endTime": endTime,
Expand Down
20 changes: 15 additions & 5 deletions lib/src/components/_internal_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,10 @@ class EventGenerator<T extends Object?> extends StatelessWidget {
/// This field will be used to set end hour for day and week view
final int endHour;

/// Setting the min height of an event tile such that event title is readable
/// when event duration difference is in range of 1 min to 15 min.
final bool isMinEventTileHeight;

/// A widget that display event tiles in day/week view.
const EventGenerator({
Key? key,
Expand All @@ -371,18 +375,22 @@ class EventGenerator<T extends Object?> extends StatelessWidget {
required this.scrollNotifier,
required this.onTileDoubleTap,
this.endHour = Constants.hoursADay,
this.isMinEventTileHeight = false,
}) : super(key: key);

/// Arrange events and returns list of [Widget] that displays event
/// tile on display area. This method uses [eventArranger] to get position
/// 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,
startHour: startHour);
events: this.events,
height: height,
width: width,
heightPerMinute: heightPerMinute,
startHour: startHour,
isMinEventTileHeight: isMinEventTileHeight,
textScaleFactor: MediaQuery.of(context).textScaler,
);

return List.generate(events.length, (index) {
return Positioned(
Expand Down Expand Up @@ -411,6 +419,8 @@ class EventGenerator<T extends Object?> extends StatelessWidget {
height - events[index].bottom - events[index].top),
events[index].startDuration,
events[index].endDuration,
heightPerMinute,
isMinEventTileHeight: isMinEventTileHeight,
);
}),
),
Expand Down
27 changes: 25 additions & 2 deletions lib/src/components/common_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -197,28 +197,51 @@ class DefaultEventTile<T> extends StatelessWidget {
required this.boundary,
required this.startDuration,
required this.endDuration,
required this.heightPerMinute,
this.isMinEventTileHeight = false,
});

final DateTime date;
final List<CalendarEventData<T>> events;
final Rect boundary;
final DateTime startDuration;
final DateTime endDuration;
final double heightPerMinute;
final bool isMinEventTileHeight;

@override
Widget build(BuildContext context) {
final double? eventTileHeight;
bool isEventTileHasSpace = false;
if (isMinEventTileHeight) {
eventTileHeight =
(endDuration.getTotalMinutes - startDuration.getTotalMinutes) *
heightPerMinute;

isEventTileHasSpace =
(events.first.titleStyle?.fontSize ?? Constants.maxFontSize) * 2.5 <=
eventTileHeight &&
eventTileHeight >
(events.first.titleStyle?.fontSize ?? Constants.maxFontSize);
}
if (events.isNotEmpty) {
final event = events[0];
return RoundedEventTile(
borderRadius: BorderRadius.circular(10.0),
title: event.title,
totalEvents: events.length - 1,
description: event.description,
padding: EdgeInsets.all(10.0),
padding: isMinEventTileHeight
? isEventTileHasSpace
? EdgeInsets.all(6)
: EdgeInsets.zero
: EdgeInsets.all(10),
backgroundColor: event.color,
margin: EdgeInsets.all(2.0),
margin: EdgeInsets.all(1.0),
titleStyle: event.titleStyle,
descriptionStyle: event.descriptionStyle,
showDescription: isMinEventTileHeight ? isEventTileHasSpace : false,
centerTitle: isMinEventTileHeight,
);
} else {
return SizedBox.shrink();
Expand Down
33 changes: 22 additions & 11 deletions lib/src/components/day_view_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ class RoundedEventTile extends StatelessWidget {
/// Style for description
final TextStyle? descriptionStyle;

/// Show description according to tile available space
final bool showDescription;

/// When we are not showing description & there some space available we
/// center the title
final bool centerTitle;

/// This is default tile to display in day view.
const RoundedEventTile({
Key? key,
Expand All @@ -55,6 +62,8 @@ class RoundedEventTile extends StatelessWidget {
this.backgroundColor = Colors.blue,
this.titleStyle,
this.descriptionStyle,
this.showDescription = true,
this.centerTitle = false,
}) : super(key: key);

@override
Expand All @@ -67,13 +76,18 @@ class RoundedEventTile extends StatelessWidget {
borderRadius: borderRadius,
),
child: Column(
mainAxisAlignment:
centerTitle ? MainAxisAlignment.center : MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (title.isNotEmpty)
Expanded(
child: Text(
title,
textScaler: showDescription
? TextScaler.linear(0.8)
: TextScaler.noScaling,
style: titleStyle ??
TextStyle(
fontSize: 20,
Expand All @@ -83,18 +97,15 @@ class RoundedEventTile extends StatelessWidget {
overflow: TextOverflow.fade,
),
),
if (description?.isNotEmpty ?? false)
if ((description?.isNotEmpty ?? false) && showDescription)
Expanded(
child: Padding(
padding: const EdgeInsets.only(bottom: 15.0),
child: Text(
description!,
style: descriptionStyle ??
TextStyle(
fontSize: 17,
color: backgroundColor.accent.withAlpha(200),
),
),
child: Text(
description!,
style: descriptionStyle ??
TextStyle(
fontSize: 17,
color: backgroundColor.accent.withAlpha(200),
),
),
),
if (totalEvents > 1)
Expand Down
2 changes: 2 additions & 0 deletions lib/src/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class Constants {
static const Color offWhite = Color(0xfff0f0f0);
static const Color headerBackground = Color(0xFFDCF0FF);

static const double maxFontSize = 20;

static Color get randomColor {
return Color.fromRGBO(_random.nextInt(_maxColor),
_random.nextInt(_maxColor), _random.nextInt(_maxColor), 1);
Expand Down
6 changes: 6 additions & 0 deletions lib/src/day_view/_internal_day_view_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ class InternalDayViewPage<T extends Object?> extends StatefulWidget {
/// Flag to keep scrollOffset of pages on page change
final bool keepScrollOffset;

/// Setting the min height of an event tile such that event title is readable
/// when event duration difference is in range of 1 min to 15 min.
final bool isMinEventTileHeight;

/// Defines a single day page.
const InternalDayViewPage({
Key? key,
Expand Down Expand Up @@ -173,6 +177,7 @@ class InternalDayViewPage<T extends Object?> extends StatefulWidget {
required this.emulateVerticalOffsetBy,
required this.onTileDoubleTap,
this.keepScrollOffset = false,
this.isMinEventTileHeight = false,
}) : super(key: key);

@override
Expand Down Expand Up @@ -311,6 +316,7 @@ class _InternalDayViewPageState<T extends Object?>
widget.timeLineWidth -
widget.hourIndicatorSettings.offset -
widget.verticalLineOffset,
isMinEventTileHeight: isMinEventTileHeight,
),
),
TimeLine(
Expand Down
12 changes: 11 additions & 1 deletion lib/src/day_view/day_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ class DayView<T extends Object?> extends StatefulWidget {
/// Flag to keep scrollOffset of pages on page change
final bool keepScrollOffset;

/// Setting the min height of an event tile such that event title is readable
/// when event duration difference is in range of 1 min to 15 min.
final bool isMinEventTileHeight;

/// Main widget for day view.
const DayView({
Key? key,
Expand Down Expand Up @@ -279,6 +283,7 @@ class DayView<T extends Object?> extends StatefulWidget {
this.onEventDoubleTap,
this.endHour = Constants.hoursADay,
this.keepScrollOffset = false,
this.isMinEventTileHeight = false,
}) : assert(!(onHeaderTitleTap != null && dayTitleBuilder != null),
"can't use [onHeaderTitleTap] & [dayTitleBuilder] simultaneously"),
assert(timeLineOffset >= 0,
Expand Down Expand Up @@ -505,6 +510,7 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
dayViewScrollController: _scrollController,
scrollListener: _scrollPageListener,
keepScrollOffset: widget.keepScrollOffset,
isMinEventTileHeight: widget.isMinEventTileHeight,
),
);
},
Expand Down Expand Up @@ -668,13 +674,17 @@ class DayViewState<T extends Object?> extends State<DayView<T>> {
Rect boundary,
DateTime startDuration,
DateTime endDuration,
) =>
double heightPerMinute, {
bool isMinEventTileHeight = false,
}) =>
DefaultEventTile(
date: date,
events: events,
boundary: boundary,
startDuration: startDuration,
endDuration: endDuration,
heightPerMinute: heightPerMinute,
isMinEventTileHeight: isMinEventTileHeight,
);

/// Default view header builder. This builder will be used if
Expand Down
8 changes: 7 additions & 1 deletion lib/src/event_arrangers/event_arrangers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ abstract class EventArranger<T extends Object?> {
required double width,
required double heightPerMinute,
required int startHour,
required TextScaler textScaleFactor,
bool isMinEventTileHeight = false,
});
}

Expand All @@ -63,6 +65,8 @@ class OrganizedCalendarEventData<T extends Object?> {
/// End duration of event/event list.
final DateTime endDuration;

final DateTime? newEndDuration;

/// Provides event data with its [left], [right], [top], and [bottom]
/// boundary.
OrganizedCalendarEventData({
Expand All @@ -73,6 +77,7 @@ class OrganizedCalendarEventData<T extends Object?> {
required this.left,
required this.right,
required this.events,
this.newEndDuration,
});

OrganizedCalendarEventData.empty()
Expand All @@ -82,7 +87,8 @@ class OrganizedCalendarEventData<T extends Object?> {
left = 0,
events = const [],
top = 0,
bottom = 0;
bottom = 0,
newEndDuration = null;

OrganizedCalendarEventData<T> getWithUpdatedRight(double right) =>
OrganizedCalendarEventData<T>(
Expand Down
Loading

0 comments on commit 4052521

Please sign in to comment.