Scrollable SegmentedButtonRow

This commit is contained in:
Sad Ellie 2023-05-03 16:35:05 +03:00
parent 62af6a5ba2
commit 84020de8f9
2 changed files with 67 additions and 63 deletions

View File

@ -18,8 +18,9 @@
package com.sadellie.unitto.core.ui.common package com.sadellie.unitto.core.ui.common
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.Crossfade
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.border
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
@ -27,7 +28,6 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Check
@ -35,51 +35,42 @@ import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedCard import androidx.compose.material3.Text
import androidx.compose.material3.contentColorFor import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
private val GroupRowContainerHeight = 40.dp
private val GroupRowItemMinWidth = 58.dp
@Composable @Composable
fun SegmentedButtonRow( fun SegmentedButtonsRow(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
content: @Composable RowScope.() -> Unit content: @Composable RowScope.() -> Unit
) { ) {
OutlinedCard(
modifier = modifier,
shape = CircleShape
) {
Row( Row(
modifier = Modifier modifier
.height(GroupRowContainerHeight) .width(IntrinsicSize.Max)
.widthIn(min = GroupRowItemMinWidth), .height(40.dp)
verticalAlignment = Alignment.CenterVertically, .clip(CircleShape)
horizontalArrangement = Arrangement.Center .border(1.dp, MaterialTheme.colorScheme.outline, CircleShape)
) { ) {
content() content()
} }
}
} }
@Composable @Composable
fun RowScope.SegmentedButton( fun RowScope.SegmentedButton(
modifier: Modifier = Modifier,
label: String,
onClick: () -> Unit, onClick: () -> Unit,
selected: Boolean, selected: Boolean,
modifier: Modifier = Modifier, icon: ImageVector
enabled: Boolean = true,
content: @Composable () -> Unit,
) { ) {
val containerColor = val containerColor =
if (selected) if (selected) MaterialTheme.colorScheme.secondaryContainer else MaterialTheme.colorScheme.surface
MaterialTheme.colorScheme.secondaryContainer
else
MaterialTheme.colorScheme.surface
OutlinedButton( OutlinedButton(
modifier = modifier.weight(1f), modifier = modifier.weight(1f),
onClick = onClick, onClick = onClick,
@ -88,19 +79,16 @@ fun RowScope.SegmentedButton(
containerColor = containerColor, containerColor = containerColor,
contentColor = contentColorFor(containerColor) contentColor = contentColorFor(containerColor)
), ),
enabled = enabled,
contentPadding = PaddingValues(horizontal = 12.dp) contentPadding = PaddingValues(horizontal = 12.dp)
) { ) {
AnimatedVisibility(visible = selected) { Crossfade(targetState = selected) {
Row { if (it) {
Icon( Icon(Icons.Default.Check, null, Modifier.size(18.dp))
modifier = Modifier.size(18.dp), } else {
imageVector = Icons.Default.Check, Icon(icon, null, Modifier.size(18.dp))
contentDescription = null }
) }
Spacer(Modifier.width(8.dp)) Spacer(Modifier.width(8.dp))
} Text(label)
}
content()
} }
} }

View File

@ -24,12 +24,19 @@ import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Colorize import androidx.compose.material.icons.filled.Colorize
import androidx.compose.material.icons.filled.DarkMode import androidx.compose.material.icons.filled.DarkMode
import androidx.compose.material.icons.filled.Palette import androidx.compose.material.icons.filled.Palette
import androidx.compose.material.icons.outlined.DarkMode
import androidx.compose.material.icons.outlined.HdrAuto
import androidx.compose.material.icons.outlined.LightMode
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.ListItem import androidx.compose.material3.ListItem
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -46,13 +53,14 @@ import com.sadellie.unitto.core.ui.R
import com.sadellie.unitto.core.ui.common.Header import com.sadellie.unitto.core.ui.common.Header
import com.sadellie.unitto.core.ui.common.NavigateUpButton import com.sadellie.unitto.core.ui.common.NavigateUpButton
import com.sadellie.unitto.core.ui.common.SegmentedButton import com.sadellie.unitto.core.ui.common.SegmentedButton
import com.sadellie.unitto.core.ui.common.SegmentedButtonRow import com.sadellie.unitto.core.ui.common.SegmentedButtonsRow
import com.sadellie.unitto.core.ui.common.UnittoListItem import com.sadellie.unitto.core.ui.common.UnittoListItem
import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar
import com.sadellie.unitto.feature.settings.components.ColorSelector import com.sadellie.unitto.feature.settings.components.ColorSelector
import com.sadellie.unitto.feature.settings.components.MonetModeSelector import com.sadellie.unitto.feature.settings.components.MonetModeSelector
import io.github.sadellie.themmo.MonetMode import io.github.sadellie.themmo.MonetMode
import io.github.sadellie.themmo.ThemingMode import io.github.sadellie.themmo.ThemingMode
import io.github.sadellie.themmo.Themmo
import io.github.sadellie.themmo.ThemmoController import io.github.sadellie.themmo.ThemmoController
private val colorSchemes: List<Color> by lazy { private val colorSchemes: List<Color> by lazy {
@ -128,9 +136,9 @@ private fun ThemesScreen(
val themingModes by remember { val themingModes by remember {
mutableStateOf( mutableStateOf(
mapOf( mapOf(
ThemingMode.AUTO to R.string.force_auto_mode, ThemingMode.AUTO to (R.string.force_auto_mode to Icons.Outlined.HdrAuto),
ThemingMode.FORCE_LIGHT to R.string.force_light_mode, ThemingMode.FORCE_LIGHT to (R.string.force_light_mode to Icons.Outlined.LightMode),
ThemingMode.FORCE_DARK to R.string.force_dark_mode ThemingMode.FORCE_DARK to (R.string.force_dark_mode to Icons.Outlined.DarkMode)
) )
) )
} }
@ -155,18 +163,24 @@ private fun ThemesScreen(
} }
item { item {
SegmentedButtonRow( Row(
modifier = Modifier.padding(56.dp, 8.dp, 24.dp, 2.dp) Modifier
.horizontalScroll(rememberScrollState())
.wrapContentWidth()
) { ) {
themingModes.forEach { (mode, stringRes) -> SegmentedButtonsRow(modifier = Modifier.padding(56.dp, 8.dp, 24.dp, 2.dp)) {
themingModes.forEach { (mode, visuals) ->
val (label, icon) = visuals
SegmentedButton( SegmentedButton(
label = stringResource(label),
onClick = { onThemeChange(mode) }, onClick = { onThemeChange(mode) },
selected = currentThemingMode == mode, selected = mode == currentThemingMode,
content = { Text(stringResource(stringRes)) } icon = icon
) )
} }
} }
} }
}
item { item {
AnimatedVisibility( AnimatedVisibility(
@ -259,17 +273,19 @@ private fun ThemesScreen(
@Preview @Preview
@Composable @Composable
private fun Preview() { private fun Preview() {
Themmo { themmoController ->
ThemesScreen( ThemesScreen(
navigateUpAction = {}, navigateUpAction = {},
currentThemingMode = ThemingMode.AUTO, currentThemingMode = themmoController.currentThemingMode,
onThemeChange = {}, onThemeChange = themmoController::setThemingMode,
isDynamicThemeEnabled = false, isDynamicThemeEnabled = themmoController.isDynamicThemeEnabled,
onDynamicThemeChange = {}, onDynamicThemeChange = themmoController::enableDynamicTheme,
isAmoledThemeEnabled = false, isAmoledThemeEnabled = themmoController.isAmoledThemeEnabled,
onAmoledThemeChange = {}, onAmoledThemeChange = themmoController::enableAmoledTheme,
selectedColor = Color.Unspecified, selectedColor = themmoController.currentCustomColor,
onColorChange = {}, onColorChange = themmoController::setCustomColor,
monetMode = MonetMode.TONAL_SPOT, monetMode = themmoController.currentMonetMode,
onMonetModeChange = {} onMonetModeChange = themmoController::setMonetMode
) )
}
} }