17898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project/* 27898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Copyright (C) 2009 The Android Open Source Project 37898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 47898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 57898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * you may not use this file except in compliance with the License. 67898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * You may obtain a copy of the License at 77898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 87898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 97898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * See the License for the specific language governing permissions and 147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * limitations under the License. 157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectpackage com.android.inputmethod.pinyin; 187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.content.Context; 207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.graphics.Canvas; 217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.graphics.Paint; 227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.graphics.Rect; 237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.graphics.Paint.FontMetricsInt; 247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.graphics.drawable.ColorDrawable; 257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.graphics.drawable.Drawable; 267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.os.Handler; 277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.Gravity; 287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.View; 297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.View.MeasureSpec; 307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.widget.PopupWindow; 317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project/** 337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Subclass of PopupWindow used as the feedback when user presses on a soft key 347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * or a candidate. 357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectpublic class BalloonHint extends PopupWindow { 377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Delayed time to show the balloon hint. 397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public static final int TIME_DELAY_SHOW = 0; 417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Delayed time to dismiss the balloon hint. 447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public static final int TIME_DELAY_DISMISS = 200; 467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The padding information of the balloon. Because PopupWindow's background 497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * can not be changed unless it is dismissed and shown again, we set the 507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * real background drawable to the content view, and make the PopupWindow's 517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * background transparent. So actually this padding information is for the 527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * content view. 537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private Rect mPaddingRect = new Rect(); 557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The context used to create this balloon hint object. 587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private Context mContext; 607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Parent used to show the balloon window. 637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private View mParent; 657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The content view of the balloon. 687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project BalloonView mBalloonView; 707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The measuring specification used to determine its size. Key-press 737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * balloons and candidates balloons have different measuring specifications. 747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mMeasureSpecMode; 767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Used to indicate whether the balloon needs to be dismissed forcibly. 797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private boolean mForceDismiss; 817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Timer used to show/dismiss the balloon window with some time delay. 847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private BalloonTimer mBalloonTimer; 867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mParentLocationInWindow[] = new int[2]; 887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public BalloonHint(Context context, View parent, int measureSpecMode) { 907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project super(context); 917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mParent = parent; 927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mMeasureSpecMode = measureSpecMode; 937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); 957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project setTouchable(false); 967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project setBackgroundDrawable(new ColorDrawable(0)); 977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonView = new BalloonView(context); 997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonView.setClickable(false); 1007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project setContentView(mBalloonView); 1017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonTimer = new BalloonTimer(); 1037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public Context getContext() { 1067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return mContext; 1077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public Rect getPadding() { 1107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return mPaddingRect; 1117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void setBalloonBackground(Drawable drawable) { 1147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // We usually pick up a background from a soft keyboard template, 1157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // and the object may has been set to this balloon before. 1167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mBalloonView.getBackground() == drawable) return; 1177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonView.setBackgroundDrawable(drawable); 1187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null != drawable) { 1207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project drawable.getPadding(mPaddingRect); 1217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 1227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPaddingRect.set(0, 0, 0, 0); 1237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Set configurations to show text label in this balloon. 1287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 1297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * @param label The text label to show in the balloon. 1307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * @param textSize The text size used to show label. 1317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * @param textBold Used to indicate whether the label should be bold. 1327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * @param textColor The text color used to show label. 1337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * @param width The desired width of the balloon. The real width is 1347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * determined by the desired width and balloon's measuring 1357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * specification. 1367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * @param height The desired width of the balloon. The real width is 1377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * determined by the desired width and balloon's measuring 1387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * specification. 1397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void setBalloonConfig(String label, float textSize, 1417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project boolean textBold, int textColor, int width, int height) { 1427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonView.setTextConfig(label, textSize, textBold, textColor); 1437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project setBalloonSize(width, height); 1447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 1477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Set configurations to show text label in this balloon. 1487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * 1497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * @param icon The icon used to shown in this balloon. 1507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * @param width The desired width of the balloon. The real width is 1517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * determined by the desired width and balloon's measuring 1527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * specification. 1537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * @param height The desired width of the balloon. The real width is 1547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * determined by the desired width and balloon's measuring 1557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * specification. 1567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 1577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void setBalloonConfig(Drawable icon, int width, int height) { 1587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonView.setIcon(icon); 1597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project setBalloonSize(width, height); 1607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public boolean needForceDismiss() { 1647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return mForceDismiss; 1657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public int getPaddingLeft() { 1687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return mPaddingRect.left; 1697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public int getPaddingTop() { 1727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return mPaddingRect.top; 1737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public int getPaddingRight() { 1767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return mPaddingRect.right; 1777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public int getPaddingBottom() { 1807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return mPaddingRect.bottom; 1817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void delayedShow(long delay, int locationInParent[]) { 1847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mBalloonTimer.isPending()) { 1857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonTimer.removeTimer(); 1867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (delay <= 0) { 1887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mParent.getLocationInWindow(mParentLocationInWindow); 1897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project showAtLocation(mParent, Gravity.LEFT | Gravity.TOP, 1907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project locationInParent[0], locationInParent[1] 1917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project + mParentLocationInWindow[1]); 1927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 1937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonTimer.startTimer(delay, BalloonTimer.ACTION_SHOW, 1947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project locationInParent, -1, -1); 1957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 1977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 1987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void delayedUpdate(long delay, int locationInParent[], 1997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int width, int height) { 2007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonView.invalidate(); 2017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mBalloonTimer.isPending()) { 2027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonTimer.removeTimer(); 2037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (delay <= 0) { 2057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mParent.getLocationInWindow(mParentLocationInWindow); 2067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project update(locationInParent[0], locationInParent[1] 2077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project + mParentLocationInWindow[1], width, height); 2087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 2097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonTimer.startTimer(delay, BalloonTimer.ACTION_UPDATE, 2107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project locationInParent, width, height); 2117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void delayedDismiss(long delay) { 2157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mBalloonTimer.isPending()) { 2167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonTimer.removeTimer(); 2177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int pendingAction = mBalloonTimer.getAction(); 2187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (0 != delay && BalloonTimer.ACTION_HIDE != pendingAction) { 2197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonTimer.run(); 2207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (delay <= 0) { 2237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project dismiss(); 2247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else { 2257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonTimer.startTimer(delay, BalloonTimer.ACTION_HIDE, null, -1, 2267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project -1); 2277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void removeTimer() { 2317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mBalloonTimer.isPending()) { 2327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonTimer.removeTimer(); 2337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private void setBalloonSize(int width, int height) { 2377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, 2387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mMeasureSpecMode); 2397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, 2407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mMeasureSpecMode); 2417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mBalloonView.measure(widthMeasureSpec, heightMeasureSpec); 2427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int oldWidth = getWidth(); 2447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int oldHeight = getHeight(); 2457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int newWidth = mBalloonView.getMeasuredWidth() + getPaddingLeft() 2467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project + getPaddingRight(); 2477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int newHeight = mBalloonView.getMeasuredHeight() + getPaddingTop() 2487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project + getPaddingBottom(); 2497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project setWidth(newWidth); 2507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project setHeight(newHeight); 2517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // If update() is called to update both size and position, the system 2537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // will first MOVE the PopupWindow to the new position, and then 2547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // perform a size-updating operation, so there will be a flash in 2557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // PopupWindow if user presses a key and moves finger to next one whose 2567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // size is different. 2577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // PopupWindow will handle the updating issue in one go in the future, 2587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // but before that, if we find the size is changed, a mandatory dismiss 2597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // operation is required. In our UI design, normal QWERTY keys' width 2607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // can be different in 1-pixel, and we do not dismiss the balloon when 2617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // user move between QWERTY keys. 2627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mForceDismiss = false; 2637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (isShowing()) { 2647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mForceDismiss = oldWidth - newWidth > 1 || newWidth - oldWidth > 1; 2657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private class BalloonTimer extends Handler implements Runnable { 2707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public static final int ACTION_SHOW = 1; 2717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public static final int ACTION_HIDE = 2; 2727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public static final int ACTION_UPDATE = 3; 2737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 2757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The pending action. 2767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 2777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mAction; 2787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mPositionInParent[] = new int[2]; 2807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mWidth; 2817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mHeight; 2827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private boolean mTimerPending = false; 2847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void startTimer(long time, int action, int positionInParent[], 2867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int width, int height) { 2877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mAction = action; 2887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (ACTION_HIDE != action) { 2897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPositionInParent[0] = positionInParent[0]; 2907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPositionInParent[1] = positionInParent[1]; 2917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mWidth = width; 2937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mHeight = height; 2947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project postDelayed(this, time); 2957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mTimerPending = true; 2967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 2977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 2987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public boolean isPending() { 2997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return mTimerPending; 3007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public boolean removeTimer() { 3037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (mTimerPending) { 3047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mTimerPending = false; 3057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project removeCallbacks(this); 3067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return true; 3077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return false; 3107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public int getAction() { 3137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return mAction; 3147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void run() { 3177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project switch (mAction) { 3187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case ACTION_SHOW: 3197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mParent.getLocationInWindow(mParentLocationInWindow); 3207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project showAtLocation(mParent, Gravity.LEFT | Gravity.TOP, 3217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPositionInParent[0], mPositionInParent[1] 3227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project + mParentLocationInWindow[1]); 3237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 3247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case ACTION_HIDE: 3257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project dismiss(); 3267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project break; 3277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project case ACTION_UPDATE: 3287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mParent.getLocationInWindow(mParentLocationInWindow); 3297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project update(mPositionInParent[0], mPositionInParent[1] 3307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project + mParentLocationInWindow[1], mWidth, mHeight); 3317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mTimerPending = false; 3337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private class BalloonView extends View { 3377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 3387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Suspension points used to display long items. 3397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 3407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private static final String SUSPENSION_POINTS = "..."; 3417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 3437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The icon to be shown. If it is not null, {@link #mLabel} will be 3447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * ignored. 3457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 3467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private Drawable mIcon; 3477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 3497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The label to be shown. It is enabled only if {@link #mIcon} is null. 3507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 3517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private String mLabel; 3527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private int mLabeColor = 0xff000000; 3547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private Paint mPaintLabel; 3557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private FontMetricsInt mFmi; 3567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project /** 3587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * The width to show suspension points. 3597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */ 3607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private float mSuspensionPointsWidth; 3617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public BalloonView(Context context) { 3647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project super(context); 3657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPaintLabel = new Paint(); 3667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPaintLabel.setColor(mLabeColor); 3677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPaintLabel.setAntiAlias(true); 3687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPaintLabel.setFakeBoldText(true); 3697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mFmi = mPaintLabel.getFontMetricsInt(); 3707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void setIcon(Drawable icon) { 3737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mIcon = icon; 3747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project public void setTextConfig(String label, float fontSize, 3777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project boolean textBold, int textColor) { 3787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project // Icon should be cleared so that the label will be enabled. 3797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mIcon = null; 3807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mLabel = label; 3817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPaintLabel.setTextSize(fontSize); 3827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPaintLabel.setFakeBoldText(textBold); 3837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPaintLabel.setColor(textColor); 3847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mFmi = mPaintLabel.getFontMetricsInt(); 3857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mSuspensionPointsWidth = mPaintLabel.measureText(SUSPENSION_POINTS); 3867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project @Override 3897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 3907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 3917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 3927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 3937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project final int heightSize = MeasureSpec.getSize(heightMeasureSpec); 3947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 3957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (widthMode == MeasureSpec.EXACTLY) { 3967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project setMeasuredDimension(widthSize, heightSize); 3977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return; 3987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 3997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int measuredWidth = mPaddingLeft + mPaddingRight; 4017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int measuredHeight = mPaddingTop + mPaddingBottom; 4027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null != mIcon) { 4037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project measuredWidth += mIcon.getIntrinsicWidth(); 4047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project measuredHeight += mIcon.getIntrinsicHeight(); 4057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (null != mLabel) { 4067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project measuredWidth += (int) (mPaintLabel.measureText(mLabel)); 4077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project measuredHeight += mFmi.bottom - mFmi.top; 4087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (widthSize > measuredWidth || widthMode == MeasureSpec.AT_MOST) { 4107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project measuredWidth = widthSize; 4117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (heightSize > measuredHeight 4147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project || heightMode == MeasureSpec.AT_MOST) { 4157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project measuredHeight = heightSize; 4167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int maxWidth = Environment.getInstance().getScreenWidth() - 4197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mPaddingLeft - mPaddingRight; 4207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (measuredWidth > maxWidth) { 4217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project measuredWidth = maxWidth; 4227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project setMeasuredDimension(measuredWidth, measuredHeight); 4247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project @Override 4277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project protected void onDraw(Canvas canvas) { 4287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int width = getWidth(); 4297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int height = getHeight(); 4307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (null != mIcon) { 4317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int marginLeft = (width - mIcon.getIntrinsicWidth()) / 2; 4327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int marginRight = width - mIcon.getIntrinsicWidth() 4337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project - marginLeft; 4347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int marginTop = (height - mIcon.getIntrinsicHeight()) / 2; 4357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int marginBottom = height - mIcon.getIntrinsicHeight() 4367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project - marginTop; 4377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mIcon.setBounds(marginLeft, marginTop, width - marginRight, 4387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project height - marginBottom); 4397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project mIcon.draw(canvas); 4407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } else if (null != mLabel) { 4417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project float labelMeasuredWidth = mPaintLabel.measureText(mLabel); 4427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project float x = mPaddingLeft; 4437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project x += (width - labelMeasuredWidth - mPaddingLeft - mPaddingRight) / 2.0f; 4447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project String labelToDraw = mLabel; 4457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (x < mPaddingLeft) { 4467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project x = mPaddingLeft; 4477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project labelToDraw = getLimitedLabelForDrawing(mLabel, 4487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project width - mPaddingLeft - mPaddingRight); 4497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int fontHeight = mFmi.bottom - mFmi.top; 4527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project float marginY = (height - fontHeight) / 2.0f; 4537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project float y = marginY - mFmi.top; 4547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project canvas.drawText(labelToDraw, x, y, mPaintLabel); 4557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project 4587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project private String getLimitedLabelForDrawing(String rawLabel, 4597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project float widthToDraw) { 4607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project int subLen = rawLabel.length(); 4617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (subLen <= 1) return rawLabel; 4627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project do { 4637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project subLen--; 4647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project float width = mPaintLabel.measureText(rawLabel, 0, subLen); 4657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project if (width + mSuspensionPointsWidth <= widthToDraw || 1 >= subLen) { 4667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project return rawLabel.substring(0, subLen) + 4677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project SUSPENSION_POINTS; 4687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } while (true); 4707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project } 4727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project} 473