1696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell/* 2696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * Copyright (C) 2011 The Android Open Source Project 3696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * 4696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 5696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * you may not use this file except in compliance with the License. 6696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * You may obtain a copy of the License at 7696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * 8696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * http://www.apache.org/licenses/LICENSE-2.0 9696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * 10696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * Unless required by applicable law or agreed to in writing, software 11696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * distributed under the License is distributed on an "AS IS" BASIS, 12696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * See the License for the specific language governing permissions and 14696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * limitations under the License. 15696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */ 16696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 17fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powellpackage android.widget; 18696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 19696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.content.Context; 20bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powellimport android.content.res.Configuration; 21696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.content.res.Resources; 229d9581f52edcbd086edcd4153e9daa29c0205256Alan Viveretteimport android.graphics.Matrix; 23f023c2530a4591889dda614aaa016d5a9f9617edAlan Viveretteimport android.graphics.Rect; 24f023c2530a4591889dda614aaa016d5a9f9617edAlan Viveretteimport android.graphics.drawable.Drawable; 2511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powellimport android.os.Parcel; 2611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powellimport android.os.Parcelable; 27696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.util.SparseBooleanArray; 28823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powellimport android.view.ActionProvider; 2954c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powellimport android.view.Gravity; 30696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.MenuItem; 31696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.SoundEffectConstants; 32696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.View; 33696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.View.MeasureSpec; 34696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.ViewGroup; 35ad79b90f21dcde6f741c47a251882c0a47c5f698Adam Powellimport android.view.accessibility.AccessibilityNodeInfo; 36ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viveretteimport android.widget.ListPopupWindow.ForwardingListener; 37ad79b90f21dcde6f741c47a251882c0a47c5f698Adam Powellimport com.android.internal.transition.ActionBarTransition; 3880e72700858eb58b379f77a0da5fd3a98e1aa07cAlan Viveretteimport com.android.internal.view.ActionBarPolicy; 39fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powellimport com.android.internal.view.menu.ActionMenuItemView; 40fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powellimport com.android.internal.view.menu.BaseMenuPresenter; 41fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powellimport com.android.internal.view.menu.MenuBuilder; 42fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powellimport com.android.internal.view.menu.MenuItemImpl; 43fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powellimport com.android.internal.view.menu.MenuPopupHelper; 44fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powellimport com.android.internal.view.menu.MenuView; 45fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powellimport com.android.internal.view.menu.SubMenuBuilder; 46696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 47696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport java.util.ArrayList; 48696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 49696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell/** 50696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * MenuPresenter for building action menus as seen in the action bar and action modes. 51fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powell * 52fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powell * @hide 53696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */ 54823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powellpublic class ActionMenuPresenter extends BaseMenuPresenter 55823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell implements ActionProvider.SubUiVisibilityListener { 56640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell private static final String TAG = "ActionMenuPresenter"; 57640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell 58696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private View mOverflowButton; 59696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private boolean mReserveOverflow; 601ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell private boolean mReserveOverflowSet; 61696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private int mWidthLimit; 62696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private int mActionItemWidthLimit; 63696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private int mMaxItems; 641ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell private boolean mMaxItemsSet; 65640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell private boolean mStrictWidthLimit; 661ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell private boolean mWidthLimitSet; 67b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell private boolean mExpandedActionViewsExclusive; 68696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 6935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell private int mMinCellSize; 7035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 71696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // Group IDs that have been added as actions - used temporarily, allocated here for reuse. 72696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray(); 73696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 74696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private View mScrapActionButtonView; 75696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 76696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private OverflowPopup mOverflowPopup; 77696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private ActionButtonSubmenu mActionButtonPopup; 78696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 79696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private OpenOverflowRunnable mPostedOpenRunnable; 8056110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette private ActionMenuPopupCallback mPopupCallback; 81696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 8211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback(); 8311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell int mOpenSubMenuId; 8411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 85538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell public ActionMenuPresenter(Context context) { 86538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell super(context, com.android.internal.R.layout.action_menu_layout, 87696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell com.android.internal.R.layout.action_menu_item_layout); 88696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 89696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 90696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 91696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void initForMenu(Context context, MenuBuilder menu) { 92696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super.initForMenu(context, menu); 93696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 94696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final Resources res = context.getResources(); 951ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell 96b8139af3dcae80c0030afd0354dc424a7c72c3d9Adam Powell final ActionBarPolicy abp = ActionBarPolicy.get(context); 971ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell if (!mReserveOverflowSet) { 98b8139af3dcae80c0030afd0354dc424a7c72c3d9Adam Powell mReserveOverflow = abp.showsOverflowMenuButton(); 991ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell } 1001ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell 1011ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell if (!mWidthLimitSet) { 102b8139af3dcae80c0030afd0354dc424a7c72c3d9Adam Powell mWidthLimit = abp.getEmbeddedMenuWidthLimit(); 1031ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell } 104696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 105696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // Measure for initial configuration 1061ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell if (!mMaxItemsSet) { 107b8139af3dcae80c0030afd0354dc424a7c72c3d9Adam Powell mMaxItems = abp.getMaxActionButtons(); 1081ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell } 109696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 110696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell int width = mWidthLimit; 111696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (mReserveOverflow) { 1129b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell if (mOverflowButton == null) { 113538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell mOverflowButton = new OverflowMenuButton(mSystemContext); 1149b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 1159b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell mOverflowButton.measure(spec, spec); 1169b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell } 117696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell width -= mOverflowButton.getMeasuredWidth(); 118696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } else { 119696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mOverflowButton = null; 120696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 121696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 122696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mActionItemWidthLimit = width; 123696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 12435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density); 12535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 126696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // Drop a scrap view as it may no longer reflect the proper context/config. 127696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mScrapActionButtonView = null; 128696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 129696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 130bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell public void onConfigurationChanged(Configuration newConfig) { 131bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell if (!mMaxItemsSet) { 132bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell mMaxItems = mContext.getResources().getInteger( 133bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell com.android.internal.R.integer.max_action_buttons); 134f203e0a44ef7578c080d63424820fb5a94a4e92fAdam Powell } 135f203e0a44ef7578c080d63424820fb5a94a4e92fAdam Powell if (mMenu != null) { 136f203e0a44ef7578c080d63424820fb5a94a4e92fAdam Powell mMenu.onItemsChanged(true); 137bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell } 138bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell } 139bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell 140640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell public void setWidthLimit(int width, boolean strict) { 1411ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell mWidthLimit = width; 142640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell mStrictWidthLimit = strict; 1431ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell mWidthLimitSet = true; 1441ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell } 1451ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell 1461ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell public void setReserveOverflow(boolean reserveOverflow) { 1471ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell mReserveOverflow = reserveOverflow; 1481ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell mReserveOverflowSet = true; 1499b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell } 1509b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell 1519b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell public void setItemLimit(int itemCount) { 1529b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell mMaxItems = itemCount; 1531ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell mMaxItemsSet = true; 1549b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell } 1559b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell 156b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell public void setExpandedActionViewsExclusive(boolean isExclusive) { 157b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell mExpandedActionViewsExclusive = isExclusive; 158b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell } 159b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell 160696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 161696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public MenuView getMenuView(ViewGroup root) { 162696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell MenuView result = super.getMenuView(root); 163696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell ((ActionMenuView) result).setPresenter(this); 164696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return result; 165696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 166696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 167696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 168fbe4a586c29b6e415e8d39d73d19bd7f0215a851Alan Viverette public View getItemView(final MenuItemImpl item, View convertView, ViewGroup parent) { 1698d02deabac62c4a68a335a7b3141795466362b89Adam Powell View actionView = item.getActionView(); 17035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (actionView == null || item.hasCollapsibleActionView()) { 171c3ca3ea3a937a20666e4f01fb1a9efb503ec274eAdam Powell actionView = super.getItemView(item, convertView, parent); 17235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 1738d02deabac62c4a68a335a7b3141795466362b89Adam Powell actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE); 17435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 175efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell final ActionMenuView menuParent = (ActionMenuView) parent; 176efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell final ViewGroup.LayoutParams lp = actionView.getLayoutParams(); 177efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell if (!menuParent.checkLayoutParams(lp)) { 178efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell actionView.setLayoutParams(menuParent.generateLayoutParams(lp)); 179efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell } 180efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell return actionView; 181efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell } 182efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell 183efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell @Override 18456110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) { 185efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell itemView.initialize(item, 0); 186efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell 187efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell final ActionMenuView menuView = (ActionMenuView) mMenuView; 188efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell final ActionMenuItemView actionItemView = (ActionMenuItemView) itemView; 189efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell actionItemView.setItemInvoker(menuView); 190efc3bb06127a6640afe4985b2b2fc03c5ecc5deeAdam Powell 19156110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette if (mPopupCallback == null) { 19256110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette mPopupCallback = new ActionMenuPopupCallback(); 193fbe4a586c29b6e415e8d39d73d19bd7f0215a851Alan Viverette } 19456110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette actionItemView.setPopupCallback(mPopupCallback); 195696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 196696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 197696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 198696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { 199696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return item.isActionButton(); 200696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 201696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 202696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 203696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void updateMenuView(boolean cleared) { 204ad79b90f21dcde6f741c47a251882c0a47c5f698Adam Powell final ViewGroup menuViewParent = (ViewGroup) ((View) mMenuView).getParent(); 205ad79b90f21dcde6f741c47a251882c0a47c5f698Adam Powell if (menuViewParent != null) { 206d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase ActionBarTransition.beginDelayedTransition(menuViewParent); 207ad79b90f21dcde6f741c47a251882c0a47c5f698Adam Powell } 208696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super.updateMenuView(cleared); 209696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 210da9710806bc7874b8c553f4daf9cf14f35ae1b07Adam Powell ((View) mMenuView).requestLayout(); 211da9710806bc7874b8c553f4daf9cf14f35ae1b07Adam Powell 212823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell if (mMenu != null) { 213823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell final ArrayList<MenuItemImpl> actionItems = mMenu.getActionItems(); 214823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell final int count = actionItems.size(); 215823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell for (int i = 0; i < count; i++) { 216823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell final ActionProvider provider = actionItems.get(i).getActionProvider(); 217823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell if (provider != null) { 218823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell provider.setSubUiVisibilityListener(this); 219823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell } 220823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell } 221823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell } 222823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell 223275702c2f47ed87ab642462530092d9777f32ecdAdam Powell final ArrayList<MenuItemImpl> nonActionItems = mMenu != null ? 224275702c2f47ed87ab642462530092d9777f32ecdAdam Powell mMenu.getNonActionItems() : null; 225275702c2f47ed87ab642462530092d9777f32ecdAdam Powell 226275702c2f47ed87ab642462530092d9777f32ecdAdam Powell boolean hasOverflow = false; 227275702c2f47ed87ab642462530092d9777f32ecdAdam Powell if (mReserveOverflow && nonActionItems != null) { 228275702c2f47ed87ab642462530092d9777f32ecdAdam Powell final int count = nonActionItems.size(); 229275702c2f47ed87ab642462530092d9777f32ecdAdam Powell if (count == 1) { 230275702c2f47ed87ab642462530092d9777f32ecdAdam Powell hasOverflow = !nonActionItems.get(0).isActionViewExpanded(); 231275702c2f47ed87ab642462530092d9777f32ecdAdam Powell } else { 232275702c2f47ed87ab642462530092d9777f32ecdAdam Powell hasOverflow = count > 0; 233275702c2f47ed87ab642462530092d9777f32ecdAdam Powell } 234275702c2f47ed87ab642462530092d9777f32ecdAdam Powell } 235275702c2f47ed87ab642462530092d9777f32ecdAdam Powell 23614b7e2c1688914ba8b6854738981337d7c0653beAdam Powell if (hasOverflow) { 237696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (mOverflowButton == null) { 238538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell mOverflowButton = new OverflowMenuButton(mSystemContext); 239696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 240696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell ViewGroup parent = (ViewGroup) mOverflowButton.getParent(); 241696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (parent != mMenuView) { 242696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (parent != null) { 243696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell parent.removeView(mOverflowButton); 244696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 24535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell ActionMenuView menuView = (ActionMenuView) mMenuView; 24635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams()); 247696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 248696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) { 249696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell ((ViewGroup) mMenuView).removeView(mOverflowButton); 250696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 25114b7e2c1688914ba8b6854738981337d7c0653beAdam Powell 25214b7e2c1688914ba8b6854738981337d7c0653beAdam Powell ((ActionMenuView) mMenuView).setOverflowReserved(mReserveOverflow); 253696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 254696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 255696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 256696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean filterLeftoverView(ViewGroup parent, int childIndex) { 257696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (parent.getChildAt(childIndex) == mOverflowButton) return false; 258696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return super.filterLeftoverView(parent, childIndex); 259696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 260696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 261696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean onSubMenuSelected(SubMenuBuilder subMenu) { 262696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (!subMenu.hasVisibleItems()) return false; 263696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 264696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell SubMenuBuilder topSubMenu = subMenu; 265696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell while (topSubMenu.getParentMenu() != mMenu) { 266696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell topSubMenu = (SubMenuBuilder) topSubMenu.getParentMenu(); 267696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 268696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell View anchor = findViewForItem(topSubMenu.getItem()); 26911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell if (anchor == null) { 27011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell if (mOverflowButton == null) return false; 27111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell anchor = mOverflowButton; 27211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 273696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 27411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell mOpenSubMenuId = subMenu.getItem().getItemId(); 275696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu); 276696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mActionButtonPopup.setAnchorView(anchor); 277696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mActionButtonPopup.show(); 278696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super.onSubMenuSelected(subMenu); 279696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return true; 280696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 281696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 282696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private View findViewForItem(MenuItem item) { 283696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final ViewGroup parent = (ViewGroup) mMenuView; 284696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (parent == null) return null; 285696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 286696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final int count = parent.getChildCount(); 287696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell for (int i = 0; i < count; i++) { 288696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final View child = parent.getChildAt(i); 289696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (child instanceof MenuView.ItemView && 290696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell ((MenuView.ItemView) child).getItemData() == item) { 291696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return child; 292696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 293696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 294696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return null; 295696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 296696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 297696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell /** 298696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * Display the overflow menu if one is present. 299696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * @return true if the overflow menu was shown, false otherwise. 300696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */ 301696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean showOverflowMenu() { 30270e9f4bd2c044858f3c1c040ffce973351a2383aAdam Powell if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null && 303a647640f85f415bd8fb8cb925e7687658fe9ae37Jake Wharton mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) { 304696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true); 305696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mPostedOpenRunnable = new OpenOverflowRunnable(popup); 306696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // Post this for later; we might still need a layout for the anchor to be right. 307696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell ((View) mMenuView).post(mPostedOpenRunnable); 308696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 309696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // ActionMenuPresenter uses null as a callback argument here 310696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // to indicate overflow is opening. 311696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super.onSubMenuSelected(null); 312696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 313696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return true; 314696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 315696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return false; 316696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 317696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 318696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell /** 319696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * Hide the overflow menu if it is currently showing. 320696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * 321696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * @return true if the overflow menu was hidden, false otherwise. 322696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */ 323696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean hideOverflowMenu() { 324696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (mPostedOpenRunnable != null && mMenuView != null) { 325696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell ((View) mMenuView).removeCallbacks(mPostedOpenRunnable); 326678ed0c5a32bac1ea18a5ac99b0b814421ea79b4Adam Powell mPostedOpenRunnable = null; 327696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return true; 328696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 329696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 330696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell MenuPopupHelper popup = mOverflowPopup; 331696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (popup != null) { 332696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell popup.dismiss(); 333696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return true; 334696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 335696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return false; 336696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 337696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 338696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell /** 339696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * Dismiss all popup menus - overflow and submenus. 340696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * @return true if popups were dismissed, false otherwise. (This can be because none were open.) 341696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */ 342696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean dismissPopupMenus() { 343696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell boolean result = hideOverflowMenu(); 344696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell result |= hideSubMenus(); 345696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return result; 346696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 347696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 348696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell /** 349696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * Dismiss all submenu popups. 350696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * 351696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * @return true if popups were dismissed, false otherwise. (This can be because none were open.) 352696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */ 353696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean hideSubMenus() { 354696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (mActionButtonPopup != null) { 355696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mActionButtonPopup.dismiss(); 356696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return true; 357696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 358696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return false; 359696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 360696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 361696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell /** 362696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * @return true if the overflow menu is currently showing 363696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */ 364696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean isOverflowMenuShowing() { 365696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return mOverflowPopup != null && mOverflowPopup.isShowing(); 366696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 367696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 3685fcf5b9fd3ff6757090c6bd166b60c18eda0b3efAdam Powell public boolean isOverflowMenuShowPending() { 3695fcf5b9fd3ff6757090c6bd166b60c18eda0b3efAdam Powell return mPostedOpenRunnable != null || isOverflowMenuShowing(); 3705fcf5b9fd3ff6757090c6bd166b60c18eda0b3efAdam Powell } 3715fcf5b9fd3ff6757090c6bd166b60c18eda0b3efAdam Powell 372696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell /** 373696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * @return true if space has been reserved in the action menu for an overflow item. 374696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */ 375696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean isOverflowReserved() { 376696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return mReserveOverflow; 377696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 378696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 379696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean flagActionItems() { 380696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems(); 381696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final int itemsSize = visibleItems.size(); 382696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell int maxActions = mMaxItems; 383696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell int widthLimit = mActionItemWidthLimit; 384696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 385696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final ViewGroup parent = (ViewGroup) mMenuView; 386696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 387696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell int requiredItems = 0; 388696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell int requestedItems = 0; 389696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell int firstActionWidth = 0; 390696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell boolean hasOverflow = false; 391696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell for (int i = 0; i < itemsSize; i++) { 392696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell MenuItemImpl item = visibleItems.get(i); 393696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (item.requiresActionButton()) { 394696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell requiredItems++; 395696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } else if (item.requestsActionButton()) { 396696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell requestedItems++; 397696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } else { 398696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell hasOverflow = true; 399696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 400b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell if (mExpandedActionViewsExclusive && item.isActionViewExpanded()) { 401b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell // Overflow everything if we have an expanded action view and we're 402b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell // space constrained. 403b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell maxActions = 0; 404b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell } 405696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 406696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 407696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // Reserve a spot for the overflow item if needed. 408696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (mReserveOverflow && 409696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell (hasOverflow || requiredItems + requestedItems > maxActions)) { 410696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell maxActions--; 411696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 412696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell maxActions -= requiredItems; 413696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 414696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final SparseBooleanArray seenGroups = mActionButtonGroups; 415696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell seenGroups.clear(); 416696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 41735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell int cellSize = 0; 41835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell int cellsRemaining = 0; 41935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (mStrictWidthLimit) { 42035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell cellsRemaining = widthLimit / mMinCellSize; 42135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int cellSizeRemaining = widthLimit % mMinCellSize; 42235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining; 42335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 42435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell 425696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // Flag as many more requested items as will fit. 426696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell for (int i = 0; i < itemsSize; i++) { 427696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell MenuItemImpl item = visibleItems.get(i); 428696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 429696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (item.requiresActionButton()) { 43035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell View v = getItemView(item, mScrapActionButtonView, parent); 43135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (mScrapActionButtonView == null) { 43235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell mScrapActionButtonView = v; 43335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 43435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (mStrictWidthLimit) { 43535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell cellsRemaining -= ActionMenuView.measureChildForCells(v, 43635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell cellSize, cellsRemaining, querySpec, 0); 43735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } else { 43835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell v.measure(querySpec, querySpec); 439696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 440696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final int measuredWidth = v.getMeasuredWidth(); 441696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell widthLimit -= measuredWidth; 442696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (firstActionWidth == 0) { 443696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell firstActionWidth = measuredWidth; 444696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 445696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final int groupId = item.getGroupId(); 446696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (groupId != 0) { 447696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell seenGroups.put(groupId, true); 448696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 449ea1ca952c625d51dc71e1cc3d955b239921888c7Adam Powell item.setIsActionButton(true); 450696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } else if (item.requestsActionButton()) { 451696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // Items in a group with other items that already have an action slot 452696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // can break the max actions rule, but not the width limit. 453696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final int groupId = item.getGroupId(); 454696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final boolean inGroup = seenGroups.get(groupId); 45535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 && 45635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell (!mStrictWidthLimit || cellsRemaining > 0); 457696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 458696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (isAction) { 45935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell View v = getItemView(item, mScrapActionButtonView, parent); 46035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (mScrapActionButtonView == null) { 46135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell mScrapActionButtonView = v; 46235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } 46335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (mStrictWidthLimit) { 46435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell final int cells = ActionMenuView.measureChildForCells(v, 46535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell cellSize, cellsRemaining, querySpec, 0); 46635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell cellsRemaining -= cells; 46735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell if (cells == 0) { 46835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell isAction = false; 469696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 47035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell } else { 47135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell v.measure(querySpec, querySpec); 472696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 473696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final int measuredWidth = v.getMeasuredWidth(); 474696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell widthLimit -= measuredWidth; 475696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (firstActionWidth == 0) { 476696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell firstActionWidth = measuredWidth; 477696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 478696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 479640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell if (mStrictWidthLimit) { 48035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell isAction &= widthLimit >= 0; 481640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell } else { 482640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell // Did this push the entire first item past the limit? 48335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell isAction &= widthLimit + firstActionWidth > 0; 484696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 485696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 486696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 487696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (isAction && groupId != 0) { 488696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell seenGroups.put(groupId, true); 489696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } else if (inGroup) { 490696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // We broke the width limit. Demote the whole group, they all overflow now. 491696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell seenGroups.put(groupId, false); 492696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell for (int j = 0; j < i; j++) { 493696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell MenuItemImpl areYouMyGroupie = visibleItems.get(j); 494696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (areYouMyGroupie.getGroupId() == groupId) { 49523f4cc0353615107cc9c19fda9cf96ddd43266e2Adam Powell // Give back the action slot 49623f4cc0353615107cc9c19fda9cf96ddd43266e2Adam Powell if (areYouMyGroupie.isActionButton()) maxActions++; 497696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell areYouMyGroupie.setIsActionButton(false); 498696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 499696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 500696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 501696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 50223f4cc0353615107cc9c19fda9cf96ddd43266e2Adam Powell if (isAction) maxActions--; 50323f4cc0353615107cc9c19fda9cf96ddd43266e2Adam Powell 504696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell item.setIsActionButton(isAction); 50514c4669916ae993b248f00c55daf0f17069903d9Svetoslav Ganov } else { 50614c4669916ae993b248f00c55daf0f17069903d9Svetoslav Ganov // Neither requires nor requests an action button. 50714c4669916ae993b248f00c55daf0f17069903d9Svetoslav Ganov item.setIsActionButton(false); 508696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 509696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 510696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return true; 511696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 512696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 513696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 514696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 515696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell dismissPopupMenus(); 516696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super.onCloseMenu(menu, allMenusAreClosing); 517696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 518696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 51911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell @Override 52011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public Parcelable onSaveInstanceState() { 52111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell SavedState state = new SavedState(); 52211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell state.openSubMenuId = mOpenSubMenuId; 52311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell return state; 52411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 52511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 52611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell @Override 52711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public void onRestoreInstanceState(Parcelable state) { 52811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell SavedState saved = (SavedState) state; 52911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell if (saved.openSubMenuId > 0) { 53011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell MenuItem item = mMenu.findItem(saved.openSubMenuId); 53111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell if (item != null) { 53211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu(); 53311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell onSubMenuSelected(subMenu); 53411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 53511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 53611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 53711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 538823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell @Override 539823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell public void onSubUiVisibilityChanged(boolean isVisible) { 540823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell if (isVisible) { 541823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell // Not a submenu, but treat it like one. 542823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell super.onSubMenuSelected(null); 543823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell } else { 544823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell mMenu.close(false); 545823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell } 546823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell } 547823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell 548fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powell public void setMenuView(ActionMenuView menuView) { 549fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powell mMenuView = menuView; 550e021e6ed8931a0a8296af182fc9b0c76b64fb0c4Adam Powell menuView.initialize(mMenu); 551fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powell } 552fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powell 55311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell private static class SavedState implements Parcelable { 55411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public int openSubMenuId; 55511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 55611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell SavedState() { 55711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 55811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 55911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell SavedState(Parcel in) { 56011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell openSubMenuId = in.readInt(); 56111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 56211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 56311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell @Override 56411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public int describeContents() { 56511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell return 0; 56611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 56711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 56811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell @Override 56911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public void writeToParcel(Parcel dest, int flags) { 57011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell dest.writeInt(openSubMenuId); 57111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 57211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 57311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public static final Parcelable.Creator<SavedState> CREATOR 57411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell = new Parcelable.Creator<SavedState>() { 57511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public SavedState createFromParcel(Parcel in) { 57611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell return new SavedState(in); 57711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 57811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 57911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public SavedState[] newArray(int size) { 58011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell return new SavedState[size]; 58111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 58211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell }; 58311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 58411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 585fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powell private class OverflowMenuButton extends ImageButton implements ActionMenuView.ActionMenuChildView { 5869d9581f52edcbd086edcd4153e9daa29c0205256Alan Viverette private final float[] mTempPts = new float[2]; 5879d9581f52edcbd086edcd4153e9daa29c0205256Alan Viverette 588696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public OverflowMenuButton(Context context) { 589696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super(context, null, com.android.internal.R.attr.actionOverflowButtonStyle); 590696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 591696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell setClickable(true); 592696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell setFocusable(true); 593696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell setVisibility(VISIBLE); 594696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell setEnabled(true); 595ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 59669960142efa8d228adbfcbabdcf618426e31e1f5Alan Viverette setOnTouchListener(new ForwardingListener(this) { 597ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette @Override 598ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette public ListPopupWindow getPopup() { 599ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette if (mOverflowPopup == null) { 600ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return null; 601ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 602ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 603ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return mOverflowPopup.getPopup(); 604ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 605ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 606ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette @Override 607ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette public boolean onForwardingStarted() { 608ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette showOverflowMenu(); 609ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return true; 610ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 611ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 612ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette @Override 613ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette public boolean onForwardingStopped() { 614ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette // Displaying the popup occurs asynchronously, so wait for 615ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette // the runnable to finish before deciding whether to stop 616ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette // forwarding. 617ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette if (mPostedOpenRunnable != null) { 618ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return false; 619ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 620ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette 621ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette hideOverflowMenu(); 622ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette return true; 623ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette } 624ca6a3611cdb28a514834adba35fcce2da6f2e7c2Alan Viverette }); 625696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 626696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 627696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 628696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean performClick() { 629696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (super.performClick()) { 630696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return true; 631696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 632696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 633696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell playSoundEffect(SoundEffectConstants.CLICK); 634696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell showOverflowMenu(); 635696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return true; 636696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 637696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 63880e72700858eb58b379f77a0da5fd3a98e1aa07cAlan Viverette @Override 639696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean needsDividerBefore() { 64035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell return false; 641696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 642696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 64380e72700858eb58b379f77a0da5fd3a98e1aa07cAlan Viverette @Override 644696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean needsDividerAfter() { 645696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return false; 646696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 647d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell 648d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell @Override 649058ac7cfe5bb7b9ecc411b94622ac3f31a7fa25eAlan Viverette public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 650058ac7cfe5bb7b9ecc411b94622ac3f31a7fa25eAlan Viverette super.onInitializeAccessibilityNodeInfo(info); 651cb8ed39b3fb591be60b9fb1799d4ea4530eab758Svetoslav Ganov info.setCanOpenPopup(true); 652058ac7cfe5bb7b9ecc411b94622ac3f31a7fa25eAlan Viverette } 653f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette 654f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette @Override 6559d9581f52edcbd086edcd4153e9daa29c0205256Alan Viverette protected boolean setFrame(int l, int t, int r, int b) { 6569d9581f52edcbd086edcd4153e9daa29c0205256Alan Viverette final boolean changed = super.setFrame(l, t, r, b); 657f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette 658199ea8c0c759d5993b23467f22f2bff120c93d38Alan Viverette // Set up the hotspot bounds to square and centered on the image. 659f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette final Drawable d = getDrawable(); 660f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette final Drawable bg = getBackground(); 661f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette if (d != null && bg != null) { 662199ea8c0c759d5993b23467f22f2bff120c93d38Alan Viverette final int width = getWidth(); 663199ea8c0c759d5993b23467f22f2bff120c93d38Alan Viverette final int height = getHeight(); 664199ea8c0c759d5993b23467f22f2bff120c93d38Alan Viverette final int halfEdge = Math.max(width, height) / 2; 665199ea8c0c759d5993b23467f22f2bff120c93d38Alan Viverette final int offsetX = getPaddingLeft() - getPaddingRight(); 666199ea8c0c759d5993b23467f22f2bff120c93d38Alan Viverette final int offsetY = getPaddingTop() - getPaddingBottom(); 667199ea8c0c759d5993b23467f22f2bff120c93d38Alan Viverette final int centerX = (width + offsetX) / 2; 668199ea8c0c759d5993b23467f22f2bff120c93d38Alan Viverette final int centerY = (height + offsetY) / 2; 669199ea8c0c759d5993b23467f22f2bff120c93d38Alan Viverette bg.setHotspotBounds(centerX - halfEdge, centerY - halfEdge, 670199ea8c0c759d5993b23467f22f2bff120c93d38Alan Viverette centerX + halfEdge, centerY + halfEdge); 671f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette } 6729d9581f52edcbd086edcd4153e9daa29c0205256Alan Viverette 6739d9581f52edcbd086edcd4153e9daa29c0205256Alan Viverette return changed; 674f023c2530a4591889dda614aaa016d5a9f9617edAlan Viverette } 675696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 676696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 677696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private class OverflowPopup extends MenuPopupHelper { 678696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public OverflowPopup(Context context, MenuBuilder menu, View anchorView, 679696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell boolean overflowOnly) { 680560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette super(context, menu, anchorView, overflowOnly, 681560f17098f90b15c8894cce127f2fed85f7aeb6bAlan Viverette com.android.internal.R.attr.actionOverflowMenuStyle); 68254c94dea8a26e66fa59a31fd9170ca221052d3aaAdam Powell setGravity(Gravity.END); 68311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell setCallback(mPopupPresenterCallback); 684696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 685696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 686696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 687696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void onDismiss() { 688696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super.onDismiss(); 689696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mMenu.close(); 690696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mOverflowPopup = null; 691696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 692696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 693696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 694696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private class ActionButtonSubmenu extends MenuPopupHelper { 695696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private SubMenuBuilder mSubMenu; 696696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 697696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) { 698d361a4f98bbc03cb61b9ac4504eda490ff704b60Alan Viverette super(context, subMenu, null, false, 699d361a4f98bbc03cb61b9ac4504eda490ff704b60Alan Viverette com.android.internal.R.attr.actionOverflowMenuStyle); 700696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mSubMenu = subMenu; 701696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 702696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell MenuItemImpl item = (MenuItemImpl) subMenu.getItem(); 703696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (!item.isActionButton()) { 704696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // Give a reasonable anchor to nested submenus. 705696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton); 706696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 70711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 70811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell setCallback(mPopupPresenterCallback); 7099151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell 7109151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell boolean preserveIconSpacing = false; 7119151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell final int count = subMenu.size(); 7129151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell for (int i = 0; i < count; i++) { 7139151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell MenuItem childItem = subMenu.getItem(i); 7149151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell if (childItem.isVisible() && childItem.getIcon() != null) { 7159151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell preserveIconSpacing = true; 7169151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell break; 7179151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell } 7189151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell } 7199151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell setForceShowIcon(preserveIconSpacing); 720696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 721696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 722696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 723696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void onDismiss() { 724696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super.onDismiss(); 725696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mActionButtonPopup = null; 72611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell mOpenSubMenuId = 0; 72711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 72811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 72911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 730fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powell private class PopupPresenterCallback implements Callback { 73111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 73211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell @Override 73311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public boolean onOpenSubMenu(MenuBuilder subMenu) { 734823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell if (subMenu == null) return false; 735823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell 73611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); 737fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powell final Callback cb = getCallback(); 738b411b32861e7794a59fa7558dbe9d97407eccf23Adam Powell return cb != null ? cb.onOpenSubMenu(subMenu) : false; 73911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 74011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 74111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell @Override 74211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 743823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell if (menu instanceof SubMenuBuilder) { 744823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell ((SubMenuBuilder) menu).getRootMenu().close(false); 745823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell } 746fa18d182a3f37505940e73ae6cd76c2e939f7f7cAdam Powell final Callback cb = getCallback(); 747b411b32861e7794a59fa7558dbe9d97407eccf23Adam Powell if (cb != null) { 748b411b32861e7794a59fa7558dbe9d97407eccf23Adam Powell cb.onCloseMenu(menu, allMenusAreClosing); 749b411b32861e7794a59fa7558dbe9d97407eccf23Adam Powell } 750696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 751696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 752696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 753696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private class OpenOverflowRunnable implements Runnable { 754696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private OverflowPopup mPopup; 755696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 756696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public OpenOverflowRunnable(OverflowPopup popup) { 757696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mPopup = popup; 758696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 759696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 760696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void run() { 761696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mMenu.changeMenuMode(); 762678ed0c5a32bac1ea18a5ac99b0b814421ea79b4Adam Powell final View menuView = (View) mMenuView; 763678ed0c5a32bac1ea18a5ac99b0b814421ea79b4Adam Powell if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) { 764696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mOverflowPopup = mPopup; 765696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 766678ed0c5a32bac1ea18a5ac99b0b814421ea79b4Adam Powell mPostedOpenRunnable = null; 767696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 768696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 76956110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette 77056110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette private class ActionMenuPopupCallback extends ActionMenuItemView.PopupCallback { 77156110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette @Override 77256110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette public ListPopupWindow getPopup() { 77356110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null; 77456110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette } 77556110725f2a0b3f09703f2cbe9705d97609ee1e5Alan Viverette } 776696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell} 777