MoreSuggestionsView.java revision 3e5a3c18bebbfb56012383411b24ee81ffde09cb
129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka/*
229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * Copyright (C) 2011 The Android Open Source Project
329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka *
429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License");
529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * you may not use this file except in compliance with the License.
629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * You may obtain a copy of the License at
729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka *
829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka *      http://www.apache.org/licenses/LICENSE-2.0
929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka *
1029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software
1129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS,
1229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * See the License for the specific language governing permissions and
1429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * limitations under the License.
1529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka */
1629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
178c3d5b6961a9b9d40c4bf21ad495f852971c24f4Tadashi G. Takaokapackage com.android.inputmethod.latin.suggestions;
1829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
1929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport android.content.Context;
2029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport android.content.res.Resources;
2129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport android.util.AttributeSet;
2229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport android.view.Gravity;
2350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaokaimport android.view.MotionEvent;
2429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport android.view.View;
2529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport android.widget.PopupWindow;
2629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
2729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyDetector;
2829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard;
2929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardActionListener;
3029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardView;
319734ecbf46cf5f68f4f7d373659713dfc55627a9Tadashi G. Takaokaimport com.android.inputmethod.keyboard.MoreKeysDetector;
3229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport com.android.inputmethod.keyboard.MoreKeysPanel;
3350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaokaimport com.android.inputmethod.keyboard.PointerTracker;
3429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
3550e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaokaimport com.android.inputmethod.keyboard.PointerTracker.KeyEventHandler;
3629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
378c3d5b6961a9b9d40c4bf21ad495f852971c24f4Tadashi G. Takaokaimport com.android.inputmethod.latin.R;
3829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
3929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka/**
4029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * A view that renders a virtual {@link MoreSuggestions}. It handles rendering of keys and detecting
4129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * key presses and touch movements.
4229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka */
43a28a05e971cc242b338331a3b78276fa95188d19Tadashi G. Takaokapublic final class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel {
4429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    private final int[] mCoordinates = new int[2];
4529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
4672913f97edb74e877f78b25418a568a4b0f5ae5cTadashi G. Takaoka    final KeyDetector mModalPanelKeyDetector;
4750e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka    private final KeyDetector mSlidingPanelKeyDetector;
4829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
4929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    private Controller mController;
5072913f97edb74e877f78b25418a568a4b0f5ae5cTadashi G. Takaoka    KeyboardActionListener mListener;
5129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    private int mOriginX;
5229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    private int mOriginY;
5329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
5472913f97edb74e877f78b25418a568a4b0f5ae5cTadashi G. Takaoka    static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy.Adapter();
5529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
5672913f97edb74e877f78b25418a568a4b0f5ae5cTadashi G. Takaoka    final KeyboardActionListener mSuggestionsPaneListener =
5729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka            new KeyboardActionListener.Adapter() {
5829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        @Override
593e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka        public void onPressKey(final int primaryCode) {
602a88440419f49d100c73e067a823390f64aba3b1Tadashi G. Takaoka            mListener.onPressKey(primaryCode);
6129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        }
6229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
6329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        @Override
643e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka        public void onReleaseKey(final int primaryCode, final boolean withSliding) {
652a88440419f49d100c73e067a823390f64aba3b1Tadashi G. Takaoka            mListener.onReleaseKey(primaryCode, withSliding);
6629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        }
6729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
6829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        @Override
693e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka        public void onCodeInput(final int primaryCode, final int x, final int y) {
708332fd0b81cf8232ca44e698ac3317f358d89ca9Tadashi G. Takaoka            final int index = primaryCode - MoreSuggestions.SUGGESTION_CODE_BASE;
714702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka            if (index >= 0 && index < SuggestionStripView.MAX_SUGGESTIONS) {
728332fd0b81cf8232ca44e698ac3317f358d89ca9Tadashi G. Takaoka                mListener.onCustomRequest(index);
738332fd0b81cf8232ca44e698ac3317f358d89ca9Tadashi G. Takaoka            }
7429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        }
7529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
7629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        @Override
7729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        public void onCancelInput() {
7829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka            mListener.onCancelInput();
7929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        }
8029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    };
8129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
823e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka    public MoreSuggestionsView(final Context context, final AttributeSet attrs) {
830e2fa6614435b0ba9ef83edd4067d085d6084e67Tadashi G. Takaoka        this(context, attrs, R.attr.moreSuggestionsViewStyle);
8429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
8529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
863e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka    public MoreSuggestionsView(final Context context, final AttributeSet attrs,
873e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka            final int defStyle) {
8829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        super(context, attrs, defStyle);
8929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
9029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        final Resources res = context.getResources();
9150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        mModalPanelKeyDetector = new KeyDetector(/* keyHysteresisDistance */ 0);
9250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        mSlidingPanelKeyDetector = new MoreKeysDetector(
9350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka                res.getDimension(R.dimen.more_suggestions_slide_allowance));
9429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        setKeyPreviewPopupEnabled(false, 0);
9529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
9629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
9729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
983e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
9929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        final Keyboard keyboard = getKeyboard();
10029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        if (keyboard != null) {
10129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka            final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight();
10229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka            final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom();
10329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka            setMeasuredDimension(width, height);
10429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        } else {
10529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
10629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        }
10729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
10829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
10929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
1103e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka    public void setKeyboard(final Keyboard keyboard) {
11129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        super.setKeyboard(keyboard);
11250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        mModalPanelKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), -getPaddingTop());
11350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        mSlidingPanelKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
11429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka                -getPaddingTop() + mVerticalCorrection);
11529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
11629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
11729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
11829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public KeyDetector getKeyDetector() {
11950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        return mSlidingPanelKeyDetector;
12029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
12129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
12229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
12329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public KeyboardActionListener getKeyboardActionListener() {
12429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        return mSuggestionsPaneListener;
12529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
12629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
12729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
12829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public DrawingProxy getDrawingProxy() {
1290cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka        return this;
13029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
13129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
13229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
13329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public TimerProxy getTimerProxy() {
13429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        return EMPTY_TIMER_PROXY;
13529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
13629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
13729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
1383e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka    public void setKeyPreviewPopupEnabled(final boolean previewEnabled, final int delay) {
13929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        // Suggestions pane needs no pop-up key preview displayed, so we pass always false with a
14029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        // delay of 0. The delay does not matter actually since the popup is not shown anyway.
14129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        super.setKeyPreviewPopupEnabled(false, 0);
14229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
14329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
14429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
1453e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka    public void showMoreKeysPanel(final View parentView, final Controller controller,
1463e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka            final int pointX, final int pointY, final PopupWindow window,
1473e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka            final KeyboardActionListener listener) {
14829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        mController = controller;
14929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        mListener = listener;
15029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        final View container = (View)getParent();
15129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        final MoreSuggestions pane = (MoreSuggestions)getKeyboard();
152bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        final int defaultCoordX = pane.mOccupiedWidth / 2;
153bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        // The coordinates of panel's left-top corner in parentView's coordinate system.
1547ecc1081ab9b4e41e4b2aec7877aaaf8df29e611Tadashi G. Takaoka        final int x = pointX - defaultCoordX - container.getPaddingLeft();
1557ecc1081ab9b4e41e4b2aec7877aaaf8df29e611Tadashi G. Takaoka        final int y = pointY - container.getMeasuredHeight() + container.getPaddingBottom();
15629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
15729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        window.setContentView(container);
15829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        window.setWidth(container.getMeasuredWidth());
15929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        window.setHeight(container.getMeasuredHeight());
160bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        parentView.getLocationInWindow(mCoordinates);
161bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        window.showAtLocation(parentView, Gravity.NO_GRAVITY,
162bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka                x + mCoordinates[0], y + mCoordinates[1]);
16329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
164bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        mOriginX = x + container.getPaddingLeft();
165bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        mOriginY = y + container.getPaddingTop();
16629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
16729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
1680cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka    private boolean mIsDismissing;
1690cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka
17029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
17129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public boolean dismissMoreKeysPanel() {
17232f4ceb2434b6f204cf8152b406d0f9a642feb73Tadashi G. Takaoka        if (mIsDismissing || mController == null) return false;
1730cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka        mIsDismissing = true;
1740cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka        final boolean dismissed = mController.dismissMoreKeysPanel();
1750cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka        mIsDismissing = false;
1760cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka        return dismissed;
17729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
17829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
17929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
1803e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka    public int translateX(final int x) {
18129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        return x - mOriginX;
18229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
18329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
18429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
1853e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka    public int translateY(final int y) {
18629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        return y - mOriginY;
18729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
18850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka
18950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka    private final KeyEventHandler mModalPanelKeyEventHandler = new KeyEventHandler() {
19050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        @Override
19150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        public KeyDetector getKeyDetector() {
19250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka            return mModalPanelKeyDetector;
19350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        }
19450e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka
19550e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        @Override
19650e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        public KeyboardActionListener getKeyboardActionListener() {
19750e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka            return mSuggestionsPaneListener;
19850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        }
19950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka
20050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        @Override
20150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        public DrawingProxy getDrawingProxy() {
20250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka            return MoreSuggestionsView.this;
20350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        }
20450e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka
20550e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        @Override
20650e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        public TimerProxy getTimerProxy() {
20750e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka            return EMPTY_TIMER_PROXY;
20850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        }
20950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka    };
21050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka
21150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka    @Override
2123e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka    public boolean onTouchEvent(final MotionEvent me) {
21350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final int action = me.getAction();
21450e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final long eventTime = me.getEventTime();
21550e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final int index = me.getActionIndex();
21650e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final int id = me.getPointerId(index);
21750e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final PointerTracker tracker = PointerTracker.getPointerTracker(id, this);
21850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final int x = (int)me.getX(index);
21950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final int y = (int)me.getY(index);
22050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        tracker.processMotionEvent(action, x, y, eventTime, mModalPanelKeyEventHandler);
22150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        return true;
22250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka    }
22329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka}
224