diff --git a/app/src/main/java/helium314/keyboard/latin/utils/Ktx.kt b/app/src/main/java/helium314/keyboard/latin/utils/Ktx.kt index 98d46c67..9db54734 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/Ktx.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/Ktx.kt @@ -13,6 +13,7 @@ inline fun Iterable.sumOf(selector: (T) -> Float): Float { return sum } +// todo: string instead of CharSequence for compose? because resource STRINGs should be strings anyway... fun CharSequence.getStringResourceOrName(prefix: String, context: Context): CharSequence { val resId = context.resources.getIdentifier(prefix + this, "string", context.packageName) return if (resId == 0) this else context.getString(resId) diff --git a/app/src/main/java/helium314/keyboard/settings/AllPrefs.kt b/app/src/main/java/helium314/keyboard/settings/AllPrefs.kt index 7fb94920..4e7d134f 100644 --- a/app/src/main/java/helium314/keyboard/settings/AllPrefs.kt +++ b/app/src/main/java/helium314/keyboard/settings/AllPrefs.kt @@ -10,6 +10,7 @@ import androidx.compose.runtime.Composable import helium314.keyboard.latin.utils.DeviceProtectedUtils import helium314.keyboard.settings.screens.createAboutPrefs import helium314.keyboard.settings.screens.createAdvancedPrefs +import helium314.keyboard.settings.screens.createAppearancePrefs import helium314.keyboard.settings.screens.createCorrectionPrefs import helium314.keyboard.settings.screens.createDebugPrefs import helium314.keyboard.settings.screens.createGestureTypingPrefs @@ -58,7 +59,8 @@ class PrefDef( private fun createPrefDefs(context: Context) = createAboutPrefs(context) + createCorrectionPrefs(context) + createPreferencesPrefs(context) + createToolbarPrefs(context) + - createGestureTypingPrefs(context) + createAdvancedPrefs(context) + createDebugPrefs(context) + createGestureTypingPrefs(context) + createAdvancedPrefs(context) + createDebugPrefs(context) + + createAppearancePrefs(context) // todo: move somewhere else fun Context.getActivity(): ComponentActivity? { diff --git a/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt b/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt index 086ef8f5..5d5aa230 100644 --- a/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt +++ b/app/src/main/java/helium314/keyboard/settings/SettingsActivity.kt @@ -18,9 +18,8 @@ import kotlinx.coroutines.flow.MutableStateFlow // good way to measure startup time? e.g. sth in activity, or in composable, compared to settings button // check if there are simple ways to improve it (try kicking out "everything" at start) // more pref screens -// appearance // colors -// personal dictionary +// personal dictionary (maybe separately) // languages (maybe separately) // consider IME insets when searching // improve performance when loading screens with many settings (lazyColumn?) diff --git a/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt b/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt index 1edb376f..ec3d3b2d 100644 --- a/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt +++ b/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt @@ -12,6 +12,8 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import helium314.keyboard.settings.screens.AboutScreen import helium314.keyboard.settings.screens.AdvancedSettingsScreen +import helium314.keyboard.settings.screens.AppearanceScreen +import helium314.keyboard.settings.screens.DebugScreen import helium314.keyboard.settings.screens.GestureTypingScreen import helium314.keyboard.settings.screens.MainSettingsScreen import helium314.keyboard.settings.screens.PreferencesScreen @@ -89,14 +91,14 @@ fun SettingsNavHost( ) } composable(SettingsDestination.Debug) { - DebugSettingsScreen( + DebugScreen( onClickBack = ::goBack ) } composable(SettingsDestination.Appearance) { -// AppearanceSettingsScreen( -// onClickBack = ::goBack -// ) + AppearanceScreen( + onClickBack = ::goBack + ) } composable(SettingsDestination.PersonalDictionary) { // PersonalDictionarySettingsScreen( @@ -106,6 +108,18 @@ fun SettingsNavHost( composable(SettingsDestination.Languages) { // LanguagesSettingsScreen( // onClickBack = ::goBack +// ) + } + composable(SettingsDestination.Colors) { +// ColorsScreen( +// night = false, +// onClickBack = ::goBack +// ) + } + composable(SettingsDestination.ColorsNight) { +// ColorsScreen( +// night = true, +// onClickBack = ::goBack // ) } } @@ -121,7 +135,8 @@ object SettingsDestination { const val Advanced = "advanced" const val Debug = "debug" const val Appearance = "appearance" -// const val Colors = "colors" todo: can't simply do this with the day/night approach (maybe colors and colorsNight?) + const val Colors = "colors" + const val ColorsNight = "colors_night" const val PersonalDictionary = "personal_dictionary" const val Languages = "languages" val navTarget = MutableStateFlow(Settings) diff --git a/app/src/main/java/helium314/keyboard/settings/screens/AdvancedSettingsScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/AdvancedScreen.kt similarity index 100% rename from app/src/main/java/helium314/keyboard/settings/screens/AdvancedSettingsScreen.kt rename to app/src/main/java/helium314/keyboard/settings/screens/AdvancedScreen.kt diff --git a/app/src/main/java/helium314/keyboard/settings/screens/AppearanceScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/AppearanceScreen.kt new file mode 100644 index 00000000..82c03d6c --- /dev/null +++ b/app/src/main/java/helium314/keyboard/settings/screens/AppearanceScreen.kt @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-3.0-only +package helium314.keyboard.settings.screens + +import android.content.Context +import android.os.Build +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import helium314.keyboard.keyboard.KeyboardTheme +import helium314.keyboard.latin.R +import helium314.keyboard.latin.settings.Settings +import helium314.keyboard.latin.utils.Log +import helium314.keyboard.latin.utils.getStringResourceOrName +import helium314.keyboard.settings.AllPrefs +import helium314.keyboard.settings.ListPreference +import helium314.keyboard.settings.PrefDef +import helium314.keyboard.settings.Preference +import helium314.keyboard.settings.PreferenceCategory +import helium314.keyboard.settings.SearchPrefScreen +import helium314.keyboard.settings.SettingsActivity2 +import helium314.keyboard.settings.SettingsDestination +import helium314.keyboard.settings.SliderPreference +import helium314.keyboard.settings.SwitchPreference +import helium314.keyboard.settings.Theme +import helium314.keyboard.settings.getActivity +import helium314.keyboard.settings.prefs +import helium314.keyboard.settings.themeChanged + +@Composable +fun AppearanceScreen( + onClickBack: () -> Unit, +) { + val prefs = LocalContext.current.prefs() + val b = (LocalContext.current.getActivity() as? SettingsActivity2)?.prefChanged?.collectAsState() + if (b?.value ?: 0 < 0) + Log.v("irrelevant", "stupid way to trigger recomposition on preference change") + val gestureEnabled = prefs.getBoolean(Settings.PREF_GESTURE_INPUT, true) + SearchPrefScreen( + onClickBack = onClickBack, + title = stringResource(R.string.settings_screen_appearance), + ) { + PreferenceCategory(stringResource(R.string.settings_screen_theme)) { + + } + PreferenceCategory(stringResource(R.string.settings_category_miscellaneous)) { + + } + SettingsActivity2.allPrefs.map[Settings.PREF_GESTURE_INPUT]!!.Preference() + } +} + +fun createAppearancePrefs(context: Context) = listOf( + PrefDef(context, Settings.PREF_THEME_STYLE, R.string.theme_style) { def -> + val ctx = LocalContext.current + val items = KeyboardTheme.STYLES.map { + it.getStringResourceOrName("style_name_", ctx).toString() to it + } + ListPreference( + def, + items, + KeyboardTheme.STYLE_MATERIAL + ) + }, + PrefDef(context, Settings.PREF_ICON_STYLE, R.string.icon_style) { def -> + val ctx = LocalContext.current + val items = KeyboardTheme.STYLES.map { + it.getStringResourceOrName("style_name_", ctx).toString() to it + } + ListPreference( + def, + items, + KeyboardTheme.STYLE_MATERIAL + ) + }, + PrefDef(context, Settings.PREF_CUSTOM_ICON_NAMES, R.string.customize_icons) { def -> + var showDialog by remember { mutableStateOf(false) } + Preference( + name = def.title, + onClick = { showDialog = true } + ) // todo: create and show the dialog + }, + PrefDef(context, Settings.PREF_THEME_COLORS, R.string.theme_colors) { def -> + val ctx = LocalContext.current + val currentStyle = ctx.prefs().getString(Settings.PREF_THEME_STYLE, KeyboardTheme.STYLE_MATERIAL) + val items = KeyboardTheme.COLORS.mapNotNull { + if (it == KeyboardTheme.THEME_HOLO_WHITE && currentStyle == KeyboardTheme.STYLE_HOLO) + return@mapNotNull null + it.getStringResourceOrName("theme_name_", ctx).toString() to it + } + ListPreference( + def, + items, + KeyboardTheme.THEME_LIGHT + ) + }, + PrefDef(context, Settings.PREF_THEME_COLORS_NIGHT, R.string.theme_colors_night) { def -> + val ctx = LocalContext.current + val currentStyle = ctx.prefs().getString(Settings.PREF_THEME_STYLE, KeyboardTheme.STYLE_MATERIAL) + val items = KeyboardTheme.COLORS.mapNotNull { + if (it == KeyboardTheme.THEME_HOLO_WHITE && currentStyle == KeyboardTheme.STYLE_HOLO) + return@mapNotNull null + it.getStringResourceOrName("theme_name_", ctx).toString() to it + } + ListPreference( + def, + items, + KeyboardTheme.THEME_DARK + ) + }, + // todo: non-settings pref + PrefDef(context, "theme_select_colors", R.string.select_user_colors, R.string.select_user_colors_summary) { def -> + Preference( + name = def.title, + description = def.description, + onClick = { SettingsDestination.navigateTo(SettingsDestination.Colors) } + ) + }, + PrefDef(context, "theme_select_colors_night", R.string.select_user_colors_night, R.string.select_user_colors_summary) { def -> + Preference( + name = def.title, + description = def.description, + onClick = { SettingsDestination.navigateTo(SettingsDestination.ColorsNight) } + ) + }, + PrefDef(context, Settings.PREF_THEME_KEY_BORDERS, R.string.key_borders) { def -> + SwitchPreference(def, false) + }, + PrefDef(context, Settings.PREF_THEME_DAY_NIGHT, R.string.day_night_mode, R.string.day_night_mode_summary) { def -> + SwitchPreference(def, Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) + }, + PrefDef(context, Settings.PREF_NAVBAR_COLOR, R.string.theme_navbar, R.string.day_night_mode_summary) { def -> + SwitchPreference(def, Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) + }, + // todo: non-settings pref + PrefDef(context, "custom_background_image", R.string.customize_background_image) { def -> + var showDialog by remember { mutableStateOf(false) } + Preference( + name = def.title, + onClick = { showDialog = true } + ) // todo: create and show the dialog + }, + // todo: non-settings pref + PrefDef(context, "custom_background_image_landscape", R.string.customize_background_image_landscape, R.string.summary_customize_background_image_landscape) { def -> + var showDialog by remember { mutableStateOf(false) } + Preference( + name = def.title, + description = def.description, + onClick = { showDialog = true } + ) // todo: create and show the dialog + }, + // todo: add misc category, then add functionality, then add to the actual screen +) + +@Preview +@Composable +private fun Preview() { + SettingsActivity2.allPrefs = AllPrefs(LocalContext.current) + Theme(true) { + Surface { + AppearanceScreen { } + } + } +} diff --git a/app/src/main/java/helium314/keyboard/settings/screens/MainSettingsScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/MainSettingsScreen.kt index e8b2d62f..4c560203 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/MainSettingsScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/MainSettingsScreen.kt @@ -58,6 +58,17 @@ fun MainSettingsScreen( contentDescription = null ) } + Preference( + name = stringResource(R.string.settings_screen_appearance), + onClick = onClickAppearance, + icon = R.drawable.ic_settings_appearance_foreground + ) { + Icon( + painter = painterResource(R.drawable.ic_arrow_left), + modifier = Modifier.scale(-1f, 1f), + contentDescription = null + ) + } Preference( name = stringResource(R.string.settings_screen_toolbar), onClick = onClickToolbar, @@ -161,7 +172,7 @@ fun Activity.switchTo(fragment: androidx.fragment.app.Fragment) { private fun PreviewScreen() { Theme(true) { Surface { - MainSettingsScreen({}, {}, {}, {}, {}, {}, {}) + MainSettingsScreen({}, {}, {}, {}, {}, {}, {}, {}) } } }