From 97dcc42416e95eb0931b2558fb30c890aeac6b39 Mon Sep 17 00:00:00 2001 From: LTFan Date: Sat, 20 Jan 2024 21:36:23 +0800 Subject: [PATCH] feat: scrollbars --- build-number.properties | 2 +- .../ui/composables/Scrollbars.android.kt | 27 ++++++++++++++++ .../kotlin/ui/composables/Scrollbars.kt | 26 ++++++++++++++++ .../commonMain/kotlin/ui/pages/root/SignIn.kt | 28 ++++++++++++++--- .../ui/composables/Scrollbars.desktop.kt | 31 +++++++++++++++++++ .../ui/composables/Scrollbars.wasmJs.kt | 27 ++++++++++++++++ 6 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 composeApp/src/androidMain/kotlin/ui/composables/Scrollbars.android.kt create mode 100644 composeApp/src/commonMain/kotlin/ui/composables/Scrollbars.kt create mode 100644 composeApp/src/desktopMain/kotlin/ui/composables/Scrollbars.desktop.kt create mode 100644 composeApp/src/wasmJsMain/kotlin/ui/composables/Scrollbars.wasmJs.kt diff --git a/build-number.properties b/build-number.properties index b21fb84..18a7270 100644 --- a/build-number.properties +++ b/build-number.properties @@ -15,4 +15,4 @@ # You should have received a copy of the GNU General Public License along # with Fhraise. If not, see . # -buildNumber=17 +buildNumber=18 diff --git a/composeApp/src/androidMain/kotlin/ui/composables/Scrollbars.android.kt b/composeApp/src/androidMain/kotlin/ui/composables/Scrollbars.android.kt new file mode 100644 index 0000000..5313852 --- /dev/null +++ b/composeApp/src/androidMain/kotlin/ui/composables/Scrollbars.android.kt @@ -0,0 +1,27 @@ +/* + * This file is part of Fhraise. + * Copyright (c) 2024 HSAS Foodies. All Rights Reserved. + * + * Fhraise is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Fhraise is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with Fhraise. If not, see . + */ + +package ui.composables + +import androidx.compose.foundation.ScrollState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +@Composable +actual fun VerticalScrollbar(scrollState: ScrollState, modifier: Modifier) { +} diff --git a/composeApp/src/commonMain/kotlin/ui/composables/Scrollbars.kt b/composeApp/src/commonMain/kotlin/ui/composables/Scrollbars.kt new file mode 100644 index 0000000..9211e20 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ui/composables/Scrollbars.kt @@ -0,0 +1,26 @@ +/* + * This file is part of Fhraise. + * Copyright (c) 2024 HSAS Foodies. All Rights Reserved. + * + * Fhraise is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Fhraise is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with Fhraise. If not, see . + */ + +package ui.composables + +import androidx.compose.foundation.ScrollState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +@Composable +expect fun VerticalScrollbar(scrollState: ScrollState, modifier: Modifier = Modifier) diff --git a/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt b/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt index d6b241e..6ba69a7 100644 --- a/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt +++ b/composeApp/src/commonMain/kotlin/ui/pages/root/SignIn.kt @@ -55,6 +55,7 @@ import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.painterResource import ui.WindowSizeClass import ui.WindowWidthSizeClass +import ui.composables.VerticalScrollbar import ui.modifiers.applyBrush import kotlin.math.max import kotlin.math.roundToInt @@ -197,6 +198,8 @@ fun SignInLayout( targetValue = if (animation == null) 0f else 1f, animationSpec = spring(stiffness = Spring.StiffnessLow) ) + val scrollState = rememberScrollState() + SubcomposeLayout( modifier = Modifier.alpha(firstPrintAnimation).offset(y = 32.dp * (1f - firstPrintAnimation)).then(modifier) ) { constraints -> @@ -248,16 +251,19 @@ fun SignInLayout( val additionalContentPlaceable = additionalContentMeasurable.measure(additionalContentConstraints) // == Measure main == + val mainBottomSpace = + ((additionalContentPlaceable.height + additionalContentPaddingBottom) * animationSecondStageReversed) + val mainMeasurable = subcompose("main") { SignInMainLayout( animation = animation, animationSecondStage = animationSecondStage, - scrollState = rememberScrollState(), + scrollState = scrollState, contentPaddingLeft = contentPaddingLeft, contentPaddingTop = contentPaddingTop, contentPaddingRight = contentPaddingRight, contentPaddingBottom = contentPaddingBottom, - bottomSpace = ((additionalContentPlaceable.height + additionalContentPaddingBottom) * animationSecondStageReversed).roundToInt(), + bottomSpace = mainBottomSpace.roundToInt(), header = header, mainContent = content, ) @@ -265,11 +271,24 @@ fun SignInLayout( val mainCompatWidth = width.toFloat() val mainMediumExpandedWidth = width * 7f / 9f - val mainWidth = mainCompatWidth + (mainMediumExpandedWidth - mainCompatWidth) * animationSecondStage + val mainWidth = + (mainCompatWidth + (mainMediumExpandedWidth - mainCompatWidth) * animationSecondStage).coerceAtLeast(0f) + .roundToInt() - val mainConstraints = Constraints.fixed(width = mainWidth.roundToInt().coerceAtLeast(0), height = height) + val mainConstraints = Constraints.fixed(width = mainWidth, height = height) val mainPlaceable = mainMeasurable.measure(mainConstraints) + // == Scrollbar == + val scrollbarHeight = (safeHeight - mainBottomSpace).roundToInt() + + val scrollbarPlaceable = subcompose("scrollBar") { + VerticalScrollbar(scrollState = scrollState) + }.firstOrNull() + ?.measure(Constraints(maxWidth = mainWidth, minHeight = scrollbarHeight, maxHeight = scrollbarHeight)) + + val scrollbarX = scrollbarPlaceable?.let { mainWidth - scrollbarPlaceable.width } + val scrollbarY = contentPaddingTop.roundToInt() + // == Place == val additionalContentCompatMediumX = 0f val additionalContentX = @@ -305,6 +324,7 @@ fun SignInLayout( layout(width, height) { mainPlaceable.placeRelative(0, 0) + scrollbarX?.let { scrollbarPlaceable.placeRelative(scrollbarX, scrollbarY) } additionalContentBackgroundPlaceable.placeRelative(0, additionalContentBackgroundY.roundToInt()) additionalContentPlaceable.placeRelative(additionalContentX.roundToInt(), additionalContentY.roundToInt()) } diff --git a/composeApp/src/desktopMain/kotlin/ui/composables/Scrollbars.desktop.kt b/composeApp/src/desktopMain/kotlin/ui/composables/Scrollbars.desktop.kt new file mode 100644 index 0000000..ce544d7 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/ui/composables/Scrollbars.desktop.kt @@ -0,0 +1,31 @@ +/* + * This file is part of Fhraise. + * Copyright (c) 2024 HSAS Foodies. All Rights Reserved. + * + * Fhraise is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Fhraise is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with Fhraise. If not, see . + */ + +package ui.composables + +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.rememberScrollbarAdapter +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +@Composable +actual fun VerticalScrollbar(scrollState: ScrollState, modifier: Modifier) { + androidx.compose.foundation.VerticalScrollbar( + adapter = rememberScrollbarAdapter(scrollState = scrollState), modifier = modifier + ) +} diff --git a/composeApp/src/wasmJsMain/kotlin/ui/composables/Scrollbars.wasmJs.kt b/composeApp/src/wasmJsMain/kotlin/ui/composables/Scrollbars.wasmJs.kt new file mode 100644 index 0000000..5313852 --- /dev/null +++ b/composeApp/src/wasmJsMain/kotlin/ui/composables/Scrollbars.wasmJs.kt @@ -0,0 +1,27 @@ +/* + * This file is part of Fhraise. + * Copyright (c) 2024 HSAS Foodies. All Rights Reserved. + * + * Fhraise is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Fhraise is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with Fhraise. If not, see . + */ + +package ui.composables + +import androidx.compose.foundation.ScrollState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +@Composable +actual fun VerticalScrollbar(scrollState: ScrollState, modifier: Modifier) { +}