diff options
author | 2015-09-10 15:51:05 -0700 | |
---|---|---|
committer | 2015-10-15 12:47:32 -0700 | |
commit | 1fdb8f31562eeef78167585a878eb0450310036b (patch) | |
tree | b6aeeb57abce26c843a2c03cf336fdb59650f402 /java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java | |
parent | de674ac02ee0090078f1ec0d286f26ef19cdeebb (diff) | |
download | latinime-1fdb8f31562eeef78167585a878eb0450310036b.tar.gz latinime-1fdb8f31562eeef78167585a878eb0450310036b.tar.xz latinime-1fdb8f31562eeef78167585a878eb0450310036b.zip |
Define shortcuts for toggling IME layouts.
Out of the box, we want Alt-Left to toggle Emojis, while Alt-Right
toggles the shifted symbols layout.
Bug: 23954008
Bug: 24369173
Change-Id: I93dd66fb469e5d0a831359ff3a786fe68e1d73ea
(cherry picked from commit 411841b374aa04e333ea5a438dfd539f49ec589a)
Diffstat (limited to 'java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java | 138 |
1 files changed, 95 insertions, 43 deletions
diff --git a/java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java b/java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java index 2a92daebc..2529424c0 100644 --- a/java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java +++ b/java/src/com/android/inputmethod/latin/EmojiAltPhysicalKeyDetector.java @@ -16,88 +16,140 @@ package com.android.inputmethod.latin; +import android.content.res.Resources; import android.util.Log; import android.view.KeyEvent; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.latin.settings.Settings; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.annotation.Nonnull; + /** * A class for detecting Emoji-Alt physical key. */ final class EmojiAltPhysicalKeyDetector { private static final String TAG = "EmojiAltPhysicalKeyDetector"; - private final RichInputConnection mRichInputConnection; + private final Map<Integer, Integer> mEmojiSwitcherMap; + private final Map<Integer, Integer> mSymbolsShiftedSwitcherMap; + private final Map<Integer, Integer> mCombinedSwitcherMap; - // True if the Alt key has been used as a modifier. In this case the Alt key up isn't - // recognized as an emoji key. - private boolean mAltHasBeenUsedAsAModifier; + // Set of keys codes that have been used as modifiers. + private Set<Integer> mActiveModifiers; - public EmojiAltPhysicalKeyDetector(final RichInputConnection richInputConnection) { - mRichInputConnection = richInputConnection; + public EmojiAltPhysicalKeyDetector(@Nonnull final Resources resources) { + mEmojiSwitcherMap = parseSwitchDefinition(resources, R.array.keyboard_switcher_emoji); + mSymbolsShiftedSwitcherMap = parseSwitchDefinition( + resources, R.array.keyboard_switcher_symbols_shifted); + mCombinedSwitcherMap = new HashMap<>(); + mCombinedSwitcherMap.putAll(mEmojiSwitcherMap); + mCombinedSwitcherMap.putAll(mSymbolsShiftedSwitcherMap); + mActiveModifiers = new HashSet<>(); } - /** - * Record a down key event. - * @param keyEvent a down key event. - */ - public void onKeyDown(final KeyEvent keyEvent) { - if (isAltKey(keyEvent)) { - mAltHasBeenUsedAsAModifier = false; - } - if (containsAltModifier(keyEvent)) { - mAltHasBeenUsedAsAModifier = true; + private static Map<Integer, Integer> parseSwitchDefinition( + @Nonnull final Resources resources, + final int resourceId) { + final Map<Integer, Integer> definition = new HashMap<>(); + final String name = resources.getResourceEntryName(resourceId); + final String[] values = resources.getStringArray(resourceId); + for (int i = 0; values != null && i < values.length; i++) { + String[] valuePair = values[i].split(","); + if (valuePair.length != 2) { + Log.w(TAG, "Expected 2 integers in " + name + "[" + i + "] : " + values[i]); + } + try { + definition.put(Integer.parseInt(valuePair[0]), Integer.parseInt(valuePair[1])); + } catch (NumberFormatException e) { + Log.w(TAG, "Failed to parse " + name + "[" + i + "] : " + values[i], e); + } } + return definition; } /** - * Determine whether an up key event is a special key up or not. + * Determine whether an up key event came from a mapped modifier key. + * * @param keyEvent an up key event. */ - public void onKeyUp(final KeyEvent keyEvent) { + public void onKeyUp(@Nonnull final KeyEvent keyEvent) { + Log.d(TAG, "onKeyUp() : " + keyEvent); + if (!Settings.getInstance().getCurrent().mEnableEmojiAltPhysicalKey) { + // The feature is disabled. + Log.d(TAG, "onKeyUp() : Disabled"); + return; + } if (keyEvent.isCanceled()) { // This key up event was a part of key combinations and should be ignored. + Log.d(TAG, "onKeyUp() : Canceled"); return; } - if (!isAltKey(keyEvent)) { - mAltHasBeenUsedAsAModifier |= containsAltModifier(keyEvent); + final Integer mappedModifier = getMappedModifier(keyEvent); + if (mappedModifier != null) { + // If the key was modified by a mapped key, then ignore the next time + // the same modifier key comes up. + Log.d(TAG, "onKeyUp() : Using Modifier: " + mappedModifier); + mActiveModifiers.add(mappedModifier); return; } - if (containsAltModifier(keyEvent)) { - mAltHasBeenUsedAsAModifier = true; + final int keyCode = keyEvent.getKeyCode(); + if (mActiveModifiers.contains(keyCode)) { + // Used as a modifier, not a standalone key press. + Log.d(TAG, "onKeyUp() : Used as Modifier: " + keyCode); + mActiveModifiers.remove(keyCode); return; } - if (!Settings.getInstance().getCurrent().mEnableEmojiAltPhysicalKey) { + if (!isMappedKeyCode(keyEvent)) { + // Nothing special about this key. + Log.d(TAG, "onKeyUp() : Not Mapped: " + keyCode); return; } - if (mAltHasBeenUsedAsAModifier) { - return; + final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance(); + if (mEmojiSwitcherMap.keySet().contains(keyCode)) { + switcher.onToggleKeyboard(KeyboardSwitcher.KeyboardSwitchState.EMOJI); + } else if (mSymbolsShiftedSwitcherMap.keySet().contains(keyCode)) { + switcher.onToggleKeyboard(KeyboardSwitcher.KeyboardSwitchState.SYMBOLS_SHIFTED); + } else { + Log.w(TAG, "Cannot toggle on keyCode: " + keyCode); } - onEmojiAltKeyDetected(); } - private static void onEmojiAltKeyDetected() { - KeyboardSwitcher.getInstance().onToggleEmojiKeyboard(); + /** + * @param keyEvent pressed key event + * @return true iff the user pressed a mapped modifier key. + */ + private boolean isMappedKeyCode(@Nonnull final KeyEvent keyEvent) { + return mCombinedSwitcherMap.get(keyEvent.getKeyCode()) != null; } - private static boolean isAltKey(final KeyEvent keyEvent) { + /** + * @param keyEvent pressed key event + * @return the mapped modifier used with this key opress, if any. + */ + private Integer getMappedModifier(@Nonnull final KeyEvent keyEvent) { final int keyCode = keyEvent.getKeyCode(); - return keyCode == KeyEvent.KEYCODE_ALT_LEFT || keyCode == KeyEvent.KEYCODE_ALT_RIGHT; - } - - private static boolean containsAltModifier(final KeyEvent keyEvent) { final int metaState = keyEvent.getMetaState(); - // TODO: Support multiple keyboards. Take device id into account. - switch (keyEvent.getKeyCode()) { - case KeyEvent.KEYCODE_ALT_LEFT: - // Return true if Left-Alt is pressed with Right-Alt pressed. - return (metaState & KeyEvent.META_ALT_RIGHT_ON) != 0; - case KeyEvent.KEYCODE_ALT_RIGHT: - // Return true if Right-Alt is pressed with Left-Alt pressed. - return (metaState & KeyEvent.META_ALT_LEFT_ON) != 0; - default: - return (metaState & (KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON)) != 0; + for (int mappedKeyCode : mCombinedSwitcherMap.keySet()) { + if (keyCode == mappedKeyCode) { + Log.d(TAG, "getMappedModifier() : KeyCode = MappedKeyCode = " + mappedKeyCode); + continue; + } + final Integer mappedMeta = mCombinedSwitcherMap.get(mappedKeyCode); + if (mappedMeta == null || mappedMeta.intValue() == -1) { + continue; + } + if ((metaState & mappedMeta) != 0) { + Log.d(TAG, "getMappedModifier() : MetaState(" + metaState + + ") contains MappedMeta(" + mappedMeta + ")"); + return mappedKeyCode; + } } + return null; } } |