Start new Home rows leftmost and gate outgoing Back handlers
This commit is contained in:
parent
5811ab0555
commit
c5dbe91076
7 changed files with 82 additions and 32 deletions
|
|
@ -1,7 +1,5 @@
|
|||
package org.justinvisser.wolfskin.design
|
||||
|
||||
import kotlin.math.abs
|
||||
|
||||
/** Home navigation mutates the shell's per-person view, including each row's remembered column. */
|
||||
class HomeFocus(
|
||||
private val shell: ShellState,
|
||||
|
|
@ -38,8 +36,7 @@ class HomeFocus(
|
|||
while (next in rows.indices && !rows[next].focusable) next += direction
|
||||
if (next in rows.indices) {
|
||||
val target = rows[next]
|
||||
val nearest = nearest(current, target)
|
||||
focus(next, view.cards[target.id] ?: nearest)
|
||||
focus(next, view.cards[target.id] ?: 0)
|
||||
} else if (direction < 0) {
|
||||
view.row = rows.indexOfFirst { it.focusable }.coerceAtLeast(0)
|
||||
view.home.resetScroll++
|
||||
|
|
@ -77,27 +74,6 @@ class HomeFocus(
|
|||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun nearest(from: HomeRow, to: HomeRow): Int {
|
||||
if (to.kind != HomeRowKind.Shelf) return (column * pitch(from) / pitch(to)).toInt()
|
||||
val fromFirst = if (from.kind == HomeRowKind.Shelf) view.home.firstCards[from.id] ?: from.adjustedFirst(column, 0) else 0
|
||||
val x = (column - fromFirst) * pitch(from) + from.cardWidth.value / 2
|
||||
val first = (view.home.firstCards[to.id] ?: 0).coerceIn(0, (to.count - to.focusSlots).coerceAtLeast(0))
|
||||
val last = minOf(to.count - 1, first + to.focusSlots - 1)
|
||||
var best = first
|
||||
var distance = Float.POSITIVE_INFINITY
|
||||
for (index in first..last) {
|
||||
val candidate = abs((index - first) * pitch(to) + to.cardWidth.value / 2 - x)
|
||||
if (candidate < distance) { best = index; distance = candidate }
|
||||
}
|
||||
return best
|
||||
}
|
||||
|
||||
private fun pitch(row: HomeRow): Float = when (row.cardKind) {
|
||||
HomeCardKind.Poster -> WolfskinTokens.Card.posterPitch.value
|
||||
HomeCardKind.Tile -> WolfskinTokens.Card.tilePitch.value
|
||||
HomeCardKind.Wide -> WolfskinTokens.Card.widePitch.value
|
||||
}
|
||||
}
|
||||
|
||||
internal val HomeRow.focusSlots: Int get() = when (cardKind) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ import androidx.compose.runtime.remember
|
|||
internal val LocalScreenView = compositionLocalOf<RememberedView?> { null }
|
||||
internal val LocalScreenActive = compositionLocalOf { true }
|
||||
|
||||
/** Outgoing entries cannot consume Back while their exit animation remains composed. */
|
||||
@Composable
|
||||
fun isScreenEntryActive(): Boolean = LocalScreenActive.current
|
||||
|
||||
/** Overlapping navigation entries retain their own viewport; only the current entry owns input. */
|
||||
@Composable
|
||||
fun ScreenEntry(shell: ShellState, route: String, active: Boolean, content: @Composable () -> Unit) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue