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
17696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellpackage com.android.internal.view.menu;
18696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
19b8139af3dcae80c0030afd0354dc424a7c72c3d9Adam Powellimport com.android.internal.view.ActionBarPolicy;
20696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport com.android.internal.view.menu.ActionMenuView.ActionMenuChildView;
21696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
22696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.content.Context;
23bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powellimport android.content.res.Configuration;
24696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.content.res.Resources;
2511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powellimport android.os.Parcel;
2611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powellimport android.os.Parcelable;
27696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.util.SparseBooleanArray;
28823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powellimport android.view.ActionProvider;
29696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.MenuItem;
30696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.SoundEffectConstants;
31696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.View;
32696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.View.MeasureSpec;
33696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.ViewGroup;
34696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.widget.ImageButton;
35696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
36696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport java.util.ArrayList;
37696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
38696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell/**
39696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * MenuPresenter for building action menus as seen in the action bar and action modes.
40696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */
41823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powellpublic class ActionMenuPresenter extends BaseMenuPresenter
42823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell        implements ActionProvider.SubUiVisibilityListener {
43640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell    private static final String TAG = "ActionMenuPresenter";
44640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell
45696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private View mOverflowButton;
46696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private boolean mReserveOverflow;
471ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell    private boolean mReserveOverflowSet;
48696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private int mWidthLimit;
49696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private int mActionItemWidthLimit;
50696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private int mMaxItems;
511ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell    private boolean mMaxItemsSet;
52640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell    private boolean mStrictWidthLimit;
531ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell    private boolean mWidthLimitSet;
54b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell    private boolean mExpandedActionViewsExclusive;
55696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
5635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell    private int mMinCellSize;
5735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell
58696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    // Group IDs that have been added as actions - used temporarily, allocated here for reuse.
59696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray();
60696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
61696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private View mScrapActionButtonView;
62696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
63696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private OverflowPopup mOverflowPopup;
64696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private ActionButtonSubmenu mActionButtonPopup;
65696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
66696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private OpenOverflowRunnable mPostedOpenRunnable;
67696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
6811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback();
6911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    int mOpenSubMenuId;
7011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
71538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell    public ActionMenuPresenter(Context context) {
72538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell        super(context, com.android.internal.R.layout.action_menu_layout,
73696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                com.android.internal.R.layout.action_menu_item_layout);
74696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
75696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
76696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
77696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void initForMenu(Context context, MenuBuilder menu) {
78696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        super.initForMenu(context, menu);
79696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
80696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final Resources res = context.getResources();
811ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell
82b8139af3dcae80c0030afd0354dc424a7c72c3d9Adam Powell        final ActionBarPolicy abp = ActionBarPolicy.get(context);
831ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell        if (!mReserveOverflowSet) {
84b8139af3dcae80c0030afd0354dc424a7c72c3d9Adam Powell            mReserveOverflow = abp.showsOverflowMenuButton();
851ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell        }
861ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell
871ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell        if (!mWidthLimitSet) {
88b8139af3dcae80c0030afd0354dc424a7c72c3d9Adam Powell            mWidthLimit = abp.getEmbeddedMenuWidthLimit();
891ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell        }
90696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
91696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        // Measure for initial configuration
921ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell        if (!mMaxItemsSet) {
93b8139af3dcae80c0030afd0354dc424a7c72c3d9Adam Powell            mMaxItems = abp.getMaxActionButtons();
941ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell        }
95696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
96696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        int width = mWidthLimit;
97696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mReserveOverflow) {
989b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell            if (mOverflowButton == null) {
99538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell                mOverflowButton = new OverflowMenuButton(mSystemContext);
1009b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell                final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
1019b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell                mOverflowButton.measure(spec, spec);
1029b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell            }
103696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            width -= mOverflowButton.getMeasuredWidth();
104696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        } else {
105696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mOverflowButton = null;
106696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
107696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
108696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mActionItemWidthLimit = width;
109696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
11035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density);
11135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell
112696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        // Drop a scrap view as it may no longer reflect the proper context/config.
113696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mScrapActionButtonView = null;
114696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
115696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
116bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell    public void onConfigurationChanged(Configuration newConfig) {
117bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell        if (!mMaxItemsSet) {
118bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell            mMaxItems = mContext.getResources().getInteger(
119bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell                    com.android.internal.R.integer.max_action_buttons);
120f203e0a44ef7578c080d63424820fb5a94a4e92fAdam Powell        }
121f203e0a44ef7578c080d63424820fb5a94a4e92fAdam Powell        if (mMenu != null) {
122f203e0a44ef7578c080d63424820fb5a94a4e92fAdam Powell            mMenu.onItemsChanged(true);
123bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell        }
124bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell    }
125bfcdfaf919cdb67897a6e24afc8f14b2c810596aAdam Powell
126640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell    public void setWidthLimit(int width, boolean strict) {
1271ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell        mWidthLimit = width;
128640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell        mStrictWidthLimit = strict;
1291ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell        mWidthLimitSet = true;
1301ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell    }
1311ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell
1321ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell    public void setReserveOverflow(boolean reserveOverflow) {
1331ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell        mReserveOverflow = reserveOverflow;
1341ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell        mReserveOverflowSet = true;
1359b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell    }
1369b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell
1379b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell    public void setItemLimit(int itemCount) {
1389b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell        mMaxItems = itemCount;
1391ab418a222e1834c4b1312fde355e41a1947af0dAdam Powell        mMaxItemsSet = true;
1409b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell    }
1419b4bee0f14bbd137b0797127aff2df46a6321ec5Adam Powell
142b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell    public void setExpandedActionViewsExclusive(boolean isExclusive) {
143b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell        mExpandedActionViewsExclusive = isExclusive;
144b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell    }
145b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell
146696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
147696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public MenuView getMenuView(ViewGroup root) {
148696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        MenuView result = super.getMenuView(root);
149696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        ((ActionMenuView) result).setPresenter(this);
150696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return result;
151696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
152696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
153696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
154696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) {
1558d02deabac62c4a68a335a7b3141795466362b89Adam Powell        View actionView = item.getActionView();
15635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        if (actionView == null || item.hasCollapsibleActionView()) {
15735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell            if (!(convertView instanceof ActionMenuItemView)) {
15835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                convertView = null;
15935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell            }
16035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell            actionView = super.getItemView(item, convertView, parent);
16135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        }
1628d02deabac62c4a68a335a7b3141795466362b89Adam Powell        actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE);
16335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell
16435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        final ActionMenuView menuParent = (ActionMenuView) parent;
16535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
16635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        if (!menuParent.checkLayoutParams(lp)) {
16735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell            actionView.setLayoutParams(menuParent.generateLayoutParams(lp));
16835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        }
1698d02deabac62c4a68a335a7b3141795466362b89Adam Powell        return actionView;
170696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
171696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
172696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
173696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) {
174696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        itemView.initialize(item, 0);
17535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell
17635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        final ActionMenuView menuView = (ActionMenuView) mMenuView;
17735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
17835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        actionItemView.setItemInvoker(menuView);
179696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
180696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
181696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
182696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) {
183696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return item.isActionButton();
184696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
185696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
186696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
187696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void updateMenuView(boolean cleared) {
188696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        super.updateMenuView(cleared);
189696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
190823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell        if (mMenu != null) {
191823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            final ArrayList<MenuItemImpl> actionItems = mMenu.getActionItems();
192823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            final int count = actionItems.size();
193823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            for (int i = 0; i < count; i++) {
194823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell                final ActionProvider provider = actionItems.get(i).getActionProvider();
195823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell                if (provider != null) {
196823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell                    provider.setSubUiVisibilityListener(this);
197823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell                }
198823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            }
199823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell        }
200823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell
201275702c2f47ed87ab642462530092d9777f32ecdAdam Powell        final ArrayList<MenuItemImpl> nonActionItems = mMenu != null ?
202275702c2f47ed87ab642462530092d9777f32ecdAdam Powell                mMenu.getNonActionItems() : null;
203275702c2f47ed87ab642462530092d9777f32ecdAdam Powell
204275702c2f47ed87ab642462530092d9777f32ecdAdam Powell        boolean hasOverflow = false;
205275702c2f47ed87ab642462530092d9777f32ecdAdam Powell        if (mReserveOverflow && nonActionItems != null) {
206275702c2f47ed87ab642462530092d9777f32ecdAdam Powell            final int count = nonActionItems.size();
207275702c2f47ed87ab642462530092d9777f32ecdAdam Powell            if (count == 1) {
208275702c2f47ed87ab642462530092d9777f32ecdAdam Powell                hasOverflow = !nonActionItems.get(0).isActionViewExpanded();
209275702c2f47ed87ab642462530092d9777f32ecdAdam Powell            } else {
210275702c2f47ed87ab642462530092d9777f32ecdAdam Powell                hasOverflow = count > 0;
211275702c2f47ed87ab642462530092d9777f32ecdAdam Powell            }
212275702c2f47ed87ab642462530092d9777f32ecdAdam Powell        }
213275702c2f47ed87ab642462530092d9777f32ecdAdam Powell
21414b7e2c1688914ba8b6854738981337d7c0653beAdam Powell        if (hasOverflow) {
215696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (mOverflowButton == null) {
216538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell                mOverflowButton = new OverflowMenuButton(mSystemContext);
217696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
218696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            ViewGroup parent = (ViewGroup) mOverflowButton.getParent();
219696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (parent != mMenuView) {
220696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                if (parent != null) {
221696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    parent.removeView(mOverflowButton);
222696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                }
22335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                ActionMenuView menuView = (ActionMenuView) mMenuView;
22435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams());
225696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
226696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) {
227696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            ((ViewGroup) mMenuView).removeView(mOverflowButton);
228696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
22914b7e2c1688914ba8b6854738981337d7c0653beAdam Powell
23014b7e2c1688914ba8b6854738981337d7c0653beAdam Powell        ((ActionMenuView) mMenuView).setOverflowReserved(mReserveOverflow);
231696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
232696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
233696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
234696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean filterLeftoverView(ViewGroup parent, int childIndex) {
235696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (parent.getChildAt(childIndex) == mOverflowButton) return false;
236696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return super.filterLeftoverView(parent, childIndex);
237696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
238696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
239696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
240696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (!subMenu.hasVisibleItems()) return false;
241696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
242696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        SubMenuBuilder topSubMenu = subMenu;
243696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        while (topSubMenu.getParentMenu() != mMenu) {
244696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            topSubMenu = (SubMenuBuilder) topSubMenu.getParentMenu();
245696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
246696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        View anchor = findViewForItem(topSubMenu.getItem());
24711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        if (anchor == null) {
24811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            if (mOverflowButton == null) return false;
24911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            anchor = mOverflowButton;
25011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
251696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
25211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        mOpenSubMenuId = subMenu.getItem().getItemId();
253696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu);
254696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mActionButtonPopup.setAnchorView(anchor);
255696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mActionButtonPopup.show();
256696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        super.onSubMenuSelected(subMenu);
257696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return true;
258696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
259696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
260696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private View findViewForItem(MenuItem item) {
261696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final ViewGroup parent = (ViewGroup) mMenuView;
262696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (parent == null) return null;
263696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
264696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final int count = parent.getChildCount();
265696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        for (int i = 0; i < count; i++) {
266696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            final View child = parent.getChildAt(i);
267696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (child instanceof MenuView.ItemView &&
268696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    ((MenuView.ItemView) child).getItemData() == item) {
269696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                return child;
270696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
271696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
272696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return null;
273696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
274696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
275696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
276696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Display the overflow menu if one is present.
277696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @return true if the overflow menu was shown, false otherwise.
278696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
279696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean showOverflowMenu() {
28070e9f4bd2c044858f3c1c040ffce973351a2383aAdam Powell        if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null &&
281a647640f85f415bd8fb8cb925e7687658fe9ae37Jake Wharton                mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) {
282696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true);
283696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mPostedOpenRunnable = new OpenOverflowRunnable(popup);
284696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            // Post this for later; we might still need a layout for the anchor to be right.
285696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            ((View) mMenuView).post(mPostedOpenRunnable);
286696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
287696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            // ActionMenuPresenter uses null as a callback argument here
288696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            // to indicate overflow is opening.
289696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            super.onSubMenuSelected(null);
290696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
291696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            return true;
292696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
293696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return false;
294696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
295696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
296696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
297696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Hide the overflow menu if it is currently showing.
298696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     *
299696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @return true if the overflow menu was hidden, false otherwise.
300696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
301696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean hideOverflowMenu() {
302696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mPostedOpenRunnable != null && mMenuView != null) {
303696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            ((View) mMenuView).removeCallbacks(mPostedOpenRunnable);
304678ed0c5a32bac1ea18a5ac99b0b814421ea79b4Adam Powell            mPostedOpenRunnable = null;
305696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            return true;
306696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
307696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
308696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        MenuPopupHelper popup = mOverflowPopup;
309696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (popup != null) {
310696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            popup.dismiss();
311696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            return true;
312696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
313696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return false;
314696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
315696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
316696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
317696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Dismiss all popup menus - overflow and submenus.
318696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @return true if popups were dismissed, false otherwise. (This can be because none were open.)
319696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
320696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean dismissPopupMenus() {
321696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        boolean result = hideOverflowMenu();
322696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        result |= hideSubMenus();
323696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return result;
324696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
325696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
326696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
327696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * Dismiss all submenu popups.
328696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     *
329696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @return true if popups were dismissed, false otherwise. (This can be because none were open.)
330696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
331696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean hideSubMenus() {
332696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mActionButtonPopup != null) {
333696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mActionButtonPopup.dismiss();
334696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            return true;
335696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
336696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return false;
337696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
338696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
339696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
340696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @return true if the overflow menu is currently showing
341696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
342696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean isOverflowMenuShowing() {
343696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return mOverflowPopup != null && mOverflowPopup.isShowing();
344696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
345696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
346696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    /**
347696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     * @return true if space has been reserved in the action menu for an overflow item.
348696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell     */
349696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean isOverflowReserved() {
350696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return mReserveOverflow;
351696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
352696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
353696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean flagActionItems() {
354696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems();
355696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final int itemsSize = visibleItems.size();
356696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        int maxActions = mMaxItems;
357696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        int widthLimit = mActionItemWidthLimit;
358696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
359696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final ViewGroup parent = (ViewGroup) mMenuView;
360696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
361696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        int requiredItems = 0;
362696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        int requestedItems = 0;
363696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        int firstActionWidth = 0;
364696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        boolean hasOverflow = false;
365696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        for (int i = 0; i < itemsSize; i++) {
366696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            MenuItemImpl item = visibleItems.get(i);
367696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (item.requiresActionButton()) {
368696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                requiredItems++;
369696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            } else if (item.requestsActionButton()) {
370696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                requestedItems++;
371696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            } else {
372696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                hasOverflow = true;
373696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
374b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell            if (mExpandedActionViewsExclusive && item.isActionViewExpanded()) {
375b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell                // Overflow everything if we have an expanded action view and we're
376b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell                // space constrained.
377b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell                maxActions = 0;
378b187cd9c54f0100c0fb47c354cdecad29ca7c0aeAdam Powell            }
379696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
380696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
381696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        // Reserve a spot for the overflow item if needed.
382696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mReserveOverflow &&
383696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                (hasOverflow || requiredItems + requestedItems > maxActions)) {
384696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            maxActions--;
385696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
386696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        maxActions -= requiredItems;
387696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
388696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final SparseBooleanArray seenGroups = mActionButtonGroups;
389696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        seenGroups.clear();
390696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
39135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        int cellSize = 0;
39235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        int cellsRemaining = 0;
39335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        if (mStrictWidthLimit) {
39435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell            cellsRemaining = widthLimit / mMinCellSize;
39535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell            final int cellSizeRemaining = widthLimit % mMinCellSize;
39635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell            cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining;
39735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell        }
39835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell
399696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        // Flag as many more requested items as will fit.
400696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        for (int i = 0; i < itemsSize; i++) {
401696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            MenuItemImpl item = visibleItems.get(i);
402696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
403696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (item.requiresActionButton()) {
40435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                View v = getItemView(item, mScrapActionButtonView, parent);
40535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                if (mScrapActionButtonView == null) {
40635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                    mScrapActionButtonView = v;
40735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                }
40835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                if (mStrictWidthLimit) {
40935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                    cellsRemaining -= ActionMenuView.measureChildForCells(v,
41035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                            cellSize, cellsRemaining, querySpec, 0);
41135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                } else {
41235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                    v.measure(querySpec, querySpec);
413696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                }
414696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                final int measuredWidth = v.getMeasuredWidth();
415696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                widthLimit -= measuredWidth;
416696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                if (firstActionWidth == 0) {
417696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    firstActionWidth = measuredWidth;
418696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                }
419696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                final int groupId = item.getGroupId();
420696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                if (groupId != 0) {
421696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    seenGroups.put(groupId, true);
422696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                }
423ea1ca952c625d51dc71e1cc3d955b239921888c7Adam Powell                item.setIsActionButton(true);
424696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            } else if (item.requestsActionButton()) {
425696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                // Items in a group with other items that already have an action slot
426696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                // can break the max actions rule, but not the width limit.
427696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                final int groupId = item.getGroupId();
428696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                final boolean inGroup = seenGroups.get(groupId);
42935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 &&
43035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                        (!mStrictWidthLimit || cellsRemaining > 0);
431696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
432696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                if (isAction) {
43335aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                    View v = getItemView(item, mScrapActionButtonView, parent);
43435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                    if (mScrapActionButtonView == null) {
43535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                        mScrapActionButtonView = v;
43635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                    }
43735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                    if (mStrictWidthLimit) {
43835aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                        final int cells = ActionMenuView.measureChildForCells(v,
43935aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                                cellSize, cellsRemaining, querySpec, 0);
44035aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                        cellsRemaining -= cells;
44135aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                        if (cells == 0) {
44235aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                            isAction = false;
443696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                        }
44435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                    } else {
44535aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                        v.measure(querySpec, querySpec);
446696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    }
447696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    final int measuredWidth = v.getMeasuredWidth();
448696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    widthLimit -= measuredWidth;
449696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    if (firstActionWidth == 0) {
450696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                        firstActionWidth = measuredWidth;
451696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    }
452696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
453640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell                    if (mStrictWidthLimit) {
45435aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                        isAction &= widthLimit >= 0;
455640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell                    } else {
456640a66eac612b850b5dabd3b93bd94f83ed2d567Adam Powell                        // Did this push the entire first item past the limit?
45735aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell                        isAction &= widthLimit + firstActionWidth > 0;
458696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    }
459696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                }
460696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
461696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                if (isAction && groupId != 0) {
462696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    seenGroups.put(groupId, true);
463696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                } else if (inGroup) {
464696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    // We broke the width limit. Demote the whole group, they all overflow now.
465696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    seenGroups.put(groupId, false);
466696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    for (int j = 0; j < i; j++) {
467696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                        MenuItemImpl areYouMyGroupie = visibleItems.get(j);
468696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                        if (areYouMyGroupie.getGroupId() == groupId) {
46923f4cc0353615107cc9c19fda9cf96ddd43266e2Adam Powell                            // Give back the action slot
47023f4cc0353615107cc9c19fda9cf96ddd43266e2Adam Powell                            if (areYouMyGroupie.isActionButton()) maxActions++;
471696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                            areYouMyGroupie.setIsActionButton(false);
472696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                        }
473696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                    }
474696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                }
475696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
47623f4cc0353615107cc9c19fda9cf96ddd43266e2Adam Powell                if (isAction) maxActions--;
47723f4cc0353615107cc9c19fda9cf96ddd43266e2Adam Powell
478696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                item.setIsActionButton(isAction);
47914c4669916ae993b248f00c55daf0f17069903d9Svetoslav Ganov            } else {
48014c4669916ae993b248f00c55daf0f17069903d9Svetoslav Ganov                // Neither requires nor requests an action button.
48114c4669916ae993b248f00c55daf0f17069903d9Svetoslav Ganov                item.setIsActionButton(false);
482696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
483696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
484696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return true;
485696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
486696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
487696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
488696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
489696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        dismissPopupMenus();
490696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        super.onCloseMenu(menu, allMenusAreClosing);
491696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
492696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
49311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    @Override
49411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    public Parcelable onSaveInstanceState() {
49511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        SavedState state = new SavedState();
49611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        state.openSubMenuId = mOpenSubMenuId;
49711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        return state;
49811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    }
49911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
50011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    @Override
50111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    public void onRestoreInstanceState(Parcelable state) {
50211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        SavedState saved = (SavedState) state;
50311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        if (saved.openSubMenuId > 0) {
50411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            MenuItem item = mMenu.findItem(saved.openSubMenuId);
50511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            if (item != null) {
50611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell                SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu();
50711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell                onSubMenuSelected(subMenu);
50811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            }
50911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
51011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    }
51111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
512823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell    @Override
513823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell    public void onSubUiVisibilityChanged(boolean isVisible) {
514823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell        if (isVisible) {
515823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            // Not a submenu, but treat it like one.
516823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            super.onSubMenuSelected(null);
517823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell        } else {
518823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            mMenu.close(false);
519823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell        }
520823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell    }
521823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell
52211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    private static class SavedState implements Parcelable {
52311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        public int openSubMenuId;
52411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
52511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        SavedState() {
52611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
52711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
52811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        SavedState(Parcel in) {
52911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            openSubMenuId = in.readInt();
53011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
53111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
53211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        @Override
53311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        public int describeContents() {
53411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            return 0;
53511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
53611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
53711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        @Override
53811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        public void writeToParcel(Parcel dest, int flags) {
53911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            dest.writeInt(openSubMenuId);
54011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
54111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
54211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        public static final Parcelable.Creator<SavedState> CREATOR
54311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell                = new Parcelable.Creator<SavedState>() {
54411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            public SavedState createFromParcel(Parcel in) {
54511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell                return new SavedState(in);
54611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            }
54711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
54811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            public SavedState[] newArray(int size) {
54911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell                return new SavedState[size];
55011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            }
55111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        };
55211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    }
55311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
554696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private class OverflowMenuButton extends ImageButton implements ActionMenuChildView {
555696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        public OverflowMenuButton(Context context) {
556696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            super(context, null, com.android.internal.R.attr.actionOverflowButtonStyle);
557696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
558696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            setClickable(true);
559696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            setFocusable(true);
560696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            setVisibility(VISIBLE);
561696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            setEnabled(true);
562696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
563696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
564696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        @Override
565696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        public boolean performClick() {
566696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (super.performClick()) {
567696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                return true;
568696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
569696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
570696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            playSoundEffect(SoundEffectConstants.CLICK);
571696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            showOverflowMenu();
572696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            return true;
573696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
574696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
575696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        public boolean needsDividerBefore() {
57635aecd5884a5ccfe380903e39f30f468315e8f92Adam Powell            return false;
577696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
578696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
579696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        public boolean needsDividerAfter() {
580696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            return false;
581696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
582d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell
583d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell        @Override
584d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
585d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell            if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
586d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell                // Fill available height
587d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell                heightMeasureSpec = MeasureSpec.makeMeasureSpec(
588d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell                        MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.EXACTLY);
589d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell            }
590d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
591d5c81db1e78e98f3e0a1a5cf206865c3056294c4Adam Powell        }
592696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
593696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
594696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private class OverflowPopup extends MenuPopupHelper {
595696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        public OverflowPopup(Context context, MenuBuilder menu, View anchorView,
596696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                boolean overflowOnly) {
597696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            super(context, menu, anchorView, overflowOnly);
59811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            setCallback(mPopupPresenterCallback);
599696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
600696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
601696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        @Override
602696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        public void onDismiss() {
603696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            super.onDismiss();
604696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mMenu.close();
605696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mOverflowPopup = null;
606696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
607696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
608696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
609696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private class ActionButtonSubmenu extends MenuPopupHelper {
610696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        private SubMenuBuilder mSubMenu;
611696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
612696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) {
613696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            super(context, subMenu);
614696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mSubMenu = subMenu;
615696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
616696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            MenuItemImpl item = (MenuItemImpl) subMenu.getItem();
617696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (!item.isActionButton()) {
618696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                // Give a reasonable anchor to nested submenus.
619696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton);
620696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
62111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
62211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            setCallback(mPopupPresenterCallback);
6239151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell
6249151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell            boolean preserveIconSpacing = false;
6259151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell            final int count = subMenu.size();
6269151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell            for (int i = 0; i < count; i++) {
6279151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell                MenuItem childItem = subMenu.getItem(i);
6289151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell                if (childItem.isVisible() && childItem.getIcon() != null) {
6299151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell                    preserveIconSpacing = true;
6309151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell                    break;
6319151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell                }
6329151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell            }
6339151103ff20d28e8db2a2cc0386d57b8dad4b5d5Adam Powell            setForceShowIcon(preserveIconSpacing);
634696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
635696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
636696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        @Override
637696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        public void onDismiss() {
638696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            super.onDismiss();
639696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mActionButtonPopup = null;
64011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            mOpenSubMenuId = 0;
64111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
64211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    }
64311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
64411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    private class PopupPresenterCallback implements MenuPresenter.Callback {
64511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
64611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        @Override
64711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        public boolean onOpenSubMenu(MenuBuilder subMenu) {
648823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            if (subMenu == null) return false;
649823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell
65011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
65111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            return false;
65211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
65311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
65411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        @Override
65511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
656823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            if (menu instanceof SubMenuBuilder) {
657823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell                ((SubMenuBuilder) menu).getRootMenu().close(false);
658823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            }
659696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
660696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
661696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
662696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private class OpenOverflowRunnable implements Runnable {
663696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        private OverflowPopup mPopup;
664696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
665696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        public OpenOverflowRunnable(OverflowPopup popup) {
666696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mPopup = popup;
667696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
668696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
669696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        public void run() {
670696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            mMenu.changeMenuMode();
671678ed0c5a32bac1ea18a5ac99b0b814421ea79b4Adam Powell            final View menuView = (View) mMenuView;
672678ed0c5a32bac1ea18a5ac99b0b814421ea79b4Adam Powell            if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) {
673696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                mOverflowPopup = mPopup;
674696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
675678ed0c5a32bac1ea18a5ac99b0b814421ea79b4Adam Powell            mPostedOpenRunnable = null;
676696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
677696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
678696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell}
679