adjust appearance settings for the simplified theme choice

This commit is contained in:
Helium314 2023-09-06 15:22:08 +02:00
parent 9650c7a85c
commit 64fa453ea1
8 changed files with 114 additions and 314 deletions

View file

@ -20,7 +20,6 @@ import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Color; import android.graphics.Color;
import android.os.Build.VERSION_CODES; import android.os.Build.VERSION_CODES;
import android.util.Log;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
@ -40,22 +39,17 @@ public final class KeyboardTheme implements Comparable<KeyboardTheme> {
// new themes using the custom colors // new themes using the custom colors
public static final String THEME_LIGHT = "light"; public static final String THEME_LIGHT = "light";
public static final String THEME_HOLO_WHITE = "holo_white"; // todo: rename (but useful to have for testing) public static final String THEME_HOLO_WHITE = "holo_white";
public static final String THEME_DARK = "dark"; public static final String THEME_DARK = "dark";
public static final String THEME_DARKER = "darker"; public static final String THEME_DARKER = "darker";
public static final String THEME_BLACK = "black"; public static final String THEME_BLACK = "black";
public static final String THEME_USER = "user"; public static final String THEME_USER = "user";
public static final String THEME_USER_DARK = "user_dark"; public static final String THEME_USER_NIGHT = "user_night";
public static final String[] THEME_VARIANTS = new String[] { THEME_LIGHT, THEME_HOLO_WHITE, THEME_DARK, THEME_DARKER, THEME_BLACK, THEME_USER }; public static final String[] THEME_VARIANTS = new String[] { THEME_LIGHT, THEME_HOLO_WHITE, THEME_DARK, THEME_DARKER, THEME_BLACK, THEME_USER };
public static final String[] THEME_VARIANTS_DARK = new String[] { THEME_DARK, THEME_DARKER, THEME_BLACK, THEME_USER_DARK }; public static final String[] THEME_VARIANTS_DARK = new String[] { THEME_HOLO_WHITE, THEME_DARK, THEME_DARKER, THEME_BLACK, THEME_USER_NIGHT};
public static final String[] THEME_STYLES = { THEME_STYLE_MATERIAL, THEME_STYLE_HOLO }; public static final String[] THEME_STYLES = { THEME_STYLE_MATERIAL, THEME_STYLE_HOLO };
private static final String TAG = KeyboardTheme.class.getSimpleName();
static final String KLP_KEYBOARD_THEME_KEY = "pref_keyboard_layout_20110916";
static final String LXX_KEYBOARD_THEME_KEY = "pref_keyboard_theme_20140509";
// These should be aligned with Keyboard.themeId and Keyboard.Case.keyboardTheme // These should be aligned with Keyboard.themeId and Keyboard.Case.keyboardTheme
// attributes' values in attrs.xml. // attributes' values in attrs.xml.
public static final int THEME_ID_HOLO_BASE = 0; public static final int THEME_ID_HOLO_BASE = 0;
@ -126,44 +120,11 @@ public final class KeyboardTheme implements Comparable<KeyboardTheme> {
return null; return null;
} }
/* package private for testing */
static KeyboardTheme getDefaultKeyboardTheme(final SharedPreferences prefs,
final int sdkVersion, final KeyboardTheme[] availableThemeArray) {
final String klpThemeIdString = prefs.getString(KLP_KEYBOARD_THEME_KEY, null);
if (klpThemeIdString != null) {
if (sdkVersion <= VERSION_CODES.KITKAT) {
try {
final int themeId = Integer.parseInt(klpThemeIdString);
final KeyboardTheme theme = searchKeyboardThemeById(themeId,
availableThemeArray);
if (theme != null) {
return theme;
}
Log.w(TAG, "Unknown keyboard theme in KLP preference: " + klpThemeIdString);
} catch (final NumberFormatException e) {
Log.w(TAG, "Illegal keyboard theme in KLP preference: " + klpThemeIdString, e);
}
}
// Remove old preference.
Log.i(TAG, "Remove KLP keyboard theme preference: " + klpThemeIdString);
prefs.edit().remove(KLP_KEYBOARD_THEME_KEY).apply();
}
// TODO: This search algorithm isn't optimal if there are many themes.
for (final KeyboardTheme theme : availableThemeArray) {
if (sdkVersion >= theme.mMinApiVersion) {
return theme;
}
}
return searchKeyboardThemeById(DEFAULT_THEME_ID, availableThemeArray);
}
public static String getKeyboardThemeName(final int themeId) { public static String getKeyboardThemeName(final int themeId) {
final KeyboardTheme theme = searchKeyboardThemeById(themeId, KEYBOARD_THEMES); final KeyboardTheme theme = searchKeyboardThemeById(themeId, KEYBOARD_THEMES);
return theme.mThemeName; return theme.mThemeName;
} }
// todo: this actually should be called style now, as the colors are independent
// and selection should be simplified, because really...
public static KeyboardTheme getKeyboardTheme(final Context context) { public static KeyboardTheme getKeyboardTheme(final Context context) {
final SharedPreferences prefs = DeviceProtectedUtils.getSharedPreferences(context); final SharedPreferences prefs = DeviceProtectedUtils.getSharedPreferences(context);
final String style = prefs.getString(Settings.PREF_THEME_STYLE, THEME_STYLE_MATERIAL); final String style = prefs.getString(Settings.PREF_THEME_STYLE, THEME_STYLE_MATERIAL);
@ -177,41 +138,9 @@ public final class KeyboardTheme implements Comparable<KeyboardTheme> {
if (keyboardTheme.mThemeId == matchingId) if (keyboardTheme.mThemeId == matchingId)
return keyboardTheme; return keyboardTheme;
} }
return KEYBOARD_THEMES[3]; // base no border as default return KEYBOARD_THEMES[DEFAULT_THEME_ID];
} }
/* package private for testing */
static KeyboardTheme getKeyboardTheme(final SharedPreferences prefs, final int sdkVersion,
final KeyboardTheme[] availableThemeArray) {
final String lxxThemeIdString = prefs.getString(LXX_KEYBOARD_THEME_KEY, null);
if (lxxThemeIdString == null) {
return getDefaultKeyboardTheme(prefs, sdkVersion, availableThemeArray);
}
try {
final int themeId = Integer.parseInt(lxxThemeIdString);
final KeyboardTheme theme = searchKeyboardThemeById(themeId, availableThemeArray);
if (theme != null) {
return theme;
}
Log.w(TAG, "Unknown keyboard theme in LXX preference: " + lxxThemeIdString);
} catch (final NumberFormatException e) {
Log.w(TAG, "Illegal keyboard theme in LXX preference: " + lxxThemeIdString, e);
}
// Remove preference that contains unknown or illegal theme id.
prefs.edit().remove(LXX_KEYBOARD_THEME_KEY).apply();
return getDefaultKeyboardTheme(prefs, sdkVersion, availableThemeArray);
}
public static String getThemeFamily(int themeId) {
if (themeId == THEME_ID_HOLO_BASE) return THEME_STYLE_HOLO;
return THEME_STYLE_MATERIAL;
}
public static boolean getHasKeyBorders(int themeId) {
return themeId != THEME_ID_LXX_BASE; // THEME_ID_LXX_BASE is the only without borders
}
// todo (later): material you, system accent, ... // todo (later): material you, system accent, ...
public static Colors getThemeColors(final String themeColors, final String themeStyle, final Context context, final SharedPreferences prefs) { public static Colors getThemeColors(final String themeColors, final String themeStyle, final Context context, final SharedPreferences prefs) {
final boolean hasBorders = prefs.getBoolean(Settings.PREF_THEME_KEY_BORDERS, false); final boolean hasBorders = prefs.getBoolean(Settings.PREF_THEME_KEY_BORDERS, false);
@ -223,7 +152,7 @@ public final class KeyboardTheme implements Comparable<KeyboardTheme> {
final int hintTextColor = prefs.getInt(Settings.PREF_THEME_USER_COLOR_HINT_TEXT, Color.WHITE); final int hintTextColor = prefs.getInt(Settings.PREF_THEME_USER_COLOR_HINT_TEXT, Color.WHITE);
final int background = prefs.getInt(Settings.PREF_THEME_USER_COLOR_BACKGROUND, Color.DKGRAY); final int background = prefs.getInt(Settings.PREF_THEME_USER_COLOR_BACKGROUND, Color.DKGRAY);
return new Colors(themeStyle, hasBorders, accent, background, keyBgColor, ColorUtilKt.brightenOrDarken(keyBgColor, true), keyBgColor, keyTextColor, hintTextColor); return new Colors(themeStyle, hasBorders, accent, background, keyBgColor, ColorUtilKt.brightenOrDarken(keyBgColor, true), keyBgColor, keyTextColor, hintTextColor);
case THEME_USER_DARK: case THEME_USER_NIGHT:
final int accent2 = prefs.getInt(Settings.PREF_THEME_USER_DARK_COLOR_ACCENT, Color.BLUE); final int accent2 = prefs.getInt(Settings.PREF_THEME_USER_DARK_COLOR_ACCENT, Color.BLUE);
final int keyBgColor2 = prefs.getInt(Settings.PREF_THEME_USER_DARK_COLOR_KEYS, Color.LTGRAY); final int keyBgColor2 = prefs.getInt(Settings.PREF_THEME_USER_DARK_COLOR_KEYS, Color.LTGRAY);
final int keyTextColor2 = prefs.getInt(Settings.PREF_THEME_USER_DARK_COLOR_TEXT, Color.WHITE); final int keyTextColor2 = prefs.getInt(Settings.PREF_THEME_USER_DARK_COLOR_TEXT, Color.WHITE);

View file

@ -1,28 +1,11 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dslul.openboard.inputmethod.latin.settings package org.dslul.openboard.inputmethod.latin.settings
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.content.res.Configuration import android.content.res.Configuration
import android.graphics.Color import android.graphics.Color
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.content.edit
import androidx.preference.ListPreference import androidx.preference.ListPreference
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.TwoStatePreference import androidx.preference.TwoStatePreference
@ -37,39 +20,42 @@ import java.util.*
/** /**
* "Appearance" settings sub screen. * "Appearance" settings sub screen.
*/ */
@Suppress("Deprecation") // yes everything here is deprecated, but only work on this if really necessary class AppearanceSettingsFragment : SubScreenFragment() {
// todo: simplify when removing old themes (or migrating holo to same style as user themes)
// there is a bunch of ugly things in the theme settings, and mostly for historic reasons...
// idea for color selection
// left: which color (background, key, text,...)
// right: color preview (always the correct one, even if determined automatically)
// maybe copy parts from simple keyboard, see e.g. screenshot 4 in https://github.com/SimpleMobileTools/Simple-Keyboard/tree/main/fastlane/metadata/android/en-US/images/phoneScreenshots
// below (for some colors, with indent):
// enable user-defining (most colors, but definitely not background)
// use system accent (for accent and text colors)
// on click: color selector
// maybe copy parts from simple keyboard, see e.g. screenshot 4 in https://github.com/SimpleMobileTools/Simple-Keyboard/tree/main/fastlane/metadata/android/en-US/images/phoneScreenshots
// but full range would be preferable
// use some color picker library? would likely allow nicer tuning
class AppearanceSettingsFragment : SubScreenFragment(), Preference.OnPreferenceChangeListener, OnSharedPreferenceChangeListener {
private var selectedThemeId = 0
private var needsReload = false private var needsReload = false
private lateinit var themeFamilyPref: ListPreference private val themeFamilyPref: ListPreference by lazy { preferenceScreen.findPreference(Settings.PREF_THEME_STYLE)!! }
private lateinit var themeVariantPref: ListPreference private val themeVariantPref: ListPreference by lazy { preferenceScreen.findPreference(Settings.PREF_THEME_VARIANT)!! }
private var customThemeVariantNightPref: ListPreference? = null private val themeVariantNightPref: ListPreference? by lazy { preferenceScreen.findPreference(Settings.PREF_THEME_VARIANT_NIGHT) }
private lateinit var keyBordersPref: TwoStatePreference private val dayNightPref: TwoStatePreference? by lazy { preferenceScreen.findPreference(Settings.PREF_THEME_DAY_NIGHT) }
private var dayNightPref: TwoStatePreference? = null private val userColorsPref: Preference by lazy { preferenceScreen.findPreference("theme_select_colors")!! }
private lateinit var userColorsPref: Preference private val userColorsPrefNight: Preference? by lazy { preferenceScreen.findPreference("theme_select_colors_night") }
override fun onCreate(icicle: Bundle?) { override fun onCreate(icicle: Bundle?) {
super.onCreate(icicle) super.onCreate(icicle)
addPreferencesFromResource(R.xml.prefs_screen_appearance) addPreferencesFromResource(R.xml.prefs_screen_appearance)
val keyboardTheme = KeyboardTheme.getKeyboardTheme(activity)
selectedThemeId = keyboardTheme.mThemeId
removeUnsuitablePreferences()
setupTheme()
setThemeVariantPrefs(sharedPreferences.getString(Settings.PREF_THEME_STYLE, KeyboardTheme.THEME_STYLE_MATERIAL)!!)
setupKeyboardHeight(Settings.PREF_KEYBOARD_HEIGHT_SCALE, SettingsValues.DEFAULT_SIZE_SCALE)
}
override fun onPause() {
super.onPause()
if (needsReload)
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext())
needsReload = false
}
override fun onSharedPreferenceChanged(prefs: SharedPreferences, key: String) {
super.onSharedPreferenceChanged(prefs, key)
needsReload = true // may not always be the necessary, but that's ok
}
private fun removeUnsuitablePreferences() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
removePreference(Settings.PREF_THEME_DAY_NIGHT) removePreference(Settings.PREF_THEME_DAY_NIGHT)
removePreference(Settings.PREF_THEME_VARIANT_NIGHT) removePreference(Settings.PREF_THEME_VARIANT_NIGHT)
@ -81,217 +67,109 @@ class AppearanceSettingsFragment : SubScreenFragment(), Preference.OnPreferenceC
) { ) {
removePreference(Settings.PREF_THEME_DAY_NIGHT) removePreference(Settings.PREF_THEME_DAY_NIGHT)
removePreference(Settings.PREF_THEME_VARIANT_NIGHT) removePreference(Settings.PREF_THEME_VARIANT_NIGHT)
removePreference("theme_select_colors_night")
} }
} }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
// todo: consider removing the preference, and always set the navbar color // todo: consider removing the preference, and always set the navbar color
removePreference(Settings.PREF_NAVBAR_COLOR) removePreference(Settings.PREF_NAVBAR_COLOR)
} }
setupTheme()
val metrics = requireContext().resources.displayMetrics val metrics = requireContext().resources.displayMetrics
val widthDp = metrics.widthPixels / metrics.density val widthDp = metrics.widthPixels / metrics.density
val heightDp = metrics.heightPixels / metrics.density val heightDp = metrics.heightPixels / metrics.density
if (!ProductionFlags.IS_SPLIT_KEYBOARD_SUPPORTED || (min(widthDp, heightDp) < 600 && max(widthDp, heightDp) < 720)) { if (!ProductionFlags.IS_SPLIT_KEYBOARD_SUPPORTED || (min(widthDp, heightDp) < 600 && max(widthDp, heightDp) < 720)) {
removePreference(Settings.PREF_ENABLE_SPLIT_KEYBOARD) removePreference(Settings.PREF_ENABLE_SPLIT_KEYBOARD)
} }
setupKeyboardHeight(
Settings.PREF_KEYBOARD_HEIGHT_SCALE, SettingsValues.DEFAULT_SIZE_SCALE)
} }
override fun onResume() { private fun setThemeVariantPrefs(themeFamily: String) {
super.onResume()
updateThemePreferencesState()
updateAfterPreferenceChanged()
}
override fun onPause() {
super.onPause()
// if (needsReload) // todo: until re-working settings, just always reload
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext())
needsReload = false
}
override fun onPreferenceChange(preference: Preference, value: Any?): Boolean {
(preference as? ListPreference)?.apply {
summary = entries[entryValues.indexOfFirst { it == value }]
}
saveSelectedThemeId()
return true
}
override fun onSharedPreferenceChanged(prefs: SharedPreferences, key: String) {
super.onSharedPreferenceChanged(prefs, key)
updateAfterPreferenceChanged()
}
// doing things on changing, but with the old values is not good, this is at least a little better
private fun updateAfterPreferenceChanged() {
customThemeVariantNightPref?.apply {
if (true) { //KeyboardTheme.getIsCustom(selectedThemeId)) {
// show preference to allow choosing a night theme
// can't hide a preference, at least not without category or maybe some androidx things
// -> just disable it instead (for now...)
isEnabled = sharedPreferences!!.getBoolean(Settings.PREF_THEME_DAY_NIGHT, false)
} else
isEnabled = false
val variant = sharedPreferences!!.getString(Settings.PREF_THEME_VARIANT_NIGHT, KeyboardTheme.THEME_DARKER)
val variants = KeyboardTheme.THEME_VARIANTS_DARK
entries = variants.map {
// todo: this workaround get the same string as for "user" theme, maybe clarify that it's a separate theme
val name = if (it == "user_dark") "theme_name_user" else "theme_name_$it"
val resId = resources.getIdentifier(name, "string", requireContext().packageName)
if (resId == 0) it else getString(resId)
}.toTypedArray()
entryValues = variants
value = variant
val name = if (variant == "user_dark") "theme_name_user" else "theme_name_$variant"
val resId = resources.getIdentifier(name, "string", requireContext().packageName)
summary = if (resId == 0) variant else getString(resId)
}
userColorsPref.apply {
isEnabled = true //KeyboardTheme.getIsCustom(selectedThemeId)
&& (sharedPreferences!!.getString(Settings.PREF_THEME_VARIANT, KeyboardTheme.THEME_LIGHT) == KeyboardTheme.THEME_USER
|| (sharedPreferences!!.getString(Settings.PREF_THEME_VARIANT_NIGHT, KeyboardTheme.THEME_DARKER) == KeyboardTheme.THEME_USER_DARK
&& sharedPreferences!!.getBoolean(Settings.PREF_THEME_DAY_NIGHT, false)
))
isEnabled = true
}
}
private fun saveSelectedThemeId(
family: String = themeFamilyPref.value,
variant: String = themeVariantPref.value,
keyBorders: Boolean = keyBordersPref.isChecked
) {
// selectedThemeId = KeyboardTheme.getThemeForParameters(family, variant, keyBorders)
// KeyboardTheme.saveKeyboardThemeId(selectedThemeId, sharedPreferences)
}
private fun updateThemePreferencesState(skipThemeFamily: Boolean = false, skipThemeVariant: Boolean = false) {
val themeFamily = KeyboardTheme.getThemeFamily(selectedThemeId)
val isLegacyFamily = KeyboardTheme.THEME_STYLE_HOLO == themeFamily
if (!skipThemeFamily) {
themeFamilyPref.apply {
value = themeFamily
summary = themeFamily
}
}
val variants = KeyboardTheme.THEME_VARIANTS
val variant = sharedPreferences.getString(Settings.PREF_THEME_VARIANT, KeyboardTheme.THEME_LIGHT)
if (!skipThemeVariant) {
themeVariantPref.apply { themeVariantPref.apply {
entries = if (isLegacyFamily) variants // todo: translatable string for holo, not internal name entryValues = if (themeFamily == KeyboardTheme.THEME_STYLE_HOLO) KeyboardTheme.THEME_VARIANTS
else variants.map { else KeyboardTheme.THEME_VARIANTS.filterNot { it == KeyboardTheme.THEME_HOLO_WHITE }.toTypedArray()
entries = entryValues.map {
val resId = resources.getIdentifier("theme_name_$it", "string", requireContext().packageName) val resId = resources.getIdentifier("theme_name_$it", "string", requireContext().packageName)
if (resId == 0) it else getString(resId) if (resId == 0) it else getString(resId)
}.toTypedArray() }.toTypedArray()
entryValues = variants if (value !in entryValues)
value = variant ?: variants[0] value = entryValues.first().toString()
summary = if (isLegacyFamily) variant summary = entries[entryValues.indexOfFirst { it == value }]
else {
val resId = resources.getIdentifier("theme_name_$variant", "string", requireContext().packageName) onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, value ->
if (resId == 0) variant else getString(resId) summary = entries[entryValues.indexOfFirst { it == value }]
userColorsPref.isVisible = value == KeyboardTheme.THEME_USER
true
} }
} }
themeVariantNightPref?.apply {
entryValues = if (themeFamily == KeyboardTheme.THEME_STYLE_HOLO) KeyboardTheme.THEME_VARIANTS_DARK
else KeyboardTheme.THEME_VARIANTS_DARK.filterNot { it == KeyboardTheme.THEME_HOLO_WHITE }.toTypedArray()
entries = entryValues.map {
val resId = resources.getIdentifier("theme_name_$it", "string", requireContext().packageName)
if (resId == 0) it else getString(resId)
}.toTypedArray()
if (value !in entryValues)
value = entryValues.first().toString()
summary = entries[entryValues.indexOfFirst { it == value }]
onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, value ->
summary = entries[entryValues.indexOfFirst { it == value }]
userColorsPrefNight?.isVisible = value == KeyboardTheme.THEME_USER_NIGHT
true
} }
keyBordersPref.apply {
isEnabled = !isLegacyFamily
isChecked = isLegacyFamily || KeyboardTheme.getHasKeyBorders(selectedThemeId)
}
dayNightPref?.apply {
isEnabled = !isLegacyFamily
isChecked = !isLegacyFamily && /*KeyboardTheme.getIsCustom(selectedThemeId) &&*/ sharedPreferences!!.getBoolean(Settings.PREF_THEME_DAY_NIGHT, false)
} }
} }
private fun setupTheme() { private fun setupTheme() {
themeFamilyPref = preferenceScreen.findPreference(Settings.PREF_THEME_STYLE)!!
themeFamilyPref.apply { themeFamilyPref.apply {
entries = KeyboardTheme.THEME_STYLES entries = KeyboardTheme.THEME_STYLES
entryValues = KeyboardTheme.THEME_STYLES entryValues = KeyboardTheme.THEME_STYLES
onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, value -> onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, value ->
summary = entries[entryValues.indexOfFirst { it == value }] summary = entries[entryValues.indexOfFirst { it == value }]
saveSelectedThemeId(family = value as String) setThemeVariantPrefs(value.toString())
updateThemePreferencesState(skipThemeFamily = true)
true true
} }
}
// todo: remove!
themeVariantPref = preferenceScreen.findPreference(Settings.PREF_THEME_VARIANT)!!
themeVariantPref.apply {
onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, value ->
summary = entries[entryValues.indexOfFirst { it == value }] summary = entries[entryValues.indexOfFirst { it == value }]
if (themeFamilyPref.value == KeyboardTheme.THEME_STYLE_MATERIAL) {
// not so nice workaround, could be removed in the necessary re-work: new value seems
// to be stored only after this method call, but we update the summary and user-defined color enablement in here -> store it now
if (value == sharedPreferences!!.getString(Settings.PREF_THEME_VARIANT, KeyboardTheme.THEME_LIGHT))
return@OnPreferenceChangeListener true // avoid infinite loop
sharedPreferences!!.edit { putString(Settings.PREF_THEME_VARIANT, value as String) }
summary = entries[entryValues.indexOfFirst { it == value }]
needsReload = true
} }
saveSelectedThemeId(variant = value as String)
updateThemePreferencesState(skipThemeFamily = true, skipThemeVariant = true)
true
}
}
keyBordersPref = preferenceScreen.findPreference(Settings.PREF_THEME_KEY_BORDERS)!!
keyBordersPref.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, value ->
saveSelectedThemeId(keyBorders = value as Boolean)
updateThemePreferencesState(skipThemeFamily = true)
true
}
dayNightPref = preferenceScreen.findPreference(Settings.PREF_THEME_DAY_NIGHT)!!
dayNightPref?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, value -> dayNightPref?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, value ->
updateThemePreferencesState(skipThemeFamily = true) themeVariantNightPref?.isVisible = value as Boolean
userColorsPrefNight?.isVisible = value && themeVariantNightPref?.value == KeyboardTheme.THEME_USER_NIGHT
true true
} }
customThemeVariantNightPref = preferenceScreen.findPreference(Settings.PREF_THEME_VARIANT_NIGHT) as? ListPreference themeVariantNightPref?.isVisible = dayNightPref?.isChecked == true
customThemeVariantNightPref?.apply { userColorsPref.isVisible = themeVariantPref.value == KeyboardTheme.THEME_USER
onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, value -> userColorsPref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
// not so nice workaround, could be removed in the necessary re-work: new value seems
// to be stored only after this method call, but we update the summary and user-defined color enablement in here -> store it now
if (value == sharedPreferences!!.getString(Settings.PREF_THEME_VARIANT_NIGHT, KeyboardTheme.THEME_DARK))
return@OnPreferenceChangeListener true // avoid infinite loop
sharedPreferences!!.edit { putString(Settings.PREF_THEME_VARIANT_NIGHT, value as String) }
summary = entries[entryValues.indexOfFirst { it == value }]
needsReload = true
true
}
}
userColorsPref = preferenceScreen.findPreference(Settings.PREF_THEME_USER)!!
userColorsPref.onPreferenceClickListener = Preference.OnPreferenceClickListener { _ ->
if (sharedPreferences.getBoolean(Settings.PREF_THEME_DAY_NIGHT, false) && sharedPreferences.getString(Settings.PREF_THEME_VARIANT, KeyboardTheme.THEME_LIGHT) == KeyboardTheme.THEME_USER)
AlertDialog.Builder(requireContext())
.setMessage(R.string.day_or_night_colors)
.setPositiveButton(R.string.day_or_night_night) { _, _ -> adjustColors(true)}
.setNegativeButton(R.string.day_or_night_day) { _, _ -> adjustColors(false)}
.show()
else if (sharedPreferences.getBoolean(Settings.PREF_THEME_DAY_NIGHT, false)) // only night theme custom
adjustColors(true)
else // customize day theme
adjustColors(false) adjustColors(false)
true true
} }
preferenceScreen.findPreference<Preference>(Settings.PREF_NARROW_KEY_GAPS)?.onPreferenceChangeListener = userColorsPrefNight?.isVisible = dayNightPref?.isChecked == true && themeVariantNightPref?.value == KeyboardTheme.THEME_USER_NIGHT
Preference.OnPreferenceChangeListener { _, _ -> userColorsPrefNight?.onPreferenceClickListener = Preference.OnPreferenceClickListener {
needsReload = true adjustColors(true)
true true
} }
} }
// todo: improve color selection, should at very least show a preview of the color
// but maybe a separate fragment would be better
// idea:
// left: which color (background, key, text,...)
// right: color preview (always the correct one, even if determined automatically)
// maybe copy parts from simple keyboard, see e.g. screenshot 4 in https://github.com/SimpleMobileTools/Simple-Keyboard/tree/main/fastlane/metadata/android/en-US/images/phoneScreenshots
// below (for some colors, with indent):
// enable user-defining (most colors, but definitely not background)
// use system accent (for accent and text colors)
// on click: color selector
// maybe copy parts from simple keyboard, see e.g. screenshot 4 in https://github.com/SimpleMobileTools/Simple-Keyboard/tree/main/fastlane/metadata/android/en-US/images/phoneScreenshots
// but full range would be preferable
// use some color picker library? would likely allow nicer tuning
private fun adjustColors(dark: Boolean) { private fun adjustColors(dark: Boolean) {
val items = listOf(R.string.select_color_background, R.string.select_color_key, R.string.select_color_key_hint, R.string.select_color_accent, R.string.select_color_key_background) val items = listOf(
.map { requireContext().getString(it) } R.string.select_color_background,
val itemsArray = if (keyBordersPref.isChecked) items.toTypedArray() R.string.select_color_key,
R.string.select_color_key_hint,
R.string.select_color_accent,
R.string.select_color_key_background
).map { requireContext().getString(it) }
val itemsArray = if (findPreference<TwoStatePreference>(Settings.PREF_THEME_KEY_BORDERS)!!.isChecked) items.toTypedArray()
else items.subList(0, 4).toTypedArray() else items.subList(0, 4).toTypedArray()
AlertDialog.Builder(requireContext()) AlertDialog.Builder(requireContext())
.setPositiveButton(android.R.string.ok, null) .setPositiveButton(android.R.string.ok, null)
@ -314,7 +192,7 @@ class AppearanceSettingsFragment : SubScreenFragment(), Preference.OnPreferenceC
3 -> Settings.PREF_THEME_USER_COLOR_ACCENT to Color.BLUE 3 -> Settings.PREF_THEME_USER_COLOR_ACCENT to Color.BLUE
else -> Settings.PREF_THEME_USER_COLOR_KEYS to Color.LTGRAY else -> Settings.PREF_THEME_USER_COLOR_KEYS to Color.LTGRAY
} }
val d = ColorPickerDialog(requireContext(), items[i], sharedPreferences, pref, default) { needsReload = true} val d = ColorPickerDialog(requireContext(), items[i], sharedPreferences, pref, default)
d.show() d.show()
} }
.show() .show()
@ -345,10 +223,6 @@ class AppearanceSettingsFragment : SubScreenFragment(), Preference.OnPreferenceC
}) })
} }
override fun onDisplayPreferenceDialog(preference: Preference) {
super.onDisplayPreferenceDialog(preference)
}
companion object { companion object {
private const val PERCENTAGE_FLOAT = 100.0f private const val PERCENTAGE_FLOAT = 100.0f
} }

View file

@ -31,7 +31,7 @@ import org.dslul.openboard.inputmethod.latin.R;
public class ColorPickerDialog extends AlertDialog implements SeekBar.OnSeekBarChangeListener { public class ColorPickerDialog extends AlertDialog implements SeekBar.OnSeekBarChangeListener {
protected ColorPickerDialog(final Context context, final String title, final SharedPreferences prefs, protected ColorPickerDialog(final Context context, final String title, final SharedPreferences prefs,
final String colorPref, final int defaultColor, Runnable onChanged) { final String colorPref, final int defaultColor) {
super(context); super(context);
setTitle(title); setTitle(title);
View view = getLayoutInflater().inflate(R.layout.color_dialog, null); View view = getLayoutInflater().inflate(R.layout.color_dialog, null);
@ -71,7 +71,6 @@ public class ColorPickerDialog extends AlertDialog implements SeekBar.OnSeekBarC
mSeekBarGreen.getProgress(), mSeekBarGreen.getProgress(),
mSeekBarBlue.getProgress()); mSeekBarBlue.getProgress());
prefs.edit().putInt(colorPref, value).apply(); prefs.edit().putInt(colorPref, value).apply();
onChanged.run();
dismiss(); dismiss();
}); });
} }

View file

@ -66,7 +66,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_THEME_VARIANT_NIGHT = "theme_variant_night"; public static final String PREF_THEME_VARIANT_NIGHT = "theme_variant_night";
public static final String PREF_THEME_KEY_BORDERS = "theme_key_borders"; public static final String PREF_THEME_KEY_BORDERS = "theme_key_borders";
public static final String PREF_THEME_DAY_NIGHT = "theme_auto_day_night"; public static final String PREF_THEME_DAY_NIGHT = "theme_auto_day_night";
public static final String PREF_THEME_USER = "theme_select_colors";
public static final String PREF_THEME_USER_COLOR_TEXT = "theme_color_text"; public static final String PREF_THEME_USER_COLOR_TEXT = "theme_color_text";
public static final String PREF_THEME_USER_COLOR_HINT_TEXT = "theme_color_hint_text"; public static final String PREF_THEME_USER_COLOR_HINT_TEXT = "theme_color_hint_text";
public static final String PREF_THEME_USER_COLOR_BACKGROUND = "theme_color_background"; public static final String PREF_THEME_USER_COLOR_BACKGROUND = "theme_color_background";

View file

@ -248,9 +248,6 @@
<string name="key_borders">বোতামের প্রান্ত</string> <string name="key_borders">বোতামের প্রান্ত</string>
<string name="day_night_mode">স্বয়ংক্রিয় দিবা/রাত্রি মোড</string> <string name="day_night_mode">স্বয়ংক্রিয় দিবা/রাত্রি মোড</string>
<string name="day_night_mode_summary">অবয়ব সিস্টেম সেটিংসকে অনুসরণ করবে</string> <string name="day_night_mode_summary">অবয়ব সিস্টেম সেটিংসকে অনুসরণ করবে</string>
<string name="day_or_night_colors">দিবা অথবা রাত্রির রং সম্পাদনা?</string>
<string name="day_or_night_day">দিবা</string>
<string name="day_or_night_night">রাত্রি</string>
<string name="theme_navbar">রঙিন ন্যাভিগেশন বার</string> <string name="theme_navbar">রঙিন ন্যাভিগেশন বার</string>
<string name="theme_name_light">উজ্জ্বল</string> <string name="theme_name_light">উজ্জ্বল</string>
<string name="theme_name_dark">নিষ্প্রভ</string> <string name="theme_name_dark">নিষ্প্রভ</string>

View file

@ -228,9 +228,6 @@
<string name="theme_variant">Variante de thème</string> <string name="theme_variant">Variante de thème</string>
<string name="theme_variant_night">Variante de thème (mode nuit)</string> <string name="theme_variant_night">Variante de thème (mode nuit)</string>
<string name="day_night_mode_summary">L\'apparence suivra les paramètres système</string> <string name="day_night_mode_summary">L\'apparence suivra les paramètres système</string>
<string name="day_or_night_colors">Modifier les couleurs du mode jour ou nuit ?</string>
<string name="day_or_night_day">Jour</string>
<string name="day_or_night_night">Nuit</string>
<string name="theme_navbar">Colorer la barre de navigation</string> <string name="theme_navbar">Colorer la barre de navigation</string>
<string name="theme_name_light">Clair</string> <string name="theme_name_light">Clair</string>
<string name="theme_name_dark">Sombre</string> <string name="theme_name_dark">Sombre</string>

View file

@ -618,23 +618,19 @@ disposition rather than other common dispositions for Latin languages. [CHAR LIM
<!-- Option for choosing theme family variant [CHAR LIMIT=33] --> <!-- Option for choosing theme family variant [CHAR LIMIT=33] -->
<string name="theme_variant">Theme variant</string> <string name="theme_variant">Theme variant</string>
<!-- Option for choosing theme family variant (night) [CHAR LIMIT=33] --> <!-- Option for choosing theme family variant (night) [CHAR LIMIT=33] -->
<string name="theme_variant_night">Theme variant (night mode)</string> <string name="theme_variant_night">Theme variant (night)</string>
<!-- Option for choosing whether we use a theme that provides borders to keys [CHAR LIMIT=33] --> <!-- Option for choosing whether we use a theme that provides borders to keys [CHAR LIMIT=33] -->
<string name="key_borders">Key borders</string> <string name="key_borders">Key borders</string>
<!-- Option for choosing auto day/night theme switch [CHAR LIMIT=33] --> <!-- Option for choosing auto day/night theme switch [CHAR LIMIT=33] -->
<string name="day_night_mode">Auto day/night mode</string> <string name="day_night_mode">Auto day/night mode</string>
<!-- Message for the dialog to choose which user-defined theme to edit -->
<string name="day_or_night_colors">Edit day or night colors?</string>
<!-- Button of the dialog above for "day"-->
<string name="day_or_night_day">Day</string>
<!-- Button of the dialog above for "night"-->
<string name="day_or_night_night">Night</string>
<!-- Description for "day_night_mode" option. --> <!-- Description for "day_night_mode" option. -->
<string name="day_night_mode_summary">Appearance will follow system settings</string> <string name="day_night_mode_summary">Appearance will follow system settings</string>
<!-- Option for setting navbar to follow keyboard color --> <!-- Option for setting navbar to follow keyboard color -->
<string name="theme_navbar">Color navigation bar</string> <string name="theme_navbar">Color navigation bar</string>
<!-- Theme name for light theme --> <!-- Theme name for light theme -->
<string name="theme_name_light" tools:keep="@string/theme_name_light">Light</string> <string name="theme_name_light" tools:keep="@string/theme_name_light">Light</string>
<!-- Theme name for holo white theme -->
<string name="theme_name_holo_white" tools:keep="@string/theme_name_holo_white">Holo White</string>
<!-- Theme name for dark theme (based on old no-border dark) --> <!-- Theme name for dark theme (based on old no-border dark) -->
<string name="theme_name_dark" tools:keep="@string/theme_name_dark">Dark</string> <string name="theme_name_dark" tools:keep="@string/theme_name_dark">Dark</string>
<!-- Theme name for darker theme (based on old border dark), todo: re-consider that stupid name --> <!-- Theme name for darker theme (based on old border dark), todo: re-consider that stupid name -->
@ -643,8 +639,12 @@ disposition rather than other common dispositions for Latin languages. [CHAR LIM
<string name="theme_name_black" tools:keep="@string/theme_name_black">Black</string> <string name="theme_name_black" tools:keep="@string/theme_name_black">Black</string>
<!-- Theme name for user-defined theme --> <!-- Theme name for user-defined theme -->
<string name="theme_name_user" tools:keep="@string/theme_name_user">User-Defined</string> <string name="theme_name_user" tools:keep="@string/theme_name_user">User-Defined</string>
<!-- Theme name for user-defined theme night mode theme -->
<string name="theme_name_user_night" tools:keep="@string/theme_name_user_night">User-Defined (night)</string>
<!-- Option for selecting custom theme colors --> <!-- Option for selecting custom theme colors -->
<string name="select_user_colors">Adjust theme colors</string> <string name="select_user_colors">Adjust theme colors</string>
<!-- Option for selecting custom theme colors for night mode only -->
<string name="select_user_colors_night">Adjust theme colors (night)</string>
<!-- Description for selection of user-defined colors. --> <!-- Description for selection of user-defined colors. -->
<string name="select_user_colors_summary">Select colors for text and background</string> <string name="select_user_colors_summary">Select colors for text and background</string>
<!-- Dialog message when selecting color to adjust. --> <!-- Dialog message when selecting color to adjust. -->

View file

@ -36,18 +36,23 @@
android:key="theme_key_borders" android:key="theme_key_borders"
android:title="@string/key_borders"/> android:title="@string/key_borders"/>
<Preference
android:key="theme_select_colors"
android:title="@string/select_user_colors"
android:summary="@string/select_user_colors_summary"/>
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:key="theme_auto_day_night" android:key="theme_auto_day_night"
android:title="@string/day_night_mode" android:title="@string/day_night_mode"
android:summary="@string/day_night_mode_summary"/> android:summary="@string/day_night_mode_summary"/>
<ListPreference <ListPreference
android:key="custom_theme_variant_night" android:key="theme_variant_night"
android:title="@string/theme_variant_night"/> android:title="@string/theme_variant_night"/>
<Preference <Preference
android:key="theme_select_colors" android:key="theme_select_colors_night"
android:title="@string/select_user_colors" android:title="@string/select_user_colors_night"
android:summary="@string/select_user_colors_summary"/> android:summary="@string/select_user_colors_summary"/>
<SwitchPreferenceCompat <SwitchPreferenceCompat