From 834cfc5e8c7de5b56e6702844b394ea3bc79e855 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:22:48 +0800 Subject: [PATCH] Support scrolling with mouse wheel in reader --- .../hippo/ehviewer/ui/reader/GalleryPager.kt | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/GalleryPager.kt b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/GalleryPager.kt index 5fff5cfeb..f7bff00d9 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/GalleryPager.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/ui/reader/GalleryPager.kt @@ -5,13 +5,20 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.pager.PagerState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.AwaitPointerEventScope +import androidx.compose.ui.input.pointer.PointerEvent +import androidx.compose.ui.input.pointer.PointerEventType +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp +import androidx.compose.ui.util.fastFold import com.hippo.ehviewer.Settings import com.hippo.ehviewer.collectAsState import com.hippo.ehviewer.gallery.PageLoader2 @@ -22,6 +29,9 @@ import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType.RIGHT_TO_LEFT import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType.VERTICAL import eu.kanade.tachiyomi.ui.reader.setting.TappingInvertMode import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.receiveAsFlow @Composable fun GalleryPager( @@ -58,6 +68,14 @@ fun GalleryPager( } val navigator by rememberUpdatedState(regions) if (isPagerType) { + val channel = remember { Channel(Channel.CONFLATED) } + LaunchedEffect(channel) { + channel.receiveAsFlow().collectLatest { delta -> + if (delta != 0f) { + if (delta < 0) pagerState.moveToNext() else pagerState.moveToPrevious() + } + } + } PagerViewer( pagerState = pagerState, isRtl = type == RIGHT_TO_LEFT, @@ -67,7 +85,15 @@ fun GalleryPager( onSelectPage = onSelectPage, onMenuRegionClick = onMenuRegionClick, contentPadding = contentPadding, - modifier = modifier, + modifier = modifier.pointerInput(channel) { + awaitPointerEventScope { + while (true) { + val event = awaitScrollEvent() + val delta = calculateMouseWheelScroll(event) + channel.trySend(delta) + } + } + }, ) } else { WebtoonViewer( @@ -83,3 +109,16 @@ fun GalleryPager( } NavigationOverlay(showNavigationOverlay, regions, modifier = Modifier.fillMaxSize()) } + +private suspend fun AwaitPointerEventScope.awaitScrollEvent(): PointerEvent { + var event: PointerEvent + do { + event = awaitPointerEvent() + } while (event.type != PointerEventType.Scroll) + return event +} + +private fun Density.calculateMouseWheelScroll(event: PointerEvent): Float { + // 64 dp value is taken from ViewConfiguration.java, replace with better solution + return event.changes.fastFold(0f) { acc, c -> acc + c.scrollDelta.y } * -64.dp.toPx() +}