Update theme picker in keyboard

This commit is contained in:
Aleksandras Kostarevas 2023-09-04 15:20:48 +03:00
parent 0a7ab52e8b
commit dc342f33a6
6 changed files with 202 additions and 11 deletions

View File

@ -144,6 +144,7 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
private var lastEditorInfo: EditorInfo? = null
// TODO: Calling this repeatedly as the theme changes tends to slow everything to a crawl
private fun recreateKeyboard() {
latinIMELegacy.updateTheme()
latinIMELegacy.mKeyboardSwitcher.mState.onLoadKeyboard(latinIMELegacy.currentAutoCapsState, latinIMELegacy.currentRecapitalizeState);
@ -311,6 +312,11 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
currWindowAction = null
currWindowActionWindow = null
if(hasThemeChanged) {
hasThemeChanged = false
recreateKeyboard()
}
setContent()
}
@ -655,14 +661,20 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
);
}
private var hasThemeChanged: Boolean = false
override fun updateTheme(newTheme: ThemeOption) {
assert(newTheme.available(this))
activeThemeOption = newTheme
updateDrawableProvider(newTheme.obtainColors(this))
deferSetSetting(THEME_KEY, newTheme.key)
if (activeThemeOption != newTheme) {
activeThemeOption = newTheme
updateDrawableProvider(newTheme.obtainColors(this))
deferSetSetting(THEME_KEY, newTheme.key)
recreateKeyboard()
hasThemeChanged = true
if(!isActionWindowOpen()) {
recreateKeyboard()
}
}
}
@RequiresApi(Build.VERSION_CODES.R)

View File

@ -143,6 +143,7 @@ public final class SystemBroadcastReceiver extends BroadcastReceiver {
}
public static void toggleAppIcon(final Context context) {
/*
final int appInfoFlags = context.getApplicationInfo().flags;
final boolean isSystemApp = (appInfoFlags & ApplicationInfo.FLAG_SYSTEM) > 0;
if (Log.isLoggable(TAG, Log.INFO)) {
@ -155,5 +156,6 @@ public final class SystemBroadcastReceiver extends BroadcastReceiver {
? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
*/
}
}

View File

@ -1,5 +0,0 @@
@file:Suppress("LocalVariableName")
package org.futo.inputmethod.latin.uix

View File

@ -21,8 +21,6 @@ import org.futo.inputmethod.latin.R
import org.futo.inputmethod.latin.uix.theme.DarkColorScheme
import kotlin.math.roundToInt
// TODO: Expand the number of drawables this provides so it covers the full theme, and
// build some system to dynamically change these colors
class BasicThemeProvider(val context: Context, val overrideColorScheme: ColorScheme? = null) :
DynamicThemeProvider {
override val primaryKeyboardColor: Int

View File

@ -16,6 +16,7 @@ import org.futo.inputmethod.latin.uix.ActionWindow
import org.futo.inputmethod.latin.uix.KeyboardManagerForAction
import org.futo.inputmethod.latin.uix.theme.ThemeOptionKeys
import org.futo.inputmethod.latin.uix.theme.ThemeOptions
import org.futo.inputmethod.latin.uix.theme.selector.ThemePicker
val ThemeAction = Action(
icon = R.drawable.eye,
@ -31,6 +32,9 @@ val ThemeAction = Action(
@Composable
override fun WindowContents() {
val context = LocalContext.current
ThemePicker { manager.updateTheme(it) }
/*
LazyColumn(
modifier = Modifier
.padding(8.dp, 0.dp)
@ -51,6 +55,8 @@ val ThemeAction = Action(
}
}
}
*/
}
override fun close() {

View File

@ -0,0 +1,178 @@
package org.futo.inputmethod.latin.uix.theme.selector
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.futo.inputmethod.latin.uix.differsFrom
import org.futo.inputmethod.latin.uix.theme.ThemeOption
import org.futo.inputmethod.latin.uix.theme.ThemeOptionKeys
import org.futo.inputmethod.latin.uix.theme.ThemeOptions
import org.futo.inputmethod.latin.uix.theme.Typography
import org.futo.inputmethod.latin.uix.theme.UixThemeWrapper
import org.futo.inputmethod.latin.uix.theme.presets.AMOLEDDarkPurple
import org.futo.inputmethod.latin.uix.theme.presets.ClassicMaterialDark
import org.futo.inputmethod.latin.uix.theme.presets.VoiceInputTheme
@Composable
fun ThemePreview(theme: ThemeOption, onClick: () -> Unit) {
val context = LocalContext.current
val colors = remember { theme.obtainColors(context) }
val currColors = MaterialTheme.colorScheme
val isSelected = !colors.differsFrom(currColors)
val borderWidth = if (isSelected) {
2.dp
} else {
0.dp
}
val borderColor = if (isSelected) {
currColors.inversePrimary
} else {
Color.Transparent
}
val textColor = colors.onBackground
// TODO: These have to be manually kept same as those in BasicThemeProvider
val spacebarColor = colors.outline.copy(alpha = 0.33f)
val actionColor = colors.primary
val keyboardShape = RoundedCornerShape(8.dp)
Surface(
modifier = Modifier
.padding(12.dp)
.width(172.dp)
.height(128.dp)
.border(borderWidth, borderColor, keyboardShape)
.clickable { onClick() },
color = colors.surface,
shape = keyboardShape
) {
Box(modifier = Modifier.fillMaxSize()) {
Text(
text = stringResource(theme.name),
textAlign = TextAlign.Center,
modifier = Modifier
.align(Alignment.TopCenter)
.background(colors.background)
.fillMaxWidth()
.padding(4.dp),
color = textColor,
style = Typography.labelSmall
)
Box(
modifier = Modifier
.fillMaxSize()
.padding(8.dp)
) {
Surface(
modifier = Modifier
.fillMaxWidth(0.5f)
.height(18.dp)
.align(Alignment.BottomCenter),
color = spacebarColor,
shape = RoundedCornerShape(12.dp)
) { }
Surface(
modifier = Modifier
.width(24.dp)
.height(18.dp)
.align(Alignment.BottomEnd)
.padding(0.dp, 1.dp),
color = actionColor,
shape = RoundedCornerShape(4.dp)
) { }
}
}
}
}
@Composable
fun ThemePicker(onSelected: (ThemeOption) -> Unit) {
val context = LocalContext.current
val isInspecting = LocalInspectionMode.current
val availableThemeOptions = remember {
ThemeOptionKeys.mapNotNull { key ->
ThemeOptions[key]?.let { Pair(key, it) }
}.filter {
it.second.available(context)
}.filter {
when (isInspecting) {
true -> !it.second.dynamic
else -> true
}
}
}
LazyVerticalGrid(
modifier = Modifier.fillMaxWidth(),
columns = GridCells.Adaptive(minSize = 172.dp)
) {
items(availableThemeOptions.count()) {
val themeOption = availableThemeOptions[it].second
ThemePreview(themeOption) {
onSelected(themeOption)
}
}
}
}
@Preview
@Composable
private fun ThemePickerPreview() {
Column {
UixThemeWrapper(VoiceInputTheme.obtainColors(LocalContext.current)) {
Surface(
color = MaterialTheme.colorScheme.background
) {
ThemePicker {}
}
}
UixThemeWrapper(ClassicMaterialDark.obtainColors(LocalContext.current)) {
Surface(
color = MaterialTheme.colorScheme.background
) {
ThemePicker {}
}
}
UixThemeWrapper(AMOLEDDarkPurple.obtainColors(LocalContext.current)) {
Surface(
color = MaterialTheme.colorScheme.background
) {
ThemePicker {}
}
}
}
}