diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/MainActivity.kt b/demo/src/main/kotlin/eu/wewox/pagecurl/MainActivity.kt index 9abb1e3..7195178 100644 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/MainActivity.kt +++ b/demo/src/main/kotlin/eu/wewox/pagecurl/MainActivity.kt @@ -8,12 +8,15 @@ import androidx.activity.compose.setContent import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Text +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 import androidx.compose.ui.graphics.Color @@ -22,6 +25,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import eu.wewox.pagecurl.components.SettingsPopup +import eu.wewox.pagecurl.components.overlayControls import eu.wewox.pagecurl.config.PageCurlConfig import eu.wewox.pagecurl.page.PageCurl import eu.wewox.pagecurl.page.rememberPageCurlState @@ -33,13 +37,31 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) setContent { PageCurlTheme { - Column { + Box { val scope = rememberCoroutineScope() val state = rememberPageCurlState(max = 6) + var showPopup by remember { mutableStateOf(false) } PageCurl( state = state, config = PageCurlConfig(), + modifier = Modifier.overlayControls( + next = { + scope.launch { + val next = (state.current + 1).coerceAtMost(state.max - 1) + state.snapTo(next) + } + }, + prev = { + scope.launch { + val prev = (state.current - 1).coerceAtLeast(0) + state.snapTo(prev) + } + }, + center = { + showPopup = true + } + ) ) { index -> Box( modifier = Modifier @@ -71,22 +93,28 @@ class MainActivity : ComponentActivity() { .background(Color.Black, RoundedCornerShape(topStartPercent = 100)) .padding(16.dp) ) - - SettingsPopup( - onSnapToFirst = { - scope.launch { - state.snapTo(0) - } - }, - onSnapToLast = { - scope.launch { - state.snapTo(state.max - 1) - } - }, - modifier = Modifier.align(Alignment.Center) - ) } } + + if (showPopup) { + SettingsPopup( + onSnapToFirst = { + scope.launch { + state.snapTo(0) + showPopup = false + } + }, + onSnapToLast = { + scope.launch { + state.snapTo(state.max - 1) + showPopup = false + } + }, + onDismiss = { + showPopup = false + } + ) + } } } } diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/components/OverlayControls.kt b/demo/src/main/kotlin/eu/wewox/pagecurl/components/OverlayControls.kt new file mode 100644 index 0000000..42c022e --- /dev/null +++ b/demo/src/main/kotlin/eu/wewox/pagecurl/components/OverlayControls.kt @@ -0,0 +1,37 @@ +package eu.wewox.pagecurl.components + +import androidx.compose.foundation.gestures.awaitFirstDown +import androidx.compose.foundation.gestures.forEachGesture +import androidx.compose.foundation.gestures.waitForUpOrCancellation +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.unit.center +import androidx.compose.ui.unit.toOffset + +internal fun Modifier.overlayControls( + next: () -> Unit, + prev: () -> Unit, + center: () -> Unit, +): Modifier = pointerInput(Unit) { + forEachGesture { + awaitPointerEventScope { + val down = awaitFirstDown().also { it.consume() } + val up = waitForUpOrCancellation() ?: return@awaitPointerEventScope + up.consume() + if ((down.position - up.position).getDistance() > viewConfiguration.touchSlop) { + return@awaitPointerEventScope + } + + if ((up.position - size.center.toOffset()).getDistance() < 100f) { + center() + return@awaitPointerEventScope + } + + if (up.position.x < size.width / 2) { + prev() + } else { + next() + } + } + } +} diff --git a/demo/src/main/kotlin/eu/wewox/pagecurl/components/SettingsPopup.kt b/demo/src/main/kotlin/eu/wewox/pagecurl/components/SettingsPopup.kt index 33f6dc6..0f8267f 100644 --- a/demo/src/main/kotlin/eu/wewox/pagecurl/components/SettingsPopup.kt +++ b/demo/src/main/kotlin/eu/wewox/pagecurl/components/SettingsPopup.kt @@ -1,26 +1,16 @@ package eu.wewox.pagecurl.components -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Card import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.material.TextButton import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.composed import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Popup @@ -28,66 +18,38 @@ import androidx.compose.ui.window.Popup internal fun SettingsPopup( onSnapToFirst: () -> Unit, onSnapToLast: () -> Unit, - modifier: Modifier = Modifier + onDismiss: () -> Unit, ) { - var showPopup by remember { mutableStateOf(false) } - - Box( - modifier = modifier - .size(100.dp) - .clickableWithoutRipple { - showPopup = true - } - ) - - if (showPopup) { - Box(Modifier.fillMaxSize()) { - Popup( - alignment = Alignment.Center, - onDismissRequest = { showPopup = false } + Popup( + alignment = Alignment.Center, + onDismissRequest = onDismiss, + ) { + Card( + shape = RoundedCornerShape(24.dp), + backgroundColor = MaterialTheme.colors.primary, + elevation = 16.dp, + ) { + Column( + verticalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier.padding(8.dp) ) { - Card( - shape = RoundedCornerShape(24.dp), - backgroundColor = MaterialTheme.colors.primary, - elevation = 16.dp + TextButton( + onClick = onSnapToFirst ) { - Column( - verticalArrangement = Arrangement.spacedBy(8.dp), - modifier = Modifier.padding(8.dp) - ) { - TextButton( - onClick = { - onSnapToFirst() - showPopup = false - } - ) { - Text( - text = "Go to first", - color = MaterialTheme.colors.onPrimary - ) - } - TextButton( - onClick = { - onSnapToLast() - showPopup = false - } - ) { - Text( - text = "Go to last", - color = MaterialTheme.colors.onPrimary - ) - } - } + Text( + text = "Go to first", + color = MaterialTheme.colors.onPrimary + ) + } + TextButton( + onClick = onSnapToLast + ) { + Text( + text = "Go to last", + color = MaterialTheme.colors.onPrimary + ) } } } } } - -private fun Modifier.clickableWithoutRipple(onClick: () -> Unit) = composed { - clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = onClick - ) -}