mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
Implement Actions, create a theme switcher action window
This commit is contained in:
parent
ad151d7f11
commit
f91a626955
20
java/res/drawable/arrow_left.xml
Normal file
20
java/res/drawable/arrow_left.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="26dp"
|
||||||
|
android:height="26dp"
|
||||||
|
android:viewportWidth="26"
|
||||||
|
android:viewportHeight="26">
|
||||||
|
<path
|
||||||
|
android:pathData="M20,13L6,13"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#FFFFFF"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M13,20L6,13L13,6"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#FFFFFF"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
20
java/res/drawable/eye.xml
Normal file
20
java/res/drawable/eye.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="26dp"
|
||||||
|
android:height="26dp"
|
||||||
|
android:viewportWidth="26"
|
||||||
|
android:viewportHeight="26">
|
||||||
|
<path
|
||||||
|
android:pathData="M2,13C2,13 6,5 13,5C20,5 24,13 24,13C24,13 20,21 13,21C6,21 2,13 2,13ZZ"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#FFFFFF"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M10,13a3,3 0,1 0,6 0a3,3 0,1 0,-6 0z"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#FFFFFF"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
@ -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,
|
private boolean updateKeyboardThemeAndContextThemeWrapper(final Context context,
|
||||||
final KeyboardTheme keyboardTheme) {
|
final KeyboardTheme keyboardTheme) {
|
||||||
if (mThemeContext == null || !keyboardTheme.equals(mKeyboardTheme)
|
if (themeSwitchPending || mThemeContext == null || !keyboardTheme.equals(mKeyboardTheme)
|
||||||
|| !mThemeContext.getResources().equals(context.getResources())) {
|
|| !mThemeContext.getResources().equals(context.getResources())) {
|
||||||
mKeyboardTheme = keyboardTheme;
|
mKeyboardTheme = keyboardTheme;
|
||||||
mThemeContext = new ContextThemeWrapper(context, keyboardTheme.mStyleId);
|
mThemeContext = new ContextThemeWrapper(context, keyboardTheme.mStyleId);
|
||||||
KeyboardLayoutSet.onKeyboardThemeChanged();
|
KeyboardLayoutSet.onKeyboardThemeChanged();
|
||||||
|
themeSwitchPending = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -35,8 +35,8 @@ import android.view.View;
|
|||||||
|
|
||||||
import org.futo.inputmethod.keyboard.internal.KeyDrawParams;
|
import org.futo.inputmethod.keyboard.internal.KeyDrawParams;
|
||||||
import org.futo.inputmethod.keyboard.internal.KeyVisualAttributes;
|
import org.futo.inputmethod.keyboard.internal.KeyVisualAttributes;
|
||||||
import org.futo.inputmethod.latin.KeyboardDrawableProvider;
|
import org.futo.inputmethod.latin.DynamicThemeProvider;
|
||||||
import org.futo.inputmethod.latin.KeyboardDrawableProviderOwner;
|
import org.futo.inputmethod.latin.DynamicThemeProviderOwner;
|
||||||
import org.futo.inputmethod.latin.R;
|
import org.futo.inputmethod.latin.R;
|
||||||
import org.futo.inputmethod.latin.common.Constants;
|
import org.futo.inputmethod.latin.common.Constants;
|
||||||
import org.futo.inputmethod.latin.utils.TypefaceUtils;
|
import org.futo.inputmethod.latin.utils.TypefaceUtils;
|
||||||
@ -96,7 +96,7 @@ public class KeyboardView extends View {
|
|||||||
private final Drawable mKeyBackground;
|
private final Drawable mKeyBackground;
|
||||||
private final Drawable mFunctionalKeyBackground;
|
private final Drawable mFunctionalKeyBackground;
|
||||||
private final Drawable mSpacebarBackground;
|
private final Drawable mSpacebarBackground;
|
||||||
protected final KeyboardDrawableProvider mDrawableProvider;
|
protected final DynamicThemeProvider mDrawableProvider;
|
||||||
private final float mSpacebarIconWidthRatio;
|
private final float mSpacebarIconWidthRatio;
|
||||||
private final Rect mKeyBackgroundPadding = new Rect();
|
private final Rect mKeyBackgroundPadding = new Rect();
|
||||||
private static final float KET_TEXT_SHADOW_RADIUS_DISABLED = -1.0f;
|
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);
|
R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
|
||||||
|
|
||||||
assert(context instanceof ContextThemeWrapper);
|
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;
|
boolean isMoreKeys = defStyle == R.attr.moreKeysKeyboardViewStyle || defStyle == R.attr.moreKeysKeyboardViewForActionStyle;
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ import android.graphics.Paint;
|
|||||||
import android.graphics.Paint.Align;
|
import android.graphics.Paint.Align;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
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.NonDistinctMultitouchHelper;
|
||||||
import org.futo.inputmethod.keyboard.internal.SlidingKeyInputDrawingPreview;
|
import org.futo.inputmethod.keyboard.internal.SlidingKeyInputDrawingPreview;
|
||||||
import org.futo.inputmethod.keyboard.internal.TimerHandler;
|
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.R;
|
||||||
import org.futo.inputmethod.latin.RichInputMethodSubtype;
|
import org.futo.inputmethod.latin.RichInputMethodSubtype;
|
||||||
import org.futo.inputmethod.latin.SuggestedWords;
|
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.LanguageOnSpacebarUtils;
|
||||||
import org.futo.inputmethod.latin.utils.TypefaceUtils;
|
import org.futo.inputmethod.latin.utils.TypefaceUtils;
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -215,7 +213,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
|
|||||||
mBackgroundDimAlphaPaint.setAlpha(backgroundDimAlpha);
|
mBackgroundDimAlphaPaint.setAlpha(backgroundDimAlpha);
|
||||||
mLanguageOnSpacebarTextRatio = mainKeyboardViewAttr.getFraction(
|
mLanguageOnSpacebarTextRatio = mainKeyboardViewAttr.getFraction(
|
||||||
R.styleable.MainKeyboardView_languageOnSpacebarTextRatio, 1, 1, 1.0f);
|
R.styleable.MainKeyboardView_languageOnSpacebarTextRatio, 1, 1, 1.0f);
|
||||||
mLanguageOnSpacebarTextColor = KeyboardDrawableProvider.Companion.getColorOrDefault(
|
mLanguageOnSpacebarTextColor = DynamicThemeProvider.Companion.getColorOrDefault(
|
||||||
R.styleable.MainKeyboardView_languageOnSpacebarTextColor, 0,
|
R.styleable.MainKeyboardView_languageOnSpacebarTextColor, 0,
|
||||||
mainKeyboardViewAttr, mDrawableProvider
|
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");
|
Log.w(TAG, "Cannot find android.R.id.content view to add DrawingPreviewPlacerView");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mDrawingPreviewPlacerView.getParent() != null) {
|
||||||
|
((ViewGroup)mDrawingPreviewPlacerView.getParent()).removeView(mDrawingPreviewPlacerView);
|
||||||
|
}
|
||||||
windowContentView.addView(mDrawingPreviewPlacerView);
|
windowContentView.addView(mDrawingPreviewPlacerView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ import android.view.View;
|
|||||||
import android.view.animation.AccelerateInterpolator;
|
import android.view.animation.AccelerateInterpolator;
|
||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
|
|
||||||
import org.futo.inputmethod.latin.KeyboardDrawableProvider;
|
import org.futo.inputmethod.latin.DynamicThemeProvider;
|
||||||
import org.futo.inputmethod.latin.R;
|
import org.futo.inputmethod.latin.R;
|
||||||
|
|
||||||
public final class KeyPreviewDrawParams {
|
public final class KeyPreviewDrawParams {
|
||||||
@ -71,7 +71,7 @@ public final class KeyPreviewDrawParams {
|
|||||||
// preview background.
|
// preview background.
|
||||||
private int mVisibleOffset;
|
private int mVisibleOffset;
|
||||||
|
|
||||||
public KeyPreviewDrawParams(final TypedArray mainKeyboardViewAttr, final KeyboardDrawableProvider provider) {
|
public KeyPreviewDrawParams(final TypedArray mainKeyboardViewAttr, final DynamicThemeProvider provider) {
|
||||||
mPreviewOffset = mainKeyboardViewAttr.getDimensionPixelOffset(
|
mPreviewOffset = mainKeyboardViewAttr.getDimensionPixelOffset(
|
||||||
R.styleable.MainKeyboardView_keyPreviewOffset, 0);
|
R.styleable.MainKeyboardView_keyPreviewOffset, 0);
|
||||||
mPreviewHeight = mainKeyboardViewAttr.getDimensionPixelSize(
|
mPreviewHeight = mainKeyboardViewAttr.getDimensionPixelSize(
|
||||||
|
@ -20,7 +20,7 @@ import android.content.res.TypedArray;
|
|||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.util.SparseIntArray;
|
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.R;
|
||||||
import org.futo.inputmethod.latin.utils.ResourceUtils;
|
import org.futo.inputmethod.latin.utils.ResourceUtils;
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ public final class KeyVisualAttributes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@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();
|
final int indexCount = keyAttr.getIndexCount();
|
||||||
for (int i = 0; i < indexCount; i++) {
|
for (int i = 0; i < indexCount; i++) {
|
||||||
final int attrId = keyAttr.getIndex(i);
|
final int attrId = keyAttr.getIndex(i);
|
||||||
@ -99,7 +99,7 @@ public final class KeyVisualAttributes {
|
|||||||
return null;
|
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)) {
|
if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyTypeface)) {
|
||||||
mTypeface = Typeface.defaultFromStyle(
|
mTypeface = Typeface.defaultFromStyle(
|
||||||
keyAttr.getInt(R.styleable.Keyboard_Key_keyTypeface, Typeface.NORMAL));
|
keyAttr.getInt(R.styleable.Keyboard_Key_keyTypeface, Typeface.NORMAL));
|
||||||
@ -126,23 +126,23 @@ public final class KeyVisualAttributes {
|
|||||||
mPreviewTextRatio = ResourceUtils.getFraction(keyAttr,
|
mPreviewTextRatio = ResourceUtils.getFraction(keyAttr,
|
||||||
R.styleable.Keyboard_Key_keyPreviewTextRatio);
|
R.styleable.Keyboard_Key_keyPreviewTextRatio);
|
||||||
|
|
||||||
mTextColor = KeyboardDrawableProvider.Companion.getColorOrDefault(
|
mTextColor = DynamicThemeProvider.Companion.getColorOrDefault(
|
||||||
R.styleable.Keyboard_Key_keyTextColor, 0, keyAttr, provider);
|
R.styleable.Keyboard_Key_keyTextColor, 0, keyAttr, provider);
|
||||||
mTextInactivatedColor = KeyboardDrawableProvider.Companion.getColorOrDefault(
|
mTextInactivatedColor = DynamicThemeProvider.Companion.getColorOrDefault(
|
||||||
R.styleable.Keyboard_Key_keyTextInactivatedColor, 0, keyAttr, provider);
|
R.styleable.Keyboard_Key_keyTextInactivatedColor, 0, keyAttr, provider);
|
||||||
mTextShadowColor = KeyboardDrawableProvider.Companion.getColorOrDefault(
|
mTextShadowColor = DynamicThemeProvider.Companion.getColorOrDefault(
|
||||||
R.styleable.Keyboard_Key_keyTextShadowColor, 0, keyAttr, provider);
|
R.styleable.Keyboard_Key_keyTextShadowColor, 0, keyAttr, provider);
|
||||||
mFunctionalTextColor = KeyboardDrawableProvider.Companion.getColorOrDefault(
|
mFunctionalTextColor = DynamicThemeProvider.Companion.getColorOrDefault(
|
||||||
R.styleable.Keyboard_Key_functionalTextColor, 0, keyAttr, provider);
|
R.styleable.Keyboard_Key_functionalTextColor, 0, keyAttr, provider);
|
||||||
mHintLetterColor = KeyboardDrawableProvider.Companion.getColorOrDefault(
|
mHintLetterColor = DynamicThemeProvider.Companion.getColorOrDefault(
|
||||||
R.styleable.Keyboard_Key_keyHintLetterColor, 0, keyAttr, provider);
|
R.styleable.Keyboard_Key_keyHintLetterColor, 0, keyAttr, provider);
|
||||||
mHintLabelColor = KeyboardDrawableProvider.Companion.getColorOrDefault(
|
mHintLabelColor = DynamicThemeProvider.Companion.getColorOrDefault(
|
||||||
R.styleable.Keyboard_Key_keyHintLabelColor, 0, keyAttr, provider);
|
R.styleable.Keyboard_Key_keyHintLabelColor, 0, keyAttr, provider);
|
||||||
mShiftedLetterHintInactivatedColor = KeyboardDrawableProvider.Companion.getColorOrDefault(
|
mShiftedLetterHintInactivatedColor = DynamicThemeProvider.Companion.getColorOrDefault(
|
||||||
R.styleable.Keyboard_Key_keyShiftedLetterHintInactivatedColor, 0, keyAttr, provider);
|
R.styleable.Keyboard_Key_keyShiftedLetterHintInactivatedColor, 0, keyAttr, provider);
|
||||||
mShiftedLetterHintActivatedColor = KeyboardDrawableProvider.Companion.getColorOrDefault(
|
mShiftedLetterHintActivatedColor = DynamicThemeProvider.Companion.getColorOrDefault(
|
||||||
R.styleable.Keyboard_Key_keyShiftedLetterHintActivatedColor, 0, keyAttr, provider);
|
R.styleable.Keyboard_Key_keyShiftedLetterHintActivatedColor, 0, keyAttr, provider);
|
||||||
mPreviewTextColor = KeyboardDrawableProvider.Companion.getColorOrDefault(
|
mPreviewTextColor = DynamicThemeProvider.Companion.getColorOrDefault(
|
||||||
R.styleable.Keyboard_Key_keyPreviewTextColor, 0, keyAttr, provider);
|
R.styleable.Keyboard_Key_keyPreviewTextColor, 0, keyAttr, provider);
|
||||||
|
|
||||||
mHintLabelVerticalAdjustment = ResourceUtils.getFraction(keyAttr,
|
mHintLabelVerticalAdjustment = ResourceUtils.getFraction(keyAttr,
|
||||||
|
@ -33,8 +33,8 @@ import org.futo.inputmethod.keyboard.Key;
|
|||||||
import org.futo.inputmethod.keyboard.Keyboard;
|
import org.futo.inputmethod.keyboard.Keyboard;
|
||||||
import org.futo.inputmethod.keyboard.KeyboardId;
|
import org.futo.inputmethod.keyboard.KeyboardId;
|
||||||
import org.futo.inputmethod.keyboard.KeyboardTheme;
|
import org.futo.inputmethod.keyboard.KeyboardTheme;
|
||||||
import org.futo.inputmethod.latin.KeyboardDrawableProvider;
|
import org.futo.inputmethod.latin.DynamicThemeProvider;
|
||||||
import org.futo.inputmethod.latin.KeyboardDrawableProviderOwner;
|
import org.futo.inputmethod.latin.DynamicThemeProviderOwner;
|
||||||
import org.futo.inputmethod.latin.R;
|
import org.futo.inputmethod.latin.R;
|
||||||
import org.futo.inputmethod.latin.common.Constants;
|
import org.futo.inputmethod.latin.common.Constants;
|
||||||
import org.futo.inputmethod.latin.common.StringUtils;
|
import org.futo.inputmethod.latin.common.StringUtils;
|
||||||
@ -153,16 +153,16 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
|||||||
private boolean mTopEdge;
|
private boolean mTopEdge;
|
||||||
private Key mRightEdgeKey = null;
|
private Key mRightEdgeKey = null;
|
||||||
|
|
||||||
private KeyboardDrawableProvider mProvider = null;
|
private DynamicThemeProvider mProvider = null;
|
||||||
|
|
||||||
public KeyboardBuilder(final Context context, @Nonnull final KP params) {
|
public KeyboardBuilder(final Context context, @Nonnull final KP params) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
if(mContext instanceof KeyboardDrawableProviderOwner) {
|
if(mContext instanceof DynamicThemeProviderOwner) {
|
||||||
mProvider = ((KeyboardDrawableProviderOwner) mContext).getDrawableProvider();
|
mProvider = ((DynamicThemeProviderOwner) mContext).getDrawableProvider();
|
||||||
}else if(mContext instanceof ContextThemeWrapper) {
|
}else if(mContext instanceof ContextThemeWrapper) {
|
||||||
Context baseContext = ((ContextThemeWrapper) mContext).getBaseContext();
|
Context baseContext = ((ContextThemeWrapper) mContext).getBaseContext();
|
||||||
if(baseContext instanceof KeyboardDrawableProviderOwner) {
|
if(baseContext instanceof DynamicThemeProviderOwner) {
|
||||||
mProvider = ((KeyboardDrawableProviderOwner) baseContext).getDrawableProvider();
|
mProvider = ((DynamicThemeProviderOwner) baseContext).getDrawableProvider();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseIntArray;
|
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.R;
|
||||||
|
|
||||||
import java.util.HashMap;
|
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();
|
final int size = ATTR_ID_TO_ICON_ID.size();
|
||||||
for (int index = 0; index < size; index++) {
|
for (int index = 0; index < size; index++) {
|
||||||
final int attrId = ATTR_ID_TO_ICON_ID.keyAt(index);
|
final int attrId = ATTR_ID_TO_ICON_ID.keyAt(index);
|
||||||
try {
|
try {
|
||||||
final Drawable icon = KeyboardDrawableProvider.Companion.getDrawableOrDefault(attrId, keyboardAttrs, provider);
|
final Drawable icon = DynamicThemeProvider.Companion.getDrawableOrDefault(attrId, keyboardAttrs, provider);
|
||||||
setDefaultBounds(icon);
|
setDefaultBounds(icon);
|
||||||
final Integer iconId = ATTR_ID_TO_ICON_ID.get(attrId);
|
final Integer iconId = ATTR_ID_TO_ICON_ID.get(attrId);
|
||||||
mIcons[iconId] = icon;
|
mIcons[iconId] = icon;
|
||||||
|
@ -6,13 +6,11 @@ import android.content.res.TypedArray
|
|||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.graphics.drawable.InsetDrawable
|
|
||||||
import android.graphics.drawable.LayerDrawable
|
import android.graphics.drawable.LayerDrawable
|
||||||
import android.graphics.drawable.ShapeDrawable
|
import android.graphics.drawable.ShapeDrawable
|
||||||
import android.graphics.drawable.StateListDrawable
|
import android.graphics.drawable.StateListDrawable
|
||||||
import android.graphics.drawable.shapes.RoundRectShape
|
import android.graphics.drawable.shapes.RoundRectShape
|
||||||
import android.inputmethodservice.InputMethodService
|
import android.inputmethodservice.InputMethodService
|
||||||
import android.util.AttributeSet
|
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -22,22 +20,34 @@ import android.view.inputmethod.InputMethodManager
|
|||||||
import android.view.inputmethod.InputMethodSubtype
|
import android.view.inputmethod.InputMethodSubtype
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
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.MaterialTheme
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.dynamicDarkColorScheme
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.dynamicLightColorScheme
|
import androidx.compose.material3.dynamicLightColorScheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.key
|
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.Modifier
|
||||||
import androidx.compose.ui.graphics.toArgb
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.layout.onSizeChanged
|
import androidx.compose.ui.layout.onSizeChanged
|
||||||
import androidx.compose.ui.platform.ComposeView
|
import androidx.compose.ui.platform.ComposeView
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
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.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
|
||||||
@ -53,12 +63,16 @@ 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 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.ActionBar
|
||||||
|
import org.futo.inputmethod.latin.uix.KeyboardManagerForAction
|
||||||
import org.futo.inputmethod.latin.uix.theme.DarkColorScheme
|
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
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
interface DynamicThemeProvider {
|
||||||
interface KeyboardDrawableProvider {
|
|
||||||
val primaryKeyboardColor: Int
|
val primaryKeyboardColor: Int
|
||||||
|
|
||||||
val keyboardBackground: Drawable
|
val keyboardBackground: Drawable
|
||||||
@ -77,11 +91,11 @@ interface KeyboardDrawableProvider {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ColorInt
|
@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)
|
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)
|
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
|
// TODO: Expand the number of drawables this provides so it covers the full theme, and
|
||||||
// build some system to dynamically change these colors
|
// 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 primaryKeyboardColor: Int
|
||||||
|
|
||||||
override val keyboardBackground: Drawable
|
override val keyboardBackground: Drawable
|
||||||
@ -152,7 +166,9 @@ class BasicThemeProvider(val context: Context) : KeyboardDrawableProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val colorScheme = if(!DynamicColors.isDynamicColorAvailable()) {
|
val colorScheme = if(overrideColorScheme != null) {
|
||||||
|
overrideColorScheme
|
||||||
|
}else if(!DynamicColors.isDynamicColorAvailable()) {
|
||||||
DarkColorScheme
|
DarkColorScheme
|
||||||
} else {
|
} else {
|
||||||
val dCtx = DynamicColors.wrapContextIfAvailable(context)
|
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),
|
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),
|
addStateWithHighlightLayerOnPressed(highlight, intArrayOf(android.R.attr.state_checkable),
|
||||||
@ -264,20 +280,39 @@ class BasicThemeProvider(val context: Context) : KeyboardDrawableProvider {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KeyboardDrawableProviderOwner {
|
interface DynamicThemeProviderOwner {
|
||||||
fun getDrawableProvider(): KeyboardDrawableProvider
|
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) {
|
if(drawableProvider == null) {
|
||||||
drawableProvider = BasicThemeProvider(this)
|
drawableProvider = BasicThemeProvider(this, activeColorScheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
return drawableProvider!!
|
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(
|
private val latinIMELegacy = LatinIMELegacy(
|
||||||
this as InputMethodService,
|
this as InputMethodService,
|
||||||
this as LatinIMELegacy.SuggestionStripController
|
this as LatinIMELegacy.SuggestionStripController
|
||||||
@ -305,6 +340,15 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
|
|||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
|
||||||
|
activeColorScheme = if(!DynamicColors.isDynamicColorAvailable()) {
|
||||||
|
DarkColorScheme
|
||||||
|
} else {
|
||||||
|
val dCtx = DynamicColors.wrapContextIfAvailable(this)
|
||||||
|
|
||||||
|
dynamicLightColorScheme(dCtx)
|
||||||
|
}
|
||||||
|
|
||||||
mSavedStateRegistryController.performRestore(null)
|
mSavedStateRegistryController.performRestore(null)
|
||||||
handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||||
|
|
||||||
@ -359,26 +403,95 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
|
|||||||
return composeView!!
|
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 shouldShowSuggestionStrip: Boolean = true
|
||||||
private var suggestedWords: SuggestedWords? = null
|
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() {
|
private fun setContent() {
|
||||||
composeView?.setContent {
|
composeView?.setContent {
|
||||||
Column {
|
UixThemeWrapper(activeColorScheme) {
|
||||||
Spacer(modifier = Modifier.weight(1.0f))
|
Column {
|
||||||
Surface(modifier = Modifier.onSizeChanged {
|
Spacer(modifier = Modifier.weight(1.0f))
|
||||||
touchableHeight = it.height
|
Surface(modifier = Modifier.onSizeChanged {
|
||||||
}, color = MaterialTheme.colorScheme.surface) {
|
touchableHeight = it.height
|
||||||
Column {
|
}) {
|
||||||
if(shouldShowSuggestionStrip) {
|
when {
|
||||||
ActionBar(
|
currWindowAction != null -> ActionViewWithHeader(currWindowAction!!)
|
||||||
suggestedWords,
|
else -> MainKeyboardViewWithActionBar()
|
||||||
latinIMELegacy
|
|
||||||
)
|
|
||||||
}
|
|
||||||
key(legacyInputView) {
|
|
||||||
AndroidView(factory = {
|
|
||||||
legacyInputView!!
|
|
||||||
}, update = { })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -500,7 +613,7 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
|
|||||||
|
|
||||||
val touchLeft = 0
|
val touchLeft = 0
|
||||||
val touchTop = visibleTopY
|
val touchTop = visibleTopY
|
||||||
val touchRight = legacyInputView!!.width
|
val touchRight = composeView!!.width
|
||||||
val touchBottom = inputHeight
|
val touchBottom = inputHeight
|
||||||
|
|
||||||
latinIMELegacy.setInsets(outInsets!!.apply {
|
latinIMELegacy.setInsets(outInsets!!.apply {
|
||||||
@ -549,4 +662,17 @@ class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, Save
|
|||||||
override fun maybeShowImportantNoticeTitle(): Boolean {
|
override fun maybeShowImportantNoticeTitle(): Boolean {
|
||||||
return false
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
@ -846,6 +846,7 @@ public class LatinIMELegacy implements KeyboardActionListener,
|
|||||||
public View onCreateInputView() {
|
public View onCreateInputView() {
|
||||||
StatsUtils.onCreateInputView();
|
StatsUtils.onCreateInputView();
|
||||||
assert mDisplayContext != null;
|
assert mDisplayContext != null;
|
||||||
|
mKeyboardSwitcher.queueThemeSwitch();
|
||||||
return mKeyboardSwitcher.onCreateInputView(mDisplayContext,
|
return mKeyboardSwitcher.onCreateInputView(mDisplayContext,
|
||||||
mIsHardwareAcceleratedDrawingEnabled);
|
mIsHardwareAcceleratedDrawingEnabled);
|
||||||
}
|
}
|
||||||
@ -1948,7 +1949,7 @@ public class LatinIMELegacy implements KeyboardActionListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setNavigationBarVisibility(final boolean visible) {
|
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) {
|
if (BuildCompatUtils.EFFECTIVE_SDK_INT > Build.VERSION_CODES.M) {
|
||||||
// For N and later, IMEs can specify Color.TRANSPARENT to make the navigation bar
|
// For N and later, IMEs can specify Color.TRANSPARENT to make the navigation bar
|
||||||
// transparent. For other colors the system uses the default color.
|
// transparent. For other colors the system uses the default color.
|
||||||
|
27
java/src/org/futo/inputmethod/latin/uix/Action.kt
Normal file
27
java/src/org/futo/inputmethod/latin/uix/Action.kt
Normal file
@ -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)?
|
||||||
|
)
|
@ -1,9 +1,12 @@
|
|||||||
package org.futo.inputmethod.latin.uix
|
package org.futo.inputmethod.latin.uix
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import android.os.Build
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.background
|
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.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.foundation.layout.Spacer
|
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.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.width
|
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.ButtonDefaults
|
||||||
|
import androidx.compose.material3.ColorScheme
|
||||||
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.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.Text
|
||||||
import androidx.compose.material3.TextButton
|
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.Composable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
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.CornerRadius
|
||||||
import androidx.compose.ui.geometry.Offset
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.geometry.Size
|
import androidx.compose.ui.geometry.Size
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.RectangleShape
|
import androidx.compose.ui.graphics.RectangleShape
|
||||||
import androidx.compose.ui.graphics.drawscope.scale
|
import androidx.compose.ui.graphics.drawscope.scale
|
||||||
import androidx.compose.ui.graphics.drawscope.translate
|
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.res.painterResource
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.text.ExperimentalTextApi
|
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.SuggestedWords.SuggestedWordInfo.KIND_TYPED
|
||||||
import org.futo.inputmethod.latin.common.Constants
|
import org.futo.inputmethod.latin.common.Constants
|
||||||
import org.futo.inputmethod.latin.suggestions.SuggestionStripView
|
import org.futo.inputmethod.latin.suggestions.SuggestionStripView
|
||||||
import org.futo.inputmethod.latin.uix.theme.Typography
|
import org.futo.inputmethod.latin.uix.theme.DarkColorScheme
|
||||||
import org.futo.inputmethod.latin.uix.theme.WhisperVoiceInputTheme
|
import org.futo.inputmethod.latin.uix.theme.UixThemeWrapper
|
||||||
import java.lang.Integer.min
|
import java.lang.Integer.min
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
import kotlin.math.roundToInt
|
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
|
@Composable
|
||||||
fun ActionItem() {
|
fun ActionItem(action: Action, onSelect: (Action) -> Unit) {
|
||||||
val col = MaterialTheme.colorScheme.secondary
|
val col = MaterialTheme.colorScheme.secondary
|
||||||
val contentCol = MaterialTheme.colorScheme.onSecondary
|
val contentCol = MaterialTheme.colorScheme.onSecondary
|
||||||
IconButton(onClick = { /*TODO*/ }, modifier = Modifier
|
IconButton(onClick = { onSelect(action) }, modifier = Modifier
|
||||||
.drawBehind {
|
.drawBehind {
|
||||||
val radius = size.height / 4.0f
|
val radius = size.height / 4.0f
|
||||||
drawRoundRect(
|
drawRoundRect(
|
||||||
col,
|
col,
|
||||||
topLeft = Offset(size.width * 0.1f, size.height * 0.1f),
|
topLeft = Offset(size.width * 0.1f, size.height * 0.05f),
|
||||||
size = Size(size.width * 0.8f, size.height * 0.8f),
|
size = Size(size.width * 0.8f, size.height * 0.9f),
|
||||||
cornerRadius = CornerRadius(radius, radius)
|
cornerRadius = CornerRadius(radius, radius)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.width(50.dp)
|
.width(64.dp)
|
||||||
.fillMaxHeight(),
|
.fillMaxHeight(),
|
||||||
colors = IconButtonDefaults.iconButtonColors(contentColor = contentCol)
|
colors = IconButtonDefaults.iconButtonColors(contentColor = contentCol)
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(id = R.drawable.mic_fill),
|
painter = painterResource(id = action.icon),
|
||||||
contentDescription = "Voice Input"
|
contentDescription = action.name
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RowScope.ActionItems() {
|
fun ActionItemSmall(action: Action, onSelect: (Action) -> Unit) {
|
||||||
// TODO
|
IconButton(onClick = {
|
||||||
ActionItem()
|
onSelect(action)
|
||||||
ActionItem()
|
}, modifier = Modifier
|
||||||
ActionItem()
|
.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
|
Box(modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.weight(1.0f)) {
|
.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(
|
fun ActionBar(
|
||||||
words: SuggestedWords?,
|
words: SuggestedWords?,
|
||||||
suggestionStripListener: SuggestionStripView.Listener,
|
suggestionStripListener: SuggestionStripView.Listener,
|
||||||
forceOpenActionsInitially: Boolean = false
|
onActionActivated: (Action) -> Unit,
|
||||||
|
forceOpenActionsInitially: Boolean = false,
|
||||||
) {
|
) {
|
||||||
val isActionsOpen = remember { mutableStateOf(forceOpenActionsInitially) }
|
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) {
|
Surface(modifier = Modifier
|
||||||
ActionItems()
|
.fillMaxWidth()
|
||||||
} else if(words != null) {
|
.height(40.dp), color = MaterialTheme.colorScheme.background)
|
||||||
SuggestionItems(words) {
|
{
|
||||||
suggestionStripListener.pickSuggestionManually(
|
Row {
|
||||||
words.getInfo(it)
|
ExpandActionsButton(isActionsOpen.value) { isActionsOpen.value = !isActionsOpen.value }
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Spacer(modifier = Modifier.weight(1.0f))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(isActionsOpen.value) {
|
||||||
// TODO: For now, this calls CODE_SHORTCUT. In the future, we will want to
|
ActionItems(onActionActivated)
|
||||||
// ask the main UI to hide the keyboard and show our own voice input menu
|
} else if(words != null) {
|
||||||
IconButton(onClick = {
|
SuggestionItems(words) {
|
||||||
suggestionStripListener.onCodeInput(
|
suggestionStripListener.pickSuggestionManually(
|
||||||
Constants.CODE_SHORTCUT,
|
words.getInfo(it)
|
||||||
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"
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Spacer(modifier = Modifier.weight(1.0f))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActionItemSmall(VoiceInputAction, onActionActivated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -437,18 +436,74 @@ val exampleSuggestedWordsEmpty = SuggestedWords(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@Preview
|
@Preview
|
||||||
fun PreviewActionBarWithSuggestions() {
|
fun PreviewActionBarWithSuggestions(colorScheme: ColorScheme = DarkColorScheme) {
|
||||||
ActionBar(words = exampleSuggestedWords, suggestionStripListener = ExampleListener())
|
UixThemeWrapper(colorScheme) {
|
||||||
|
ActionBar(
|
||||||
|
words = exampleSuggestedWords,
|
||||||
|
onActionActivated = { },
|
||||||
|
suggestionStripListener = ExampleListener()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@Preview
|
@Preview
|
||||||
fun PreviewActionBarWithEmptySuggestions() {
|
fun PreviewActionBarWithEmptySuggestions(colorScheme: ColorScheme = DarkColorScheme) {
|
||||||
ActionBar(words = exampleSuggestedWordsEmpty, suggestionStripListener = ExampleListener())
|
UixThemeWrapper(colorScheme) {
|
||||||
|
ActionBar(
|
||||||
|
words = exampleSuggestedWordsEmpty,
|
||||||
|
onActionActivated = { },
|
||||||
|
suggestionStripListener = ExampleListener()
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@Preview
|
@Preview
|
||||||
fun PreviewExpandedActionBar() {
|
fun PreviewExpandedActionBar(colorScheme: ColorScheme = DarkColorScheme) {
|
||||||
ActionBar(words = exampleSuggestedWordsEmpty, suggestionStripListener = ExampleListener(), forceOpenActionsInitially = true)
|
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))
|
||||||
}
|
}
|
211
java/src/org/futo/inputmethod/latin/uix/BaseActions.kt
Normal file
211
java/src/org/futo/inputmethod/latin/uix/BaseActions.kt
Normal file
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
@ -2,6 +2,7 @@ package org.futo.inputmethod.latin.uix.theme
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import androidx.compose.material3.ColorScheme
|
||||||
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.dynamicDarkColorScheme
|
||||||
@ -45,37 +46,10 @@ val DarkColorScheme = darkColorScheme(
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun WhisperVoiceInputTheme(content: @Composable () -> Unit) {
|
fun UixThemeWrapper(colorScheme: ColorScheme, 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colorScheme = colorScheme,
|
colorScheme = colorScheme,
|
||||||
typography = Typography,
|
typography = Typography,
|
||||||
content = content,
|
content = content,
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user