mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-14 05:52:47 +00:00
allow setting a background image (separate for day and night)
todo: allow setting transparent background that should only apply to pressed keys with borders disabled?
This commit is contained in:
parent
fa04c393c8
commit
9d8a22880c
96 changed files with 266 additions and 115 deletions
|
@ -17,6 +17,7 @@ import org.dslul.openboard.inputmethod.latin.common.DefaultColors
|
|||
import org.dslul.openboard.inputmethod.latin.common.DynamicColors
|
||||
import org.dslul.openboard.inputmethod.latin.settings.Settings
|
||||
import org.dslul.openboard.inputmethod.latin.utils.DeviceProtectedUtils
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils
|
||||
|
||||
class KeyboardTheme // Note: The themeId should be aligned with "themeId" attribute of Keyboard style in values/themes-<style>.xml.
|
||||
private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
||||
|
@ -100,6 +101,8 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
@JvmStatic
|
||||
fun getThemeColors(themeColors: String, themeStyle: String, context: Context, prefs: SharedPreferences): Colors {
|
||||
val hasBorders = prefs.getBoolean(Settings.PREF_THEME_KEY_BORDERS, false)
|
||||
val useNightImage = Settings.readDayNightPref(prefs, context.resources) && ResourceUtils.isNight(context.resources)
|
||||
val backgroundImage = Settings.readUserBackgroundImage(context, useNightImage)
|
||||
return when (themeColors) {
|
||||
THEME_USER -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -114,6 +117,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Settings.readUserColor(prefs, context, Settings.PREF_COLOR_SUGGESTION_TEXT_SUFFIX, false),
|
||||
Settings.readUserColor(prefs, context, Settings.PREF_COLOR_SPACEBAR_TEXT_SUFFIX, false),
|
||||
Settings.readUserColor(prefs, context, Settings.PREF_COLOR_GESTURE_SUFFIX, false),
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_USER_NIGHT -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -128,9 +132,10 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Settings.readUserColor(prefs, context, Settings.PREF_COLOR_SUGGESTION_TEXT_SUFFIX, true),
|
||||
Settings.readUserColor(prefs, context, Settings.PREF_COLOR_SPACEBAR_TEXT_SUFFIX, true),
|
||||
Settings.readUserColor(prefs, context, Settings.PREF_COLOR_GESTURE_SUFFIX, true),
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_DYNAMIC -> {
|
||||
if (Build.VERSION.SDK_INT >= VERSION_CODES.S) DynamicColors(context, themeStyle, hasBorders)
|
||||
if (Build.VERSION.SDK_INT >= VERSION_CODES.S) DynamicColors(context, themeStyle, hasBorders, backgroundImage)
|
||||
else getThemeColors(THEME_LIGHT, themeStyle, context, prefs)
|
||||
}
|
||||
THEME_DARK -> DefaultColors(
|
||||
|
@ -143,6 +148,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.parseColor("#364248"),
|
||||
ContextCompat.getColor(context, R.color.key_text_color_lxx_dark),
|
||||
ContextCompat.getColor(context, R.color.key_hint_letter_color_lxx_dark),
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_HOLO_WHITE -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -156,6 +162,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.parseColor("#282828"),
|
||||
Color.WHITE,
|
||||
Color.parseColor("#80FFFFFF"),
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_DARKER -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -167,6 +174,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
ContextCompat.getColor(context, R.color.key_background_normal_lxx_dark_border),
|
||||
ContextCompat.getColor(context, R.color.key_text_color_lxx_dark),
|
||||
ContextCompat.getColor(context, R.color.key_hint_letter_color_lxx_dark),
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_BLACK -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -178,6 +186,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
ContextCompat.getColor(context, R.color.background_amoled_dark),
|
||||
ContextCompat.getColor(context, R.color.key_text_color_lxx_dark),
|
||||
ContextCompat.getColor(context, R.color.key_hint_letter_color_lxx_dark),
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_BLUE_GRAY -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -189,6 +198,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.WHITE,
|
||||
Color.BLACK,
|
||||
Color.BLACK,
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_BROWN -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -200,6 +210,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.WHITE,
|
||||
Color.BLACK,
|
||||
Color.BLACK,
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_CHOCOLATE -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -211,6 +222,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.rgb(193, 163, 146),
|
||||
Color.WHITE,
|
||||
Color.WHITE,
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_CLOUDY -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -222,6 +234,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.rgb(117, 128, 142),
|
||||
Color.WHITE,
|
||||
Color.WHITE,
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_FOREST -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -235,6 +248,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.rgb(0, 50, 0),
|
||||
Color.rgb(0, 50, 0),
|
||||
Color.rgb(0, 80, 0),
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_INDIGO -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -246,6 +260,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.WHITE,
|
||||
Color.BLACK,
|
||||
Color.BLACK,
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_OCEAN -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -257,6 +272,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.rgb(132, 157, 212),
|
||||
Color.WHITE,
|
||||
Color.WHITE,
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_PINK -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -268,6 +284,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.WHITE,
|
||||
Color.BLACK,
|
||||
Color.BLACK,
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_SAND -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -279,6 +296,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.WHITE,
|
||||
Color.BLACK,
|
||||
Color.BLACK,
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
THEME_VIOLETTE -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -290,6 +308,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
Color.rgb(150, 150, 216),
|
||||
Color.WHITE,
|
||||
Color.WHITE,
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
else /* THEME_LIGHT */ -> DefaultColors(
|
||||
themeStyle,
|
||||
|
@ -301,6 +320,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
ContextCompat.getColor(context, R.color.key_background_normal_lxx_light_border),
|
||||
ContextCompat.getColor(context, R.color.key_text_color_lxx_light),
|
||||
ContextCompat.getColor(context, R.color.key_hint_letter_color_lxx_light),
|
||||
keyboardBackground = backgroundImage
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.content.res.TypedArray
|
|||
import android.graphics.Color
|
||||
import android.graphics.ColorFilter
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.Build
|
||||
|
@ -21,6 +22,7 @@ import androidx.core.graphics.BlendModeColorFilterCompat
|
|||
import androidx.core.graphics.BlendModeCompat
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme.Companion.STYLE_HOLO
|
||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme.Companion.STYLE_MATERIAL
|
||||
import org.dslul.openboard.inputmethod.latin.common.ColorType.*
|
||||
|
@ -60,7 +62,7 @@ interface Colors {
|
|||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.S)
|
||||
class DynamicColors(context: Context, override val themeStyle: String, override val hasKeyBorders: Boolean) : Colors {
|
||||
class DynamicColors(context: Context, override val themeStyle: String, override val hasKeyBorders: Boolean, private var keyboardBackground: Drawable? = null) : Colors {
|
||||
|
||||
private val isNight = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
||||
|
||||
|
@ -126,9 +128,6 @@ class DynamicColors(context: Context, override val themeStyle: String, override
|
|||
private val stripBackgroundList: ColorStateList
|
||||
private val toolbarKeyStateList = activatedStateList(keyText, darken(darken(keyText)))
|
||||
|
||||
/** custom drawable used for keyboard background */
|
||||
private val keyboardBackground: Drawable?
|
||||
|
||||
/** darkened variant of [accent] because the accent color is always light for dynamic colors */
|
||||
private val adjustedAccent: Int = darken(accent)
|
||||
/** further darkened variant of [adjustedAccent] */
|
||||
|
@ -143,17 +142,18 @@ class DynamicColors(context: Context, override val themeStyle: String, override
|
|||
private val adjustedKeyBackground: Int = brighten(keyBackground)
|
||||
/** further brightened variant of [adjustedKeyBackground] */
|
||||
private val doubleAdjustedKeyBackground: Int = brighten(adjustedKeyBackground)
|
||||
private var backgroundSetupDone = false
|
||||
|
||||
init {
|
||||
accentColorFilter = colorFilter(doubleAdjustedAccent)
|
||||
|
||||
if (themeStyle == STYLE_HOLO) {
|
||||
if (themeStyle == STYLE_HOLO && keyboardBackground == null) {
|
||||
val darkerBackground = adjustLuminosityAndKeepAlpha(background, -0.2f)
|
||||
navBar = darkerBackground
|
||||
keyboardBackground = GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(background, darkerBackground))
|
||||
backgroundSetupDone = true
|
||||
} else {
|
||||
navBar = background
|
||||
keyboardBackground = null
|
||||
}
|
||||
|
||||
// todo (idea): make better use of the states?
|
||||
|
@ -342,8 +342,15 @@ class DynamicColors(context: Context, override val themeStyle: String, override
|
|||
else view.background.colorFilter = adjustedBackgroundFilter
|
||||
KEYBOARD_BACKGROUND -> view.setBackgroundColor(Color.TRANSPARENT)
|
||||
MAIN_BACKGROUND -> {
|
||||
if (keyboardBackground != null) view.background = keyboardBackground
|
||||
else view.background.colorFilter = backgroundFilter
|
||||
if (keyboardBackground != null) {
|
||||
if (!backgroundSetupDone) {
|
||||
keyboardBackground = BitmapDrawable(view.context.resources, keyboardBackground!!.toBitmap(view.width, view.height))
|
||||
backgroundSetupDone = true
|
||||
}
|
||||
view.background = keyboardBackground
|
||||
} else {
|
||||
view.background.colorFilter = backgroundFilter
|
||||
}
|
||||
}
|
||||
else -> view.background.colorFilter = backgroundFilter
|
||||
}
|
||||
|
@ -363,6 +370,7 @@ class DefaultColors (
|
|||
private val suggestionText: Int = keyText,
|
||||
private val spaceBarText: Int = keyHintText,
|
||||
private val gesture: Int = accent,
|
||||
private var keyboardBackground: Drawable? = null,
|
||||
) : Colors {
|
||||
private val navBar: Int
|
||||
/** brightened or darkened variant of [background], to be used if exact background color would be
|
||||
|
@ -389,20 +397,18 @@ class DefaultColors (
|
|||
private val adjustedBackgroundStateList: ColorStateList
|
||||
private val stripBackgroundList: ColorStateList
|
||||
private val toolbarKeyStateList = activatedStateList(suggestionText, darken(darken(suggestionText)))
|
||||
|
||||
/** custom drawable used for keyboard background */
|
||||
private val keyboardBackground: Drawable?
|
||||
private var backgroundSetupDone = false
|
||||
|
||||
override fun haveColorsChanged(context: Context) = false
|
||||
|
||||
init {
|
||||
if (themeStyle == STYLE_HOLO) {
|
||||
if (themeStyle == STYLE_HOLO && keyboardBackground == null) {
|
||||
val darkerBackground = adjustLuminosityAndKeepAlpha(background, -0.2f)
|
||||
navBar = darkerBackground
|
||||
keyboardBackground = GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, intArrayOf(background, darkerBackground))
|
||||
backgroundSetupDone = true
|
||||
} else {
|
||||
navBar = background
|
||||
keyboardBackground = null
|
||||
}
|
||||
|
||||
if (isDarkColor(background)) {
|
||||
|
@ -513,8 +519,15 @@ class DefaultColors (
|
|||
MORE_SUGGESTIONS_BACKGROUND -> view.background.colorFilter = backgroundFilter
|
||||
KEYBOARD_BACKGROUND -> view.setBackgroundColor(Color.TRANSPARENT)
|
||||
MAIN_BACKGROUND -> {
|
||||
if (keyboardBackground != null) view.background = keyboardBackground
|
||||
else view.background.colorFilter = backgroundFilter
|
||||
if (keyboardBackground != null) {
|
||||
if (!backgroundSetupDone) {
|
||||
keyboardBackground = BitmapDrawable(view.context.resources, keyboardBackground!!.toBitmap(view.width, view.height))
|
||||
backgroundSetupDone = true
|
||||
}
|
||||
view.background = keyboardBackground
|
||||
} else {
|
||||
view.background.colorFilter = backgroundFilter
|
||||
}
|
||||
}
|
||||
else -> view.background.colorFilter = backgroundFilter
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.annotation.SuppressLint
|
|||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
|
@ -61,8 +62,10 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
|||
"userunigram.*/userunigram.*\\.(body|header)".toRegex(),
|
||||
"UserHistoryDictionary.*/UserHistoryDictionary.*\\.(body|header)".toRegex(),
|
||||
"spellcheck_userunigram.*/spellcheck_userunigram.*\\.(body|header)".toRegex(),
|
||||
"custom_background_image.*".toRegex(),
|
||||
) }
|
||||
|
||||
// is there any way to get additional information into the ActivityResult? would remove the need for 5 times the (almost) same code
|
||||
private val libraryFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode != Activity.RESULT_OK) return@registerForActivityResult
|
||||
val uri = it.data?.data ?: return@registerForActivityResult
|
||||
|
@ -81,6 +84,18 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
|||
restore(uri)
|
||||
}
|
||||
|
||||
private val dayImageFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode != Activity.RESULT_OK) return@registerForActivityResult
|
||||
val uri = it.data?.data ?: return@registerForActivityResult
|
||||
loadImage(uri, false)
|
||||
}
|
||||
|
||||
private val nightImageFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode != Activity.RESULT_OK) return@registerForActivityResult
|
||||
val uri = it.data?.data ?: return@registerForActivityResult
|
||||
loadImage(uri, true)
|
||||
}
|
||||
|
||||
override fun onCreate(icicle: Bundle?) {
|
||||
super.onCreate(icicle)
|
||||
addPreferencesFromResource(R.xml.prefs_screen_advanced)
|
||||
|
@ -96,6 +111,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
|||
setupKeyLongpressTimeoutSettings()
|
||||
findPreference<Preference>("load_gesture_library")?.setOnPreferenceClickListener { onClickLoadLibrary() }
|
||||
findPreference<Preference>("pref_backup_restore")?.setOnPreferenceClickListener { showBackupRestoreDialog() }
|
||||
findPreference<Preference>("custom_background_image")?.setOnPreferenceClickListener { onClickLoadImage() }
|
||||
|
||||
findPreference<Preference>("custom_symbols_layout")?.setOnPreferenceClickListener {
|
||||
val layoutName = Settings.readSymbolsLayoutName(context, context.resources.configuration.locale).takeIf { it.startsWith(CUSTOM_LAYOUT_PREFIX) }
|
||||
|
@ -170,6 +186,55 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun onClickLoadImage(): Boolean {
|
||||
if (Settings.readDayNightPref(sharedPreferences, resources)) {
|
||||
AlertDialog.Builder(requireContext())
|
||||
.setMessage(R.string.day_or_night_image)
|
||||
.setPositiveButton(R.string.day_or_night_day) { _, _ -> customImageDialog(false) }
|
||||
.setNegativeButton(R.string.day_or_night_night) { _, _ -> customImageDialog(true) }
|
||||
.setNeutralButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
} else {
|
||||
customImageDialog(false)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun customImageDialog(night: Boolean) {
|
||||
val imageFile = Settings.getCustomBackgroundFile(requireContext(), night)
|
||||
val builder = AlertDialog.Builder(requireContext())
|
||||
.setMessage(R.string.customize_background_image)
|
||||
.setPositiveButton(R.string.button_load_custom) { _, _ ->
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||
.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
.setType("image/*")
|
||||
if (night) nightImageFilePicker.launch(intent)
|
||||
else dayImageFilePicker.launch(intent)
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
if (imageFile.exists()) {
|
||||
builder.setNeutralButton(R.string.delete) { _, _ ->
|
||||
imageFile.delete()
|
||||
Settings.clearCachedBackgroundImages()
|
||||
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext())
|
||||
}
|
||||
}
|
||||
builder.show()
|
||||
}
|
||||
|
||||
private fun loadImage(uri: Uri, night: Boolean) {
|
||||
val imageFile = Settings.getCustomBackgroundFile(requireContext(), night)
|
||||
FileUtils.copyStreamToNewFile(requireContext().contentResolver.openInputStream(uri), imageFile)
|
||||
try {
|
||||
BitmapFactory.decodeFile(imageFile.absolutePath)
|
||||
} catch (_: Exception) {
|
||||
infoDialog(requireContext(), R.string.file_read_error)
|
||||
imageFile.delete()
|
||||
}
|
||||
Settings.clearCachedBackgroundImages()
|
||||
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext())
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
private fun renameToLibfileAndRestart(file: File, checksum: String) {
|
||||
libfile.delete()
|
||||
|
|
|
@ -123,7 +123,7 @@ class LanguageSettingsDialog(
|
|||
.setMessage(message)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setNeutralButton(R.string.button_copy_existing_layout) { _, _ -> copyLayout() }
|
||||
.setPositiveButton(R.string.button_load_custom_layout) { _, _ -> fragment?.requestLayoutFile() }
|
||||
.setPositiveButton(R.string.button_load_custom) { _, _ -> fragment?.requestLayoutFile() }
|
||||
.create()
|
||||
dialog.show()
|
||||
(dialog.findViewById<View>(android.R.id.message) as? TextView)?.movementMethod = LinkMovementMethod.getInstance()
|
||||
|
@ -201,7 +201,7 @@ class LanguageSettingsDialog(
|
|||
reloadSetting()
|
||||
}
|
||||
if (isCustom) {
|
||||
confirmDialog(context, context.getString(R.string.delete_layout, getLayoutDisplayName(layoutSetName!!)), context.getString(R.string.delete_dict)) { delete() }
|
||||
confirmDialog(context, context.getString(R.string.delete_layout, getLayoutDisplayName(layoutSetName!!)), context.getString(R.string.delete)) { delete() }
|
||||
} else {
|
||||
delete()
|
||||
}
|
||||
|
@ -345,7 +345,7 @@ class LanguageSettingsDialog(
|
|||
isVisible = true
|
||||
setOnClickListener {
|
||||
confirmDialog(context, context.getString(R.string.remove_dictionary_message, dictType), context.getString(
|
||||
R.string.delete_dict)) {
|
||||
R.string.delete)) {
|
||||
val parent = dictFile.parentFile
|
||||
dictFile.delete()
|
||||
if (parent?.list()?.isEmpty() == true)
|
||||
|
|
|
@ -12,7 +12,10 @@ import android.content.SharedPreferences;
|
|||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
|
||||
import org.dslul.openboard.inputmethod.latin.utils.CustomLayoutUtilsKt;
|
||||
|
@ -23,6 +26,7 @@ import android.view.ContextThemeWrapper;
|
|||
import android.view.Gravity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme;
|
||||
|
@ -160,6 +164,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
private SettingsValues mSettingsValues;
|
||||
private final ReentrantLock mSettingsValuesLock = new ReentrantLock();
|
||||
|
||||
// static cache for background images to avoid potentially slow reload on every settings reload
|
||||
private static Drawable sCachedBackgroundDay;
|
||||
private static Drawable sCachedBackgroundNight;
|
||||
|
||||
private static final Settings sInstance = new Settings();
|
||||
|
||||
// preferences that are not used in SettingsValues and thus should not trigger reload when changed
|
||||
|
@ -532,6 +540,37 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
return "symbols_shifted";
|
||||
}
|
||||
|
||||
@Nullable public static Drawable readUserBackgroundImage(final Context context, final boolean night) {
|
||||
if (night && sCachedBackgroundNight != null) return sCachedBackgroundNight;
|
||||
if (!night && sCachedBackgroundDay != null) return sCachedBackgroundDay;
|
||||
final File image = getCustomBackgroundFile(context, night);
|
||||
if (!image.isFile()) return null;
|
||||
try {
|
||||
if (night) {
|
||||
sCachedBackgroundNight = new BitmapDrawable(context.getResources(), BitmapFactory.decodeFile(image.getAbsolutePath()));
|
||||
return sCachedBackgroundNight;
|
||||
} else {
|
||||
sCachedBackgroundDay = new BitmapDrawable(context.getResources(), BitmapFactory.decodeFile(image.getAbsolutePath()));
|
||||
return sCachedBackgroundDay;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static File getCustomBackgroundFile(final Context context, final boolean night) {
|
||||
return new File(context.getFilesDir(), "custom_background_image" + (night ? "_night" : ""));
|
||||
}
|
||||
|
||||
public static boolean readDayNightPref(final SharedPreferences prefs, final Resources res) {
|
||||
return prefs.getBoolean(PREF_THEME_DAY_NIGHT, res.getBoolean(R.bool.day_night_default));
|
||||
}
|
||||
|
||||
public static void clearCachedBackgroundImages() {
|
||||
sCachedBackgroundDay = null;
|
||||
sCachedBackgroundNight = null;
|
||||
}
|
||||
|
||||
public static List<Locale> getSecondaryLocales(final SharedPreferences prefs, final String mainLocaleString) {
|
||||
final String localesString = prefs.getString(PREF_SECONDARY_LOCALES_PREFIX + mainLocaleString.toLowerCase(Locale.ROOT), "");
|
||||
|
||||
|
@ -558,7 +597,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public static Colors getColorsForCurrentTheme(final Context context, final SharedPreferences prefs) {
|
||||
boolean isNight = ResourceUtils.isNight(context.getResources());
|
||||
if (prefs.getBoolean(PREF_FORCE_OPPOSITE_THEME, false)) isNight = !isNight;
|
||||
final String themeColors = (isNight && prefs.getBoolean(PREF_THEME_DAY_NIGHT, context.getResources().getBoolean(R.bool.day_night_default)))
|
||||
final String themeColors = (isNight && readDayNightPref(prefs, context.getResources()))
|
||||
? prefs.getString(Settings.PREF_THEME_COLORS_NIGHT, KeyboardTheme.THEME_DARKER)
|
||||
: prefs.getString(Settings.PREF_THEME_COLORS, KeyboardTheme.THEME_LIGHT);
|
||||
final String themeStyle = prefs.getString(Settings.PREF_THEME_STYLE, KeyboardTheme.STYLE_MATERIAL);
|
||||
|
|
|
@ -161,8 +161,8 @@ fun editCustomLayout(layoutName: String, context: Context, startContent: String?
|
|||
if (isSymbols) {
|
||||
val name = if (layoutName.contains("shift")) context.getString(R.string.shift_symbols) else context.getString(R.string.more_keys_symbols)
|
||||
if (file.exists()) {
|
||||
builder.setNeutralButton(R.string.delete_dict) { _, _ ->
|
||||
confirmDialog(context, context.getString(R.string.delete_layout, name), context.getString(R.string.delete_dict)) {
|
||||
builder.setNeutralButton(R.string.delete) { _, _ ->
|
||||
confirmDialog(context, context.getString(R.string.delete_layout, name), context.getString(R.string.delete)) {
|
||||
file.delete()
|
||||
KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(context)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue