SuggestionStripView.java revision 01748cde4e692c970617e4478368f83b710a86b6
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/* 2913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka * Copyright (C) 2011 The Android Open Source Project 3e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka * 48aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 58aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * you may not use this file except in compliance with the License. 68aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * You may obtain a copy of the License at 7e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka * 88aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 9e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka * 10923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 118aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 128aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * See the License for the specific language governing permissions and 148aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * limitations under the License. 15923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 16923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 178c3d5b6961a9b9d40c4bf21ad495f852971c24f4Tadashi G. Takaokapackage com.android.inputmethod.latin.suggestions; 18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 19923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Context; 2066a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasaniimport android.content.res.Resources; 21c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaokaimport android.content.res.TypedArray; 22c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaokaimport android.graphics.Color; 23c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaokaimport android.graphics.drawable.Drawable; 24bcd30bf3e74c7c10d5b69a54cdf90c6b682a0747Tadashi G. Takaokaimport android.support.v4.view.ViewCompat; 256abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaokaimport android.text.TextUtils; 26923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.AttributeSet; 27c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaokaimport android.util.TypedValue; 283fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaokaimport android.view.GestureDetector; 29923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.LayoutInflater; 3029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport android.view.MotionEvent; 31923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.View; 32e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaokaimport android.view.View.OnClickListener; 33ae5c736e37973e26b201d45ff6c139862a6e05cfTadashi G. Takaokaimport android.view.View.OnLongClickListener; 34e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaokaimport android.view.ViewGroup; 359ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaokaimport android.view.ViewParent; 36c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaokaimport android.widget.ImageButton; 37c412309b7a32308b1b0a175dafc13f90254353c5Tadashi G. Takaokaimport android.widget.RelativeLayout; 38923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.widget.TextView; 39923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 407339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard; 41d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaokaimport com.android.inputmethod.keyboard.MainKeyboardView; 4229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport com.android.inputmethod.keyboard.MoreKeysPanel; 436f9105383a56c9ae15e35d3abf19c33d1efe5636Tadashi G. Takaokaimport com.android.inputmethod.latin.AudioAndHapticFeedbackManager; 445faf41951929301af80026bc3191812ef874fd5aTadashi G. Takaokaimport com.android.inputmethod.latin.Constants; 45ce78a2d8ab7630cff509c2b21b4b11abd8db4795Tadashi G. Takaokaimport com.android.inputmethod.latin.InputAttributes; 468c3d5b6961a9b9d40c4bf21ad495f852971c24f4Tadashi G. Takaokaimport com.android.inputmethod.latin.LatinImeLogger; 478c3d5b6961a9b9d40c4bf21ad495f852971c24f4Tadashi G. Takaokaimport com.android.inputmethod.latin.R; 488c3d5b6961a9b9d40c4bf21ad495f852971c24f4Tadashi G. Takaokaimport com.android.inputmethod.latin.SuggestedWords; 499310f42a36eabe99ed7dcd3b835d6cdaa3c6fdcaJean Chalardimport com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; 50a9ca7867b5a7c0be115966211a05f5d460c8638cKurt Partridgeimport com.android.inputmethod.latin.define.ProductionFlag; 51ce78a2d8ab7630cff509c2b21b4b11abd8db4795Tadashi G. Takaokaimport com.android.inputmethod.latin.settings.Settings; 5201748cde4e692c970617e4478368f83b710a86b6Tadashi G. Takaokaimport com.android.inputmethod.latin.suggestions.MoreSuggestionsView.MoreSuggestionsListener; 538dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.ImportantNoticeUtils; 546b966160ac8570271547bf63217efa5e228d4accKurt Partridgeimport com.android.inputmethod.research.ResearchLogger; 55ddb61ea461b920d87be4ad78c8a36eec1013b965Tadashi G. Takaoka 56179ada958b0bb46c6b9c8eb8b220d84dd3db855aTadashi G. Takaokaimport java.util.ArrayList; 57179ada958b0bb46c6b9c8eb8b220d84dd3db855aTadashi G. Takaoka 58a28a05e971cc242b338331a3b78276fa95188d19Tadashi G. Takaokapublic final class SuggestionStripView extends RelativeLayout implements OnClickListener, 59c412309b7a32308b1b0a175dafc13f90254353c5Tadashi G. Takaoka OnLongClickListener { 60c97810693dfe83bf37c09f73c8d4b40f2ba8dddbTadashi G. Takaoka public interface Listener { 6118d688c94bb8e1e26de2d12445cb3096c6126f75Jean Chalard public void addWordToUserDictionary(String word); 628a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka public void showImportantNoticeContents(); 639310f42a36eabe99ed7dcd3b835d6cdaa3c6fdcaJean Chalard public void pickSuggestionManually(int index, SuggestedWordInfo word); 64c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka public void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat); 65c97810693dfe83bf37c09f73c8d4b40f2ba8dddbTadashi G. Takaoka } 66c97810693dfe83bf37c09f73c8d4b40f2ba8dddbTadashi G. Takaoka 678c3d5b6961a9b9d40c4bf21ad495f852971c24f4Tadashi G. Takaoka static final boolean DBG = LatinImeLogger.sDBG; 68c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka private static final float DEBUG_INFO_TEXT_SIZE_IN_DIP = 6.0f; 696f7218627eda110a8454053f8ecb7b80edfdc8cesatok 70913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka private final ViewGroup mSuggestionsStrip; 71c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka private final ImageButton mVoiceKey; 72148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka private final ViewGroup mAddToDictionaryStrip; 738a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka private final View mImportantNoticeStrip; 74d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka MainKeyboardView mMainKeyboardView; 7574b6897a12ec603ef835aaa77a01f0c32f49aa1cTadashi G. Takaoka 7629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka private final View mMoreSuggestionsContainer; 7729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka private final MoreSuggestionsView mMoreSuggestionsView; 7829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka private final MoreSuggestions.Builder mMoreSuggestionsBuilder; 7929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 80a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka private final ArrayList<TextView> mWordViews = new ArrayList<>(); 81a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka private final ArrayList<TextView> mDebugInfoViews = new ArrayList<>(); 82a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka private final ArrayList<View> mDividerViews = new ArrayList<>(); 8374b6897a12ec603ef835aaa77a01f0c32f49aa1cTadashi G. Takaoka 843e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka Listener mListener; 856f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY; 864f8a8f125e329b55e49d31a98b5368113440c755Tadashi G. Takaoka private int mSuggestionsCountInStrip; 876a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 88653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka private final SuggestionStripLayoutHelper mLayoutHelper; 89148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka private final StripVisibilityGroup mStripVisibilityGroup; 90148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka 91148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka private static class StripVisibilityGroup { 92630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka private final View mSuggestionStripView; 93148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka private final View mSuggestionsStrip; 94c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka private final View mVoiceKey; 95148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka private final View mAddToDictionaryStrip; 968a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka private final View mImportantNoticeStrip; 97148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka 98630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka public StripVisibilityGroup(final View suggestionStripView, 99630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka final ViewGroup suggestionsStrip, final ImageButton voiceKey, 100630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka final ViewGroup addToDictionaryStrip, final View importantNoticeStrip) { 101630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka mSuggestionStripView = suggestionStripView; 102148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mSuggestionsStrip = suggestionsStrip; 103c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mVoiceKey = voiceKey; 104148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mAddToDictionaryStrip = addToDictionaryStrip; 1058a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mImportantNoticeStrip = importantNoticeStrip; 106c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka showSuggestionsStrip(false /* voiceKeyEnabled */); 107148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka } 108148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka 109630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka public void setLayoutDirection(final boolean isRtlLanguage) { 110630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka final int layoutDirection = isRtlLanguage ? ViewCompat.LAYOUT_DIRECTION_RTL 111630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka : ViewCompat.LAYOUT_DIRECTION_LTR; 112630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka ViewCompat.setLayoutDirection(mSuggestionStripView, layoutDirection); 113bcd30bf3e74c7c10d5b69a54cdf90c6b682a0747Tadashi G. Takaoka ViewCompat.setLayoutDirection(mSuggestionsStrip, layoutDirection); 114bcd30bf3e74c7c10d5b69a54cdf90c6b682a0747Tadashi G. Takaoka ViewCompat.setLayoutDirection(mAddToDictionaryStrip, layoutDirection); 1158a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka ViewCompat.setLayoutDirection(mImportantNoticeStrip, layoutDirection); 116bcd30bf3e74c7c10d5b69a54cdf90c6b682a0747Tadashi G. Takaoka } 117bcd30bf3e74c7c10d5b69a54cdf90c6b682a0747Tadashi G. Takaoka 118c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka public void showSuggestionsStrip(final boolean enableVoiceKey) { 119148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mSuggestionsStrip.setVisibility(VISIBLE); 120c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mVoiceKey.setVisibility(enableVoiceKey ? VISIBLE : INVISIBLE); 121148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mAddToDictionaryStrip.setVisibility(INVISIBLE); 1228a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mImportantNoticeStrip.setVisibility(INVISIBLE); 123148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka } 124148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka 125148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka public void showAddToDictionaryStrip() { 126148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mSuggestionsStrip.setVisibility(INVISIBLE); 127c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mVoiceKey.setVisibility(INVISIBLE); 128148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mAddToDictionaryStrip.setVisibility(VISIBLE); 1298a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mImportantNoticeStrip.setVisibility(INVISIBLE); 1308a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka } 1318a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka 13208103a0e0784ef0396fd17cbd955309270f8d3a9Tadashi G. Takaoka public void showImportantNoticeStrip(final boolean enableVoiceKey) { 1338a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mSuggestionsStrip.setVisibility(INVISIBLE); 13408103a0e0784ef0396fd17cbd955309270f8d3a9Tadashi G. Takaoka mVoiceKey.setVisibility(enableVoiceKey ? VISIBLE : INVISIBLE); 1358a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mAddToDictionaryStrip.setVisibility(INVISIBLE); 1368a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mImportantNoticeStrip.setVisibility(VISIBLE); 137148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka } 138148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka 139148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka public boolean isShowingAddToDictionaryStrip() { 140148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka return mAddToDictionaryStrip.getVisibility() == VISIBLE; 141148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka } 142148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka } 14374b6897a12ec603ef835aaa77a01f0c32f49aa1cTadashi G. Takaoka 144923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 1454702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka * Construct a {@link SuggestionStripView} for showing suggestions to be picked by the user. 146923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @param context 147923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @param attrs 148923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 1493e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka public SuggestionStripView(final Context context, final AttributeSet attrs) { 1504702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka this(context, attrs, R.attr.suggestionStripViewStyle); 15108a6f2aea71d998206c47c16dcda4eaa90f8c9eaTadashi G. Takaoka } 15208a6f2aea71d998206c47c16dcda4eaa90f8c9eaTadashi G. Takaoka 1533e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka public SuggestionStripView(final Context context, final AttributeSet attrs, 1543e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka final int defStyle) { 155c412309b7a32308b1b0a175dafc13f90254353c5Tadashi G. Takaoka super(context, attrs, defStyle); 156923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 15716713e5630b93fb5625df26745eb73271f189457Tadashi G. Takaoka final LayoutInflater inflater = LayoutInflater.from(context); 158913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka inflater.inflate(R.layout.suggestions_strip, this); 15986e815a142c8aa13213151e381a8a24ef23073d3Tadashi G. Takaoka 160913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka mSuggestionsStrip = (ViewGroup)findViewById(R.id.suggestions_strip); 161c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mVoiceKey = (ImageButton)findViewById(R.id.suggestions_strip_voice_key); 162148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mAddToDictionaryStrip = (ViewGroup)findViewById(R.id.add_to_dictionary_strip); 1638a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mImportantNoticeStrip = findViewById(R.id.important_notice_strip); 164630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka mStripVisibilityGroup = new StripVisibilityGroup(this, mSuggestionsStrip, mVoiceKey, 165c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mAddToDictionaryStrip, mImportantNoticeStrip); 166148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka 167a1ed211c4e80eb81ce399e0eaff88bbdf1e3199fJean Chalard for (int pos = 0; pos < SuggestedWords.MAX_SUGGESTIONS; pos++) { 168c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka final TextView word = new TextView(context, null, R.attr.suggestionWordStyle); 1692442e779857e7eda253aadcb1c4dff5ccb3e53f4Tadashi G. Takaoka word.setOnClickListener(this); 170ae5c736e37973e26b201d45ff6c139862a6e05cfTadashi G. Takaoka word.setOnLongClickListener(this); 171500a9752b1e61885f37b0fb26f09dfdd65da4e5eTadashi G. Takaoka mWordViews.add(word); 172913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka final View divider = inflater.inflate(R.layout.suggestion_divider, null); 173a1aab83a24e74cb0fad4b1c1e59b18d23ecbdad3Tadashi G. Takaoka divider.setOnClickListener(this); 174500a9752b1e61885f37b0fb26f09dfdd65da4e5eTadashi G. Takaoka mDividerViews.add(divider); 175c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka final TextView info = new TextView(context, null, R.attr.suggestionWordStyle); 176c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka info.setTextColor(Color.WHITE); 177c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka info.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEBUG_INFO_TEXT_SIZE_IN_DIP); 178c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka mDebugInfoViews.add(info); 179c9716b28ce438e06b5cacc07fc002944bcbe24a0Tadashi G. Takaoka } 180179ada958b0bb46c6b9c8eb8b220d84dd3db855aTadashi G. Takaoka 181653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka mLayoutHelper = new SuggestionStripLayoutHelper( 182500a9752b1e61885f37b0fb26f09dfdd65da4e5eTadashi G. Takaoka context, attrs, defStyle, mWordViews, mDividerViews, mDebugInfoViews); 18329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 18429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka mMoreSuggestionsContainer = inflater.inflate(R.layout.more_suggestions, null); 18529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka mMoreSuggestionsView = (MoreSuggestionsView)mMoreSuggestionsContainer 18629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka .findViewById(R.id.more_suggestions_view); 18708ae0d5ca03ed455827e82222df249d1cafb5d71Tadashi G. Takaoka mMoreSuggestionsBuilder = new MoreSuggestions.Builder(context, mMoreSuggestionsView); 188bfc1d732ac92fa1bd5b19ad9e7c71ce9a1f9dc00Tadashi G. Takaoka 18950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka final Resources res = context.getResources(); 19050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka mMoreSuggestionsModalTolerance = res.getDimensionPixelOffset( 1912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa R.dimen.config_more_suggestions_modal_tolerance); 1923fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka mMoreSuggestionsSlidingDetector = new GestureDetector( 1933fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka context, mMoreSuggestionsSlidingListener); 194c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka 195c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka final TypedArray keyboardAttr = context.obtainStyledAttributes(attrs, 196c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka R.styleable.Keyboard, defStyle, R.style.SuggestionStripView); 197c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka final Drawable iconVoice = keyboardAttr.getDrawable(R.styleable.Keyboard_iconShortcutKey); 198c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka keyboardAttr.recycle(); 199c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mVoiceKey.setImageDrawable(iconVoice); 200c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mVoiceKey.setOnClickListener(this); 201923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 202c9716b28ce438e06b5cacc07fc002944bcbe24a0Tadashi G. Takaoka 203923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 204c97810693dfe83bf37c09f73c8d4b40f2ba8dddbTadashi G. Takaoka * A connection back to the input method. 205923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @param listener 206923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 2073e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka public void setListener(final Listener listener, final View inputView) { 208c97810693dfe83bf37c09f73c8d4b40f2ba8dddbTadashi G. Takaoka mListener = listener; 209d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka mMainKeyboardView = (MainKeyboardView)inputView.findViewById(R.id.keyboard_view); 210923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 211923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 212c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka private boolean isVoiceKeyEnabled() { 213c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka if (mMainKeyboardView == null) { 214c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka return false; 215c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka } 216c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka final Keyboard keyboard = mMainKeyboardView.getKeyboard(); 217c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka if (keyboard == null) { 218c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka return false; 219c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka } 220c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka return keyboard.mId.mHasShortcutKey; 221c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka } 222c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka 223bcd30bf3e74c7c10d5b69a54cdf90c6b682a0747Tadashi G. Takaoka public void setSuggestions(final SuggestedWords suggestedWords, final boolean isRtlLanguage) { 224e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka clear(); 225630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka mStripVisibilityGroup.setLayoutDirection(isRtlLanguage); 226e79b1a83126b41e09a8ec0a8dbb751ae0e02c7f6Tadashi G. Takaoka mSuggestedWords = suggestedWords; 2274f8a8f125e329b55e49d31a98b5368113440c755Tadashi G. Takaoka mSuggestionsCountInStrip = mLayoutHelper.layoutAndReturnSuggestionCountInStrip( 2284f8a8f125e329b55e49d31a98b5368113440c755Tadashi G. Takaoka mSuggestedWords, mSuggestionsStrip, this); 2299c3860ce461c3791891bf667edc77fe798c8d332Ken Wakasa if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { 2304702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka ResearchLogger.suggestionStripView_setSuggestions(mSuggestedWords); 231a9ca7867b5a7c0be115966211a05f5d460c8638cKurt Partridge } 232c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mStripVisibilityGroup.showSuggestionsStrip(isVoiceKeyEnabled()); 23316713e5630b93fb5625df26745eb73271f189457Tadashi G. Takaoka } 23474b6897a12ec603ef835aaa77a01f0c32f49aa1cTadashi G. Takaoka 235c160a3932f74fea72c5347798c001d4ae961864cKen Wakasa public int setMoreSuggestionsHeight(final int remainingHeight) { 236c160a3932f74fea72c5347798c001d4ae961864cKen Wakasa return mLayoutHelper.setMoreSuggestionsHeight(remainingHeight); 237c8b0e5797e20d3fa25d319a9709aabc9149f8ff9Tadashi G. Takaoka } 238b47319867ef3834a222865b8cb6abe62962e70f7Tadashi G. Takaoka 239b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani public boolean isShowingAddToDictionaryHint() { 240148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka return mStripVisibilityGroup.isShowingAddToDictionaryStrip(); 241b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 242b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani 2439b1a66843ddde552ea626a7b24c2c71ba23aa63aTadashi G. Takaoka public void showAddToDictionaryHint(final String word) { 2442b479cccaeb0bb54121730cb5e47cca3f7517c67Tadashi G. Takaoka mLayoutHelper.layoutAddToDictionaryHint(word, mAddToDictionaryStrip); 245148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka // {@link TextView#setTag()} is used to hold the word to be added to dictionary. The word 246148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka // will be extracted at {@link #onClick(View)}. 247148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mAddToDictionaryStrip.setTag(word); 248148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mAddToDictionaryStrip.setOnClickListener(this); 249148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mStripVisibilityGroup.showAddToDictionaryStrip(); 25066a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani } 25166a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani 2526558253160e2039c87f424bd814f402ecd31de3bKen Wakasa public boolean dismissAddToDictionaryHint() { 253c04bbc1ae9be81d25a356407c27a8e7fa22028bfTadashi G. Takaoka if (isShowingAddToDictionaryHint()) { 254c04bbc1ae9be81d25a356407c27a8e7fa22028bfTadashi G. Takaoka clear(); 255c04bbc1ae9be81d25a356407c27a8e7fa22028bfTadashi G. Takaoka return true; 256c04bbc1ae9be81d25a356407c27a8e7fa22028bfTadashi G. Takaoka } 257c04bbc1ae9be81d25a356407c27a8e7fa22028bfTadashi G. Takaoka return false; 2586558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } 2596558253160e2039c87f424bd814f402ecd31de3bKen Wakasa 2608dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka // This method checks if we should show the important notice (checks on permanent storage if 2618dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka // it has been shown once already or not, and if in the setup wizard). If applicable, it shows 2628dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka // the notice. In all cases, it returns true if it was shown, false otherwise. 263ce78a2d8ab7630cff509c2b21b4b11abd8db4795Tadashi G. Takaoka public boolean maybeShowImportantNoticeTitle(final InputAttributes inputAttributes) { 264ce78a2d8ab7630cff509c2b21b4b11abd8db4795Tadashi G. Takaoka if (!ImportantNoticeUtils.shouldShowImportantNotice(getContext(), inputAttributes)) { 2658dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka return false; 2668dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka } 26714e908c3486ae5996e66625e959ff45c5f3740efTadashi G. Takaoka if (getWidth() <= 0) { 268affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka return false; 269affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka } 2701672ccbbb6167f434842093feaadc2bcd5634eabTadashi G. Takaoka final String importantNoticeTitle = ImportantNoticeUtils.getNextImportantNoticeTitle( 2716abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka getContext()); 2726abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka if (TextUtils.isEmpty(importantNoticeTitle)) { 2736abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka return false; 2746abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka } 275c8abd13c77ed90b209301ea379e1142e0d60e3f5Tadashi G. Takaoka if (isShowingMoreSuggestionPanel()) { 276c8abd13c77ed90b209301ea379e1142e0d60e3f5Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 277c8abd13c77ed90b209301ea379e1142e0d60e3f5Tadashi G. Takaoka } 27814e908c3486ae5996e66625e959ff45c5f3740efTadashi G. Takaoka mLayoutHelper.layoutImportantNotice(mImportantNoticeStrip, importantNoticeTitle); 27908103a0e0784ef0396fd17cbd955309270f8d3a9Tadashi G. Takaoka mStripVisibilityGroup.showImportantNoticeStrip(isVoiceKeyEnabled()); 2808a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mImportantNoticeStrip.setOnClickListener(this); 2818dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka return true; 2828a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka } 2838a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka 284923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void clear() { 285913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka mSuggestionsStrip.removeAllViews(); 2869ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka removeAllDebugInfoViews(); 287c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mStripVisibilityGroup.showSuggestionsStrip(false /* enableVoiceKey */); 28819dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 289923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 290923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2919ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka private void removeAllDebugInfoViews() { 2929ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka // The debug info views may be placed as children views of this {@link SuggestionStripView}. 2939ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka for (final View debugInfoView : mDebugInfoViews) { 2949ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka final ViewParent parent = debugInfoView.getParent(); 2959ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka if (parent instanceof ViewGroup) { 2969ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka ((ViewGroup)parent).removeView(debugInfoView); 2979ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka } 2989ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka } 2999ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka } 3009ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka 3016f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka private final MoreSuggestionsListener mMoreSuggestionsListener = new MoreSuggestionsListener() { 30229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka @Override 3036f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka public void onSuggestionSelected(final int index, final SuggestedWordInfo wordInfo) { 3049310f42a36eabe99ed7dcd3b835d6cdaa3c6fdcaJean Chalard mListener.pickSuggestionManually(index, wordInfo); 30519dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 30629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka } 30729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 30829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka @Override 30929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka public void onCancelInput() { 31019dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 31129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka } 31229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka }; 31329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 31429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka private final MoreKeysPanel.Controller mMoreSuggestionsController = 31529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka new MoreKeysPanel.Controller() { 31629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka @Override 3171f215a58c99f0eb2f536e9cccd51371f2883e201Tadashi G. Takaoka public void onDismissMoreKeysPanel() { 3181f215a58c99f0eb2f536e9cccd51371f2883e201Tadashi G. Takaoka mMainKeyboardView.onDismissMoreKeysPanel(); 319fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang } 320fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang 321fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang @Override 322a729377395967f7652d93992cbcf50cd2ff522d1Tadashi G. Takaoka public void onShowMoreKeysPanel(final MoreKeysPanel panel) { 323d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka mMainKeyboardView.onShowMoreKeysPanel(panel); 32429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka } 325ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang 326ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang @Override 3271f215a58c99f0eb2f536e9cccd51371f2883e201Tadashi G. Takaoka public void onCancelMoreKeysPanel() { 32819dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 329ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang } 33029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka }; 33129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 33219dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka public boolean isShowingMoreSuggestionPanel() { 33319dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka return mMoreSuggestionsView.isShowingInParent(); 33419dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka } 33519dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka 33619dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka public void dismissMoreSuggestionsPanel() { 33719dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka mMoreSuggestionsView.dismissMoreKeysPanel(); 33819dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka } 33919dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka 340e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka @Override 3413e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka public boolean onLongClick(final View view) { 342ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback( 3436f9105383a56c9ae15e35d3abf19c33d1efe5636Tadashi G. Takaoka Constants.NOT_A_CODE, this); 3443fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka return showMoreSuggestions(); 3453fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka } 3463fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka 3473e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka boolean showMoreSuggestions() { 34856e0373b5c0c516cd57352cebf882e2b358f168cTadashi G. Takaoka final Keyboard parentKeyboard = mMainKeyboardView.getKeyboard(); 3497339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka if (parentKeyboard == null) { 3507339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka return false; 351ae5c736e37973e26b201d45ff6c139862a6e05cfTadashi G. Takaoka } 352653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka final SuggestionStripLayoutHelper layoutHelper = mLayoutHelper; 353653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka if (!layoutHelper.mMoreSuggestionsAvailable) { 3547339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka return false; 3557339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka } 35656e0373b5c0c516cd57352cebf882e2b358f168cTadashi G. Takaoka // Dismiss another {@link MoreKeysPanel} that may be being showed, for example 35756e0373b5c0c516cd57352cebf882e2b358f168cTadashi G. Takaoka // {@link MoreKeysKeyboardView}. 3581f215a58c99f0eb2f536e9cccd51371f2883e201Tadashi G. Takaoka mMainKeyboardView.onDismissMoreKeysPanel(); 359ddc21f5bd1113c24840fd436d09de62c8e476335Tadashi G. Takaoka // Dismiss all key previews and sliding key input preview that may be being showed. 360ddc21f5bd1113c24840fd436d09de62c8e476335Tadashi G. Takaoka mMainKeyboardView.dismissAllKeyPreviews(); 361ddc21f5bd1113c24840fd436d09de62c8e476335Tadashi G. Takaoka mMainKeyboardView.dismissSlidingKeyInputPreview(); 3627339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final int stripWidth = getWidth(); 3637339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final View container = mMoreSuggestionsContainer; 3647339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final int maxWidth = stripWidth - container.getPaddingLeft() - container.getPaddingRight(); 3657339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final MoreSuggestions.Builder builder = mMoreSuggestionsBuilder; 3664f8a8f125e329b55e49d31a98b5368113440c755Tadashi G. Takaoka builder.layout(mSuggestedWords, mSuggestionsCountInStrip, maxWidth, 367653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka (int)(maxWidth * layoutHelper.mMinMoreSuggestionsWidth), 368653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka layoutHelper.getMaxMoreSuggestionsRow(), parentKeyboard); 3697339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka mMoreSuggestionsView.setKeyboard(builder.build()); 3707339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 3717339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka 3727339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final MoreKeysPanel moreKeysPanel = mMoreSuggestionsView; 3737339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final int pointX = stripWidth / 2; 374653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka final int pointY = -layoutHelper.mMoreSuggestionsBottomGap; 3757339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka moreKeysPanel.showMoreKeysPanel(this, mMoreSuggestionsController, pointX, pointY, 376fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang mMoreSuggestionsListener); 3777339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka mOriginX = mLastX; 3787339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka mOriginY = mLastY; 3794f8a8f125e329b55e49d31a98b5368113440c755Tadashi G. Takaoka for (int i = 0; i < mSuggestionsCountInStrip; i++) { 380500a9752b1e61885f37b0fb26f09dfdd65da4e5eTadashi G. Takaoka mWordViews.get(i).setPressed(false); 3817339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka } 3827339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka return true; 383ae5c736e37973e26b201d45ff6c139862a6e05cfTadashi G. Takaoka } 384ae5c736e37973e26b201d45ff6c139862a6e05cfTadashi G. Takaoka 385e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // Working variables for {@link #onLongClick(View)} and 386e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // {@link onInterceptTouchEvent(MotionEvent)}. 38750e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka private int mLastX; 38850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka private int mLastY; 38950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka private int mOriginX; 39050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka private int mOriginY; 39150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka private final int mMoreSuggestionsModalTolerance; 3923fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka private final GestureDetector mMoreSuggestionsSlidingDetector; 3933fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka private final GestureDetector.OnGestureListener mMoreSuggestionsSlidingListener = 3943fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka new GestureDetector.SimpleOnGestureListener() { 3953fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka @Override 3963fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka public boolean onScroll(MotionEvent down, MotionEvent me, float deltaX, float deltaY) { 3973fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka final float dy = me.getY() - down.getY(); 3983fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka if (deltaY > 0 && dy < 0) { 3993fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka return showMoreSuggestions(); 4003fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka } 4013fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka return false; 4023fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka } 4033fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka }; 40450e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka 405ae5c736e37973e26b201d45ff6c139862a6e05cfTadashi G. Takaoka @Override 406e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka public boolean onInterceptTouchEvent(final MotionEvent me) { 40751c38a441a09a4920703e765cb26179e7a80f029Tadashi G. Takaoka if (!mMoreSuggestionsView.isShowingInParent()) { 40850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka mLastX = (int)me.getX(); 40950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka mLastY = (int)me.getY(); 410e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka return mMoreSuggestionsSlidingDetector.onTouchEvent(me); 41129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka } 4128ac6d505b7ceab020a4085b3dfbea5b47362b030Tadashi G. Takaoka 41329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka final int action = me.getAction(); 41429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka final int index = me.getActionIndex(); 4158ac6d505b7ceab020a4085b3dfbea5b47362b030Tadashi G. Takaoka final int x = (int)me.getX(index); 4168ac6d505b7ceab020a4085b3dfbea5b47362b030Tadashi G. Takaoka final int y = (int)me.getY(index); 417e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka if (Math.abs(x - mOriginX) >= mMoreSuggestionsModalTolerance 418e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka || mOriginY - y >= mMoreSuggestionsModalTolerance) { 419e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // Decided to be in the sliding input mode only when the touch point has been moved 420e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // upward. Further {@link MotionEvent}s will be delivered to 421e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // {@link #onTouchEvent(MotionEvent)}. 42250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka return true; 42350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka } 42450e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka 425e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) { 426e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // Decided to be in the modal input mode. 427e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka mMoreSuggestionsView.adjustVerticalCorrectionForModalMode(); 428e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka } 429e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka return false; 430e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka } 431e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka 432e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka @Override 433e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka public boolean onTouchEvent(final MotionEvent me) { 434e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // In the sliding input mode. {@link MotionEvent} should be forwarded to 435e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // {@link MoreSuggestionsView}. 436e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka final int index = me.getActionIndex(); 437e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka final int x = (int)me.getX(index); 438e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka final int y = (int)me.getY(index); 43933482a9b9ccf605c63fab7c9b8273a240bbc2035Tadashi G. Takaoka me.setLocation(mMoreSuggestionsView.translateX(x), mMoreSuggestionsView.translateY(y)); 44033482a9b9ccf605c63fab7c9b8273a240bbc2035Tadashi G. Takaoka mMoreSuggestionsView.onTouchEvent(me); 44129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka return true; 44229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka } 44329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 44429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka @Override 4453e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka public void onClick(final View view) { 4468a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka if (view == mImportantNoticeStrip) { 4478a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mListener.showImportantNoticeContents(); 4488a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka return; 4498a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka } 450c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka if (view == mVoiceKey) { 451c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mListener.onCodeInput(Constants.CODE_SHORTCUT, 452c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, 453c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka false /* isKeyRepeat */); 454c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka return; 455c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka } 456148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka final Object tag = view.getTag(); 457148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka // {@link String} tag is set at {@link #showAddToDictionaryHint(String,CharSequence)}. 458148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka if (tag instanceof String) { 459148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka final String wordToSave = (String)tag; 460148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mListener.addWordToUserDictionary(wordToSave); 461717a8f50aec421f74e4d43432059c2fb41cb32c7Tadashi G. Takaoka clear(); 462717a8f50aec421f74e4d43432059c2fb41cb32c7Tadashi G. Takaoka return; 463717a8f50aec421f74e4d43432059c2fb41cb32c7Tadashi G. Takaoka } 464717a8f50aec421f74e4d43432059c2fb41cb32c7Tadashi G. Takaoka 465148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka // {@link Integer} tag is set at 4669b570b5e62581f41c40c4558d95c77ad5896934cTadashi G. Takaoka // {@link SuggestionStripLayoutHelper#setupWordViewsTextAndColor(SuggestedWords,int)} and 4679b570b5e62581f41c40c4558d95c77ad5896934cTadashi G. Takaoka // {@link SuggestionStripLayoutHelper#layoutPunctuationSuggestions(SuggestedWords,ViewGroup} 468148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka if (tag instanceof Integer) { 469148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka final int index = (Integer) tag; 470148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka if (index >= mSuggestedWords.size()) { 471148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka return; 472148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka } 473148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka final SuggestedWordInfo wordInfo = mSuggestedWords.getInfo(index); 474148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mListener.pickSuggestionManually(index, wordInfo); 475500a9752b1e61885f37b0fb26f09dfdd65da4e5eTadashi G. Takaoka } 476923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 47782411d47ba7e8133ed2390c6920945e139a738cesatok 4786ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani @Override 47973cd4c1428ac370e1c15c5f61b1ce499f0d4f4c7Tadashi G. Takaoka protected void onDetachedFromWindow() { 4806ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani super.onDetachedFromWindow(); 48119dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 4826ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani } 4838dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka 4848dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka @Override 485affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) { 4868dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka // Called by the framework when the size is known. Show the important notice if applicable. 4878dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka // This may be overriden by showing suggestions later, if applicable. 488affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka if (oldw <= 0 && w > 0) { 489affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka maybeShowImportantNoticeTitle(Settings.getInstance().getCurrent().mInputAttributes); 490affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka } 4918dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka } 492923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 493