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

View File

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