Add color scheme previews

This commit is contained in:
MM20 2022-04-11 22:47:24 +02:00
parent 41707672ce
commit 408a23563e
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
3 changed files with 103 additions and 23 deletions

View File

@ -1,19 +1,28 @@
package de.mm20.launcher2.ui.settings.colorscheme package de.mm20.launcher2.ui.settings.colorscheme
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.RadioButtonChecked import androidx.compose.material.icons.rounded.RadioButtonChecked
import androidx.compose.material.icons.rounded.RadioButtonUnchecked import androidx.compose.material.icons.rounded.RadioButtonUnchecked
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme import de.mm20.launcher2.preferences.Settings.AppearanceSettings
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.preferences.Preference import de.mm20.launcher2.ui.component.preferences.Preference
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
import de.mm20.launcher2.ui.theme.getColorScheme
@Composable @Composable
fun ColorSchemeSettingsScreen() { fun ColorSchemeSettingsScreen() {
@ -23,18 +32,84 @@ fun ColorSchemeSettingsScreen() {
PreferenceScreen(title = stringResource(R.string.preference_screen_colors)) { PreferenceScreen(title = stringResource(R.string.preference_screen_colors)) {
item { item {
PreferenceCategory { PreferenceCategory {
val theme by viewModel.theme.observeAsState()
val darkTheme =
theme == AppearanceSettings.Theme.Dark || theme == AppearanceSettings.Theme.System && isSystemInDarkTheme()
val colorScheme by viewModel.colorScheme.observeAsState() val colorScheme by viewModel.colorScheme.observeAsState()
Preference(
title = stringResource(R.string.preference_colors_default), val items = listOf(
icon = if (colorScheme == ColorScheme.Default) Icons.Rounded.RadioButtonChecked else Icons.Rounded.RadioButtonUnchecked, AppearanceSettings.ColorScheme.Default to R.string.preference_colors_default,
onClick = { viewModel.setColorScheme(ColorScheme.Default) } AppearanceSettings.ColorScheme.BlackAndWhite to R.string.preference_colors_bw
)
Preference(
title = stringResource(R.string.preference_colors_bw),
icon = if (colorScheme == ColorScheme.BlackAndWhite) Icons.Rounded.RadioButtonChecked else Icons.Rounded.RadioButtonUnchecked,
onClick = { viewModel.setColorScheme(ColorScheme.BlackAndWhite) }
) )
for (cs in items) {
Preference(
title = stringResource(cs.second),
icon = if (colorScheme == cs.first) Icons.Rounded.RadioButtonChecked else Icons.Rounded.RadioButtonUnchecked,
onClick = { viewModel.setColorScheme(cs.first) },
controls = {
ColorSchemePreview(
getColorScheme(
LocalContext.current,
cs.first,
darkTheme,
)
)
}
)
}
} }
} }
} }
}
@Composable
fun ColorSchemePreview(colorScheme: ColorScheme) {
Box(
modifier = Modifier
.padding(vertical = 12.dp)
.width(72.dp)
.height(36.dp),
contentAlignment = Alignment.Center
) {
Row(
verticalAlignment = Alignment.CenterVertically
) {
Surface(
tonalElevation = 1.dp,
color = colorScheme.surface,
modifier = Modifier
.size(36.dp)
) {}
Surface(
tonalElevation = 1.dp,
color = colorScheme.surfaceVariant,
modifier = Modifier
.size(36.dp)
) {}
}
Row(
verticalAlignment = Alignment.CenterVertically
) {
Surface(
tonalElevation = 1.dp,
color = colorScheme.primary,
modifier = Modifier
.size(16.dp)
) {}
Surface(
tonalElevation = 1.dp,
color = colorScheme.secondary,
modifier = Modifier
.padding(horizontal = 8.dp)
.size(16.dp)
) {}
Surface(
tonalElevation = 1.dp,
color = colorScheme.tertiary,
modifier = Modifier
.size(16.dp)
) {}
}
}
} }

View File

@ -13,6 +13,8 @@ import org.koin.core.component.inject
class ColorSchemeSettingsScreenVM : ViewModel(), KoinComponent { class ColorSchemeSettingsScreenVM : ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject() private val dataStore: LauncherDataStore by inject()
val theme = dataStore.data.map { it.appearance.theme }.asLiveData()
val colorScheme = dataStore.data.map { it.appearance.colorScheme }.asLiveData() val colorScheme = dataStore.data.map { it.appearance.colorScheme }.asLiveData()
fun setColorScheme(colorScheme: AppearanceSettings.ColorScheme) { fun setColorScheme(colorScheme: AppearanceSettings.ColorScheme) {
viewModelScope.launch { viewModelScope.launch {

View File

@ -1,6 +1,8 @@
package de.mm20.launcher2.ui.theme package de.mm20.launcher2.ui.theme
import android.content.Context
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.dynamicLightColorScheme
@ -11,7 +13,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import de.mm20.launcher2.ktx.isAtLeastApiLevel import de.mm20.launcher2.ktx.isAtLeastApiLevel
import de.mm20.launcher2.preferences.LauncherDataStore import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme import de.mm20.launcher2.preferences.Settings.AppearanceSettings
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
import de.mm20.launcher2.ui.theme.colorscheme.DarkBlackAndWhiteColorScheme import de.mm20.launcher2.ui.theme.colorscheme.DarkBlackAndWhiteColorScheme
import de.mm20.launcher2.ui.theme.colorscheme.DarkPre31DefaultColorScheme import de.mm20.launcher2.ui.theme.colorscheme.DarkPre31DefaultColorScheme
@ -30,7 +32,7 @@ fun LauncherTheme(
val dataStore: LauncherDataStore by inject() val dataStore: LauncherDataStore by inject()
val colorSchemePreference by remember { dataStore.data.map { it.appearance.colorScheme } }.collectAsState( val colorSchemePreference by remember { dataStore.data.map { it.appearance.colorScheme } }.collectAsState(
ColorScheme.Default AppearanceSettings.ColorScheme.Default
) )
val themePreference by remember { dataStore.data.map { it.appearance.theme } }.collectAsState( val themePreference by remember { dataStore.data.map { it.appearance.theme } }.collectAsState(
Theme.System Theme.System
@ -39,26 +41,27 @@ fun LauncherTheme(
val darkTheme = val darkTheme =
themePreference == Theme.Dark || themePreference == Theme.System && isSystemInDarkTheme() themePreference == Theme.Dark || themePreference == Theme.System && isSystemInDarkTheme()
MaterialTheme(
colorScheme = getColorScheme(LocalContext.current, colorSchemePreference, darkTheme),
typography = DefaultTypography,
content = content
)
}
val colorScheme = when (colorSchemePreference) { fun getColorScheme(context: Context, colorScheme: AppearanceSettings.ColorScheme, darkTheme: Boolean): ColorScheme {
ColorScheme.BlackAndWhite -> { return when (colorScheme) {
AppearanceSettings.ColorScheme.BlackAndWhite -> {
if (darkTheme) DarkBlackAndWhiteColorScheme if (darkTheme) DarkBlackAndWhiteColorScheme
else LightBlackAndWhiteColorScheme else LightBlackAndWhiteColorScheme
} }
else -> { else -> {
if (darkTheme) { if (darkTheme) {
if (isAtLeastApiLevel(31)) dynamicDarkColorScheme(LocalContext.current) if (isAtLeastApiLevel(31)) dynamicDarkColorScheme(context)
else DarkPre31DefaultColorScheme else DarkPre31DefaultColorScheme
} else { } else {
if (isAtLeastApiLevel(31)) dynamicLightColorScheme(LocalContext.current) if (isAtLeastApiLevel(31)) dynamicLightColorScheme(context)
else LightPre31DefaultColorScheme else LightPre31DefaultColorScheme
} }
} }
} }
}
MaterialTheme(
colorScheme = colorScheme,
typography = DefaultTypography,
content = content
)
}