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.util.AttributeSet;
216f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaokaimport android.util.Log;
2229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
235fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Key;
246f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard;
2501748cde4e692c970617e4478368f83b710a86b6Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardActionListener;
2635580bad6f3da3b204653825bbb6871563e70728Tom Ouyangimport com.android.inputmethod.keyboard.MoreKeysKeyboardView;
278c3d5b6961a9b9d40c4bf21ad495f852971c24f4Tadashi G. Takaokaimport com.android.inputmethod.latin.R;
286f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaokaimport com.android.inputmethod.latin.SuggestedWords;
2901748cde4e692c970617e4478368f83b710a86b6Tadashi G. Takaokaimport com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
305fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaokaimport com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionKey;
3129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
3229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka/**
3329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * A view that renders a virtual {@link MoreSuggestions}. It handles rendering of keys and detecting
3429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka * key presses and touch movements.
3529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka */
3635580bad6f3da3b204653825bbb6871563e70728Tom Ouyangpublic final class MoreSuggestionsView extends MoreKeysKeyboardView {
376f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka    private static final String TAG = MoreSuggestionsView.class.getSimpleName();
386f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka
3901748cde4e692c970617e4478368f83b710a86b6Tadashi G. Takaoka    public static abstract class MoreSuggestionsListener extends KeyboardActionListener.Adapter {
4035c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard        public abstract void onSuggestionSelected(final SuggestedWordInfo info);
4101748cde4e692c970617e4478368f83b710a86b6Tadashi G. Takaoka    }
4201748cde4e692c970617e4478368f83b710a86b6Tadashi G. Takaoka
43d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka    private boolean mIsInModalMode;
44d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka
453e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka    public MoreSuggestionsView(final Context context, final AttributeSet attrs) {
4608323cd597cd2c85eaf1ade9c98ee5fe9d8ecea2Tadashi G. Takaoka        this(context, attrs, R.attr.moreKeysKeyboardViewStyle);
4729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
4829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
493e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka    public MoreSuggestionsView(final Context context, final AttributeSet attrs,
503e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka            final int defStyle) {
5129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka        super(context, attrs, defStyle);
5235580bad6f3da3b204653825bbb6871563e70728Tom Ouyang    }
5329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
543d8848e5cb709fb47b450e7ede5a2926d99c957dTadashi G. Takaoka    // TODO: Remove redundant override method.
5535580bad6f3da3b204653825bbb6871563e70728Tom Ouyang    @Override
56aea429200e997762cd92744a2b1f3f586fc00b35Tadashi G. Takaoka    public void setKeyboard(final Keyboard keyboard) {
57aea429200e997762cd92744a2b1f3f586fc00b35Tadashi G. Takaoka        super.setKeyboard(keyboard);
58d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka        mIsInModalMode = false;
59aea429200e997762cd92744a2b1f3f586fc00b35Tadashi G. Takaoka        // With accessibility mode off, {@link #mAccessibilityDelegate} is set to null at the
60aea429200e997762cd92744a2b1f3f586fc00b35Tadashi G. Takaoka        // above {@link MoreKeysKeyboardView#setKeyboard(Keyboard)} call.
61dec599d1723f4ff52f066bd2dd1a4457d30cd33cTadashi G. Takaoka        // With accessibility mode on, {@link #mAccessibilityDelegate} is set to a
62dec599d1723f4ff52f066bd2dd1a4457d30cd33cTadashi G. Takaoka        // {@link MoreKeysKeyboardAccessibilityDelegate} object at the above
63adba09b54ed1b30bf9b24d632165229a0752b144Tadashi G. Takaoka        // {@link MoreKeysKeyboardView#setKeyboard(Keyboard)} call.
64adba09b54ed1b30bf9b24d632165229a0752b144Tadashi G. Takaoka        if (mAccessibilityDelegate != null) {
65adba09b54ed1b30bf9b24d632165229a0752b144Tadashi G. Takaoka            mAccessibilityDelegate.setOpenAnnounce(R.string.spoken_open_more_suggestions);
66adba09b54ed1b30bf9b24d632165229a0752b144Tadashi G. Takaoka            mAccessibilityDelegate.setCloseAnnounce(R.string.spoken_close_more_suggestions);
67aea429200e997762cd92744a2b1f3f586fc00b35Tadashi G. Takaoka        }
68aea429200e997762cd92744a2b1f3f586fc00b35Tadashi G. Takaoka    }
69aea429200e997762cd92744a2b1f3f586fc00b35Tadashi G. Takaoka
70aea429200e997762cd92744a2b1f3f586fc00b35Tadashi G. Takaoka    @Override
7135580bad6f3da3b204653825bbb6871563e70728Tom Ouyang    protected int getDefaultCoordX() {
7235580bad6f3da3b204653825bbb6871563e70728Tom Ouyang        final MoreSuggestions pane = (MoreSuggestions)getKeyboard();
7335580bad6f3da3b204653825bbb6871563e70728Tom Ouyang        return pane.mOccupiedWidth / 2;
7429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    }
7529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka
76bdc8b9e42b90e1fdf8e15d7ee5c0d319934fec0aTadashi G. Takaoka    public void updateKeyboardGeometry(final int keyHeight) {
7708ae0d5ca03ed455827e82222df249d1cafb5d71Tadashi G. Takaoka        updateKeyDrawParams(keyHeight);
78bdc8b9e42b90e1fdf8e15d7ee5c0d319934fec0aTadashi G. Takaoka    }
79bdc8b9e42b90e1fdf8e15d7ee5c0d319934fec0aTadashi G. Takaoka
80d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka    public void setModalMode() {
81d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka        mIsInModalMode = true;
8251c38a441a09a4920703e765cb26179e7a80f029Tadashi G. Takaoka        // Set vertical correction to zero (Reset more keys keyboard sliding allowance
832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa        // {@link R#dimen.config_more_keys_keyboard_slide_allowance}).
8451c38a441a09a4920703e765cb26179e7a80f029Tadashi G. Takaoka        mKeyDetector.setKeyboard(getKeyboard(), -getPaddingLeft(), -getPaddingTop());
8551c38a441a09a4920703e765cb26179e7a80f029Tadashi G. Takaoka    }
8651c38a441a09a4920703e765cb26179e7a80f029Tadashi G. Takaoka
87d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka    public boolean isInModalMode() {
88d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka        return mIsInModalMode;
89d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka    }
90d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka
9129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka    @Override
925fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaoka    protected void onKeyInput(final Key key, final int x, final int y) {
935fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaoka        if (!(key instanceof MoreSuggestionKey)) {
945fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaoka            Log.e(TAG, "Expected key is MoreSuggestionKey, but found "
955fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaoka                    + key.getClass().getName());
965fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaoka            return;
975fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaoka        }
986f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka        final Keyboard keyboard = getKeyboard();
996f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka        if (!(keyboard instanceof MoreSuggestions)) {
1006f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka            Log.e(TAG, "Expected keyboard is MoreSuggestions, but found "
1016f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka                    + keyboard.getClass().getName());
1026f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka            return;
1036f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka        }
1046f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka        final SuggestedWords suggestedWords = ((MoreSuggestions)keyboard).mSuggestedWords;
1055fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaoka        final int index = ((MoreSuggestionKey)key).mSuggestedWordIndex;
1066f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka        if (index < 0 || index >= suggestedWords.size()) {
1076f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka            Log.e(TAG, "Selected suggestion has an illegal index: " + index);
1086f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka            return;
1096f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka        }
1106f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka        if (!(mListener instanceof MoreSuggestionsListener)) {
1116f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka            Log.e(TAG, "Expected mListener is MoreSuggestionsListener, but found "
1126f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka                    + mListener.getClass().getName());
1136f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka            return;
11450e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka        }
11535c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard        ((MoreSuggestionsListener)mListener).onSuggestionSelected(suggestedWords.getInfo(index));
116fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang    }
11729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka}
118