@@ -66,6 +66,25 @@ internal class MonthMorphScope(
|
|||||||
|
|
||||||
internal val LocalMonthMorph = compositionLocalOf<MonthMorphScope?> { null }
|
internal val LocalMonthMorph = compositionLocalOf<MonthMorphScope?> { null }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True while the grid is mid-morph, for content that has to stop clipping to let
|
||||||
|
* the travelling pieces through.
|
||||||
|
*
|
||||||
|
* A mark's two homes are in *different rows*: the dot for the 20th sits a third
|
||||||
|
* of the way down the compact grid, its bar most of the way down the expanded
|
||||||
|
* one. Clipped to the row it is arriving at, a mark spends the first half of its
|
||||||
|
* journey outside those bounds and is simply not drawn — so it appears from
|
||||||
|
* nowhere, part-way through, already near its destination. Rendering in place
|
||||||
|
* rather than in an overlay is what subjects them to that clip, and is worth
|
||||||
|
* keeping; the clip is what has to yield, and only while pieces are in flight.
|
||||||
|
*/
|
||||||
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||||
|
@Composable
|
||||||
|
internal fun morphInFlight(): Boolean {
|
||||||
|
val morph = LocalMonthMorph.current ?: return false
|
||||||
|
return morph.shared.isTransitionActive
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tag content that is *the same thing* on both sides — a background pill, a day
|
* Tag content that is *the same thing* on both sides — a background pill, a day
|
||||||
* number — so it animates between its two positions and sizes.
|
* number — so it animates between its two positions and sizes.
|
||||||
|
|||||||
@@ -1647,6 +1647,7 @@ private fun MonthWeekRow(
|
|||||||
val dark = isSystemInDarkTheme()
|
val dark = isSystemInDarkTheme()
|
||||||
val laneCount = (week.spans.maxOfOrNull { it.lane } ?: -1) + 1
|
val laneCount = (week.spans.maxOfOrNull { it.lane } ?: -1) + 1
|
||||||
val shownLanes = laneCount.coerceAtMost(MAX_EVENT_ROWS)
|
val shownLanes = laneCount.coerceAtMost(MAX_EVENT_ROWS)
|
||||||
|
val morphing = morphInFlight()
|
||||||
|
|
||||||
Row(modifier) {
|
Row(modifier) {
|
||||||
// Optional calendar-week gutter, sized so the seven day columns below
|
// Optional calendar-week gutter, sized so the seven day columns below
|
||||||
@@ -1720,11 +1721,15 @@ private fun MonthWeekRow(
|
|||||||
// Breathing room between the day number (and today's circle) and the
|
// Breathing room between the day number (and today's circle) and the
|
||||||
// first event row.
|
// first event row.
|
||||||
Spacer(Modifier.height(DAY_NUMBER_GAP))
|
Spacer(Modifier.height(DAY_NUMBER_GAP))
|
||||||
|
// Clipped at rest so a bar can't spill into the row below, but not
|
||||||
|
// while a morph is in flight: a mark travels between two different
|
||||||
|
// rows, and clipping it to the one it is arriving at hides it for
|
||||||
|
// the whole first half of the journey. See [morphInFlight].
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.clipToBounds(),
|
.then(if (morphing) Modifier else Modifier.clipToBounds()),
|
||||||
) {
|
) {
|
||||||
// Spanning bars on their shared lanes.
|
// Spanning bars on their shared lanes.
|
||||||
week.spans.filter { it.lane < shownLanes }.forEach { span ->
|
week.spans.filter { it.lane < shownLanes }.forEach { span ->
|
||||||
|
|||||||
Reference in New Issue
Block a user