Add color scheme previews
This commit is contained in:
parent
41707672ce
commit
408a23563e
@ -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)
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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 {
|
||||||
|
|||||||
@ -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
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user