1f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes/* 2f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * Copyright (C) 2013 The Android Open Source Project 3f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * 4f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 5f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * you may not use this file except in compliance with the License. 6f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * You may obtain a copy of the License at 7f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * 8f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * http://www.apache.org/licenses/LICENSE-2.0 9f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * 10f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * Unless required by applicable law or agreed to in writing, software 11f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * distributed under the License is distributed on an "AS IS" BASIS, 12f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * See the License for the specific language governing permissions and 14f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes * limitations under the License. 15f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes */ 16f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 17f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banespackage android.support.v7.app; 18f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 19f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.app.Activity; 20f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.content.Context; 21f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.content.res.TypedArray; 22f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.graphics.drawable.Drawable; 23f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.os.Bundle; 24f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v7.appcompat.R; 25f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v7.internal.view.SupportMenuInflater; 26f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v7.internal.view.WindowCallbackWrapper; 27f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v7.internal.view.menu.MenuBuilder; 28f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v7.internal.widget.TintTypedArray; 29f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.support.v7.view.ActionMode; 30f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.view.KeyEvent; 31f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.view.Menu; 32f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.view.MenuInflater; 33f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.view.View; 34f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesimport android.view.Window; 35f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 36f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banesabstract class AppCompatDelegateImplBase extends AppCompatDelegate { 37f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 3816e8d4dd91083260223c007c797e46bc8f631055Chris Banes final Context mContext; 3916e8d4dd91083260223c007c797e46bc8f631055Chris Banes final Window mWindow; 4016e8d4dd91083260223c007c797e46bc8f631055Chris Banes final Window.Callback mOriginalWindowCallback; 418d4765883ff24f0f79bf64fea23d4687d50cec85Chris Banes final Window.Callback mAppCompatWindowCallback; 4216e8d4dd91083260223c007c797e46bc8f631055Chris Banes final AppCompatCallback mAppCompatCallback; 43f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 448122ad54f129c2214631fad86cabda82815cc0d8Chris Banes ActionBar mActionBar; 455ecdb2c5042da49d36d7cda3fa08f1d9151a1fbdChris Banes MenuInflater mMenuInflater; 46f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 47f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // true if this activity has an action bar. 48f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes boolean mHasActionBar; 49f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // true if this activity's action bar overlays other activity content. 50f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes boolean mOverlayActionBar; 51f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // true if this any action modes should overlay the activity content 52f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes boolean mOverlayActionMode; 53f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // true if this activity is floating (e.g. Dialog) 54f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes boolean mIsFloating; 550f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes // true if this activity has no title 560f58401dc72db8ea2a201e3c0220f6529f2a7b33Chris Banes boolean mWindowNoTitle; 57f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 5816e8d4dd91083260223c007c797e46bc8f631055Chris Banes private CharSequence mTitle; 5916e8d4dd91083260223c007c797e46bc8f631055Chris Banes 60f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes private boolean mIsDestroyed; 61f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 6216e8d4dd91083260223c007c797e46bc8f631055Chris Banes AppCompatDelegateImplBase(Context context, Window window, AppCompatCallback callback) { 6316e8d4dd91083260223c007c797e46bc8f631055Chris Banes mContext = context; 6416e8d4dd91083260223c007c797e46bc8f631055Chris Banes mWindow = window; 65f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes mAppCompatCallback = callback; 6616e8d4dd91083260223c007c797e46bc8f631055Chris Banes 6716e8d4dd91083260223c007c797e46bc8f631055Chris Banes mOriginalWindowCallback = mWindow.getCallback(); 68547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes if (mOriginalWindowCallback instanceof AppCompatWindowCallbackBase) { 6916e8d4dd91083260223c007c797e46bc8f631055Chris Banes throw new IllegalStateException( 7016e8d4dd91083260223c007c797e46bc8f631055Chris Banes "AppCompat has already installed itself into the Window"); 7116e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 728d4765883ff24f0f79bf64fea23d4687d50cec85Chris Banes mAppCompatWindowCallback = wrapWindowCallback(mOriginalWindowCallback); 7316e8d4dd91083260223c007c797e46bc8f631055Chris Banes // Now install the new callback 748d4765883ff24f0f79bf64fea23d4687d50cec85Chris Banes mWindow.setCallback(mAppCompatWindowCallback); 75f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 76f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 778122ad54f129c2214631fad86cabda82815cc0d8Chris Banes abstract void initWindowDecorActionBar(); 78f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 79547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes Window.Callback wrapWindowCallback(Window.Callback callback) { 80547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes return new AppCompatWindowCallbackBase(callback); 81547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 82547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 83f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 84f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public ActionBar getSupportActionBar() { 85f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // The Action Bar should be lazily created as hasActionBar 86f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // could change after onCreate 878122ad54f129c2214631fad86cabda82815cc0d8Chris Banes initWindowDecorActionBar(); 88f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return mActionBar; 89f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 90f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 91f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final ActionBar peekSupportActionBar() { 92f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return mActionBar; 93f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 94f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 95f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 96f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public MenuInflater getMenuInflater() { 975ecdb2c5042da49d36d7cda3fa08f1d9151a1fbdChris Banes // Make sure that action views can get an appropriate theme. 98f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (mMenuInflater == null) { 995ecdb2c5042da49d36d7cda3fa08f1d9151a1fbdChris Banes initWindowDecorActionBar(); 1005ecdb2c5042da49d36d7cda3fa08f1d9151a1fbdChris Banes mMenuInflater = new SupportMenuInflater( 1015ecdb2c5042da49d36d7cda3fa08f1d9151a1fbdChris Banes mActionBar != null ? mActionBar.getThemedContext() : mContext); 102f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 103f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return mMenuInflater; 104f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 105f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 106f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // Methods used to create and respond to options menu 107d25af35061a9f20d59b25329d613c62c20184dadChris Banes abstract void onPanelClosed(int featureId, Menu menu); 108f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 109f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes abstract boolean onMenuOpened(int featureId, Menu menu); 110f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 111f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes abstract boolean dispatchKeyEvent(KeyEvent event); 112f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 113f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes abstract boolean onKeyShortcut(int keyCode, KeyEvent event); 114f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 115f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 116f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public final ActionBarDrawerToggle.Delegate getDrawerToggleDelegate() { 117f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return new ActionBarDrawableToggleImpl(); 118f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 119f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 120f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final Context getActionBarThemedContext() { 121f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes Context context = null; 122f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 123f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // If we have an action bar, let it return a themed context 124f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes ActionBar ab = getSupportActionBar(); 125f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (ab != null) { 126f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes context = ab.getThemedContext(); 127f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 128f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 129f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (context == null) { 13016e8d4dd91083260223c007c797e46bc8f631055Chris Banes context = mContext; 131f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 132f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return context; 133f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 134f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 135f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes private class ActionBarDrawableToggleImpl implements ActionBarDrawerToggle.Delegate { 136f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 137f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public Drawable getThemeUpIndicator() { 138f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final TintTypedArray a = TintTypedArray.obtainStyledAttributes( 139f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes getActionBarThemedContext(), null, new int[]{ R.attr.homeAsUpIndicator }); 140f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final Drawable result = a.getDrawable(0); 141f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes a.recycle(); 142f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return result; 143f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 144f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 145f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 146f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public Context getActionBarThemedContext() { 147f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return AppCompatDelegateImplBase.this.getActionBarThemedContext(); 148f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 149f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 150f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 151f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public boolean isNavigationVisible() { 152f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final ActionBar ab = getSupportActionBar(); 153f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return ab != null && (ab.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0; 154f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 155f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 156f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 157f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void setActionBarUpIndicator(Drawable upDrawable, int contentDescRes) { 158f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes ActionBar ab = getSupportActionBar(); 159f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (ab != null) { 160f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes ab.setHomeAsUpIndicator(upDrawable); 161f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes ab.setHomeActionContentDescription(contentDescRes); 162f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 163f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 164f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 165f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 166f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void setActionBarDescription(int contentDescRes) { 167f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes ActionBar ab = getSupportActionBar(); 168f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (ab != null) { 169f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes ab.setHomeActionContentDescription(contentDescRes); 170f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 171f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 172f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 173f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 174f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes abstract ActionMode startSupportActionModeFromWindow(ActionMode.Callback callback); 175f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 176f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 177f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public final void onDestroy() { 178f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes mIsDestroyed = true; 179f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 180f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 181547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes @Override 182547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes public void setHandleNativeActionModesEnabled(boolean enabled) { 183547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes // no-op pre-v14 184547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 185547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 186547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes @Override 187547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes public boolean isHandleNativeActionModesEnabled() { 188547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes // Always false pre-v14 189547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes return false; 190547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes } 191547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes 192f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final boolean isDestroyed() { 193f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return mIsDestroyed; 194f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 195f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 196f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes final Window.Callback getWindowCallback() { 19716e8d4dd91083260223c007c797e46bc8f631055Chris Banes return mWindow.getCallback(); 198f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 199f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 20016e8d4dd91083260223c007c797e46bc8f631055Chris Banes @Override 20116e8d4dd91083260223c007c797e46bc8f631055Chris Banes public final void setTitle(CharSequence title) { 20216e8d4dd91083260223c007c797e46bc8f631055Chris Banes mTitle = title; 20316e8d4dd91083260223c007c797e46bc8f631055Chris Banes onTitleChanged(title); 20416e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 205f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 20616e8d4dd91083260223c007c797e46bc8f631055Chris Banes abstract void onTitleChanged(CharSequence title); 207f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 20816e8d4dd91083260223c007c797e46bc8f631055Chris Banes final CharSequence getTitle() { 20916e8d4dd91083260223c007c797e46bc8f631055Chris Banes // If the original window callback is an Activity, we'll use it's title 21016e8d4dd91083260223c007c797e46bc8f631055Chris Banes if (mOriginalWindowCallback instanceof Activity) { 21116e8d4dd91083260223c007c797e46bc8f631055Chris Banes return ((Activity) mOriginalWindowCallback).getTitle(); 21216e8d4dd91083260223c007c797e46bc8f631055Chris Banes } 21316e8d4dd91083260223c007c797e46bc8f631055Chris Banes // Else, we'll return the title we have recorded ourselves 21416e8d4dd91083260223c007c797e46bc8f631055Chris Banes return mTitle; 215f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 216f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 217547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes class AppCompatWindowCallbackBase extends WindowCallbackWrapper { 218547a80d347e0dc9751bbe3cf91f947477145bdbaChris Banes AppCompatWindowCallbackBase(Window.Callback callback) { 219f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes super(callback); 220f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 221f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 222f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 223f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public boolean dispatchKeyEvent(KeyEvent event) { 224559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes return AppCompatDelegateImplBase.this.dispatchKeyEvent(event) 225559fa14454cc053127b3b96c0e63c48c06937e38Chris Banes || super.dispatchKeyEvent(event); 226d25af35061a9f20d59b25329d613c62c20184dadChris Banes } 227d25af35061a9f20d59b25329d613c62c20184dadChris Banes 228d25af35061a9f20d59b25329d613c62c20184dadChris Banes @Override 229d25af35061a9f20d59b25329d613c62c20184dadChris Banes public boolean dispatchKeyShortcutEvent(KeyEvent event) { 230d25af35061a9f20d59b25329d613c62c20184dadChris Banes return super.dispatchKeyShortcutEvent(event) 231d25af35061a9f20d59b25329d613c62c20184dadChris Banes || AppCompatDelegateImplBase.this.onKeyShortcut(event.getKeyCode(), event); 232f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 233f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 234f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 235f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public boolean onCreatePanelMenu(int featureId, Menu menu) { 236f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes if (featureId == Window.FEATURE_OPTIONS_PANEL && !(menu instanceof MenuBuilder)) { 237f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // If this is an options menu but it's not an AppCompat menu, we eat the event 238f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // and return false 239f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return false; 240f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 241f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return super.onCreatePanelMenu(featureId, menu); 242f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 243f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 244f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 245d25af35061a9f20d59b25329d613c62c20184dadChris Banes public void onContentChanged() { 246d25af35061a9f20d59b25329d613c62c20184dadChris Banes // We purposely do not propagate this call as this is called when we install 247d25af35061a9f20d59b25329d613c62c20184dadChris Banes // our sub-decor rather than the user's content 248d25af35061a9f20d59b25329d613c62c20184dadChris Banes } 249d25af35061a9f20d59b25329d613c62c20184dadChris Banes 250d25af35061a9f20d59b25329d613c62c20184dadChris Banes @Override 251f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public boolean onPreparePanel(int featureId, View view, Menu menu) { 2524e411251159c965caccb3bf3727c2921d74f06c1Chris Banes final MenuBuilder mb = menu instanceof MenuBuilder ? (MenuBuilder) menu : null; 2534e411251159c965caccb3bf3727c2921d74f06c1Chris Banes 2544e411251159c965caccb3bf3727c2921d74f06c1Chris Banes if (featureId == Window.FEATURE_OPTIONS_PANEL && mb == null) { 255f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // If this is an options menu but it's not an AppCompat menu, we eat the event 256f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes // and return false 257f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes return false; 258f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 259f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 2604e411251159c965caccb3bf3727c2921d74f06c1Chris Banes // On ICS and below devices, onPreparePanel calls menu.hasVisibleItems() to determine 2614e411251159c965caccb3bf3727c2921d74f06c1Chris Banes // if a panel is prepared. This interferes with any initially invisible items, which 2624e411251159c965caccb3bf3727c2921d74f06c1Chris Banes // are later made visible. We workaround it by making hasVisibleItems() always 2634e411251159c965caccb3bf3727c2921d74f06c1Chris Banes // return true during the onPreparePanel call. 2644e411251159c965caccb3bf3727c2921d74f06c1Chris Banes if (mb != null) { 2654e411251159c965caccb3bf3727c2921d74f06c1Chris Banes mb.setOverrideVisibleItems(true); 2664e411251159c965caccb3bf3727c2921d74f06c1Chris Banes } 2674e411251159c965caccb3bf3727c2921d74f06c1Chris Banes 2684e411251159c965caccb3bf3727c2921d74f06c1Chris Banes final boolean handled = super.onPreparePanel(featureId, view, menu); 2694e411251159c965caccb3bf3727c2921d74f06c1Chris Banes 2704e411251159c965caccb3bf3727c2921d74f06c1Chris Banes if (mb != null) { 2714e411251159c965caccb3bf3727c2921d74f06c1Chris Banes mb.setOverrideVisibleItems(false); 272f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 273f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 2744e411251159c965caccb3bf3727c2921d74f06c1Chris Banes return handled; 275f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 276f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 277f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 278f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public boolean onMenuOpened(int featureId, Menu menu) { 279d25af35061a9f20d59b25329d613c62c20184dadChris Banes return super.onMenuOpened(featureId, menu) 280d25af35061a9f20d59b25329d613c62c20184dadChris Banes || AppCompatDelegateImplBase.this.onMenuOpened(featureId, menu); 281f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 282f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes 283f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes @Override 284f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes public void onPanelClosed(int featureId, Menu menu) { 285f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes super.onPanelClosed(featureId, menu); 286d25af35061a9f20d59b25329d613c62c20184dadChris Banes AppCompatDelegateImplBase.this.onPanelClosed(featureId, menu); 287f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 288f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes } 289f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes} 290