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