From f309c81ebdc0d39dacb89cb9f5743221ef2276a5 Mon Sep 17 00:00:00 2001 From: Suphon Thanakornpakapong Date: Fri, 18 Jun 2021 23:45:09 +0700 Subject: [PATCH] Extract common color logic to ColorPreference --- .../components/AccentColorPreference.kt | 144 +++--------------- .../preferences/components/ColorPreference.kt | 143 +++++++++++++++++ 2 files changed, 164 insertions(+), 123 deletions(-) create mode 100644 lawnchair/src/app/lawnchair/ui/preferences/components/ColorPreference.kt diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/AccentColorPreference.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/AccentColorPreference.kt index 71facfc9d0..4b9eac6750 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/AccentColorPreference.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/AccentColorPreference.kt @@ -1,140 +1,38 @@ package app.lawnchair.ui.preferences.components import androidx.compose.animation.ExperimentalAnimationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Close -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp import app.lawnchair.preferences.getAdapter import app.lawnchair.preferences.preferenceManager import app.lawnchair.ui.theme.getDefaultAccentColor import com.android.launcher3.R -import com.google.accompanist.insets.navigationBarsPadding -import kotlinx.coroutines.launch + +val accentColorEntries = listOf( + ColorPreferenceEntry( + value = 0, + lightColor = { LocalContext.current.getDefaultAccentColor(false) }, + darkColor = { LocalContext.current.getDefaultAccentColor(true) } + ), + AccentColorEntry(value = 0xFFF44336), + AccentColorEntry(value = 0xFF673AB7), + AccentColorEntry(value = 0xFF2196F3), + AccentColorEntry(value = 0xFF4CAF50), + AccentColorEntry(value = 0xFFFF9800), +) @Composable @ExperimentalMaterialApi @ExperimentalAnimationApi fun AccentColorPreference(showDivider: Boolean) { - val sheetState = rememberBottomSheetState(initialValue = ModalBottomSheetValue.Hidden) - val scope = rememberCoroutineScope() - val context = LocalContext.current - var accentColor by preferenceManager().accentColor.getAdapter() - val defaultAccentColor = context.getDefaultAccentColor(false) - - val presets = listOf( - defaultAccentColor, - 0xFFF44336.toInt(), - 0xFF673AB7.toInt(), - 0xFF2196F3.toInt(), - 0xFF4CAF50.toInt(), - 0xFFFF9800.toInt() + ColorPreference( + adapter = preferenceManager().accentColor.getAdapter(), + label = stringResource(id = R.string.accent_color), + entries = accentColorEntries, + showDivider = showDivider ) - - fun applyAccentColor(newColor: Int) { - accentColor = if (newColor == defaultAccentColor) 0 else newColor - } - - PreferenceTemplate(height = 52.dp, showDivider = showDivider) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxSize() - .clickable { scope.launch { sheetState.show() } } - .padding(start = 16.dp, end = 16.dp) - ) { - Text( - text = stringResource(id = R.string.accent_color), - style = MaterialTheme.typography.subtitle1, - color = MaterialTheme.colors.onBackground - ) - } - } - - BottomSheet(sheetState = sheetState) { - val initialNewAccentColor = if (accentColor == 0) defaultAccentColor else accentColor - var newAccentColor by remember { mutableStateOf(initialNewAccentColor) } - - Column(modifier = Modifier.navigationBarsPadding()) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .height(56.dp) - .padding(start = 8.dp, end = 16.dp), - ) { - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .width(40.dp) - .height(40.dp) - .clip(CircleShape) - .clickable { scope.launch { sheetState.hide() } } - ) { - Icon( - imageVector = Icons.Rounded.Close, - contentDescription = null, - tint = MaterialTheme.colors.onSurface - ) - } - Spacer(modifier = Modifier.requiredWidth(8.dp)) - Text( - text = stringResource(id = R.string.accent_color), - style = MaterialTheme.typography.h6 - ) - } - Row(modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)) { - presets.forEachIndexed { index, it -> - ColorSwatch( - color = it, - onClick = { newAccentColor = it }, - modifier = Modifier.weight(1F), - isSelected = it == newAccentColor - ) - if (index != presets.size - 1) Spacer(modifier = Modifier.requiredWidth(12.dp)) - } - } - Button( - shape = MaterialTheme.shapes.small, - onClick = { - applyAccentColor(newAccentColor) - scope.launch { - sheetState.hide() - } - }, - modifier = Modifier - .align(Alignment.End) - .padding(16.dp) - ) { - Text(text = stringResource(id = R.string.done)) - } - } - } } -@Composable -@ExperimentalAnimationApi -fun ColorSwatch(color: Int, onClick: (Int) -> Unit, modifier: Modifier = Modifier, isSelected: Boolean) { - Box( - modifier = modifier - .aspectRatio(1F) - .clip(CircleShape) - .background(color = Color(color)) - .clickable { onClick(color) }, contentAlignment = Alignment.Center - ) { - AnimatedCheck( - visible = isSelected, - tint = Color.White - ) - } -} \ No newline at end of file +class AccentColorEntry(value: Long) : ColorPreferenceEntry(value.toInt(), { value.toInt() }) diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/ColorPreference.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/ColorPreference.kt new file mode 100644 index 0000000000..9f5bcc0dd1 --- /dev/null +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/ColorPreference.kt @@ -0,0 +1,143 @@ +package app.lawnchair.ui.preferences.components + +import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.* +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.Close +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import app.lawnchair.preferences.PreferenceAdapter +import app.lawnchair.ui.theme.lightenColor +import com.android.launcher3.R +import com.google.accompanist.insets.navigationBarsPadding +import kotlinx.coroutines.launch + +@Composable +@ExperimentalMaterialApi +@ExperimentalAnimationApi +fun ColorPreference( + adapter: PreferenceAdapter, + label: String, + entries: List>, + showDivider: Boolean +) { + val sheetState = rememberBottomSheetState(initialValue = ModalBottomSheetValue.Hidden) + val scope = rememberCoroutineScope() + var currentColor by adapter + + fun applyColor(newColor: T) { + currentColor = newColor + } + + PreferenceTemplate(height = 52.dp, showDivider = showDivider) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxSize() + .clickable { scope.launch { sheetState.show() } } + .padding(start = 16.dp, end = 16.dp) + ) { + Text( + text = label, + style = MaterialTheme.typography.subtitle1, + color = MaterialTheme.colors.onBackground + ) + } + } + + BottomSheet(sheetState = sheetState) { + var newColor by remember { mutableStateOf(currentColor) } + + Column(modifier = Modifier.navigationBarsPadding()) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .height(56.dp) + .padding(start = 8.dp, end = 16.dp), + ) { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .width(40.dp) + .height(40.dp) + .clip(CircleShape) + .clickable { scope.launch { sheetState.hide() } } + ) { + Icon( + imageVector = Icons.Rounded.Close, + contentDescription = null, + tint = MaterialTheme.colors.onSurface + ) + } + Spacer(modifier = Modifier.requiredWidth(8.dp)) + Text( + text = label, + style = MaterialTheme.typography.h6 + ) + } + Row(modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)) { + entries.forEachIndexed { index, it -> + ColorSwatch( + entry = it, + onClick = { newColor = it.value }, + modifier = Modifier.weight(1F), + isSelected = it.value == newColor + ) + if (index != entries.lastIndex) Spacer(modifier = Modifier.requiredWidth(12.dp)) + } + } + Button( + shape = MaterialTheme.shapes.small, + onClick = { + applyColor(newColor) + scope.launch { + sheetState.hide() + } + }, + modifier = Modifier + .align(Alignment.End) + .padding(16.dp) + ) { + Text(text = stringResource(id = R.string.done)) + } + } + } +} + +@Composable +@ExperimentalAnimationApi +fun ColorSwatch( + entry: ColorPreferenceEntry, + onClick: () -> Unit, + modifier: Modifier = Modifier, + isSelected: Boolean +) { + Box( + modifier = modifier + .aspectRatio(1F) + .clip(CircleShape) + .background(color = Color(entry.lightColor())) + .clickable { onClick() }, + contentAlignment = Alignment.Center + ) { + AnimatedCheck( + visible = isSelected, + tint = Color.White + ) + } +} + +open class ColorPreferenceEntry( + val value: T, + val lightColor: @Composable () -> Int, + val darkColor: @Composable () -> Int = { lightenColor(lightColor()) }, +)