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; 36a2e365da0acf80c1bcd8413d72f697a0da374779Tadashi G. Takaokaimport android.view.accessibility.AccessibilityEvent; 37c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaokaimport android.widget.ImageButton; 38c412309b7a32308b1b0a175dafc13f90254353c5Tadashi G. Takaokaimport android.widget.RelativeLayout; 39923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.widget.TextView; 40923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 41da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaokaimport com.android.inputmethod.accessibility.AccessibilityUtils; 427339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard; 43d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaokaimport com.android.inputmethod.keyboard.MainKeyboardView; 4429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaokaimport com.android.inputmethod.keyboard.MoreKeysPanel; 456f9105383a56c9ae15e35d3abf19c33d1efe5636Tadashi G. Takaokaimport com.android.inputmethod.latin.AudioAndHapticFeedbackManager; 468c3d5b6961a9b9d40c4bf21ad495f852971c24f4Tadashi G. Takaokaimport com.android.inputmethod.latin.R; 478c3d5b6961a9b9d40c4bf21ad495f852971c24f4Tadashi G. Takaokaimport com.android.inputmethod.latin.SuggestedWords; 489310f42a36eabe99ed7dcd3b835d6cdaa3c6fdcaJean Chalardimport com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; 499342484e8d573a40f470b6a593df31c602fa4076Ken Wakasaimport com.android.inputmethod.latin.common.Constants; 502dae79b1966a7970c25c8b79beec1c95c13f6c87Tadashi G. Takaokaimport com.android.inputmethod.latin.define.DebugFlags; 51ce78a2d8ab7630cff509c2b21b4b11abd8db4795Tadashi G. Takaokaimport com.android.inputmethod.latin.settings.Settings; 52aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaokaimport com.android.inputmethod.latin.settings.SettingsValues; 5301748cde4e692c970617e4478368f83b710a86b6Tadashi G. Takaokaimport com.android.inputmethod.latin.suggestions.MoreSuggestionsView.MoreSuggestionsListener; 548dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.ImportantNoticeUtils; 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 { 618a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka public void showImportantNoticeContents(); 6235c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard public void pickSuggestionManually(SuggestedWordInfo word); 63c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka public void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat); 64c97810693dfe83bf37c09f73c8d4b40f2ba8dddbTadashi G. Takaoka } 65c97810693dfe83bf37c09f73c8d4b40f2ba8dddbTadashi G. Takaoka 662dae79b1966a7970c25c8b79beec1c95c13f6c87Tadashi G. Takaoka static final boolean DBG = DebugFlags.DEBUG_ENABLED; 67c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka private static final float DEBUG_INFO_TEXT_SIZE_IN_DIP = 6.0f; 686f7218627eda110a8454053f8ecb7b80edfdc8cesatok 69913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka private final ViewGroup mSuggestionsStrip; 70c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka private final ImageButton mVoiceKey; 718a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka private final View mImportantNoticeStrip; 72d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka MainKeyboardView mMainKeyboardView; 7374b6897a12ec603ef835aaa77a01f0c32f49aa1cTadashi G. Takaoka 7429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka private final View mMoreSuggestionsContainer; 7529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka private final MoreSuggestionsView mMoreSuggestionsView; 7629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka private final MoreSuggestions.Builder mMoreSuggestionsBuilder; 7729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 78a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka private final ArrayList<TextView> mWordViews = new ArrayList<>(); 79a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka private final ArrayList<TextView> mDebugInfoViews = new ArrayList<>(); 80a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka private final ArrayList<View> mDividerViews = new ArrayList<>(); 8174b6897a12ec603ef835aaa77a01f0c32f49aa1cTadashi G. Takaoka 823e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka Listener mListener; 8330f4a2a4d750dc8c3132d706d9148daf71fbd168Adrian Velicu private SuggestedWords mSuggestedWords = SuggestedWords.getEmptyInstance(); 842637be27c51be03e39b0db1c66312c4cc55bc7deTadashi G. Takaoka private int mStartIndexOfMoreSuggestions; 856a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 86653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka private final SuggestionStripLayoutHelper mLayoutHelper; 87148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka private final StripVisibilityGroup mStripVisibilityGroup; 88148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka 89148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka private static class StripVisibilityGroup { 90630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka private final View mSuggestionStripView; 91148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka private final View mSuggestionsStrip; 928a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka private final View mImportantNoticeStrip; 93148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka 94630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka public StripVisibilityGroup(final View suggestionStripView, 9523574d1231296e090e6efb41a50c7885a116ddb4Dan Zivkovic final ViewGroup suggestionsStrip, final View importantNoticeStrip) { 96630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka mSuggestionStripView = suggestionStripView; 97148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mSuggestionsStrip = suggestionsStrip; 988a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mImportantNoticeStrip = importantNoticeStrip; 99aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka showSuggestionsStrip(); 100148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka } 101148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka 102630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka public void setLayoutDirection(final boolean isRtlLanguage) { 103630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka final int layoutDirection = isRtlLanguage ? ViewCompat.LAYOUT_DIRECTION_RTL 104630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka : ViewCompat.LAYOUT_DIRECTION_LTR; 105630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka ViewCompat.setLayoutDirection(mSuggestionStripView, layoutDirection); 106bcd30bf3e74c7c10d5b69a54cdf90c6b682a0747Tadashi G. Takaoka ViewCompat.setLayoutDirection(mSuggestionsStrip, layoutDirection); 1078a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka ViewCompat.setLayoutDirection(mImportantNoticeStrip, layoutDirection); 108bcd30bf3e74c7c10d5b69a54cdf90c6b682a0747Tadashi G. Takaoka } 109bcd30bf3e74c7c10d5b69a54cdf90c6b682a0747Tadashi G. Takaoka 110aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka public void showSuggestionsStrip() { 111148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka mSuggestionsStrip.setVisibility(VISIBLE); 1128a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mImportantNoticeStrip.setVisibility(INVISIBLE); 1138a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka } 1148a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka 115aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka public void showImportantNoticeStrip() { 1168a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mSuggestionsStrip.setVisibility(INVISIBLE); 1178a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mImportantNoticeStrip.setVisibility(VISIBLE); 118148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka } 119148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka 12021f038ee0aadfeb2036c238d543b107d97729449Tadashi G. Takaoka public boolean isShowingImportantNoticeStrip() { 12121f038ee0aadfeb2036c238d543b107d97729449Tadashi G. Takaoka return mImportantNoticeStrip.getVisibility() == VISIBLE; 12221f038ee0aadfeb2036c238d543b107d97729449Tadashi G. Takaoka } 123148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka } 12474b6897a12ec603ef835aaa77a01f0c32f49aa1cTadashi G. Takaoka 125923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 1264702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka * Construct a {@link SuggestionStripView} for showing suggestions to be picked by the user. 127923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @param context 128923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @param attrs 129923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 1303e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka public SuggestionStripView(final Context context, final AttributeSet attrs) { 1314702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka this(context, attrs, R.attr.suggestionStripViewStyle); 13208a6f2aea71d998206c47c16dcda4eaa90f8c9eaTadashi G. Takaoka } 13308a6f2aea71d998206c47c16dcda4eaa90f8c9eaTadashi G. Takaoka 1343e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka public SuggestionStripView(final Context context, final AttributeSet attrs, 1353e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka final int defStyle) { 136c412309b7a32308b1b0a175dafc13f90254353c5Tadashi G. Takaoka super(context, attrs, defStyle); 137923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 13816713e5630b93fb5625df26745eb73271f189457Tadashi G. Takaoka final LayoutInflater inflater = LayoutInflater.from(context); 139913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka inflater.inflate(R.layout.suggestions_strip, this); 14086e815a142c8aa13213151e381a8a24ef23073d3Tadashi G. Takaoka 141913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka mSuggestionsStrip = (ViewGroup)findViewById(R.id.suggestions_strip); 142c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mVoiceKey = (ImageButton)findViewById(R.id.suggestions_strip_voice_key); 1438a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mImportantNoticeStrip = findViewById(R.id.important_notice_strip); 144aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka mStripVisibilityGroup = new StripVisibilityGroup(this, mSuggestionsStrip, 14523574d1231296e090e6efb41a50c7885a116ddb4Dan Zivkovic mImportantNoticeStrip); 146148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka 147a1ed211c4e80eb81ce399e0eaff88bbdf1e3199fJean Chalard for (int pos = 0; pos < SuggestedWords.MAX_SUGGESTIONS; pos++) { 148c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka final TextView word = new TextView(context, null, R.attr.suggestionWordStyle); 14924c275ccb9d12d6160b09c20afe17601b09957f1Dan Zivkovic word.setContentDescription(getResources().getString(R.string.spoken_empty_suggestion)); 1502442e779857e7eda253aadcb1c4dff5ccb3e53f4Tadashi G. Takaoka word.setOnClickListener(this); 151ae5c736e37973e26b201d45ff6c139862a6e05cfTadashi G. Takaoka word.setOnLongClickListener(this); 152500a9752b1e61885f37b0fb26f09dfdd65da4e5eTadashi G. Takaoka mWordViews.add(word); 153913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka final View divider = inflater.inflate(R.layout.suggestion_divider, null); 154500a9752b1e61885f37b0fb26f09dfdd65da4e5eTadashi G. Takaoka mDividerViews.add(divider); 155c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka final TextView info = new TextView(context, null, R.attr.suggestionWordStyle); 156c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka info.setTextColor(Color.WHITE); 157c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka info.setTextSize(TypedValue.COMPLEX_UNIT_DIP, DEBUG_INFO_TEXT_SIZE_IN_DIP); 158c2ea3f7dd95e7e9dccc61ac2ef9b56b1db8e5b48Tadashi G. Takaoka mDebugInfoViews.add(info); 159c9716b28ce438e06b5cacc07fc002944bcbe24a0Tadashi G. Takaoka } 160179ada958b0bb46c6b9c8eb8b220d84dd3db855aTadashi G. Takaoka 161653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka mLayoutHelper = new SuggestionStripLayoutHelper( 162500a9752b1e61885f37b0fb26f09dfdd65da4e5eTadashi G. Takaoka context, attrs, defStyle, mWordViews, mDividerViews, mDebugInfoViews); 16329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 16429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka mMoreSuggestionsContainer = inflater.inflate(R.layout.more_suggestions, null); 16529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka mMoreSuggestionsView = (MoreSuggestionsView)mMoreSuggestionsContainer 16629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka .findViewById(R.id.more_suggestions_view); 16708ae0d5ca03ed455827e82222df249d1cafb5d71Tadashi G. Takaoka mMoreSuggestionsBuilder = new MoreSuggestions.Builder(context, mMoreSuggestionsView); 168bfc1d732ac92fa1bd5b19ad9e7c71ce9a1f9dc00Tadashi G. Takaoka 16950e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka final Resources res = context.getResources(); 17050e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka mMoreSuggestionsModalTolerance = res.getDimensionPixelOffset( 1712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa R.dimen.config_more_suggestions_modal_tolerance); 1723fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka mMoreSuggestionsSlidingDetector = new GestureDetector( 1733fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka context, mMoreSuggestionsSlidingListener); 174c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka 175c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka final TypedArray keyboardAttr = context.obtainStyledAttributes(attrs, 176c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka R.styleable.Keyboard, defStyle, R.style.SuggestionStripView); 177c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka final Drawable iconVoice = keyboardAttr.getDrawable(R.styleable.Keyboard_iconShortcutKey); 178c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka keyboardAttr.recycle(); 179c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mVoiceKey.setImageDrawable(iconVoice); 180c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mVoiceKey.setOnClickListener(this); 181923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 182c9716b28ce438e06b5cacc07fc002944bcbe24a0Tadashi G. Takaoka 183923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project /** 184c97810693dfe83bf37c09f73c8d4b40f2ba8dddbTadashi G. Takaoka * A connection back to the input method. 185923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * @param listener 186923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 1873e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka public void setListener(final Listener listener, final View inputView) { 188c97810693dfe83bf37c09f73c8d4b40f2ba8dddbTadashi G. Takaoka mListener = listener; 189d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka mMainKeyboardView = (MainKeyboardView)inputView.findViewById(R.id.keyboard_view); 190923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 191923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 192aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka public void updateVisibility(final boolean shouldBeVisible, final boolean isFullscreenMode) { 193aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka final int visibility = shouldBeVisible ? VISIBLE : (isFullscreenMode ? GONE : INVISIBLE); 194aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka setVisibility(visibility); 195aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent(); 196987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka mVoiceKey.setVisibility(currentSettingsValues.mShowsVoiceInputKey ? VISIBLE : INVISIBLE); 197c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka } 198c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka 199bcd30bf3e74c7c10d5b69a54cdf90c6b682a0747Tadashi G. Takaoka public void setSuggestions(final SuggestedWords suggestedWords, final boolean isRtlLanguage) { 200e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka clear(); 201630a24141eeb80063648bc1bc4678439117321d2Tadashi G. Takaoka mStripVisibilityGroup.setLayoutDirection(isRtlLanguage); 202e79b1a83126b41e09a8ec0a8dbb751ae0e02c7f6Tadashi G. Takaoka mSuggestedWords = suggestedWords; 2032637be27c51be03e39b0db1c66312c4cc55bc7deTadashi G. Takaoka mStartIndexOfMoreSuggestions = mLayoutHelper.layoutAndReturnStartIndexOfMoreSuggestions( 20424c275ccb9d12d6160b09c20afe17601b09957f1Dan Zivkovic getContext(), mSuggestedWords, mSuggestionsStrip, this); 205aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka mStripVisibilityGroup.showSuggestionsStrip(); 20616713e5630b93fb5625df26745eb73271f189457Tadashi G. Takaoka } 20774b6897a12ec603ef835aaa77a01f0c32f49aa1cTadashi G. Takaoka 20816a43d2bd9c5d80f8e50f5a7682b657ee10621e1Yohei Yukawa public void setMoreSuggestionsHeight(final int remainingHeight) { 20916a43d2bd9c5d80f8e50f5a7682b657ee10621e1Yohei Yukawa mLayoutHelper.setMoreSuggestionsHeight(remainingHeight); 210c8b0e5797e20d3fa25d319a9709aabc9149f8ff9Tadashi G. Takaoka } 211b47319867ef3834a222865b8cb6abe62962e70f7Tadashi G. Takaoka 2128dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka // This method checks if we should show the important notice (checks on permanent storage if 2138dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka // it has been shown once already or not, and if in the setup wizard). If applicable, it shows 2148dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka // the notice. In all cases, it returns true if it was shown, false otherwise. 215987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka public boolean maybeShowImportantNoticeTitle() { 2168ec36026c93d13c1118eda936ac12325e0085561Chieu Nguyen final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent(); 2178ec36026c93d13c1118eda936ac12325e0085561Chieu Nguyen if (!ImportantNoticeUtils.shouldShowImportantNotice(getContext(), currentSettingsValues)) { 2188dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka return false; 2198dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka } 22014e908c3486ae5996e66625e959ff45c5f3740efTadashi G. Takaoka if (getWidth() <= 0) { 221affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka return false; 222affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka } 223604158669b407a40cd0f23538fad4dce5d738f24Mohammadinamul Sheik final String importantNoticeTitle = ImportantNoticeUtils.getSuggestContactsNoticeTitle( 2246abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka getContext()); 2256abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka if (TextUtils.isEmpty(importantNoticeTitle)) { 2266abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka return false; 2276abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka } 228c8abd13c77ed90b209301ea379e1142e0d60e3f5Tadashi G. Takaoka if (isShowingMoreSuggestionPanel()) { 229c8abd13c77ed90b209301ea379e1142e0d60e3f5Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 230c8abd13c77ed90b209301ea379e1142e0d60e3f5Tadashi G. Takaoka } 23114e908c3486ae5996e66625e959ff45c5f3740efTadashi G. Takaoka mLayoutHelper.layoutImportantNotice(mImportantNoticeStrip, importantNoticeTitle); 232aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka mStripVisibilityGroup.showImportantNoticeStrip(); 2338a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mImportantNoticeStrip.setOnClickListener(this); 2348dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka return true; 2358a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka } 2368a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka 237923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void clear() { 238913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka mSuggestionsStrip.removeAllViews(); 2399ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka removeAllDebugInfoViews(); 240aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka mStripVisibilityGroup.showSuggestionsStrip(); 24119dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 242923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 243923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2449ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka private void removeAllDebugInfoViews() { 2459ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka // The debug info views may be placed as children views of this {@link SuggestionStripView}. 2469ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka for (final View debugInfoView : mDebugInfoViews) { 2479ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka final ViewParent parent = debugInfoView.getParent(); 2489ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka if (parent instanceof ViewGroup) { 2499ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka ((ViewGroup)parent).removeView(debugInfoView); 2509ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka } 2519ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka } 2529ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka } 2539ac6c9064d24a3a0e96db470bb76c997c51bb5c8Tadashi G. Takaoka 2546f7905ae757c30ac0f8080f025b88afc61a6f6b1Tadashi G. Takaoka private final MoreSuggestionsListener mMoreSuggestionsListener = new MoreSuggestionsListener() { 25529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka @Override 25635c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard public void onSuggestionSelected(final SuggestedWordInfo wordInfo) { 25735c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard mListener.pickSuggestionManually(wordInfo); 25819dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 25929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka } 26029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 26129e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka @Override 26229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka public void onCancelInput() { 26319dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 26429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka } 26529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka }; 26629e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 26729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka private final MoreKeysPanel.Controller mMoreSuggestionsController = 26829e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka new MoreKeysPanel.Controller() { 26929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka @Override 2701f215a58c99f0eb2f536e9cccd51371f2883e201Tadashi G. Takaoka public void onDismissMoreKeysPanel() { 2711f215a58c99f0eb2f536e9cccd51371f2883e201Tadashi G. Takaoka mMainKeyboardView.onDismissMoreKeysPanel(); 272fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang } 273fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang 274fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang @Override 275a729377395967f7652d93992cbcf50cd2ff522d1Tadashi G. Takaoka public void onShowMoreKeysPanel(final MoreKeysPanel panel) { 276d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka mMainKeyboardView.onShowMoreKeysPanel(panel); 27729e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka } 278ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang 279ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang @Override 2801f215a58c99f0eb2f536e9cccd51371f2883e201Tadashi G. Takaoka public void onCancelMoreKeysPanel() { 28119dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 282ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang } 28329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka }; 28429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 28519dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka public boolean isShowingMoreSuggestionPanel() { 28619dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka return mMoreSuggestionsView.isShowingInParent(); 28719dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka } 28819dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka 28919dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka public void dismissMoreSuggestionsPanel() { 29019dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka mMoreSuggestionsView.dismissMoreKeysPanel(); 29119dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka } 29219dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka 293e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka @Override 2943e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka public boolean onLongClick(final View view) { 295ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback( 2966f9105383a56c9ae15e35d3abf19c33d1efe5636Tadashi G. Takaoka Constants.NOT_A_CODE, this); 2973fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka return showMoreSuggestions(); 2983fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka } 2993fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka 3003e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka boolean showMoreSuggestions() { 30156e0373b5c0c516cd57352cebf882e2b358f168cTadashi G. Takaoka final Keyboard parentKeyboard = mMainKeyboardView.getKeyboard(); 3027339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka if (parentKeyboard == null) { 3037339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka return false; 304ae5c736e37973e26b201d45ff6c139862a6e05cfTadashi G. Takaoka } 305653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka final SuggestionStripLayoutHelper layoutHelper = mLayoutHelper; 3062637be27c51be03e39b0db1c66312c4cc55bc7deTadashi G. Takaoka if (mSuggestedWords.size() <= mStartIndexOfMoreSuggestions) { 3077339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka return false; 3087339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka } 3097339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final int stripWidth = getWidth(); 3107339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final View container = mMoreSuggestionsContainer; 3117339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final int maxWidth = stripWidth - container.getPaddingLeft() - container.getPaddingRight(); 3127339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final MoreSuggestions.Builder builder = mMoreSuggestionsBuilder; 3132637be27c51be03e39b0db1c66312c4cc55bc7deTadashi G. Takaoka builder.layout(mSuggestedWords, mStartIndexOfMoreSuggestions, maxWidth, 314653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka (int)(maxWidth * layoutHelper.mMinMoreSuggestionsWidth), 315653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka layoutHelper.getMaxMoreSuggestionsRow(), parentKeyboard); 3167339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka mMoreSuggestionsView.setKeyboard(builder.build()); 3177339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 3187339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka 3197339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final MoreKeysPanel moreKeysPanel = mMoreSuggestionsView; 3207339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka final int pointX = stripWidth / 2; 321653603b7253d96c7fad674ed301de5bc8050b68cTadashi G. Takaoka final int pointY = -layoutHelper.mMoreSuggestionsBottomGap; 3227339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka moreKeysPanel.showMoreKeysPanel(this, mMoreSuggestionsController, pointX, pointY, 323fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang mMoreSuggestionsListener); 3247339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka mOriginX = mLastX; 3257339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka mOriginY = mLastY; 3262637be27c51be03e39b0db1c66312c4cc55bc7deTadashi G. Takaoka for (int i = 0; i < mStartIndexOfMoreSuggestions; i++) { 327500a9752b1e61885f37b0fb26f09dfdd65da4e5eTadashi G. Takaoka mWordViews.get(i).setPressed(false); 3287339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka } 3297339a62a1368b632c0cedaf1d876a0e8590a47edTadashi G. Takaoka return true; 330ae5c736e37973e26b201d45ff6c139862a6e05cfTadashi G. Takaoka } 331ae5c736e37973e26b201d45ff6c139862a6e05cfTadashi G. Takaoka 332da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // Working variables for {@link onInterceptTouchEvent(MotionEvent)} and 333da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // {@link onTouchEvent(MotionEvent)}. 33450e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka private int mLastX; 33550e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka private int mLastY; 33650e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka private int mOriginX; 33750e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka private int mOriginY; 33850e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka private final int mMoreSuggestionsModalTolerance; 339da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka private boolean mNeedsToTransformTouchEventToHoverEvent; 340da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka private boolean mIsDispatchingHoverEventToMoreSuggestions; 3413fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka private final GestureDetector mMoreSuggestionsSlidingDetector; 3423fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka private final GestureDetector.OnGestureListener mMoreSuggestionsSlidingListener = 3433fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka new GestureDetector.SimpleOnGestureListener() { 3443fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka @Override 3453fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka public boolean onScroll(MotionEvent down, MotionEvent me, float deltaX, float deltaY) { 3463fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka final float dy = me.getY() - down.getY(); 3473fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka if (deltaY > 0 && dy < 0) { 3483fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka return showMoreSuggestions(); 3493fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka } 3503fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka return false; 3513fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka } 3523fc4ddec68b4f56f53ed6da80b5e44f38c085740Tadashi G. Takaoka }; 35350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka 354ae5c736e37973e26b201d45ff6c139862a6e05cfTadashi G. Takaoka @Override 355e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka public boolean onInterceptTouchEvent(final MotionEvent me) { 35621f038ee0aadfeb2036c238d543b107d97729449Tadashi G. Takaoka if (mStripVisibilityGroup.isShowingImportantNoticeStrip()) { 357d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka return false; 358d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka } 3598ab46225b3e819fe31dd3bd487a7e9d1ff859dedTadashi G. Takaoka // Detecting sliding up finger to show {@link MoreSuggestionsView}. 36051c38a441a09a4920703e765cb26179e7a80f029Tadashi G. Takaoka if (!mMoreSuggestionsView.isShowingInParent()) { 36150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka mLastX = (int)me.getX(); 36250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka mLastY = (int)me.getY(); 363e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka return mMoreSuggestionsSlidingDetector.onTouchEvent(me); 36429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka } 36521f038ee0aadfeb2036c238d543b107d97729449Tadashi G. Takaoka if (mMoreSuggestionsView.isInModalMode()) { 36621f038ee0aadfeb2036c238d543b107d97729449Tadashi G. Takaoka return false; 36721f038ee0aadfeb2036c238d543b107d97729449Tadashi G. Takaoka } 3688ac6d505b7ceab020a4085b3dfbea5b47362b030Tadashi G. Takaoka 36929e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka final int action = me.getAction(); 37029e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka final int index = me.getActionIndex(); 3718ac6d505b7ceab020a4085b3dfbea5b47362b030Tadashi G. Takaoka final int x = (int)me.getX(index); 3728ac6d505b7ceab020a4085b3dfbea5b47362b030Tadashi G. Takaoka final int y = (int)me.getY(index); 373e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka if (Math.abs(x - mOriginX) >= mMoreSuggestionsModalTolerance 374e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka || mOriginY - y >= mMoreSuggestionsModalTolerance) { 375da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // Decided to be in the sliding suggestion mode only when the touch point has been moved 376e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // upward. Further {@link MotionEvent}s will be delivered to 377e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // {@link #onTouchEvent(MotionEvent)}. 37804cd8794e04b14c2b7e7eed036b83075792134a1Tadashi G. Takaoka mNeedsToTransformTouchEventToHoverEvent = 37904cd8794e04b14c2b7e7eed036b83075792134a1Tadashi G. Takaoka AccessibilityUtils.getInstance().isTouchExplorationEnabled(); 380da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka mIsDispatchingHoverEventToMoreSuggestions = false; 38150e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka return true; 38250e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka } 38350e1073e11240fe51b3baf0e2ed80dac0d9f001dTadashi G. Takaoka 384e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) { 385e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // Decided to be in the modal input mode. 386d144b7874efc843bccc3ec7cd9a48d32d8f2395dTadashi G. Takaoka mMoreSuggestionsView.setModalMode(); 387e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka } 388e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka return false; 389e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka } 390e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka 391e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka @Override 392a2e365da0acf80c1bcd8413d72f697a0da374779Tadashi G. Takaoka public boolean dispatchPopulateAccessibilityEvent(final AccessibilityEvent event) { 393a2e365da0acf80c1bcd8413d72f697a0da374779Tadashi G. Takaoka // Don't populate accessibility event with suggested words and voice key. 394a2e365da0acf80c1bcd8413d72f697a0da374779Tadashi G. Takaoka return true; 395a2e365da0acf80c1bcd8413d72f697a0da374779Tadashi G. Takaoka } 396a2e365da0acf80c1bcd8413d72f697a0da374779Tadashi G. Takaoka 397a2e365da0acf80c1bcd8413d72f697a0da374779Tadashi G. Takaoka @Override 398e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka public boolean onTouchEvent(final MotionEvent me) { 3998ab46225b3e819fe31dd3bd487a7e9d1ff859dedTadashi G. Takaoka if (!mMoreSuggestionsView.isShowingInParent()) { 4008ab46225b3e819fe31dd3bd487a7e9d1ff859dedTadashi G. Takaoka // Ignore any touch event while more suggestions panel hasn't been shown. 4018ab46225b3e819fe31dd3bd487a7e9d1ff859dedTadashi G. Takaoka // Detecting sliding up is done at {@link #onInterceptTouchEvent}. 4028ab46225b3e819fe31dd3bd487a7e9d1ff859dedTadashi G. Takaoka return true; 4038ab46225b3e819fe31dd3bd487a7e9d1ff859dedTadashi G. Takaoka } 404e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // In the sliding input mode. {@link MotionEvent} should be forwarded to 405e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka // {@link MoreSuggestionsView}. 406e32548f32d32bc2fbf07ccd373bc55ece80388ceTadashi G. Takaoka final int index = me.getActionIndex(); 407da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka final int x = mMoreSuggestionsView.translateX((int)me.getX(index)); 408da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka final int y = mMoreSuggestionsView.translateY((int)me.getY(index)); 409da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka me.setLocation(x, y); 410da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka if (!mNeedsToTransformTouchEventToHoverEvent) { 411da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka mMoreSuggestionsView.onTouchEvent(me); 412da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka return true; 413da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka } 414da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // In sliding suggestion mode with accessibility mode on, a touch event should be 415da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // transformed to a hover event. 416da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka final int width = mMoreSuggestionsView.getWidth(); 417da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka final int height = mMoreSuggestionsView.getHeight(); 418da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka final boolean onMoreSuggestions = (x >= 0 && x < width && y >= 0 && y < height); 419da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka if (!onMoreSuggestions && !mIsDispatchingHoverEventToMoreSuggestions) { 420da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // Just drop this touch event because dispatching hover event isn't started yet and 421da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // the touch event isn't on {@link MoreSuggestionsView}. 422da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka return true; 423da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka } 424da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka final int hoverAction; 425da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka if (onMoreSuggestions && !mIsDispatchingHoverEventToMoreSuggestions) { 426da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // Transform this touch event to a hover enter event and start dispatching a hover 427da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // event to {@link MoreSuggestionsView}. 428da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka mIsDispatchingHoverEventToMoreSuggestions = true; 429da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka hoverAction = MotionEvent.ACTION_HOVER_ENTER; 430da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka } else if (me.getActionMasked() == MotionEvent.ACTION_UP) { 431da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // Transform this touch event to a hover exit event and stop dispatching a hover event 432da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // after this. 433da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka mIsDispatchingHoverEventToMoreSuggestions = false; 434da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka mNeedsToTransformTouchEventToHoverEvent = false; 435da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka hoverAction = MotionEvent.ACTION_HOVER_EXIT; 436da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka } else { 437da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka // Transform this touch event to a hover move event. 438da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka hoverAction = MotionEvent.ACTION_HOVER_MOVE; 439da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka } 440da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka me.setAction(hoverAction); 441da232a70a8c73f8d2a26a74e1937c12500244209Tadashi G. Takaoka mMoreSuggestionsView.onHoverEvent(me); 44229e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka return true; 44329e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka } 44429e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka 44529e7b7ed6ef88c3e10cc6469801fef87241c9cb5Tadashi G. Takaoka @Override 4463e5a3c18bebbfb56012383411b24ee81ffde09cbTadashi G. Takaoka public void onClick(final View view) { 447874a600dc805b6ab9fe92fccddfe4765b8d29a35Tadashi G. Takaoka AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback( 448874a600dc805b6ab9fe92fccddfe4765b8d29a35Tadashi G. Takaoka Constants.CODE_UNSPECIFIED, this); 4498a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka if (view == mImportantNoticeStrip) { 4508a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka mListener.showImportantNoticeContents(); 4518a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka return; 4528a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka } 453c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka if (view == mVoiceKey) { 454c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka mListener.onCodeInput(Constants.CODE_SHORTCUT, 455c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, 456c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka false /* isKeyRepeat */); 457c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka return; 458c41d261b7e1e626aaa4e333c9c4cc73ec13cb68aTadashi G. Takaoka } 459717a8f50aec421f74e4d43432059c2fb41cb32c7Tadashi G. Takaoka 46023574d1231296e090e6efb41a50c7885a116ddb4Dan Zivkovic final Object tag = view.getTag(); 461148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka // {@link Integer} tag is set at 4629b570b5e62581f41c40c4558d95c77ad5896934cTadashi G. Takaoka // {@link SuggestionStripLayoutHelper#setupWordViewsTextAndColor(SuggestedWords,int)} and 4639b570b5e62581f41c40c4558d95c77ad5896934cTadashi G. Takaoka // {@link SuggestionStripLayoutHelper#layoutPunctuationSuggestions(SuggestedWords,ViewGroup} 464148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka if (tag instanceof Integer) { 465148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka final int index = (Integer) tag; 466148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka if (index >= mSuggestedWords.size()) { 467148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka return; 468148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka } 469148dedbc5dfa22d6db30b28ae9ede139206af429Tadashi G. Takaoka final SuggestedWordInfo wordInfo = mSuggestedWords.getInfo(index); 47035c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard mListener.pickSuggestionManually(wordInfo); 471500a9752b1e61885f37b0fb26f09dfdd65da4e5eTadashi G. Takaoka } 472923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 47382411d47ba7e8133ed2390c6920945e139a738cesatok 4746ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani @Override 47573cd4c1428ac370e1c15c5f61b1ce499f0d4f4c7Tadashi G. Takaoka protected void onDetachedFromWindow() { 4766ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani super.onDetachedFromWindow(); 47719dd753c0ccaea8dee71eeae7edc724c58c6f024Tadashi G. Takaoka dismissMoreSuggestionsPanel(); 4786ec55a1599c74150e82ea7e4371ec815f0d2df27Amith Yamasani } 4798dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka 4808dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka @Override 481affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) { 4828dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka // Called by the framework when the size is known. Show the important notice if applicable. 4838dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka // This may be overriden by showing suggestions later, if applicable. 484affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka if (oldw <= 0 && w > 0) { 485987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka maybeShowImportantNoticeTitle(); 486affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka } 4878dda9e480b6519ca57565c8aa507e14bff739b60Tadashi G. Takaoka } 488923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 489