From f91a6269553acb1b78c5588d259e5b65a4df8ec5 Mon Sep 17 00:00:00 2001 From: Aleksandras Kostarevas Date: Tue, 22 Aug 2023 15:36:40 +0300 Subject: [PATCH] Implement Actions, create a theme switcher action window --- java/res/drawable/arrow_left.xml | 20 ++ java/res/drawable/eye.xml | 20 ++ .../keyboard/KeyboardSwitcher.java | 8 +- .../inputmethod/keyboard/KeyboardView.java | 10 +- .../keyboard/MainKeyboardView.java | 10 +- .../internal/KeyPreviewDrawParams.java | 4 +- .../internal/KeyVisualAttributes.java | 24 +- .../keyboard/internal/KeyboardBuilder.java | 14 +- .../keyboard/internal/KeyboardIconsSet.java | 6 +- .../org/futo/inputmethod/latin/LatinIME.kt | 194 +++++++++++++--- .../inputmethod/latin/LatinIMELegacy.java | 3 +- .../org/futo/inputmethod/latin/uix/Action.kt | 27 +++ .../futo/inputmethod/latin/uix/ActionBar.kt | 187 ++++++++++------ .../futo/inputmethod/latin/uix/BaseActions.kt | 211 ++++++++++++++++++ .../futo/inputmethod/latin/uix/theme/Theme.kt | 30 +-- 15 files changed, 605 insertions(+), 163 deletions(-) create mode 100644 java/res/drawable/arrow_left.xml create mode 100644 java/res/drawable/eye.xml create mode 100644 java/src/org/futo/inputmethod/latin/uix/Action.kt create mode 100644 java/src/org/futo/inputmethod/latin/uix/BaseActions.kt diff --git a/java/res/drawable/arrow_left.xml b/java/res/drawable/arrow_left.xml new file mode 100644 index 000000000..f53ed4d37 --- /dev/null +++ b/java/res/drawable/arrow_left.xml @@ -0,0 +1,20 @@ + + + + diff --git a/java/res/drawable/eye.xml b/java/res/drawable/eye.xml new file mode 100644 index 000000000..a3d75c9fb --- /dev/null +++ b/java/res/drawable/eye.xml @@ -0,0 +1,20 @@ + + + + diff --git a/java/src/org/futo/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/org/futo/inputmethod/keyboard/KeyboardSwitcher.java index 7970f8587..624ed2ba7 100644 --- a/java/src/org/futo/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/org/futo/inputmethod/keyboard/KeyboardSwitcher.java @@ -98,13 +98,19 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { } } + private boolean themeSwitchPending = false; + public void queueThemeSwitch() { + themeSwitchPending = true; + } + private boolean updateKeyboardThemeAndContextThemeWrapper(final Context context, final KeyboardTheme keyboardTheme) { - if (mThemeContext == null || !keyboardTheme.equals(mKeyboardTheme) + if (themeSwitchPending || mThemeContext == null || !keyboardTheme.equals(mKeyboardTheme) || !mThemeContext.getResources().equals(context.getResources())) { mKeyboardTheme = keyboardTheme; mThemeContext = new ContextThemeWrapper(context, keyboardTheme.mStyleId); KeyboardLayoutSet.onKeyboardThemeChanged(); + themeSwitchPending = false; return true; } return false; diff --git a/java/src/org/futo/inputmethod/keyboard/KeyboardView.java b/java/src/org/futo/inputmethod/keyboard/KeyboardView.java index 2cc9f9619..116ad922e 100644 --- a/java/src/org/futo/inputmethod/keyboard/KeyboardView.java +++ b/java/src/org/futo/inputmethod/keyboard/KeyboardView.java @@ -35,8 +35,8 @@ import android.view.View; import org.futo.inputmethod.keyboard.internal.KeyDrawParams; import org.futo.inputmethod.keyboard.internal.KeyVisualAttributes; -import org.futo.inputmethod.latin.KeyboardDrawableProvider; -import org.futo.inputmethod.latin.KeyboardDrawableProviderOwner; +import org.futo.inputmethod.latin.DynamicThemeProvider; +import org.futo.inputmethod.latin.DynamicThemeProviderOwner; import org.futo.inputmethod.latin.R; import org.futo.inputmethod.latin.common.Constants; import org.futo.inputmethod.latin.utils.TypefaceUtils; @@ -96,7 +96,7 @@ public class KeyboardView extends View { private final Drawable mKeyBackground; private final Drawable mFunctionalKeyBackground; private final Drawable mSpacebarBackground; - protected final KeyboardDrawableProvider mDrawableProvider; + protected final DynamicThemeProvider mDrawableProvider; private final float mSpacebarIconWidthRatio; private final Rect mKeyBackgroundPadding = new Rect(); private static final float KET_TEXT_SHADOW_RADIUS_DISABLED = -1.0f; @@ -138,9 +138,9 @@ public class KeyboardView extends View { R.styleable.KeyboardView, defStyle, R.style.KeyboardView); assert(context instanceof ContextThemeWrapper); - assert(((ContextThemeWrapper) context).getBaseContext() instanceof KeyboardDrawableProviderOwner); + assert(((ContextThemeWrapper) context).getBaseContext() instanceof DynamicThemeProviderOwner); - mDrawableProvider = ((KeyboardDrawableProviderOwner) ((ContextThemeWrapper) context).getBaseContext()).getDrawableProvider(); + mDrawableProvider = ((DynamicThemeProviderOwner) ((ContextThemeWrapper) context).getBaseContext()).getDrawableProvider(); boolean isMoreKeys = defStyle == R.attr.moreKeysKeyboardViewStyle || defStyle == R.attr.moreKeysKeyboardViewForActionStyle; diff --git a/java/src/org/futo/inputmethod/keyboard/MainKeyboardView.java b/java/src/org/futo/inputmethod/keyboard/MainKeyboardView.java index a8cf07672..b53b4c1eb 100644 --- a/java/src/org/futo/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/org/futo/inputmethod/keyboard/MainKeyboardView.java @@ -28,7 +28,6 @@ import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Typeface; import android.preference.PreferenceManager; -import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; @@ -51,7 +50,7 @@ import org.futo.inputmethod.keyboard.internal.MoreKeySpec; import org.futo.inputmethod.keyboard.internal.NonDistinctMultitouchHelper; import org.futo.inputmethod.keyboard.internal.SlidingKeyInputDrawingPreview; import org.futo.inputmethod.keyboard.internal.TimerHandler; -import org.futo.inputmethod.latin.KeyboardDrawableProvider; +import org.futo.inputmethod.latin.DynamicThemeProvider; import org.futo.inputmethod.latin.R; import org.futo.inputmethod.latin.RichInputMethodSubtype; import org.futo.inputmethod.latin.SuggestedWords; @@ -61,7 +60,6 @@ import org.futo.inputmethod.latin.settings.DebugSettings; import org.futo.inputmethod.latin.utils.LanguageOnSpacebarUtils; import org.futo.inputmethod.latin.utils.TypefaceUtils; -import java.util.Locale; import java.util.WeakHashMap; import javax.annotation.Nonnull; @@ -215,7 +213,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy mBackgroundDimAlphaPaint.setAlpha(backgroundDimAlpha); mLanguageOnSpacebarTextRatio = mainKeyboardViewAttr.getFraction( R.styleable.MainKeyboardView_languageOnSpacebarTextRatio, 1, 1, 1.0f); - mLanguageOnSpacebarTextColor = KeyboardDrawableProvider.Companion.getColorOrDefault( + mLanguageOnSpacebarTextColor = DynamicThemeProvider.Companion.getColorOrDefault( R.styleable.MainKeyboardView_languageOnSpacebarTextColor, 0, mainKeyboardViewAttr, mDrawableProvider ); @@ -461,6 +459,10 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy Log.w(TAG, "Cannot find android.R.id.content view to add DrawingPreviewPlacerView"); return; } + + if(mDrawingPreviewPlacerView.getParent() != null) { + ((ViewGroup)mDrawingPreviewPlacerView.getParent()).removeView(mDrawingPreviewPlacerView); + } windowContentView.addView(mDrawingPreviewPlacerView); } diff --git a/java/src/org/futo/inputmethod/keyboard/internal/KeyPreviewDrawParams.java b/java/src/org/futo/inputmethod/keyboard/internal/KeyPreviewDrawParams.java index c488983ad..93b00b4fd 100644 --- a/java/src/org/futo/inputmethod/keyboard/internal/KeyPreviewDrawParams.java +++ b/java/src/org/futo/inputmethod/keyboard/internal/KeyPreviewDrawParams.java @@ -26,7 +26,7 @@ import android.view.View; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; -import org.futo.inputmethod.latin.KeyboardDrawableProvider; +import org.futo.inputmethod.latin.DynamicThemeProvider; import org.futo.inputmethod.latin.R; public final class KeyPreviewDrawParams { @@ -71,7 +71,7 @@ public final class KeyPreviewDrawParams { // preview background. private int mVisibleOffset; - public KeyPreviewDrawParams(final TypedArray mainKeyboardViewAttr, final KeyboardDrawableProvider provider) { + public KeyPreviewDrawParams(final TypedArray mainKeyboardViewAttr, final DynamicThemeProvider provider) { mPreviewOffset = mainKeyboardViewAttr.getDimensionPixelOffset( R.styleable.MainKeyboardView_keyPreviewOffset, 0); mPreviewHeight = mainKeyboardViewAttr.getDimensionPixelSize( diff --git a/java/src/org/futo/inputmethod/keyboard/internal/KeyVisualAttributes.java b/java/src/org/futo/inputmethod/keyboard/internal/KeyVisualAttributes.java index 10e13e2c8..ad0388369 100644 --- a/java/src/org/futo/inputmethod/keyboard/internal/KeyVisualAttributes.java +++ b/java/src/org/futo/inputmethod/keyboard/internal/KeyVisualAttributes.java @@ -20,7 +20,7 @@ import android.content.res.TypedArray; import android.graphics.Typeface; import android.util.SparseIntArray; -import org.futo.inputmethod.latin.KeyboardDrawableProvider; +import org.futo.inputmethod.latin.DynamicThemeProvider; import org.futo.inputmethod.latin.R; import org.futo.inputmethod.latin.utils.ResourceUtils; @@ -87,7 +87,7 @@ public final class KeyVisualAttributes { } @Nullable - public static KeyVisualAttributes newInstance(@Nonnull final TypedArray keyAttr, @Nullable final KeyboardDrawableProvider provider) { + public static KeyVisualAttributes newInstance(@Nonnull final TypedArray keyAttr, @Nullable final DynamicThemeProvider provider) { final int indexCount = keyAttr.getIndexCount(); for (int i = 0; i < indexCount; i++) { final int attrId = keyAttr.getIndex(i); @@ -99,7 +99,7 @@ public final class KeyVisualAttributes { return null; } - private KeyVisualAttributes(@Nonnull final TypedArray keyAttr, @Nullable final KeyboardDrawableProvider provider) { + private KeyVisualAttributes(@Nonnull final TypedArray keyAttr, @Nullable final DynamicThemeProvider provider) { if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyTypeface)) { mTypeface = Typeface.defaultFromStyle( keyAttr.getInt(R.styleable.Keyboard_Key_keyTypeface, Typeface.NORMAL)); @@ -126,23 +126,23 @@ public final class KeyVisualAttributes { mPreviewTextRatio = ResourceUtils.getFraction(keyAttr, R.styleable.Keyboard_Key_keyPreviewTextRatio); - mTextColor = KeyboardDrawableProvider.Companion.getColorOrDefault( + mTextColor = DynamicThemeProvider.Companion.getColorOrDefault( R.styleable.Keyboard_Key_keyTextColor, 0, keyAttr, provider); - mTextInactivatedColor = KeyboardDrawableProvider.Companion.getColorOrDefault( + mTextInactivatedColor = DynamicThemeProvider.Companion.getColorOrDefault( R.styleable.Keyboard_Key_keyTextInactivatedColor, 0, keyAttr, provider); - mTextShadowColor = KeyboardDrawableProvider.Companion.getColorOrDefault( + mTextShadowColor = DynamicThemeProvider.Companion.getColorOrDefault( R.styleable.Keyboard_Key_keyTextShadowColor, 0, keyAttr, provider); - mFunctionalTextColor = KeyboardDrawableProvider.Companion.getColorOrDefault( + mFunctionalTextColor = DynamicThemeProvider.Companion.getColorOrDefault( R.styleable.Keyboard_Key_functionalTextColor, 0, keyAttr, provider); - mHintLetterColor = KeyboardDrawableProvider.Companion.getColorOrDefault( + mHintLetterColor = DynamicThemeProvider.Companion.getColorOrDefault( R.styleable.Keyboard_Key_keyHintLetterColor, 0, keyAttr, provider); - mHintLabelColor = KeyboardDrawableProvider.Companion.getColorOrDefault( + mHintLabelColor = DynamicThemeProvider.Companion.getColorOrDefault( R.styleable.Keyboard_Key_keyHintLabelColor, 0, keyAttr, provider); - mShiftedLetterHintInactivatedColor = KeyboardDrawableProvider.Companion.getColorOrDefault( + mShiftedLetterHintInactivatedColor = DynamicThemeProvider.Companion.getColorOrDefault( R.styleable.Keyboard_Key_keyShiftedLetterHintInactivatedColor, 0, keyAttr, provider); - mShiftedLetterHintActivatedColor = KeyboardDrawableProvider.Companion.getColorOrDefault( + mShiftedLetterHintActivatedColor = DynamicThemeProvider.Companion.getColorOrDefault( R.styleable.Keyboard_Key_keyShiftedLetterHintActivatedColor, 0, keyAttr, provider); - mPreviewTextColor = KeyboardDrawableProvider.Companion.getColorOrDefault( + mPreviewTextColor = DynamicThemeProvider.Companion.getColorOrDefault( R.styleable.Keyboard_Key_keyPreviewTextColor, 0, keyAttr, provider); mHintLabelVerticalAdjustment = ResourceUtils.getFraction(keyAttr, diff --git a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardBuilder.java index 1c01309d6..9e07dcb5b 100644 --- a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardBuilder.java +++ b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardBuilder.java @@ -33,8 +33,8 @@ import org.futo.inputmethod.keyboard.Key; import org.futo.inputmethod.keyboard.Keyboard; import org.futo.inputmethod.keyboard.KeyboardId; import org.futo.inputmethod.keyboard.KeyboardTheme; -import org.futo.inputmethod.latin.KeyboardDrawableProvider; -import org.futo.inputmethod.latin.KeyboardDrawableProviderOwner; +import org.futo.inputmethod.latin.DynamicThemeProvider; +import org.futo.inputmethod.latin.DynamicThemeProviderOwner; import org.futo.inputmethod.latin.R; import org.futo.inputmethod.latin.common.Constants; import org.futo.inputmethod.latin.common.StringUtils; @@ -153,16 +153,16 @@ public class KeyboardBuilder { private boolean mTopEdge; private Key mRightEdgeKey = null; - private KeyboardDrawableProvider mProvider = null; + private DynamicThemeProvider mProvider = null; public KeyboardBuilder(final Context context, @Nonnull final KP params) { mContext = context; - if(mContext instanceof KeyboardDrawableProviderOwner) { - mProvider = ((KeyboardDrawableProviderOwner) mContext).getDrawableProvider(); + if(mContext instanceof DynamicThemeProviderOwner) { + mProvider = ((DynamicThemeProviderOwner) mContext).getDrawableProvider(); }else if(mContext instanceof ContextThemeWrapper) { Context baseContext = ((ContextThemeWrapper) mContext).getBaseContext(); - if(baseContext instanceof KeyboardDrawableProviderOwner) { - mProvider = ((KeyboardDrawableProviderOwner) baseContext).getDrawableProvider(); + if(baseContext instanceof DynamicThemeProviderOwner) { + mProvider = ((DynamicThemeProviderOwner) baseContext).getDrawableProvider(); } } diff --git a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardIconsSet.java index 92443a579..3e4a1ff9c 100644 --- a/java/src/org/futo/inputmethod/keyboard/internal/KeyboardIconsSet.java +++ b/java/src/org/futo/inputmethod/keyboard/internal/KeyboardIconsSet.java @@ -22,7 +22,7 @@ import android.graphics.drawable.Drawable; import android.util.Log; import android.util.SparseIntArray; -import org.futo.inputmethod.latin.KeyboardDrawableProvider; +import org.futo.inputmethod.latin.DynamicThemeProvider; import org.futo.inputmethod.latin.R; import java.util.HashMap; @@ -108,12 +108,12 @@ public final class KeyboardIconsSet { } } - public void loadIcons(final TypedArray keyboardAttrs, @Nullable KeyboardDrawableProvider provider) { + public void loadIcons(final TypedArray keyboardAttrs, @Nullable DynamicThemeProvider provider) { final int size = ATTR_ID_TO_ICON_ID.size(); for (int index = 0; index < size; index++) { final int attrId = ATTR_ID_TO_ICON_ID.keyAt(index); try { - final Drawable icon = KeyboardDrawableProvider.Companion.getDrawableOrDefault(attrId, keyboardAttrs, provider); + final Drawable icon = DynamicThemeProvider.Companion.getDrawableOrDefault(attrId, keyboardAttrs, provider); setDefaultBounds(icon); final Integer iconId = ATTR_ID_TO_ICON_ID.get(attrId); mIcons[iconId] = icon; diff --git a/java/src/org/futo/inputmethod/latin/LatinIME.kt b/java/src/org/futo/inputmethod/latin/LatinIME.kt index 195a9137d..45d0640bb 100644 --- a/java/src/org/futo/inputmethod/latin/LatinIME.kt +++ b/java/src/org/futo/inputmethod/latin/LatinIME.kt @@ -6,13 +6,11 @@ import android.content.res.TypedArray import android.graphics.Color import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable -import android.graphics.drawable.InsetDrawable import android.graphics.drawable.LayerDrawable import android.graphics.drawable.ShapeDrawable import android.graphics.drawable.StateListDrawable import android.graphics.drawable.shapes.RoundRectShape import android.inputmethodservice.InputMethodService -import android.util.AttributeSet import android.util.TypedValue import android.view.KeyEvent import android.view.View @@ -22,22 +20,34 @@ import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodSubtype import androidx.annotation.ColorInt import androidx.appcompat.content.res.AppCompatResources +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.material3.Button +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface -import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.Text import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.runtime.Composable import androidx.compose.runtime.key +import androidx.compose.ui.Alignment +import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.ViewCompositionStrategy +import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView -import androidx.core.graphics.toColor import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry @@ -53,12 +63,16 @@ import androidx.savedstate.SavedStateRegistryOwner import androidx.savedstate.findViewTreeSavedStateRegistryOwner import androidx.savedstate.setViewTreeSavedStateRegistryOwner import com.google.android.material.color.DynamicColors +import org.futo.inputmethod.latin.common.Constants +import org.futo.inputmethod.latin.uix.Action import org.futo.inputmethod.latin.uix.ActionBar +import org.futo.inputmethod.latin.uix.KeyboardManagerForAction import org.futo.inputmethod.latin.uix.theme.DarkColorScheme +import org.futo.inputmethod.latin.uix.theme.Typography +import org.futo.inputmethod.latin.uix.theme.UixThemeWrapper import kotlin.math.roundToInt - -interface KeyboardDrawableProvider { +interface DynamicThemeProvider { val primaryKeyboardColor: Int val keyboardBackground: Drawable @@ -77,11 +91,11 @@ interface KeyboardDrawableProvider { companion object { @ColorInt - fun getColorOrDefault(i: Int, @ColorInt default: Int, keyAttr: TypedArray, provider: KeyboardDrawableProvider?): Int { + fun getColorOrDefault(i: Int, @ColorInt default: Int, keyAttr: TypedArray, provider: DynamicThemeProvider?): Int { return (provider?.getColor(i)) ?: keyAttr.getColor(i, default) } - fun getDrawableOrDefault(i: Int, keyAttr: TypedArray, provider: KeyboardDrawableProvider?): Drawable? { + fun getDrawableOrDefault(i: Int, keyAttr: TypedArray, provider: DynamicThemeProvider?): Drawable? { return (provider?.getDrawable(i)) ?: keyAttr.getDrawable(i) } } @@ -89,7 +103,7 @@ interface KeyboardDrawableProvider { // 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) : KeyboardDrawableProvider { +class BasicThemeProvider(val context: Context, val overrideColorScheme: ColorScheme? = null) : DynamicThemeProvider { override val primaryKeyboardColor: Int override val keyboardBackground: Drawable @@ -152,7 +166,9 @@ class BasicThemeProvider(val context: Context) : KeyboardDrawableProvider { } init { - val colorScheme = if(!DynamicColors.isDynamicColorAvailable()) { + val colorScheme = if(overrideColorScheme != null) { + overrideColorScheme + }else if(!DynamicColors.isDynamicColorAvailable()) { DarkColorScheme } else { val dCtx = DynamicColors.wrapContextIfAvailable(context) @@ -213,7 +229,7 @@ class BasicThemeProvider(val context: Context) : KeyboardDrawableProvider { ) addStateWithHighlightLayerOnPressed(highlight, intArrayOf(android.R.attr.state_checkable, android.R.attr.state_checked), - coloredRoundedRectangle(secondary, dp(8.dp)) + coloredRoundedRectangle(colorScheme.secondaryContainer.toArgb(), dp(8.dp)) ) addStateWithHighlightLayerOnPressed(highlight, intArrayOf(android.R.attr.state_checkable), @@ -264,20 +280,39 @@ class BasicThemeProvider(val context: Context) : KeyboardDrawableProvider { } -interface KeyboardDrawableProviderOwner { - fun getDrawableProvider(): KeyboardDrawableProvider +interface DynamicThemeProviderOwner { + fun getDrawableProvider(): DynamicThemeProvider } -class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner, LatinIMELegacy.SuggestionStripController, KeyboardDrawableProviderOwner { - private var drawableProvider: KeyboardDrawableProvider? = null - override fun getDrawableProvider(): KeyboardDrawableProvider { + + +class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner, LatinIMELegacy.SuggestionStripController, DynamicThemeProviderOwner, + KeyboardManagerForAction { + private var activeColorScheme = DarkColorScheme + + private var drawableProvider: DynamicThemeProvider? = null + override fun getDrawableProvider(): DynamicThemeProvider { if(drawableProvider == null) { - drawableProvider = BasicThemeProvider(this) + drawableProvider = BasicThemeProvider(this, activeColorScheme) } return drawableProvider!! } + private fun updateDrawableProvider(colorScheme: ColorScheme) { + activeColorScheme = colorScheme + + // ... update drawableProvider with params + drawableProvider = BasicThemeProvider(this, overrideColorScheme = colorScheme) + + // ... force change keyboard view + legacyInputView = latinIMELegacy.onCreateInputView() + latinIMELegacy.loadKeyboard() + setContent() + + window.window?.navigationBarColor = drawableProvider!!.primaryKeyboardColor + } + private val latinIMELegacy = LatinIMELegacy( this as InputMethodService, this as LatinIMELegacy.SuggestionStripController @@ -305,6 +340,15 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save override fun onCreate() { super.onCreate() + + activeColorScheme = if(!DynamicColors.isDynamicColorAvailable()) { + DarkColorScheme + } else { + val dCtx = DynamicColors.wrapContextIfAvailable(this) + + dynamicLightColorScheme(dCtx) + } + mSavedStateRegistryController.performRestore(null) handleLifecycleEvent(Lifecycle.Event.ON_RESUME) @@ -359,26 +403,95 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save return composeView!! } + private var currWindowAction: Action? = null + private fun onActionActivated(action: Action) { + if(action.windowImpl != null) { + currWindowAction = action + setContent() + } else if(action.simplePressImpl != null) { + action.simplePressImpl.invoke(this) + } else { + throw IllegalStateException("An action must have either a window implementation or a simple press implementation") + } + } + + private var inputViewHeight: Int = -1 private var shouldShowSuggestionStrip: Boolean = true private var suggestedWords: SuggestedWords? = null + + @Composable + private fun LegacyKeyboardView() { + key(legacyInputView) { + AndroidView(factory = { + legacyInputView!! + }, update = { }, modifier = Modifier.onSizeChanged { + inputViewHeight = it.height + }) + } + } + + @Composable + private fun MainKeyboardViewWithActionBar() { + Column { + if (shouldShowSuggestionStrip) { + ActionBar( + suggestedWords, + latinIMELegacy, + onActionActivated = { onActionActivated(it) } + ) + } + LegacyKeyboardView() + } + } + + private fun returnBackToMainKeyboardViewFromAction() { + assert(currWindowAction != null) + currWindowAction = null + + setContent() + } + @Composable + private fun ActionViewWithHeader(action: Action) { + val windowImpl = action.windowImpl!! + println("The height is $inputViewHeight, which in DP is ${ with(LocalDensity.current) { inputViewHeight.toDp() }}") + Column { + Surface(modifier = Modifier + .fillMaxWidth() + .height(40.dp), color = MaterialTheme.colorScheme.background) + { + Row { + IconButton(onClick = { + returnBackToMainKeyboardViewFromAction() + }) { + Icon( + painter = painterResource(id = R.drawable.arrow_left), + contentDescription = "Back" + ) + } + + Text(windowImpl.windowName(), style = Typography.titleMedium, modifier = Modifier.align(CenterVertically)) + } + } + + Box(modifier = Modifier + .fillMaxWidth() + .height(with(LocalDensity.current) { inputViewHeight.toDp() })) { + windowImpl.WindowContents(manager = this@LatinIME) + } + } + } + private fun setContent() { composeView?.setContent { - Column { - Spacer(modifier = Modifier.weight(1.0f)) - Surface(modifier = Modifier.onSizeChanged { - touchableHeight = it.height - }, color = MaterialTheme.colorScheme.surface) { - Column { - if(shouldShowSuggestionStrip) { - ActionBar( - suggestedWords, - latinIMELegacy - ) - } - key(legacyInputView) { - AndroidView(factory = { - legacyInputView!! - }, update = { }) + UixThemeWrapper(activeColorScheme) { + Column { + Spacer(modifier = Modifier.weight(1.0f)) + Surface(modifier = Modifier.onSizeChanged { + touchableHeight = it.height + }) { + when { + currWindowAction != null -> ActionViewWithHeader(currWindowAction!!) + else -> MainKeyboardViewWithActionBar() } } } @@ -500,7 +613,7 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save val touchLeft = 0 val touchTop = visibleTopY - val touchRight = legacyInputView!!.width + val touchRight = composeView!!.width val touchBottom = inputHeight latinIMELegacy.setInsets(outInsets!!.apply { @@ -549,4 +662,17 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save override fun maybeShowImportantNoticeTitle(): Boolean { return false } + + override fun triggerSystemVoiceInput() { + latinIMELegacy.onCodeInput( + Constants.CODE_SHORTCUT, + Constants.SUGGESTION_STRIP_COORDINATE, + Constants.SUGGESTION_STRIP_COORDINATE, + false + ); + } + + override fun updateTheme(newTheme: ColorScheme) { + updateDrawableProvider(newTheme) + } } \ No newline at end of file diff --git a/java/src/org/futo/inputmethod/latin/LatinIMELegacy.java b/java/src/org/futo/inputmethod/latin/LatinIMELegacy.java index 92a6e4730..995bc1dbe 100644 --- a/java/src/org/futo/inputmethod/latin/LatinIMELegacy.java +++ b/java/src/org/futo/inputmethod/latin/LatinIMELegacy.java @@ -846,6 +846,7 @@ public class LatinIMELegacy implements KeyboardActionListener, public View onCreateInputView() { StatsUtils.onCreateInputView(); assert mDisplayContext != null; + mKeyboardSwitcher.queueThemeSwitch(); return mKeyboardSwitcher.onCreateInputView(mDisplayContext, mIsHardwareAcceleratedDrawingEnabled); } @@ -1948,7 +1949,7 @@ public class LatinIMELegacy implements KeyboardActionListener, } private void setNavigationBarVisibility(final boolean visible) { - int color = ((KeyboardDrawableProviderOwner)getInputMethodService()).getDrawableProvider().getPrimaryKeyboardColor(); + int color = ((DynamicThemeProviderOwner)getInputMethodService()).getDrawableProvider().getPrimaryKeyboardColor(); if (BuildCompatUtils.EFFECTIVE_SDK_INT > Build.VERSION_CODES.M) { // For N and later, IMEs can specify Color.TRANSPARENT to make the navigation bar // transparent. For other colors the system uses the default color. diff --git a/java/src/org/futo/inputmethod/latin/uix/Action.kt b/java/src/org/futo/inputmethod/latin/uix/Action.kt new file mode 100644 index 000000000..af8a734e3 --- /dev/null +++ b/java/src/org/futo/inputmethod/latin/uix/Action.kt @@ -0,0 +1,27 @@ +package org.futo.inputmethod.latin.uix + +import androidx.annotation.DrawableRes +import androidx.compose.material3.ColorScheme +import androidx.compose.runtime.Composable + + +interface KeyboardManagerForAction { + fun triggerSystemVoiceInput() + + fun updateTheme(newTheme: ColorScheme) +} + +interface ActionWindow { + @Composable + fun windowName(): String + + @Composable + fun WindowContents(manager: KeyboardManagerForAction) +} + +data class Action( + @DrawableRes val icon: Int, + val name: String, // TODO: @StringRes Int + val windowImpl: ActionWindow?, + val simplePressImpl: ((KeyboardManagerForAction) -> Unit)? +) diff --git a/java/src/org/futo/inputmethod/latin/uix/ActionBar.kt b/java/src/org/futo/inputmethod/latin/uix/ActionBar.kt index cbe7331ce..e20b4595f 100644 --- a/java/src/org/futo/inputmethod/latin/uix/ActionBar.kt +++ b/java/src/org/futo/inputmethod/latin/uix/ActionBar.kt @@ -1,9 +1,12 @@ package org.futo.inputmethod.latin.uix -import androidx.annotation.DrawableRes +import android.os.Build import androidx.compose.foundation.Canvas import androidx.compose.foundation.background +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.gestures.scrollable import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.Spacer @@ -12,14 +15,21 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ColorScheme import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.IconButtonColors import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface +import androidx.compose.material3.Text import androidx.compose.material3.TextButton +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -31,10 +41,11 @@ import androidx.compose.ui.draw.rotate import androidx.compose.ui.geometry.CornerRadius import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.drawscope.scale import androidx.compose.ui.graphics.drawscope.translate -import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.ExperimentalTextApi @@ -55,8 +66,8 @@ import org.futo.inputmethod.latin.SuggestedWords.SuggestedWordInfo import org.futo.inputmethod.latin.SuggestedWords.SuggestedWordInfo.KIND_TYPED import org.futo.inputmethod.latin.common.Constants import org.futo.inputmethod.latin.suggestions.SuggestionStripView -import org.futo.inputmethod.latin.uix.theme.Typography -import org.futo.inputmethod.latin.uix.theme.WhisperVoiceInputTheme +import org.futo.inputmethod.latin.uix.theme.DarkColorScheme +import org.futo.inputmethod.latin.uix.theme.UixThemeWrapper import java.lang.Integer.min import kotlin.math.ceil import kotlin.math.roundToInt @@ -249,48 +260,54 @@ fun RowScope.SuggestionItems(words: SuggestedWords, onClick: (i: Int) -> Unit) { } } -data class Action( - @DrawableRes val icon: Int - // TODO: How should the actual action abstraction look? -) - @Composable -fun ActionItem() { +fun ActionItem(action: Action, onSelect: (Action) -> Unit) { val col = MaterialTheme.colorScheme.secondary val contentCol = MaterialTheme.colorScheme.onSecondary - IconButton(onClick = { /*TODO*/ }, modifier = Modifier + IconButton(onClick = { onSelect(action) }, modifier = Modifier .drawBehind { val radius = size.height / 4.0f drawRoundRect( col, - topLeft = Offset(size.width * 0.1f, size.height * 0.1f), - size = Size(size.width * 0.8f, size.height * 0.8f), + topLeft = Offset(size.width * 0.1f, size.height * 0.05f), + size = Size(size.width * 0.8f, size.height * 0.9f), cornerRadius = CornerRadius(radius, radius) ) } - .width(50.dp) + .width(64.dp) .fillMaxHeight(), colors = IconButtonDefaults.iconButtonColors(contentColor = contentCol) ) { Icon( - painter = painterResource(id = R.drawable.mic_fill), - contentDescription = "Voice Input" + painter = painterResource(id = action.icon), + contentDescription = action.name ) } - } @Composable -fun RowScope.ActionItems() { - // TODO - ActionItem() - ActionItem() - ActionItem() +fun ActionItemSmall(action: Action, onSelect: (Action) -> Unit) { + IconButton(onClick = { + onSelect(action) + }, modifier = Modifier + .width(42.dp) + .fillMaxHeight()) { + Icon( + painter = painterResource(id = action.icon), + contentDescription = action.name + ) + } +} + +@Composable +fun RowScope.ActionItems(onSelect: (Action) -> Unit) { + ActionItem(VoiceInputAction, onSelect) + ActionItem(ThemeAction, onSelect) Box(modifier = Modifier .fillMaxHeight() .weight(1.0f)) { - AutoFitText("Note: Actions not yet implemented", style = Typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onBackground)) + } } @@ -341,49 +358,31 @@ fun ExpandActionsButton(isActionsOpen: Boolean, onClick: () -> Unit) { fun ActionBar( words: SuggestedWords?, suggestionStripListener: SuggestionStripView.Listener, - forceOpenActionsInitially: Boolean = false + onActionActivated: (Action) -> Unit, + forceOpenActionsInitially: Boolean = false, ) { val isActionsOpen = remember { mutableStateOf(forceOpenActionsInitially) } - - WhisperVoiceInputTheme { - Surface(modifier = Modifier - .fillMaxWidth() - .height(40.dp), color = MaterialTheme.colorScheme.background) - { - Row { - ExpandActionsButton(isActionsOpen.value) { isActionsOpen.value = !isActionsOpen.value } - if(isActionsOpen.value) { - ActionItems() - } else if(words != null) { - SuggestionItems(words) { - suggestionStripListener.pickSuggestionManually( - words.getInfo(it) - ) - } - } else { - Spacer(modifier = Modifier.weight(1.0f)) - } + Surface(modifier = Modifier + .fillMaxWidth() + .height(40.dp), color = MaterialTheme.colorScheme.background) + { + Row { + ExpandActionsButton(isActionsOpen.value) { isActionsOpen.value = !isActionsOpen.value } - - // TODO: For now, this calls CODE_SHORTCUT. In the future, we will want to - // ask the main UI to hide the keyboard and show our own voice input menu - IconButton(onClick = { - suggestionStripListener.onCodeInput( - Constants.CODE_SHORTCUT, - Constants.SUGGESTION_STRIP_COORDINATE, - Constants.SUGGESTION_STRIP_COORDINATE, - false - ); - }, modifier = Modifier - .width(42.dp) - .fillMaxHeight()) { - Icon( - painter = painterResource(id = R.drawable.mic_fill), - contentDescription = "Voice Input" + if(isActionsOpen.value) { + ActionItems(onActionActivated) + } else if(words != null) { + SuggestionItems(words) { + suggestionStripListener.pickSuggestionManually( + words.getInfo(it) ) } + } else { + Spacer(modifier = Modifier.weight(1.0f)) } + + ActionItemSmall(VoiceInputAction, onActionActivated) } } } @@ -437,18 +436,74 @@ val exampleSuggestedWordsEmpty = SuggestedWords( @Composable @Preview -fun PreviewActionBarWithSuggestions() { - ActionBar(words = exampleSuggestedWords, suggestionStripListener = ExampleListener()) +fun PreviewActionBarWithSuggestions(colorScheme: ColorScheme = DarkColorScheme) { + UixThemeWrapper(colorScheme) { + ActionBar( + words = exampleSuggestedWords, + onActionActivated = { }, + suggestionStripListener = ExampleListener() + ) + } } @Composable @Preview -fun PreviewActionBarWithEmptySuggestions() { - ActionBar(words = exampleSuggestedWordsEmpty, suggestionStripListener = ExampleListener()) +fun PreviewActionBarWithEmptySuggestions(colorScheme: ColorScheme = DarkColorScheme) { + UixThemeWrapper(colorScheme) { + ActionBar( + words = exampleSuggestedWordsEmpty, + onActionActivated = { }, + suggestionStripListener = ExampleListener() + ) + } } @Composable @Preview -fun PreviewExpandedActionBar() { - ActionBar(words = exampleSuggestedWordsEmpty, suggestionStripListener = ExampleListener(), forceOpenActionsInitially = true) +fun PreviewExpandedActionBar(colorScheme: ColorScheme = DarkColorScheme) { + UixThemeWrapper(colorScheme) { + ActionBar( + words = exampleSuggestedWordsEmpty, + onActionActivated = { }, + suggestionStripListener = ExampleListener(), + forceOpenActionsInitially = true + ) + } +} + + +@Composable +@Preview +fun PreviewActionBarWithSuggestionsDynamicLight() { + PreviewActionBarWithSuggestions(dynamicLightColorScheme(LocalContext.current)) +} + +@Composable +@Preview +fun PreviewActionBarWithEmptySuggestionsDynamicLight() { + PreviewActionBarWithEmptySuggestions(dynamicLightColorScheme(LocalContext.current)) +} + +@Composable +@Preview +fun PreviewExpandedActionBarDynamicLight() { + PreviewExpandedActionBar(dynamicLightColorScheme(LocalContext.current)) +} + +@Composable +@Preview +fun PreviewActionBarWithSuggestionsDynamicDark() { + PreviewActionBarWithSuggestions(dynamicDarkColorScheme(LocalContext.current)) +} + +@Composable +@Preview +fun PreviewActionBarWithEmptySuggestionsDynamicDark() { + PreviewActionBarWithEmptySuggestions(dynamicDarkColorScheme(LocalContext.current)) +} + +@Composable +@Preview +fun PreviewExpandedActionBarDynamicDark() { + PreviewExpandedActionBar(dynamicDarkColorScheme(LocalContext.current)) } \ No newline at end of file diff --git a/java/src/org/futo/inputmethod/latin/uix/BaseActions.kt b/java/src/org/futo/inputmethod/latin/uix/BaseActions.kt new file mode 100644 index 000000000..2a761f8d8 --- /dev/null +++ b/java/src/org/futo/inputmethod/latin/uix/BaseActions.kt @@ -0,0 +1,211 @@ +@file:Suppress("LocalVariableName") + +package org.futo.inputmethod.latin.uix + +import android.os.Build +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.gestures.scrollable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.rememberScrollState +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import org.futo.inputmethod.latin.R +import org.futo.inputmethod.latin.uix.theme.DarkColorScheme + + +// TODO: For now, this calls CODE_SHORTCUT. In the future, we will want to +// make this a window +val VoiceInputAction = Action( + icon = R.drawable.mic_fill, + name = "Voice Input", + simplePressImpl = { + it.triggerSystemVoiceInput() + }, + windowImpl = null +) + +val ThemeAction = Action( + icon = R.drawable.eye, + name = "Theme Switcher", + simplePressImpl = null, + windowImpl = object : ActionWindow { + @Composable + override fun windowName(): String { + return "Theme Switcher" + } + + @Composable + override fun WindowContents(manager: KeyboardManagerForAction) { + val context = LocalContext.current + Column(modifier = Modifier.fillMaxSize().scrollable(rememberScrollState(), Orientation.Vertical)) { + Button(onClick = { + manager.updateTheme(DarkColorScheme) + }) { + Text("Default voice input theme") + } + + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + Button(onClick = { + manager.updateTheme(dynamicLightColorScheme(context)) + }) { + Text("Dynamic light color scheme") + } + + Button(onClick = { + manager.updateTheme(dynamicDarkColorScheme(context)) + }) { + Text("Dynamic dark color scheme") + } + } + + + Button(onClick = { + val md_theme_light_primary = Color(0xFF6750A4) + val md_theme_light_onPrimary = Color(0xFFFFFFFF) + val md_theme_light_primaryContainer = Color(0xFFEADDFF) + val md_theme_light_onPrimaryContainer = Color(0xFF21005D) + val md_theme_light_secondary = Color(0xFF625B71) + val md_theme_light_onSecondary = Color(0xFFFFFFFF) + val md_theme_light_secondaryContainer = Color(0xFFE8DEF8) + val md_theme_light_onSecondaryContainer = Color(0xFF1D192B) + val md_theme_light_tertiary = Color(0xFF7D5260) + val md_theme_light_onTertiary = Color(0xFFFFFFFF) + val md_theme_light_tertiaryContainer = Color(0xFFFFD8E4) + val md_theme_light_onTertiaryContainer = Color(0xFF31111D) + val md_theme_light_error = Color(0xFFB3261E) + val md_theme_light_onError = Color(0xFFFFFFFF) + val md_theme_light_errorContainer = Color(0xFFF9DEDC) + val md_theme_light_onErrorContainer = Color(0xFF410E0B) + val md_theme_light_outline = Color(0xFF79747E) + val md_theme_light_background = Color(0xFFFFFBFE) + val md_theme_light_onBackground = Color(0xFF1C1B1F) + val md_theme_light_surface = Color(0xFFFFFBFE) + val md_theme_light_onSurface = Color(0xFF1C1B1F) + val md_theme_light_surfaceVariant = Color(0xFFE7E0EC) + val md_theme_light_onSurfaceVariant = Color(0xFF49454F) + val md_theme_light_inverseSurface = Color(0xFF313033) + val md_theme_light_inverseOnSurface = Color(0xFFF4EFF4) + val md_theme_light_inversePrimary = Color(0xFFD0BCFF) + val md_theme_light_shadow = Color(0xFF000000) + val md_theme_light_surfaceTint = Color(0xFF6750A4) + val md_theme_light_outlineVariant = Color(0xFFCAC4D0) + val md_theme_light_scrim = Color(0xFF000000) + + manager.updateTheme( + lightColorScheme( + primary = md_theme_light_primary, + onPrimary = md_theme_light_onPrimary, + primaryContainer = md_theme_light_primaryContainer, + onPrimaryContainer = md_theme_light_onPrimaryContainer, + secondary = md_theme_light_secondary, + onSecondary = md_theme_light_onSecondary, + secondaryContainer = md_theme_light_secondaryContainer, + onSecondaryContainer = md_theme_light_onSecondaryContainer, + tertiary = md_theme_light_tertiary, + onTertiary = md_theme_light_onTertiary, + tertiaryContainer = md_theme_light_tertiaryContainer, + onTertiaryContainer = md_theme_light_onTertiaryContainer, + error = md_theme_light_error, + onError = md_theme_light_onError, + errorContainer = md_theme_light_errorContainer, + onErrorContainer = md_theme_light_onErrorContainer, + outline = md_theme_light_outline, + background = md_theme_light_background, + onBackground = md_theme_light_onBackground, + surface = md_theme_light_surface, + onSurface = md_theme_light_onSurface, + surfaceVariant = md_theme_light_surfaceVariant, + onSurfaceVariant = md_theme_light_onSurfaceVariant, + inverseSurface = md_theme_light_inverseSurface, + inverseOnSurface = md_theme_light_inverseOnSurface, + inversePrimary = md_theme_light_inversePrimary, + surfaceTint = md_theme_light_surfaceTint, + outlineVariant = md_theme_light_outlineVariant, + scrim = md_theme_light_scrim, + ) + ) + }) { + Text("Some random light theme") + } + + Button(onClick = { + val md_theme_dark_primary = Color(0xFFD0BCFF) + val md_theme_dark_onPrimary = Color(0xFF381E72) + val md_theme_dark_primaryContainer = Color(0xFF4F378B) + val md_theme_dark_onPrimaryContainer = Color(0xFFEADDFF) + val md_theme_dark_secondary = Color(0xFFCCC2DC) + val md_theme_dark_onSecondary = Color(0xFF332D41) + val md_theme_dark_secondaryContainer = Color(0xFF4A4458) + val md_theme_dark_onSecondaryContainer = Color(0xFFE8DEF8) + val md_theme_dark_tertiary = Color(0xFFEFB8C8) + val md_theme_dark_onTertiary = Color(0xFF492532) + val md_theme_dark_tertiaryContainer = Color(0xFF633B48) + val md_theme_dark_onTertiaryContainer = Color(0xFFFFD8E4) + val md_theme_dark_error = Color(0xFFF2B8B5) + val md_theme_dark_onError = Color(0xFF601410) + val md_theme_dark_errorContainer = Color(0xFF8C1D18) + val md_theme_dark_onErrorContainer = Color(0xFFF9DEDC) + val md_theme_dark_outline = Color(0xFF938F99) + val md_theme_dark_background = Color(0xFF1C1B1F) + val md_theme_dark_onBackground = Color(0xFFE6E1E5) + val md_theme_dark_surface = Color(0xFF1C1B1F) + val md_theme_dark_onSurface = Color(0xFFE6E1E5) + val md_theme_dark_surfaceVariant = Color(0xFF49454F) + val md_theme_dark_onSurfaceVariant = Color(0xFFCAC4D0) + val md_theme_dark_inverseSurface = Color(0xFFE6E1E5) + val md_theme_dark_inverseOnSurface = Color(0xFF313033) + val md_theme_dark_inversePrimary = Color(0xFF6750A4) + val md_theme_dark_shadow = Color(0xFF000000) + val md_theme_dark_surfaceTint = Color(0xFFD0BCFF) + val md_theme_dark_outlineVariant = Color(0xFF49454F) + val md_theme_dark_scrim = Color(0xFF000000) + + manager.updateTheme( + darkColorScheme( + primary = md_theme_dark_primary, + onPrimary = md_theme_dark_onPrimary, + primaryContainer = md_theme_dark_primaryContainer, + onPrimaryContainer = md_theme_dark_onPrimaryContainer, + secondary = md_theme_dark_secondary, + onSecondary = md_theme_dark_onSecondary, + secondaryContainer = md_theme_dark_secondaryContainer, + onSecondaryContainer = md_theme_dark_onSecondaryContainer, + tertiary = md_theme_dark_tertiary, + onTertiary = md_theme_dark_onTertiary, + tertiaryContainer = md_theme_dark_tertiaryContainer, + onTertiaryContainer = md_theme_dark_onTertiaryContainer, + error = md_theme_dark_error, + onError = md_theme_dark_onError, + errorContainer = md_theme_dark_errorContainer, + onErrorContainer = md_theme_dark_onErrorContainer, + outline = md_theme_dark_outline, + background = md_theme_dark_background, + onBackground = md_theme_dark_onBackground, + surface = md_theme_dark_surface, + onSurface = md_theme_dark_onSurface, + surfaceVariant = md_theme_dark_surfaceVariant, + onSurfaceVariant = md_theme_dark_onSurfaceVariant, + inverseSurface = md_theme_dark_inverseSurface, + inverseOnSurface = md_theme_dark_inverseOnSurface, + inversePrimary = md_theme_dark_inversePrimary, + surfaceTint = md_theme_dark_surfaceTint, + outlineVariant = md_theme_dark_outlineVariant, + scrim = md_theme_dark_scrim, + ) + ) + }) { + Text("Some random dark theme") + } + } + } + } +) diff --git a/java/src/org/futo/inputmethod/latin/uix/theme/Theme.kt b/java/src/org/futo/inputmethod/latin/uix/theme/Theme.kt index 08896b61f..4c36da67b 100644 --- a/java/src/org/futo/inputmethod/latin/uix/theme/Theme.kt +++ b/java/src/org/futo/inputmethod/latin/uix/theme/Theme.kt @@ -2,6 +2,7 @@ package org.futo.inputmethod.latin.uix.theme import android.app.Activity import android.os.Build +import androidx.compose.material3.ColorScheme import androidx.compose.material3.MaterialTheme import androidx.compose.material3.darkColorScheme import androidx.compose.material3.dynamicDarkColorScheme @@ -45,37 +46,10 @@ val DarkColorScheme = darkColorScheme( ) @Composable -fun WhisperVoiceInputTheme(content: @Composable () -> Unit) { - // TODO: Switch light or dark mode - val colorScheme = when { - Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - val context = LocalContext.current - dynamicLightColorScheme(context) - } - - else -> DarkColorScheme - } - - //val colorScheme = DarkColorScheme // TODO: Figure out light/dynamic if it's worth it - - - val view = LocalView.current - if (!view.isInEditMode) { - SideEffect { - if(view.context is Activity) { - val window = (view.context as Activity).window - window.statusBarColor = colorScheme.primary.toArgb() - WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = - false - } - } - } - - +fun UixThemeWrapper(colorScheme: ColorScheme, content: @Composable () -> Unit) { MaterialTheme( colorScheme = colorScheme, typography = Typography, content = content, - ) } \ No newline at end of file