Skip to content

Commit

Permalink
Merge pull request #34 from JonasWanke/issue/31-customizable-event-st…
Browse files Browse the repository at this point in the history
…acking

Customizable event stacking
  • Loading branch information
JonasWanke authored Jul 12, 2020
2 parents f89327b + 825c7aa commit 35913ee
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 12 deletions.
40 changes: 30 additions & 10 deletions lib/src/content/date_events.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ class DateEvents<E extends Event> extends StatelessWidget {
static const _defaultMinEventHeight = 16.0;
static const _defaultEventSpacing = 1.0;
static const _defaultStackedEventSpacing = 4.0;
static final Period minStackOverlap = Period(minutes: 15);
static final _defaultPartDayEventMinimumDeltaForStacking =
Period(minutes: 15);
@Deprecated('This is now configurable via '
'[TimetableThemeData.partDayEventMinimumDeltaForStacking].')
static Period get minStackOverlap =>
_defaultPartDayEventMinimumDeltaForStacking;

final LocalDate date;
final List<E> events;
Expand All @@ -54,6 +59,10 @@ class DateEvents<E extends Event> extends StatelessWidget {
timetableTheme?.partDayEventMinimumHeight ?? _defaultMinEventHeight,
eventSpacing:
timetableTheme?.partDayEventSpacing ?? _defaultEventSpacing,
enableStacking: timetableTheme?.enablePartDayEventStacking ?? true,
minimumDeltaForStacking:
timetableTheme?.partDayEventMinimumDeltaForStacking ??
_defaultPartDayEventMinimumDeltaForStacking,
stackedEventSpacing: timetableTheme?.partDayStackedEventSpacing ??
_defaultStackedEventSpacing,
),
Expand All @@ -77,12 +86,16 @@ class _DayEventsLayoutDelegate<E extends Event>
@required this.minEventDuration,
@required this.minEventHeight,
@required this.eventSpacing,
@required this.enableStacking,
@required this.minimumDeltaForStacking,
@required this.stackedEventSpacing,
}) : assert(date != null),
assert(events != null),
assert(minEventDuration != null),
assert(minEventHeight != null),
assert(eventSpacing != null),
assert(enableStacking != null),
assert(minimumDeltaForStacking != null),
assert(stackedEventSpacing != null);

static const minWidth = 4.0;
Expand All @@ -93,6 +106,8 @@ class _DayEventsLayoutDelegate<E extends Event>
final Period minEventDuration;
final double minEventHeight;
final double eventSpacing;
final bool enableStacking;
final Period minimumDeltaForStacking;
final double stackedEventSpacing;

@override
Expand Down Expand Up @@ -184,7 +199,9 @@ class _DayEventsLayoutDelegate<E extends Event>
final other = column.last;

// No space in current column
if (event.start < other.start + DateEvents.minStackOverlap) {
if (!enableStacking && event.start < _actualEnd(other, height) ||
enableStacking &&
event.start < other.start + minimumDeltaForStacking) {
continue;
}

Expand Down Expand Up @@ -226,19 +243,22 @@ class _DayEventsLayoutDelegate<E extends Event>
continue;
}

final cols =
(position.column + 1).rangeTo(columns.length - 1).where((column) {
return currentGroup
.where((e) => positions.eventPositions[e].column == column)
var columnSpan = 1;
for (var i = position.column + 1; i < columns.length; i++) {
final hasOverlapInColumn = currentGroup
.where((e) => positions.eventPositions[e].column == i)
.where((e) =>
event.start < _actualEnd(e, height) &&
e.start < _actualEnd(event, height))
.isEmpty;
}).toList();
final maxColumnWithoutIntersections = cols.max() ?? position.column;
.isNotEmpty;
if (hasOverlapInColumn) {
break;
}

columnSpan++;
}
positions.eventPositions[event] = position.copyWith(
columnSpan: maxColumnWithoutIntersections - position.column + 1,
columnSpan: columnSpan,
);
}

Expand Down
33 changes: 31 additions & 2 deletions lib/src/theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class TimetableThemeData {
this.partDayEventMinimumDuration,
this.partDayEventMinimumHeight,
this.partDayEventSpacing,
this.enablePartDayEventStacking,
this.partDayEventMinimumDeltaForStacking,
this.partDayStackedEventSpacing,
}) : assert(allDayEventHeight == null || allDayEventHeight > 0),
assert(minimumHourHeight == null || minimumHourHeight > 0),
Expand Down Expand Up @@ -135,12 +137,34 @@ class TimetableThemeData {
/// Horizontal space between two parallel events shown next to each other.
final double partDayEventSpacing;

/// Controls whether overlapping events may be stacked on top of each other.
///
/// If set to `true`, intersecting events may be stacked if their start values
/// differ by at least [partDayEventMinimumDeltaForStacking]. If set to
/// `false`, intersecting events will always be shown next to each other and
/// not overlap.
///
/// Defaults to `true`.
final bool enablePartDayEventStacking;

/// When the start values of two events differ by at least this value, they
/// may be stacked on top of each other.
///
/// If the difference is less, they will be shown next to each other.
///
/// Defaults to 15 min.
///
/// See also:
/// - [enablePartDayEventStacking], which can disable the stacking behavior
/// completely.
final Period partDayEventMinimumDeltaForStacking;

/// Horizontal space between two parallel events stacked on top of each other.
final double partDayStackedEventSpacing;

@override
int get hashCode {
return hashValues(
return hashList([
primaryColor,
weekIndicatorDecoration,
weekIndicatorTextStyle,
Expand All @@ -160,8 +184,10 @@ class TimetableThemeData {
partDayEventMinimumDuration,
partDayEventMinimumHeight,
partDayEventSpacing,
enablePartDayEventStacking,
partDayEventMinimumDeltaForStacking,
partDayStackedEventSpacing,
);
]);
}

@override
Expand Down Expand Up @@ -192,6 +218,9 @@ class TimetableThemeData {
other.partDayEventMinimumDuration == partDayEventMinimumDuration &&
other.partDayEventMinimumHeight == partDayEventMinimumHeight &&
other.partDayEventSpacing == partDayEventSpacing &&
other.enablePartDayEventStacking == enablePartDayEventStacking &&
other.partDayEventMinimumDeltaForStacking ==
partDayEventMinimumDeltaForStacking &&
other.partDayStackedEventSpacing == partDayStackedEventSpacing;
}
}
Expand Down

0 comments on commit 35913ee

Please sign in to comment.