aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin
diff options
context:
space:
mode:
authorKen Wakasa <kwakasa@google.com>2014-08-27 18:41:31 +0900
committerKen Wakasa <kwakasa@google.com>2014-08-27 18:41:31 +0900
commitc1596086d3de32b66a382acf2c9b5fa00779008f (patch)
tree765f0e249c53ad274b62e2c1b26d731bd33d3630 /java/src/com/android/inputmethod/latin
parentb7bedccb295b43f486ec60d029d7e6219d9c5a8b (diff)
parent0268f7368ffe774fe0d9b12888b9c2986516b480 (diff)
downloadlatinime-c1596086d3de32b66a382acf2c9b5fa00779008f.tar.gz
latinime-c1596086d3de32b66a382acf2c9b5fa00779008f.tar.xz
latinime-c1596086d3de32b66a382acf2c9b5fa00779008f.zip
resolved conflicts for merge of 0268f736 to master
Change-Id: Ib89ef55a8752f9b5e357eed3a05c79dd28d0ec0e
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java49
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java144
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java22
3 files changed, 200 insertions, 15 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 9a3927c4f..779f4cc2c 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -69,6 +69,7 @@ import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.MainKeyboardView;
+import com.android.inputmethod.keyboard.TextDecoratorUi;
import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.DebugFlags;
@@ -183,8 +184,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final int MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED = 6;
private static final int MSG_RESET_CACHES = 7;
private static final int MSG_WAIT_FOR_DICTIONARY_LOAD = 8;
+ private static final int MSG_SHOW_COMMIT_INDICATOR = 9;
// Update this when adding new messages
- private static final int MSG_LAST = MSG_WAIT_FOR_DICTIONARY_LOAD;
+ private static final int MSG_LAST = MSG_SHOW_COMMIT_INDICATOR;
private static final int ARG1_NOT_GESTURE_INPUT = 0;
private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
@@ -195,6 +197,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private int mDelayInMillisecondsToUpdateSuggestions;
private int mDelayInMillisecondsToUpdateShiftState;
+ private int mDelayInMillisecondsToShowCommitIndicator;
public UIHandler(final LatinIME ownerInstance) {
super(ownerInstance);
@@ -206,10 +209,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
final Resources res = latinIme.getResources();
- mDelayInMillisecondsToUpdateSuggestions =
- res.getInteger(R.integer.config_delay_in_milliseconds_to_update_suggestions);
- mDelayInMillisecondsToUpdateShiftState =
- res.getInteger(R.integer.config_delay_in_milliseconds_to_update_shift_state);
+ mDelayInMillisecondsToUpdateSuggestions = res.getInteger(
+ R.integer.config_delay_in_milliseconds_to_update_suggestions);
+ mDelayInMillisecondsToUpdateShiftState = res.getInteger(
+ R.integer.config_delay_in_milliseconds_to_update_shift_state);
+ mDelayInMillisecondsToShowCommitIndicator = res.getInteger(
+ R.integer.text_decorator_delay_in_milliseconds_to_show_commit_indicator);
}
@Override
@@ -258,7 +263,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
case MSG_RESET_CACHES:
final SettingsValues settingsValues = latinIme.mSettings.getCurrent();
if (latinIme.mInputLogic.retryResetCachesAndReturnSuccess(
- msg.arg1 == 1 /* tryResumeSuggestions */,
+ msg.arg1 == ARG1_TRUE /* tryResumeSuggestions */,
msg.arg2 /* remainingTries */, this /* handler */)) {
// If we were able to reset the caches, then we can reload the keyboard.
// Otherwise, we'll do it when we can.
@@ -267,6 +272,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
latinIme.getCurrentRecapitalizeState());
}
break;
+ case MSG_SHOW_COMMIT_INDICATOR:
+ // Protocol of MSG_SET_COMMIT_INDICATOR_ENABLED:
+ // - what: MSG_SHOW_COMMIT_INDICATOR
+ // - arg1: not used.
+ // - arg2: not used.
+ // - obj: the Runnable object to be called back.
+ ((Runnable) msg.obj).run();
+ break;
case MSG_WAIT_FOR_DICTIONARY_LOAD:
Log.i(TAG, "Timeout waiting for dictionary load");
break;
@@ -367,6 +380,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
obtainMessage(MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED, suggestedWords).sendToTarget();
}
+ /**
+ * Posts a delayed task to show the commit indicator.
+ *
+ * <p>Only one task can exist in the queue. When this method is called, any prior task that
+ * has not yet fired will be canceled.</p>
+ * @param task the runnable object that will be fired when the delayed task is dispatched.
+ */
+ public void postShowCommitIndicatorTask(final Runnable task) {
+ removeMessages(MSG_SHOW_COMMIT_INDICATOR);
+ sendMessageDelayed(obtainMessage(MSG_SHOW_COMMIT_INDICATOR, task),
+ mDelayInMillisecondsToShowCommitIndicator);
+ }
+
// Working variables for the following methods.
private boolean mIsOrientationChanging;
private boolean mPendingSuccessiveImsCallback;
@@ -717,6 +743,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (hasSuggestionStripView()) {
mSuggestionStripView.setListener(this, view);
}
+ mInputLogic.setTextDecoratorUi(new TextDecoratorUi(this, view));
}
@Override
@@ -973,9 +1000,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// @Override
public void onUpdateCursorAnchorInfo(final CursorAnchorInfo info) {
if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) {
- final CursorAnchorInfoCompatWrapper wrapper =
- CursorAnchorInfoCompatWrapper.fromObject(info);
- // TODO: Implement here
+ mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.fromObject(info));
}
}
@@ -1179,6 +1204,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// In fullscreen mode, no need to have extra space to show the key preview.
// If not, we should have extra space above the keyboard to show the key preview.
mKeyPreviewBackingView.setVisibility(isFullscreenMode() ? View.GONE : View.VISIBLE);
+ mInputLogic.onUpdateFullscreenMode(isFullscreenMode());
}
private int getCurrentAutoCapsState() {
@@ -1216,6 +1242,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
mDictionaryFacilitator.addWordToUserDictionary(this /* context */, word);
+ mInputLogic.onAddWordToUserDictionary();
}
// Callback for the {@link SuggestionStripView}, to call when the important notice strip is
@@ -1412,7 +1439,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void setSuggestedWords(final SuggestedWords suggestedWords) {
- mInputLogic.setSuggestedWords(suggestedWords);
+ final SettingsValues currentSettingsValues = mSettings.getCurrent();
+ mInputLogic.setSuggestedWords(suggestedWords, currentSettingsValues, mHandler);
// TODO: Modify this when we support suggestions with hard keyboard
if (!hasSuggestionStripView()) {
return;
@@ -1421,7 +1449,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
}
- final SettingsValues currentSettingsValues = mSettings.getCurrent();
final boolean shouldShowImportantNotice =
ImportantNoticeUtils.shouldShowImportantNotice(this);
final boolean shouldShowSuggestionCandidates =
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 790f72e79..e05725700 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.latin.inputlogic;
import android.graphics.Color;
+import android.inputmethodservice.InputMethodService;
import android.os.SystemClock;
import android.text.SpannableString;
import android.text.TextUtils;
@@ -27,11 +28,14 @@ import android.view.KeyEvent;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.EditorInfo;
+import com.android.inputmethod.compat.CursorAnchorInfoCompatWrapper;
import com.android.inputmethod.compat.SuggestionSpanUtils;
import com.android.inputmethod.event.Event;
import com.android.inputmethod.event.InputTransaction;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.keyboard.TextDecorator;
+import com.android.inputmethod.keyboard.TextDecoratorUiOperator;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.DictionaryFacilitator;
@@ -81,6 +85,18 @@ public final class InputLogic {
public final Suggest mSuggest;
private final DictionaryFacilitator mDictionaryFacilitator;
+ private final TextDecorator mTextDecorator = new TextDecorator(new TextDecorator.Listener() {
+ @Override
+ public void onClickComposingTextToCommit(SuggestedWordInfo wordInfo) {
+ mLatinIME.pickSuggestionManually(wordInfo);
+ }
+ @Override
+ public void onClickComposingTextToAddToDictionary(SuggestedWordInfo wordInfo) {
+ mLatinIME.addWordToUserDictionary(wordInfo.mWord);
+ mLatinIME.dismissAddToDictionaryHint();
+ }
+ });
+
public LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
// This has package visibility so it can be accessed from InputLogicHandler.
/* package */ final WordComposer mWordComposer;
@@ -303,8 +319,18 @@ public final class InputLogic {
return inputTransaction;
}
- commitChosenWord(settingsValues, suggestion,
- LastComposedWord.COMMIT_TYPE_MANUAL_PICK, LastComposedWord.NOT_A_SEPARATOR);
+ final boolean shouldShowAddToDictionaryHint = shouldShowAddToDictionaryHint(suggestionInfo);
+ final boolean shouldShowAddToDictionaryIndicator =
+ shouldShowAddToDictionaryHint && settingsValues.mShouldShowUiToAcceptTypedWord;
+ final int backgroundColor;
+ if (shouldShowAddToDictionaryIndicator) {
+ backgroundColor = settingsValues.mTextHighlightColorForAddToDictionaryIndicator;
+ } else {
+ backgroundColor = Color.TRANSPARENT;
+ }
+ commitChosenWordWithBackgroundColor(settingsValues, suggestion,
+ LastComposedWord.COMMIT_TYPE_MANUAL_PICK, LastComposedWord.NOT_A_SEPARATOR,
+ backgroundColor);
mConnection.endBatchEdit();
// Don't allow cancellation of manual pick
mLastComposedWord.deactivate();
@@ -312,13 +338,16 @@ public final class InputLogic {
mSpaceState = SpaceState.PHANTOM;
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
- if (shouldShowAddToDictionaryHint(suggestionInfo)) {
+ if (shouldShowAddToDictionaryHint) {
mSuggestionStripViewAccessor.showAddToDictionaryHint(suggestion);
} else {
// If we're not showing the "Touch again to save", then update the suggestion strip.
// That's going to be predictions (or punctuation suggestions), so INPUT_STYLE_NONE.
handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE);
}
+ if (shouldShowAddToDictionaryIndicator) {
+ mTextDecorator.showAddToDictionaryIndicator(suggestionInfo);
+ }
return inputTransaction;
}
@@ -386,6 +415,8 @@ public final class InputLogic {
// The cursor has been moved : we now accept to perform recapitalization
mRecapitalizeStatus.enable();
+ // We moved the cursor and need to invalidate the indicator right now.
+ mTextDecorator.reset();
// We moved the cursor. If we are touching a word, we need to resume suggestion.
mLatinIME.mHandler.postResumeSuggestions(false /* shouldIncludeResumedWordInSuggestions */,
true /* shouldDelay */);
@@ -561,7 +592,8 @@ public final class InputLogic {
// TODO: on the long term, this method should become private, but it will be difficult.
// Especially, how do we deal with InputMethodService.onDisplayCompletions?
- public void setSuggestedWords(final SuggestedWords suggestedWords) {
+ public void setSuggestedWords(final SuggestedWords suggestedWords,
+ final SettingsValues settingsValues, final LatinIME.UIHandler handler) {
if (SuggestedWords.EMPTY != suggestedWords) {
final String autoCorrection;
if (suggestedWords.mWillAutoCorrect) {
@@ -575,6 +607,38 @@ public final class InputLogic {
}
mSuggestedWords = suggestedWords;
final boolean newAutoCorrectionIndicator = suggestedWords.mWillAutoCorrect;
+ if (shouldShowCommitIndicator(suggestedWords, settingsValues)) {
+ // typedWordInfo is never null here.
+ final SuggestedWordInfo typedWordInfo = suggestedWords.getTypedWordInfoOrNull();
+ handler.postShowCommitIndicatorTask(new Runnable() {
+ @Override
+ public void run() {
+ // TODO: This needs to be refactored to ensure that mWordComposer is accessed
+ // only from the UI thread.
+ if (!mWordComposer.isComposingWord()) {
+ mTextDecorator.reset();
+ return;
+ }
+ final SuggestedWordInfo currentTypedWordInfo =
+ mSuggestedWords.getTypedWordInfoOrNull();
+ if (currentTypedWordInfo == null) {
+ mTextDecorator.reset();
+ return;
+ }
+ if (!currentTypedWordInfo.equals(typedWordInfo)) {
+ // Suggested word has been changed. This task is obsolete.
+ mTextDecorator.reset();
+ return;
+ }
+ mTextDecorator.showCommitIndicator(typedWordInfo);
+ }
+ });
+ } else {
+ // Note: It is OK to not cancel previous postShowCommitIndicatorTask() here. Having a
+ // cancellation mechanism could improve performance a bit though.
+ mTextDecorator.reset();
+ }
+
// Put a blue underline to a word in TextView which will be auto-corrected.
if (mIsAutoCorrectionIndicatorOn != newAutoCorrectionIndicator
&& mWordComposer.isComposingWord()) {
@@ -756,6 +820,8 @@ public final class InputLogic {
if (!mWordComposer.isComposingWord() &&
mSuggestionStripViewAccessor.isShowingAddToDictionaryHint()) {
mSuggestionStripViewAccessor.dismissAddToDictionaryHint();
+ mConnection.removeBackgroundColorFromHighlightedTextIfNecessary();
+ mTextDecorator.reset();
}
final int codePoint = event.mCodePoint;
@@ -2108,4 +2174,74 @@ public final class InputLogic {
settingsValues.mAutoCorrectionEnabledPerUserSettings,
inputStyle, sequenceNumber, callback);
}
+
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // Following methods are tentatively placed in this class for the integration with
+ // TextDecorator.
+ // TODO: Decouple things that are not related to the input logic.
+ //////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Sets the UI operator for {@link TextDecorator}.
+ * @param uiOperator the UI operator which should be associated with {@link TextDecorator}.
+ */
+ public void setTextDecoratorUi(final TextDecoratorUiOperator uiOperator) {
+ mTextDecorator.setUiOperator(uiOperator);
+ }
+
+ /**
+ * Must be called from {@link InputMethodService#onUpdateCursorAnchorInfo} is called.
+ * @param info The wrapper object with which we can access cursor/anchor info.
+ */
+ public void onUpdateCursorAnchorInfo(final CursorAnchorInfoCompatWrapper info) {
+ mTextDecorator.onUpdateCursorAnchorInfo(info);
+ }
+
+ /**
+ * Must be called when {@link InputMethodService#updateFullscreenMode} is called.
+ * @param isFullscreen {@code true} if the input method is in full-screen mode.
+ */
+ public void onUpdateFullscreenMode(final boolean isFullscreen) {
+ mTextDecorator.notifyFullScreenMode(isFullscreen);
+ }
+
+ /**
+ * Must be called from {@link LatinIME#addWordToUserDictionary(String)}.
+ */
+ public void onAddWordToUserDictionary() {
+ mConnection.removeBackgroundColorFromHighlightedTextIfNecessary();
+ mTextDecorator.reset();
+ }
+
+ /**
+ * Returns whether the commit indicator should be shown or not.
+ * @param suggestedWords the suggested word that is being displayed.
+ * @param settingsValues the current settings value.
+ * @return {@code true} if the commit indicator should be shown.
+ */
+ private boolean shouldShowCommitIndicator(final SuggestedWords suggestedWords,
+ final SettingsValues settingsValues) {
+ if (!settingsValues.mShouldShowUiToAcceptTypedWord) {
+ return false;
+ }
+ final SuggestedWordInfo typedWordInfo = suggestedWords.getTypedWordInfoOrNull();
+ if (typedWordInfo == null) {
+ return false;
+ }
+ if (suggestedWords.mInputStyle != SuggestedWords.INPUT_STYLE_TYPING){
+ return false;
+ }
+ if (settingsValues.mShowCommitIndicatorOnlyForAutoCorrection
+ && !suggestedWords.mWillAutoCorrect) {
+ return false;
+ }
+ // TODO: Calling shouldShowAddToDictionaryHint(typedWordInfo) multiple times should be fine
+ // in terms of performance, but we can do better. One idea is to make SuggestedWords include
+ // a boolean that tells whether the word is a dictionary word or not.
+ if (settingsValues.mShowCommitIndicatorOnlyForOutOfVocabulary
+ && !shouldShowAddToDictionaryHint(typedWordInfo)) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index a9789d888..91a2b6776 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -96,6 +96,12 @@ public class SettingsValues {
public final int[] mAdditionalFeaturesSettingValues =
new int[AdditionalFeaturesSettingUtils.ADDITIONAL_FEATURES_SETTINGS_SIZE];
+ // TextDecorator
+ public final int mTextHighlightColorForCommitIndicator;
+ public final int mTextHighlightColorForAddToDictionaryIndicator;
+ public final boolean mShowCommitIndicatorOnlyForAutoCorrection;
+ public final boolean mShowCommitIndicatorOnlyForOutOfVocabulary;
+
// Debug settings
public final boolean mIsInternal;
public final int mKeyPreviewShowUpDuration;
@@ -164,6 +170,14 @@ public class SettingsValues {
mSuggestionsEnabledPerUserSettings = readSuggestionsEnabled(prefs);
AdditionalFeaturesSettingUtils.readAdditionalFeaturesPreferencesIntoArray(
prefs, mAdditionalFeaturesSettingValues);
+ mShowCommitIndicatorOnlyForAutoCorrection = res.getBoolean(
+ R.bool.text_decorator_only_for_auto_correction);
+ mShowCommitIndicatorOnlyForOutOfVocabulary = res.getBoolean(
+ R.bool.text_decorator_only_for_out_of_vocabulary);
+ mTextHighlightColorForCommitIndicator = res.getColor(
+ R.color.text_decorator_commit_indicator_text_highlight_color);
+ mTextHighlightColorForAddToDictionaryIndicator = res.getColor(
+ R.color.text_decorator_add_to_dictionary_indicator_text_highlight_color);
mIsInternal = Settings.isInternal(prefs);
mKeyPreviewShowUpDuration = Settings.readKeyPreviewAnimationDuration(
prefs, DebugSettings.PREF_KEY_PREVIEW_SHOW_UP_DURATION,
@@ -401,6 +415,14 @@ public class SettingsValues {
sb.append("" + (null == awu ? "null" : awu.toString()));
sb.append("\n mAdditionalFeaturesSettingValues = ");
sb.append("" + Arrays.toString(mAdditionalFeaturesSettingValues));
+ sb.append("\n mShowCommitIndicatorOnlyForAutoCorrection = ");
+ sb.append("" + mShowCommitIndicatorOnlyForAutoCorrection);
+ sb.append("\n mShowCommitIndicatorOnlyForOutOfVocabulary = ");
+ sb.append("" + mShowCommitIndicatorOnlyForOutOfVocabulary);
+ sb.append("\n mTextHighlightColorForCommitIndicator = ");
+ sb.append("" + mTextHighlightColorForCommitIndicator);
+ sb.append("\n mTextHighlightColorForAddToDictionaryIndicator = ");
+ sb.append("" + mTextHighlightColorForAddToDictionaryIndicator);
sb.append("\n mIsInternal = ");
sb.append("" + mIsInternal);
sb.append("\n mKeyPreviewShowUpDuration = ");