1bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/*
249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Copyright (C) 2014 The Android Open Source Project
3bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
4bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * you may not use this file except in compliance with the License.
6bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * You may obtain a copy of the License at
7bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
8bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
10bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Unless required by applicable law or agreed to in writing, software
11bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * See the License for the specific language governing permissions and
14bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * limitations under the License.
15bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */
16bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
1749c78900da0d43140fb602431fb93212bd7f6c70Chris Banespackage android.support.v7.widget;
18bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
19bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.Context;
20bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.Configuration;
21bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.Resources;
22ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banesimport android.graphics.drawable.Drawable;
23bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.os.Parcel;
24bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.os.Parcelable;
25ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banesimport android.support.v4.graphics.drawable.DrawableCompat;
2649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ActionProvider;
2749c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.GravityCompat;
28da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.appcompat.R;
2949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.transition.ActionBarTransition;
30da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.internal.view.ActionBarPolicy;
3149c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.ActionMenuItemView;
3249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.BaseMenuPresenter;
3349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuBuilder;
3449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuItemImpl;
3549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuPopupHelper;
3649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.MenuView;
3749c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.internal.view.menu.SubMenuBuilder;
38469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banesimport android.support.v7.internal.widget.TintImageView;
39bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.util.SparseBooleanArray;
4030837f1095c803f332f4a1c3f0917c8afdd50156Adam Powellimport android.view.MenuItem;
41bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.SoundEffectConstants;
42bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View;
43bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View.MeasureSpec;
44bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.ViewGroup;
45bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
46bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport java.util.ArrayList;
47bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
48bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/**
49bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * MenuPresenter for building action menus as seen in the action bar and action modes.
5089208232f3b5d1451408d787872504a190bc7ee0Chris Banes *
5189208232f3b5d1451408d787872504a190bc7ee0Chris Banes * @hide
52bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */
53bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellpublic class ActionMenuPresenter extends BaseMenuPresenter
5420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        implements ActionProvider.SubUiVisibilityListener {
55bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
5620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private static final String TAG = "ActionMenuPresenter";
57bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
5820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private View mOverflowButton;
5920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private boolean mReserveOverflow;
6020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private boolean mReserveOverflowSet;
6120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private int mWidthLimit;
6220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private int mActionItemWidthLimit;
6320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private int mMaxItems;
6420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private boolean mMaxItemsSet;
6520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private boolean mStrictWidthLimit;
6620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private boolean mWidthLimitSet;
6720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private boolean mExpandedActionViewsExclusive;
68bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
6920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private int mMinCellSize;
70bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
7120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    // Group IDs that have been added as actions - used temporarily, allocated here for reuse.
7220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray();
73bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
7420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private View mScrapActionButtonView;
75bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
7620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private OverflowPopup mOverflowPopup;
7720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private ActionButtonSubmenu mActionButtonPopup;
78bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
7920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private OpenOverflowRunnable mPostedOpenRunnable;
8049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private ActionMenuPopupCallback mPopupCallback;
81bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
8220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback();
8320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    int mOpenSubMenuId;
84bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
8520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public ActionMenuPresenter(Context context) {
86ee7c9fb199e9b9af8d40a1f9e27d85465acf8301Chris Banes        super(context, R.layout.abc_action_menu_layout, R.layout.abc_action_menu_item_layout);
87bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
88bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
8920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    @Override
9020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void initForMenu(Context context, MenuBuilder menu) {
9120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        super.initForMenu(context, menu);
92bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
9320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final Resources res = context.getResources();
94bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
9520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final ActionBarPolicy abp = ActionBarPolicy.get(context);
9620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (!mReserveOverflowSet) {
9720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mReserveOverflow = abp.showsOverflowMenuButton();
9820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
99bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
10020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (!mWidthLimitSet) {
10120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mWidthLimit = abp.getEmbeddedMenuWidthLimit();
10220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
103bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
10420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        // Measure for initial configuration
10520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (!mMaxItemsSet) {
10620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mMaxItems = abp.getMaxActionButtons();
10720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
108bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
10920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int width = mWidthLimit;
11020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mReserveOverflow) {
11120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (mOverflowButton == null) {
11220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                mOverflowButton = new OverflowMenuButton(mSystemContext);
11320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
11420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                mOverflowButton.measure(spec, spec);
11520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
11620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            width -= mOverflowButton.getMeasuredWidth();
11720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        } else {
11820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mOverflowButton = null;
11920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
120bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
12120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mActionItemWidthLimit = width;
122bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
12320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density);
124bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
12520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        // Drop a scrap view as it may no longer reflect the proper context/config.
12620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mScrapActionButtonView = null;
127bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
12820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
12920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void onConfigurationChanged(Configuration newConfig) {
13020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (!mMaxItemsSet) {
13120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mMaxItems = mContext.getResources().getInteger(
13207a07ce59efb770e9fb9ca53a0133e5e64a63bbcChris Banes                    R.integer.abc_max_action_buttons);
133bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        }
13420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mMenu != null) {
135d900fe072335d488f883585e3f686ef955d1ccc9Chris Banes            mMenu.onItemsChanged(true);
136bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        }
13720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
138bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
13920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void setWidthLimit(int width, boolean strict) {
14020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mWidthLimit = width;
14120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mStrictWidthLimit = strict;
14220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mWidthLimitSet = true;
143bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
144bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
14520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void setReserveOverflow(boolean reserveOverflow) {
14620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mReserveOverflow = reserveOverflow;
14720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mReserveOverflowSet = true;
14820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
149bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
15020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void setItemLimit(int itemCount) {
15120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mMaxItems = itemCount;
15220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mMaxItemsSet = true;
15320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
154bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
15520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void setExpandedActionViewsExclusive(boolean isExclusive) {
15620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mExpandedActionViewsExclusive = isExclusive;
157bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
158bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
15920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    @Override
16020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public MenuView getMenuView(ViewGroup root) {
16120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        MenuView result = super.getMenuView(root);
16220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        ((ActionMenuView) result).setPresenter(this);
16320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return result;
164bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
165bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
16620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    @Override
16749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public View getItemView(final MenuItemImpl item, View convertView, ViewGroup parent) {
16820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        View actionView = item.getActionView();
16920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (actionView == null || item.hasCollapsibleActionView()) {
17020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            actionView = super.getItemView(item, convertView, parent);
17120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
17220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE);
173bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
17420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final ActionMenuView menuParent = (ActionMenuView) parent;
17520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
17620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (!menuParent.checkLayoutParams(lp)) {
17720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            actionView.setLayoutParams(menuParent.generateLayoutParams(lp));
17820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
17920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return actionView;
180bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
181bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
18220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    @Override
18320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) {
18420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        itemView.initialize(item, 0);
18520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
18620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final ActionMenuView menuView = (ActionMenuView) mMenuView;
18749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        final ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
18881173a86853974bb27d4197a0f0768922f8205caTrevor Johns        actionItemView.setItemInvoker(menuView);
18949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
19049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (mPopupCallback == null) {
19149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mPopupCallback = new ActionMenuPopupCallback();
19249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
19349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        actionItemView.setPopupCallback(mPopupCallback);
194bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
195bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
196bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    @Override
19720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) {
19820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return item.isActionButton();
199bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
200bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
201bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    @Override
20220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void updateMenuView(boolean cleared) {
20349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        final ViewGroup menuViewParent = (ViewGroup) ((View) mMenuView).getParent();
20449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (menuViewParent != null) {
20549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            ActionBarTransition.beginDelayedTransition(menuViewParent);
20649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
20720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        super.updateMenuView(cleared);
20820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
20949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        ((View) mMenuView).requestLayout();
210176a17e30644b1d5a4206cc462268d151e43949bChris Banes
21120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mMenu != null) {
21220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            final ArrayList<MenuItemImpl> actionItems = mMenu.getActionItems();
21320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            final int count = actionItems.size();
21420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            for (int i = 0; i < count; i++) {
21530837f1095c803f332f4a1c3f0917c8afdd50156Adam Powell                final ActionProvider provider = actionItems.get(i).getSupportActionProvider();
21620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                if (provider != null) {
21720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    provider.setSubUiVisibilityListener(this);
21820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                }
21920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
22020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
221bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
22220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final ArrayList<MenuItemImpl> nonActionItems = mMenu != null ?
22320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                mMenu.getNonActionItems() : null;
224bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
22520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        boolean hasOverflow = false;
22620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mReserveOverflow && nonActionItems != null) {
22720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            final int count = nonActionItems.size();
22820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (count == 1) {
22920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                hasOverflow = !nonActionItems.get(0).isActionViewExpanded();
23020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            } else {
23120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                hasOverflow = count > 0;
23220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
23320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
234bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
23520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (hasOverflow) {
23620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (mOverflowButton == null) {
23720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                mOverflowButton = new OverflowMenuButton(mSystemContext);
23820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
23920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            ViewGroup parent = (ViewGroup) mOverflowButton.getParent();
24020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (parent != mMenuView) {
24120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                if (parent != null) {
24220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    parent.removeView(mOverflowButton);
24320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                }
24420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                ActionMenuView menuView = (ActionMenuView) mMenuView;
24520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams());
24620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
24720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) {
24820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            ((ViewGroup) mMenuView).removeView(mOverflowButton);
24920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
250bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
25120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        ((ActionMenuView) mMenuView).setOverflowReserved(mReserveOverflow);
252bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
253bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
254bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    @Override
25520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean filterLeftoverView(ViewGroup parent, int childIndex) {
25649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (parent.getChildAt(childIndex) == mOverflowButton) return false;
25720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return super.filterLeftoverView(parent, childIndex);
25820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
25920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
26020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
26149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (!subMenu.hasVisibleItems()) return false;
26220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
26320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        SubMenuBuilder topSubMenu = subMenu;
26420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        while (topSubMenu.getParentMenu() != mMenu) {
26520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            topSubMenu = (SubMenuBuilder) topSubMenu.getParentMenu();
26620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
26720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        View anchor = findViewForItem(topSubMenu.getItem());
26820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (anchor == null) {
26949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (mOverflowButton == null) return false;
27020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            anchor = mOverflowButton;
27120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
27220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
27320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mOpenSubMenuId = subMenu.getItem().getItemId();
27449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu);
27549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mActionButtonPopup.setAnchorView(anchor);
27649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mActionButtonPopup.show();
27720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        super.onSubMenuSelected(subMenu);
278bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        return true;
27920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
28020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
28120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private View findViewForItem(MenuItem item) {
28220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final ViewGroup parent = (ViewGroup) mMenuView;
28349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (parent == null) return null;
28420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
28520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final int count = parent.getChildCount();
28620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        for (int i = 0; i < count; i++) {
28720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            final View child = parent.getChildAt(i);
28820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (child instanceof MenuView.ItemView &&
28920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    ((MenuView.ItemView) child).getItemData() == item) {
29020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                return child;
29120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
29220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
29320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return null;
29420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
29520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
29620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    /**
29720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Display the overflow menu if one is present.
29820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return true if the overflow menu was shown, false otherwise.
29920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     */
30020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean showOverflowMenu() {
30120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null &&
30249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) {
30320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true);
30420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mPostedOpenRunnable = new OpenOverflowRunnable(popup);
30520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            // Post this for later; we might still need a layout for the anchor to be right.
30620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            ((View) mMenuView).post(mPostedOpenRunnable);
30720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
30820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            // ActionMenuPresenter uses null as a callback argument here
30920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            // to indicate overflow is opening.
31020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            super.onSubMenuSelected(null);
31120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
31220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return true;
31320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
31420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return false;
31520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
31620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
31720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    /**
31820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Hide the overflow menu if it is currently showing.
31920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *
32020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return true if the overflow menu was hidden, false otherwise.
32120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     */
32220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean hideOverflowMenu() {
32320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mPostedOpenRunnable != null && mMenuView != null) {
32420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            ((View) mMenuView).removeCallbacks(mPostedOpenRunnable);
32520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mPostedOpenRunnable = null;
32620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return true;
32720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
32820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
32920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        MenuPopupHelper popup = mOverflowPopup;
33020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (popup != null) {
33120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            popup.dismiss();
33220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return true;
33320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
33420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return false;
33520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
33620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
33720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    /**
33820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Dismiss all popup menus - overflow and submenus.
33920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return true if popups were dismissed, false otherwise. (This can be because none were open.)
34020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     */
34120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean dismissPopupMenus() {
34220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        boolean result = hideOverflowMenu();
34320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        result |= hideSubMenus();
34420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return result;
34520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
34620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
34720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    /**
34820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Dismiss all submenu popups.
34920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *
35020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return true if popups were dismissed, false otherwise. (This can be because none were open.)
35120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     */
35220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean hideSubMenus() {
35320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mActionButtonPopup != null) {
35420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mActionButtonPopup.dismiss();
35520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return true;
35620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
35720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return false;
35820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
35920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
36020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    /**
36120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return true if the overflow menu is currently showing
36220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     */
36320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean isOverflowMenuShowing() {
36420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return mOverflowPopup != null && mOverflowPopup.isShowing();
36520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
36620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
36749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public boolean isOverflowMenuShowPending() {
36849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return mPostedOpenRunnable != null || isOverflowMenuShowing();
36949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
37049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
37120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    /**
37220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return true if space has been reserved in the action menu for an overflow item.
37320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     */
37420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean isOverflowReserved() {
37520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return mReserveOverflow;
37620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
37720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
37820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean flagActionItems() {
37920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems();
38020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final int itemsSize = visibleItems.size();
38120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int maxActions = mMaxItems;
38220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int widthLimit = mActionItemWidthLimit;
38320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
38420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final ViewGroup parent = (ViewGroup) mMenuView;
38520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
38620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int requiredItems = 0;
38720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int requestedItems = 0;
38820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int firstActionWidth = 0;
38920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        boolean hasOverflow = false;
39020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        for (int i = 0; i < itemsSize; i++) {
39120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            MenuItemImpl item = visibleItems.get(i);
39220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (item.requiresActionButton()) {
39320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                requiredItems++;
39420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            } else if (item.requestsActionButton()) {
39520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                requestedItems++;
39620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            } else {
39720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                hasOverflow = true;
39820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
39920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (mExpandedActionViewsExclusive && item.isActionViewExpanded()) {
40020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                // Overflow everything if we have an expanded action view and we're
40120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                // space constrained.
40220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                maxActions = 0;
40320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
40420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
40520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
40620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        // Reserve a spot for the overflow item if needed.
40720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mReserveOverflow &&
40820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                (hasOverflow || requiredItems + requestedItems > maxActions)) {
40920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            maxActions--;
41020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
41120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        maxActions -= requiredItems;
412bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
41320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        final SparseBooleanArray seenGroups = mActionButtonGroups;
41420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        seenGroups.clear();
41520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
41620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int cellSize = 0;
41720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int cellsRemaining = 0;
41820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mStrictWidthLimit) {
41920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            cellsRemaining = widthLimit / mMinCellSize;
42020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            final int cellSizeRemaining = widthLimit % mMinCellSize;
42120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining;
42220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
42320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
42420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        // Flag as many more requested items as will fit.
42520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        for (int i = 0; i < itemsSize; i++) {
42620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            MenuItemImpl item = visibleItems.get(i);
42720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
42820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (item.requiresActionButton()) {
42920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                View v = getItemView(item, mScrapActionButtonView, parent);
43020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                if (mScrapActionButtonView == null) {
43120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    mScrapActionButtonView = v;
43220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                }
43320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                if (mStrictWidthLimit) {
43420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    cellsRemaining -= ActionMenuView.measureChildForCells(v,
43520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                            cellSize, cellsRemaining, querySpec, 0);
43620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                } else {
43720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    v.measure(querySpec, querySpec);
43820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                }
43920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                final int measuredWidth = v.getMeasuredWidth();
44020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                widthLimit -= measuredWidth;
44120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                if (firstActionWidth == 0) {
44220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    firstActionWidth = measuredWidth;
44320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                }
44420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                final int groupId = item.getGroupId();
44520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                if (groupId != 0) {
44620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    seenGroups.put(groupId, true);
44720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                }
44820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                item.setIsActionButton(true);
44920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            } else if (item.requestsActionButton()) {
45020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                // Items in a group with other items that already have an action slot
45120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                // can break the max actions rule, but not the width limit.
45220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                final int groupId = item.getGroupId();
45320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                final boolean inGroup = seenGroups.get(groupId);
45420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 &&
45520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        (!mStrictWidthLimit || cellsRemaining > 0);
45620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
45720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                if (isAction) {
45820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    View v = getItemView(item, mScrapActionButtonView, parent);
45920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    if (mScrapActionButtonView == null) {
46020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        mScrapActionButtonView = v;
46120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    }
46220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    if (mStrictWidthLimit) {
46320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        final int cells = ActionMenuView.measureChildForCells(v,
46420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                                cellSize, cellsRemaining, querySpec, 0);
46520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        cellsRemaining -= cells;
46620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        if (cells == 0) {
46720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                            isAction = false;
46820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        }
46920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    } else {
47020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        v.measure(querySpec, querySpec);
47120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    }
47220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    final int measuredWidth = v.getMeasuredWidth();
47320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    widthLimit -= measuredWidth;
47420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    if (firstActionWidth == 0) {
47520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        firstActionWidth = measuredWidth;
47620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    }
47720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
47820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    if (mStrictWidthLimit) {
47920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        isAction &= widthLimit >= 0;
48020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    } else {
48120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        // Did this push the entire first item past the limit?
48220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        isAction &= widthLimit + firstActionWidth > 0;
48320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    }
48420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                }
48520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
48620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                if (isAction && groupId != 0) {
48720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    seenGroups.put(groupId, true);
48820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                } else if (inGroup) {
48920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    // We broke the width limit. Demote the whole group, they all overflow now.
49020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    seenGroups.put(groupId, false);
49120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    for (int j = 0; j < i; j++) {
49220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        MenuItemImpl areYouMyGroupie = visibleItems.get(j);
49320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        if (areYouMyGroupie.getGroupId() == groupId) {
49420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                            // Give back the action slot
49549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                            if (areYouMyGroupie.isActionButton()) maxActions++;
49620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                            areYouMyGroupie.setIsActionButton(false);
49720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                        }
49820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                    }
49920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                }
50020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
50149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                if (isAction) maxActions--;
50220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
50320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                item.setIsActionButton(isAction);
50449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            } else {
50549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                // Neither requires nor requests an action button.
50649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                item.setIsActionButton(false);
50720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
50820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
50920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return true;
510bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
511bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
51220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    @Override
51320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
51420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        dismissPopupMenus();
51520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        super.onCloseMenu(menu, allMenusAreClosing);
516bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
517bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
51820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    @Override
51920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public Parcelable onSaveInstanceState() {
52020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        SavedState state = new SavedState();
52120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        state.openSubMenuId = mOpenSubMenuId;
52220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return state;
523bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
524bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
52520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    @Override
52620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void onRestoreInstanceState(Parcelable state) {
52720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        SavedState saved = (SavedState) state;
52820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (saved.openSubMenuId > 0) {
52920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            MenuItem item = mMenu.findItem(saved.openSubMenuId);
53020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (item != null) {
53120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu();
53220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                onSubMenuSelected(subMenu);
53320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
53420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
535bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
536bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
537bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    @Override
53820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void onSubUiVisibilityChanged(boolean isVisible) {
53920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (isVisible) {
54020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            // Not a submenu, but treat it like one.
54120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            super.onSubMenuSelected(null);
54220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        } else {
54320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mMenu.close(false);
54420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
545bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
546bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
54749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setMenuView(ActionMenuView menuView) {
54849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mMenuView = menuView;
54949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        menuView.initialize(mMenu);
55049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
551bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
55249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private static class SavedState implements Parcelable {
55320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public int openSubMenuId;
554bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
55520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        SavedState() {
55620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
557bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
55820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        SavedState(Parcel in) {
55920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            openSubMenuId = in.readInt();
56020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
56120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
56220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        @Override
56320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public int describeContents() {
56420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return 0;
56520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
566bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
56720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        @Override
56820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public void writeToParcel(Parcel dest, int flags) {
56920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            dest.writeInt(openSubMenuId);
570bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell        }
57120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
57220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public static final Parcelable.Creator<SavedState> CREATOR
57320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                = new Parcelable.Creator<SavedState>() {
57420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            public SavedState createFromParcel(Parcel in) {
57520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                return new SavedState(in);
57620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
57720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
57820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            public SavedState[] newArray(int size) {
57920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                return new SavedState[size];
58020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
58120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        };
582bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
583bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
584469286122bcbbecbdd0bef74fb50f9d8920e77b9Chris Banes    private class OverflowMenuButton extends TintImageView implements ActionMenuView.ActionMenuChildView {
5850517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes        private final float[] mTempPts = new float[2];
5860517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes
58720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public OverflowMenuButton(Context context) {
58820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            super(context, null, R.attr.actionOverflowButtonStyle);
58920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
59020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            setClickable(true);
59120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            setFocusable(true);
59220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            setVisibility(VISIBLE);
59320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            setEnabled(true);
5940517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes
59549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            setOnTouchListener(new ListPopupWindow.ForwardingListener(this) {
59649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                @Override
59749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                public ListPopupWindow getPopup() {
59849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    if (mOverflowPopup == null) {
59949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                        return null;
60049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    }
60149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
60249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    return mOverflowPopup.getPopup();
60349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                }
60449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
60549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                @Override
60649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                public boolean onForwardingStarted() {
60749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    showOverflowMenu();
60849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    return true;
60949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                }
61049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
61149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                @Override
61249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                public boolean onForwardingStopped() {
61349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    // Displaying the popup occurs asynchronously, so wait for
61449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    // the runnable to finish before deciding whether to stop
61549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    // forwarding.
61649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    if (mPostedOpenRunnable != null) {
61749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                        return false;
61849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    }
61949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
62049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    hideOverflowMenu();
62149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    return true;
62249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                }
62349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            });
62420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
62520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
62620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        @Override
62720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public boolean performClick() {
62820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (super.performClick()) {
62920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                return true;
63020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
63120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
63220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            playSoundEffect(SoundEffectConstants.CLICK);
63320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            showOverflowMenu();
63420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return true;
63520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
63620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
63749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        @Override
63820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public boolean needsDividerBefore() {
63920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return false;
64020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
64120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
64249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        @Override
64320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public boolean needsDividerAfter() {
64420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return false;
64520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
646ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes
647ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes        @Override
6480517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes        protected boolean setFrame(int l, int t, int r, int b) {
6490517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes            final boolean changed = super.setFrame(l, t, r, b);
650ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes
651ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes            // Set up the hotspot bounds to be centered on the image.
652ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes            final Drawable d = getDrawable();
653ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes            final Drawable bg = getBackground();
654ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes            if (d != null && bg != null) {
6550517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes                final float[] pts = mTempPts;
6560517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes                pts[0] = d.getBounds().centerX();
6570517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes                getImageMatrix().mapPoints(pts);
6580517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes                final int offset =  (int) pts[0] - getWidth() / 2;
6590517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes                DrawableCompat.setHotspotBounds(bg, offset, 0, getWidth() + offset, getHeight());
660ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes            }
6610517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes
6620517b282bde8b9a0377dfe5bc4756405a196adb4Chris Banes            return changed;
663ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes        }
664bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
665bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
66620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private class OverflowPopup extends MenuPopupHelper {
667bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
66820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public OverflowPopup(Context context, MenuBuilder menu, View anchorView,
66920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                boolean overflowOnly) {
67049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            super(context, menu, anchorView, overflowOnly, R.attr.actionOverflowMenuStyle);
67149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            setGravity(GravityCompat.END);
67220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            setCallback(mPopupPresenterCallback);
67320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
674bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
67520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        @Override
67620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public void onDismiss() {
67720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            super.onDismiss();
67820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mMenu.close();
67920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mOverflowPopup = null;
68020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
681bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
682bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
68349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private class ActionButtonSubmenu extends MenuPopupHelper {
68449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        private SubMenuBuilder mSubMenu;
68549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
68649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) {
68749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            super(context, subMenu, null, false,
68849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    R.attr.actionOverflowMenuStyle);
68949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mSubMenu = subMenu;
69049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
69149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            MenuItemImpl item = (MenuItemImpl) subMenu.getItem();
69249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (!item.isActionButton()) {
69349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                // Give a reasonable anchor to nested submenus.
69449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton);
69549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
69620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
69720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            setCallback(mPopupPresenterCallback);
69849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
69949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            boolean preserveIconSpacing = false;
70049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            final int count = subMenu.size();
70149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            for (int i = 0; i < count; i++) {
70249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                MenuItem childItem = subMenu.getItem(i);
70349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                if (childItem.isVisible() && childItem.getIcon() != null) {
70449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    preserveIconSpacing = true;
70549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    break;
70649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                }
70749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
70849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            setForceShowIcon(preserveIconSpacing);
70920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
71020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
71120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        @Override
71249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        public void onDismiss() {
71349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            super.onDismiss();
71420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mActionButtonPopup = null;
71520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mOpenSubMenuId = 0;
71620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
717bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
718bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
71949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private class PopupPresenterCallback implements Callback {
72020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
72120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        @Override
72220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public boolean onOpenSubMenu(MenuBuilder subMenu) {
72349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (subMenu == null) return false;
72420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
72520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
72649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            final Callback cb = getCallback();
72749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            return cb != null ? cb.onOpenSubMenu(subMenu) : false;
72820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
729bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
73020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        @Override
73120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
73220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (menu instanceof SubMenuBuilder) {
73320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                ((SubMenuBuilder) menu).getRootMenu().close(false);
73420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
73549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            final Callback cb = getCallback();
73649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (cb != null) {
73749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                cb.onCloseMenu(menu, allMenusAreClosing);
73849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
73920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
740bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
741bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
74220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private class OpenOverflowRunnable implements Runnable {
74320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        private OverflowPopup mPopup;
74420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
74520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public OpenOverflowRunnable(OverflowPopup popup) {
74620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mPopup = popup;
74720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
74820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
74920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        public void run() {
75020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mMenu.changeMenuMode();
75120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            final View menuView = (View) mMenuView;
75220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) {
75320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                mOverflowPopup = mPopup;
75420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
75520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mPostedOpenRunnable = null;
75620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
757bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell    }
75849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
75949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private class ActionMenuPopupCallback extends ActionMenuItemView.PopupCallback {
76049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        @Override
76149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        public ListPopupWindow getPopup() {
76249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null;
76349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
76449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
765bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell}
766