Update theme to use dynamic color scheme

This commit is contained in:
Aleksandras Kostarevas 2023-08-19 15:06:18 +03:00
parent cccc18a1de
commit ad151d7f11
3 changed files with 95 additions and 43 deletions

View File

@ -26,6 +26,8 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.key import androidx.compose.runtime.key
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
@ -35,6 +37,7 @@ import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.graphics.toColor
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry import androidx.lifecycle.LifecycleRegistry
@ -49,6 +52,7 @@ import androidx.savedstate.SavedStateRegistryController
import androidx.savedstate.SavedStateRegistryOwner import androidx.savedstate.SavedStateRegistryOwner
import androidx.savedstate.findViewTreeSavedStateRegistryOwner import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner import androidx.savedstate.setViewTreeSavedStateRegistryOwner
import com.google.android.material.color.DynamicColors
import org.futo.inputmethod.latin.uix.ActionBar import org.futo.inputmethod.latin.uix.ActionBar
import org.futo.inputmethod.latin.uix.theme.DarkColorScheme import org.futo.inputmethod.latin.uix.theme.DarkColorScheme
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -148,43 +152,62 @@ class BasicThemeProvider(val context: Context) : KeyboardDrawableProvider {
} }
init { init {
val primary = DarkColorScheme.primary.toArgb() val colorScheme = if(!DynamicColors.isDynamicColorAvailable()) {
val secondary = DarkColorScheme.secondary.toArgb() DarkColorScheme
val highlight = DarkColorScheme.outline.copy(alpha = 0.33f).toArgb() } else {
val background = DarkColorScheme.surface.toArgb() val dCtx = DynamicColors.wrapContextIfAvailable(context)
val surface = DarkColorScheme.background.toArgb()
val outline = DarkColorScheme.outline.toArgb() dynamicLightColorScheme(dCtx)
}
val primary = colorScheme.primary.toArgb()
val secondary = colorScheme.secondary.toArgb()
val highlight = colorScheme.outline.copy(alpha = 0.33f).toArgb()
val background = colorScheme.surface.toArgb()
val surface = colorScheme.background.toArgb()
val outline = colorScheme.outline.toArgb()
val onSecondary = colorScheme.onSecondary.toArgb()
val onBackground = colorScheme.onBackground.toArgb()
val onBackgroundHalf = colorScheme.onBackground.copy(alpha = 0.5f).toArgb()
val transparent = Color.TRANSPARENT val transparent = Color.TRANSPARENT
colors[R.styleable.Keyboard_Key_keyTextColor] = DarkColorScheme.onBackground.toArgb() colors[R.styleable.Keyboard_Key_keyTextColor] = onBackground
colors[R.styleable.Keyboard_Key_keyTextInactivatedColor] = DarkColorScheme.onBackground.copy(alpha = 0.5f).toArgb() colors[R.styleable.Keyboard_Key_keyTextInactivatedColor] = onBackgroundHalf
colors[R.styleable.Keyboard_Key_keyTextShadowColor] = 0 colors[R.styleable.Keyboard_Key_keyTextShadowColor] = 0
colors[R.styleable.Keyboard_Key_functionalTextColor] = DarkColorScheme.onBackground.toArgb() colors[R.styleable.Keyboard_Key_functionalTextColor] = onBackground
colors[R.styleable.Keyboard_Key_keyHintLetterColor] = DarkColorScheme.onBackground.copy(alpha = 0.5f).toArgb() colors[R.styleable.Keyboard_Key_keyHintLetterColor] = onBackgroundHalf
colors[R.styleable.Keyboard_Key_keyHintLabelColor] = DarkColorScheme.onBackground.copy(alpha = 0.5f).toArgb() colors[R.styleable.Keyboard_Key_keyHintLabelColor] = onBackgroundHalf
colors[R.styleable.Keyboard_Key_keyShiftedLetterHintInactivatedColor] = DarkColorScheme.onBackground.copy(alpha = 0.5f).toArgb() colors[R.styleable.Keyboard_Key_keyShiftedLetterHintInactivatedColor] = onBackgroundHalf
colors[R.styleable.Keyboard_Key_keyShiftedLetterHintActivatedColor] = DarkColorScheme.onBackground.copy(alpha = 0.5f).toArgb() colors[R.styleable.Keyboard_Key_keyShiftedLetterHintActivatedColor] = onBackgroundHalf
colors[R.styleable.Keyboard_Key_keyPreviewTextColor] = DarkColorScheme.onBackground.toArgb() colors[R.styleable.Keyboard_Key_keyPreviewTextColor] = onSecondary
colors[R.styleable.MainKeyboardView_languageOnSpacebarTextColor] = DarkColorScheme.onBackground.copy(alpha = 0.5f).toArgb() colors[R.styleable.MainKeyboardView_languageOnSpacebarTextColor] = onBackgroundHalf
drawables[R.styleable.Keyboard_iconDeleteKey] = AppCompatResources.getDrawable(context, R.drawable.delete)!! drawables[R.styleable.Keyboard_iconDeleteKey] = AppCompatResources.getDrawable(context, R.drawable.delete)!!.apply {
drawables[R.styleable.Keyboard_iconLanguageSwitchKey] = AppCompatResources.getDrawable(context, R.drawable.globe)!! setTint(onBackground)
}
drawables[R.styleable.Keyboard_iconLanguageSwitchKey] = AppCompatResources.getDrawable(context, R.drawable.globe)!!.apply {
setTint(onBackground)
}
drawables[R.styleable.Keyboard_iconShiftKey] = AppCompatResources.getDrawable(context, R.drawable.shift)!! drawables[R.styleable.Keyboard_iconShiftKey] = AppCompatResources.getDrawable(context, R.drawable.shift)!!.apply {
drawables[R.styleable.Keyboard_iconShiftKeyShifted] = AppCompatResources.getDrawable(context, R.drawable.shiftshifted)!! setTint(onBackground)
}
drawables[R.styleable.Keyboard_iconShiftKeyShifted] = AppCompatResources.getDrawable(context, R.drawable.shiftshifted)!!.apply {
setTint(onBackground)
}
primaryKeyboardColor = background primaryKeyboardColor = background
keyboardBackground = LayerDrawable(arrayOf( keyboardBackground = coloredRectangle(background)
coloredRectangle(primary),
InsetDrawable(coloredRectangle(background),
0, 1, 0, 0)
))
keyBackground = StateListDrawable().apply { keyBackground = StateListDrawable().apply {
addStateWithHighlightLayerOnPressed(highlight, intArrayOf(android.R.attr.state_active), addStateWithHighlightLayerOnPressed(highlight, intArrayOf(android.R.attr.state_active),
coloredRoundedRectangle(secondary, dp(8.dp)).apply { coloredRoundedRectangle(primary, dp(8.dp)).apply {
setSize(dp(64.dp).toInt(), dp(48.dp).toInt()) setSize(dp(64.dp).toInt(), dp(48.dp).toInt())
} }
) )
@ -209,12 +232,12 @@ class BasicThemeProvider(val context: Context) : KeyboardDrawableProvider {
spaceBarBackground = StateListDrawable().apply { spaceBarBackground = StateListDrawable().apply {
addState(intArrayOf(android.R.attr.state_pressed), addState(intArrayOf(android.R.attr.state_pressed),
LayerDrawable(arrayOf( LayerDrawable(arrayOf(
coloredRoundedRectangle(secondary, dp(32.dp)), coloredRoundedRectangle(highlight, dp(32.dp)),
coloredRoundedRectangle(highlight, dp(32.dp)) coloredRoundedRectangle(highlight, dp(32.dp))
)) ))
) )
addState(intArrayOf(), addState(intArrayOf(),
coloredRoundedRectangle(secondary, dp(32.dp)) coloredRoundedRectangle(highlight, dp(32.dp))
) )
} }
@ -331,6 +354,8 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
setContent() setContent()
latinIMELegacy.setComposeInputView(composeView)
return composeView!! return composeView!!
} }
@ -366,13 +391,20 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
legacyInputView = newView legacyInputView = newView
setContent() setContent()
latinIMELegacy.setComposeInputView(composeView!!) if(composeView != null) {
latinIMELegacy.setComposeInputView(composeView)
}
latinIMELegacy.setInputView(legacyInputView) latinIMELegacy.setInputView(legacyInputView)
} }
override fun setInputView(view: View?) { override fun setInputView(view: View?) {
super.setInputView(view) super.setInputView(view)
latinIMELegacy.setComposeInputView(composeView!!)
if(composeView != null) {
latinIMELegacy.setComposeInputView(composeView)
}
latinIMELegacy.setInputView(legacyInputView) latinIMELegacy.setInputView(legacyInputView)
} }

View File

@ -15,6 +15,8 @@ import androidx.compose.foundation.layout.width
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonColors
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
@ -179,7 +181,7 @@ fun RowScope.SuggestionItem(words: SuggestedWords, idx: Int, isPrimary: Boolean,
val textStyle = when (isPrimary) { val textStyle = when (isPrimary) {
true -> suggestionStylePrimary true -> suggestionStylePrimary
false -> suggestionStyleAlternative false -> suggestionStyleAlternative
}.copy(color = MaterialTheme.colorScheme.onPrimary) }.copy(color = MaterialTheme.colorScheme.onBackground)
TextButton( TextButton(
onClick = onClick, onClick = onClick,
@ -187,7 +189,7 @@ fun RowScope.SuggestionItem(words: SuggestedWords, idx: Int, isPrimary: Boolean,
.weight(1.0f) .weight(1.0f)
.fillMaxHeight(), .fillMaxHeight(),
shape = RectangleShape, shape = RectangleShape,
colors = ButtonDefaults.textButtonColors(contentColor = MaterialTheme.colorScheme.onSurface), colors = ButtonDefaults.textButtonColors(contentColor = MaterialTheme.colorScheme.onBackground),
enabled = word != null enabled = word != null
) { ) {
if(word != null) { if(word != null) {
@ -202,7 +204,7 @@ fun RowScope.SuggestionItem(words: SuggestedWords, idx: Int, isPrimary: Boolean,
.fillMaxHeight(0.66f) .fillMaxHeight(0.66f)
.align(CenterVertically) .align(CenterVertically)
.background(color = MaterialTheme.colorScheme.outline) .background(color = MaterialTheme.colorScheme.outline)
.width((1f / LocalDensity.current.density).dp) .width(1.dp)
) )
} }
@ -255,6 +257,7 @@ data class Action(
@Composable @Composable
fun ActionItem() { fun ActionItem() {
val col = MaterialTheme.colorScheme.secondary val col = MaterialTheme.colorScheme.secondary
val contentCol = MaterialTheme.colorScheme.onSecondary
IconButton(onClick = { /*TODO*/ }, modifier = Modifier IconButton(onClick = { /*TODO*/ }, modifier = Modifier
.drawBehind { .drawBehind {
val radius = size.height / 4.0f val radius = size.height / 4.0f
@ -266,7 +269,9 @@ fun ActionItem() {
) )
} }
.width(50.dp) .width(50.dp)
.fillMaxHeight()) { .fillMaxHeight(),
colors = IconButtonDefaults.iconButtonColors(contentColor = contentCol)
) {
Icon( Icon(
painter = painterResource(id = R.drawable.mic_fill), painter = painterResource(id = R.drawable.mic_fill),
contentDescription = "Voice Input" contentDescription = "Voice Input"
@ -282,7 +287,9 @@ fun RowScope.ActionItems() {
ActionItem() ActionItem()
ActionItem() ActionItem()
Box(modifier = Modifier.fillMaxHeight().weight(1.0f)) { Box(modifier = Modifier
.fillMaxHeight()
.weight(1.0f)) {
AutoFitText("Note: Actions not yet implemented", style = Typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onBackground)) AutoFitText("Note: Actions not yet implemented", style = Typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onBackground))
} }
} }
@ -297,6 +304,13 @@ fun ExpandActionsButton(isActionsOpen: Boolean, onClick: () -> Unit) {
} else { } else {
MaterialTheme.colorScheme.background MaterialTheme.colorScheme.background
} }
val actionsContent = if(isActionsOpen) {
MaterialTheme.colorScheme.onPrimary
} else {
MaterialTheme.colorScheme.onBackground
}
IconButton( IconButton(
onClick = onClick, onClick = onClick,
modifier = Modifier modifier = Modifier
@ -312,7 +326,9 @@ fun ExpandActionsButton(isActionsOpen: Boolean, onClick: () -> Unit) {
.drawBehind { .drawBehind {
drawCircle(color = moreActionsColor, radius = size.width / 3.0f + 1.0f) drawCircle(color = moreActionsColor, radius = size.width / 3.0f + 1.0f)
drawCircle(color = moreActionsFill, radius = size.width / 3.0f - 2.0f) drawCircle(color = moreActionsFill, radius = size.width / 3.0f - 2.0f)
} },
colors = IconButtonDefaults.iconButtonColors(contentColor = actionsContent)
) { ) {
Icon( Icon(
painter = painterResource(id = R.drawable.chevron_right), painter = painterResource(id = R.drawable.chevron_right),

View File

@ -1,11 +1,15 @@
package org.futo.inputmethod.latin.uix.theme package org.futo.inputmethod.latin.uix.theme
import android.app.Activity import android.app.Activity
import android.os.Build
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
@ -42,18 +46,17 @@ val DarkColorScheme = darkColorScheme(
@Composable @Composable
fun WhisperVoiceInputTheme(content: @Composable () -> Unit) { fun WhisperVoiceInputTheme(content: @Composable () -> Unit) {
/* // TODO: Switch light or dark mode
val colorScheme = when { val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) dynamicLightColorScheme(context)
} }
darkTheme -> DarkColorScheme else -> DarkColorScheme
else -> LightColorScheme
} }
*/
val colorScheme = DarkColorScheme // TODO: Figure out light/dynamic if it's worth it //val colorScheme = DarkColorScheme // TODO: Figure out light/dynamic if it's worth it
val view = LocalView.current val view = LocalView.current
@ -72,6 +75,7 @@ fun WhisperVoiceInputTheme(content: @Composable () -> Unit) {
MaterialTheme( MaterialTheme(
colorScheme = colorScheme, colorScheme = colorScheme,
typography = Typography, typography = Typography,
content = content content = content,
) )
} }