SuggestionStripView.java revision 66a787b953d703201c6b827abbee74e8cd9bb063
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; 2466a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasaniimport android.content.res.Resources; 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; 296a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasaniimport android.graphics.Paint.Align; 30923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.graphics.drawable.Drawable; 31923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Handler; 32923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Message; 33923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.AttributeSet; 34923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.GestureDetector; 35923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.Gravity; 36923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.LayoutInflater; 37923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.MotionEvent; 38923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.View; 39923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.ViewGroup.LayoutParams; 40923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.widget.PopupWindow; 41923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.widget.TextView; 42923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 43923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpublic class CandidateView extends View { 44923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 45923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int OUT_OF_BOUNDS = -1; 46923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final List<CharSequence> EMPTY_LIST = new ArrayList<CharSequence>(); 47923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 48923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private LatinIME mService; 49923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private List<CharSequence> mSuggestions = EMPTY_LIST; 50923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mShowingCompletions; 51923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private CharSequence mSelectedString; 52923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mSelectedIndex; 53923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mTouchX = OUT_OF_BOUNDS; 54923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private Drawable mSelectionHighlight; 55923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mTypedWordValid; 56923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 57923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mHaveMinimalSuggestion; 58923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 59923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private Rect mBgPadding; 60923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 61923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private TextView mPreviewText; 62923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private PopupWindow mPreviewPopup; 63923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mCurrentWordIndex; 64923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private Drawable mDivider; 65923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 66923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int MAX_SUGGESTIONS = 32; 67923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int SCROLL_PIXELS = 20; 68923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 69923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int MSG_REMOVE_PREVIEW = 1; 70923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int MSG_REMOVE_THROUGH_PREVIEW = 2; 71923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 72923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int[] mWordWidth = new int[MAX_SUGGESTIONS]; 73923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int[] mWordX = new int[MAX_SUGGESTIONS]; 74923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mPopupPreviewX; 75923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mPopupPreviewY; 76923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 77923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int X_GAP = 10; 78923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 79923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mColorNormal; 80923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mColorRecommended; 81923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mColorOther; 82923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private Paint mPaint; 83923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mDescent; 84923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mScrolled; 8566a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani private boolean mShowingAddToDictionary; 8666a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani private CharSequence mWordToAddToDictionary; 8766a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani private CharSequence mAddToDictionaryHint; 8866a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani 89923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mTargetScrollX; 906a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 916a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani private int mMinTouchableWidth; 926a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 93923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mTotalWidth; 94923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 95923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private GestureDetector mGestureDetector; 96923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 97923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project Handler mHandler = new Handler() { 98923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 99923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void handleMessage(Message msg) { 100923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (msg.what) { 101923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project case MSG_REMOVE_PREVIEW: 102923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewText.setVisibility(GONE); 103923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 104923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project case MSG_REMOVE_THROUGH_PREVIEW: 105923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewText.setVisibility(GONE); 106923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mTouchX != OUT_OF_BOUNDS) { 107923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project removeHighlight(); 108923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 109923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 110923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 111923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 112923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 113923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project }; 114923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 115923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 116923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Construct a CandidateView for showing suggested words for completion. 117923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @param context 118923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @param attrs 119923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 120923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public CandidateView(Context context, AttributeSet attrs) { 121923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super(context, attrs); 122923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectionHighlight = context.getResources().getDrawable( 123466741d8a78965b8509bf527344f289e50873092Mike LeBeau R.drawable.list_selector_background_pressed); 124923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 125923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project LayoutInflater inflate = 126923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project (LayoutInflater) context 127923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 12866a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani Resources res = context.getResources(); 129923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewPopup = new PopupWindow(context); 130923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewText = (TextView) inflate.inflate(R.layout.candidate_preview, null); 131923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewPopup.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 132923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewPopup.setContentView(mPreviewText); 133923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewPopup.setBackgroundDrawable(null); 13466a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mColorNormal = res.getColor(R.color.candidate_normal); 13566a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mColorRecommended = res.getColor(R.color.candidate_recommended); 13666a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mColorOther = res.getColor(R.color.candidate_other); 13766a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mDivider = res.getDrawable(R.drawable.keyboard_suggest_strip_divider); 13866a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mAddToDictionaryHint = res.getString(R.string.hint_add_to_dictionary); 139923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 140923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPaint = new Paint(); 141923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPaint.setColor(mColorNormal); 142923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPaint.setAntiAlias(true); 143923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPaint.setTextSize(mPreviewText.getTextSize()); 144923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPaint.setStrokeWidth(0); 1456a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani mPaint.setTextAlign(Align.CENTER); 146923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mDescent = (int) mPaint.descent(); 1476a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani // 80 pixels for a 160dpi device would mean half an inch 1486a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani mMinTouchableWidth = (int) (getResources().getDisplayMetrics().density * 50); 149923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 150923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mGestureDetector = new GestureDetector(new GestureDetector.SimpleOnGestureListener() { 151923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 152923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onLongPress(MotionEvent me) { 153923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mSuggestions.size() > 0) { 1547a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani if (me.getX() + getScrollX() < mWordWidth[0] && getScrollX() < 10) { 155923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project longPressFirstWord(); 156923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 157923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 158923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 159923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 160923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 161923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean onScroll(MotionEvent e1, MotionEvent e2, 162923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project float distanceX, float distanceY) { 1636ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani final int width = getWidth(); 164923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mScrolled = true; 1657a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani int scrollX = getScrollX(); 1667a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollX += (int) distanceX; 1677a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani if (scrollX < 0) { 1687a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollX = 0; 169923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1707a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani if (distanceX > 0 && scrollX + width > mTotalWidth) { 1717a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollX -= (int) distanceX; 172923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1737a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani mTargetScrollX = scrollX; 1747a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollTo(scrollX, getScrollY()); 1756ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani hidePreview(); 176923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project invalidate(); 177923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 178923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 179923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project }); 180923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project setHorizontalFadingEdgeEnabled(true); 181923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project setWillNotDraw(false); 182923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project setHorizontalScrollBarEnabled(false); 183923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project setVerticalScrollBarEnabled(false); 1847a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollTo(0, getScrollY()); 185923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 186923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 187923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 188923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * A connection back to the service to communicate with the text field 189923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @param listener 190923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 191923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void setService(LatinIME listener) { 192923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mService = listener; 193923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 194923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 195923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 196923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public int computeHorizontalScrollRange() { 197923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return mTotalWidth; 198923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 199923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 200923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 201923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * If the canvas is null, then only touch calculations are performed to pick the target 202923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * candidate. 203923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 204923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 205923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project protected void onDraw(Canvas canvas) { 206923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (canvas != null) { 207923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onDraw(canvas); 208923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 209923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mTotalWidth = 0; 210923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mSuggestions == null) return; 211923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 212923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int height = getHeight(); 213923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mBgPadding == null) { 214923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBgPadding = new Rect(0, 0, 0, 0); 215923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (getBackground() != null) { 216923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project getBackground().getPadding(mBgPadding); 217923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2186a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani mDivider.setBounds(0, 0, mDivider.getIntrinsicWidth(), 219923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mDivider.getIntrinsicHeight()); 220923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 221923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int x = 0; 222923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int count = mSuggestions.size(); 223923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int width = getWidth(); 224923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final Rect bgPadding = mBgPadding; 225923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final Paint paint = mPaint; 226923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int touchX = mTouchX; 2277a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani final int scrollX = getScrollX(); 228923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final boolean scrolled = mScrolled; 229923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final boolean typedWordValid = mTypedWordValid; 230923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int y = (int) (height + mPaint.getTextSize() - mDescent) / 2; 231923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 232923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project for (int i = 0; i < count; i++) { 233923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence suggestion = mSuggestions.get(i); 234923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (suggestion == null) continue; 235923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project paint.setColor(mColorNormal); 236923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mHaveMinimalSuggestion 237923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project && ((i == 1 && !typedWordValid) || (i == 0 && typedWordValid))) { 238923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project paint.setTypeface(Typeface.DEFAULT_BOLD); 239923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project paint.setColor(mColorRecommended); 240923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else if (i != 0) { 241923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project paint.setColor(mColorOther); 242923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 243923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int wordWidth; 244923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mWordWidth[i] != 0) { 245923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project wordWidth = mWordWidth[i]; 246923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 247923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project float textWidth = paint.measureText(suggestion, 0, suggestion.length()); 2486a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani wordWidth = Math.max(mMinTouchableWidth, (int) textWidth + X_GAP * 2); 249923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mWordWidth[i] = wordWidth; 250923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 251923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 252923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mWordX[i] = x; 253923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2546ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani if (touchX + scrollX >= x && touchX + scrollX < x + wordWidth && !scrolled && 2556ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani touchX != OUT_OF_BOUNDS) { 25666a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani if (canvas != null && !mShowingAddToDictionary) { 257923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project canvas.translate(x, 0); 258923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectionHighlight.setBounds(0, bgPadding.top, wordWidth, height); 259923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectionHighlight.draw(canvas); 260923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project canvas.translate(-x, 0); 261923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project showPreview(i, null); 262923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 263923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectedString = suggestion; 264923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectedIndex = i; 265923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 266923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 267923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (canvas != null) { 2686a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani canvas.drawText(suggestion, 0, suggestion.length(), x + wordWidth / 2, y, paint); 269923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project paint.setColor(mColorOther); 270923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project canvas.translate(x + wordWidth, 0); 27166a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani // Draw a divider unless it's after the hint 27266a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani if (!(mShowingAddToDictionary && i == 1)) { 27366a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mDivider.draw(canvas); 27466a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani } 275923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project canvas.translate(-x - wordWidth, 0); 276923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 277923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project paint.setTypeface(Typeface.DEFAULT); 278923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project x += wordWidth; 279923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 280923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mTotalWidth = x; 2817a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani if (mTargetScrollX != scrollX) { 282923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project scrollToTarget(); 283923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 284923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 285923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 286923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void scrollToTarget() { 2877a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani int scrollX = getScrollX(); 2887a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani if (mTargetScrollX > scrollX) { 2897a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollX += SCROLL_PIXELS; 2907a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani if (scrollX >= mTargetScrollX) { 2917a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollX = mTargetScrollX; 2927a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollTo(scrollX, getScrollY()); 293923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project requestLayout(); 2947a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani } else { 2957a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollTo(scrollX, getScrollY()); 296923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 297923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 2987a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollX -= SCROLL_PIXELS; 2997a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani if (scrollX <= mTargetScrollX) { 3007a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollX = mTargetScrollX; 3017a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollTo(scrollX, getScrollY()); 302923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project requestLayout(); 3037a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani } else { 3047a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollTo(scrollX, getScrollY()); 305923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 306923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 307923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project invalidate(); 308923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 309923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 310923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void setSuggestions(List<CharSequence> suggestions, boolean completions, 311923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project boolean typedWordValid, boolean haveMinimalSuggestion) { 312923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project clear(); 313923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (suggestions != null) { 314923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSuggestions = new ArrayList<CharSequence>(suggestions); 315923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 316923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mShowingCompletions = completions; 317923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mTypedWordValid = typedWordValid; 3187a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani scrollTo(0, getScrollY()); 319923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mTargetScrollX = 0; 320923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mHaveMinimalSuggestion = haveMinimalSuggestion; 321923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Compute the total width 322923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project onDraw(null); 323923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project invalidate(); 324923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project requestLayout(); 325923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 326923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 32766a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani public void showAddToDictionaryHint(CharSequence word) { 32866a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mWordToAddToDictionary = word; 32966a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani ArrayList<CharSequence> suggestions = new ArrayList<CharSequence>(); 33066a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani suggestions.add(word); 33166a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani suggestions.add(mAddToDictionaryHint); 33266a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani setSuggestions(suggestions, false, false, false); 33366a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mShowingAddToDictionary = true; 33466a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani } 33566a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani 336923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void scrollPrev() { 337923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int i = 0; 338923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int count = mSuggestions.size(); 339923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int firstItem = 0; // Actually just before the first item, if at the boundary 340923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project while (i < count) { 3417a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani if (mWordX[i] < getScrollX() 3427a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani && mWordX[i] + mWordWidth[i] >= getScrollX() - 1) { 343923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project firstItem = i; 344923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 345923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 346923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project i++; 347923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 348923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int leftEdge = mWordX[firstItem] + mWordWidth[firstItem] - getWidth(); 349923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (leftEdge < 0) leftEdge = 0; 350923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateScrollPosition(leftEdge); 351923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 352923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 353923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void scrollNext() { 354923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int i = 0; 3557a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani int scrollX = getScrollX(); 3567a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani int targetX = scrollX; 357923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int count = mSuggestions.size(); 3587a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani int rightEdge = scrollX + getWidth(); 359923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project while (i < count) { 360923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mWordX[i] <= rightEdge && 361923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mWordX[i] + mWordWidth[i] >= rightEdge) { 362923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project targetX = Math.min(mWordX[i], mTotalWidth - getWidth()); 363923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 364923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 365923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project i++; 366923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 367923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateScrollPosition(targetX); 368923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 369923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 370923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void updateScrollPosition(int targetX) { 3717a722cbfc8bbb8a7b260895266a0fd3a9baf1994Amith Yamasani if (targetX != getScrollX()) { 372923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // TODO: Animate 373923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mTargetScrollX = targetX; 374923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project requestLayout(); 375923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project invalidate(); 376923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mScrolled = true; 377923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 378923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 379923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 380923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void clear() { 381923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSuggestions = EMPTY_LIST; 382923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mTouchX = OUT_OF_BOUNDS; 383923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectedString = null; 384923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectedIndex = -1; 38566a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mShowingAddToDictionary = false; 386923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project invalidate(); 387923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project Arrays.fill(mWordWidth, 0); 388923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project Arrays.fill(mWordX, 0); 389923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mPreviewPopup.isShowing()) { 390923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewPopup.dismiss(); 391923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 392923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 393923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 394923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 395923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean onTouchEvent(MotionEvent me) { 396923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 397923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mGestureDetector.onTouchEvent(me)) { 398923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 399923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 400923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 401923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int action = me.getAction(); 402923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int x = (int) me.getX(); 403923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int y = (int) me.getY(); 404923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mTouchX = x; 405923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 406923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (action) { 407923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project case MotionEvent.ACTION_DOWN: 408923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mScrolled = false; 409923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project invalidate(); 410923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 411923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project case MotionEvent.ACTION_MOVE: 412923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (y <= 0) { 413923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Fling up!? 414923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mSelectedString != null) { 415923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (!mShowingCompletions) { 416923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedSuggestion(mSuggestions.get(0), 417923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectedString); 418923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 419923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mService.pickSuggestionManually(mSelectedIndex, mSelectedString); 420923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectedString = null; 421923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectedIndex = -1; 422923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 423923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 424923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project invalidate(); 425923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 426923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project case MotionEvent.ACTION_UP: 427923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (!mScrolled) { 428923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mSelectedString != null) { 42966a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani if (mShowingAddToDictionary) { 43066a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani longPressFirstWord(); 43166a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani clear(); 43266a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani } else { 43366a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani if (!mShowingCompletions) { 43466a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani TextEntryState.acceptedSuggestion(mSuggestions.get(0), 43566a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mSelectedString); 43666a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani } 43766a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mService.pickSuggestionManually(mSelectedIndex, mSelectedString); 438923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 439923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 440923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 441923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectedString = null; 442923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSelectedIndex = -1; 443923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project removeHighlight(); 4446ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani hidePreview(); 445923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project requestLayout(); 446923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 447923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 448923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 449923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 450923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 451923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 452923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * For flick through from keyboard, call this method with the x coordinate of the flick 453923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * gesture. 454923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @param x 455923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 456923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void takeSuggestionAt(float x) { 457923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mTouchX = (int) x; 458923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // To detect candidate 459923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project onDraw(null); 460923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mSelectedString != null) { 461923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (!mShowingCompletions) { 462923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedSuggestion(mSuggestions.get(0), mSelectedString); 463923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 464923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mService.pickSuggestionManually(mSelectedIndex, mSelectedString); 465923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 466923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project invalidate(); 467923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_REMOVE_THROUGH_PREVIEW), 200); 468923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 469923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 4706ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani private void hidePreview() { 4716ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani mCurrentWordIndex = OUT_OF_BOUNDS; 4726ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani if (mPreviewPopup.isShowing()) { 4736ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani mHandler.sendMessageDelayed(mHandler 4746ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani .obtainMessage(MSG_REMOVE_PREVIEW), 60); 4756ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani } 4766ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani } 4776ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani 478923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void showPreview(int wordIndex, String altText) { 479923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int oldWordIndex = mCurrentWordIndex; 480923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCurrentWordIndex = wordIndex; 481923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // If index changed or changing text 482923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (oldWordIndex != mCurrentWordIndex || altText != null) { 483923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (wordIndex == OUT_OF_BOUNDS) { 4846ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani hidePreview(); 485923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 486923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence word = altText != null? altText : mSuggestions.get(wordIndex); 487923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewText.setText(word); 488923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 489923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 490923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int wordWidth = (int) (mPaint.measureText(word, 0, word.length()) + X_GAP * 2); 491923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int popupWidth = wordWidth 492923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight(); 493923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int popupHeight = mPreviewText.getMeasuredHeight(); 494923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project //mPreviewText.setVisibility(INVISIBLE); 4956a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani mPopupPreviewX = mWordX[wordIndex] - mPreviewText.getPaddingLeft() - getScrollX() 4966a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani + (mWordWidth[wordIndex] - wordWidth) / 2; 497923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPopupPreviewY = - popupHeight; 498923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mHandler.removeMessages(MSG_REMOVE_PREVIEW); 499923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int [] offsetInWindow = new int[2]; 500923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project getLocationInWindow(offsetInWindow); 501923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mPreviewPopup.isShowing()) { 502923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewPopup.update(mPopupPreviewX, mPopupPreviewY + offsetInWindow[1], 503923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project popupWidth, popupHeight); 504923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 505923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewPopup.setWidth(popupWidth); 506923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewPopup.setHeight(popupHeight); 507923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewPopup.showAtLocation(this, Gravity.NO_GRAVITY, mPopupPreviewX, 508923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPopupPreviewY + offsetInWindow[1]); 509923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 510923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mPreviewText.setVisibility(VISIBLE); 511923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 512923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 513923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 514923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 515923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void removeHighlight() { 516923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mTouchX = OUT_OF_BOUNDS; 517923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project invalidate(); 518923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 519923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 520923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void longPressFirstWord() { 521923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence word = mSuggestions.get(0); 5226a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani if (word.length() < 2) return; 523923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mService.addWordToDictionary(word.toString())) { 524923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project showPreview(0, getContext().getResources().getString(R.string.added_word, word)); 525923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 526923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 5276ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani 5286ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani @Override 5296ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani public void onDetachedFromWindow() { 5306ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani super.onDetachedFromWindow(); 5316ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani hidePreview(); 5326ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani } 533923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 534