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.content.res.Resources;
217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.graphics.Canvas;
227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.graphics.Paint;
237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.graphics.Paint.FontMetricsInt;
247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.graphics.drawable.Drawable;
257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.util.AttributeSet;
267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.KeyEvent;
277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.View;
287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectimport android.view.ViewGroup.LayoutParams;
297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project/**
317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * View used to show composing string (The Pinyin string for the unselected
327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * syllables and the Chinese string for the selected syllables.)
337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */
347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectpublic class ComposingView extends View {
357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * <p>
377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * There are three statuses for the composing view.
387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * </p>
397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     *
407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * <p>
417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * {@link #SHOW_PINYIN} is used to show the current Pinyin string without
427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * highlighted effect. When user inputs Pinyin characters one by one, the
437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Pinyin string will be shown in this mode.
447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * </p>
457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * <p>
467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * {@link #SHOW_STRING_LOWERCASE} is used to show the Pinyin string in
477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * lowercase with highlighted effect. When user presses UP key and there is
487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * no fixed Chinese characters, composing view will switch from
497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * {@link #SHOW_PINYIN} to this mode, and in this mode, user can press
507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * confirm key to input the lower-case string, so that user can input
517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * English letter in Chinese mode.
527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * </p>
537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * <p>
547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * {@link #EDIT_PINYIN} is used to edit the Pinyin string (shown with
557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * highlighted effect). When current status is {@link #SHOW_PINYIN} and user
567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * presses UP key, if there are fixed Characters, the input method will
577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * switch to {@link #EDIT_PINYIN} thus user can modify some characters in
587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * the middle of the Pinyin string. If the current status is
597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * {@link #SHOW_STRING_LOWERCASE} and user presses LEFT and RIGHT key, it
607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * will also switch to {@link #EDIT_PINYIN}.
617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * </p>
627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * <p>
637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Whenever user presses down key, the status switches to
647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * {@link #SHOW_PINYIN}.
657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * </p>
667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * <p>
677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * When composing view's status is {@link #SHOW_PINYIN}, the IME's status is
687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * {@link PinyinIME.ImeState#STATE_INPUT}, otherwise, the IME's status
697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * should be {@link PinyinIME.ImeState#STATE_COMPOSING}.
707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * </p>
717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public enum ComposingStatus {
737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        SHOW_PINYIN, SHOW_STRING_LOWERCASE, EDIT_PINYIN,
747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private static final int LEFT_RIGHT_MARGIN = 5;
777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Used to draw composing string. When drawing the active and idle part of
807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * the spelling(Pinyin) string, the color may be changed.
817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private Paint mPaint;
837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Drawable used to draw highlight effect.
867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private Drawable mHlDrawable;
887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Drawable used to draw cursor for editing mode.
917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private Drawable mCursor;
937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Used to estimate dimensions to show the string .
967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private FontMetricsInt mFmi;
987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private int mStrColor;
1007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private int mStrColorHl;
1017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private int mStrColorIdle;
1027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private int mFontSize;
1047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private ComposingStatus mComposingStatus;
1067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    PinyinIME.DecodingInfo mDecInfo;
1087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public ComposingView(Context context, AttributeSet attrs) {
1107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        super(context, attrs);
1117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        Resources r = context.getResources();
1137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mHlDrawable = r.getDrawable(R.drawable.composing_hl_bg);
1147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mCursor = r.getDrawable(R.drawable.composing_area_cursor);
1157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mStrColor = r.getColor(R.color.composing_color);
1177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mStrColorHl = r.getColor(R.color.composing_color_hl);
1187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mStrColorIdle = r.getColor(R.color.composing_color_idle);
1197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mFontSize = r.getDimensionPixelSize(R.dimen.composing_height);
1217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mPaint = new Paint();
1237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mPaint.setColor(mStrColor);
1247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mPaint.setAntiAlias(true);
1257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mPaint.setTextSize(mFontSize);
1267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mFmi = mPaint.getFontMetricsInt();
1287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
1297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void reset() {
1317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mComposingStatus = ComposingStatus.SHOW_PINYIN;
1327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
1337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    /**
1357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * Set the composing string to show. If the IME status is
1367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * {@link PinyinIME.ImeState#STATE_INPUT}, the composing view's status will
1377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * be set to {@link ComposingStatus#SHOW_PINYIN}, otherwise the composing
1387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * view will set its status to {@link ComposingStatus#SHOW_STRING_LOWERCASE}
1397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     * or {@link ComposingStatus#EDIT_PINYIN} automatically.
1407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project     */
1417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public void setDecodingInfo(PinyinIME.DecodingInfo decInfo,
1427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            PinyinIME.ImeState imeStatus) {
1437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mDecInfo = decInfo;
1447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (PinyinIME.ImeState.STATE_INPUT == imeStatus) {
1467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mComposingStatus = ComposingStatus.SHOW_PINYIN;
1477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mDecInfo.moveCursorToEdge(false);
1487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else {
1497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (decInfo.getFixedLen() != 0
1507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    || ComposingStatus.EDIT_PINYIN == mComposingStatus) {
1517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mComposingStatus = ComposingStatus.EDIT_PINYIN;
1527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else {
1537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mComposingStatus = ComposingStatus.SHOW_STRING_LOWERCASE;
1547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
1557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mDecInfo.moveCursor(0);
1567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
1577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
1597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        requestLayout();
1607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        invalidate();
1617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
1627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public boolean moveCursor(int keyCode) {
1647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (keyCode != KeyEvent.KEYCODE_DPAD_LEFT
1657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                && keyCode != KeyEvent.KEYCODE_DPAD_RIGHT) return false;
1667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (ComposingStatus.EDIT_PINYIN == mComposingStatus) {
1687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int offset = 0;
1697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT)
1707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                offset = -1;
1717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) offset = 1;
1727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mDecInfo.moveCursor(offset);
1737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else if (ComposingStatus.SHOW_STRING_LOWERCASE == mComposingStatus) {
1747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT
1757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
1767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                mComposingStatus = ComposingStatus.EDIT_PINYIN;
1777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
1797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                requestLayout();
1807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
1817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
1837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        invalidate();
1847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return true;
1857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
1867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    public ComposingStatus getComposingStatus() {
1887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return mComposingStatus;
1897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
1907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
1927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
1937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        float width;
1947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        int height;
1957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        height = mFmi.bottom - mFmi.top + mPaddingTop + mPaddingBottom;
1967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (null == mDecInfo) {
1987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            width = 0;
1997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        } else {
2007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            width = mPaddingLeft + mPaddingRight + LEFT_RIGHT_MARGIN * 2;
2017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            String str;
2037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (ComposingStatus.SHOW_STRING_LOWERCASE == mComposingStatus) {
2047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                str = mDecInfo.getOrigianlSplStr().toString();
2057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            } else {
2067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                str = mDecInfo.getComposingStrForDisplay();
2077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
2087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            width += mPaint.measureText(str, 0, str.length());
2097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        setMeasuredDimension((int) (width + 0.5f), height);
2117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
2127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    @Override
2147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    protected void onDraw(Canvas canvas) {
2157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (ComposingStatus.EDIT_PINYIN == mComposingStatus
2167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                || ComposingStatus.SHOW_PINYIN == mComposingStatus) {
2177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            drawForPinyin(canvas);
2187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            return;
2197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        float x, y;
2227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        x = mPaddingLeft + LEFT_RIGHT_MARGIN;
2237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        y = -mFmi.top + mPaddingTop;
2247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mPaint.setColor(mStrColorHl);
2267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mHlDrawable.setBounds(mPaddingLeft, mPaddingTop, getWidth()
2277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                - mPaddingRight, getHeight() - mPaddingBottom);
2287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mHlDrawable.draw(canvas);
2297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        String splStr = mDecInfo.getOrigianlSplStr().toString();
2317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        canvas.drawText(splStr, 0, splStr.length(), x, y, mPaint);
2327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
2337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void drawCursor(Canvas canvas, float x) {
2357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mCursor.setBounds((int) x, mPaddingTop, (int) x
2367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                + mCursor.getIntrinsicWidth(), getHeight() - mPaddingBottom);
2377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mCursor.draw(canvas);
2387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
2397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    private void drawForPinyin(Canvas canvas) {
2417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        float x, y;
2427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        x = mPaddingLeft + LEFT_RIGHT_MARGIN;
2437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        y = -mFmi.top + mPaddingTop;
2447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        mPaint.setColor(mStrColor);
2467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        int cursorPos = mDecInfo.getCursorPosInCmpsDisplay();
2487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        int cmpsPos = cursorPos;
2497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        String cmpsStr = mDecInfo.getComposingStrForDisplay();
2507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        int activeCmpsLen = mDecInfo.getActiveCmpsDisplayLen();
2517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (cursorPos > activeCmpsLen) cmpsPos = activeCmpsLen;
2527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        canvas.drawText(cmpsStr, 0, cmpsPos, x, y, mPaint);
2537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        x += mPaint.measureText(cmpsStr, 0, cmpsPos);
2547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (cursorPos <= activeCmpsLen) {
2557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (ComposingStatus.EDIT_PINYIN == mComposingStatus) {
2567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                drawCursor(canvas, x);
2577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
2587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            canvas.drawText(cmpsStr, cmpsPos, activeCmpsLen, x, y, mPaint);
2597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        x += mPaint.measureText(cmpsStr, cmpsPos, activeCmpsLen);
2627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        if (cmpsStr.length() > activeCmpsLen) {
2647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            mPaint.setColor(mStrColorIdle);
2657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            int oriPos = activeCmpsLen;
2667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            if (cursorPos > activeCmpsLen) {
2674248fb0083e2e0f2f9b379ea5ce898036b900218The Android Open Source Project                if (cursorPos > cmpsStr.length()) cursorPos = cmpsStr.length();
2687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                canvas.drawText(cmpsStr, oriPos, cursorPos, x, y, mPaint);
2697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                x += mPaint.measureText(cmpsStr, oriPos, cursorPos);
2707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                if (ComposingStatus.EDIT_PINYIN == mComposingStatus) {
2727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                    drawCursor(canvas, x);
2737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                }
2747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
2757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                oriPos = cursorPos;
2767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            }
2777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project            canvas.drawText(cmpsStr, oriPos, cmpsStr.length(), x, y, mPaint);
2787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        }
2797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
2807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project}
281