Merge remote-tracking branch 'goog/master' into merge
Conflicts: java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java Change-Id: Iba0f2202bc2561f29b850dc22e9de52f84943a9cmain
commit
7c06332be2
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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:minHeight="@dimen/candidate_strip_minimum_height"
|
||||
>
|
||||
<!-- 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"
|
||||
>
|
||||
<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="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:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/candidate_strip_height"
|
||||
android:background="@drawable/keyboard_suggest_strip_holo" />
|
||||
android:layout_height="match_parent" />
|
||||
</HorizontalScrollView>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -107,7 +107,8 @@ public class InputMethodManagerCompatWrapper {
|
|||
public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList(
|
||||
InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) {
|
||||
if (!SUBTYPE_SUPPORTED) {
|
||||
String[] languages = mLanguageSwitcherProxy.getEnabledLanguages();
|
||||
String[] languages = mLanguageSwitcherProxy.getEnabledLanguages(
|
||||
allowsImplicitlySelectedSubtypes);
|
||||
List<InputMethodSubtypeCompatWrapper> subtypeList =
|
||||
new ArrayList<InputMethodSubtypeCompatWrapper>();
|
||||
for (String lang: languages) {
|
||||
|
@ -195,10 +196,6 @@ 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());
|
||||
}
|
||||
|
|
|
@ -16,23 +16,13 @@
|
|||
|
||||
package com.android.inputmethod.compat;
|
||||
|
||||
import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
|
||||
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().
|
||||
|
@ -62,17 +52,13 @@ public class InputMethodServiceCompatWrapper extends InputMethodService {
|
|||
subtype = mImm.getCurrentInputMethodSubtype();
|
||||
}
|
||||
if (subtype != null) {
|
||||
if (!InputMethodManagerCompatWrapper.SUBTYPE_SUPPORTED) {
|
||||
LanguageSwitcherProxy.getInstance().setLocale(subtype.getLocale());
|
||||
}
|
||||
SubtypeSwitcher.getInstance().updateSubtype(subtype);
|
||||
}
|
||||
}
|
||||
|
||||
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 //
|
||||
//////////////////////////////////////
|
||||
|
|
|
@ -19,6 +19,7 @@ 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 com.android.inputmethod.latin.Settings;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
|
@ -26,7 +27,7 @@ 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 {
|
||||
public class LanguageSwitcherProxy implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
private static final LanguageSwitcherProxy sInstance = new LanguageSwitcherProxy();
|
||||
private LanguageSwitcher mLanguageSwitcher;
|
||||
private SharedPreferences mPrefs;
|
||||
|
@ -42,6 +43,7 @@ public class LanguageSwitcherProxy {
|
|||
sInstance.mLanguageSwitcher = new LanguageSwitcher(service);
|
||||
sInstance.mLanguageSwitcher.loadLocales(prefs, conf.locale);
|
||||
sInstance.mPrefs = prefs;
|
||||
prefs.registerOnSharedPreferenceChangeListener(sInstance);
|
||||
}
|
||||
|
||||
public static void onConfigurationChanged(Configuration conf) {
|
||||
|
@ -58,8 +60,8 @@ public class LanguageSwitcherProxy {
|
|||
return mLanguageSwitcher.getLocaleCount();
|
||||
}
|
||||
|
||||
public String[] getEnabledLanguages() {
|
||||
return mLanguageSwitcher.getEnabledLanguages();
|
||||
public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) {
|
||||
return mLanguageSwitcher.getEnabledLanguages(allowImplicitlySelectedLanguages);
|
||||
}
|
||||
|
||||
public Locale getInputLocale() {
|
||||
|
@ -70,4 +72,14 @@ public class LanguageSwitcherProxy {
|
|||
mLanguageSwitcher.setLocale(localeStr);
|
||||
mLanguageSwitcher.persist(mPrefs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
|
||||
// PREF_SELECTED_LANGUAGES: enabled input subtypes
|
||||
// PREF_INPUT_LANGUAGE: current input subtype
|
||||
if (key.equals(Settings.PREF_SELECTED_LANGUAGES)
|
||||
|| key.equals(Settings.PREF_INPUT_LANGUAGE)) {
|
||||
mLanguageSwitcher.loadLocales(prefs, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package com.android.inputmethod.deprecated.languageswitcher;
|
|||
|
||||
import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper;
|
||||
import com.android.inputmethod.latin.LatinIME;
|
||||
import com.android.inputmethod.latin.LatinImeLogger;
|
||||
import com.android.inputmethod.latin.Settings;
|
||||
import com.android.inputmethod.latin.SharedPreferencesCompat;
|
||||
|
||||
|
@ -25,6 +26,7 @@ import android.content.SharedPreferences;
|
|||
import android.content.SharedPreferences.Editor;
|
||||
import android.content.res.Configuration;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
@ -34,12 +36,14 @@ import java.util.Locale;
|
|||
* input language that the user has selected.
|
||||
*/
|
||||
public class LanguageSwitcher {
|
||||
private static final String TAG = LanguageSwitcher.class.getSimpleName();
|
||||
|
||||
private static final String KEYBOARD_MODE = "keyboard";
|
||||
private static final String[] EMPTY_STIRNG_ARRAY = new String[0];
|
||||
|
||||
private final ArrayList<Locale> mLocales = new ArrayList<Locale>();
|
||||
private final LatinIME mIme;
|
||||
private String[] mSelectedLanguageArray;
|
||||
private String[] mSelectedLanguageArray = EMPTY_STIRNG_ARRAY;
|
||||
private String mSelectedLanguages;
|
||||
private int mCurrentIndex = 0;
|
||||
private String mDefaultInputLanguage;
|
||||
|
@ -69,12 +73,16 @@ public class LanguageSwitcher {
|
|||
* @return whether there was any change
|
||||
*/
|
||||
public boolean loadLocales(SharedPreferences sp, Locale systemLocale) {
|
||||
if (LatinImeLogger.sDBG) {
|
||||
Log.d(TAG, "load locales");
|
||||
}
|
||||
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) {
|
||||
if (TextUtils.isEmpty(selectedLanguages)) {
|
||||
mSelectedLanguageArray = EMPTY_STIRNG_ARRAY;
|
||||
loadDefaults();
|
||||
if (mLocales.size() == 0) {
|
||||
return false;
|
||||
|
@ -104,6 +112,9 @@ public class LanguageSwitcher {
|
|||
}
|
||||
|
||||
private void loadDefaults() {
|
||||
if (LatinImeLogger.sDBG) {
|
||||
Log.d(TAG, "load default locales:");
|
||||
}
|
||||
mDefaultInputLocale = mIme.getResources().getConfiguration().locale;
|
||||
String country = mDefaultInputLocale.getCountry();
|
||||
mDefaultInputLanguage = mDefaultInputLocale.getLanguage() +
|
||||
|
@ -132,7 +143,10 @@ public class LanguageSwitcher {
|
|||
/**
|
||||
* Returns the list of enabled language codes.
|
||||
*/
|
||||
public String[] getEnabledLanguages() {
|
||||
public String[] getEnabledLanguages(boolean allowImplicitlySelectedLanguages) {
|
||||
if (mSelectedLanguageArray.length == 0 && allowImplicitlySelectedLanguages) {
|
||||
return new String[] { mDefaultInputLanguage };
|
||||
}
|
||||
return mSelectedLanguageArray;
|
||||
}
|
||||
|
||||
|
@ -218,9 +232,5 @@ public class LanguageSwitcher {
|
|||
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, ""));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,10 +237,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
|
|||
}
|
||||
|
||||
public void dismissPreview(long delay) {
|
||||
if (mPreviewPopup.isShowing()) {
|
||||
sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay);
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelDismissPreview() {
|
||||
removeMessages(MSG_DISMISS_PREVIEW);
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
}
|
||||
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.");
|
||||
}
|
||||
// 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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -57,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;
|
||||
|
@ -71,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;
|
||||
|
@ -144,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;
|
||||
|
@ -377,10 +375,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
|||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
mPrefs = prefs;
|
||||
LatinImeLogger.init(this, prefs);
|
||||
LanguageSwitcherProxy.init(this, prefs);
|
||||
SubtypeSwitcher.init(this, prefs);
|
||||
KeyboardSwitcher.init(this, prefs);
|
||||
AccessibilityUtils.init(this, prefs);
|
||||
LanguageSwitcherProxy.init(this, prefs);
|
||||
|
||||
super.onCreate();
|
||||
|
||||
|
@ -533,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);
|
||||
|
@ -586,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();
|
||||
|
||||
|
@ -877,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -892,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -138,13 +138,14 @@ static void prof_out(void) {
|
|||
#define SUGGEST_WORDS_WITH_SPACE_PROXIMITY true
|
||||
|
||||
// The following "rate"s are used as a multiplier before dividing by 100, so they are in percent.
|
||||
#define WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE 90
|
||||
#define WORDS_WITH_MISSING_CHARACTER_DEMOTION_RATE 80
|
||||
#define WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X 12
|
||||
#define WORDS_WITH_MISSING_SPACE_CHARACTER_DEMOTION_RATE 80
|
||||
#define WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE 75
|
||||
#define WORDS_WITH_EXCESSIVE_CHARACTER_OUT_OF_PROXIMITY_DEMOTION_RATE 75
|
||||
#define WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE 60
|
||||
#define FULL_MATCHED_WORDS_PROMOTION_RATE 120
|
||||
#define WORDS_WITH_JUST_ONE_PROXIMITY_CHARACTER_PROMOTION_RATE 110
|
||||
|
||||
// This should be greater than or equal to MAX_WORD_LENGTH defined in BinaryDictionary.java
|
||||
// This is only used for the size of array. Not to be used in c functions.
|
||||
|
|
|
@ -523,6 +523,9 @@ inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int
|
|||
* (10 * mInputLength - WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X)
|
||||
/ (10 * mInputLength
|
||||
- WORDS_WITH_MISSING_CHARACTER_DEMOTION_START_POS_10X + 10);
|
||||
if (DEBUG_DICT) {
|
||||
LOGI("Demotion rate for missing character is %d.", demotionRate);
|
||||
}
|
||||
multiplyRate(demotionRate, &finalFreq);
|
||||
} else {
|
||||
finalFreq = 0;
|
||||
|
@ -539,6 +542,7 @@ inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int
|
|||
int lengthFreq = TYPED_LETTER_MULTIPLIER;
|
||||
for (int i = 0; i < depth; ++i) lengthFreq *= TYPED_LETTER_MULTIPLIER;
|
||||
if (lengthFreq == matchWeight) {
|
||||
// Full exact match
|
||||
if (depth > 1) {
|
||||
if (DEBUG_DICT) {
|
||||
LOGI("Found full matched word.");
|
||||
|
@ -548,6 +552,13 @@ inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int
|
|||
if (sameLength && transposedPos < 0 && skipPos < 0 && excessivePos < 0) {
|
||||
finalFreq = capped255MultForFullMatchAccentsOrCapitalizationDifference(finalFreq);
|
||||
}
|
||||
} else if (lengthFreq / 2 == matchWeight && transposedPos < 0 && skipPos < 0
|
||||
&& excessivePos < 0 && depth > 1) {
|
||||
// Full match except only one proximity correction
|
||||
if (DEBUG_DICT) {
|
||||
LOGI("Found one proximity correction.");
|
||||
}
|
||||
multiplyRate(WORDS_WITH_JUST_ONE_PROXIMITY_CHARACTER_PROMOTION_RATE, &finalFreq);
|
||||
}
|
||||
if (sameLength) finalFreq *= FULL_WORD_MULTIPLIER;
|
||||
return finalFreq;
|
||||
|
|
Loading…
Reference in New Issue