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 */
4329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokapublic 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
592a88440419f49d100c73e067a823390f64aba3b1Tadashi G. Takaoka        public void onPressKey(int primaryCode) {
602a88440419f49d100c73e067a823390f64aba3b1Tadashi G. Takaoka            mListener.onPressKey(primaryCode);
6129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        }
6229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
6329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        @Override
642a88440419f49d100c73e067a823390f64aba3b1Tadashi G. Takaoka        public void onReleaseKey(int primaryCode, boolean withSliding) {
652a88440419f49d100c73e067a823390f64aba3b1Tadashi G. Takaoka            mListener.onReleaseKey(primaryCode, withSliding);
6629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        }
6729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
6829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        @Override
69ca7ec2097ca6af1505c1e6aa8b81b6068ba46daesatok        public void onCodeInput(int primaryCode, int x, int y) {
708332fd0b81cf8232ca44e698ac3317f358d89ca9Tadashi G. Takaoka            final int index = primaryCode - MoreSuggestions.SUGGESTION_CODE_BASE;
718332fd0b81cf8232ca44e698ac3317f358d89ca9Tadashi G. Takaoka            if (index >= 0 && index < SuggestionsView.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
8229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public MoreSuggestionsView(Context context, AttributeSet attrs) {
830e2fa6614435b0ba9ef83edd4067d085d6084e67Tadashi G. Takaoka        this(context, attrs, R.attr.moreSuggestionsViewStyle);
8429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
8529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
8629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public MoreSuggestionsView(Context context, AttributeSet attrs, int defStyle) {
8729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        super(context, attrs, defStyle);
8829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
8929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        final Resources res = context.getResources();
9050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        mModalPanelKeyDetector = new KeyDetector(/* keyHysteresisDistance */ 0);
9150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        mSlidingPanelKeyDetector = new MoreKeysDetector(
9250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka                res.getDimension(R.dimen.more_suggestions_slide_allowance));
9329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        setKeyPreviewPopupEnabled(false, 0);
9429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
9529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
9629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
9729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
9829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        final Keyboard keyboard = getKeyboard();
9929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        if (keyboard != null) {
10029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka            final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight();
10129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka            final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom();
10229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka            setMeasuredDimension(width, height);
10329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        } else {
10429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
10529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        }
10629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
10729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
10829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
10929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public void setKeyboard(Keyboard keyboard) {
11029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        super.setKeyboard(keyboard);
11150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        mModalPanelKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), -getPaddingTop());
11250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        mSlidingPanelKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
11329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka                -getPaddingTop() + mVerticalCorrection);
11429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
11529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
11629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
11729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public KeyDetector getKeyDetector() {
11850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        return mSlidingPanelKeyDetector;
11929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
12029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
12129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
12229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public KeyboardActionListener getKeyboardActionListener() {
12329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        return mSuggestionsPaneListener;
12429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
12529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
12629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
12729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public DrawingProxy getDrawingProxy() {
1280cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka        return this;
12929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
13029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
13129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
13229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public TimerProxy getTimerProxy() {
13329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        return EMPTY_TIMER_PROXY;
13429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
13529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
13629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
13729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
13829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        // Suggestions pane needs no pop-up key preview displayed, so we pass always false with a
13929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        // delay of 0. The delay does not matter actually since the popup is not shown anyway.
14029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        super.setKeyPreviewPopupEnabled(false, 0);
14129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
14229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
14329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
14429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public void showMoreKeysPanel(View parentView, Controller controller, int pointX, int pointY,
14529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka            PopupWindow window, KeyboardActionListener listener) {
14629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        mController = controller;
14729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        mListener = listener;
14829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        final View container = (View)getParent();
14929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        final MoreSuggestions pane = (MoreSuggestions)getKeyboard();
150bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        final int defaultCoordX = pane.mOccupiedWidth / 2;
151bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        // The coordinates of panel's left-top corner in parentView's coordinate system.
1527ecc1081ab9b4e41e4b2aec7877aaaf8df29e611Tadashi G. Takaoka        final int x = pointX - defaultCoordX - container.getPaddingLeft();
1537ecc1081ab9b4e41e4b2aec7877aaaf8df29e611Tadashi G. Takaoka        final int y = pointY - container.getMeasuredHeight() + container.getPaddingBottom();
15429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
15529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        window.setContentView(container);
15629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        window.setWidth(container.getMeasuredWidth());
15729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        window.setHeight(container.getMeasuredHeight());
158bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        parentView.getLocationInWindow(mCoordinates);
159bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        window.showAtLocation(parentView, Gravity.NO_GRAVITY,
160bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka                x + mCoordinates[0], y + mCoordinates[1]);
16129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
162bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        mOriginX = x + container.getPaddingLeft();
163bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka        mOriginY = y + container.getPaddingTop();
16429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
16529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
1660cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka    private boolean mIsDismissing;
1670cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka
16829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
16929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public boolean dismissMoreKeysPanel() {
17032f4ceb2434b6f204cf8152b406d0f9a642feb73Tadashi G. Takaoka        if (mIsDismissing || mController == null) return false;
1710cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka        mIsDismissing = true;
1720cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka        final boolean dismissed = mController.dismissMoreKeysPanel();
1730cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka        mIsDismissing = false;
1740cf7a45ac53eef7399826a548a2ef8dab225bdf0Tadashi G. Takaoka        return dismissed;
17529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
17629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
17729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
17829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public int translateX(int x) {
17929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        return x - mOriginX;
18029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
18129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
18229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
18329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    public int translateY(int y) {
18429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        return y - mOriginY;
18529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
18650e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka
18750e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka    private final KeyEventHandler mModalPanelKeyEventHandler = new KeyEventHandler() {
18850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        @Override
18950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        public KeyDetector getKeyDetector() {
19050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka            return mModalPanelKeyDetector;
19150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        }
19250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka
19350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        @Override
19450e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        public KeyboardActionListener getKeyboardActionListener() {
19550e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka            return mSuggestionsPaneListener;
19650e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        }
19750e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka
19850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        @Override
19950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        public DrawingProxy getDrawingProxy() {
20050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka            return MoreSuggestionsView.this;
20150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        }
20250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka
20350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        @Override
20450e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        public TimerProxy getTimerProxy() {
20550e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka            return EMPTY_TIMER_PROXY;
20650e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        }
20750e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka    };
20850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka
20950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka    @Override
21050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka    public boolean onTouchEvent(MotionEvent me) {
21150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final int action = me.getAction();
21250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final long eventTime = me.getEventTime();
21350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final int index = me.getActionIndex();
21450e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final int id = me.getPointerId(index);
21550e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final PointerTracker tracker = PointerTracker.getPointerTracker(id, this);
21650e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final int x = (int)me.getX(index);
21750e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        final int y = (int)me.getY(index);
21850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        tracker.processMotionEvent(action, x, y, eventTime, mModalPanelKeyEventHandler);
21950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        return true;
22050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka    }
22129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka}
222