AppCompatDelegateImplV7.java revision 88c0ac5649d6b82c882e2de4bc4f043b107a4428
16386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes/* 26386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * Copyright (C) 2013 The Android Open Source Project 36386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * 46386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 56386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * you may not use this file except in compliance with the License. 66386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * You may obtain a copy of the License at 76386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * 86386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * http://www.apache.org/licenses/LICENSE-2.0 96386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * 106386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * Unless required by applicable law or agreed to in writing, software 116386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * distributed under the License is distributed on an "AS IS" BASIS, 126386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * See the License for the specific language governing permissions and 146386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes * limitations under the License. 156386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes */ 166386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 176386aac7ea9be44d23dcea28d9a02110c174e988Chris Banespackage android.support.v7.app; 186386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 19f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.app.Activity; 2016e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.app.Dialog; 216386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.Context; 226386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.res.Configuration; 2361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banesimport android.content.res.Resources; 246386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.content.res.TypedArray; 2546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.graphics.PixelFormat; 26ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banesimport android.graphics.Rect; 2746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.media.AudioManager; 28469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.os.Build; 298902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banesimport android.os.Bundle; 3000d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.os.Parcel; 3100d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.os.Parcelable; 32469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.support.annotation.NonNull; 3349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.app.NavUtils; 34f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v4.view.LayoutInflaterCompat; 35f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v4.view.LayoutInflaterFactory; 36ea4f700ac38424954c56df5138ff794def50b019Chris Banesimport android.support.v4.view.OnApplyWindowInsetsListener; 3703fc11b659da1645507062bddda450136e13af35Chris Banesimport android.support.v4.view.ViewCompat; 3849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewConfigurationCompat; 39d25af35061a9f20d59b25329d613c62c20184dadChris Banesimport android.support.v4.view.WindowCompat; 40ea4f700ac38424954c56df5138ff794def50b019Chris Banesimport android.support.v4.view.WindowInsetsCompat; 41f5829201b976fc650789accc22f325a2541ed478Chris Banesimport android.support.v4.widget.PopupWindowCompat; 426386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.appcompat.R; 432cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banesimport android.support.v7.internal.app.AppCompatViewInflater; 4449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.app.ToolbarActionBar; 4549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.app.WindowDecorActionBar; 46878ed08a784cafb112a5d350573b0d1e81c554dbChris Banesimport android.support.v7.internal.view.ContextThemeWrapper; 474c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.support.v7.internal.view.StandaloneActionMode; 486386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.ListMenuPresenter; 496386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.MenuBuilder; 506386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.MenuPresenter; 516386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.support.v7.internal.view.menu.MenuView; 524c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.support.v7.internal.widget.ActionBarContextView; 5319eaf14cb3cca613f984a32be2fab2534427fb29Chris Banesimport android.support.v7.internal.widget.ContentFrameLayout; 5449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.widget.DecorContentParent; 55ea4f700ac38424954c56df5138ff794def50b019Chris Banesimport android.support.v7.internal.widget.FitWindowsViewGroup; 5646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.support.v7.internal.widget.TintManager; 574bd5cbd6ca4f1e5ed43217b808068a48f937feabChris Banesimport android.support.v7.internal.widget.ViewStubCompat; 58ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banesimport android.support.v7.internal.widget.ViewUtils; 59d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banesimport android.support.v7.view.ActionMode; 6049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.widget.Toolbar; 6116e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.text.TextUtils; 62cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banesimport android.util.AndroidRuntimeException; 63469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.util.AttributeSet; 6446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.util.Log; 6556fd50144df518461398a9b3397ee4842b346708Chris Banesimport android.util.TypedValue; 664c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.Gravity; 6700d183885b54de433e43118d3032340f40cac8c0Chris Banesimport android.view.KeyCharacterMap; 68dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banesimport android.view.KeyEvent; 69dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banesimport android.view.LayoutInflater; 7030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.Menu; 7130837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem; 7246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.view.MotionEvent; 736386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.View; 7449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.ViewConfiguration; 756386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.ViewGroup; 7646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.view.ViewParent; 776386aac7ea9be44d23dcea28d9a02110c174e988Chris Banesimport android.view.Window; 7846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport android.view.WindowManager; 794c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.view.accessibility.AccessibilityEvent; 8030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.widget.FrameLayout; 814c2a95906254748cb9a843b061288265d6e185a9Chris Banesimport android.widget.PopupWindow; 8216e8d4dd91083260223c007c797e46bc8f631055Chris Banesimport android.widget.TextView; 836386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 8446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport static android.view.ViewGroup.LayoutParams.MATCH_PARENT; 8546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banesimport static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; 8600d183885b54de433e43118d3032340f40cac8c0Chris Banesimport static android.view.Window.FEATURE_OPTIONS_PANEL; 8700d183885b54de433e43118d3032340f40cac8c0Chris Banes 88f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesclass AppCompatDelegateImplV7 extends AppCompatDelegateImplBase 89f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes implements MenuBuilder.Callback, LayoutInflaterFactory { 906386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 9149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private DecorContentParent mDecorContentParent; 9203fc11b659da1645507062bddda450136e13af35Chris Banes private ActionMenuPresenterCallback mActionMenuPresenterCallback; 9303fc11b659da1645507062bddda450136e13af35Chris Banes private PanelMenuPresenterCallback mPanelMenuPresenterCallback; 9403fc11b659da1645507062bddda450136e13af35Chris Banes 954c2a95906254748cb9a843b061288265d6e185a9Chris Banes ActionMode mActionMode; 964c2a95906254748cb9a843b061288265d6e185a9Chris Banes ActionBarContextView mActionModeView; 974c2a95906254748cb9a843b061288265d6e185a9Chris Banes PopupWindow mActionModePopup; 984c2a95906254748cb9a843b061288265d6e185a9Chris Banes Runnable mShowActionModePopup; 995a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes 1005a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes // true if we have installed a window sub-decor layout. 1015a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes private boolean mSubDecorInstalled; 10203fc11b659da1645507062bddda450136e13af35Chris Banes private ViewGroup mWindowDecor; 103ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes private ViewGroup mSubDecor; 104ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes 10516e8d4dd91083260223c007c797e46bc8f631055Chris Banes private TextView mTitleView; 106ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes private View mStatusGuard; 107d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 108ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes // Used to keep track of Progress Bar Window features 109ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes private boolean mFeatureProgress, mFeatureIndeterminateProgress; 110ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes 1118902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes // Used for emulating PanelFeatureState 1128902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes private boolean mClosingActionMenu; 11300d183885b54de433e43118d3032340f40cac8c0Chris Banes private PanelFeatureState[] mPanels; 11400d183885b54de433e43118d3032340f40cac8c0Chris Banes private PanelFeatureState mPreparedPanel; 115556ac47ce764a4a9320b5ac914536e9da2524176Chris Banes 11603fc11b659da1645507062bddda450136e13af35Chris Banes private boolean mInvalidatePanelMenuPosted; 11700d183885b54de433e43118d3032340f40cac8c0Chris Banes private int mInvalidatePanelMenuFeatures; 11803fc11b659da1645507062bddda450136e13af35Chris Banes private final Runnable mInvalidatePanelMenuRunnable = new Runnable() { 11903fc11b659da1645507062bddda450136e13af35Chris Banes @Override 12003fc11b659da1645507062bddda450136e13af35Chris Banes public void run() { 12100d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((mInvalidatePanelMenuFeatures & 1 << FEATURE_OPTIONS_PANEL) != 0) { 12200d183885b54de433e43118d3032340f40cac8c0Chris Banes doInvalidatePanelMenu(FEATURE_OPTIONS_PANEL); 12300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 124d25af35061a9f20d59b25329d613c62c20184dadChris Banes if ((mInvalidatePanelMenuFeatures & 1 << FEATURE_SUPPORT_ACTION_BAR) != 0) { 125d25af35061a9f20d59b25329d613c62c20184dadChris Banes doInvalidatePanelMenu(FEATURE_SUPPORT_ACTION_BAR); 12600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 12700d183885b54de433e43118d3032340f40cac8c0Chris Banes mInvalidatePanelMenuPosted = false; 12800d183885b54de433e43118d3032340f40cac8c0Chris Banes mInvalidatePanelMenuFeatures = 0; 12903fc11b659da1645507062bddda450136e13af35Chris Banes } 13003fc11b659da1645507062bddda450136e13af35Chris Banes }; 13103fc11b659da1645507062bddda450136e13af35Chris Banes 13249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes private boolean mEnableDefaultActionBarUp; 13349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 1347efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell private Rect mTempRect1; 1357efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell private Rect mTempRect2; 1367efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell 1372cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes private AppCompatViewInflater mAppCompatViewInflater; 138fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes 13916e8d4dd91083260223c007c797e46bc8f631055Chris Banes AppCompatDelegateImplV7(Context context, Window window, AppCompatCallback callback) { 14016e8d4dd91083260223c007c797e46bc8f631055Chris Banes super(context, window, callback); 1416386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 1426386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 1436386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 144f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void onCreate(Bundle savedInstanceState) { 14549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes super.onCreate(savedInstanceState); 14649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 14716e8d4dd91083260223c007c797e46bc8f631055Chris Banes mWindowDecor = (ViewGroup) mWindow.getDecorView(); 14803fc11b659da1645507062bddda450136e13af35Chris Banes 14916e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (mOriginalWindowCallback instanceof Activity) { 15016e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (NavUtils.getParentActivityName((Activity) mOriginalWindowCallback) != null) { 15116e8d4dd91083260223c007c797e46bc8f631055Chris Banes // Peek at the Action Bar and update it if it already exists 15216e8d4dd91083260223c007c797e46bc8f631055Chris Banes ActionBar ab = peekSupportActionBar(); 15316e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (ab == null) { 15416e8d4dd91083260223c007c797e46bc8f631055Chris Banes mEnableDefaultActionBarUp = true; 15516e8d4dd91083260223c007c797e46bc8f631055Chris Banes } else { 15616e8d4dd91083260223c007c797e46bc8f631055Chris Banes ab.setDefaultDisplayHomeAsUpEnabled(true); 15716e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 15849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 15949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 16049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 16149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 16249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 163f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void onPostCreate(Bundle savedInstanceState) { 164c826d759805928c84b20e646e442d55483e003c8Chris Banes // Make sure that the sub decor is installed 165c826d759805928c84b20e646e442d55483e003c8Chris Banes ensureSubDecor(); 166c826d759805928c84b20e646e442d55483e003c8Chris Banes } 167c826d759805928c84b20e646e442d55483e003c8Chris Banes 168c826d759805928c84b20e646e442d55483e003c8Chris Banes @Override 16988c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes public ActionBar initWindowDecorActionBar() { 17030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell ensureSubDecor(); 17188c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes 17288c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes if (!mHasActionBar || peekSupportActionBar() != null) { 17388c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes return null; 17488c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes } 17588c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes 17616e8d4dd91083260223c007c797e46bc8f631055Chris Banes ActionBar ab = null; 17716e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (mOriginalWindowCallback instanceof Activity) { 17816e8d4dd91083260223c007c797e46bc8f631055Chris Banes ab = new WindowDecorActionBar((Activity) mOriginalWindowCallback, mOverlayActionBar); 17916e8d4dd91083260223c007c797e46bc8f631055Chris Banes } else if (mOriginalWindowCallback instanceof Dialog) { 18016e8d4dd91083260223c007c797e46bc8f631055Chris Banes ab = new WindowDecorActionBar((Dialog) mOriginalWindowCallback); 18116e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 18216e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (ab != null) { 18316e8d4dd91083260223c007c797e46bc8f631055Chris Banes ab.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp); 18416e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 18549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes return ab; 18649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 18749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 18849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes @Override 189f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void setSupportActionBar(Toolbar toolbar) { 19016e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (!(mOriginalWindowCallback instanceof Activity)) { 19116e8d4dd91083260223c007c797e46bc8f631055Chris Banes // Only Activities support custom Action Bars 19216e8d4dd91083260223c007c797e46bc8f631055Chris Banes return; 19316e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 19416e8d4dd91083260223c007c797e46bc8f631055Chris Banes 195da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes final ActionBar ab = getSupportActionBar(); 196da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes if (ab instanceof WindowDecorActionBar) { 19749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes throw new IllegalStateException("This Activity already has an action bar supplied " + 198d25af35061a9f20d59b25329d613c62c20184dadChris Banes "by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set " + 19949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes "windowActionBar to false in your theme to use a Toolbar instead."); 20049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 201da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes 20216e8d4dd91083260223c007c797e46bc8f631055Chris Banes ToolbarActionBar tbab = new ToolbarActionBar(toolbar, ((Activity) mContext).getTitle(), 20316e8d4dd91083260223c007c797e46bc8f631055Chris Banes mWindow); 2040b216f2263135782c361e122892a12156d5d2ce1Chris Banes setSupportActionBar(tbab); 20516e8d4dd91083260223c007c797e46bc8f631055Chris Banes mWindow.setCallback(tbab.getWrappedWindowCallback()); 2060b216f2263135782c361e122892a12156d5d2ce1Chris Banes tbab.invalidateOptionsMenu(); 2076386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2086386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 2096386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 2106386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void onConfigurationChanged(Configuration newConfig) { 2116386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes // If this is called before sub-decor is installed, ActionBar will not 2126386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes // be properly initialized. 2135a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes if (mHasActionBar && mSubDecorInstalled) { 2146386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes // Note: The action bar will need to access 2156386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes // view changes from superclass. 21649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBar ab = getSupportActionBar(); 21749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (ab != null) { 21849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ab.onConfigurationChanged(newConfig); 21949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes } 2206386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2216386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2226386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 2236386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 224a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes public void onStop() { 22549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBar ab = getSupportActionBar(); 226a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes if (ab != null) { 227a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes ab.setShowHideAnimationEnabled(false); 228a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes } 229a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes } 230a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes 231a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes @Override 232a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes public void onPostResume() { 23349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBar ab = getSupportActionBar(); 234a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes if (ab != null) { 235a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes ab.setShowHideAnimationEnabled(true); 236a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes } 237a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes } 238a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes 239a1fae63dbeeef71c2daa25bfcaa2348bffc369aaChris Banes @Override 2406386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void setContentView(View v) { 2416386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes ensureSubDecor(); 24216e8d4dd91083260223c007c797e46bc8f631055Chris Banes ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content); 24356fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.removeAllViews(); 24456fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.addView(v); 24516e8d4dd91083260223c007c797e46bc8f631055Chris Banes mOriginalWindowCallback.onContentChanged(); 2466386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2476386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 2486386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 2496386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void setContentView(int resId) { 2506386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes ensureSubDecor(); 25116e8d4dd91083260223c007c797e46bc8f631055Chris Banes ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content); 25256fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.removeAllViews(); 25316e8d4dd91083260223c007c797e46bc8f631055Chris Banes LayoutInflater.from(mContext).inflate(resId, contentParent); 25416e8d4dd91083260223c007c797e46bc8f631055Chris Banes mOriginalWindowCallback.onContentChanged(); 2556386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2566386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 2576386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 2586386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void setContentView(View v, ViewGroup.LayoutParams lp) { 2596386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes ensureSubDecor(); 26016e8d4dd91083260223c007c797e46bc8f631055Chris Banes ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content); 26156fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.removeAllViews(); 26256fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.addView(v, lp); 26316e8d4dd91083260223c007c797e46bc8f631055Chris Banes mOriginalWindowCallback.onContentChanged(); 2646386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 2656386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 2666386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 2676386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void addContentView(View v, ViewGroup.LayoutParams lp) { 2686386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes ensureSubDecor(); 26916e8d4dd91083260223c007c797e46bc8f631055Chris Banes ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content); 27056fd50144df518461398a9b3397ee4842b346708Chris Banes contentParent.addView(v, lp); 27116e8d4dd91083260223c007c797e46bc8f631055Chris Banes mOriginalWindowCallback.onContentChanged(); 272d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes } 273d64322f4b9686fabfd5a03f402d50a8e3fe5adedChris Banes 274f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes private void ensureSubDecor() { 27556fd50144df518461398a9b3397ee4842b346708Chris Banes if (!mSubDecorInstalled) { 2760f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes final LayoutInflater inflater = LayoutInflater.from(mContext); 2774b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes 2780f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes if (!mWindowNoTitle) { 2790f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes if (mIsFloating) { 2800f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes // If we're floating, inflate the dialog title decor 2810f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes mSubDecor = (ViewGroup) inflater.inflate( 2820f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes R.layout.abc_dialog_title_material, null); 283a9279663ecb98b85bf95a5ba1ebc145756fc13a2Chris Banes 284a9279663ecb98b85bf95a5ba1ebc145756fc13a2Chris Banes // Floating windows can never have an action bar, reset the flags 285a9279663ecb98b85bf95a5ba1ebc145756fc13a2Chris Banes mHasActionBar = mOverlayActionBar = false; 2860f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes } else if (mHasActionBar) { 2870f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes /** 2880f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes * This needs some explanation. As we can not use the android:theme attribute 2890f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes * pre-L, we emulate it by manually creating a LayoutInflater using a 2900f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes * ContextThemeWrapper pointing to actionBarTheme. 2910f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes */ 2920f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes TypedValue outValue = new TypedValue(); 2930f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes mContext.getTheme().resolveAttribute(R.attr.actionBarTheme, outValue, true); 2940f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes 2950f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes Context themedContext; 2960f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes if (outValue.resourceId != 0) { 2970f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes themedContext = new ContextThemeWrapper(mContext, outValue.resourceId); 2980f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes } else { 2990f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes themedContext = mContext; 3000f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes } 3010f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes 3020f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes // Now inflate the view using the themed context and set it as the content view 3030f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes mSubDecor = (ViewGroup) LayoutInflater.from(themedContext) 3040f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes .inflate(R.layout.abc_screen_toolbar, null); 3050f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes 3060f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes mDecorContentParent = (DecorContentParent) mSubDecor 3070f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes .findViewById(R.id.decor_content_parent); 3080f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes mDecorContentParent.setWindowCallback(getWindowCallback()); 3090f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes 3100f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes /** 3110f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes * Propagate features to DecorContentParent 3120f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes */ 3130f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes if (mOverlayActionBar) { 314d25af35061a9f20d59b25329d613c62c20184dadChris Banes mDecorContentParent.initFeature(FEATURE_SUPPORT_ACTION_BAR_OVERLAY); 3150f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes } 3160f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes if (mFeatureProgress) { 3170f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes mDecorContentParent.initFeature(Window.FEATURE_PROGRESS); 3180f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes } 3190f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes if (mFeatureIndeterminateProgress) { 3200f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes mDecorContentParent.initFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 3210f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes } 32256fd50144df518461398a9b3397ee4842b346708Chris Banes } 32356fd50144df518461398a9b3397ee4842b346708Chris Banes } else { 3240f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes if (mOverlayActionMode) { 3250f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes mSubDecor = (ViewGroup) inflater.inflate( 3260f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes R.layout.abc_screen_simple_overlay_action_mode, null); 327ea4f700ac38424954c56df5138ff794def50b019Chris Banes } else { 3280f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes mSubDecor = (ViewGroup) inflater.inflate(R.layout.abc_screen_simple, null); 329ea4f700ac38424954c56df5138ff794def50b019Chris Banes } 330ea4f700ac38424954c56df5138ff794def50b019Chris Banes 331ea4f700ac38424954c56df5138ff794def50b019Chris Banes if (Build.VERSION.SDK_INT >= 21) { 332ea4f700ac38424954c56df5138ff794def50b019Chris Banes // If we're running on L or above, we can rely on ViewCompat's 333ea4f700ac38424954c56df5138ff794def50b019Chris Banes // setOnApplyWindowInsetsListener 334ea4f700ac38424954c56df5138ff794def50b019Chris Banes ViewCompat.setOnApplyWindowInsetsListener(mSubDecor, 335ea4f700ac38424954c56df5138ff794def50b019Chris Banes new OnApplyWindowInsetsListener() { 336ea4f700ac38424954c56df5138ff794def50b019Chris Banes @Override 337ea4f700ac38424954c56df5138ff794def50b019Chris Banes public WindowInsetsCompat onApplyWindowInsets(View v, 338ea4f700ac38424954c56df5138ff794def50b019Chris Banes WindowInsetsCompat insets) { 339ea4f700ac38424954c56df5138ff794def50b019Chris Banes final int top = insets.getSystemWindowInsetTop(); 340ea4f700ac38424954c56df5138ff794def50b019Chris Banes final int newTop = updateStatusGuard(top); 341ea4f700ac38424954c56df5138ff794def50b019Chris Banes 342ea4f700ac38424954c56df5138ff794def50b019Chris Banes if (top != newTop) { 3433040adc60c191aca58e34a01428db628604924c5Chris Banes insets = insets.replaceSystemWindowInsets( 344ea4f700ac38424954c56df5138ff794def50b019Chris Banes insets.getSystemWindowInsetLeft(), 345ea4f700ac38424954c56df5138ff794def50b019Chris Banes newTop, 346ea4f700ac38424954c56df5138ff794def50b019Chris Banes insets.getSystemWindowInsetRight(), 347ea4f700ac38424954c56df5138ff794def50b019Chris Banes insets.getSystemWindowInsetBottom()); 348ea4f700ac38424954c56df5138ff794def50b019Chris Banes } 3493040adc60c191aca58e34a01428db628604924c5Chris Banes 3503040adc60c191aca58e34a01428db628604924c5Chris Banes // Now apply the insets on our view 3513040adc60c191aca58e34a01428db628604924c5Chris Banes return ViewCompat.onApplyWindowInsets(v, insets); 352ea4f700ac38424954c56df5138ff794def50b019Chris Banes } 353ea4f700ac38424954c56df5138ff794def50b019Chris Banes }); 354ea4f700ac38424954c56df5138ff794def50b019Chris Banes } else { 355ea4f700ac38424954c56df5138ff794def50b019Chris Banes // Else, we need to use our own FitWindowsViewGroup handling 356ea4f700ac38424954c56df5138ff794def50b019Chris Banes ((FitWindowsViewGroup) mSubDecor).setOnFitSystemWindowsListener( 357ea4f700ac38424954c56df5138ff794def50b019Chris Banes new FitWindowsViewGroup.OnFitSystemWindowsListener() { 358ea4f700ac38424954c56df5138ff794def50b019Chris Banes @Override 359ea4f700ac38424954c56df5138ff794def50b019Chris Banes public void onFitSystemWindows(Rect insets) { 360ea4f700ac38424954c56df5138ff794def50b019Chris Banes insets.top = updateStatusGuard(insets.top); 361ea4f700ac38424954c56df5138ff794def50b019Chris Banes } 362ea4f700ac38424954c56df5138ff794def50b019Chris Banes }); 363ea4f700ac38424954c56df5138ff794def50b019Chris Banes } 3643954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes } 3653954d59cb6073615ead9dd34cbdba9e16b8c5b6fChris Banes 3660f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes if (mSubDecor == null) { 3670f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes throw new IllegalArgumentException( 3680f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes "AppCompat does not support the current theme features"); 3690f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes } 3700f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes 37116e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (mDecorContentParent == null) { 37216e8d4dd91083260223c007c797e46bc8f631055Chris Banes mTitleView = (TextView) mSubDecor.findViewById(R.id.title); 37316e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 37416e8d4dd91083260223c007c797e46bc8f631055Chris Banes 3751f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes // Make the decor optionally fit system windows, like the window's decor 376ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes ViewUtils.makeOptionalFitsSystemWindows(mSubDecor); 3771f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes 37816e8d4dd91083260223c007c797e46bc8f631055Chris Banes final ViewGroup decorContent = (ViewGroup) mWindow.findViewById(android.R.id.content); 37919eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes final ContentFrameLayout abcContent = (ContentFrameLayout) mSubDecor.findViewById( 380c826d759805928c84b20e646e442d55483e003c8Chris Banes R.id.action_bar_activity_content); 381c826d759805928c84b20e646e442d55483e003c8Chris Banes 382c826d759805928c84b20e646e442d55483e003c8Chris Banes // There might be Views already added to the Window's content view so we need to 383c826d759805928c84b20e646e442d55483e003c8Chris Banes // migrate them to our content view 384c826d759805928c84b20e646e442d55483e003c8Chris Banes while (decorContent.getChildCount() > 0) { 385c826d759805928c84b20e646e442d55483e003c8Chris Banes final View child = decorContent.getChildAt(0); 386c826d759805928c84b20e646e442d55483e003c8Chris Banes decorContent.removeViewAt(0); 387c826d759805928c84b20e646e442d55483e003c8Chris Banes abcContent.addView(child); 388c826d759805928c84b20e646e442d55483e003c8Chris Banes } 389c826d759805928c84b20e646e442d55483e003c8Chris Banes 390f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // Now set the Window's content view with the decor 39116e8d4dd91083260223c007c797e46bc8f631055Chris Banes mWindow.setContentView(mSubDecor); 3921f4989216d62f70088cea29f9ae200a9bb3ff955Chris Banes 39392b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes // Change our content FrameLayout to use the android.R.id.content id. 39492b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes // Useful for fragments. 3954b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes decorContent.setId(View.NO_ID); 39692b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes abcContent.setId(android.R.id.content); 39792b18eb0263ef2421fda5bf977fea3bf044bf941Chris Banes 3984b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes // The decorContent may have a foreground drawable set (windowContentOverlay). 3994b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes // Remove this as we handle it ourselves 4004b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes if (decorContent instanceof FrameLayout) { 4014b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes ((FrameLayout) decorContent).setForeground(null); 4024b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes } 4034b217eaec19887b37d6d124df5ba04c5bb8b8141Chris Banes 40416e8d4dd91083260223c007c797e46bc8f631055Chris Banes // If a title was set before we installed the decor, propogate it now 40516e8d4dd91083260223c007c797e46bc8f631055Chris Banes CharSequence title = getTitle(); 40616e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (!TextUtils.isEmpty(title)) { 40716e8d4dd91083260223c007c797e46bc8f631055Chris Banes onTitleChanged(title); 408f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes } 409556ac47ce764a4a9320b5ac914536e9da2524176Chris Banes 41019eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes applyFixedSizeWindow(abcContent); 41156fd50144df518461398a9b3397ee4842b346708Chris Banes 41216e8d4dd91083260223c007c797e46bc8f631055Chris Banes onSubDecorInstalled(mSubDecor); 41349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 414f53c7bf3146bf9bcba46324f9f06449df475be36Chris Banes mSubDecorInstalled = true; 4158902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 41600d183885b54de433e43118d3032340f40cac8c0Chris Banes // Invalidate if the panel menu hasn't been created before this. 41700d183885b54de433e43118d3032340f40cac8c0Chris Banes // Panel menu invalidation is deferred avoiding application onCreateOptionsMenu 41800d183885b54de433e43118d3032340f40cac8c0Chris Banes // being called in the middle of onCreate or similar. 41900d183885b54de433e43118d3032340f40cac8c0Chris Banes // A pending invalidation will typically be resolved before the posted message 42000d183885b54de433e43118d3032340f40cac8c0Chris Banes // would run normally in order to satisfy instance state restoration. 42100d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false); 4229b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (!isDestroyed() && (st == null || st.menu == null)) { 423d25af35061a9f20d59b25329d613c62c20184dadChris Banes invalidatePanelMenu(FEATURE_SUPPORT_ACTION_BAR); 42400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 4256386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 4266386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 4276386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 42816e8d4dd91083260223c007c797e46bc8f631055Chris Banes void onSubDecorInstalled(ViewGroup subDecor) {} 42949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes 43019eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes private void applyFixedSizeWindow(ContentFrameLayout contentFrameLayout) { 431d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes // This is a bit weird. In the framework, the window sizing attributes control 432d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes // the decor view's size, meaning that any padding is inset for the min/max widths below. 433d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes // We don't control measurement at that level, so we need to workaround it by making sure 434d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes // that the decor view's padding is taken into account. 435d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes contentFrameLayout.setDecorPadding(mWindowDecor.getPaddingLeft(), 436d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes mWindowDecor.getPaddingTop(), mWindowDecor.getPaddingRight(), 437d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes mWindowDecor.getPaddingBottom()); 438d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes 439d8b7157eae680353a2821dca3c9e52b3aaf737a5Chris Banes 44016e8d4dd91083260223c007c797e46bc8f631055Chris Banes TypedArray a = mContext.obtainStyledAttributes(R.styleable.Theme); 44119eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes a.getValue(R.styleable.Theme_windowMinWidthMajor, contentFrameLayout.getMinWidthMajor()); 44219eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes a.getValue(R.styleable.Theme_windowMinWidthMinor, contentFrameLayout.getMinWidthMinor()); 44356fd50144df518461398a9b3397ee4842b346708Chris Banes 44449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (a.hasValue(R.styleable.Theme_windowFixedWidthMajor)) { 44519eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes a.getValue(R.styleable.Theme_windowFixedWidthMajor, 44619eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes contentFrameLayout.getFixedWidthMajor()); 44756fd50144df518461398a9b3397ee4842b346708Chris Banes } 44849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (a.hasValue(R.styleable.Theme_windowFixedWidthMinor)) { 44919eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes a.getValue(R.styleable.Theme_windowFixedWidthMinor, 45019eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes contentFrameLayout.getFixedWidthMinor()); 45156fd50144df518461398a9b3397ee4842b346708Chris Banes } 45249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (a.hasValue(R.styleable.Theme_windowFixedHeightMajor)) { 45319eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes a.getValue(R.styleable.Theme_windowFixedHeightMajor, 45419eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes contentFrameLayout.getFixedHeightMajor()); 45556fd50144df518461398a9b3397ee4842b346708Chris Banes } 45649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (a.hasValue(R.styleable.Theme_windowFixedHeightMinor)) { 45719eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes a.getValue(R.styleable.Theme_windowFixedHeightMinor, 45819eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes contentFrameLayout.getFixedHeightMinor()); 45956fd50144df518461398a9b3397ee4842b346708Chris Banes } 46056fd50144df518461398a9b3397ee4842b346708Chris Banes a.recycle(); 46119eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes 46219eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes contentFrameLayout.requestLayout(); 46356fd50144df518461398a9b3397ee4842b346708Chris Banes } 46456fd50144df518461398a9b3397ee4842b346708Chris Banes 4656386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 466f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public boolean requestWindowFeature(int featureId) { 46788c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes if (mWindowNoTitle && featureId == FEATURE_SUPPORT_ACTION_BAR) { 46888c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes return false; // Ignore. No title dominates. 46988c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes } 47088c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes if (mHasActionBar && featureId == Window.FEATURE_NO_TITLE) { 47188c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes // Remove the action bar feature if we have no title. No title dominates. 47288c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes mHasActionBar = false; 47388c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes } 47488c0ac5649d6b82c882e2de4bc4f043b107a4428Chris Banes 4756386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes switch (featureId) { 476d25af35061a9f20d59b25329d613c62c20184dadChris Banes case WindowCompat.FEATURE_ACTION_BAR: 477d25af35061a9f20d59b25329d613c62c20184dadChris Banes Log.i(TAG, "You should now use the AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR" 478d25af35061a9f20d59b25329d613c62c20184dadChris Banes + " id when requesting this feature."); 479d25af35061a9f20d59b25329d613c62c20184dadChris Banes // $FALLTHROUGH 480d25af35061a9f20d59b25329d613c62c20184dadChris Banes case FEATURE_SUPPORT_ACTION_BAR: 481cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throwFeatureRequestIfSubDecorInstalled(); 4825a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes mHasActionBar = true; 4836386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes return true; 484d25af35061a9f20d59b25329d613c62c20184dadChris Banes case WindowCompat.FEATURE_ACTION_BAR_OVERLAY: 485d25af35061a9f20d59b25329d613c62c20184dadChris Banes Log.i(TAG, "You should now use the AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR_OVERLAY" 486d25af35061a9f20d59b25329d613c62c20184dadChris Banes + " id when requesting this feature."); 487d25af35061a9f20d59b25329d613c62c20184dadChris Banes // $FALLTHROUGH 488d25af35061a9f20d59b25329d613c62c20184dadChris Banes case FEATURE_SUPPORT_ACTION_BAR_OVERLAY: 489cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throwFeatureRequestIfSubDecorInstalled(); 4905a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes mOverlayActionBar = true; 4916386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes return true; 49200d183885b54de433e43118d3032340f40cac8c0Chris Banes case FEATURE_ACTION_MODE_OVERLAY: 493cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throwFeatureRequestIfSubDecorInstalled(); 494de9f38cc4a30b33ac46b105edf470fbc4a044e99Chris Banes mOverlayActionMode = true; 495de9f38cc4a30b33ac46b105edf470fbc4a044e99Chris Banes return true; 496ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes case Window.FEATURE_PROGRESS: 497cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throwFeatureRequestIfSubDecorInstalled(); 498ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes mFeatureProgress = true; 499ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes return true; 500ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes case Window.FEATURE_INDETERMINATE_PROGRESS: 501cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throwFeatureRequestIfSubDecorInstalled(); 502ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes mFeatureIndeterminateProgress = true; 503ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes return true; 50419eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes case Window.FEATURE_NO_TITLE: 50519eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes throwFeatureRequestIfSubDecorInstalled(); 50619eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes mWindowNoTitle = true; 50719eaf14cb3cca613f984a32be2fab2534427fb29Chris Banes return true; 5086386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 509cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes 51016e8d4dd91083260223c007c797e46bc8f631055Chris Banes return mWindow.requestFeature(featureId); 5116386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 5126386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 5136386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 51416e8d4dd91083260223c007c797e46bc8f631055Chris Banes void onTitleChanged(CharSequence title) { 51549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (mDecorContentParent != null) { 51649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes mDecorContentParent.setWindowTitle(title); 517535c5737ba868a622d7783d57f7078ab285717c0Chris Banes } else if (peekSupportActionBar() != null) { 518535c5737ba868a622d7783d57f7078ab285717c0Chris Banes peekSupportActionBar().setWindowTitle(title); 51916e8d4dd91083260223c007c797e46bc8f631055Chris Banes } else if (mTitleView != null) { 52016e8d4dd91083260223c007c797e46bc8f631055Chris Banes mTitleView.setText(title); 5216386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 5226386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 5236386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 5246386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 525d25af35061a9f20d59b25329d613c62c20184dadChris Banes void onPanelClosed(final int featureId, Menu menu) { 526d25af35061a9f20d59b25329d613c62c20184dadChris Banes if (featureId == FEATURE_SUPPORT_ACTION_BAR) { 52700d183885b54de433e43118d3032340f40cac8c0Chris Banes ActionBar ab = getSupportActionBar(); 52800d183885b54de433e43118d3032340f40cac8c0Chris Banes if (ab != null) { 52900d183885b54de433e43118d3032340f40cac8c0Chris Banes ab.dispatchMenuVisibilityChanged(false); 53000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 531436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes } else if (featureId == FEATURE_OPTIONS_PANEL) { 532436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes // Make sure that the options panel is closed. This is mainly used when we're using a 533436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes // ToolbarActionBar 534436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes PanelFeatureState st = getPanelState(featureId, true); 535436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes if (st.isOpen) { 536436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes closePanel(st, false); 537436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes } 538c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes } 539c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes } 540c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes 541c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes @Override 54200d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean onMenuOpened(final int featureId, Menu menu) { 543d25af35061a9f20d59b25329d613c62c20184dadChris Banes if (featureId == FEATURE_SUPPORT_ACTION_BAR) { 54400d183885b54de433e43118d3032340f40cac8c0Chris Banes ActionBar ab = getSupportActionBar(); 54500d183885b54de433e43118d3032340f40cac8c0Chris Banes if (ab != null) { 54600d183885b54de433e43118d3032340f40cac8c0Chris Banes ab.dispatchMenuVisibilityChanged(true); 54700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 54800d183885b54de433e43118d3032340f40cac8c0Chris Banes return true; 549c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes } 550f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return false; 55103fc11b659da1645507062bddda450136e13af35Chris Banes } 55203fc11b659da1645507062bddda450136e13af35Chris Banes 55303fc11b659da1645507062bddda450136e13af35Chris Banes @Override 5546386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { 555f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final Window.Callback cb = getWindowCallback(); 5569b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (cb != null && !isDestroyed()) { 5579b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes final PanelFeatureState panel = findMenuPanel(menu.getRootMenu()); 5589b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (panel != null) { 5599b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes return cb.onMenuItemSelected(panel.featureId, item); 5609b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 5619b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 5629b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes return false; 5636386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 5646386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 5656386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 5666386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes public void onMenuModeChange(MenuBuilder menu) { 5676386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes reopenMenu(menu, true); 5686386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 5696386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 5706386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes @Override 571d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes public ActionMode startSupportActionMode(ActionMode.Callback callback) { 572d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes if (callback == null) { 573d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes throw new IllegalArgumentException("ActionMode callback can not be null."); 574d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 575d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 576d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes if (mActionMode != null) { 577d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes mActionMode.finish(); 578d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 579d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 580547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapperV7(callback); 581d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 58249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBar ab = getSupportActionBar(); 583d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes if (ab != null) { 5845a2bcc375e046c5b6644dcc4d331d3fca0778aedChris Banes mActionMode = ab.startActionMode(wrappedCallback); 585f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (mActionMode != null && mAppCompatCallback != null) { 586f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes mAppCompatCallback.onSupportActionModeStarted(mActionMode); 5870bf48858279237f95d6aad565a074490745491cdChris Banes } 588d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 589d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 5900bf48858279237f95d6aad565a074490745491cdChris Banes if (mActionMode == null) { 5910bf48858279237f95d6aad565a074490745491cdChris Banes // If the action bar didn't provide an action mode, start the emulated window one 5920bf48858279237f95d6aad565a074490745491cdChris Banes mActionMode = startSupportActionModeFromWindow(wrappedCallback); 593d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 5940bf48858279237f95d6aad565a074490745491cdChris Banes 595d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return mActionMode; 596d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 597d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 598d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes @Override 599f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void invalidateOptionsMenu() { 600f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes final ActionBar ab = getSupportActionBar(); 601f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes if (ab != null && ab.invalidateOptionsMenu()) return; 602f2045f06bdfc9e2cc40a734e41e45d11adf2bc23Chris Banes 60300d183885b54de433e43118d3032340f40cac8c0Chris Banes invalidatePanelMenu(FEATURE_OPTIONS_PANEL); 6046386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes } 6056386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes 6064c2a95906254748cb9a843b061288265d6e185a9Chris Banes @Override 6074c2a95906254748cb9a843b061288265d6e185a9Chris Banes ActionMode startSupportActionModeFromWindow(ActionMode.Callback callback) { 6084c2a95906254748cb9a843b061288265d6e185a9Chris Banes if (mActionMode != null) { 6094c2a95906254748cb9a843b061288265d6e185a9Chris Banes mActionMode.finish(); 6104c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 6114c2a95906254748cb9a843b061288265d6e185a9Chris Banes 612547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final ActionMode.Callback wrappedCallback = new ActionModeCallbackWrapperV7(callback); 613547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes ActionMode mode = null; 614547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mAppCompatCallback != null && !isDestroyed()) { 615547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes try { 616547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mode = mAppCompatCallback.onWindowStartingSupportActionMode(wrappedCallback); 617547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } catch (AbstractMethodError ame) { 618547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes // Older apps might not implement this callback method. 6194c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 6204c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 6214c2a95906254748cb9a843b061288265d6e185a9Chris Banes 622547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mode != null) { 623547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionMode = mode; 624547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } else { 625547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mActionModeView == null) { 626547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mIsFloating) { 627547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes // Use the action bar theme. 628547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final TypedValue outValue = new TypedValue(); 629547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final Resources.Theme baseTheme = mContext.getTheme(); 630547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true); 631547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 632547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final Context actionBarContext; 633547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (outValue.resourceId != 0) { 634547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final Resources.Theme actionBarTheme = mContext.getResources().newTheme(); 635547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarTheme.setTo(baseTheme); 636547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarTheme.applyStyle(outValue.resourceId, true); 637547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 638547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarContext = new ContextThemeWrapper(mContext, 0); 639547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarContext.getTheme().setTo(actionBarTheme); 640547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } else { 641547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarContext = mContext; 642547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 643547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 644547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView = new ActionBarContextView(actionBarContext); 645547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModePopup = new PopupWindow(actionBarContext, null, 646547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes R.attr.actionModePopupWindowStyle); 647f5829201b976fc650789accc22f325a2541ed478Chris Banes PopupWindowCompat.setWindowLayoutType(mActionModePopup, 648f5829201b976fc650789accc22f325a2541ed478Chris Banes WindowManager.LayoutParams.TYPE_APPLICATION); 649547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModePopup.setContentView(mActionModeView); 650547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModePopup.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); 651547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 652547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarContext.getTheme().resolveAttribute( 653547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes R.attr.actionBarSize, outValue, true); 654547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes final int height = TypedValue.complexToDimensionPixelSize(outValue.data, 655547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes actionBarContext.getResources().getDisplayMetrics()); 656547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView.setContentHeight(height); 657547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModePopup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); 658547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mShowActionModePopup = new Runnable() { 659547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes public void run() { 660547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModePopup.showAtLocation( 661547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView, 662547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0); 663547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 664547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes }; 665547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } else { 666547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes ViewStubCompat stub = (ViewStubCompat) mSubDecor 667547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes .findViewById(R.id.action_mode_bar_stub); 668547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (stub != null) { 669547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes // Set the layout inflater so that it is inflated with the action bar's context 670547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes stub.setLayoutInflater(LayoutInflater.from(getActionBarThemedContext())); 671547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView = (ActionBarContextView) stub.inflate(); 672547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 6734c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 674547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 675ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes 676547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mActionModeView != null) { 677547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView.killMode(); 678547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mode = new StandaloneActionMode(mActionModeView.getContext(), mActionModeView, 679547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes wrappedCallback, mActionModePopup == null); 680547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (callback.onCreateActionMode(mode, mode.getMenu())) { 681547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mode.invalidate(); 682547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView.initForMode(mode); 683547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView.setVisibility(View.VISIBLE); 684547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionMode = mode; 685547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mActionModePopup != null) { 686547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mWindow.getDecorView().post(mShowActionModePopup); 687547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 688547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionModeView.sendAccessibilityEvent( 689547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 690547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 691547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mActionModeView.getParent() != null) { 692547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes ViewCompat.requestApplyInsets((View) mActionModeView.getParent()); 693547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 694547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } else { 695547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes mActionMode = null; 696ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 6974c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 6984c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 699f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (mActionMode != null && mAppCompatCallback != null) { 700f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes mAppCompatCallback.onSupportActionModeStarted(mActionMode); 7014c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 7024c2a95906254748cb9a843b061288265d6e185a9Chris Banes return mActionMode; 7034c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 7044c2a95906254748cb9a843b061288265d6e185a9Chris Banes 705f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes boolean onBackPressed() { 706d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes // Back cancels action modes first. 707d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes if (mActionMode != null) { 708d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes mActionMode.finish(); 709d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return true; 710d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 711d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 712d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes // Next collapse any expanded action views. 71349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes ActionBar ab = getSupportActionBar(); 71449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes if (ab != null && ab.collapseActionView()) { 715d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return true; 716d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 717d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 718f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // Let the call through... 719d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return false; 720d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 721d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 722d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes @Override 72300d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean onKeyShortcut(int keyCode, KeyEvent ev) { 724d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes // Let the Action Bar have a chance at handling the shortcut 725d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes ActionBar ab = getSupportActionBar(); 726d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes if (ab != null && ab.onKeyShortcut(keyCode, ev)) { 727d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes return true; 728d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes } 729d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes 730dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // If the panel is already prepared, then perform the shortcut using it. 73100d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean handled; 73200d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mPreparedPanel != null) { 73300d183885b54de433e43118d3032340f40cac8c0Chris Banes handled = performPanelShortcut(mPreparedPanel, ev.getKeyCode(), ev, 73400d183885b54de433e43118d3032340f40cac8c0Chris Banes Menu.FLAG_PERFORM_NO_CLOSE); 73500d183885b54de433e43118d3032340f40cac8c0Chris Banes if (handled) { 73600d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mPreparedPanel != null) { 73700d183885b54de433e43118d3032340f40cac8c0Chris Banes mPreparedPanel.isHandled = true; 73800d183885b54de433e43118d3032340f40cac8c0Chris Banes } 73900d183885b54de433e43118d3032340f40cac8c0Chris Banes return true; 74000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 74100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 74200d183885b54de433e43118d3032340f40cac8c0Chris Banes 74300d183885b54de433e43118d3032340f40cac8c0Chris Banes // If the panel is not prepared, then we may be trying to handle a shortcut key 74400d183885b54de433e43118d3032340f40cac8c0Chris Banes // combination such as Control+C. Temporarily prepare the panel then mark it 74500d183885b54de433e43118d3032340f40cac8c0Chris Banes // unprepared again when finished to ensure that the panel will again be prepared 74600d183885b54de433e43118d3032340f40cac8c0Chris Banes // the next time it is shown for real. 74700d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mPreparedPanel == null) { 74800d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); 74900d183885b54de433e43118d3032340f40cac8c0Chris Banes preparePanel(st, ev); 75000d183885b54de433e43118d3032340f40cac8c0Chris Banes handled = performPanelShortcut(st, ev.getKeyCode(), ev, Menu.FLAG_PERFORM_NO_CLOSE); 75100d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isPrepared = false; 75200d183885b54de433e43118d3032340f40cac8c0Chris Banes if (handled) { 75300d183885b54de433e43118d3032340f40cac8c0Chris Banes return true; 75400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 75500d183885b54de433e43118d3032340f40cac8c0Chris Banes } 75600d183885b54de433e43118d3032340f40cac8c0Chris Banes return false; 757dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 758dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 759dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes @Override 76046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes boolean dispatchKeyEvent(KeyEvent event) { 76146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes final int keyCode = event.getKeyCode(); 76246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes final int action = event.getAction(); 76346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes final boolean isDown = action == KeyEvent.ACTION_DOWN; 76446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 76546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return isDown ? onKeyDown(keyCode, event) : onKeyUp(keyCode, event); 76646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 76746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 768f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes boolean onKeyUp(int keyCode, KeyEvent event) { 76946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes switch (keyCode) { 77046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes case KeyEvent.KEYCODE_MENU: 771559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes if (onKeyUpPanel(Window.FEATURE_OPTIONS_PANEL, event)) { 772559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes return true; 773559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes } 774559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes break; 77546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes case KeyEvent.KEYCODE_BACK: 77646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes PanelFeatureState st = getPanelState(Window.FEATURE_OPTIONS_PANEL, false); 77746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st != null && st.isOpen) { 77846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes closePanel(st, true); 77946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return true; 78046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 781f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (onBackPressed()) { 782f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return true; 783f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 78446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes break; 78546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 78646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return false; 78746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 78846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 789f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes boolean onKeyDown(int keyCode, KeyEvent event) { 790f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes switch (keyCode) { 791f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes case KeyEvent.KEYCODE_MENU: 792559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes if (onKeyDownPanel(Window.FEATURE_OPTIONS_PANEL, event)) { 793559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes return true; 794559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes } 795559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes break; 79646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 79746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 798dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // On API v7-10 we need to manually call onKeyShortcut() as this is not called 799dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // from the Activity 80046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 80146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return onKeyShortcut(keyCode, event); 80246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 80346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return false; 804dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 805dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 806469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes @Override 807f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public View createView(View parent, final String name, @NonNull Context context, 808fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes @NonNull AttributeSet attrs) { 809a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes final boolean isPre21 = Build.VERSION.SDK_INT < 21; 810878ed08a784cafb112a5d350573b0d1e81c554dbChris Banes 8112cccf609662389d6a23dbc0711d5fb2e826e8c63Chris Banes if (mAppCompatViewInflater == null) { 812e183f2600fb31c69eceacc1c263cd56f12489a65Chris Banes mAppCompatViewInflater = new AppCompatViewInflater(); 813469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes } 814fd1eb27a3700de31507de34fd1bcc51830fe876cChris Banes 815e183f2600fb31c69eceacc1c263cd56f12489a65Chris Banes // We only want the View to inherit it's context if we're running pre-v21 and... 816a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes final boolean inheritContext = isPre21 && mSubDecorInstalled && parent != null 817e183f2600fb31c69eceacc1c263cd56f12489a65Chris Banes // We do not want to inherit context from any decor content 818e183f2600fb31c69eceacc1c263cd56f12489a65Chris Banes && parent.getId() != android.R.id.content 819e183f2600fb31c69eceacc1c263cd56f12489a65Chris Banes // We do not want to inherit context if this is the root view in the layout. 820e183f2600fb31c69eceacc1c263cd56f12489a65Chris Banes // We use parent.isAttachedToWindow() to determine this, which works because 821e183f2600fb31c69eceacc1c263cd56f12489a65Chris Banes // an inflated layout is only added to the hierarchy AFTER it is completely 822f6610f183f0afe6e392dea804474f722d82083fdChris Banes // inflated. Thus isAttachedToWindow() will only return true if the parent 823e183f2600fb31c69eceacc1c263cd56f12489a65Chris Banes // has not been inflated within the outer inflation call. 824f6610f183f0afe6e392dea804474f722d82083fdChris Banes && !ViewCompat.isAttachedToWindow(parent); 825a73cf65dff6d7fa58907e614f95e1d3679de0a79Chris Banes 826484705a5e6fdc1f6ef746b822716a45f82652ab9Chris Banes return mAppCompatViewInflater.createView(parent, name, context, attrs, inheritContext, 827484705a5e6fdc1f6ef746b822716a45f82652ab9Chris Banes isPre21, /* Only read android:theme pre-L (L+ handles this anyway) */ 828484705a5e6fdc1f6ef746b822716a45f82652ab9Chris Banes true /* Read read app:theme as a fallback at all times for legacy reasons */ 829484705a5e6fdc1f6ef746b822716a45f82652ab9Chris Banes ); 830469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes } 831469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes 832f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 833f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void installViewFactory() { 83416e8d4dd91083260223c007c797e46bc8f631055Chris Banes LayoutInflater layoutInflater = LayoutInflater.from(mContext); 835f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (layoutInflater.getFactory() == null) { 836f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes LayoutInflaterCompat.setFactory(layoutInflater, this); 837f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } else { 838f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Log.i(TAG, "The Activity's LayoutInflater already has a Factory installed" 839f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes + " so we can not install AppCompat's"); 840f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 841f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 842f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 843f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes /** 844f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * From {@link android.support.v4.view.LayoutInflaterFactory} 845f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes */ 846f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 847498356fea126122c3e3720a419969055cb889428Chris Banes public final View onCreateView(View parent, String name, 848f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Context context, AttributeSet attrs) { 849498356fea126122c3e3720a419969055cb889428Chris Banes // First let the Activity's Factory try and inflate the view 850498356fea126122c3e3720a419969055cb889428Chris Banes final View view = callActivityOnCreateView(parent, name, context, attrs); 851498356fea126122c3e3720a419969055cb889428Chris Banes if (view != null) { 852498356fea126122c3e3720a419969055cb889428Chris Banes return view; 853498356fea126122c3e3720a419969055cb889428Chris Banes } 854498356fea126122c3e3720a419969055cb889428Chris Banes 855498356fea126122c3e3720a419969055cb889428Chris Banes // If the Factory didn't handle it, let our createView() method try 856498356fea126122c3e3720a419969055cb889428Chris Banes return createView(parent, name, context, attrs); 857498356fea126122c3e3720a419969055cb889428Chris Banes } 85816e8d4dd91083260223c007c797e46bc8f631055Chris Banes 859498356fea126122c3e3720a419969055cb889428Chris Banes View callActivityOnCreateView(View parent, String name, Context context, AttributeSet attrs) { 860498356fea126122c3e3720a419969055cb889428Chris Banes // Let the Activity's LayoutInflater.Factory try and handle it 86116e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (mOriginalWindowCallback instanceof LayoutInflater.Factory) { 862498356fea126122c3e3720a419969055cb889428Chris Banes final View result = ((LayoutInflater.Factory) mOriginalWindowCallback) 86316e8d4dd91083260223c007c797e46bc8f631055Chris Banes .onCreateView(name, context, attrs); 86416e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (result != null) { 86516e8d4dd91083260223c007c797e46bc8f631055Chris Banes return result; 86616e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 867f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 868498356fea126122c3e3720a419969055cb889428Chris Banes return null; 869f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 870f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 87100d183885b54de433e43118d3032340f40cac8c0Chris Banes private void openPanel(final PanelFeatureState st, KeyEvent event) { 87200d183885b54de433e43118d3032340f40cac8c0Chris Banes // Already open, return 8739b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (st.isOpen || isDestroyed()) { 87400d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 87500d183885b54de433e43118d3032340f40cac8c0Chris Banes } 87600d183885b54de433e43118d3032340f40cac8c0Chris Banes 87700d183885b54de433e43118d3032340f40cac8c0Chris Banes // Don't open an options panel for honeycomb apps on xlarge devices. 87800d183885b54de433e43118d3032340f40cac8c0Chris Banes // (The app should be using an action bar for menu items.) 87900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st.featureId == FEATURE_OPTIONS_PANEL) { 88016e8d4dd91083260223c007c797e46bc8f631055Chris Banes Context context = mContext; 88100d183885b54de433e43118d3032340f40cac8c0Chris Banes Configuration config = context.getResources().getConfiguration(); 88200d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isXLarge = (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == 88300d183885b54de433e43118d3032340f40cac8c0Chris Banes Configuration.SCREENLAYOUT_SIZE_XLARGE; 88400d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isHoneycombApp = context.getApplicationInfo().targetSdkVersion >= 88500d183885b54de433e43118d3032340f40cac8c0Chris Banes android.os.Build.VERSION_CODES.HONEYCOMB; 88600d183885b54de433e43118d3032340f40cac8c0Chris Banes 88700d183885b54de433e43118d3032340f40cac8c0Chris Banes if (isXLarge && isHoneycombApp) { 88800d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 88900d183885b54de433e43118d3032340f40cac8c0Chris Banes } 89000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 89100d183885b54de433e43118d3032340f40cac8c0Chris Banes 892f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Window.Callback cb = getWindowCallback(); 89300d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((cb != null) && (!cb.onMenuOpened(st.featureId, st.menu))) { 89400d183885b54de433e43118d3032340f40cac8c0Chris Banes // Callback doesn't want the menu to open, reset any state 89500d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(st, true); 89600d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 89700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 89800d183885b54de433e43118d3032340f40cac8c0Chris Banes 89916e8d4dd91083260223c007c797e46bc8f631055Chris Banes final WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 90046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (wm == null) { 90146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return; 90246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 90346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 90400d183885b54de433e43118d3032340f40cac8c0Chris Banes // Prepare panel (should have been done before, but just in case) 90500d183885b54de433e43118d3032340f40cac8c0Chris Banes if (!preparePanel(st, event)) { 90600d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 90700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 90800d183885b54de433e43118d3032340f40cac8c0Chris Banes 90946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int width = WRAP_CONTENT; 91000d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st.decorView == null || st.refreshDecorView) { 91146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.decorView == null) { 91246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Initialize the panel decor, this will populate st.decorView 91346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!initializePanelDecor(st) || (st.decorView == null)) 91446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return; 91546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else if (st.refreshDecorView && (st.decorView.getChildCount() > 0)) { 91646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Decor needs refreshing, so remove its views 91746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.decorView.removeAllViews(); 91846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 91900d183885b54de433e43118d3032340f40cac8c0Chris Banes 92046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // This will populate st.shownPanelView 92146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!initializePanelContent(st) || !st.hasPanelItems()) { 92246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return; 92346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 92446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 92546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes ViewGroup.LayoutParams lp = st.shownPanelView.getLayoutParams(); 92646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (lp == null) { 92746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes lp = new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); 92846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 92946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 93046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int backgroundResId = st.background; 93146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.decorView.setBackgroundResource(backgroundResId); 93246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 93346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes ViewParent shownPanelParent = st.shownPanelView.getParent(); 93446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (shownPanelParent != null && shownPanelParent instanceof ViewGroup) { 93546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes ((ViewGroup) shownPanelParent).removeView(st.shownPanelView); 93646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 93746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.decorView.addView(st.shownPanelView, lp); 93846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 93946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes /* 94046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes * Give focus to the view, if it or one of its children does not 94146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes * already have it. 94246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes */ 94346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!st.shownPanelView.hasFocus()) { 94446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.shownPanelView.requestFocus(); 94546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 94646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else if (st.createdPanelView != null) { 94746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // If we already had a panel view, carry width=MATCH_PARENT through 94846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // as we did above when it was created. 94946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes ViewGroup.LayoutParams lp = st.createdPanelView.getLayoutParams(); 95046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (lp != null && lp.width == ViewGroup.LayoutParams.MATCH_PARENT) { 95146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes width = MATCH_PARENT; 95246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 95300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 95400d183885b54de433e43118d3032340f40cac8c0Chris Banes 95500d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isHandled = false; 95646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 95746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 95846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes width, WRAP_CONTENT, 95946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.x, st.y, WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL, 96046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM 96146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, 96246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes PixelFormat.TRANSLUCENT); 96346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 96446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes lp.gravity = st.gravity; 96546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes lp.windowAnimations = st.windowAnimations; 96646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 96746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes wm.addView(st.decorView, lp); 96800d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isOpen = true; 96900d183885b54de433e43118d3032340f40cac8c0Chris Banes } 97000d183885b54de433e43118d3032340f40cac8c0Chris Banes 97146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes private boolean initializePanelDecor(PanelFeatureState st) { 97257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes st.setStyle(getActionBarThemedContext()); 97346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.decorView = new ListMenuDecorView(st.listPresenterContext); 97446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.gravity = Gravity.CENTER | Gravity.BOTTOM; 97546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return true; 97600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 97700d183885b54de433e43118d3032340f40cac8c0Chris Banes 97800d183885b54de433e43118d3032340f40cac8c0Chris Banes private void reopenMenu(MenuBuilder menu, boolean toggleMenuMode) { 97900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mDecorContentParent != null && mDecorContentParent.canShowOverflowMenu() && 98016e8d4dd91083260223c007c797e46bc8f631055Chris Banes (!ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mContext)) || 98100d183885b54de433e43118d3032340f40cac8c0Chris Banes mDecorContentParent.isOverflowMenuShowPending())) { 9829b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes 983f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final Window.Callback cb = getWindowCallback(); 9849b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes 98500d183885b54de433e43118d3032340f40cac8c0Chris Banes if (!mDecorContentParent.isOverflowMenuShowing() || !toggleMenuMode) { 9869b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (cb != null && !isDestroyed()) { 9879b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes // If we have a menu invalidation pending, do it now. 9889b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (mInvalidatePanelMenuPosted && 9899b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes (mInvalidatePanelMenuFeatures & (1 << FEATURE_OPTIONS_PANEL)) != 0) { 9909b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes mWindowDecor.removeCallbacks(mInvalidatePanelMenuRunnable); 9919b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes mInvalidatePanelMenuRunnable.run(); 9929b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 99300d183885b54de433e43118d3032340f40cac8c0Chris Banes 9949b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); 99500d183885b54de433e43118d3032340f40cac8c0Chris Banes 9969b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes // If we don't have a menu or we're waiting for a full content refresh, 9979b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes // forget it. This is a lingering event that no longer matters. 9989b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (st.menu != null && !st.refreshMenuContent && 99946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) { 1000d25af35061a9f20d59b25329d613c62c20184dadChris Banes cb.onMenuOpened(FEATURE_SUPPORT_ACTION_BAR, st.menu); 10019b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes mDecorContentParent.showOverflowMenu(); 10029b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 100300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 100400d183885b54de433e43118d3032340f40cac8c0Chris Banes } else { 100500d183885b54de433e43118d3032340f40cac8c0Chris Banes mDecorContentParent.hideOverflowMenu(); 10069b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (!isDestroyed()) { 10079b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); 1008d25af35061a9f20d59b25329d613c62c20184dadChris Banes cb.onPanelClosed(FEATURE_SUPPORT_ACTION_BAR, st.menu); 10099b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 101000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 101100d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 101200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 101300d183885b54de433e43118d3032340f40cac8c0Chris Banes 101400d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); 101500d183885b54de433e43118d3032340f40cac8c0Chris Banes 101600d183885b54de433e43118d3032340f40cac8c0Chris Banes st.refreshDecorView = true; 101700d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(st, false); 101800d183885b54de433e43118d3032340f40cac8c0Chris Banes 101900d183885b54de433e43118d3032340f40cac8c0Chris Banes openPanel(st, null); 102000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 102100d183885b54de433e43118d3032340f40cac8c0Chris Banes 102200d183885b54de433e43118d3032340f40cac8c0Chris Banes private boolean initializePanelMenu(final PanelFeatureState st) { 102316e8d4dd91083260223c007c797e46bc8f631055Chris Banes Context context = mContext; 102461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 102500d183885b54de433e43118d3032340f40cac8c0Chris Banes // If we have an action bar, initialize the menu with the right theme. 1026d25af35061a9f20d59b25329d613c62c20184dadChris Banes if ((st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_SUPPORT_ACTION_BAR) && 102700d183885b54de433e43118d3032340f40cac8c0Chris Banes mDecorContentParent != null) { 102861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes final TypedValue outValue = new TypedValue(); 102961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes final Resources.Theme baseTheme = context.getTheme(); 103061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes baseTheme.resolveAttribute(R.attr.actionBarTheme, outValue, true); 103161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 103261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes Resources.Theme widgetTheme = null; 103361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes if (outValue.resourceId != 0) { 103461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme = context.getResources().newTheme(); 103561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme.setTo(baseTheme); 103661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme.applyStyle(outValue.resourceId, true); 103761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme.resolveAttribute( 103861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes R.attr.actionBarWidgetTheme, outValue, true); 103961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } else { 104061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes baseTheme.resolveAttribute( 104161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes R.attr.actionBarWidgetTheme, outValue, true); 104261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } 104361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 104461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes if (outValue.resourceId != 0) { 104561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes if (widgetTheme == null) { 104661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme = context.getResources().newTheme(); 104761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme.setTo(baseTheme); 104861c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } 104961c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes widgetTheme.applyStyle(outValue.resourceId, true); 105061c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } 105161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 105261c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes if (widgetTheme != null) { 105361c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes context = new ContextThemeWrapper(context, 0); 105461c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes context.getTheme().setTo(widgetTheme); 105561c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } 105661c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes } 105761c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 105800d183885b54de433e43118d3032340f40cac8c0Chris Banes final MenuBuilder menu = new MenuBuilder(context); 105900d183885b54de433e43118d3032340f40cac8c0Chris Banes menu.setCallback(this); 106000d183885b54de433e43118d3032340f40cac8c0Chris Banes st.setMenu(menu); 106161c0bbe56a13fe55ce91a5b1d64e751164ecb894Chris Banes 10628902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes return true; 10638902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 10648902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 106500d183885b54de433e43118d3032340f40cac8c0Chris Banes private boolean initializePanelContent(PanelFeatureState st) { 106646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.createdPanelView != null) { 106746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.shownPanelView = st.createdPanelView; 106846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return true; 106946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 107046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 107100d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st.menu == null) { 107200d183885b54de433e43118d3032340f40cac8c0Chris Banes return false; 107300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 107400d183885b54de433e43118d3032340f40cac8c0Chris Banes 107500d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mPanelMenuPresenterCallback == null) { 107600d183885b54de433e43118d3032340f40cac8c0Chris Banes mPanelMenuPresenterCallback = new PanelMenuPresenterCallback(); 107700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 107800d183885b54de433e43118d3032340f40cac8c0Chris Banes 107957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes MenuView menuView = st.getListMenuView(mPanelMenuPresenterCallback); 108000d183885b54de433e43118d3032340f40cac8c0Chris Banes 108100d183885b54de433e43118d3032340f40cac8c0Chris Banes st.shownPanelView = (View) menuView; 108200d183885b54de433e43118d3032340f40cac8c0Chris Banes 108300d183885b54de433e43118d3032340f40cac8c0Chris Banes return st.shownPanelView != null; 108400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 108500d183885b54de433e43118d3032340f40cac8c0Chris Banes 108600d183885b54de433e43118d3032340f40cac8c0Chris Banes private boolean preparePanel(PanelFeatureState st, KeyEvent event) { 10879b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (isDestroyed()) { 10889b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes return false; 10899b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes } 10909b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes 10918902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes // Already prepared (isPrepared will be reset to false later) 109200d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st.isPrepared) { 10938902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes return true; 10948902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 10958902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 109600d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((mPreparedPanel != null) && (mPreparedPanel != st)) { 109700d183885b54de433e43118d3032340f40cac8c0Chris Banes // Another Panel is prepared and possibly open, so close it 109800d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(mPreparedPanel, false); 109900d183885b54de433e43118d3032340f40cac8c0Chris Banes } 110000d183885b54de433e43118d3032340f40cac8c0Chris Banes 1101f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final Window.Callback cb = getWindowCallback(); 110246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 110346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (cb != null) { 110446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.createdPanelView = cb.onCreatePanelView(st.featureId); 110546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 110646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 110700d183885b54de433e43118d3032340f40cac8c0Chris Banes final boolean isActionBarMenu = 1108d25af35061a9f20d59b25329d613c62c20184dadChris Banes (st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_SUPPORT_ACTION_BAR); 110900d183885b54de433e43118d3032340f40cac8c0Chris Banes 111000d183885b54de433e43118d3032340f40cac8c0Chris Banes if (isActionBarMenu && mDecorContentParent != null) { 11118088261dec5dd277ccace13fe00f280ffa80098cChris Banes // Enforce ordering guarantees around events so that the action bar never 11128088261dec5dd277ccace13fe00f280ffa80098cChris Banes // dispatches menu-related events before the panel is prepared. 11138088261dec5dd277ccace13fe00f280ffa80098cChris Banes mDecorContentParent.setMenuPrepared(); 11148088261dec5dd277ccace13fe00f280ffa80098cChris Banes } 11158088261dec5dd277ccace13fe00f280ffa80098cChris Banes 111646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.createdPanelView == null) { 111746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Init the panel state's menu--return false if init failed 111846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.menu == null || st.refreshMenuContent) { 111946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.menu == null) { 112046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!initializePanelMenu(st) || (st.menu == null)) { 112146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return false; 112246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 11238902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 11248902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 112546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (isActionBarMenu && mDecorContentParent != null) { 112646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (mActionMenuPresenterCallback == null) { 112746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes mActionMenuPresenterCallback = new ActionMenuPresenterCallback(); 112846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 112946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes mDecorContentParent.setMenu(st.menu, mActionMenuPresenterCallback); 113046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 113146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 113246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Creating the panel menu will involve a lot of manipulation; 113346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // don't dispatch change events to presenters until we're done. 113446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.menu.stopDispatchingItemsChanged(); 1135f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (!cb.onCreatePanelMenu(st.featureId, st.menu)) { 113646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Ditch the menu created above 113746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.setMenu(null); 113846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 113946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (isActionBarMenu && mDecorContentParent != null) { 114046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Don't show it in the action bar either 114146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes mDecorContentParent.setMenu(null, mActionMenuPresenterCallback); 114246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 114346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 114446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return false; 114503fc11b659da1645507062bddda450136e13af35Chris Banes } 114646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 114746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.refreshMenuContent = false; 11488902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 11498902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 115046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Preparing the panel menu can involve a lot of manipulation; 11518902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes // don't dispatch change events to presenters until we're done. 115200d183885b54de433e43118d3032340f40cac8c0Chris Banes st.menu.stopDispatchingItemsChanged(); 11538902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 115446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Restore action view state before we prepare. This gives apps 115546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // an opportunity to override frozen/restored state in onPrepare. 115646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.frozenActionViewState != null) { 115746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.menu.restoreActionViewStates(st.frozenActionViewState); 115846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.frozenActionViewState = null; 115946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 116046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 116146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Callback and return if the callback does not want to show the menu 116246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) { 116300d183885b54de433e43118d3032340f40cac8c0Chris Banes if (isActionBarMenu && mDecorContentParent != null) { 116446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // The app didn't want to show the menu for now but it still exists. 116546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Clear it out of the action bar. 116603fc11b659da1645507062bddda450136e13af35Chris Banes mDecorContentParent.setMenu(null, mActionMenuPresenterCallback); 11678902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 116846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.menu.startDispatchingItemsChanged(); 11698902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes return false; 11708902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 11718902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 117246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Set the proper keymap 117346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes KeyCharacterMap kmap = KeyCharacterMap.load( 117446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes event != null ? event.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD); 117546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.qwertyMode = kmap.getKeyboardType() != KeyCharacterMap.NUMERIC; 117646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.menu.setQwertyMode(st.qwertyMode); 117700d183885b54de433e43118d3032340f40cac8c0Chris Banes st.menu.startDispatchingItemsChanged(); 11788902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 11798902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 11808902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes // Set other state 118100d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isPrepared = true; 118200d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isHandled = false; 118300d183885b54de433e43118d3032340f40cac8c0Chris Banes mPreparedPanel = st; 11848902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 11858902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes return true; 11868902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes } 11878902df1bf0006a156503d40b1fc8a01f95d5b806Chris Banes 118800d183885b54de433e43118d3032340f40cac8c0Chris Banes private void checkCloseActionMenu(MenuBuilder menu) { 118903fc11b659da1645507062bddda450136e13af35Chris Banes if (mClosingActionMenu) { 119003fc11b659da1645507062bddda450136e13af35Chris Banes return; 119103fc11b659da1645507062bddda450136e13af35Chris Banes } 119203fc11b659da1645507062bddda450136e13af35Chris Banes 119303fc11b659da1645507062bddda450136e13af35Chris Banes mClosingActionMenu = true; 119403fc11b659da1645507062bddda450136e13af35Chris Banes mDecorContentParent.dismissPopups(); 1195f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Window.Callback cb = getWindowCallback(); 11969b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (cb != null && !isDestroyed()) { 1197d25af35061a9f20d59b25329d613c62c20184dadChris Banes cb.onPanelClosed(FEATURE_SUPPORT_ACTION_BAR, menu); 119800d183885b54de433e43118d3032340f40cac8c0Chris Banes } 119903fc11b659da1645507062bddda450136e13af35Chris Banes mClosingActionMenu = false; 120003fc11b659da1645507062bddda450136e13af35Chris Banes } 120103fc11b659da1645507062bddda450136e13af35Chris Banes 120246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes private void closePanel(int featureId) { 120346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes closePanel(getPanelState(featureId, true), true); 120446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 120546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 120600d183885b54de433e43118d3032340f40cac8c0Chris Banes private void closePanel(PanelFeatureState st, boolean doCallback) { 120700d183885b54de433e43118d3032340f40cac8c0Chris Banes if (doCallback && st.featureId == FEATURE_OPTIONS_PANEL && 120800d183885b54de433e43118d3032340f40cac8c0Chris Banes mDecorContentParent != null && mDecorContentParent.isOverflowMenuShowing()) { 120900d183885b54de433e43118d3032340f40cac8c0Chris Banes checkCloseActionMenu(st.menu); 121000d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 121100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 121200d183885b54de433e43118d3032340f40cac8c0Chris Banes 1213436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes final boolean wasOpen = st.isOpen; 121446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 1215436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes final WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 1216436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes if (wm != null && wasOpen && st.decorView != null) { 1217436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes wm.removeView(st.decorView); 121800d183885b54de433e43118d3032340f40cac8c0Chris Banes } 121900d183885b54de433e43118d3032340f40cac8c0Chris Banes 122000d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isPrepared = false; 122100d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isHandled = false; 122200d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isOpen = false; 122300d183885b54de433e43118d3032340f40cac8c0Chris Banes 1224436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes if (wasOpen && doCallback) { 1225436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes // If the panel was open and we should callback, do so. This should be done after 1226436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes // isOpen is updated to ensure that we do not get into an infinite recursion 1227436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes callOnPanelClosed(st.featureId, st, null); 1228436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes } 1229436e191f80e197712dd1a7f1f7c61acfff8b1f04Chris Banes 123000d183885b54de433e43118d3032340f40cac8c0Chris Banes // This view is no longer shown, so null it out 123100d183885b54de433e43118d3032340f40cac8c0Chris Banes st.shownPanelView = null; 123200d183885b54de433e43118d3032340f40cac8c0Chris Banes 123300d183885b54de433e43118d3032340f40cac8c0Chris Banes // Next time the menu opens, it should not be in expanded mode, so 123400d183885b54de433e43118d3032340f40cac8c0Chris Banes // force a refresh of the decor 123500d183885b54de433e43118d3032340f40cac8c0Chris Banes st.refreshDecorView = true; 123600d183885b54de433e43118d3032340f40cac8c0Chris Banes 123700d183885b54de433e43118d3032340f40cac8c0Chris Banes if (mPreparedPanel == st) { 123800d183885b54de433e43118d3032340f40cac8c0Chris Banes mPreparedPanel = null; 123903fc11b659da1645507062bddda450136e13af35Chris Banes } 124003fc11b659da1645507062bddda450136e13af35Chris Banes } 124103fc11b659da1645507062bddda450136e13af35Chris Banes 124246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes private boolean onKeyDownPanel(int featureId, KeyEvent event) { 124346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (event.getRepeatCount() == 0) { 124446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes PanelFeatureState st = getPanelState(featureId, true); 124546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!st.isOpen) { 124646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return preparePanel(st, event); 124746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 124846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 124946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 125046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return false; 125146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 125246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 1253559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes private boolean onKeyUpPanel(int featureId, KeyEvent event) { 125446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (mActionMode != null) { 1255559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes return false; 125646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 125746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 1258559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes boolean handled = false; 125946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes final PanelFeatureState st = getPanelState(featureId, true); 126046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (featureId == FEATURE_OPTIONS_PANEL && mDecorContentParent != null && 126146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes mDecorContentParent.canShowOverflowMenu() && 126216e8d4dd91083260223c007c797e46bc8f631055Chris Banes !ViewConfigurationCompat.hasPermanentMenuKey(ViewConfiguration.get(mContext))) { 126346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!mDecorContentParent.isOverflowMenuShowing()) { 126446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (!isDestroyed() && preparePanel(st, event)) { 1265559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes handled = mDecorContentParent.showOverflowMenu(); 126646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 126746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else { 1268559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes handled = mDecorContentParent.hideOverflowMenu(); 126946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 127046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else { 127146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.isOpen || st.isHandled) { 127246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Play the sound effect if the user closed an open menu (and not if 127346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // they just released a menu shortcut) 1274559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes handled = st.isOpen; 127546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Close menu 127646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes closePanel(st, true); 127746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else if (st.isPrepared) { 127846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes boolean show = true; 127946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (st.refreshMenuContent) { 128046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Something may have invalidated the menu since we prepared it. 128146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Re-prepare it to refresh. 128246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes st.isPrepared = false; 128346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes show = preparePanel(st, event); 128446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 128546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 128646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (show) { 128746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes // Show menu 128846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes openPanel(st, event); 1289559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes handled = true; 129046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 129146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 129246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 129346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 1294559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes if (handled) { 129516e8d4dd91083260223c007c797e46bc8f631055Chris Banes AudioManager audioManager = (AudioManager) mContext.getSystemService( 129646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes Context.AUDIO_SERVICE); 129746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (audioManager != null) { 129846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK); 129946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } else { 130046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes Log.w(TAG, "Couldn't get audio manager"); 130146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 130246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 1303559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes return handled; 130446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 130546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 130600d183885b54de433e43118d3032340f40cac8c0Chris Banes private void callOnPanelClosed(int featureId, PanelFeatureState panel, Menu menu) { 130700d183885b54de433e43118d3032340f40cac8c0Chris Banes // Try to get a menu 130800d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu == null) { 130900d183885b54de433e43118d3032340f40cac8c0Chris Banes // Need a panel to grab the menu, so try to get that 131000d183885b54de433e43118d3032340f40cac8c0Chris Banes if (panel == null) { 131100d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((featureId >= 0) && (featureId < mPanels.length)) { 131200d183885b54de433e43118d3032340f40cac8c0Chris Banes panel = mPanels[featureId]; 131300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 131400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 131500d183885b54de433e43118d3032340f40cac8c0Chris Banes 131600d183885b54de433e43118d3032340f40cac8c0Chris Banes if (panel != null) { 131700d183885b54de433e43118d3032340f40cac8c0Chris Banes // menu still may be null, which is okay--we tried our best 131800d183885b54de433e43118d3032340f40cac8c0Chris Banes menu = panel.menu; 131900d183885b54de433e43118d3032340f40cac8c0Chris Banes } 132000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 132100d183885b54de433e43118d3032340f40cac8c0Chris Banes 132200d183885b54de433e43118d3032340f40cac8c0Chris Banes // If the panel is not open, do not callback 132300d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((panel != null) && (!panel.isOpen)) 132400d183885b54de433e43118d3032340f40cac8c0Chris Banes return; 132500d183885b54de433e43118d3032340f40cac8c0Chris Banes 1326f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Window.Callback cb = getWindowCallback(); 1327f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (cb != null) { 1328f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes cb.onPanelClosed(featureId, menu); 1329f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 133000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 133100d183885b54de433e43118d3032340f40cac8c0Chris Banes 133200d183885b54de433e43118d3032340f40cac8c0Chris Banes private PanelFeatureState findMenuPanel(Menu menu) { 133300d183885b54de433e43118d3032340f40cac8c0Chris Banes final PanelFeatureState[] panels = mPanels; 133400d183885b54de433e43118d3032340f40cac8c0Chris Banes final int N = panels != null ? panels.length : 0; 133500d183885b54de433e43118d3032340f40cac8c0Chris Banes for (int i = 0; i < N; i++) { 133600d183885b54de433e43118d3032340f40cac8c0Chris Banes final PanelFeatureState panel = panels[i]; 133700d183885b54de433e43118d3032340f40cac8c0Chris Banes if (panel != null && panel.menu == menu) { 133800d183885b54de433e43118d3032340f40cac8c0Chris Banes return panel; 133900d183885b54de433e43118d3032340f40cac8c0Chris Banes } 134000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 134100d183885b54de433e43118d3032340f40cac8c0Chris Banes return null; 134200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 134300d183885b54de433e43118d3032340f40cac8c0Chris Banes 134400d183885b54de433e43118d3032340f40cac8c0Chris Banes private PanelFeatureState getPanelState(int featureId, boolean required) { 134500d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState[] ar; 134600d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((ar = mPanels) == null || ar.length <= featureId) { 134700d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState[] nar = new PanelFeatureState[featureId + 1]; 134800d183885b54de433e43118d3032340f40cac8c0Chris Banes if (ar != null) { 134900d183885b54de433e43118d3032340f40cac8c0Chris Banes System.arraycopy(ar, 0, nar, 0, ar.length); 135000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 135100d183885b54de433e43118d3032340f40cac8c0Chris Banes mPanels = ar = nar; 135203fc11b659da1645507062bddda450136e13af35Chris Banes } 135300d183885b54de433e43118d3032340f40cac8c0Chris Banes 135400d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState st = ar[featureId]; 135500d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st == null) { 135600d183885b54de433e43118d3032340f40cac8c0Chris Banes ar[featureId] = st = new PanelFeatureState(featureId); 135700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 135800d183885b54de433e43118d3032340f40cac8c0Chris Banes return st; 135903fc11b659da1645507062bddda450136e13af35Chris Banes } 136003fc11b659da1645507062bddda450136e13af35Chris Banes 1361f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes private boolean performPanelShortcut(PanelFeatureState st, int keyCode, KeyEvent event, 136200d183885b54de433e43118d3032340f40cac8c0Chris Banes int flags) { 1363dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes if (event.isSystem()) { 1364dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes return false; 1365dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 1366dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 1367dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes boolean handled = false; 1368dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 1369dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // Only try to perform menu shortcuts if preparePanel returned true (possible false 1370dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // return value from application not wanting to show the menu). 137100d183885b54de433e43118d3032340f40cac8c0Chris Banes if ((st.isPrepared || preparePanel(st, event)) && st.menu != null) { 1372dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // The menu is prepared now, perform the shortcut on it 137300d183885b54de433e43118d3032340f40cac8c0Chris Banes handled = st.menu.performShortcut(keyCode, event, flags); 1374dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 1375dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 1376dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes if (handled) { 1377dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes // Only close down the menu if we don't have an action bar keeping it open. 1378dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes if ((flags & Menu.FLAG_PERFORM_NO_CLOSE) == 0 && mDecorContentParent == null) { 137900d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(st, true); 1380dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 1381dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 1382dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 1383dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes return handled; 1384dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes } 1385dea1122145ed85590d298a3a9d88ba9f9e2f5f46Chris Banes 138600d183885b54de433e43118d3032340f40cac8c0Chris Banes private void invalidatePanelMenu(int featureId) { 138700d183885b54de433e43118d3032340f40cac8c0Chris Banes mInvalidatePanelMenuFeatures |= 1 << featureId; 138800d183885b54de433e43118d3032340f40cac8c0Chris Banes 138900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (!mInvalidatePanelMenuPosted && mWindowDecor != null) { 139000d183885b54de433e43118d3032340f40cac8c0Chris Banes ViewCompat.postOnAnimation(mWindowDecor, mInvalidatePanelMenuRunnable); 139100d183885b54de433e43118d3032340f40cac8c0Chris Banes mInvalidatePanelMenuPosted = true; 139200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 139300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 139400d183885b54de433e43118d3032340f40cac8c0Chris Banes 139500d183885b54de433e43118d3032340f40cac8c0Chris Banes private void doInvalidatePanelMenu(int featureId) { 139600d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState st = getPanelState(featureId, true); 139700d183885b54de433e43118d3032340f40cac8c0Chris Banes Bundle savedActionViewStates = null; 139800d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st.menu != null) { 139900d183885b54de433e43118d3032340f40cac8c0Chris Banes savedActionViewStates = new Bundle(); 140000d183885b54de433e43118d3032340f40cac8c0Chris Banes st.menu.saveActionViewStates(savedActionViewStates); 140100d183885b54de433e43118d3032340f40cac8c0Chris Banes if (savedActionViewStates.size() > 0) { 140200d183885b54de433e43118d3032340f40cac8c0Chris Banes st.frozenActionViewState = savedActionViewStates; 140300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 140400d183885b54de433e43118d3032340f40cac8c0Chris Banes // This will be started again when the panel is prepared. 140500d183885b54de433e43118d3032340f40cac8c0Chris Banes st.menu.stopDispatchingItemsChanged(); 140600d183885b54de433e43118d3032340f40cac8c0Chris Banes st.menu.clear(); 140700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 140800d183885b54de433e43118d3032340f40cac8c0Chris Banes st.refreshMenuContent = true; 140900d183885b54de433e43118d3032340f40cac8c0Chris Banes st.refreshDecorView = true; 141000d183885b54de433e43118d3032340f40cac8c0Chris Banes 141100d183885b54de433e43118d3032340f40cac8c0Chris Banes // Prepare the options panel if we have an action bar 1412d25af35061a9f20d59b25329d613c62c20184dadChris Banes if ((featureId == FEATURE_SUPPORT_ACTION_BAR || featureId == FEATURE_OPTIONS_PANEL) 141300d183885b54de433e43118d3032340f40cac8c0Chris Banes && mDecorContentParent != null) { 141400d183885b54de433e43118d3032340f40cac8c0Chris Banes st = getPanelState(Window.FEATURE_OPTIONS_PANEL, false); 141500d183885b54de433e43118d3032340f40cac8c0Chris Banes if (st != null) { 141600d183885b54de433e43118d3032340f40cac8c0Chris Banes st.isPrepared = false; 141700d183885b54de433e43118d3032340f40cac8c0Chris Banes preparePanel(st, null); 141800d183885b54de433e43118d3032340f40cac8c0Chris Banes } 141900d183885b54de433e43118d3032340f40cac8c0Chris Banes } 142000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 142100d183885b54de433e43118d3032340f40cac8c0Chris Banes 1422ea4f700ac38424954c56df5138ff794def50b019Chris Banes /** 1423ea4f700ac38424954c56df5138ff794def50b019Chris Banes * Updates the status bar guard 1424ea4f700ac38424954c56df5138ff794def50b019Chris Banes * 1425ea4f700ac38424954c56df5138ff794def50b019Chris Banes * @param insetTop the current top system window inset 1426ea4f700ac38424954c56df5138ff794def50b019Chris Banes * @return the new top system window inset 1427ea4f700ac38424954c56df5138ff794def50b019Chris Banes */ 1428ea4f700ac38424954c56df5138ff794def50b019Chris Banes private int updateStatusGuard(int insetTop) { 1429ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes boolean showStatusGuard = false; 1430ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes // Show the status guard when the non-overlay contextual action bar is showing 1431ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mActionModeView != null) { 1432ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mActionModeView.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { 1433ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) 1434ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mActionModeView.getLayoutParams(); 1435ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes boolean mlpChanged = false; 1436ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes 1437ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mActionModeView.isShown()) { 14387efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell if (mTempRect1 == null) { 14397efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell mTempRect1 = new Rect(); 14407efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell mTempRect2 = new Rect(); 14417efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell } 14427efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell final Rect insets = mTempRect1; 14437efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell final Rect localInsets = mTempRect2; 14447efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell insets.set(0, insetTop, 0, 0); 14457efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell 14467efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell ViewUtils.computeFitSystemWindows(mSubDecor, insets, localInsets); 14477efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell final int newMargin = localInsets.top == 0 ? insetTop : 0; 14487efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell if (mlp.topMargin != newMargin) { 14497efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell mlpChanged = true; 14507efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell mlp.topMargin = insetTop; 14517efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell 1452ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mStatusGuard == null) { 145316e8d4dd91083260223c007c797e46bc8f631055Chris Banes mStatusGuard = new View(mContext); 145416e8d4dd91083260223c007c797e46bc8f631055Chris Banes mStatusGuard.setBackgroundColor(mContext.getResources() 1455ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes .getColor(R.color.abc_input_method_navigation_guard)); 14567efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell mSubDecor.addView(mStatusGuard, -1, 1457ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1458ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes insetTop)); 1459ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } else { 1460ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes ViewGroup.LayoutParams lp = mStatusGuard.getLayoutParams(); 1461ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (lp.height != insetTop) { 1462ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes lp.height = insetTop; 1463ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mStatusGuard.setLayoutParams(lp); 1464ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1465ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1466ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1467ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes 1468bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell // The action mode's theme may differ from the app, so 1469bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell // always show the status guard above it. 1470bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell showStatusGuard = mStatusGuard != null; 1471bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell 14727efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell // We only need to consume the insets if the action 14737efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell // mode is overlaid on the app content (e.g. it's 14747efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell // sitting in a FrameLayout, see 14757efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell // screen_simple_overlay_action_mode.xml). 1476bbb50c78cc6ee24677c79bd4548fa38fcdc41d92Adam Powell if (!mOverlayActionMode && showStatusGuard) { 14777efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell insetTop = 0; 14787efc56b68ff933dfeeac81dd2d8a32096b90f0f4Adam Powell } 1479ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } else { 1480ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes // reset top margin 1481ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mlp.topMargin != 0) { 1482ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mlpChanged = true; 1483ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mlp.topMargin = 0; 1484ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1485ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1486ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mlpChanged) { 1487ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mActionModeView.setLayoutParams(mlp); 1488ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1489ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1490ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1491ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mStatusGuard != null) { 1492ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes mStatusGuard.setVisibility(showStatusGuard ? View.VISIBLE : View.GONE); 1493ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1494ea4f700ac38424954c56df5138ff794def50b019Chris Banes 1495ea4f700ac38424954c56df5138ff794def50b019Chris Banes return insetTop; 1496ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 1497ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes 1498cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes private void throwFeatureRequestIfSubDecorInstalled() { 1499cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes if (mSubDecorInstalled) { 1500cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes throw new AndroidRuntimeException( 1501f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes "Window feature must be requested before adding content"); 1502cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes } 1503cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes } 1504cc7aada3ee922cfb38eeb36ee696cc73dcbae0a4Chris Banes 150516e8d4dd91083260223c007c797e46bc8f631055Chris Banes ViewGroup getSubDecor() { 150616e8d4dd91083260223c007c797e46bc8f631055Chris Banes return mSubDecor; 150716e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 150816e8d4dd91083260223c007c797e46bc8f631055Chris Banes 1509ed34e2dffd0ce7da89063d06fd3b25687ca367a2Chris Banes /** 1510d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes * Clears out internal reference when the action mode is destroyed. 1511d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes */ 1512547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes class ActionModeCallbackWrapperV7 implements ActionMode.Callback { 1513d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes private ActionMode.Callback mWrapped; 1514d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 1515547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes public ActionModeCallbackWrapperV7(ActionMode.Callback wrapped) { 1516d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes mWrapped = wrapped; 1517d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1518d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 1519d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes public boolean onCreateActionMode(ActionMode mode, Menu menu) { 1520d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return mWrapped.onCreateActionMode(mode, menu); 1521d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1522d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 1523d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 15249addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes return mWrapped.onPrepareActionMode(mode, menu); 1525d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1526d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 1527d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 1528d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes return mWrapped.onActionItemClicked(mode, item); 1529d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1530d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 1531d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes public void onDestroyActionMode(ActionMode mode) { 1532d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes mWrapped.onDestroyActionMode(mode); 15334c2a95906254748cb9a843b061288265d6e185a9Chris Banes if (mActionModePopup != null) { 153416e8d4dd91083260223c007c797e46bc8f631055Chris Banes mWindow.getDecorView().removeCallbacks(mShowActionModePopup); 15354c2a95906254748cb9a843b061288265d6e185a9Chris Banes mActionModePopup.dismiss(); 15364c2a95906254748cb9a843b061288265d6e185a9Chris Banes } else if (mActionModeView != null) { 15374c2a95906254748cb9a843b061288265d6e185a9Chris Banes mActionModeView.setVisibility(View.GONE); 1538ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes if (mActionModeView.getParent() != null) { 1539ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes ViewCompat.requestApplyInsets((View) mActionModeView.getParent()); 1540ec3f49d21a507835c1f50ce5600000b587a2af08Chris Banes } 15414c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 15424c2a95906254748cb9a843b061288265d6e185a9Chris Banes if (mActionModeView != null) { 15434c2a95906254748cb9a843b061288265d6e185a9Chris Banes mActionModeView.removeAllViews(); 15444c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1545f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (mAppCompatCallback != null) { 1546f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes mAppCompatCallback.onSupportActionModeFinished(mActionMode); 15474c2a95906254748cb9a843b061288265d6e185a9Chris Banes } 1548d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes mActionMode = null; 1549d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1550d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes } 1551d8222dedaacae30fa03bee346ebf42ee75b39928Chris Banes 155203fc11b659da1645507062bddda450136e13af35Chris Banes private final class PanelMenuPresenterCallback implements MenuPresenter.Callback { 155303fc11b659da1645507062bddda450136e13af35Chris Banes @Override 155400d183885b54de433e43118d3032340f40cac8c0Chris Banes public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 155500d183885b54de433e43118d3032340f40cac8c0Chris Banes final Menu parentMenu = menu.getRootMenu(); 155600d183885b54de433e43118d3032340f40cac8c0Chris Banes final boolean isSubMenu = parentMenu != menu; 155700d183885b54de433e43118d3032340f40cac8c0Chris Banes final PanelFeatureState panel = findMenuPanel(isSubMenu ? parentMenu : menu); 155800d183885b54de433e43118d3032340f40cac8c0Chris Banes if (panel != null) { 155900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (isSubMenu) { 156000d183885b54de433e43118d3032340f40cac8c0Chris Banes callOnPanelClosed(panel.featureId, panel, parentMenu); 156100d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(panel, true); 156200d183885b54de433e43118d3032340f40cac8c0Chris Banes } else { 156300d183885b54de433e43118d3032340f40cac8c0Chris Banes // Close the panel and only do the callback if the menu is being 156400d183885b54de433e43118d3032340f40cac8c0Chris Banes // closed completely, not if opening a sub menu 156500d183885b54de433e43118d3032340f40cac8c0Chris Banes closePanel(panel, allMenusAreClosing); 156600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 156700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 156803fc11b659da1645507062bddda450136e13af35Chris Banes } 156903fc11b659da1645507062bddda450136e13af35Chris Banes 157003fc11b659da1645507062bddda450136e13af35Chris Banes @Override 157100d183885b54de433e43118d3032340f40cac8c0Chris Banes public boolean onOpenSubMenu(MenuBuilder subMenu) { 157200d183885b54de433e43118d3032340f40cac8c0Chris Banes if (subMenu == null && mHasActionBar) { 1573f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Window.Callback cb = getWindowCallback(); 15749b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes if (cb != null && !isDestroyed()) { 1575d25af35061a9f20d59b25329d613c62c20184dadChris Banes cb.onMenuOpened(FEATURE_SUPPORT_ACTION_BAR, subMenu); 157600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 157700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 157800d183885b54de433e43118d3032340f40cac8c0Chris Banes return true; 157903fc11b659da1645507062bddda450136e13af35Chris Banes } 158003fc11b659da1645507062bddda450136e13af35Chris Banes } 158103fc11b659da1645507062bddda450136e13af35Chris Banes 158203fc11b659da1645507062bddda450136e13af35Chris Banes private final class ActionMenuPresenterCallback implements MenuPresenter.Callback { 158303fc11b659da1645507062bddda450136e13af35Chris Banes @Override 158403fc11b659da1645507062bddda450136e13af35Chris Banes public boolean onOpenSubMenu(MenuBuilder subMenu) { 1585f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Window.Callback cb = getWindowCallback(); 158600d183885b54de433e43118d3032340f40cac8c0Chris Banes if (cb != null) { 1587d25af35061a9f20d59b25329d613c62c20184dadChris Banes cb.onMenuOpened(FEATURE_SUPPORT_ACTION_BAR, subMenu); 158800d183885b54de433e43118d3032340f40cac8c0Chris Banes } 158900d183885b54de433e43118d3032340f40cac8c0Chris Banes return true; 159003fc11b659da1645507062bddda450136e13af35Chris Banes } 159103fc11b659da1645507062bddda450136e13af35Chris Banes 159203fc11b659da1645507062bddda450136e13af35Chris Banes @Override 159303fc11b659da1645507062bddda450136e13af35Chris Banes public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 159400d183885b54de433e43118d3032340f40cac8c0Chris Banes checkCloseActionMenu(menu); 159500d183885b54de433e43118d3032340f40cac8c0Chris Banes } 159600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 159700d183885b54de433e43118d3032340f40cac8c0Chris Banes 159800d183885b54de433e43118d3032340f40cac8c0Chris Banes private static final class PanelFeatureState { 15999b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes 160000d183885b54de433e43118d3032340f40cac8c0Chris Banes /** Feature ID for this panel. */ 160100d183885b54de433e43118d3032340f40cac8c0Chris Banes int featureId; 160200d183885b54de433e43118d3032340f40cac8c0Chris Banes 160346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int background; 160446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 160546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int gravity; 160646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 160746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int x; 160846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 160946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int y; 161046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 161146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int windowAnimations; 161246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 161300d183885b54de433e43118d3032340f40cac8c0Chris Banes /** Dynamic state of the panel. */ 161400d183885b54de433e43118d3032340f40cac8c0Chris Banes ViewGroup decorView; 161500d183885b54de433e43118d3032340f40cac8c0Chris Banes 161600d183885b54de433e43118d3032340f40cac8c0Chris Banes /** The panel that we are actually showing. */ 161700d183885b54de433e43118d3032340f40cac8c0Chris Banes View shownPanelView; 161800d183885b54de433e43118d3032340f40cac8c0Chris Banes 161946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes /** The panel that was returned by onCreatePanelView(). */ 162046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes View createdPanelView; 162146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 162200d183885b54de433e43118d3032340f40cac8c0Chris Banes /** Use {@link #setMenu} to set this. */ 162300d183885b54de433e43118d3032340f40cac8c0Chris Banes MenuBuilder menu; 162400d183885b54de433e43118d3032340f40cac8c0Chris Banes 162500d183885b54de433e43118d3032340f40cac8c0Chris Banes ListMenuPresenter listMenuPresenter; 162600d183885b54de433e43118d3032340f40cac8c0Chris Banes 162757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes Context listPresenterContext; 162800d183885b54de433e43118d3032340f40cac8c0Chris Banes 162900d183885b54de433e43118d3032340f40cac8c0Chris Banes /** 163000d183885b54de433e43118d3032340f40cac8c0Chris Banes * Whether the panel has been prepared (see 16319b1b5bfac6abfda6c7543fc1b57050649b04f41bChris Banes * {@link #preparePanel}). 163200d183885b54de433e43118d3032340f40cac8c0Chris Banes */ 163300d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isPrepared; 163400d183885b54de433e43118d3032340f40cac8c0Chris Banes 163500d183885b54de433e43118d3032340f40cac8c0Chris Banes /** 163600d183885b54de433e43118d3032340f40cac8c0Chris Banes * Whether an item's action has been performed. This happens in obvious 163700d183885b54de433e43118d3032340f40cac8c0Chris Banes * scenarios (user clicks on menu item), but can also happen with 163800d183885b54de433e43118d3032340f40cac8c0Chris Banes * chording menu+(shortcut key). 163900d183885b54de433e43118d3032340f40cac8c0Chris Banes */ 164000d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isHandled; 164100d183885b54de433e43118d3032340f40cac8c0Chris Banes 164200d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isOpen; 164300d183885b54de433e43118d3032340f40cac8c0Chris Banes 164400d183885b54de433e43118d3032340f40cac8c0Chris Banes public boolean qwertyMode; 164500d183885b54de433e43118d3032340f40cac8c0Chris Banes 164600d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean refreshDecorView; 164700d183885b54de433e43118d3032340f40cac8c0Chris Banes 164800d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean refreshMenuContent; 164900d183885b54de433e43118d3032340f40cac8c0Chris Banes 165000d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean wasLastOpen; 165100d183885b54de433e43118d3032340f40cac8c0Chris Banes 165200d183885b54de433e43118d3032340f40cac8c0Chris Banes /** 165300d183885b54de433e43118d3032340f40cac8c0Chris Banes * Contains the state of the menu when told to freeze. 165400d183885b54de433e43118d3032340f40cac8c0Chris Banes */ 165500d183885b54de433e43118d3032340f40cac8c0Chris Banes Bundle frozenMenuState; 165600d183885b54de433e43118d3032340f40cac8c0Chris Banes 165700d183885b54de433e43118d3032340f40cac8c0Chris Banes /** 165800d183885b54de433e43118d3032340f40cac8c0Chris Banes * Contains the state of associated action views when told to freeze. 165900d183885b54de433e43118d3032340f40cac8c0Chris Banes * These are saved across invalidations. 166000d183885b54de433e43118d3032340f40cac8c0Chris Banes */ 166100d183885b54de433e43118d3032340f40cac8c0Chris Banes Bundle frozenActionViewState; 166200d183885b54de433e43118d3032340f40cac8c0Chris Banes 166300d183885b54de433e43118d3032340f40cac8c0Chris Banes PanelFeatureState(int featureId) { 166400d183885b54de433e43118d3032340f40cac8c0Chris Banes this.featureId = featureId; 166500d183885b54de433e43118d3032340f40cac8c0Chris Banes 166600d183885b54de433e43118d3032340f40cac8c0Chris Banes refreshDecorView = false; 166700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 166800d183885b54de433e43118d3032340f40cac8c0Chris Banes 166900d183885b54de433e43118d3032340f40cac8c0Chris Banes public boolean hasPanelItems() { 167000d183885b54de433e43118d3032340f40cac8c0Chris Banes if (shownPanelView == null) return false; 167146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (createdPanelView != null) return true; 167200d183885b54de433e43118d3032340f40cac8c0Chris Banes 167300d183885b54de433e43118d3032340f40cac8c0Chris Banes return listMenuPresenter.getAdapter().getCount() > 0; 167400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 167500d183885b54de433e43118d3032340f40cac8c0Chris Banes 167600d183885b54de433e43118d3032340f40cac8c0Chris Banes /** 167700d183885b54de433e43118d3032340f40cac8c0Chris Banes * Unregister and free attached MenuPresenters. They will be recreated as needed. 167800d183885b54de433e43118d3032340f40cac8c0Chris Banes */ 167900d183885b54de433e43118d3032340f40cac8c0Chris Banes public void clearMenuPresenters() { 168000d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu != null) { 168100d183885b54de433e43118d3032340f40cac8c0Chris Banes menu.removeMenuPresenter(listMenuPresenter); 168200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 168300d183885b54de433e43118d3032340f40cac8c0Chris Banes listMenuPresenter = null; 168400d183885b54de433e43118d3032340f40cac8c0Chris Banes } 168500d183885b54de433e43118d3032340f40cac8c0Chris Banes 168600d183885b54de433e43118d3032340f40cac8c0Chris Banes void setStyle(Context context) { 168757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes final TypedValue outValue = new TypedValue(); 168857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes final Resources.Theme widgetTheme = context.getResources().newTheme(); 168957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.setTo(context.getTheme()); 169057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes 169157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes // First apply the actionBarPopupTheme 169257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.resolveAttribute(R.attr.actionBarPopupTheme, outValue, true); 169357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes if (outValue.resourceId != 0) { 169457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.applyStyle(outValue.resourceId, true); 169557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes } 169657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes 169757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes // Now apply the panelMenuListTheme 169857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.resolveAttribute(R.attr.panelMenuListTheme, outValue, true); 169957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes if (outValue.resourceId != 0) { 170057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.applyStyle(outValue.resourceId, true); 170157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes } else { 170257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes widgetTheme.applyStyle(R.style.Theme_AppCompat_CompactMenu, true); 170357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes } 170457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes 170557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes context = new ContextThemeWrapper(context, 0); 170657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes context.getTheme().setTo(widgetTheme); 170757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes 170857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes listPresenterContext = context; 170946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 171046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes TypedArray a = context.obtainStyledAttributes(R.styleable.Theme); 171146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes background = a.getResourceId( 171246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes R.styleable.Theme_panelBackground, 0); 171346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes windowAnimations = a.getResourceId( 171446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes R.styleable.Theme_android_windowAnimationStyle, 0); 171546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes a.recycle(); 171600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 171700d183885b54de433e43118d3032340f40cac8c0Chris Banes 171800d183885b54de433e43118d3032340f40cac8c0Chris Banes void setMenu(MenuBuilder menu) { 171900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu == this.menu) return; 172000d183885b54de433e43118d3032340f40cac8c0Chris Banes 172100d183885b54de433e43118d3032340f40cac8c0Chris Banes if (this.menu != null) { 172200d183885b54de433e43118d3032340f40cac8c0Chris Banes this.menu.removeMenuPresenter(listMenuPresenter); 172300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 172400d183885b54de433e43118d3032340f40cac8c0Chris Banes this.menu = menu; 172500d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu != null) { 172600d183885b54de433e43118d3032340f40cac8c0Chris Banes if (listMenuPresenter != null) menu.addMenuPresenter(listMenuPresenter); 172700d183885b54de433e43118d3032340f40cac8c0Chris Banes } 172800d183885b54de433e43118d3032340f40cac8c0Chris Banes } 172900d183885b54de433e43118d3032340f40cac8c0Chris Banes 173057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes MenuView getListMenuView(MenuPresenter.Callback cb) { 173100d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu == null) return null; 173200d183885b54de433e43118d3032340f40cac8c0Chris Banes 173300d183885b54de433e43118d3032340f40cac8c0Chris Banes if (listMenuPresenter == null) { 173457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes listMenuPresenter = new ListMenuPresenter(listPresenterContext, 173557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes R.layout.abc_list_menu_item_layout); 173600d183885b54de433e43118d3032340f40cac8c0Chris Banes listMenuPresenter.setCallback(cb); 173700d183885b54de433e43118d3032340f40cac8c0Chris Banes menu.addMenuPresenter(listMenuPresenter); 173800d183885b54de433e43118d3032340f40cac8c0Chris Banes } 173900d183885b54de433e43118d3032340f40cac8c0Chris Banes 174000d183885b54de433e43118d3032340f40cac8c0Chris Banes MenuView result = listMenuPresenter.getMenuView(decorView); 174100d183885b54de433e43118d3032340f40cac8c0Chris Banes 174200d183885b54de433e43118d3032340f40cac8c0Chris Banes return result; 174300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 174400d183885b54de433e43118d3032340f40cac8c0Chris Banes 174500d183885b54de433e43118d3032340f40cac8c0Chris Banes Parcelable onSaveInstanceState() { 174600d183885b54de433e43118d3032340f40cac8c0Chris Banes SavedState savedState = new SavedState(); 174700d183885b54de433e43118d3032340f40cac8c0Chris Banes savedState.featureId = featureId; 174800d183885b54de433e43118d3032340f40cac8c0Chris Banes savedState.isOpen = isOpen; 174900d183885b54de433e43118d3032340f40cac8c0Chris Banes 175000d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu != null) { 175100d183885b54de433e43118d3032340f40cac8c0Chris Banes savedState.menuState = new Bundle(); 175200d183885b54de433e43118d3032340f40cac8c0Chris Banes menu.savePresenterStates(savedState.menuState); 175300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 175400d183885b54de433e43118d3032340f40cac8c0Chris Banes 175500d183885b54de433e43118d3032340f40cac8c0Chris Banes return savedState; 175600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 175700d183885b54de433e43118d3032340f40cac8c0Chris Banes 175800d183885b54de433e43118d3032340f40cac8c0Chris Banes void onRestoreInstanceState(Parcelable state) { 175900d183885b54de433e43118d3032340f40cac8c0Chris Banes SavedState savedState = (SavedState) state; 176000d183885b54de433e43118d3032340f40cac8c0Chris Banes featureId = savedState.featureId; 176100d183885b54de433e43118d3032340f40cac8c0Chris Banes wasLastOpen = savedState.isOpen; 176200d183885b54de433e43118d3032340f40cac8c0Chris Banes frozenMenuState = savedState.menuState; 176300d183885b54de433e43118d3032340f40cac8c0Chris Banes 176400d183885b54de433e43118d3032340f40cac8c0Chris Banes shownPanelView = null; 176500d183885b54de433e43118d3032340f40cac8c0Chris Banes decorView = null; 176600d183885b54de433e43118d3032340f40cac8c0Chris Banes } 176700d183885b54de433e43118d3032340f40cac8c0Chris Banes 176800d183885b54de433e43118d3032340f40cac8c0Chris Banes void applyFrozenState() { 176900d183885b54de433e43118d3032340f40cac8c0Chris Banes if (menu != null && frozenMenuState != null) { 177000d183885b54de433e43118d3032340f40cac8c0Chris Banes menu.restorePresenterStates(frozenMenuState); 177100d183885b54de433e43118d3032340f40cac8c0Chris Banes frozenMenuState = null; 177200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 177300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 177400d183885b54de433e43118d3032340f40cac8c0Chris Banes 177500d183885b54de433e43118d3032340f40cac8c0Chris Banes private static class SavedState implements Parcelable { 177600d183885b54de433e43118d3032340f40cac8c0Chris Banes int featureId; 177700d183885b54de433e43118d3032340f40cac8c0Chris Banes boolean isOpen; 177800d183885b54de433e43118d3032340f40cac8c0Chris Banes Bundle menuState; 177900d183885b54de433e43118d3032340f40cac8c0Chris Banes 178000d183885b54de433e43118d3032340f40cac8c0Chris Banes public int describeContents() { 178100d183885b54de433e43118d3032340f40cac8c0Chris Banes return 0; 178200d183885b54de433e43118d3032340f40cac8c0Chris Banes } 178300d183885b54de433e43118d3032340f40cac8c0Chris Banes 178400d183885b54de433e43118d3032340f40cac8c0Chris Banes public void writeToParcel(Parcel dest, int flags) { 178500d183885b54de433e43118d3032340f40cac8c0Chris Banes dest.writeInt(featureId); 178600d183885b54de433e43118d3032340f40cac8c0Chris Banes dest.writeInt(isOpen ? 1 : 0); 178700d183885b54de433e43118d3032340f40cac8c0Chris Banes 178800d183885b54de433e43118d3032340f40cac8c0Chris Banes if (isOpen) { 178900d183885b54de433e43118d3032340f40cac8c0Chris Banes dest.writeBundle(menuState); 179000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 179100d183885b54de433e43118d3032340f40cac8c0Chris Banes } 179200d183885b54de433e43118d3032340f40cac8c0Chris Banes 179300d183885b54de433e43118d3032340f40cac8c0Chris Banes private static SavedState readFromParcel(Parcel source) { 179400d183885b54de433e43118d3032340f40cac8c0Chris Banes SavedState savedState = new SavedState(); 179500d183885b54de433e43118d3032340f40cac8c0Chris Banes savedState.featureId = source.readInt(); 179600d183885b54de433e43118d3032340f40cac8c0Chris Banes savedState.isOpen = source.readInt() == 1; 179700d183885b54de433e43118d3032340f40cac8c0Chris Banes 179800d183885b54de433e43118d3032340f40cac8c0Chris Banes if (savedState.isOpen) { 179900d183885b54de433e43118d3032340f40cac8c0Chris Banes savedState.menuState = source.readBundle(); 180000d183885b54de433e43118d3032340f40cac8c0Chris Banes } 180100d183885b54de433e43118d3032340f40cac8c0Chris Banes 180200d183885b54de433e43118d3032340f40cac8c0Chris Banes return savedState; 180300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 180400d183885b54de433e43118d3032340f40cac8c0Chris Banes 180500d183885b54de433e43118d3032340f40cac8c0Chris Banes public static final Parcelable.Creator<SavedState> CREATOR 180600d183885b54de433e43118d3032340f40cac8c0Chris Banes = new Parcelable.Creator<SavedState>() { 180700d183885b54de433e43118d3032340f40cac8c0Chris Banes public SavedState createFromParcel(Parcel in) { 180800d183885b54de433e43118d3032340f40cac8c0Chris Banes return readFromParcel(in); 180900d183885b54de433e43118d3032340f40cac8c0Chris Banes } 181000d183885b54de433e43118d3032340f40cac8c0Chris Banes 181100d183885b54de433e43118d3032340f40cac8c0Chris Banes public SavedState[] newArray(int size) { 181200d183885b54de433e43118d3032340f40cac8c0Chris Banes return new SavedState[size]; 181300d183885b54de433e43118d3032340f40cac8c0Chris Banes } 181400d183885b54de433e43118d3032340f40cac8c0Chris Banes }; 181503fc11b659da1645507062bddda450136e13af35Chris Banes } 181603fc11b659da1645507062bddda450136e13af35Chris Banes } 181703fc11b659da1645507062bddda450136e13af35Chris Banes 181846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes private class ListMenuDecorView extends FrameLayout { 181946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes public ListMenuDecorView(Context context) { 182046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes super(context); 182146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 182246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 182346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes @Override 182446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes public boolean dispatchKeyEvent(KeyEvent event) { 1825f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return AppCompatDelegateImplV7.this.dispatchKeyEvent(event); 182646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 182746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 182846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes @Override 182946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes public boolean onInterceptTouchEvent(MotionEvent event) { 183046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int action = event.getAction(); 183146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (action == MotionEvent.ACTION_DOWN) { 183246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int x = (int) event.getX(); 183346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes int y = (int) event.getY(); 183446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes if (isOutOfBounds(x, y)) { 183546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes closePanel(Window.FEATURE_OPTIONS_PANEL); 183646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return true; 183746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 183846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 183946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return super.onInterceptTouchEvent(event); 184046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 184146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 184246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes @Override 184346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes public void setBackgroundResource(int resid) { 184446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes setBackgroundDrawable(TintManager.getDrawable(getContext(), resid)); 184546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 184646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 184746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes private boolean isOutOfBounds(int x, int y) { 184846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes return x < -5 || y < -5 || x > (getWidth() + 5) || y > (getHeight() + 5); 184946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 185046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes } 185146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes 18526386aac7ea9be44d23dcea28d9a02110c174e988Chris Banes} 1853