diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml index 78217b01a207c30ff2bb553607a0b9e0516daff7..86bd1e6c7e3d6ccceee4736306d42d55c9c60245 100644 --- a/java/res/layout/input_view.xml +++ b/java/res/layout/input_view.xml @@ -20,26 +20,33 @@ <com.android.inputmethod.latin.InputView xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="bottom|center_horizontal" -> - <!-- To ensure that key preview popup is correctly placed when the current system locale is - one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. --> - <com.android.inputmethod.latin.suggestions.SuggestionStripView - android:id="@+id/suggestion_strip_view" - android:layoutDirection="ltr" - android:layout_width="match_parent" - android:layout_height="@dimen/suggestions_strip_height" - android:paddingRight="@dimen/suggestions_strip_padding" - android:paddingLeft="@dimen/suggestions_strip_padding" - style="?attr/suggestionStripViewStyle" /> - <!-- To ensure that key preview popup is correctly placed when the current system locale is - one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. --> - <com.android.inputmethod.keyboard.MainKeyboardView - android:id="@+id/keyboard_view" - android:layoutDirection="ltr" + android:orientation="vertical" > + <include + layout="@layout/emoji_keyboard_view" /> + <LinearLayout + android:id="@+id/main_keyboard_frame" android:layout_width="wrap_content" - android:layout_height="wrap_content" /> + android:layout_height="wrap_content" + android:orientation="vertical" > + <!-- To ensure that key preview popup is correctly placed when the current system locale is + one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. --> + <com.android.inputmethod.latin.suggestions.SuggestionStripView + android:id="@+id/suggestion_strip_view" + android:layoutDirection="ltr" + android:layout_width="match_parent" + android:layout_height="@dimen/suggestions_strip_height" + android:paddingRight="@dimen/suggestions_strip_padding" + android:paddingLeft="@dimen/suggestions_strip_padding" + style="?attr/suggestionStripViewStyle" /> + <!-- To ensure that key preview popup is correctly placed when the current system locale is + one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. --> + <com.android.inputmethod.keyboard.MainKeyboardView + android:id="@+id/keyboard_view" + android:layoutDirection="ltr" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + </LinearLayout> </com.android.inputmethod.latin.InputView> diff --git a/java/res/values/emoji-categories.xml b/java/res/values/emoji-categories.xml index 8f3dead88fc63222fc78cc2913ea4dfeb006b215..ce82a8b40b24e550bd5be48659745e28df3e1122 100644 --- a/java/res/values/emoji-categories.xml +++ b/java/res/values/emoji-categories.xml @@ -36,26 +36,73 @@ name="emoji_nature" format="string" > + <item>2744</item> <!-- SNOWFLAKE --> </array> <array name="emoji_symbols" format="string" > + <item>2460</item> <!-- CIRCLED DIGIT ONE --> + <item>2461</item> <!-- CIRCLED DIGIT TWO --> + <item>2462</item> <!-- CIRCLED DIGIT THREE --> + <item>2463</item> <!-- CIRCLED DIGIT FOUR --> + <item>2464</item> <!-- CIRCLED DIGIT FIVE --> + <item>2465</item> <!-- CIRCLED DIGIT SIX --> + <item>2466</item> <!-- CIRCLED DIGIT SEVEN --> + <item>2467</item> <!-- CIRCLED DIGIT EIGHT --> + <item>2468</item> <!-- CIRCLED DIGIT NINE --> + <item>2469</item> <!-- CIRCLED DIGIT TEN --> + <item>00ae</item> <!-- REGISTERED SIGN --> + <item>00a9</item> <!-- COPYRIGHT SIGN --> + <item>2122</item> <!-- TRADE MARK SIGN --> + <item>2734</item> <!-- EIGHT POINTED BLACK STAR --> + <item>2733</item> <!-- EIGHT POINTED PINWHEEL STAR --> + <item>2716</item> <!-- HEAVY MULTIPLICATION MARK --> + <item>2195</item> <!-- UP DOWN ARROW --> + <item>2197</item> <!-- NORTH EAST ARROW --> + <item>27a1</item> <!-- BLACK RIGHTWARDS ARROW --> + <item>2198</item> <!-- SOUTH EAST ARROW --> + <item>2199</item> <!-- SOUTH WEST ARROW --> + <item>2196</item> <!-- NORTH EAST ARROW --> + <item>2194</item> <!-- LEFT RIGHT ARROW --> + <item>25c0</item> <!-- BLACK LEFT-POINTING TRIANGLE --> + <item>25b6</item> <!-- BLACK ROGHT-POINTING TRIANGLE --> + <item>2747</item> <!-- SPARKLE --> + <item>25aa</item> <!-- BLACK SMALL SQUARE --> + <item>203c</item> <!-- DOUBLE EXCLAMATION MARK --> + <item>2660</item> <!-- BLACK SPADE SUIT --> + <item>2665</item> <!-- BLACK HEART SUIT --> + <item>2663</item> <!-- BLACK CLUB SUIT --> + <item>2666</item> <!-- BLACK DIAMOND SUIT --> + <item>21a9</item> <!-- LEFTWARDS ARROW WITH HOOK --> + <item>21aa</item> <!-- RIGHTWARDS ARROW WITH HOOK --> </array> <array name="emoji_faces" format="string" > + <item>270C</item> <!-- VICTORY HAND --> + <item>2764</item> <!-- HEAVY BLACK HEART --> </array> <array name="emoji_objects" format="string" > + <item>260e</item> <!-- BLACK TELEPHONE --> + <item>2709</item> <!-- ENVELOPE --> + <item>2712</item> <!-- BLACK NIB --> + <item>270f</item> <!-- PENCIL --> + <item>2702</item> <!-- BLACK SCISSORS --> + <item>2669</item> <!-- QUARTER NOTE --> + <item>266a</item> <!-- EIGHTH NOTE --> + <item>266c</item> <!-- BEAMED SIXTEENTH NOTES --> </array> <array name="emoji_places" format="string" > + <item>2708</item> <!-- AIRPLANE --> + <item>2668</item> <!-- HOT SPRINGS --> </array> <array name="emoji_emoticons" diff --git a/java/res/values/themes-common.xml b/java/res/values/themes-common.xml index 473a1257ec7ef7722aa0d773b8e42fc5271f0a98..8e9cfc90bfb08ca581afbfeb5567e6c26a62c526 100644 --- a/java/res/values/themes-common.xml +++ b/java/res/values/themes-common.xml @@ -104,7 +104,14 @@ <style name="MainKeyboardView" parent="KeyboardView" /> - <style name="EmojiKeyboardView" /> + <!-- Though {@link EmojiKeyboardView} doesn't extend {@link KeyboardView}, some views inside it, + for instance delete button, need themed {@link KeyboardView} attributes. --> + <style + name="EmojiKeyboardView" + parent="KeyboardView" + > + <item name="emojiTabLabelColor">@color/emoji_tab_label_color_ics</item> + </style> <style name="MoreKeysKeyboard" /> <style name="MoreKeysKeyboardView" diff --git a/java/res/values/themes-gb.xml b/java/res/values/themes-gb.xml index d39003d949bc20f0ed34fa2bb839c0773a10bb16..7f8dd235b44009b810eb4c532b5569c887fc7c04 100644 --- a/java/res/values/themes-gb.xml +++ b/java/res/values/themes-gb.xml @@ -96,6 +96,8 @@ <item name="spacebarTextColor">@color/spacebar_text_color_gb</item> <item name="spacebarTextShadowColor">@color/spacebar_text_shadow_color_gb</item> </style> + <!-- Though {@link EmojiKeyboardView} doesn't extend {@link KeyboardView}, some views inside it, + for instance delete button, need themed {@link KeyboardView} attributes. --> <style name="EmojiKeyboardView.GB" parent="KeyboardView.GB" diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml index f5b74838bdf22dea2d1ff224446609197fae62e8..f3b6b13212cd09346f2fb945a62c8461655b4bb0 100644 --- a/java/res/values/themes-ics.xml +++ b/java/res/values/themes-ics.xml @@ -97,6 +97,8 @@ <item name="spacebarTextColor">@color/spacebar_text_color_ics</item> <item name="spacebarTextShadowColor">@color/spacebar_text_shadow_color_ics</item> </style> + <!-- Though {@link EmojiKeyboardView} doesn't extend {@link KeyboardView}, some views inside it, + for instance delete button, need themed {@link KeyboardView} attributes. --> <style name="EmojiKeyboardView.ICS" parent="KeyboardView.ICS" diff --git a/java/res/xml-sw600dp/key_f2.xml b/java/res/xml-sw600dp/key_f2.xml index ca3b30b54487cd8b86887e262c161d984f8b153c..56f233da965a1e9d0d482786dcaef90913d445b9 100644 --- a/java/res/xml-sw600dp/key_f2.xml +++ b/java/res/xml-sw600dp/key_f2.xml @@ -39,7 +39,7 @@ </case> <default> <Key - latin:keyStyle="smileyKeyStyle" /> + latin:keyStyle="emojiKeyStyle" /> </default> </switch> </merge> diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml index fc9342b91fb1f7099161f23cd077b98d4253ca3c..3b20281bead809f7dc8d92669b7409acd4f3d372 100644 --- a/java/res/xml-sw600dp/key_styles_common.xml +++ b/java/res/xml-sw600dp/key_styles_common.xml @@ -123,7 +123,8 @@ latin:styleName="emojiKeyStyle" latin:code="!code/key_emoji" latin:keyIcon="!icon/emoji_key" - latin:keyActionFlags="noKeyPreview" /> + latin:keyActionFlags="noKeyPreview" + latin:backgroundType="functional" /> <key-style latin:styleName="settingsKeyStyle" latin:code="!code/key_settings" diff --git a/java/res/xml-sw768dp/key_styles_common.xml b/java/res/xml-sw768dp/key_styles_common.xml index 538930948267ef7722c5b5513ca5d5f54dc9bcb0..5ee9ac591fe6bd4c67a593d4ad156d7c5198c3f3 100644 --- a/java/res/xml-sw768dp/key_styles_common.xml +++ b/java/res/xml-sw768dp/key_styles_common.xml @@ -113,7 +113,8 @@ latin:styleName="emojiKeyStyle" latin:code="!code/key_emoji" latin:keyIcon="!icon/emoji_key" - latin:keyActionFlags="noKeyPreview" /> + latin:keyActionFlags="noKeyPreview" + latin:backgroundType="functional" /> <key-style latin:styleName="settingsKeyStyle" latin:code="!code/key_settings" diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml index dabe1e7eb25e22211978b5d239212b61449478c7..c1c2c3e06b0d2116fc29ecf71d8f3ad8ad5ae283 100644 --- a/java/res/xml/key_styles_common.xml +++ b/java/res/xml/key_styles_common.xml @@ -67,30 +67,6 @@ latin:backgroundType="functional" /> <include latin:keyboardLayout="@xml/key_styles_enter" /> - <switch> - <!-- Shift + Enter in textMultiLine field. --> - <case - latin:isMultiLine="true" - latin:keyboardLayoutSetElement="alphabetManualShifted|alphabetShiftLockShifted" - > - <key-style - latin:styleName="enterKeyStyle" - latin:parentStyle="shiftEnterKeyStyle" /> - </case> - <!-- Smiley in textShortMessage field. - Overrides common enter key style. --> - <case - latin:mode="im" - > - <key-style - latin:styleName="enterKeyStyle" - latin:keyLabel=":-)" - latin:keyOutputText=":-) " - latin:keyLabelFlags="hasPopupHint" - latin:moreKeys="!text/more_keys_for_smiley" - latin:backgroundType="functional" /> - </case> - </switch> <key-style latin:styleName="spaceKeyStyle" latin:code="!code/key_space" @@ -129,7 +105,8 @@ latin:styleName="emojiKeyStyle" latin:code="!code/key_emoji" latin:keyIcon="!icon/emoji_key" - latin:keyActionFlags="noKeyPreview" /> + latin:keyActionFlags="noKeyPreview" + latin:backgroundType="functional" /> <key-style latin:styleName="tabKeyStyle" latin:code="!code/key_tab" diff --git a/java/res/xml/row_symbols4.xml b/java/res/xml/row_symbols4.xml index 5c15da6a5eb90d2f33173228f1d043d03be345da..bea139aba616680ee5a1f0d0cc756cfc46934601 100644 --- a/java/res/xml/row_symbols4.xml +++ b/java/res/xml/row_symbols4.xml @@ -50,7 +50,7 @@ latin:keyboardLayout="@xml/key_symbols_period" latin:backgroundType="functional" /> <Key - latin:keyStyle="enterKeyStyle" + latin:keyStyle="emojiKeyStyle" latin:keyWidth="fillRight" /> </Row> </merge> diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 098c8b3df1c887ca74ff43241dc46e2132d7a1fe..0208249d1bd21810ecb8bb78bba80c9592d38569 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -66,7 +66,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { private SharedPreferences mPrefs; private InputView mCurrentInputView; + private View mMainKeyboardFrame; private MainKeyboardView mKeyboardView; + private EmojiKeyboardView mEmojiKeyboardView; private LatinIME mLatinIME; private Resources mResources; @@ -167,6 +169,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { } private void setKeyboard(final Keyboard keyboard) { + // Make {@link MainKeyboardView} visible and hide {@link EmojiKeyboardView}. + setMainKeyboardFrame(); final MainKeyboardView keyboardView = mKeyboardView; final Keyboard oldKeyboard = keyboardView.getKeyboard(); keyboardView.setKeyboard(keyboard); @@ -253,6 +257,18 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { setKeyboard(mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_SYMBOLS)); } + private void setMainKeyboardFrame() { + mMainKeyboardFrame.setVisibility(View.VISIBLE); + mEmojiKeyboardView.setVisibility(View.GONE); + } + + // Implements {@link KeyboardState.SwitchActions}. + @Override + public void setEmojiKeyboard() { + mMainKeyboardFrame.setVisibility(View.GONE); + mEmojiKeyboardView.setVisibility(View.VISIBLE); + } + // Implements {@link KeyboardState.SwitchActions}. @Override public void requestUpdatingShiftState() { @@ -304,10 +320,16 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { setContextThemeWrapper(mLatinIME, mKeyboardTheme); mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate( R.layout.input_view, null); + mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame); + mEmojiKeyboardView = (EmojiKeyboardView)mCurrentInputView.findViewById( + R.id.emoji_keyboard_view); mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view); mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled); mKeyboardView.setKeyboardActionListener(mLatinIME); + mEmojiKeyboardView.setHardwareAcceleratedDrawingEnabled( + isHardwareAcceleratedDrawingEnabled); + mEmojiKeyboardView.setKeyboardActionListener(mLatinIME); // This always needs to be set since the accessibility state can // potentially change without the input view being re-created. diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java index 0b10a1d1aa26bb854fcbc1137a888e8537a587ac..089db12a2851333b5fea4b06d09da6c59ea9d87a 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java @@ -46,6 +46,7 @@ public final class KeyboardState { public void setAlphabetShiftLockedKeyboard(); public void setAlphabetShiftLockShiftedKeyboard(); public void setSymbolsKeyboard(); + public void setEmojiKeyboard(); /** * Request to call back {@link KeyboardState#onUpdateShiftState(int, int)}. @@ -71,7 +72,10 @@ public final class KeyboardState { private static final int SWITCH_STATE_MOMENTARY_ALPHA_SHIFT = 5; private int mSwitchState = SWITCH_STATE_ALPHA; + // TODO: Consolidate these two mode booleans into one integer to distinguish between alphabet, + // symbols, and emoji mode. private boolean mIsAlphabetMode; + private boolean mIsEmojiMode; private AlphabetShiftState mAlphabetShiftState = new AlphabetShiftState(); private boolean mPrevMainKeyboardWasShiftLocked; private int mRecapitalizeMode; @@ -86,6 +90,7 @@ public final class KeyboardState { public boolean mIsValid; public boolean mIsAlphabetMode; public boolean mIsAlphabetShiftLocked; + public boolean mIsEmojiMode; public int mShiftMode; @Override @@ -94,6 +99,8 @@ public final class KeyboardState { if (mIsAlphabetMode) { if (mIsAlphabetShiftLocked) return "ALPHABET_SHIFT_LOCKED"; return "ALPHABET_" + shiftModeToString(mShiftMode); + } else if (mIsEmojiMode) { + return "EMOJI"; } else { return "SYMBOLS"; } @@ -125,6 +132,7 @@ public final class KeyboardState { public void onSaveKeyboardState() { final SavedKeyboardState state = mSavedKeyboardState; state.mIsAlphabetMode = mIsAlphabetMode; + state.mIsEmojiMode = mIsEmojiMode; if (mIsAlphabetMode) { state.mIsAlphabetShiftLocked = mAlphabetShiftState.isShiftLocked(); state.mShiftMode = mAlphabetShiftState.isAutomaticShifted() ? AUTOMATIC_SHIFT @@ -145,6 +153,8 @@ public final class KeyboardState { } if (!state.mIsValid || state.mIsAlphabetMode) { setAlphabetKeyboard(); + } else if (state.mIsEmojiMode) { + setEmojiKeyboard(); } else { setSymbolsKeyboard(); } @@ -254,6 +264,7 @@ public final class KeyboardState { mSwitchActions.setAlphabetKeyboard(); mIsAlphabetMode = true; + mIsEmojiMode = false; mRecapitalizeMode = RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE; mSwitchState = SWITCH_STATE_ALPHA; mSwitchActions.requestUpdatingShiftState(); @@ -270,6 +281,15 @@ public final class KeyboardState { mSwitchState = SWITCH_STATE_SYMBOL_BEGIN; } + private void setEmojiKeyboard() { + if (DEBUG_ACTION) { + Log.d(TAG, "setEmojiKeyboard"); + } + mIsAlphabetMode = false; + mIsEmojiMode = true; + mSwitchActions.setEmojiKeyboard(); + } + public void onPressKey(final int code, final boolean isSinglePointer, final int autoCaps) { if (DEBUG_EVENT) { Log.d(TAG, "onPressKey: code=" + Constants.printableCode(code) @@ -547,6 +567,8 @@ public final class KeyboardState { // If the code is a letter, update keyboard shift state. if (Constants.isLetterCode(code)) { updateAlphabetShiftState(autoCaps, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE); + } else if (code == Constants.CODE_EMOJI) { + setEmojiKeyboard(); } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index de4baf948934d9cc5460e9b85013b286d6c90845..27a1739b9f5c847df2b47115a734baa4b8e60c23 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1532,7 +1532,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen handleLanguageSwitchKey(); break; case Constants.CODE_EMOJI: - // TODO: Implement emoji keyboard switch. + // Note: Switching emoji keyboard is being handled in + // {@link KeyboardState#onCodeInput(int,int)}. break; case Constants.CODE_ENTER: final EditorInfo editorInfo = getCurrentInputEditorInfo(); diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java index 682d8fc634ea7449145c4a172ca07699a72d10de..b209b00853014cacc6fe6961c158b6b2e2170e5b 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java @@ -112,6 +112,11 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions { mLayout = MockConstants.SYMBOLS; } + @Override + public void setEmojiKeyboard() { + // Just ignore. + } + @Override public void requestUpdatingShiftState() { mState.onUpdateShiftState(mAutoCapsState, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE);