diff --git a/i18n/src/main/res/values-de/strings.xml b/i18n/src/main/res/values-de/strings.xml index 8d87d29e..0a5eeee4 100644 --- a/i18n/src/main/res/values-de/strings.xml +++ b/i18n/src/main/res/values-de/strings.xml @@ -397,6 +397,7 @@ System / Material You Schwarz-Weiß Benutzerdefiniert + Farbschema bearbeiten Heute Morgen diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index d2911889..af85f755 100644 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -72,6 +72,7 @@ System / Material You Black and White Custom + Edit color scheme About Version Developer diff --git a/preferences/src/main/proto/settings.proto b/preferences/src/main/proto/settings.proto index 00cbeef1..09f48838 100644 --- a/preferences/src/main/proto/settings.proto +++ b/preferences/src/main/proto/settings.proto @@ -21,6 +21,15 @@ message Settings { } ColorScheme color_scheme = 6; + message CustomColors { + uint32 neutral1 = 1; + uint32 neutral2 = 2; + uint32 accent1 = 3; + uint32 accent2 = 4; + uint32 accent3 = 5; + } + CustomColors custom_colors = 7; + bool light_status_bar = 2; bool light_nav_bar = 3; bool dim_wallpaper = 4; diff --git a/ui/src/main/java/de/mm20/launcher2/ui/activity/ComposeActivity.kt b/ui/src/main/java/de/mm20/launcher2/ui/activity/ComposeActivity.kt index 5e5b0f44..d64431c5 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/activity/ComposeActivity.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/activity/ComposeActivity.kt @@ -69,7 +69,10 @@ class ComposeActivity : AppCompatActivity() { } else DefaultColorScheme() } Settings.AppearanceSettings.ColorScheme.BlackAndWhite -> BlackWhiteColorScheme() - Settings.AppearanceSettings.ColorScheme.Custom -> TODO() + Settings.AppearanceSettings.ColorScheme.Custom -> { + val customColors by customColorsAsState() + CustomColorScheme(customColors) + } else -> DefaultColorScheme() } diff --git a/ui/src/main/java/de/mm20/launcher2/ui/screens/settings/SettingsColorsScreen.kt b/ui/src/main/java/de/mm20/launcher2/ui/screens/settings/SettingsColorsScreen.kt index 4fc9243e..3fb8128d 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/screens/settings/SettingsColorsScreen.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/screens/settings/SettingsColorsScreen.kt @@ -10,12 +10,14 @@ import androidx.compose.material.icons.rounded.RadioButtonUnchecked import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import de.mm20.launcher2.ktx.isAtLeastApiLevel import de.mm20.launcher2.preferences.dataStore import de.mm20.launcher2.ui.R +import de.mm20.launcher2.ui.component.preferences.ColorPreference import de.mm20.launcher2.ui.component.preferences.Preference import de.mm20.launcher2.ui.component.preferences.PreferenceCategory import de.mm20.launcher2.ui.component.preferences.PreferenceScreen @@ -30,13 +32,14 @@ fun SettingsColorsScreen() { val context = LocalContext.current val dataStore = context.dataStore val scope = rememberCoroutineScope() + val customColors by customColorsAsState() + val colorScheme by remember { + dataStore.data.map { + it.appearance.colorScheme + } + }.collectAsState(initial = ColorSchemeOption.Default) PreferenceScreen(title = stringResource(id = R.string.preference_screen_colors)) { item { - val colorScheme by remember { - dataStore.data.map { - it.appearance.colorScheme - } - }.collectAsState(initial = ColorSchemeOption.Default) val schemes = mutableListOf( ColorSchemeItem( ColorSchemeOption.Default, @@ -73,6 +76,13 @@ fun SettingsColorsScreen() { ) ) } + schemes.add( + ColorSchemeItem( + ColorSchemeOption.Custom, + CustomColorScheme(customColors), + stringResource(id = R.string.preference_colors_custom) + ) + ) PreferenceCategory { for (scheme in schemes) { Preference( @@ -96,6 +106,92 @@ fun SettingsColorsScreen() { } } } + if (colorScheme == ColorSchemeOption.Custom) { + item { + PreferenceCategory(title = stringResource(R.string.preference_category_custom_colors)) { + ColorPreference( + title = "Neutral1", + value = customColors.neutral1, + onValueChanged = { newValue -> + scope.launch { + dataStore.updateData { + it.toBuilder().setAppearance( + it.appearance.toBuilder().setCustomColors( + it.appearance.customColors.toBuilder() + .setNeutral1(newValue.toArgb()) + ) + ).build() + } + } + } + ) + ColorPreference( + title = "Neutral2", + value = customColors.neutral2, + onValueChanged = { newValue -> + scope.launch { + dataStore.updateData { + it.toBuilder().setAppearance( + it.appearance.toBuilder().setCustomColors( + it.appearance.customColors.toBuilder() + .setNeutral2(newValue.toArgb()) + ) + ).build() + } + } + } + ) + ColorPreference( + title = "Accent1", + value = customColors.accent1, + onValueChanged = { newValue -> + scope.launch { + dataStore.updateData { + it.toBuilder().setAppearance( + it.appearance.toBuilder().setCustomColors( + it.appearance.customColors.toBuilder() + .setAccent1(newValue.toArgb()) + ) + ).build() + } + } + } + ) + ColorPreference( + title = "Accent2", + value = customColors.accent2, + onValueChanged = { newValue -> + scope.launch { + dataStore.updateData { + it.toBuilder().setAppearance( + it.appearance.toBuilder().setCustomColors( + it.appearance.customColors.toBuilder() + .setAccent2(newValue.toArgb()) + ) + ).build() + } + } + } + ) + ColorPreference( + title = "Accent3", + value = customColors.accent3, + onValueChanged = { newValue -> + scope.launch { + dataStore.updateData { + it.toBuilder().setAppearance( + it.appearance.toBuilder().setCustomColors( + it.appearance.customColors.toBuilder() + .setAccent3(newValue.toArgb()) + ) + ).build() + } + } + } + ) + } + } + } } } diff --git a/ui/src/main/java/de/mm20/launcher2/ui/theme/colors/CustomColorScheme.kt b/ui/src/main/java/de/mm20/launcher2/ui/theme/colors/CustomColorScheme.kt new file mode 100644 index 00000000..1ce07570 --- /dev/null +++ b/ui/src/main/java/de/mm20/launcher2/ui/theme/colors/CustomColorScheme.kt @@ -0,0 +1,59 @@ +package de.mm20.launcher2.ui.theme.colors + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.remember +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import de.mm20.launcher2.preferences.dataStore +import kotlinx.coroutines.flow.map + +class CustomColorScheme(val colors: CustomColors) : ColorScheme() { + override val neutral1: ColorSwatch + get() = colorSwatch(colors.neutral1) + override val neutral2: ColorSwatch + get() = colorSwatch(colors.neutral2) + override val accent1: ColorSwatch + get() = colorSwatch(colors.accent1) + override val accent2: ColorSwatch + get() = colorSwatch(colors.accent2) + override val accent3: ColorSwatch + get() = colorSwatch(colors.accent3) + +} + +data class CustomColors( + val neutral1: Color, + val neutral2: Color, + val accent1: Color, + val accent2: Color, + val accent3: Color, +) + +@Composable +fun customColorsAsState(): State { + val dataStore = LocalContext.current.dataStore + return remember { + dataStore.data.map { + val colors = it.appearance.customColors + CustomColors( + neutral1 = Color(colors.neutral1).copy(alpha = 1f), + neutral2 = Color(colors.neutral2).copy(alpha = 1f), + accent1 = Color(colors.accent1).copy(alpha = 1f), + accent2 = Color(colors.accent2).copy(alpha = 1f), + accent3 = Color(colors.accent3).copy(alpha = 1f), + ) + } + }.collectAsState( + initial = DefaultCustomColors + ) +} + +val DefaultCustomColors = CustomColors( + Color.Black, + Color.Black, + Color.Black, + Color.Black, + Color.Black, +) \ No newline at end of file