diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardTheme.kt b/app/src/main/java/helium314/keyboard/keyboard/KeyboardTheme.kt index bb90e5ab..7510ab92 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardTheme.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardTheme.kt @@ -12,6 +12,7 @@ import android.os.Build import android.util.TypedValue import android.view.ContextThemeWrapper import androidx.core.content.ContextCompat +import androidx.core.content.edit import helium314.keyboard.latin.R import helium314.keyboard.latin.common.AllColors import helium314.keyboard.latin.common.ColorType @@ -373,6 +374,41 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) { return colorMap } + // returns false if not renamed due to invalid name or collision + fun renameUserColors(from: String, to: String, prefs: SharedPreferences): Boolean { + if (to.isBlank()) return false // don't want that + if (to == from) return true // nothing to do + val existingNames = prefs.all.keys.mapNotNull { + when { + it.startsWith(Settings.PREF_USER_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_COLORS_PREFIX) + it.startsWith(Settings.PREF_USER_ALL_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_ALL_COLORS_PREFIX) + it.startsWith(Settings.PREF_USER_MORE_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_MORE_COLORS_PREFIX) + else -> null + } + }.toSortedSet() + if (to in existingNames) return false + // all good, now rename + prefs.edit { + if (prefs.contains(Settings.PREF_USER_COLORS_PREFIX + from)) { + putString(Settings.PREF_USER_COLORS_PREFIX + to, prefs.getString(Settings.PREF_USER_COLORS_PREFIX + from, "")) + remove(Settings.PREF_USER_COLORS_PREFIX + from) + } + if (prefs.contains(Settings.PREF_USER_ALL_COLORS_PREFIX + from)) { + putString(Settings.PREF_USER_ALL_COLORS_PREFIX + to, prefs.getString(Settings.PREF_USER_ALL_COLORS_PREFIX + from, "")) + remove(Settings.PREF_USER_ALL_COLORS_PREFIX + from) + } + if (prefs.contains(Settings.PREF_USER_MORE_COLORS_PREFIX + from)) { + putInt(Settings.PREF_USER_MORE_COLORS_PREFIX + to, prefs.getInt(Settings.PREF_USER_MORE_COLORS_PREFIX + from, 0)) + remove(Settings.PREF_USER_MORE_COLORS_PREFIX + from) + } + if (prefs.getString(Settings.PREF_THEME_COLORS, Defaults.PREF_THEME_COLORS) == from) + putString(Settings.PREF_THEME_COLORS, to) + if (prefs.getString(Settings.PREF_THEME_COLORS_NIGHT, Defaults.PREF_THEME_COLORS_NIGHT) == from) + putString(Settings.PREF_THEME_COLORS_NIGHT, to) + } + return true + } + fun determineUserColor(colors: List, context: Context, colorName: String, isNight: Boolean): Int { val c = colors.firstOrNull { it.name == colorName } val color = c?.color diff --git a/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt b/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt index 6cc4f173..747eb1fc 100644 --- a/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt @@ -56,7 +56,7 @@ fun SearchSettingsScreen( ) { SearchScreen( onClickBack = onClickBack, - title = title, + title = { Text(title) }, content = { if (content != null) content() else { @@ -101,7 +101,7 @@ fun SearchSettingsScreen( @Composable fun SearchScreen( onClickBack: () -> Unit, - title: String, + title: @Composable () -> Unit, filteredItems: (String) -> List, itemContent: @Composable (T) -> Unit, content: @Composable (ColumnScope.() -> Unit)? = null, @@ -123,7 +123,7 @@ fun SearchScreen( ) { Column { TopAppBar( - title = { Text(title) }, + title = title, windowInsets = TopAppBarDefaults.windowInsets, navigationIcon = { IconButton(onClick = { diff --git a/app/src/main/java/helium314/keyboard/settings/dialogs/ColorPickerDialog.kt b/app/src/main/java/helium314/keyboard/settings/dialogs/ColorPickerDialog.kt index cbfef4af..1507da73 100644 --- a/app/src/main/java/helium314/keyboard/settings/dialogs/ColorPickerDialog.kt +++ b/app/src/main/java/helium314/keyboard/settings/dialogs/ColorPickerDialog.kt @@ -30,6 +30,7 @@ import com.github.skydoves.colorpicker.compose.BrightnessSlider import com.github.skydoves.colorpicker.compose.HsvColorPicker import com.github.skydoves.colorpicker.compose.rememberColorPickerController +// todo: needs different layout in landscape (bars on the side or something like that) @Composable fun ColorPickerDialog( onDismissRequest: () -> Unit, diff --git a/app/src/main/java/helium314/keyboard/settings/dialogs/ColorThemePickerDialog.kt b/app/src/main/java/helium314/keyboard/settings/dialogs/ColorThemePickerDialog.kt index 9bddbd2e..720e6abb 100644 --- a/app/src/main/java/helium314/keyboard/settings/dialogs/ColorThemePickerDialog.kt +++ b/app/src/main/java/helium314/keyboard/settings/dialogs/ColorThemePickerDialog.kt @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-3.0-only package helium314.keyboard.settings.dialogs import androidx.compose.foundation.clickable @@ -56,6 +57,7 @@ fun ColorThemePickerDialog( when { it.startsWith(Settings.PREF_USER_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_COLORS_PREFIX) it.startsWith(Settings.PREF_USER_ALL_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_ALL_COLORS_PREFIX) + it.startsWith(Settings.PREF_USER_MORE_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_MORE_COLORS_PREFIX) else -> null } }.toSortedSet() // we don't want duplicates, and we want a consistent order diff --git a/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt index 87d65b75..6aa0ab35 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt @@ -8,25 +8,31 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.Icon import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalTextStyle import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Switch import androidx.compose.material3.Text +import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import helium314.keyboard.keyboard.ColorSetting @@ -88,9 +94,34 @@ fun ColorsScreen( fun ColorSetting.displayColor() = if (auto == true) KeyboardTheme.determineUserColor(userColors, ctx, name, isNight) else color ?: KeyboardTheme.determineUserColor(userColors, ctx, name, isNight) + var newThemeName by rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue(themeName)) } var chosenColor: ColorSetting? by remember { mutableStateOf(null) } SearchScreen( - title = themeName, + title = { + var nameValid by rememberSaveable { mutableStateOf(true) } + var nameField by rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(newThemeName) } + Row(verticalAlignment = Alignment.CenterVertically) { + TextField( + value = nameField, + onValueChange = { + nameValid = KeyboardTheme.renameUserColors(newThemeName.text, it.text, prefs) + if (nameValid) + newThemeName = it + nameField = it + }, + // modifier = Modifier.weight(1f) + ) + CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.secondary) { + // todo: this should indicate whether name is saved, but looks like a button + // either make it flash and then disappear, or use a better indicator + Icon( + painterResource(if (nameValid) R.drawable.ic_setup_check else R.drawable.ic_close), + null, + Modifier.width(24.dp) + ) + } + } + }, onClickBack = onClickBack, filteredItems = { search -> shownColors.filter { it.displayName.split(" ", "_").any { it.startsWith(search, true) } @@ -107,7 +138,9 @@ fun ColorsScreen( .background(Color(colorSetting.displayColor()), shape = CircleShape) .size(50.dp) ) - Column(Modifier.weight(1f).padding(horizontal = 16.dp)) { + Column(Modifier + .weight(1f) + .padding(horizontal = 16.dp)) { Text(colorSetting.displayName) if (colorSetting.auto == true) CompositionLocalProvider(