Skip to content

Commit 423c91a

Browse files
committed
Replace WeekViewEntity with more versatile WeekViewItem
1 parent b2dd221 commit 423c91a

33 files changed

+814
-578
lines changed

core/src/main/java/com/alamkanak/weekview/CalendarExtensions.kt

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ internal fun Calendar.format(): String {
312312
return sdf.format(time)
313313
}
314314

315-
fun Calendar.computeDifferenceWithFirstDayOfWeek(): Int {
315+
internal fun Calendar.computeDifferenceWithFirstDayOfWeek(): Int {
316316
val firstDayOfWeek = firstDayOfWeek
317317
return if (firstDayOfWeek == Calendar.MONDAY && dayOfWeek == Calendar.SUNDAY) {
318318
// Special case, because Calendar.MONDAY has constant value 2 and Calendar.SUNDAY has
@@ -323,18 +323,34 @@ fun Calendar.computeDifferenceWithFirstDayOfWeek(): Int {
323323
}
324324
}
325325

326-
fun Calendar.previousFirstDayOfWeek(): Calendar {
326+
internal fun Calendar.previousFirstDayOfWeek(): Calendar {
327327
val result = this - Days(1)
328328
while (result.dayOfWeek != firstDayOfWeek) {
329329
result.add(Calendar.DATE, -1)
330330
}
331331
return result
332332
}
333333

334-
fun Calendar.nextFirstDayOfWeek(): Calendar {
334+
internal fun Calendar.nextFirstDayOfWeek(): Calendar {
335335
val result = this + Days(1)
336336
while (result.dayOfWeek != firstDayOfWeek) {
337337
result.add(Calendar.DATE, 1)
338338
}
339339
return result
340340
}
341+
342+
internal fun Calendar.limitToMinHour(minHour: Int): Calendar {
343+
return if (hour < minHour) {
344+
withTimeAtStartOfPeriod(hour = minHour)
345+
} else {
346+
this
347+
}
348+
}
349+
350+
internal fun Calendar.limitToMaxHour(maxHour: Int): Calendar {
351+
return if (hour >= maxHour) {
352+
withTimeAtEndOfPeriod(hour = maxHour)
353+
} else {
354+
this
355+
}
356+
}

core/src/main/java/com/alamkanak/weekview/CalendarRenderer.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ private class SingleEventsUpdater(
5757
}
5858

5959
val eventChips = chipsCache?.normalEventChipsByDate(date).orEmpty().filter {
60-
it.event.isWithin(viewState.minHour, viewState.maxHour)
60+
it.item.isWithin(viewState.minHour, viewState.maxHour)
6161
}
6262

6363
eventChips.calculateBounds(startPixel = modifiedStartPixel)
@@ -244,11 +244,19 @@ private class SingleEventsDrawer(
244244
return
245245
}
246246

247-
val sortedEventChips = eventChips.sortedBy {
248-
it.event.id == viewState.dragState?.eventId
247+
val (backgroundChips, foregroundChips) = eventChips.partition {
248+
it.item.configuration.arrangement == WeekViewItem.Arrangement.Background
249249
}
250250

251-
for (eventChip in sortedEventChips) {
251+
val draggedEventId = viewState.dragState?.eventId
252+
253+
val sortedChips = mutableListOf<EventChip>().apply {
254+
// Make sure that the currently dragged chip is rendered above all other chips
255+
this += backgroundChips.sortedBy { it.item.id == draggedEventId }
256+
this += foregroundChips.sortedBy { it.item.id == draggedEventId }
257+
}
258+
259+
for (eventChip in sortedChips) {
252260
val textLayout = eventLabels[eventChip.id]
253261
eventChipDrawer.draw(eventChip, canvas = this, textLayout)
254262
}

core/src/main/java/com/alamkanak/weekview/DragHandler.kt

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ internal class DragHandler(
1818

1919
private val executor = DragScrollExecutor()
2020

21-
private val draggedEvent: ResolvedWeekViewEntity?
21+
private val draggedEvent: WeekViewItem?
2222
get() {
2323
val eventsCache = eventsCacheProvider() ?: return null
2424
val eventId = viewState.dragState?.eventId ?: return null
@@ -30,8 +30,8 @@ internal class DragHandler(
3030

3131
fun startDragAndDrop(eventChip: EventChip, x: Float, y: Float) {
3232
viewState.dragState = DragState(
33-
eventId = eventChip.eventId,
34-
draggedEventStartTime = eventChip.event.startTime,
33+
eventId = eventChip.itemId,
34+
draggedEventStartTime = eventChip.item.timing.startTime,
3535
dragStartTime = requireNotNull(touchHandler.calculateTimeFromPoint(x, y)),
3636
)
3737

@@ -84,10 +84,12 @@ internal class DragHandler(
8484

8585
private fun updateDraggedEvent(newStartTime: Calendar) {
8686
val originalEvent = draggedEvent ?: return
87-
val updatedEvent = originalEvent.createCopy(
88-
startTime = newStartTime,
89-
endTime = newStartTime + Minutes(originalEvent.durationInMinutes),
90-
)
87+
val updatedEvent = originalEvent
88+
// TODO
89+
// .copyWith(
90+
// startTime = newStartTime,
91+
// endTime = newStartTime + Minutes(originalEvent.durationInMinutes),
92+
// )
9193

9294
val eventsProcessor = eventsProcessorProvider() ?: return
9395
eventsProcessor.updateDraggedEntity(updatedEvent, viewState)
@@ -116,7 +118,7 @@ internal class DragHandler(
116118
}
117119

118120
val draggedEvent = draggedEvent ?: return@execute
119-
updateDraggedEvent(newStartTime = draggedEvent.startTime - Minutes(15))
121+
updateDraggedEvent(newStartTime = draggedEvent.timing.startTime - Minutes(15))
120122

121123
val distance = viewState.hourHeight / 4f
122124
navigator.scrollVerticallyBy(distance = distance * (-1))
@@ -132,7 +134,7 @@ internal class DragHandler(
132134
}
133135

134136
val draggedEvent = draggedEvent ?: return@execute
135-
updateDraggedEvent(newStartTime = draggedEvent.startTime + Minutes(15))
137+
updateDraggedEvent(newStartTime = draggedEvent.timing.startTime + Minutes(15))
136138

137139
val distance = viewState.hourHeight / 4f
138140
navigator.scrollVerticallyBy(distance = distance)
@@ -142,19 +144,19 @@ internal class DragHandler(
142144
private fun scrollLeft() {
143145
executor.execute(delay = 600) {
144146
val draggedEvent = draggedEvent ?: return@execute
145-
updateDraggedEvent(newStartTime = draggedEvent.startTime - Days(1))
147+
updateDraggedEvent(newStartTime = draggedEvent.timing.startTime - Days(1))
146148

147-
val date = draggedEvent.startTime.atStartOfDay
149+
val date = draggedEvent.timing.startTime.atStartOfDay
148150
navigator.scrollHorizontallyTo(date - Days(1))
149151
}
150152
}
151153

152154
private fun scrollRight() {
153155
executor.execute(delay = 600) {
154156
val draggedEvent = draggedEvent ?: return@execute
155-
updateDraggedEvent(newStartTime = draggedEvent.startTime + Days(1))
157+
updateDraggedEvent(newStartTime = draggedEvent.timing.startTime + Days(1))
156158

157-
val date = draggedEvent.startTime.atStartOfDay
159+
val date = draggedEvent.timing.startTime.atStartOfDay
158160
navigator.scrollHorizontallyTo(date + Days(1))
159161
}
160162
}

core/src/main/java/com/alamkanak/weekview/EventChip.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import android.graphics.RectF
44
import java.util.Calendar
55

66
/**
7-
* This class encapsulates a [ResolvedWeekViewEntity] and its visual representation, a [RectF] which
8-
* is drawn to the screen. There may be more than one [EventChip] for any [ResolvedWeekViewEntity],
9-
* for instance in the case of multi-day events.
7+
* This class encapsulates a [WeekViewItem] and its visual representation, a [RectF] which is drawn
8+
* to the screen. There may be more than one [EventChip] for any [WeekViewItem], for instance in the
9+
* case of multi-day events.
1010
*/
1111
internal data class EventChip(
12-
val event: ResolvedWeekViewEntity,
12+
val item: WeekViewItem,
1313
val index: Int,
1414
val startTime: Calendar,
1515
val endTime: Calendar,
@@ -18,12 +18,12 @@ internal data class EventChip(
1818
/**
1919
* A unique ID of this [EventChip].
2020
*/
21-
val id: String = "${event.id}-$index"
21+
val id: String = "${item.id}-$index"
2222

2323
/**
24-
* The ID of this [EventChip]'s [ResolvedWeekViewEntity].
24+
* The ID of this [EventChip]'s [WeekViewItem].
2525
*/
26-
val eventId: Long = event.id
26+
val itemId: Long = item.id
2727

2828
/**
2929
* The bounds in which [EventChip] will be drawn.
@@ -62,10 +62,10 @@ internal data class EventChip(
6262
var minutesFromStartHour: Int = 0
6363

6464
val startsOnEarlierDay: Boolean
65-
get() = event.startTime < startTime
65+
get() = item.timing.startTime < startTime
6666

6767
val endsOnLaterDay: Boolean
68-
get() = event.endTime > endTime
68+
get() = item.timing.endTime > endTime
6969

7070
fun setEmpty() {
7171
bounds.setEmpty()

core/src/main/java/com/alamkanak/weekview/EventChipBoundsCalculator.kt

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,10 @@ internal class EventChipBoundsCalculator(
1010
eventChip: EventChip,
1111
startPixel: Float
1212
): RectF {
13-
val drawableWidth = when (eventChip.event) {
14-
is ResolvedWeekViewEntity.Event<*> -> viewState.drawableDayWidth
15-
is ResolvedWeekViewEntity.BlockedTime -> viewState.dayWidth
16-
}
13+
val respectDayGap = eventChip.item.configuration.respectDayGap
14+
val drawableWidth = if (respectDayGap) viewState.drawableDayWidth else viewState.dayWidth
1715

18-
val isBlockedTime = eventChip.event is ResolvedWeekViewEntity.BlockedTime
19-
val leftOffset = if (viewState.isLtr || isBlockedTime) 0 else viewState.columnGap
16+
val leftOffset = if (viewState.isLtr || !respectDayGap) 0 else viewState.columnGap
2017

2118
val minutesFromStart = eventChip.minutesFromStartHour
2219
val top = calculateDistanceFromTop(minutesFromStart)
@@ -27,7 +24,7 @@ internal class EventChipBoundsCalculator(
2724
val partialEventEndsAtEndOfDay = eventChip.endTime.isAtEndOfPeriod(hour = viewState.maxHour)
2825
val fullEventContinuesOnNextDay = eventChip.endsOnLaterDay
2926

30-
if (!(partialEventEndsAtEndOfDay && fullEventContinuesOnNextDay) && !isBlockedTime) {
27+
if (!(partialEventEndsAtEndOfDay && fullEventContinuesOnNextDay)) {
3128
// There's only one case where we don't render a vertical margin: The partial event ends
3229
// at midnight, but the full event continues continues on the next day.
3330
bottom -= viewState.eventMarginVertical
@@ -49,7 +46,7 @@ internal class EventChipBoundsCalculator(
4946
right -= viewState.singleDayHorizontalPadding * 2
5047
}
5148

52-
val isBeingDragged = eventChip.eventId == viewState.dragState?.eventId
49+
val isBeingDragged = eventChip.itemId == viewState.dragState?.eventId
5350
if (isBeingDragged) {
5451
left = startPixel + leftOffset
5552
right = left + drawableWidth

core/src/main/java/com/alamkanak/weekview/EventChipDrawer.kt

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,39 +17,27 @@ internal class EventChipDrawer(
1717
private val backgroundPaint = Paint()
1818
private val borderPaint = Paint()
1919

20-
private val patternPaint = Paint(Paint.ANTI_ALIAS_FLAG)
21-
2220
internal fun draw(
2321
eventChip: EventChip,
2422
canvas: Canvas,
2523
textLayout: StaticLayout?
2624
) = with(canvas) {
27-
val entity = eventChip.event
25+
val item = eventChip.item
2826
val bounds = eventChip.bounds
29-
val cornerRadius = (entity.style.cornerRadius ?: viewState.eventCornerRadius).toFloat()
27+
val cornerRadius = (item.style.cornerRadius ?: viewState.eventCornerRadius).toFloat()
3028

31-
val isBeingDragged = entity.id == viewState.dragState?.eventId
32-
updateBackgroundPaint(entity, isBeingDragged, backgroundPaint)
29+
val isBeingDragged = item.id == viewState.dragState?.eventId
30+
updateBackgroundPaint(item, isBeingDragged, backgroundPaint)
3331
drawRoundRect(bounds, cornerRadius, cornerRadius, backgroundPaint)
3432

35-
val pattern = entity.style.pattern
36-
if (pattern != null) {
37-
drawPattern(
38-
pattern = pattern,
39-
bounds = eventChip.bounds,
40-
isLtr = viewState.isLtr,
41-
paint = patternPaint
42-
)
43-
}
44-
45-
val borderWidth = entity.style.borderWidth
33+
val borderWidth = item.style.borderWidth
4634
if (borderWidth != null && borderWidth > 0) {
47-
updateBorderPaint(entity, borderPaint)
35+
updateBorderPaint(item, borderPaint)
4836
val borderBounds = bounds.insetBy(borderWidth / 2f)
4937
drawRoundRect(borderBounds, cornerRadius, cornerRadius, borderPaint)
5038
}
5139

52-
if (entity.isMultiDay && entity.isNotAllDay) {
40+
if (item.isMultiDay && item.isNotAllDay) {
5341
drawCornersForMultiDayEvents(eventChip, cornerRadius)
5442
}
5543

@@ -62,11 +50,11 @@ internal class EventChipDrawer(
6250
eventChip: EventChip,
6351
cornerRadius: Float
6452
) {
65-
val event = eventChip.event
53+
val item = eventChip.item
6654
val bounds = eventChip.bounds
6755

68-
val isBeingDragged = event.id == viewState.dragState?.eventId
69-
updateBackgroundPaint(event, isBeingDragged, backgroundPaint)
56+
val isBeingDragged = item.id == viewState.dragState?.eventId
57+
updateBackgroundPaint(item, isBeingDragged, backgroundPaint)
7058

7159
if (eventChip.startsOnEarlierDay) {
7260
val topRect = RectF(bounds)
@@ -80,7 +68,7 @@ internal class EventChipDrawer(
8068
drawRect(bottomRect, backgroundPaint)
8169
}
8270

83-
if (event.style.borderWidth != null) {
71+
if (item.style.borderWidth != null) {
8472
drawMultiDayBorderStroke(eventChip, cornerRadius)
8573
}
8674
}
@@ -89,14 +77,14 @@ internal class EventChipDrawer(
8977
eventChip: EventChip,
9078
cornerRadius: Float
9179
) {
92-
val event = eventChip.event
80+
val item = eventChip.item
9381
val bounds = eventChip.bounds
9482

95-
val borderWidth = event.style.borderWidth ?: 0
83+
val borderWidth = item.style.borderWidth ?: 0
9684
val borderStart = bounds.left + borderWidth / 2
9785
val borderEnd = bounds.right - borderWidth / 2
9886

99-
updateBorderPaint(event, backgroundPaint)
87+
updateBorderPaint(item, backgroundPaint)
10088

10189
if (eventChip.startsOnEarlierDay) {
10290
drawVerticalLine(
@@ -143,7 +131,7 @@ internal class EventChipDrawer(
143131
bounds.right - viewState.eventPaddingHorizontal
144132
}
145133

146-
val verticalOffset = if (eventChip.event.isAllDay) {
134+
val verticalOffset = if (eventChip.item.isAllDay) {
147135
(bounds.height() - textLayout.height) / 2f
148136
} else {
149137
viewState.eventPaddingVertical.toFloat()
@@ -155,11 +143,11 @@ internal class EventChipDrawer(
155143
}
156144

157145
private fun updateBackgroundPaint(
158-
entity: ResolvedWeekViewEntity,
146+
item: WeekViewItem,
159147
isBeingDragged: Boolean,
160148
paint: Paint
161149
) = with(paint) {
162-
color = entity.style.backgroundColor ?: viewState.defaultEventColor
150+
color = item.style.backgroundColor ?: viewState.defaultEventColor
163151
isAntiAlias = true
164152
strokeWidth = 0f
165153
style = Paint.Style.FILL
@@ -172,12 +160,12 @@ internal class EventChipDrawer(
172160
}
173161

174162
private fun updateBorderPaint(
175-
entity: ResolvedWeekViewEntity,
163+
item: WeekViewItem,
176164
paint: Paint
177165
) = with(paint) {
178-
color = entity.style.borderColor ?: viewState.defaultEventColor
166+
color = item.style.borderColor ?: viewState.defaultEventColor
179167
isAntiAlias = true
180-
strokeWidth = entity.style.borderWidth?.toFloat() ?: 0f
168+
strokeWidth = item.style.borderWidth?.toFloat() ?: 0f
181169
style = Paint.Style.STROKE
182170
}
183171
}

0 commit comments

Comments
 (0)