SuggestionStripView.java revision 6ec55a1599c74150e82ea7e4371ec815f0d2df27
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/*
2923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Copyright (C) 2008-2009 Google Inc.
3923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
4923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of
6923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License at
7923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
8923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0
9923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
10923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * License for the specific language governing permissions and limitations under
14923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License.
15923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */
16923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
17923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpackage com.android.inputmethod.latin;
18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
19923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport java.util.ArrayList;
20923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport java.util.Arrays;
21923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport java.util.List;
22923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
23923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Context;
24923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Intent;
25923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.graphics.Canvas;
26923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.graphics.Paint;
27923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.graphics.Rect;
28923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.graphics.Typeface;
29923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.graphics.drawable.Drawable;
30923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Handler;
31923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Message;
32923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.AttributeSet;
33923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.GestureDetector;
34923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.Gravity;
35923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.LayoutInflater;
36923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.MotionEvent;
37923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.View;
38923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.ViewGroup.LayoutParams;
39923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.widget.PopupWindow;
40923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.widget.TextView;
41923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
42923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpublic class CandidateView extends View {
43923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
44923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private static final int OUT_OF_BOUNDS = -1;
45923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private static final List<CharSequence> EMPTY_LIST = new ArrayList<CharSequence>();
46923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
47923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private LatinIME mService;
48923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private List<CharSequence> mSuggestions = EMPTY_LIST;
49923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private boolean mShowingCompletions;
50923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private CharSequence mSelectedString;
51923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mSelectedIndex;
52923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mTouchX = OUT_OF_BOUNDS;
53923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private Drawable mSelectionHighlight;
54923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private boolean mTypedWordValid;
55923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
56923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private boolean mHaveMinimalSuggestion;
57923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
58923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private Rect mBgPadding;
59923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
60923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private TextView mPreviewText;
61923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private PopupWindow mPreviewPopup;
62923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mCurrentWordIndex;
63923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private Drawable mDivider;
64923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
65923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private static final int MAX_SUGGESTIONS = 32;
66923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private static final int SCROLL_PIXELS = 20;
67923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
68923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private static final int MSG_REMOVE_PREVIEW = 1;
69923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private static final int MSG_REMOVE_THROUGH_PREVIEW = 2;
70923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
71923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int[] mWordWidth = new int[MAX_SUGGESTIONS];
72923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int[] mWordX = new int[MAX_SUGGESTIONS];
73923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mPopupPreviewX;
74923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mPopupPreviewY;
75923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
76923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private static final int X_GAP = 10;
77923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
78923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mColorNormal;
79923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mColorRecommended;
80923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mColorOther;
81923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private Paint mPaint;
82923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mDescent;
83923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private boolean mScrolled;
84923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mTargetScrollX;
85923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
86923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mTotalWidth;
87923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
88923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private GestureDetector mGestureDetector;
89923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
90923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    Handler mHandler = new Handler() {
91923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        @Override
92923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        public void handleMessage(Message msg) {
93923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            switch (msg.what) {
94923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                case MSG_REMOVE_PREVIEW:
95923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mPreviewText.setVisibility(GONE);
96923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    break;
97923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                case MSG_REMOVE_THROUGH_PREVIEW:
98923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mPreviewText.setVisibility(GONE);
99923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    if (mTouchX != OUT_OF_BOUNDS) {
100923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                        removeHighlight();
101923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    }
102923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    break;
103923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
104923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
105923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
106923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    };
107923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
108923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
109923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * Construct a CandidateView for showing suggested words for completion.
110923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @param context
111923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @param attrs
112923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
113923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public CandidateView(Context context, AttributeSet attrs) {
114923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        super(context, attrs);
115923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mSelectionHighlight = context.getResources().getDrawable(
116923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                com.android.internal.R.drawable.list_selector_background_pressed);
117923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
118923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        LayoutInflater inflate =
119923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            (LayoutInflater) context
120923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
121923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPreviewPopup = new PopupWindow(context);
122923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPreviewText = (TextView) inflate.inflate(R.layout.candidate_preview, null);
123923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPreviewPopup.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
124923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPreviewPopup.setContentView(mPreviewText);
125923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPreviewPopup.setBackgroundDrawable(null);
126923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mColorNormal = context.getResources().getColor(R.color.candidate_normal);
127923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mColorRecommended = context.getResources().getColor(R.color.candidate_recommended);
128923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mColorOther = context.getResources().getColor(R.color.candidate_other);
129923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mDivider = context.getResources().getDrawable(R.drawable.keyboard_suggest_strip_divider);
130923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
131923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPaint = new Paint();
132923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPaint.setColor(mColorNormal);
133923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPaint.setAntiAlias(true);
134923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPaint.setTextSize(mPreviewText.getTextSize());
135923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPaint.setStrokeWidth(0);
136923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mDescent = (int) mPaint.descent();
137923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
138923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() {
139923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            @Override
140923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            public void onLongPress(MotionEvent me) {
141923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                if (mSuggestions.size() > 0) {
142923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    if (me.getX() + mScrollX < mWordWidth[0] && mScrollX < 10) {
143923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                        longPressFirstWord();
144923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    }
145923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                }
146923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
147923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
148923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            @Override
149923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            public boolean onScroll(MotionEvent e1, MotionEvent e2,
150923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    float distanceX, float distanceY) {
1516ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani                final int width = getWidth();
152923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mScrolled = true;
1536ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani                mScrollX += (int) distanceX;
154923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                if (mScrollX < 0) {
155923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mScrollX = 0;
156923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                }
1576ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani                if (distanceX > 0 && mScrollX + width > mTotalWidth) {
1586ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani                    mScrollX -= (int) distanceX;
159923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                }
160923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mTargetScrollX = mScrollX;
1616ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani                hidePreview();
162923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                invalidate();
163923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                return true;
164923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
165923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        });
166923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        setHorizontalFadingEdgeEnabled(true);
167923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        setWillNotDraw(false);
168923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        setHorizontalScrollBarEnabled(false);
169923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        setVerticalScrollBarEnabled(false);
170923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mScrollX = 0;
171923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
172923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
173923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
174923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * A connection back to the service to communicate with the text field
175923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @param listener
176923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
177923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void setService(LatinIME listener) {
178923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mService = listener;
179923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
180923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
181923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    @Override
182923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public int computeHorizontalScrollRange() {
183923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        return mTotalWidth;
184923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
185923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
186923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
187923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * If the canvas is null, then only touch calculations are performed to pick the target
188923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * candidate.
189923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
190923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    @Override
191923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    protected void onDraw(Canvas canvas) {
192923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (canvas != null) {
193923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            super.onDraw(canvas);
194923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
195923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mTotalWidth = 0;
196923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (mSuggestions == null) return;
197923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
198923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final int height = getHeight();
199923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (mBgPadding == null) {
200923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mBgPadding = new Rect(0, 0, 0, 0);
201923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (getBackground() != null) {
202923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                getBackground().getPadding(mBgPadding);
203923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
204923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mDivider.setBounds(0, mBgPadding.top, mDivider.getIntrinsicWidth(),
205923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mDivider.getIntrinsicHeight());
206923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
207923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int x = 0;
208923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final int count = mSuggestions.size();
209923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final int width = getWidth();
210923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final Rect bgPadding = mBgPadding;
211923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final Paint paint = mPaint;
212923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final int touchX = mTouchX;
213923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final int scrollX = mScrollX;
214923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final boolean scrolled = mScrolled;
215923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final boolean typedWordValid = mTypedWordValid;
216923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final int y = (int) (height + mPaint.getTextSize() - mDescent) / 2;
217923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
218923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        for (int i = 0; i < count; i++) {
219923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            CharSequence suggestion = mSuggestions.get(i);
220923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (suggestion == null) continue;
221923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            paint.setColor(mColorNormal);
222923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (mHaveMinimalSuggestion
223923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    && ((i == 1 && !typedWordValid) || (i == 0 && typedWordValid))) {
224923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                paint.setTypeface(Typeface.DEFAULT_BOLD);
225923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                paint.setColor(mColorRecommended);
226923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            } else if (i != 0) {
227923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                paint.setColor(mColorOther);
228923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
229923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            final int wordWidth;
230923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (mWordWidth[i] != 0) {
231923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                wordWidth = mWordWidth[i];
232923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            } else {
233923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                float textWidth =  paint.measureText(suggestion, 0, suggestion.length());
234923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                wordWidth = (int) textWidth + X_GAP * 2;
235923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mWordWidth[i] = wordWidth;
236923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
237923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
238923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mWordX[i] = x;
239923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
2406ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani            if (touchX + scrollX >= x && touchX + scrollX < x + wordWidth && !scrolled &&
2416ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani                    touchX != OUT_OF_BOUNDS) {
242923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                if (canvas != null) {
243923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    canvas.translate(x, 0);
244923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mSelectionHighlight.setBounds(0, bgPadding.top, wordWidth, height);
245923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mSelectionHighlight.draw(canvas);
246923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    canvas.translate(-x, 0);
247923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    showPreview(i, null);
248923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                }
249923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mSelectedString = suggestion;
250923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mSelectedIndex = i;
251923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
252923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
253923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (canvas != null) {
254923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                canvas.drawText(suggestion, 0, suggestion.length(), x + X_GAP, y, paint);
255923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                paint.setColor(mColorOther);
256923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                canvas.translate(x + wordWidth, 0);
257923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mDivider.draw(canvas);
258923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                canvas.translate(-x - wordWidth, 0);
259923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
260923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            paint.setTypeface(Typeface.DEFAULT);
261923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            x += wordWidth;
262923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
263923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mTotalWidth = x;
264923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (mTargetScrollX != mScrollX) {
265923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            scrollToTarget();
266923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
267923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
268923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
269923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private void scrollToTarget() {
270923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (mTargetScrollX > mScrollX) {
271923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mScrollX += SCROLL_PIXELS;
272923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (mScrollX >= mTargetScrollX) {
273923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mScrollX = mTargetScrollX;
274923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                requestLayout();
275923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
276923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        } else {
277923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mScrollX -= SCROLL_PIXELS;
278923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (mScrollX <= mTargetScrollX) {
279923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mScrollX = mTargetScrollX;
280923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                requestLayout();
281923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
282923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
283923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        invalidate();
284923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
285923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
286923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void setSuggestions(List<CharSequence> suggestions, boolean completions,
287923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            boolean typedWordValid, boolean haveMinimalSuggestion) {
288923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        clear();
289923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (suggestions != null) {
290923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mSuggestions = new ArrayList<CharSequence>(suggestions);
291923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
292923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mShowingCompletions = completions;
293923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mTypedWordValid = typedWordValid;
294923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mScrollX = 0;
295923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mTargetScrollX = 0;
296923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mHaveMinimalSuggestion = haveMinimalSuggestion;
297923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        // Compute the total width
298923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        onDraw(null);
299923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        invalidate();
300923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        requestLayout();
301923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
302923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
303923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void scrollPrev() {
304923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int i = 0;
305923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final int count = mSuggestions.size();
306923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int firstItem = 0; // Actually just before the first item, if at the boundary
307923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        while (i < count) {
308923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (mWordX[i] < mScrollX
309923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    && mWordX[i] + mWordWidth[i] >= mScrollX - 1) {
310923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                firstItem = i;
311923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                break;
312923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
313923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            i++;
314923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
315923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int leftEdge = mWordX[firstItem] + mWordWidth[firstItem] - getWidth();
316923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (leftEdge < 0) leftEdge = 0;
317923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        updateScrollPosition(leftEdge);
318923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
319923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
320923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void scrollNext() {
321923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int i = 0;
322923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int targetX = mScrollX;
323923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        final int count = mSuggestions.size();
324923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int rightEdge = mScrollX + getWidth();
325923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        while (i < count) {
326923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (mWordX[i] <= rightEdge &&
327923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mWordX[i] + mWordWidth[i] >= rightEdge) {
328923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                targetX = Math.min(mWordX[i], mTotalWidth - getWidth());
329923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                break;
330923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
331923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            i++;
332923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
333923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        updateScrollPosition(targetX);
334923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
335923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
336923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private void updateScrollPosition(int targetX) {
337923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (targetX != mScrollX) {
338923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            // TODO: Animate
339923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mTargetScrollX = targetX;
340923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            requestLayout();
341923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            invalidate();
342923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mScrolled = true;
343923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
344923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
345923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
346923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void clear() {
347923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mSuggestions = EMPTY_LIST;
348923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mTouchX = OUT_OF_BOUNDS;
349923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mSelectedString = null;
350923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mSelectedIndex = -1;
351923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        invalidate();
352923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        Arrays.fill(mWordWidth, 0);
353923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        Arrays.fill(mWordX, 0);
354923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (mPreviewPopup.isShowing()) {
355923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mPreviewPopup.dismiss();
356923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
357923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
358923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
359923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    @Override
360923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public boolean onTouchEvent(MotionEvent me) {
361923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
362923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (mGestureDetector.onTouchEvent(me)) {
363923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            return true;
364923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
365923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
366923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int action = me.getAction();
367923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int x = (int) me.getX();
368923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int y = (int) me.getY();
369923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mTouchX = x;
370923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
371923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        switch (action) {
372923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        case MotionEvent.ACTION_DOWN:
373923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mScrolled = false;
374923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            invalidate();
375923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            break;
376923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        case MotionEvent.ACTION_MOVE:
377923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (y <= 0) {
378923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                // Fling up!?
379923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                if (mSelectedString != null) {
380923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    if (!mShowingCompletions) {
381923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                        TextEntryState.acceptedSuggestion(mSuggestions.get(0),
382923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                mSelectedString);
383923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    }
384923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mService.pickSuggestionManually(mSelectedIndex, mSelectedString);
385923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mSelectedString = null;
386923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mSelectedIndex = -1;
387923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                }
388923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
389923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            invalidate();
390923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            break;
391923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        case MotionEvent.ACTION_UP:
392923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (!mScrolled) {
393923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                if (mSelectedString != null) {
394923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    if (!mShowingCompletions) {
395923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                        TextEntryState.acceptedSuggestion(mSuggestions.get(0),
396923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                mSelectedString);
397923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    }
398923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mService.pickSuggestionManually(mSelectedIndex, mSelectedString);
399923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                }
400923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
401923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mSelectedString = null;
402923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mSelectedIndex = -1;
403923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            removeHighlight();
4046ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani            hidePreview();
405923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            requestLayout();
406923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            break;
407923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
408923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        return true;
409923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
410923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
411923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /**
412923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * For flick through from keyboard, call this method with the x coordinate of the flick
413923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * gesture.
414923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     * @param x
415923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project     */
416923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void takeSuggestionAt(float x) {
417923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mTouchX = (int) x;
418923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        // To detect candidate
419923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        onDraw(null);
420923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (mSelectedString != null) {
421923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (!mShowingCompletions) {
422923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                TextEntryState.acceptedSuggestion(mSuggestions.get(0), mSelectedString);
423923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
424923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mService.pickSuggestionManually(mSelectedIndex, mSelectedString);
425923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
426923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        invalidate();
427923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_REMOVE_THROUGH_PREVIEW), 200);
428923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
429923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
4306ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani    private void hidePreview() {
4316ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani        mCurrentWordIndex = OUT_OF_BOUNDS;
4326ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani        if (mPreviewPopup.isShowing()) {
4336ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani            mHandler.sendMessageDelayed(mHandler
4346ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani                    .obtainMessage(MSG_REMOVE_PREVIEW), 60);
4356ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani        }
4366ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani    }
4376ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani
438923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private void showPreview(int wordIndex, String altText) {
439923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        int oldWordIndex = mCurrentWordIndex;
440923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mCurrentWordIndex = wordIndex;
441923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        // If index changed or changing text
442923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (oldWordIndex != mCurrentWordIndex || altText != null) {
443923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (wordIndex == OUT_OF_BOUNDS) {
4446ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani                hidePreview();
445923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            } else {
446923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                CharSequence word = altText != null? altText : mSuggestions.get(wordIndex);
447923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mPreviewText.setText(word);
448923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
449923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                        MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
450923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                int wordWidth = (int) (mPaint.measureText(word, 0, word.length()) + X_GAP * 2);
451923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                final int popupWidth = wordWidth
452923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                        + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight();
453923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                final int popupHeight = mPreviewText.getMeasuredHeight();
454923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                //mPreviewText.setVisibility(INVISIBLE);
455923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mPopupPreviewX = mWordX[wordIndex] - mPreviewText.getPaddingLeft() - mScrollX;
456923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mPopupPreviewY = - popupHeight;
457923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mHandler.removeMessages(MSG_REMOVE_PREVIEW);
458923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                int [] offsetInWindow = new int[2];
459923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                getLocationInWindow(offsetInWindow);
460923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                if (mPreviewPopup.isShowing()) {
461923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mPreviewPopup.update(mPopupPreviewX, mPopupPreviewY + offsetInWindow[1],
462923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                            popupWidth, popupHeight);
463923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                } else {
464923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mPreviewPopup.setWidth(popupWidth);
465923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mPreviewPopup.setHeight(popupHeight);
466923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    mPreviewPopup.showAtLocation(this, Gravity.NO_GRAVITY, mPopupPreviewX,
467923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                            mPopupPreviewY + offsetInWindow[1]);
468923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                }
469923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mPreviewText.setVisibility(VISIBLE);
470923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
471923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
472923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
473923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
474923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private void removeHighlight() {
475923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mTouchX = OUT_OF_BOUNDS;
476923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        invalidate();
477923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
478923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
479923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private void longPressFirstWord() {
480923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        CharSequence word = mSuggestions.get(0);
481923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (mService.addWordToDictionary(word.toString())) {
482923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            showPreview(0, getContext().getResources().getString(R.string.added_word, word));
483923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
484923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
4856ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani
4866ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani    @Override
4876ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani    public void onDetachedFromWindow() {
4886ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani        super.onDetachedFromWindow();
4896ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani        hidePreview();
4906ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani    }
491923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project}
492