aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/CandidateView.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/CandidateView.java')
-rw-r--r--java/src/com/android/inputmethod/latin/CandidateView.java285
1 files changed, 118 insertions, 167 deletions
diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java
index b9ded31cb..fe48f0bc1 100644
--- a/java/src/com/android/inputmethod/latin/CandidateView.java
+++ b/java/src/com/android/inputmethod/latin/CandidateView.java
@@ -23,6 +23,7 @@ import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Message;
+import android.os.SystemClock;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
@@ -34,8 +35,10 @@ import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
@@ -46,6 +49,9 @@ import android.widget.TextView;
import com.android.inputmethod.compat.FrameLayoutCompatUtils;
import com.android.inputmethod.compat.LinearLayoutCompatUtils;
+import com.android.inputmethod.keyboard.KeyboardActionListener;
+import com.android.inputmethod.keyboard.MoreKeysPanel;
+import com.android.inputmethod.keyboard.PointerTracker;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import java.util.ArrayList;
@@ -58,16 +64,19 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
}
// The maximum number of suggestions available. See {@link Suggest#mPrefMaxSuggestions}.
- private static final int MAX_SUGGESTIONS = 18;
+ public static final int MAX_SUGGESTIONS = 18;
private static final boolean DBG = LatinImeLogger.sDBG;
private final ViewGroup mCandidatesPlacer;
private final ViewGroup mCandidatesStrip;
- private ViewGroup mCandidatesPane;
- private ViewGroup mCandidatesPaneContainer;
private View mKeyboardView;
+ private final View mMoreSuggestionsContainer;
+ private final MoreSuggestionsView mMoreSuggestionsView;
+ private final MoreSuggestions.Builder mMoreSuggestionsBuilder;
+ private final PopupWindow mMoreSuggestionsWindow;
+
private final ArrayList<TextView> mWords = new ArrayList<TextView>();
private final ArrayList<TextView> mInfos = new ArrayList<TextView>();
private final ArrayList<View> mDividers = new ArrayList<View>();
@@ -80,7 +89,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
private boolean mShowingAutoCorrectionInverted;
private final SuggestionsStripParams mStripParams;
- private final SuggestionsPaneParams mPaneParams;
private static final float MIN_TEXT_XSCALE = 0.70f;
private final UiHandler mHandler = new UiHandler(this);
@@ -137,7 +145,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
private static class CandidateViewParams {
public final int mPadding;
public final int mDividerWidth;
- public final int mDividerHeight;
public final int mCandidateStripHeight;
protected final List<TextView> mWords;
@@ -156,96 +163,9 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
divider.measure(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
mDividerWidth = divider.getMeasuredWidth();
- mDividerHeight = divider.getMeasuredHeight();
final Resources res = word.getResources();
- mCandidateStripHeight = res.getDimensionPixelOffset(R.dimen.candidate_strip_height);
- }
- }
-
- private static class SuggestionsPaneParams extends CandidateViewParams {
- public SuggestionsPaneParams(List<TextView> words, List<View> dividers,
- List<TextView> infos) {
- super(words, dividers, infos);
- }
-
- public int layout(SuggestedWords suggestions, ViewGroup paneView, int from, int textColor,
- int paneWidth) {
- final int count = Math.min(mWords.size(), suggestions.size());
- View centeringFrom = null, lastView = null;
- int x = 0, y = 0;
- for (int index = from; index < count; index++) {
- final int pos = index;
- final TextView word = mWords.get(pos);
- final View divider = mDividers.get(pos);
- final TextPaint paint = word.getPaint();
- word.setTextColor(textColor);
- final CharSequence styled = suggestions.getWord(pos);
-
- final TextView info;
- if (DBG) {
- final CharSequence debugInfo = getDebugInfo(suggestions, index);
- if (debugInfo != null) {
- info = mInfos.get(index);
- info.setText(debugInfo);
- } else {
- info = null;
- }
- } else {
- info = null;
- }
-
- final CharSequence text;
- final float scaleX;
- paint.setTextScaleX(1.0f);
- final int textWidth = getTextWidth(styled, paint);
- int available = paneWidth - x - mPadding;
- if (textWidth >= available) {
- // Needs new row, centering previous row.
- centeringCandidates(paneView, centeringFrom, lastView, x, paneWidth);
- x = 0;
- y += mCandidateStripHeight;
- }
- if (x != 0) {
- // Add divider if this isn't the left most suggestion in current row.
- paneView.addView(divider);
- FrameLayoutCompatUtils.placeViewAt(divider, x, y
- + (mCandidateStripHeight - mDividerHeight) / 2, mDividerWidth,
- mDividerHeight);
- x += mDividerWidth;
- }
- available = paneWidth - x - mPadding;
- text = getEllipsizedText(styled, available, paint);
- scaleX = paint.getTextScaleX();
- word.setText(text);
- word.setTextScaleX(scaleX);
- paneView.addView(word);
- lastView = word;
- if (x == 0)
- centeringFrom = word;
- word.measure(ViewGroup.LayoutParams.WRAP_CONTENT,
- MeasureSpec.makeMeasureSpec(mCandidateStripHeight, MeasureSpec.EXACTLY));
- final int width = word.getMeasuredWidth();
- final int height = word.getMeasuredHeight();
- FrameLayoutCompatUtils.placeViewAt(word, x, y + (mCandidateStripHeight - height)
- / 2, width, height);
- x += width;
- if (info != null) {
- paneView.addView(info);
- lastView = info;
- info.measure(ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- final int infoWidth = info.getMeasuredWidth();
- FrameLayoutCompatUtils.placeViewAt(
- info, x - infoWidth, y, infoWidth, info.getMeasuredHeight());
- }
- }
- if (x != 0) {
- // Centering last candidates row.
- centeringCandidates(paneView, centeringFrom, lastView, x, paneWidth);
- }
-
- return count - from;
+ mCandidateStripHeight = res.getDimensionPixelSize(R.dimen.candidate_strip_height);
}
}
@@ -257,7 +177,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
private final int mColorTypedWord;
private final int mColorAutoCorrect;
private final int mColorSuggestedCandidate;
- private final int mCandidateCountInStrip;
+ public final int mCandidateCountInStrip;
private final float mCenterCandidateWeight;
private final int mCenterCandidateIndex;
private final Drawable mMoreCandidateHint;
@@ -311,10 +231,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
mHintToSaveText = context.getText(R.string.hint_add_to_dictionary);
}
- public int getTextColor() {
- return mColorTypedWord;
- }
-
private CharSequence getStyledCandidateWord(SuggestedWords suggestions, int pos) {
final CharSequence word = suggestions.getWord(pos);
final boolean isAutoCorrect = pos == 1 && willAutoCorrect(suggestions);
@@ -389,10 +305,11 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
return word;
}
- public int layout(SuggestedWords suggestions, ViewGroup stripView, ViewGroup placer,
+ public void layout(SuggestedWords suggestions, ViewGroup stripView, ViewGroup placer,
int stripWidth) {
if (suggestions.isPunctuationSuggestions()) {
- return layoutPunctuationSuggestions(suggestions, stripView);
+ layoutPunctuationSuggestions(suggestions, stripView);
+ return;
}
final int countInStrip = mCandidateCountInStrip;
@@ -449,8 +366,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
}
}
}
-
- return countInStrip;
}
private int getCandidateWidth(int index, int maxWidth) {
@@ -482,7 +397,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
}
}
- private int layoutPunctuationSuggestions(SuggestedWords suggestions, ViewGroup stripView) {
+ private void layoutPunctuationSuggestions(SuggestedWords suggestions, ViewGroup stripView) {
final int countInStrip = Math.min(suggestions.size(), PUNCTUATIONS_IN_STRIP);
for (int index = 0; index < countInStrip; index++) {
if (index != 0) {
@@ -501,7 +416,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
setLayoutWeight(word, 1.0f, mCandidateStripHeight);
}
mMoreSuggestionsAvailable = false;
- return countInStrip;
}
public void layoutAddToDictionaryHint(CharSequence word, ViewGroup stripView,
@@ -583,8 +497,16 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
mStripParams = new SuggestionsStripParams(context, attrs, defStyle, mWords, mDividers,
mInfos);
- mPaneParams = new SuggestionsPaneParams(mWords, mDividers, mInfos);
mStripParams.mWordToSaveView.setOnClickListener(this);
+
+ mMoreSuggestionsContainer = inflater.inflate(R.layout.more_suggestions, null);
+ mMoreSuggestionsView = (MoreSuggestionsView)mMoreSuggestionsContainer
+ .findViewById(R.id.more_suggestions_view);
+ mMoreSuggestionsBuilder = new MoreSuggestions.Builder(mMoreSuggestionsView);
+ mMoreSuggestionsWindow = new PopupWindow(context);
+ mMoreSuggestionsWindow.setWindowLayoutMode(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ mMoreSuggestionsWindow.setBackgroundDrawable(null);
}
/**
@@ -594,11 +516,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
public void setListener(Listener listener, View inputView) {
mListener = listener;
mKeyboardView = inputView.findViewById(R.id.keyboard_view);
- mCandidatesPane = FrameLayoutCompatUtils.getPlacer(
- (ViewGroup)inputView.findViewById(R.id.candidates_pane));
- mCandidatesPane.setOnClickListener(this);
- mCandidatesPaneContainer = (ViewGroup)inputView.findViewById(
- R.id.candidates_pane_container);
}
public void setSuggestions(SuggestedWords suggestions) {
@@ -614,15 +531,10 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
private void updateSuggestions() {
clear();
- closeCandidatesPane();
if (mSuggestions.size() == 0)
return;
- final int width = getWidth();
- final int countInStrip = mStripParams.layout(
- mSuggestions, mCandidatesStrip, mCandidatesPlacer, width);
- mPaneParams.layout(
- mSuggestions, mCandidatesPane, countInStrip, mStripParams.getTextColor(), width);
+ mStripParams.layout(mSuggestions, mCandidatesStrip, mCandidatesPlacer, getWidth());
}
private static CharSequence getDebugInfo(SuggestedWords suggestions, int pos) {
@@ -648,26 +560,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
}
}
- private static void centeringCandidates(ViewGroup parent, View from, View to, int width,
- int parentWidth) {
- final int fromIndex = parent.indexOfChild(from);
- final int toIndex = parent.indexOfChild(to);
- final int offset = (parentWidth - width) / 2;
- for (int index = fromIndex; index <= toIndex; index++) {
- offsetMargin(parent.getChildAt(index), offset, 0);
- }
- }
-
- private static void offsetMargin(View v, int dx, int dy) {
- if (v == null)
- return;
- final ViewGroup.LayoutParams lp = v.getLayoutParams();
- if (lp instanceof ViewGroup.MarginLayoutParams) {
- final ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)lp;
- mlp.setMargins(mlp.leftMargin + dx, mlp.topMargin + dy, 0, 0);
- }
- }
-
private static float getTextScaleX(CharSequence text, int maxWidth, TextPaint paint) {
paint.setTextScaleX(1.0f);
final int width = getTextWidth(text, paint);
@@ -730,25 +622,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
}
}
- private void expandCandidatesPane() {
- mCandidatesPaneContainer.setMinimumHeight(mKeyboardView.getMeasuredHeight());
- mCandidatesPaneContainer.setVisibility(VISIBLE);
- mKeyboardView.setVisibility(GONE);
- }
-
- private void closeCandidatesPane() {
- mCandidatesPaneContainer.setVisibility(GONE);
- mKeyboardView.setVisibility(VISIBLE);
- }
-
- private void toggleCandidatesPane() {
- if (mCandidatesPaneContainer.getVisibility() == VISIBLE) {
- closeCandidatesPane();
- } else {
- expandCandidatesPane();
- }
- }
-
public void onAutoCorrectionInverted(CharSequence autoCorrectedWord) {
final CharSequence inverted = mStripParams.getInvertedText(autoCorrectedWord);
if (inverted == null)
@@ -785,8 +658,7 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
mCandidatesPlacer.removeAllViews();
mCandidatesPlacer.addView(mCandidatesStrip);
mCandidatesStrip.removeAllViews();
- mCandidatesPane.removeAllViews();
- closeCandidatesPane();
+ mMoreSuggestionsWindow.dismiss();
}
private void hidePreview() {
@@ -823,16 +695,103 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
}
}
+ private final KeyboardActionListener mMoreSuggestionsListener =
+ new KeyboardActionListener.Adapter() {
+ @Override
+ public boolean onCustomRequest(int requestCode) {
+ final int index = requestCode;
+ final CharSequence word = mSuggestions.getWord(index);
+ mListener.pickSuggestionManually(index, word);
+ mMoreSuggestionsView.dismissMoreKeysPanel();
+ return true;
+ }
+
+ @Override
+ public void onCancelInput() {
+ mMoreSuggestionsView.dismissMoreKeysPanel();
+ }
+ };
+
+ private final MoreKeysPanel.Controller mMoreSuggestionsController =
+ new MoreKeysPanel.Controller() {
+ @Override
+ public boolean dismissMoreKeysPanel() {
+ if (mMoreSuggestionsWindow.isShowing()) {
+ mMoreSuggestionsWindow.dismiss();
+ return true;
+ }
+ return false;
+ }
+ };
+
@Override
public boolean onLongClick(View view) {
- if (mStripParams.mMoreSuggestionsAvailable) {
- toggleCandidatesPane();
+ final SuggestionsStripParams params = mStripParams;
+ if (params.mMoreSuggestionsAvailable) {
+ final int stripWidth = getWidth();
+ final View container = mMoreSuggestionsContainer;
+ final int maxWidth = stripWidth - container.getPaddingLeft()
+ - container.getPaddingRight();
+ final DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
+ // TODO: Revise how we determine the height
+ final int maxHeight = dm.heightPixels - mKeyboardView.getHeight() - getHeight() * 3;
+ final MoreSuggestions.Builder builder = mMoreSuggestionsBuilder;
+ builder.layout(mSuggestions, params.mCandidateCountInStrip, maxWidth, maxHeight);
+ mMoreSuggestionsView.setKeyboard(builder.build());
+ container.measure(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ final MoreKeysPanel moreKeysPanel = mMoreSuggestionsView;
+ final int pointX = stripWidth / 2;
+ final int pointY = 0;
+ moreKeysPanel.showMoreKeysPanel(
+ this, mMoreSuggestionsController, pointX, pointY,
+ mMoreSuggestionsWindow, mMoreSuggestionsListener);
+ // TODO: Should figure out how to select the pointer tracker correctly.
+ final PointerTracker tracker = PointerTracker.getPointerTracker(0, moreKeysPanel);
+ final int translatedX = moreKeysPanel.translateX(tracker.getLastX());
+ final int translatedY = moreKeysPanel.translateY(tracker.getLastY());
+ tracker.onShowMoreKeysPanel(
+ translatedX, translatedY, SystemClock.uptimeMillis(), moreKeysPanel);
+ view.setPressed(false);
+ // TODO: Should gray out the keyboard here as well?
return true;
}
return false;
}
@Override
+ public boolean dispatchTouchEvent(MotionEvent me) {
+ if (!mMoreSuggestionsWindow.isShowing()) {
+ return super.dispatchTouchEvent(me);
+ }
+ final int action = me.getAction();
+ final long eventTime = me.getEventTime();
+ final int index = me.getActionIndex();
+ final int id = me.getPointerId(index);
+ final PointerTracker tracker = PointerTracker.getPointerTracker(id, mMoreSuggestionsView);
+ final int x = mMoreSuggestionsView.translateX((int)me.getX(index));
+ final int y = mMoreSuggestionsView.translateY((int)me.getY(index));
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_POINTER_DOWN:
+ tracker.onDownEvent(x, y, eventTime, mMoreSuggestionsView);
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_POINTER_UP:
+ tracker.onUpEvent(x, y, eventTime);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ tracker.onMoveEvent(x, y, eventTime);
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ tracker.onCancelEvent(x, y, eventTime);
+ break;
+ }
+ return true;
+ }
+
+ @Override
public void onClick(View view) {
if (view == mStripParams.mWordToSaveView) {
addToDictionary((CharSequence)view.getTag());
@@ -840,11 +799,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
return;
}
- if (view == mCandidatesPane) {
- closeCandidatesPane();
- return;
- }
-
final Object tag = view.getTag();
if (!(tag instanceof Integer))
return;
@@ -854,9 +808,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo
final CharSequence word = mSuggestions.getWord(index);
mListener.pickSuggestionManually(index, word);
- // Because some punctuation letters are not treated as word separator depending on locale,
- // {@link #setSuggestions} might not be called and candidates pane left opened.
- closeCandidatesPane();
}
@Override