mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-10 16:39:35 +00:00
497 lines
24 KiB
Kotlin
497 lines
24 KiB
Kotlin
/*
|
|
* Copyright (C) 2014 The Android Open Source Project
|
|
* modified
|
|
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
|
*/
|
|
package helium314.keyboard.keyboard
|
|
|
|
import android.content.Context
|
|
import android.content.SharedPreferences
|
|
import android.graphics.Color
|
|
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
|
|
import helium314.keyboard.latin.common.Colors
|
|
import helium314.keyboard.latin.common.DefaultColors
|
|
import helium314.keyboard.latin.common.DynamicColors
|
|
import helium314.keyboard.latin.settings.Defaults
|
|
import helium314.keyboard.latin.settings.Settings
|
|
import helium314.keyboard.latin.utils.brightenOrDarken
|
|
import helium314.keyboard.latin.utils.isBrightColor
|
|
import helium314.keyboard.latin.utils.isGoodContrast
|
|
import helium314.keyboard.latin.utils.prefs
|
|
import helium314.keyboard.settings.keyboardNeedsReload
|
|
import kotlinx.serialization.Serializable
|
|
import kotlinx.serialization.json.Json
|
|
import java.util.EnumMap
|
|
|
|
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) {
|
|
override fun equals(other: Any?) = if (other === this) true
|
|
else (other as? KeyboardTheme)?.themeId == themeId
|
|
|
|
override fun hashCode(): Int {
|
|
return themeId
|
|
}
|
|
|
|
companion object {
|
|
// old themes, now called styles
|
|
const val STYLE_MATERIAL = "Material"
|
|
const val STYLE_HOLO = "Holo"
|
|
const val STYLE_ROUNDED = "Rounded"
|
|
|
|
// new themes that are just colors
|
|
const val THEME_LIGHT = "light"
|
|
const val THEME_HOLO_WHITE = "holo_white"
|
|
const val THEME_DARK = "dark"
|
|
const val THEME_DARKER = "darker"
|
|
const val THEME_BLACK = "black"
|
|
const val THEME_DYNAMIC = "dynamic"
|
|
const val THEME_BLUE_GRAY = "blue_gray"
|
|
const val THEME_BROWN = "brown"
|
|
const val THEME_CHOCOLATE = "chocolate"
|
|
const val THEME_CLOUDY = "cloudy"
|
|
const val THEME_FOREST = "forest"
|
|
const val THEME_INDIGO = "indigo"
|
|
const val THEME_OCEAN = "ocean"
|
|
const val THEME_PINK = "pink"
|
|
const val THEME_SAND = "sand"
|
|
const val THEME_VIOLETTE = "violette"
|
|
fun getAvailableDefaultColors(prefs: SharedPreferences, isNight: Boolean) = listOfNotNull(
|
|
if (!isNight) THEME_LIGHT else null, THEME_DARK,
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) THEME_DYNAMIC else null,
|
|
if (prefs.getString(Settings.PREF_THEME_STYLE, Defaults.PREF_THEME_STYLE) == STYLE_HOLO) THEME_HOLO_WHITE else null,
|
|
THEME_DARKER,
|
|
THEME_BLACK,
|
|
if (!isNight) THEME_BLUE_GRAY else null,
|
|
if (!isNight) THEME_BROWN else null,
|
|
THEME_CHOCOLATE,
|
|
THEME_CLOUDY,
|
|
THEME_FOREST,
|
|
if (!isNight) THEME_INDIGO else null,
|
|
if (!isNight) THEME_PINK else null,
|
|
THEME_OCEAN,
|
|
if (!isNight) THEME_SAND else null,
|
|
THEME_VIOLETTE
|
|
)
|
|
val STYLES = arrayOf(STYLE_MATERIAL, STYLE_HOLO, STYLE_ROUNDED)
|
|
|
|
// These should be aligned with Keyboard.themeId and Keyboard.Case.keyboardTheme
|
|
// attributes' values in attrs.xml.
|
|
private const val THEME_ID_HOLO_BASE = 0
|
|
private const val THEME_ID_LXX_BASE = 1
|
|
private const val THEME_ID_LXX_BASE_BORDER = 2
|
|
private const val THEME_ID_ROUNDED_BASE = 3
|
|
private const val THEME_ID_ROUNDED_BASE_BORDER = 4
|
|
private const val DEFAULT_THEME_ID = THEME_ID_LXX_BASE
|
|
|
|
private val KEYBOARD_THEMES = arrayOf(
|
|
KeyboardTheme(THEME_ID_HOLO_BASE, R.style.KeyboardTheme_HoloBase),
|
|
KeyboardTheme(THEME_ID_LXX_BASE, R.style.KeyboardTheme_LXX_Base),
|
|
KeyboardTheme(THEME_ID_LXX_BASE_BORDER, R.style.KeyboardTheme_LXX_Base_Border),
|
|
KeyboardTheme(THEME_ID_ROUNDED_BASE, R.style.KeyboardTheme_Rounded_Base),
|
|
KeyboardTheme(THEME_ID_ROUNDED_BASE_BORDER, R.style.KeyboardTheme_Rounded_Base_Border)
|
|
)
|
|
|
|
// named colors, with names from old settings
|
|
const val COLOR_ACCENT = "accent"
|
|
const val COLOR_GESTURE = "gesture"
|
|
const val COLOR_SUGGESTION_TEXT = "suggestion_text"
|
|
const val COLOR_TEXT = "text"
|
|
const val COLOR_HINT_TEXT = "hint_text"
|
|
const val COLOR_KEYS = "keys"
|
|
const val COLOR_FUNCTIONAL_KEYS = "functional_keys"
|
|
const val COLOR_SPACEBAR = "spacebar"
|
|
const val COLOR_SPACEBAR_TEXT = "spacebar_text"
|
|
const val COLOR_BACKGROUND = "background"
|
|
|
|
@JvmStatic
|
|
fun getKeyboardTheme(context: Context): KeyboardTheme {
|
|
val prefs = context.prefs()
|
|
val style = prefs.getString(Settings.PREF_THEME_STYLE, Defaults.PREF_THEME_STYLE)
|
|
val borders = prefs.getBoolean(Settings.PREF_THEME_KEY_BORDERS, Defaults.PREF_THEME_KEY_BORDERS)
|
|
val matchingId = when (style) {
|
|
STYLE_HOLO -> THEME_ID_HOLO_BASE
|
|
STYLE_ROUNDED -> if (borders) THEME_ID_ROUNDED_BASE_BORDER else THEME_ID_ROUNDED_BASE
|
|
else -> if (borders) THEME_ID_LXX_BASE_BORDER else THEME_ID_LXX_BASE
|
|
}
|
|
return KEYBOARD_THEMES.firstOrNull { it.themeId == matchingId } ?: KEYBOARD_THEMES[DEFAULT_THEME_ID]
|
|
}
|
|
|
|
fun getThemeActionAndEmojiKeyLabelFlags(themeId: Int): Int {
|
|
return if (themeId == THEME_ID_LXX_BASE || themeId == THEME_ID_ROUNDED_BASE) Key.LABEL_FLAGS_KEEP_BACKGROUND_ASPECT_RATIO else 0
|
|
}
|
|
|
|
@JvmStatic
|
|
fun getThemeColors(themeName: String, themeStyle: String, context: Context, prefs: SharedPreferences, isNight: Boolean): Colors {
|
|
val hasBorders = prefs.getBoolean(Settings.PREF_THEME_KEY_BORDERS, Defaults.PREF_THEME_KEY_BORDERS)
|
|
val backgroundImage = Settings.readUserBackgroundImage(context, isNight)
|
|
return when (themeName) {
|
|
THEME_DYNAMIC -> {
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) DynamicColors(context, themeStyle, hasBorders, backgroundImage)
|
|
else getThemeColors(THEME_LIGHT, themeStyle, context, prefs, isNight)
|
|
}
|
|
THEME_DARK -> DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
ContextCompat.getColor(context, R.color.gesture_trail_color_lxx_dark),
|
|
Color.parseColor("#263238"),
|
|
Color.parseColor("#364248"),
|
|
Color.parseColor("#2d393f"),
|
|
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,
|
|
hasBorders,
|
|
Color.WHITE,
|
|
Color.parseColor("#282828"),
|
|
Color.WHITE, // drawable is transparent
|
|
Color.parseColor("#444444"), // should be 222222, but the key drawable is already grey
|
|
Color.WHITE,
|
|
Color.WHITE,
|
|
Color.parseColor("#282828"),
|
|
Color.WHITE,
|
|
Color.parseColor("#80FFFFFF"),
|
|
keyboardBackground = backgroundImage
|
|
)
|
|
THEME_DARKER -> DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
ContextCompat.getColor(context, R.color.gesture_trail_color_lxx_dark),
|
|
ContextCompat.getColor(context, R.color.keyboard_background_lxx_dark_border),
|
|
ContextCompat.getColor(context, R.color.key_background_normal_lxx_dark_border),
|
|
ContextCompat.getColor(context, R.color.key_background_functional_lxx_dark_border),
|
|
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,
|
|
hasBorders,
|
|
ContextCompat.getColor(context, R.color.gesture_trail_color_lxx_dark),
|
|
ContextCompat.getColor(context, R.color.background_amoled_black),
|
|
ContextCompat.getColor(context, R.color.background_amoled_dark),
|
|
ContextCompat.getColor(context, R.color.background_amoled_dark),
|
|
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,
|
|
hasBorders,
|
|
Color.rgb(120, 144, 156),
|
|
Color.rgb(236, 239, 241),
|
|
Color.WHITE,
|
|
Color.rgb(207, 216, 220),
|
|
Color.WHITE,
|
|
Color.BLACK,
|
|
Color.BLACK,
|
|
keyboardBackground = backgroundImage
|
|
)
|
|
THEME_BROWN -> DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
Color.rgb(141, 110, 99),
|
|
Color.rgb(239, 235, 233),
|
|
Color.WHITE,
|
|
Color.rgb(215, 204, 200),
|
|
Color.WHITE,
|
|
Color.BLACK,
|
|
Color.BLACK,
|
|
keyboardBackground = backgroundImage
|
|
)
|
|
THEME_CHOCOLATE -> DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
Color.rgb(80, 128, 255),
|
|
Color.rgb(140, 112, 94),
|
|
Color.rgb(193, 163, 146),
|
|
Color.rgb(168, 127, 103),
|
|
Color.rgb(193, 163, 146),
|
|
Color.WHITE,
|
|
Color.WHITE,
|
|
keyboardBackground = backgroundImage
|
|
)
|
|
THEME_CLOUDY -> DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
Color.rgb(255, 113, 129),
|
|
Color.rgb(81, 97, 113),
|
|
Color.rgb(117, 128, 142),
|
|
Color.rgb(99, 109, 121),
|
|
Color.rgb(117, 128, 142),
|
|
Color.WHITE,
|
|
Color.WHITE,
|
|
keyboardBackground = backgroundImage
|
|
)
|
|
THEME_FOREST -> DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
Color.rgb(75, 110, 75),
|
|
Color.rgb(181, 125, 88),
|
|
Color.rgb(228, 212, 191),
|
|
Color.rgb(212, 186, 153),
|
|
Color.rgb(228, 212, 191),
|
|
Color.rgb(0, 50, 0),
|
|
Color.rgb(0, 50, 0),
|
|
Color.rgb(0, 50, 0),
|
|
Color.rgb(0, 80, 0),
|
|
keyboardBackground = backgroundImage
|
|
)
|
|
THEME_INDIGO -> DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
Color.rgb(92, 107, 192),
|
|
Color.rgb(232, 234, 246),
|
|
Color.WHITE,
|
|
Color.rgb(197, 202, 233),
|
|
Color.WHITE,
|
|
Color.BLACK,
|
|
Color.BLACK,
|
|
keyboardBackground = backgroundImage
|
|
)
|
|
THEME_OCEAN -> DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
Color.rgb(255, 124, 0),
|
|
Color.rgb(89, 109, 155),
|
|
Color.rgb(132, 157, 212),
|
|
Color.rgb(81, 116, 194),
|
|
Color.rgb(132, 157, 212),
|
|
Color.WHITE,
|
|
Color.WHITE,
|
|
keyboardBackground = backgroundImage
|
|
)
|
|
THEME_PINK -> DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
Color.rgb(236, 64, 122),
|
|
Color.rgb(252, 228, 236),
|
|
Color.WHITE,
|
|
Color.rgb(248, 187, 208),
|
|
Color.WHITE,
|
|
Color.BLACK,
|
|
Color.BLACK,
|
|
keyboardBackground = backgroundImage
|
|
)
|
|
THEME_SAND -> DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
Color.rgb(110, 155, 255),
|
|
Color.rgb(242, 232, 218),
|
|
Color.WHITE,
|
|
Color.rgb(234, 211, 185),
|
|
Color.WHITE,
|
|
Color.BLACK,
|
|
Color.BLACK,
|
|
keyboardBackground = backgroundImage
|
|
)
|
|
THEME_VIOLETTE -> DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
Color.rgb(255, 96, 255),
|
|
Color.rgb(112, 112, 174),
|
|
Color.rgb(150, 150, 216),
|
|
Color.rgb(123, 123, 206),
|
|
Color.rgb(150, 150, 216),
|
|
Color.WHITE,
|
|
Color.WHITE,
|
|
keyboardBackground = backgroundImage
|
|
)
|
|
else -> { // user-defined theme
|
|
if (readUserMoreColors(prefs, themeName) == 2)
|
|
AllColors(readUserAllColors(prefs, themeName), themeStyle, hasBorders, backgroundImage)
|
|
else {
|
|
val colors = readUserColors(prefs, themeName)
|
|
DefaultColors(
|
|
themeStyle,
|
|
hasBorders,
|
|
determineUserColor(colors, context, COLOR_ACCENT, false),
|
|
determineUserColor(colors, context, COLOR_BACKGROUND, false),
|
|
determineUserColor(colors, context, COLOR_KEYS, false),
|
|
determineUserColor(colors, context, COLOR_FUNCTIONAL_KEYS, false),
|
|
determineUserColor(colors, context, COLOR_SPACEBAR, false),
|
|
determineUserColor(colors, context, COLOR_TEXT, false),
|
|
determineUserColor(colors, context, COLOR_HINT_TEXT, false),
|
|
determineUserColor(colors, context, COLOR_SUGGESTION_TEXT, false),
|
|
determineUserColor(colors, context, COLOR_SPACEBAR_TEXT, false),
|
|
determineUserColor(colors, context, COLOR_GESTURE, false),
|
|
backgroundImage,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun writeUserColors(prefs: SharedPreferences, themeName: String, colors: List<ColorSetting>) {
|
|
val key = Settings.PREF_USER_COLORS_PREFIX + themeName
|
|
val value = Json.encodeToString(colors.filter { it.color != null || it.auto == false })
|
|
prefs.edit().putString(key, value).apply()
|
|
keyboardNeedsReload = true
|
|
}
|
|
|
|
fun readUserColors(prefs: SharedPreferences, themeName: String): List<ColorSetting> {
|
|
val key = Settings.PREF_USER_COLORS_PREFIX + themeName
|
|
return Json.decodeFromString(prefs.getString(key, Defaults.PREF_USER_COLORS)!!)
|
|
}
|
|
|
|
fun writeUserMoreColors(prefs: SharedPreferences, themeName: String, value: Int) {
|
|
val key = Settings.PREF_USER_MORE_COLORS_PREFIX + themeName
|
|
prefs.edit().putInt(key, value).apply()
|
|
keyboardNeedsReload = true
|
|
}
|
|
|
|
fun readUserMoreColors(prefs: SharedPreferences, themeName: String): Int {
|
|
val key = Settings.PREF_USER_MORE_COLORS_PREFIX + themeName
|
|
return prefs.getInt(key, Defaults.PREF_USER_MORE_COLORS)
|
|
}
|
|
|
|
fun writeUserAllColors(prefs: SharedPreferences, themeName: String, colorMap: EnumMap<ColorType, Int>) {
|
|
val key = Settings.PREF_USER_ALL_COLORS_PREFIX + themeName
|
|
prefs.edit().putString(key, colorMap.map { "${it.key},${it.value}" }.joinToString(";")).apply()
|
|
keyboardNeedsReload = true
|
|
}
|
|
|
|
fun readUserAllColors(prefs: SharedPreferences, themeName: String): EnumMap<ColorType, Int> {
|
|
val key = Settings.PREF_USER_ALL_COLORS_PREFIX + themeName
|
|
val colorsString = prefs.getString(key, Defaults.PREF_USER_ALL_COLORS)!!
|
|
val colorMap = EnumMap<ColorType, Int>(ColorType::class.java)
|
|
colorsString.split(";").forEach {
|
|
val ct = try {
|
|
ColorType.valueOf(it.substringBefore(",").uppercase())
|
|
} catch (_: Exception) { // todo: which one?
|
|
return@forEach
|
|
}
|
|
val i = it.substringAfter(",").toIntOrNull() ?: return@forEach
|
|
colorMap[ct] = i
|
|
}
|
|
return colorMap
|
|
}
|
|
|
|
fun getUnusedThemeName(initialName: String, prefs: SharedPreferences): String {
|
|
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 (initialName !in existingNames) return initialName
|
|
var i = 1
|
|
while ("$initialName$i" in existingNames)
|
|
i++
|
|
return "$initialName$i"
|
|
}
|
|
|
|
// 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<ColorSetting>, context: Context, colorName: String, isNight: Boolean): Int {
|
|
val c = colors.firstOrNull { it.name == colorName }
|
|
val color = c?.color
|
|
val auto = c?.auto ?: true
|
|
return if (auto || color == null)
|
|
determineAutoColor(colors, colorName, isNight, context)
|
|
else color
|
|
}
|
|
|
|
private fun determineAutoColor(colors: List<ColorSetting>, colorName: String, isNight: Boolean, context: Context): Int {
|
|
when (colorName) {
|
|
COLOR_ACCENT -> {
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
|
// try determining accent color on Android 10 & 11, accent is not available in resources
|
|
val wrapper: Context = ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault)
|
|
val value = TypedValue()
|
|
if (wrapper.theme.resolveAttribute(android.R.attr.colorAccent, value, true)) return value.data
|
|
}
|
|
return ContextCompat.getColor(Settings.getDayNightContext(context, isNight), R.color.accent)
|
|
}
|
|
COLOR_GESTURE -> return determineUserColor(colors, context, COLOR_ACCENT, isNight)
|
|
COLOR_SUGGESTION_TEXT ->
|
|
return determineUserColor(colors, context, COLOR_TEXT, isNight)
|
|
COLOR_TEXT -> {
|
|
// base it on background color, and not key, because it's also used for suggestions
|
|
val background = determineUserColor(colors, context, COLOR_BACKGROUND, isNight)
|
|
return if (isBrightColor(background)) {
|
|
// but if key borders are enabled, we still want reasonable contrast
|
|
if (!context.prefs().getBoolean(Settings.PREF_THEME_KEY_BORDERS, Defaults.PREF_THEME_KEY_BORDERS)
|
|
|| isGoodContrast(Color.BLACK, determineUserColor(colors, context, COLOR_KEYS, isNight))
|
|
) Color.BLACK
|
|
else Color.GRAY
|
|
} else Color.WHITE
|
|
}
|
|
COLOR_HINT_TEXT -> {
|
|
return if (isBrightColor(determineUserColor(colors, context, COLOR_KEYS, isNight))) Color.DKGRAY
|
|
else determineUserColor(colors, context, COLOR_TEXT, isNight)
|
|
}
|
|
COLOR_KEYS ->
|
|
return brightenOrDarken(determineUserColor(colors, context, COLOR_BACKGROUND, isNight), isNight)
|
|
COLOR_FUNCTIONAL_KEYS ->
|
|
return brightenOrDarken(determineUserColor(colors, context, COLOR_KEYS, isNight), true)
|
|
COLOR_SPACEBAR -> return determineUserColor(colors, context, COLOR_KEYS, isNight)
|
|
COLOR_SPACEBAR_TEXT -> {
|
|
val spacebar = determineUserColor(colors, context, COLOR_SPACEBAR, isNight)
|
|
val hintText = determineUserColor(colors, context, COLOR_HINT_TEXT, isNight)
|
|
if (isGoodContrast(hintText, spacebar)) return hintText and -0x7f000001 // add some transparency
|
|
val text = determineUserColor(colors, context, COLOR_TEXT, isNight)
|
|
if (isGoodContrast(text, spacebar)) return text and -0x7f000001
|
|
return if (isBrightColor(spacebar)) Color.BLACK and -0x7f000001
|
|
else Color.WHITE and -0x7f000001
|
|
}
|
|
COLOR_BACKGROUND -> return ContextCompat.getColor(
|
|
Settings.getDayNightContext(context, isNight),
|
|
R.color.keyboard_background
|
|
)
|
|
else -> return ContextCompat.getColor(Settings.getDayNightContext(context, isNight), R.color.keyboard_background)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Serializable
|
|
data class ColorSetting(val name: String, val auto: Boolean?, val color: Int?) {
|
|
var displayName = name
|
|
}
|