diff options
Diffstat (limited to 'java')
22 files changed, 377 insertions, 339 deletions
diff --git a/java/res/anim/key_preview_fadein.xml b/java/res/anim/key_preview_fadein.xml deleted file mode 100644 index 9fad7b9a7..000000000 --- a/java/res/anim/key_preview_fadein.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2010, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<set - xmlns:android="http://schemas.android.com/apk/res/android" - android:interpolator="@android:anim/decelerate_interpolator" -> - <alpha - android:fromAlpha="0.5" - android:toAlpha="1.0" - android:duration="@integer/config_preview_fadein_anim_time" /> -</set> diff --git a/java/res/anim/key_preview_fadeout.xml b/java/res/anim/key_preview_fadeout.xml deleted file mode 100644 index 7de5123cd..000000000 --- a/java/res/anim/key_preview_fadeout.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2010, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ ---> - -<set - xmlns:android="http://schemas.android.com/apk/res/android" - android:interpolator="@android:anim/accelerate_interpolator" -> - <alpha - android:fromAlpha="1.0" - android:toAlpha="0.0" - android:duration="@integer/config_preview_fadeout_anim_time" /> -</set> diff --git a/java/res/anim/mini_keyboard_fadein.xml b/java/res/anim/mini_keyboard_fadein.xml index 9fad7b9a7..f80e8b8de 100644 --- a/java/res/anim/mini_keyboard_fadein.xml +++ b/java/res/anim/mini_keyboard_fadein.xml @@ -25,5 +25,5 @@ <alpha android:fromAlpha="0.5" android:toAlpha="1.0" - android:duration="@integer/config_preview_fadein_anim_time" /> + android:duration="@integer/config_mini_keyboard_fadein_anim_time" /> </set> diff --git a/java/res/anim/mini_keyboard_fadeout.xml b/java/res/anim/mini_keyboard_fadeout.xml index 7de5123cd..535b100ae 100644 --- a/java/res/anim/mini_keyboard_fadeout.xml +++ b/java/res/anim/mini_keyboard_fadeout.xml @@ -25,5 +25,5 @@ <alpha android:fromAlpha="1.0" android:toAlpha="0.0" - android:duration="@integer/config_preview_fadeout_anim_time" /> + android:duration="@integer/config_mini_keyboard_fadeout_anim_time" /> </set> diff --git a/java/res/layout-xlarge/candidates.xml b/java/res/layout-xlarge/candidates.xml index d10035c9c..9d6cd241c 100644 --- a/java/res/layout-xlarge/candidates.xml +++ b/java/res/layout-xlarge/candidates.xml @@ -21,25 +21,33 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" + android:gravity="bottom" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/keyboard_suggest_strip_holo" - android:paddingRight="@dimen/candidate_strip_padding" - android:paddingLeft="@dimen/candidate_strip_padding" + android:minHeight="@dimen/candidate_strip_minimum_height" > - <HorizontalScrollView - android:id="@+id/candidates_scroll_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:fadingEdge="horizontal" - android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length" - android:scrollbars="none" + <!-- On tablets, the candidate strip is centered with horizontal paddings on both sides because + width of the landscape mode is too long for the candidate strip. This LinearLayout is + required to hold the paddings. --> + <LinearLayout + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="@dimen/candidate_strip_height" + android:background="@drawable/keyboard_suggest_strip_holo" + android:paddingRight="@dimen/candidate_strip_padding" + android:paddingLeft="@dimen/candidate_strip_padding" > - <com.android.inputmethod.latin.CandidateView - android:id="@+id/candidates" - android:orientation="horizontal" + <HorizontalScrollView android:layout_width="match_parent" - android:layout_height="@dimen/candidate_strip_height" - android:background="@drawable/keyboard_suggest_strip_holo" /> - </HorizontalScrollView> + android:layout_height="match_parent" + android:fadingEdge="horizontal" + android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length" + android:scrollbars="none" + > + <com.android.inputmethod.latin.CandidateView + android:id="@+id/candidates" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + </HorizontalScrollView> + </LinearLayout> </LinearLayout> diff --git a/java/res/layout/candidates.xml b/java/res/layout/candidates.xml index 794c4ed42..39e39a1b7 100644 --- a/java/res/layout/candidates.xml +++ b/java/res/layout/candidates.xml @@ -21,25 +21,24 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" + android:gravity="bottom" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/keyboard_suggest_strip" + android:minHeight="@dimen/candidate_strip_minimum_height" android:paddingRight="@dimen/candidate_strip_padding" android:paddingLeft="@dimen/candidate_strip_padding" > <HorizontalScrollView - android:id="@+id/candidates_scroll_view" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_width="match_parent" + android:layout_height="@dimen/candidate_strip_height" + android:background="@drawable/keyboard_suggest_strip" android:fadingEdge="horizontal" android:fadingEdgeLength="@dimen/candidate_strip_fading_edge_length" android:scrollbars="none" > <com.android.inputmethod.latin.CandidateView android:id="@+id/candidates" - android:orientation="horizontal" android:layout_width="match_parent" - android:layout_height="@dimen/candidate_strip_height" - android:background="@drawable/keyboard_suggest_strip" /> + android:layout_height="match_parent" /> </HorizontalScrollView> </LinearLayout> diff --git a/java/res/values-xlarge/dimens.xml b/java/res/values-xlarge/dimens.xml index 0dc5621ff..9bb50f62a 100644 --- a/java/res/values-xlarge/dimens.xml +++ b/java/res/values-xlarge/dimens.xml @@ -46,6 +46,9 @@ <dimen name="key_preview_offset_holo">8.0mm</dimen> <dimen name="candidate_strip_height">46dip</dimen> + <!-- candidate_strip_minimum_height = + key_preview_height_holo - key_preview_offset_holo + alpha --> + <dimen name="candidate_strip_minimum_height">18mm</dimen> <dimen name="candidate_strip_padding">15.0mm</dimen> <dimen name="candidate_min_width">0.3in</dimen> <dimen name="candidate_padding">12dip</dimen> diff --git a/java/res/values/config.xml b/java/res/values/config.xml index bdb4409f0..32fb5bf1a 100644 --- a/java/res/values/config.xml +++ b/java/res/values/config.xml @@ -49,8 +49,6 @@ <integer name="config_final_fadeout_percentage_of_language_on_spacebar">15</integer> <integer name="config_delay_before_preview">0</integer> <integer name="config_delay_after_preview">10</integer> - <integer name="config_preview_fadein_anim_time">0</integer> - <integer name="config_preview_fadeout_anim_time">70</integer> <integer name="config_mini_keyboard_fadein_anim_time">0</integer> <integer name="config_mini_keyboard_fadeout_anim_time">100</integer> <integer name="config_delay_before_key_repeat_start">400</integer> diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index 767dc4aa9..0a0b16d47 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -52,6 +52,9 @@ <dimen name="key_preview_offset_holo">0.193in</dimen> <dimen name="candidate_strip_height">42dip</dimen> + <!-- candidate_strip_minimum_height = + key_preview_height_holo - key_preview_offset_holo + alpha --> + <dimen name="candidate_strip_minimum_height">100sp</dimen> <dimen name="candidate_strip_fading_edge_length">63dip</dimen> <dimen name="candidate_strip_padding">0dip</dimen> <dimen name="candidate_min_width">0.3in</dimen> diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml index 130714fd3..ef48a4bd2 100644 --- a/java/res/values/styles.xml +++ b/java/res/values/styles.xml @@ -35,10 +35,6 @@ <item name="backgroundDimAmount">0.5</item> <item name="colorScheme">white</item> </style> - <style name="KeyPreviewAnimation"> - <item name="android:windowEnterAnimation">@anim/key_preview_fadein</item> - <item name="android:windowExitAnimation">@anim/key_preview_fadeout</item> - </style> <style name="MiniKeyboardAnimation"> <item name="android:windowEnterAnimation">@anim/mini_keyboard_fadein</item> <item name="android:windowExitAnimation">@anim/mini_keyboard_fadeout</item> diff --git a/java/res/xml/kbd_ar_rows.xml b/java/res/xml/kbd_ar_rows.xml index 4b490f18b..d5264fd2d 100644 --- a/java/res/xml/kbd_ar_rows.xml +++ b/java/res/xml/kbd_ar_rows.xml @@ -51,8 +51,8 @@ <Key latin:keyLabel="ح" /> <Key - latin:keyLabel="چ" - latin:popupCharacters="ج" + latin:keyLabel="ج" + latin:popupCharacters="چ" latin:keyEdgeFlags="right" /> </Row> <Row @@ -65,7 +65,7 @@ latin:keyLabel="س" /> <Key latin:keyLabel="ي" - latin:popupCharacters="ئ,ى" /> + latin:popupCharacters="ى,ئ" /> <Key latin:keyLabel="ب" latin:popupCharacters="پ" /> @@ -74,7 +74,7 @@ latin:popupCharacters="لا" /> <Key latin:keyLabel="ا" - latin:popupCharacters="ء,آ,إ,أ" /> + latin:popupCharacters="أ,إ,آ,ء" /> <Key latin:keyLabel="ت" /> <Key diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java index 80586b753..e7eaba2d8 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java @@ -16,6 +16,7 @@ package com.android.inputmethod.compat; +import com.android.inputmethod.deprecated.LanguageSwitcherProxy; import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.Utils; @@ -56,6 +57,14 @@ public class InputMethodManagerCompatWrapper { private static final InputMethodManagerCompatWrapper sInstance = new InputMethodManagerCompatWrapper(); + public static final boolean SUBTYPE_SUPPORTED; + + static { + // This static initializer guarantees that METHOD_getShortcutInputMethodsAndSubtypes is + // already instantiated. + SUBTYPE_SUPPORTED = METHOD_getShortcutInputMethodsAndSubtypes != null; + } + // For the compatibility, IMM will create dummy subtypes if subtypes are not found. // This is required to be false if the current behavior is broken. For now, it's ok to be true. private static final boolean ALLOW_DUMMY_SUBTYPE = true; @@ -64,7 +73,9 @@ public class InputMethodManagerCompatWrapper { private static final String KEYBOARD_MODE = "keyboard"; private InputMethodManager mImm; + private LanguageSwitcherProxy mLanguageSwitcherProxy; private String mLatinImePackageName; + private InputMethodManagerCompatWrapper() { } @@ -81,15 +92,29 @@ public class InputMethodManagerCompatWrapper { if (context instanceof LatinIME) { mLatinImePackageName = context.getPackageName(); } + mLanguageSwitcherProxy = LanguageSwitcherProxy.getInstance(); } public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() { + if (!SUBTYPE_SUPPORTED) { + return new InputMethodSubtypeCompatWrapper( + 0, 0, mLanguageSwitcherProxy.getInputLocale().toString(), KEYBOARD_MODE, ""); + } Object o = CompatUtils.invoke(mImm, null, METHOD_getCurrentInputMethodSubtype); return new InputMethodSubtypeCompatWrapper(o); } public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList( InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) { + if (!SUBTYPE_SUPPORTED) { + String[] languages = mLanguageSwitcherProxy.getEnabledLanguages(); + List<InputMethodSubtypeCompatWrapper> subtypeList = + new ArrayList<InputMethodSubtypeCompatWrapper>(); + for (String lang: languages) { + subtypeList.add(new InputMethodSubtypeCompatWrapper(0, 0, lang, KEYBOARD_MODE, "")); + } + return subtypeList; + } Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList, (imi != null ? imi.getInputMethodInfo() : null), allowsImplicitlySelectedSubtypes); if (retval == null || !(retval instanceof List) || ((List<?>)retval).isEmpty()) { @@ -170,6 +195,10 @@ public class InputMethodManagerCompatWrapper { public void setInputMethodAndSubtype( IBinder token, String id, InputMethodSubtypeCompatWrapper subtype) { + if (!SUBTYPE_SUPPORTED) { + mLanguageSwitcherProxy.setLocale(subtype.getLocale()); + return; + } CompatUtils.invoke(mImm, null, METHOD_setInputMethodAndSubtype, token, id, subtype.getOriginalObject()); } diff --git a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java index e02aac704..1ea7236f9 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java @@ -19,20 +19,9 @@ package com.android.inputmethod.compat; import com.android.inputmethod.latin.SubtypeSwitcher; import android.inputmethodservice.InputMethodService; -import android.view.View; import android.view.inputmethod.InputMethodSubtype; -import android.widget.HorizontalScrollView; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; public class InputMethodServiceCompatWrapper extends InputMethodService { - private static final Method METHOD_HorizontalScrollView_setOverScrollMode = - CompatUtils.getMethod(HorizontalScrollView.class, "setOverScrollMode", int.class); - private static final Field FIELD_View_OVER_SCROLL_NEVER = - CompatUtils.getField(View.class, "OVER_SCROLL_NEVER"); - private static final Integer View_OVER_SCROLL_NEVER = - (Integer)CompatUtils.getFieldValue(null, null, FIELD_View_OVER_SCROLL_NEVER); // CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED needs to be false if the API level is 10 // or previous. Note that InputMethodSubtype was added in the API level 11. // For the API level 11 or later, LatinIME should override onCurrentInputMethodSubtypeChanged(). @@ -66,13 +55,6 @@ public class InputMethodServiceCompatWrapper extends InputMethodService { } } - protected static void setOverScrollModeNever(HorizontalScrollView scrollView) { - if (View_OVER_SCROLL_NEVER != null) { - CompatUtils.invoke(scrollView, null, METHOD_HorizontalScrollView_setOverScrollMode, - View_OVER_SCROLL_NEVER); - } - } - ////////////////////////////////////// // Functions using API v11 or later // ////////////////////////////////////// diff --git a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java index 317b02216..86c8af37f 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java @@ -58,9 +58,6 @@ public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper public InputMethodSubtypeCompatWrapper(Object subtype) { super((CLASS_InputMethodSubtype != null && CLASS_InputMethodSubtype.isInstance(subtype)) ? subtype : null); - if (DBG) { - Log.d(TAG, "CreateInputMethodSubtypeCompatWrapper"); - } mDummyNameResId = 0; mDummyIconResId = 0; mDummyLocale = DEFAULT_LOCALE; diff --git a/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java new file mode 100644 index 000000000..5d165cda9 --- /dev/null +++ b/java/src/com/android/inputmethod/deprecated/LanguageSwitcherProxy.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.deprecated; + +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.deprecated.languageswitcher.LanguageSwitcher; +import com.android.inputmethod.latin.LatinIME; + +import android.content.SharedPreferences; +import android.content.res.Configuration; + +import java.util.Locale; + +// This class is used only when the IME doesn't use method.xml for language switching. +public class LanguageSwitcherProxy { + private static final LanguageSwitcherProxy sInstance = new LanguageSwitcherProxy(); + private LanguageSwitcher mLanguageSwitcher; + private SharedPreferences mPrefs; + + public static LanguageSwitcherProxy getInstance() { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return null; + return sInstance; + } + + public static void init(LatinIME service, SharedPreferences prefs) { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; + final Configuration conf = service.getResources().getConfiguration(); + sInstance.mLanguageSwitcher = new LanguageSwitcher(service); + sInstance.mLanguageSwitcher.loadLocales(prefs, conf.locale); + sInstance.mPrefs = prefs; + } + + public static void onConfigurationChanged(Configuration conf) { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; + sInstance.mLanguageSwitcher.onConfigurationChanged(conf, sInstance.mPrefs); + } + + public static void loadSettings() { + if (InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) return; + sInstance.mLanguageSwitcher.loadLocales(sInstance.mPrefs, null); + } + + public int getLocaleCount() { + return mLanguageSwitcher.getLocaleCount(); + } + + public String[] getEnabledLanguages() { + return mLanguageSwitcher.getEnabledLanguages(); + } + + public Locale getInputLocale() { + return mLanguageSwitcher.getInputLocale(); + } + + public void setLocale(String localeStr) { + mLanguageSwitcher.setLocale(localeStr); + mLanguageSwitcher.persist(mPrefs); + } +} diff --git a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java index 6faf7f95e..639b7cdd0 100644 --- a/java/src/com/android/inputmethod/latin/LanguageSwitcher.java +++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java @@ -14,10 +14,16 @@ * the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.deprecated.languageswitcher; + +import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; +import com.android.inputmethod.latin.LatinIME; +import com.android.inputmethod.latin.Settings; +import com.android.inputmethod.latin.SharedPreferencesCompat; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; +import android.content.res.Configuration; import android.text.TextUtils; import java.util.ArrayList; @@ -29,6 +35,8 @@ import java.util.Locale; */ public class LanguageSwitcher { + private static final String KEYBOARD_MODE = "keyboard"; + private final ArrayList<Locale> mLocales = new ArrayList<Locale>(); private final LatinIME mIme; private String[] mSelectedLanguageArray; @@ -46,12 +54,24 @@ public class LanguageSwitcher { return mLocales.size(); } + public void onConfigurationChanged(Configuration conf, SharedPreferences prefs) { + final Locale newLocale = conf.locale; + if (!getSystemLocale().toString().equals(newLocale.toString())) { + loadLocales(prefs, newLocale); + } + } + /** * Loads the currently selected input languages from shared preferences. - * @param sp + * @param sp shared preference for getting the current input language and enabled languages + * @param systemLocale the current system locale, stored for changing the current input language + * based on the system current system locale. * @return whether there was any change */ - public boolean loadLocales(SharedPreferences sp) { + public boolean loadLocales(SharedPreferences sp, Locale systemLocale) { + if (systemLocale != null) { + setSystemLocale(systemLocale); + } String selectedLanguages = sp.getString(Settings.PREF_SELECTED_LANGUAGES, null); String currentLanguage = sp.getString(Settings.PREF_INPUT_LANGUAGE, null); if (selectedLanguages == null || selectedLanguages.length() < 1) { @@ -151,7 +171,7 @@ public class LanguageSwitcher { * Sets the system locale (display UI) used for comparing with the input language. * @param locale the locale of the system */ - public void setSystemLocale(Locale locale) { + private void setSystemLocale(Locale locale) { mSystemLocale = locale; } @@ -159,7 +179,7 @@ public class LanguageSwitcher { * Returns the system locale. * @return the system locale */ - public Locale getSystemLocale() { + private Locale getSystemLocale() { return mSystemLocale; } @@ -185,9 +205,22 @@ public class LanguageSwitcher { mCurrentIndex = prevLocaleIndex(); } + public void setLocale(String localeStr) { + final int N = mLocales.size(); + for (int i = 0; i < N; ++i) { + if (mLocales.get(i).toString().equals(localeStr)) { + mCurrentIndex = i; + } + } + } + public void persist(SharedPreferences prefs) { Editor editor = prefs.edit(); editor.putString(Settings.PREF_INPUT_LANGUAGE, getInputLanguage()); SharedPreferencesCompat.apply(editor); + // When the current language is changed, the event for this change should be handled + // internally as a subtype switching. + mIme.notifyOnCurrentInputMethodSubtypeChanged(new InputMethodSubtypeCompatWrapper( + 0, 0, getInputLocale().toString(), KEYBOARD_MODE, "")); } } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 7b570d7ed..71863803b 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -45,8 +45,8 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.WindowManager; +import android.view.ViewGroup; +import android.widget.FrameLayout; import android.widget.PopupWindow; import android.widget.TextView; @@ -110,14 +110,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { // Key preview popup private boolean mInForeground; private TextView mPreviewText; - private PopupWindow mPreviewPopup; private int mPreviewTextSizeLarge; - private int[] mOffsetInWindow; + private final int[] mOffsetInWindow = new int[2]; private int mOldPreviewKeyIndex = KeyDetector.NOT_A_KEY; private boolean mShowPreview = true; private int mPopupPreviewOffsetX; private int mPopupPreviewOffsetY; - private int mWindowY; private int mPopupPreviewDisplayedY; private final int mDelayBeforePreview; private final int mDelayAfterPreview; @@ -125,7 +123,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { // Popup mini keyboard private PopupWindow mMiniKeyboardPopup; private KeyboardView mMiniKeyboardView; - private View mMiniKeyboardParent; private final WeakHashMap<Key, View> mMiniKeyboardCache = new WeakHashMap<Key, View>(); private int mMiniKeyboardOriginX; private int mMiniKeyboardOriginY; @@ -204,7 +201,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { showKey(msg.arg1, (PointerTracker)msg.obj); break; case MSG_DISMISS_PREVIEW: - mPreviewPopup.dismiss(); + mPreviewText.setVisibility(View.INVISIBLE); break; case MSG_REPEAT_KEY: { final PointerTracker tracker = (PointerTracker)msg.obj; @@ -227,12 +224,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { public void popupPreview(long delay, int keyIndex, PointerTracker tracker) { removeMessages(MSG_POPUP_PREVIEW); - if (mPreviewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) { + if (mPreviewText.getVisibility() == VISIBLE) { // Show right away, if it's already visible and finger is moving around showKey(keyIndex, tracker); } else { - sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0, tracker), - delay); + sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0, tracker), delay); } } @@ -241,9 +237,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } public void dismissPreview(long delay) { - if (mPreviewPopup.isShowing()) { - sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay); - } + sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay); } public void cancelDismissPreview() { @@ -366,24 +360,17 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { final Resources res = getResources(); - mPreviewPopup = new PopupWindow(context); if (previewLayout != 0) { mPreviewText = (TextView) LayoutInflater.from(context).inflate(previewLayout, null); mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large); - mPreviewPopup.setContentView(mPreviewText); - mPreviewPopup.setBackgroundDrawable(null); } else { mShowPreview = false; } - mPreviewPopup.setTouchable(false); - mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation); - mPreviewPopup.setClippingEnabled(false); mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview); mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview); mKeyLabelHorizontalPadding = (int)res.getDimension( R.dimen.key_label_horizontal_alignment_padding); - mMiniKeyboardParent = this; mMiniKeyboardPopup = new PopupWindow(context); mMiniKeyboardPopup.setBackgroundDrawable(null); mMiniKeyboardPopup.setAnimationStyle(R.style.MiniKeyboardAnimation); @@ -583,7 +570,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { public void setPopupOffset(int x, int y) { mPopupPreviewOffsetX = x; mPopupPreviewOffsetY = y; - mPreviewPopup.dismiss(); } /** @@ -915,8 +901,16 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } } - // TODO Must fix popup preview on xlarge layout + // TODO: Introduce minimum duration for displaying key previews + // TODO: Display up to two key previews when the user presses two keys at the same time private void showKey(final int keyIndex, PointerTracker tracker) { + // If the preview popup has no parent view yet, add it to the screen FrameLayout. + if (mPreviewText.getParent() == null) { + final FrameLayout screenContent = (FrameLayout) getRootView() + .findViewById(android.R.id.content); + screenContent.addView(mPreviewText, new FrameLayout.LayoutParams(0, 0)); + } + Key key = tracker.getKey(keyIndex); // If keyIndex is invalid or IME is already closed, we must not show key preview. // Trying to show preview PopupWindow while root window is closed causes @@ -948,7 +942,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), keyDrawWidth + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight()); final int popupHeight = mPreviewHeight; - LayoutParams lp = mPreviewText.getLayoutParams(); + final ViewGroup.LayoutParams lp = mPreviewText.getLayoutParams(); if (lp != null) { lp.width = popupWidth; lp.height = popupHeight; @@ -958,47 +952,23 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { int popupPreviewY = key.mY - popupHeight + mPreviewOffset; mHandler.cancelDismissPreview(); - if (mOffsetInWindow == null) { - mOffsetInWindow = new int[2]; - getLocationInWindow(mOffsetInWindow); - mOffsetInWindow[0] += mPopupPreviewOffsetX; // Offset may be zero - mOffsetInWindow[1] += mPopupPreviewOffsetY; // Offset may be zero - int[] windowLocation = new int[2]; - getLocationOnScreen(windowLocation); - mWindowY = windowLocation[1]; - } + getLocationInWindow(mOffsetInWindow); + mOffsetInWindow[0] += mPopupPreviewOffsetX; // Offset may be zero + mOffsetInWindow[1] += mPopupPreviewOffsetY; // Offset may be zero + // Set the preview background state mPreviewText.getBackground().setState( key.mPopupCharacters != null ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET); popupPreviewX += mOffsetInWindow[0]; popupPreviewY += mOffsetInWindow[1]; - // If the popup cannot be shown above the key, put it on the side - if (popupPreviewY + mWindowY < 0) { - // If the key you're pressing is on the left side of the keyboard, show the popup on - // the right, offset by enough to see at least one key to the left/right. - if (keyDrawX + keyDrawWidth <= getWidth() / 2) { - popupPreviewX += (int) (keyDrawWidth * 2.5); - } else { - popupPreviewX -= (int) (keyDrawWidth * 2.5); - } - popupPreviewY += popupHeight; - } - - try { - if (mPreviewPopup.isShowing()) { - mPreviewPopup.update(popupPreviewX, popupPreviewY, popupWidth, popupHeight); - } else { - mPreviewPopup.setWidth(popupWidth); - mPreviewPopup.setHeight(popupHeight); - mPreviewPopup.showAtLocation(mMiniKeyboardParent, Gravity.NO_GRAVITY, - popupPreviewX, popupPreviewY); - } - } catch (WindowManager.BadTokenException e) { - // Swallow the exception which will be happened when IME is already closed. - Log.w(TAG, "LatinIME is already closed when tried showing key preview."); + // Place the key preview. + // TODO: Adjust position of key previews which touch screen edges + if (lp instanceof ViewGroup.MarginLayoutParams) { + ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)lp; + mlp.setMargins(popupPreviewX, popupPreviewY, 0, 0); } - // Record popup preview position to display mini-keyboard later at the same positon + // Record popup preview position to display mini-keyboard later at the same position mPopupPreviewDisplayedY = popupPreviewY; mPreviewText.setVisibility(VISIBLE); } @@ -1114,7 +1084,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { final Keyboard keyboard = new MiniKeyboardBuilder(this, mKeyboard.getPopupKeyboardResId(), popupKey).build(); miniKeyboardView.setKeyboard(keyboard); - miniKeyboardView.mMiniKeyboardParent = this; container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST)); @@ -1349,7 +1318,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } public void closing() { - mPreviewPopup.dismiss(); + mPreviewText.setVisibility(View.GONE); mHandler.cancelAllMessages(); dismissPopupKeyboard(); diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java index 9b87df3fe..9d9793e1e 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java @@ -271,7 +271,7 @@ public class LatinKeyboard extends Keyboard { canvas.drawText(language, width / 2, baseline - descent, paint); // Put arrows that are already layed out on either side of the text - if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher() + if (subtypeSwitcher.useSpacebarLanguageSwitcher() && subtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) { mButtonArrowLeftIcon.draw(canvas); mButtonArrowRightIcon.draw(canvas); diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index eb5335ffd..add38cf45 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -549,7 +549,6 @@ public class PointerTracker { final Key key = getKey(keyIndex); if (key != null && !key.mEnabled) return; - updateKeyGraphics(keyIndex); // The modifier key, such as shift key, should not be shown as preview when multi-touch is // supported. On the other hand, if multi-touch is not supported, the modifier key should // be shown as preview. If accessibility is turned on, the modifier key should be shown as @@ -559,6 +558,7 @@ public class PointerTracker { } else { mProxy.showPreview(keyIndex, this); } + updateKeyGraphics(keyIndex); } private void startLongPressTimer(int keyIndex) { diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java index 5719b9012..6fb80adf0 100644 --- a/java/src/com/android/inputmethod/latin/CandidateView.java +++ b/java/src/com/android/inputmethod/latin/CandidateView.java @@ -133,7 +133,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo ViewGroup.LayoutParams.WRAP_CONTENT); mPreviewPopup.setContentView(mPreviewText); mPreviewPopup.setBackgroundDrawable(null); - mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation); mConfigCandidateHighlightFontColorEnabled = res.getBoolean(R.bool.config_candidate_highlight_font_color_enabled); mColorNormal = res.getColor(R.color.candidate_normal); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 6a858fe99..d87de09c6 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -23,6 +23,7 @@ import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.compat.VibratorCompatWrapper; +import com.android.inputmethod.deprecated.LanguageSwitcherProxy; import com.android.inputmethod.deprecated.VoiceProxy; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardActionListener; @@ -56,7 +57,6 @@ import android.util.DisplayMetrics; import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Printer; -import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -70,8 +70,6 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; -import android.widget.FrameLayout; -import android.widget.HorizontalScrollView; import android.widget.LinearLayout; import java.io.FileDescriptor; @@ -143,6 +141,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar }; private View mCandidateViewContainer; + private int mCandidateStripHeight; private CandidateView mCandidateView; private Suggest mSuggest; private CompletionInfo[] mApplicationSpecifiedCompletions; @@ -379,6 +378,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar SubtypeSwitcher.init(this, prefs); KeyboardSwitcher.init(this, prefs); AccessibilityUtils.init(this, prefs); + LanguageSwitcherProxy.init(this, prefs); super.onCreate(); @@ -516,6 +516,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar super.onConfigurationChanged(conf); mVoiceProxy.onConfigurationChanged(conf); mConfigurationChanging = false; + + // This will work only when the subtype is not supported. + LanguageSwitcherProxy.onConfigurationChanged(conf); } @Override @@ -528,12 +531,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar LayoutInflater inflater = getLayoutInflater(); LinearLayout container = (LinearLayout)inflater.inflate(R.layout.candidates, null); mCandidateViewContainer = container; - if (container.getPaddingRight() != 0) { - HorizontalScrollView scrollView = - (HorizontalScrollView) container.findViewById(R.id.candidates_scroll_view); - setOverScrollModeNever(scrollView); - container.setGravity(Gravity.CENTER_HORIZONTAL); - } + mCandidateStripHeight = (int)mResources.getDimension(R.dimen.candidate_strip_height); mCandidateView = (CandidateView) container.findViewById(R.id.candidates); mCandidateView.setService(this); setCandidatesViewShown(true); @@ -581,8 +579,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar switcher.updateShiftState(); } - setCandidatesViewShownInternal(isCandidateStripVisible(), - false /* needsInputViewShown */ ); + setCandidatesViewShownInternal(isCandidateStripVisible(), false /* needsInputViewShown */ ); // Delay updating suggestions because keyboard input view may not be shown at this point. mHandler.postUpdateSuggestions(); @@ -872,10 +869,21 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) { - // TODO: Remove this if we support candidates with hard keyboard + // TODO: Modify this if we support candidates with hard keyboard if (onEvaluateInputViewShown()) { - super.setCandidatesViewShown(shown - && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true)); + final boolean shouldShowCandidates = shown + && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true); + if (isExtractViewShown()) { + // No need to have extra space to show the key preview. + mCandidateViewContainer.setMinimumHeight(0); + super.setCandidatesViewShown(shown); + } else { + // We must control the visibility of the suggestion strip in order to avoid clipped + // key previews, even when we don't show the suggestion strip. + mCandidateViewContainer.setVisibility( + shouldShowCandidates ? View.VISIBLE : View.INVISIBLE); + super.setCandidatesViewShown(true); + } } } @@ -887,35 +895,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar @Override public void onComputeInsets(InputMethodService.Insets outInsets) { super.onComputeInsets(outInsets); - if (!isFullscreenMode()) { - outInsets.contentTopInsets = outInsets.visibleTopInsets; - } - KeyboardView inputView = mKeyboardSwitcher.getInputView(); + final KeyboardView inputView = mKeyboardSwitcher.getInputView(); // Need to set touchable region only if input view is being shown if (inputView != null && mKeyboardSwitcher.isInputViewShown()) { - final int x = 0; - int y = 0; - final int width = inputView.getWidth(); - int height = inputView.getHeight() + EXTENDED_TOUCHABLE_REGION_HEIGHT; - if (mCandidateViewContainer != null) { - ViewParent candidateParent = mCandidateViewContainer.getParent(); - if (candidateParent instanceof FrameLayout) { - FrameLayout fl = (FrameLayout) candidateParent; - if (fl != null) { - // Check frame layout's visibility - if (fl.getVisibility() == View.INVISIBLE) { - y = fl.getHeight(); - height += y; - } else if (fl.getVisibility() == View.VISIBLE) { - height += fl.getHeight(); - } - } - } + final int containerHeight = mCandidateViewContainer.getHeight(); + int touchY = containerHeight; + if (mCandidateViewContainer.getVisibility() == View.VISIBLE) { + touchY -= mCandidateStripHeight; } + outInsets.contentTopInsets = touchY; + outInsets.visibleTopInsets = touchY; + final int touchWidth = inputView.getWidth(); + final int touchHeight = inputView.getHeight() + containerHeight + // Extend touchable region below the keyboard. + + EXTENDED_TOUCHABLE_REGION_HEIGHT; if (DEBUG) { - Log.d(TAG, "Touchable region " + x + ", " + y + ", " + width + ", " + height); + Log.d(TAG, "Touchable region: y=" + touchY + " width=" + touchWidth + + " height=" + touchHeight); } - setTouchableRegionCompat(outInsets, x, y, width, height); + setTouchableRegionCompat(outInsets, 0, touchY, touchWidth, touchHeight); } } @@ -1155,10 +1153,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar onSettingsKeyLongPressed(); break; case Keyboard.CODE_NEXT_LANGUAGE: - toggleLanguage(false, true); + toggleLanguage(true); break; case Keyboard.CODE_PREV_LANGUAGE: - toggleLanguage(false, false); + toggleLanguage(false); break; case Keyboard.CODE_CAPSLOCK: switcher.toggleCapsLock(); @@ -1930,17 +1928,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return mWord.isFirstCharCapitalized(); } - // Notify that language or mode have been changed and toggleLanguage will update KeyboaredID + // Notify that language or mode have been changed and toggleLanguage will update KeyboardID // according to new language or mode. public void onRefreshKeyboard() { - toggleLanguage(true, true); - } - - // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER. - private void toggleLanguage(boolean reset, boolean next) { - if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) { - mSubtypeSwitcher.toggleLanguage(reset, next); - } // Reload keyboard because the current language has been changed. mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mSubtypeSwitcher.isShortcutImeEnabled() && mVoiceProxy.isVoiceButtonEnabled(), @@ -1949,6 +1939,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mKeyboardSwitcher.updateShiftState(); } + // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER. + private void toggleLanguage(boolean next) { + if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) { + mSubtypeSwitcher.toggleLanguage(next); + } + onRefreshKeyboard();// no need?? + } + @Override public void onSwipeDown() { if (mConfigSwipeDownDismissKeyboardEnabled) @@ -2134,7 +2132,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar updateCorrectionMode(); updateAutoTextEnabled(); updateSuggestionVisibility(prefs); - SubtypeSwitcher.getInstance().loadSettings(); + + // This will work only when the subtype is not supported. + LanguageSwitcherProxy.loadSettings(); } /** diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index 053e2abe4..2cdc4d2cd 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -57,7 +57,6 @@ public class SubtypeSwitcher { private static final SubtypeSwitcher sInstance = new SubtypeSwitcher(); private /* final */ LatinIME mService; - private /* final */ SharedPreferences mPrefs; private /* final */ InputMethodManagerCompatWrapper mImm; private /* final */ Resources mResources; private /* final */ ConnectivityManager mConnectivityManager; @@ -66,6 +65,7 @@ public class SubtypeSwitcher { mEnabledKeyboardSubtypesOfCurrentInputMethod = new ArrayList<InputMethodSubtypeCompatWrapper>(); private final ArrayList<String> mEnabledLanguagesOfCurrentInputMethod = new ArrayList<String>(); + private final LanguageBarInfo mLanguageBarInfo = new LanguageBarInfo(); /*-----------------------------------------------------------*/ // Variants which should be changed only by reload functions. @@ -78,6 +78,7 @@ public class SubtypeSwitcher { private Locale mSystemLocale; private Locale mInputLocale; private String mInputLocaleStr; + private String mInputMethodId; private VoiceProxy.VoiceInputWrapper mVoiceInputWrapper; /*-----------------------------------------------------------*/ @@ -100,7 +101,6 @@ public class SubtypeSwitcher { private void initialize(LatinIME service, SharedPreferences prefs) { mService = service; - mPrefs = prefs; mResources = service.getResources(); mImm = InputMethodManagerCompatWrapper.getInstance(service); mConnectivityManager = (ConnectivityManager) service.getSystemService( @@ -114,13 +114,12 @@ public class SubtypeSwitcher { mAllEnabledSubtypesOfCurrentInputMethod = null; // TODO: Voice input should be created here mVoiceInputWrapper = null; - mConfigUseSpacebarLanguageSwitcher = mResources.getBoolean( + mConfigUseSpacebarLanguageSwitcher = service.getResources().getBoolean( R.bool.config_use_spacebar_language_switcher); - if (mConfigUseSpacebarLanguageSwitcher) - initLanguageSwitcher(service); final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo(); mIsNetworkConnected = (info != null && info.isConnected()); + mInputMethodId = Utils.getInputMethodId(mImm, service.getPackageName()); } // Update all parameters stored in SubtypeSwitcher. @@ -134,11 +133,7 @@ public class SubtypeSwitcher { // Update parameters which are changed outside LatinIME. This parameters affect UI so they // should be updated every time onStartInputview. public void updateParametersOnStartInputView() { - if (mConfigUseSpacebarLanguageSwitcher) { - updateForSpacebarLanguageSwitch(); - } else { - updateEnabledSubtypes(); - } + updateEnabledSubtypes(); updateShortcutIME(); } @@ -150,7 +145,7 @@ public class SubtypeSwitcher { null, true); mEnabledLanguagesOfCurrentInputMethod.clear(); mEnabledKeyboardSubtypesOfCurrentInputMethod.clear(); - for (InputMethodSubtypeCompatWrapper ims: mAllEnabledSubtypesOfCurrentInputMethod) { + for (InputMethodSubtypeCompatWrapper ims : mAllEnabledSubtypesOfCurrentInputMethod) { final String locale = ims.getLocale(); final String mode = ims.getMode(); mLocaleSplitter.setString(locale); @@ -172,6 +167,10 @@ public class SubtypeSwitcher { Log.w(TAG, "Last subtype was disabled. Update to the current one."); } updateSubtype(mImm.getCurrentInputMethodSubtype()); + } else { + // mLanguageBarInfo.update() will be called in updateSubtype so there is no need + // to call this in the if-clause above. + mLanguageBarInfo.update(); } } @@ -269,6 +268,7 @@ public class SubtypeSwitcher { mVoiceInputWrapper.reset(); } } + mLanguageBarInfo.update(); } // Update the current input locale from Locale string. @@ -303,12 +303,21 @@ public class SubtypeSwitcher { //////////////////////////// public void switchToShortcutIME() { - final IBinder token = mService.getWindow().getWindow().getAttributes().token; - if (token == null || mShortcutInputMethodInfo == null) { + if (mShortcutInputMethodInfo == null) { return; } + final String imiId = mShortcutInputMethodInfo.getId(); final InputMethodSubtypeCompatWrapper subtype = mShortcutSubtype; + switchToTargetIME(imiId, subtype); + } + + private void switchToTargetIME( + final String imiId, final InputMethodSubtypeCompatWrapper subtype) { + final IBinder token = mService.getWindow().getWindow().getAttributes().token; + if (token == null) { + return; + } new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { @@ -412,11 +421,7 @@ public class SubtypeSwitcher { ////////////////////////////////// public int getEnabledKeyboardLocaleCount() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getLocaleCount(); - } else { - return mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); - } + return mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); } public boolean useSpacebarLanguageSwitcher() { @@ -428,74 +433,37 @@ public class SubtypeSwitcher { } public Locale getInputLocale() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getInputLocale(); - } else { - return mInputLocale; - } + return mInputLocale; } public String getInputLocaleStr() { - if (mConfigUseSpacebarLanguageSwitcher) { - String inputLanguage = null; - inputLanguage = mLanguageSwitcher.getInputLanguage(); - // Should return system locale if there is no Language available. - if (inputLanguage == null) { - inputLanguage = getSystemLocale().getLanguage(); - } - return inputLanguage; - } else { - return mInputLocaleStr; - } + return mInputLocaleStr; } public String[] getEnabledLanguages() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getEnabledLanguages(); - } else { - int enabledLanguageCount = mEnabledLanguagesOfCurrentInputMethod.size(); - // Workaround for explicitly specifying the voice language - if (enabledLanguageCount == 1) { - mEnabledLanguagesOfCurrentInputMethod.add( - mEnabledLanguagesOfCurrentInputMethod.get(0)); - ++enabledLanguageCount; - } - return mEnabledLanguagesOfCurrentInputMethod.toArray( - new String[enabledLanguageCount]); + int enabledLanguageCount = mEnabledLanguagesOfCurrentInputMethod.size(); + // Workaround for explicitly specifying the voice language + if (enabledLanguageCount == 1) { + mEnabledLanguagesOfCurrentInputMethod.add(mEnabledLanguagesOfCurrentInputMethod + .get(0)); + ++enabledLanguageCount; } + return mEnabledLanguagesOfCurrentInputMethod.toArray(new String[enabledLanguageCount]); } public Locale getSystemLocale() { - if (mConfigUseSpacebarLanguageSwitcher) { - return mLanguageSwitcher.getSystemLocale(); - } else { - return mSystemLocale; - } + return mSystemLocale; } public boolean isSystemLanguageSameAsInputLanguage() { - if (mConfigUseSpacebarLanguageSwitcher) { - return getSystemLocale().getLanguage().equalsIgnoreCase( - getInputLocaleStr().substring(0, 2)); - } else { - return mIsSystemLanguageSameAsInputLanguage; - } + return mIsSystemLanguageSameAsInputLanguage; } public void onConfigurationChanged(Configuration conf) { final Locale systemLocale = conf.locale; // If system configuration was changed, update all parameters. if (!TextUtils.equals(systemLocale.toString(), mSystemLocale.toString())) { - if (mConfigUseSpacebarLanguageSwitcher) { - // If the system locale changes and is different from the saved - // locale (mSystemLocale), then reload the input locale list from the - // latin ime settings (shared prefs) and reset the input locale - // to the first one. - mLanguageSwitcher.loadLocales(mPrefs); - mLanguageSwitcher.setSystemLocale(systemLocale); - } else { - updateAllParameters(); - } + updateAllParameters(); } } @@ -554,7 +522,70 @@ public class SubtypeSwitcher { // Spacebar Language Switch support // ////////////////////////////////////// - private LanguageSwitcher mLanguageSwitcher; + private class LanguageBarInfo { + private int mCurrentKeyboardSubtypeIndex; + private InputMethodSubtypeCompatWrapper mNextKeyboardSubtype; + private InputMethodSubtypeCompatWrapper mPreviousKeyboardSubtype; + private String mNextLanguage; + private String mPreviousLanguage; + public LanguageBarInfo() { + update(); + } + + private String getNextLanguage() { + return mNextLanguage; + } + + private String getPreviousLanguage() { + return mPreviousLanguage; + } + + public InputMethodSubtypeCompatWrapper getNextKeyboardSubtype() { + return mNextKeyboardSubtype; + } + + public InputMethodSubtypeCompatWrapper getPreviousKeyboardSubtype() { + return mPreviousKeyboardSubtype; + } + + public void update() { + if (!mConfigUseSpacebarLanguageSwitcher + || mEnabledKeyboardSubtypesOfCurrentInputMethod == null + || mEnabledKeyboardSubtypesOfCurrentInputMethod.size() == 0) return; + mCurrentKeyboardSubtypeIndex = getCurrentIndex(); + mNextKeyboardSubtype = getNextKeyboardSubtypeInternal(mCurrentKeyboardSubtypeIndex); + Locale locale = new Locale(mNextKeyboardSubtype.getLocale()); + mNextLanguage = getDisplayLanguage(locale); + mPreviousKeyboardSubtype = getPreviousKeyboardSubtypeInternal( + mCurrentKeyboardSubtypeIndex); + locale = new Locale(mPreviousKeyboardSubtype.getLocale()); + mPreviousLanguage = getDisplayLanguage(locale); + } + + private int normalize(int index) { + final int N = mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); + final int ret = index % N; + return ret < 0 ? ret + N : ret; + } + + private int getCurrentIndex() { + final int N = mEnabledKeyboardSubtypesOfCurrentInputMethod.size(); + for (int i = 0; i < N; ++i) { + if (mEnabledKeyboardSubtypesOfCurrentInputMethod.get(i).equals(mCurrentSubtype)) { + return i; + } + } + return 0; + } + + private InputMethodSubtypeCompatWrapper getNextKeyboardSubtypeInternal(int index) { + return mEnabledKeyboardSubtypesOfCurrentInputMethod.get(normalize(index + 1)); + } + + private InputMethodSubtypeCompatWrapper getPreviousKeyboardSubtypeInternal(int index) { + return mEnabledKeyboardSubtypesOfCurrentInputMethod.get(normalize(index - 1)); + } + } public static String getFullDisplayName(Locale locale, boolean returnsNameInThisLocale) { if (returnsNameInThisLocale) { @@ -579,32 +610,16 @@ public class SubtypeSwitcher { return Character.toUpperCase(s.charAt(0)) + s.substring(1); } - private void updateForSpacebarLanguageSwitch() { - // We need to update mNeedsToDisplayLanguage in onStartInputView because - // getEnabledKeyboardLocaleCount could have been changed. - mNeedsToDisplayLanguage = !(getEnabledKeyboardLocaleCount() <= 1 - && getSystemLocale().getLanguage().equalsIgnoreCase( - getInputLocale().getLanguage())); - } - public String getInputLanguageName() { return getDisplayLanguage(getInputLocale()); } public String getNextInputLanguageName() { - if (mConfigUseSpacebarLanguageSwitcher) { - return getDisplayLanguage(mLanguageSwitcher.getNextInputLocale()); - } else { - return ""; - } + return mLanguageBarInfo.getNextLanguage(); } public String getPreviousInputLanguageName() { - if (mConfigUseSpacebarLanguageSwitcher) { - return getDisplayLanguage(mLanguageSwitcher.getPrevInputLocale()); - } else { - return ""; - } + return mLanguageBarInfo.getPreviousLanguage(); } ///////////////////////////// @@ -644,31 +659,23 @@ public class SubtypeSwitcher { return voiceInputSupportedLocales.contains(locale); } - public void loadSettings() { - if (mConfigUseSpacebarLanguageSwitcher) { - mLanguageSwitcher.loadLocales(mPrefs); - } + private void changeToNextSubtype() { + final InputMethodSubtypeCompatWrapper subtype = + mLanguageBarInfo.getNextKeyboardSubtype(); + switchToTargetIME(mInputMethodId, subtype); } - public void toggleLanguage(boolean reset, boolean next) { - if (mConfigUseSpacebarLanguageSwitcher) { - if (reset) { - mLanguageSwitcher.reset(); - } else { - if (next) { - mLanguageSwitcher.next(); - } else { - mLanguageSwitcher.prev(); - } - } - mLanguageSwitcher.persist(mPrefs); - } + private void changeToPreviousSubtype() { + final InputMethodSubtypeCompatWrapper subtype = + mLanguageBarInfo.getPreviousKeyboardSubtype(); + switchToTargetIME(mInputMethodId, subtype); } - private void initLanguageSwitcher(LatinIME service) { - final Configuration conf = service.getResources().getConfiguration(); - mLanguageSwitcher = new LanguageSwitcher(service); - mLanguageSwitcher.loadLocales(mPrefs); - mLanguageSwitcher.setSystemLocale(conf.locale); + public void toggleLanguage(boolean next) { + if (next) { + changeToNextSubtype(); + } else { + changeToPreviousSubtype(); + } } } |