mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
Add option to replace emoji key with different action
This commit is contained in:
parent
0b48de4ac9
commit
bf47b3f17c
@ -248,6 +248,9 @@ public final class Constants {
|
||||
// Code value representing the code is not specified.
|
||||
public static final int CODE_UNSPECIFIED = -15;
|
||||
|
||||
public static final int CODE_ACTION_0 = -1050;
|
||||
public static final int CODE_ACTION_MAX = CODE_ACTION_0 + 100;
|
||||
|
||||
public static boolean isLetterCode(final int code) {
|
||||
return code >= CODE_SPACE;
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ public final class KeyboardId {
|
||||
public final EditorInfo mEditorInfo;
|
||||
public final boolean mClobberSettingsKey;
|
||||
public final boolean mBottomEmojiKeyEnabled;
|
||||
public final int mBottomActionKeyId;
|
||||
public final String mCustomActionLabel;
|
||||
public final boolean mHasShortcutKey;
|
||||
public final boolean mIsSplitLayout;
|
||||
@ -95,6 +96,7 @@ public final class KeyboardId {
|
||||
mEditorInfo = params.mEditorInfo;
|
||||
mClobberSettingsKey = params.mNoSettingsKey;
|
||||
mBottomEmojiKeyEnabled = params.mBottomEmojiKeyEnabled;
|
||||
mBottomActionKeyId = params.mBottomActionKeyId;
|
||||
mCustomActionLabel = (mEditorInfo.actionLabel != null)
|
||||
? mEditorInfo.actionLabel.toString() : null;
|
||||
mHasShortcutKey = params.mVoiceInputKeyEnabled;
|
||||
@ -114,6 +116,7 @@ public final class KeyboardId {
|
||||
id.mClobberSettingsKey,
|
||||
id.mHasShortcutKey,
|
||||
id.mBottomEmojiKeyEnabled,
|
||||
id.mBottomActionKeyId,
|
||||
id.isMultiLine(),
|
||||
id.imeAction(),
|
||||
id.mCustomActionLabel,
|
||||
@ -136,6 +139,7 @@ public final class KeyboardId {
|
||||
&& other.mClobberSettingsKey == mClobberSettingsKey
|
||||
&& other.mHasShortcutKey == mHasShortcutKey
|
||||
&& other.mBottomEmojiKeyEnabled == mBottomEmojiKeyEnabled
|
||||
&& other.mBottomActionKeyId == mBottomActionKeyId
|
||||
&& other.isMultiLine() == isMultiLine()
|
||||
&& other.imeAction() == imeAction()
|
||||
&& TextUtils.equals(other.mCustomActionLabel, mCustomActionLabel)
|
||||
|
@ -119,6 +119,7 @@ public final class KeyboardLayoutSet {
|
||||
boolean mVoiceInputKeyEnabled;
|
||||
boolean mNoSettingsKey;
|
||||
boolean mBottomEmojiKeyEnabled;
|
||||
int mBottomActionKeyId;
|
||||
RichInputMethodSubtype mSubtype;
|
||||
boolean mIsSpellChecker;
|
||||
int mKeyboardWidth;
|
||||
@ -324,8 +325,9 @@ public final class KeyboardLayoutSet {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setBottomEmojiKeyEnabled(final boolean enabled) {
|
||||
public Builder setBottomActionKey(final boolean enabled, final int action) {
|
||||
mParams.mBottomEmojiKeyEnabled = enabled;
|
||||
mParams.mBottomActionKeyId = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||
builder.setKeyboardGeometry(keyboardWidth, keyboardHeight);
|
||||
builder.setSubtype(mRichImm.getCurrentSubtype());
|
||||
builder.setVoiceInputKeyEnabled(settingsValues.mShowsVoiceInputKey);
|
||||
builder.setBottomEmojiKeyEnabled(mLatinIMELegacy.shouldShowEmojiKey());
|
||||
builder.setBottomActionKey(settingsValues.mShowsActionKey, settingsValues.mActionKeyId);
|
||||
builder.setSplitLayoutEnabledByUser(ProductionFlags.IS_SPLIT_KEYBOARD_SUPPORTED
|
||||
&& settingsValues.mIsSplitKeyboardEnabled);
|
||||
builder.setNumberRow(settingsValues.mIsNumberRowEnabled);
|
||||
|
@ -171,11 +171,6 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
||||
|
||||
mParams = params;
|
||||
|
||||
mParams.mKeyStyles.addDynamicKeyStyle("bottomEmojiKeyStyle",
|
||||
"!icon/emoji_normal_key|!code/key_emoji",
|
||||
2,
|
||||
2);
|
||||
|
||||
params.GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
|
||||
params.GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
|
||||
}
|
||||
@ -186,6 +181,13 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
||||
|
||||
public KeyboardBuilder<KP> load(final int xmlId, final KeyboardId id) {
|
||||
mParams.mId = id;
|
||||
|
||||
final String actionKeySpec = "!icon/action_" + id.mBottomActionKeyId + "|!code/action_" + id.mBottomActionKeyId;
|
||||
mParams.mKeyStyles.addDynamicKeyStyle("bottomEmojiKeyStyle",
|
||||
actionKeySpec,
|
||||
2,
|
||||
2);
|
||||
|
||||
final XmlResourceParser parser = mResources.getXml(xmlId);
|
||||
try {
|
||||
parseKeyboard(parser);
|
||||
|
@ -16,12 +16,16 @@
|
||||
|
||||
package org.futo.inputmethod.keyboard.internal;
|
||||
|
||||
import static org.futo.inputmethod.latin.common.Constants.CODE_ACTION_0;
|
||||
import static org.futo.inputmethod.latin.common.Constants.CODE_UNSPECIFIED;
|
||||
|
||||
import org.futo.inputmethod.latin.common.Constants;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class KeyboardCodesSet {
|
||||
public static final String PREFIX_CODE = "!code/";
|
||||
public static final String ACTION_CODE_PREFIX = "action_";
|
||||
|
||||
private static final HashMap<String, Integer> sNameToIdMap = new HashMap<>();
|
||||
|
||||
@ -30,6 +34,11 @@ public final class KeyboardCodesSet {
|
||||
}
|
||||
|
||||
public static int getCode(final String name) {
|
||||
if(name.startsWith(ACTION_CODE_PREFIX)) {
|
||||
int id = CODE_ACTION_0 + Integer.parseInt(name.substring(ACTION_CODE_PREFIX.length()));
|
||||
if(id >= CODE_UNSPECIFIED) throw new RuntimeException("Action ID too high!");
|
||||
return id;
|
||||
}
|
||||
Integer id = sNameToIdMap.get(name);
|
||||
if (id == null) throw new RuntimeException("Unknown key code: " + name);
|
||||
return DEFAULT[id];
|
||||
|
@ -532,6 +532,13 @@ public class LatinIMELegacy implements KeyboardActionListener,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void triggerAction(int actionId) {
|
||||
final LatinIMELegacy latinImeLegacy = getOwnerInstance();
|
||||
if (latinImeLegacy != null) {
|
||||
((LatinIME) (latinImeLegacy.getInputMethodService())).getUixManager().triggerAction(actionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static final class SubtypeState {
|
||||
@ -1943,13 +1950,6 @@ public class LatinIMELegacy implements KeyboardActionListener,
|
||||
return mRichImm.shouldOfferSwitchingToNextInputMethod(token, fallbackValue);
|
||||
}
|
||||
|
||||
public boolean shouldShowEmojiKey() {
|
||||
// TODO: Revisit here to reorganize the settings. Probably we can/should use different
|
||||
// strategy once the implementation of
|
||||
// {@link InputMethodManager#shouldOfferSwitchingToNextInputMethod} is defined well.
|
||||
return mSettings.getCurrent().isEmojiKeyEnabled();
|
||||
}
|
||||
|
||||
private void setNavigationBarVisibility(final boolean visible) {
|
||||
((LatinIME)mInputMethodService).updateNavigationBarVisibility(visible);
|
||||
}
|
||||
|
@ -674,6 +674,14 @@ public final class InputLogic {
|
||||
*/
|
||||
private void handleFunctionalEvent(final Event event, final InputTransaction inputTransaction,
|
||||
final int currentKeyboardScriptId, final LatinIMELegacy.UIHandler handler) {
|
||||
|
||||
if(event.mKeyCode <= Constants.CODE_ACTION_MAX && event.mKeyCode >= Constants.CODE_ACTION_0) {
|
||||
final int actionId = event.mKeyCode - Constants.CODE_ACTION_0;
|
||||
handler.triggerAction(actionId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event.mKeyCode) {
|
||||
case Constants.CODE_DELETE:
|
||||
handleBackspaceEvent(event, inputTransaction, currentKeyboardScriptId);
|
||||
|
@ -101,8 +101,9 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||
|
||||
public static final String PREF_ENABLE_METRICS_LOGGING = "pref_enable_metrics_logging";
|
||||
|
||||
public static final String PREF_SHOW_EMOJI_KEY =
|
||||
public static final String PREF_SHOW_ACTION_KEY =
|
||||
"pref_show_emoji_key";
|
||||
public static final String PREF_ACTION_KEY_ID = "pref_action_key_id";
|
||||
|
||||
public static final String PREF_ENABLE_NUMBER_ROW = "pref_enable_number_row";
|
||||
|
||||
@ -261,10 +262,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||
R.integer.config_key_preview_linger_timeout))));
|
||||
}
|
||||
|
||||
public static boolean readShowsEmojiKey(final SharedPreferences prefs) {
|
||||
return prefs.getBoolean(PREF_SHOW_EMOJI_KEY, true);
|
||||
}
|
||||
|
||||
public static String readPrefAdditionalSubtypes(final SharedPreferences prefs,
|
||||
final Resources res) {
|
||||
final String predefinedPrefSubtypes = AdditionalSubtypeUtils.createPrefSubtypes(
|
||||
|
@ -67,7 +67,9 @@ public class SettingsValues {
|
||||
public final boolean mKeyPreviewPopupOn;
|
||||
public final boolean mShowsVoiceInputKey;
|
||||
public final boolean mIncludesOtherImesInLanguageSwitchList;
|
||||
public final boolean mShowsEmojiKey;
|
||||
public final boolean mShowsActionKey;
|
||||
public final int mActionKeyId;
|
||||
|
||||
public final boolean mUseContactsDict;
|
||||
public final boolean mUsePersonalizedDicts;
|
||||
public final boolean mUseDoubleSpacePeriod;
|
||||
@ -142,7 +144,8 @@ public class SettingsValues {
|
||||
mIncludesOtherImesInLanguageSwitchList = Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS
|
||||
? prefs.getBoolean(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false)
|
||||
: true /* forcibly */;
|
||||
mShowsEmojiKey = Settings.readShowsEmojiKey(prefs);
|
||||
mShowsActionKey = prefs.getBoolean(Settings.PREF_SHOW_ACTION_KEY, true);
|
||||
mActionKeyId = prefs.getInt(Settings.PREF_ACTION_KEY_ID, 0);
|
||||
mIsNumberRowEnabled = prefs.getBoolean(Settings.PREF_ENABLE_NUMBER_ROW, false);
|
||||
mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
|
||||
mUsePersonalizedDicts = prefs.getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true);
|
||||
@ -270,10 +273,6 @@ public class SettingsValues {
|
||||
return mInputAttributes.mShouldInsertSpacesAutomatically;
|
||||
}
|
||||
|
||||
public boolean isEmojiKeyEnabled() {
|
||||
return mShowsEmojiKey;
|
||||
}
|
||||
|
||||
public boolean isSameInputType(final EditorInfo editorInfo) {
|
||||
return mInputAttributes.isSameInputType(editorInfo);
|
||||
}
|
||||
@ -384,8 +383,10 @@ public class SettingsValues {
|
||||
sb.append("" + mShowsVoiceInputKey);
|
||||
sb.append("\n mIncludesOtherImesInLanguageSwitchList = ");
|
||||
sb.append("" + mIncludesOtherImesInLanguageSwitchList);
|
||||
sb.append("\n mShowsEmojiKey = ");
|
||||
sb.append("" + mShowsEmojiKey);
|
||||
sb.append("\n mShowsActionKey = ");
|
||||
sb.append("" + mShowsActionKey);
|
||||
sb.append("\n mActionKeyId = ");
|
||||
sb.append("" + mActionKeyId);
|
||||
sb.append("\n mUseContactsDict = ");
|
||||
sb.append("" + mUseContactsDict);
|
||||
sb.append("\n mUsePersonalizedDicts = ");
|
||||
|
@ -24,6 +24,8 @@ import androidx.datastore.preferences.core.floatPreferencesKey
|
||||
import com.google.android.material.color.DynamicColors
|
||||
import org.futo.inputmethod.keyboard.internal.KeyboardIconsSet
|
||||
import org.futo.inputmethod.latin.R
|
||||
import org.futo.inputmethod.latin.uix.actions.ActionRegistry
|
||||
import org.futo.inputmethod.latin.uix.actions.AllActions
|
||||
import org.futo.inputmethod.latin.uix.theme.DarkColorScheme
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@ -270,10 +272,13 @@ class BasicThemeProvider(val context: Context, val overrideColorScheme: ColorSch
|
||||
addIcon(KeyboardIconsSet.NAME_ZWNJ_KEY, R.drawable.sym_keyboard_zwnj_lxx_dark, onBackground)
|
||||
addIcon(KeyboardIconsSet.NAME_ZWJ_KEY, R.drawable.sym_keyboard_zwj_lxx_dark, onPrimary)
|
||||
|
||||
|
||||
addIcon(KeyboardIconsSet.NAME_EMOJI_ACTION_KEY, R.drawable.smile, onPrimary)
|
||||
addIcon(KeyboardIconsSet.NAME_EMOJI_NORMAL_KEY, R.drawable.smile, onBackground)
|
||||
|
||||
AllActions.forEachIndexed { i, it ->
|
||||
addIcon("action_${i}", it.icon, onBackground)
|
||||
}
|
||||
|
||||
// No good replacements for these icons yet, but we set them anyway for setTint
|
||||
overrideDrawable(R.styleable.Keyboard_iconEnterKey, R.drawable.sym_keyboard_return_lxx_light, enterKeyForeground)
|
||||
overrideDrawable(R.styleable.Keyboard_iconGoKey, R.drawable.sym_keyboard_go_lxx_light, enterKeyForeground)
|
||||
|
@ -664,6 +664,14 @@ class UixManager(private val latinIME: LatinIME) {
|
||||
}
|
||||
}
|
||||
|
||||
fun triggerAction(id: Int) {
|
||||
if(currWindowAction == null) {
|
||||
onActionActivated(
|
||||
AllActions.getOrNull(id) ?: throw IllegalArgumentException("No such action with ID $id")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun requestForgetWord(suggestedWordInfo: SuggestedWords.SuggestedWordInfo) {
|
||||
keyboardManagerForAction.requestDialog(
|
||||
latinIME.getString(R.string.blacklist_from_suggestions, suggestedWordInfo.mWord),
|
||||
|
@ -1,12 +1,15 @@
|
||||
package org.futo.inputmethod.latin.uix.settings.pages
|
||||
|
||||
import android.preference.PreferenceManager
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.booleanResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.edit
|
||||
import androidx.datastore.preferences.core.intPreferencesKey
|
||||
import androidx.navigation.NavHostController
|
||||
@ -18,14 +21,18 @@ import org.futo.inputmethod.latin.settings.Settings
|
||||
import org.futo.inputmethod.latin.settings.Settings.PREF_VIBRATION_DURATION_SETTINGS
|
||||
import org.futo.inputmethod.latin.uix.SHOW_EMOJI_SUGGESTIONS
|
||||
import org.futo.inputmethod.latin.uix.SettingsKey
|
||||
import org.futo.inputmethod.latin.uix.actions.AllActions
|
||||
import org.futo.inputmethod.latin.uix.actions.ClipboardHistoryEnabled
|
||||
import org.futo.inputmethod.latin.uix.settings.DropDownPicker
|
||||
import org.futo.inputmethod.latin.uix.settings.ScreenTitle
|
||||
import org.futo.inputmethod.latin.uix.settings.ScrollableList
|
||||
import org.futo.inputmethod.latin.uix.settings.SettingItem
|
||||
import org.futo.inputmethod.latin.uix.settings.SettingSlider
|
||||
import org.futo.inputmethod.latin.uix.settings.SettingSliderSharedPrefsInt
|
||||
import org.futo.inputmethod.latin.uix.settings.SettingToggleDataStore
|
||||
import org.futo.inputmethod.latin.uix.settings.SettingToggleSharedPrefs
|
||||
import org.futo.inputmethod.latin.uix.settings.useDataStore
|
||||
import org.futo.inputmethod.latin.uix.settings.useSharedPrefsInt
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
val vibrationDurationSetting = SettingsKey(
|
||||
@ -75,11 +82,28 @@ fun TypingScreen(navController: NavHostController = rememberNavController()) {
|
||||
)
|
||||
|
||||
SettingToggleSharedPrefs(
|
||||
title = "Emoji key",
|
||||
subtitle = "Show the emoji key on the bottom row",
|
||||
key = Settings.PREF_SHOW_EMOJI_KEY,
|
||||
title = "Action key enabled",
|
||||
subtitle = "Show the action key on the bottom row",
|
||||
key = Settings.PREF_SHOW_ACTION_KEY,
|
||||
default = true
|
||||
)
|
||||
|
||||
val emojiKey = useSharedPrefsInt(key = Settings.PREF_ACTION_KEY_ID, default = 0)
|
||||
SettingItem(title = "Action key") {
|
||||
DropDownPicker(
|
||||
label = "",
|
||||
options = AllActions,
|
||||
selection = AllActions[emojiKey.value],
|
||||
onSet = {
|
||||
emojiKey.setValue(AllActions.indexOf(it))
|
||||
},
|
||||
getDisplayName = {
|
||||
context.getString(it.name)
|
||||
},
|
||||
modifier = Modifier.width(180.dp)
|
||||
)
|
||||
}
|
||||
|
||||
SettingToggleSharedPrefs(
|
||||
title = stringResource(R.string.auto_cap),
|
||||
subtitle = stringResource(R.string.auto_cap_summary),
|
||||
|
Loading…
Reference in New Issue
Block a user