Skip to content

Commit

Permalink
Fix SelectableLazyList scrolling logic and event handling (#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
fscarponi authored Oct 16, 2023
1 parent a36e52d commit 4da6105
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand All @@ -22,6 +23,7 @@ import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import org.jetbrains.jewel.foundation.lazy.SelectableLazyListScopeContainer.Entry
import org.jetbrains.jewel.foundation.tree.DefaultSelectableLazyColumnEventAction
import org.jetbrains.jewel.foundation.tree.DefaultSelectableLazyColumnKeyActions
Expand All @@ -48,6 +50,7 @@ fun SelectableLazyColumn(
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: SelectableLazyListScope.() -> Unit,
) {
val scope = rememberCoroutineScope()
val container = SelectableLazyListScopeContainer()
.apply(content)

Expand All @@ -74,7 +77,16 @@ fun SelectableLazyColumn(
.focusable(interactionSource = interactionSource)
.onPreviewKeyEvent { event ->
if (state.lastActiveItemIndex != null) {
keyActions.handleOnKeyEvent(event, keys, state, selectionMode).invoke(event)
val actionHandled = keyActions
.handleOnKeyEvent(event, keys, state, selectionMode)
.invoke(event)
if (actionHandled) {
scope.launch {
state.lastActiveItemIndex?.let {
state.scrollToItem(it)
}
}
}
}
true
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ val SelectableLazyListState.visibleItemsRange
get() = firstVisibleItemIndex..firstVisibleItemIndex + layoutInfo.visibleItemsInfo.size

interface SelectableScope {

var selectedKeys: List<Any>
}

Expand All @@ -41,16 +42,14 @@ class SelectableLazyListState(
* @param itemIndex The index of the item to focus on.
* @param animateScroll Whether to animate the scroll to the focused item.
* @param scrollOffset The scroll offset for the focused item.
* @param skipScroll Whether to skip the scroll to the focused item.
*/
suspend fun scrollToItem(
itemIndex: Int,
animateScroll: Boolean = false,
scrollOffset: Int = 0,
skipScroll: Boolean = false,
) {
val visibleRange = visibleItemsRange.drop(2).dropLast(4)
if (!skipScroll && itemIndex !in visibleRange && visibleRange.isNotEmpty()) {
if (itemIndex !in visibleRange && visibleRange.isNotEmpty()) {
when {
itemIndex < visibleRange.first() -> lazyListState.scrollToItem(
max(0, itemIndex - 2),
Expand All @@ -59,7 +58,7 @@ class SelectableLazyListState(
)

itemIndex > visibleRange.last() -> {
lazyListState.scrollToItem(max(itemIndex - (visibleRange.size + 1), 0), animateScroll, 0)
lazyListState.scrollToItem(max(itemIndex - (visibleRange.size + 2), 0), animateScroll, 0)
}
}
}
Expand Down

0 comments on commit 4da6105

Please sign in to comment.