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 Powellpackage com.android.internal.view.menu;
17696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
18696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport com.android.internal.view.menu.MenuView.ItemView;
19696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
20696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.content.Context;
21696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.os.Bundle;
22696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.os.Parcelable;
23696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.util.SparseArray;
24696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.ContextThemeWrapper;
2511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powellimport android.view.MenuItem;
26696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.View;
27696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.ViewGroup;
28696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
29696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport java.util.ArrayList;
30696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
31696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell/**
32696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * MenuPresenter for the classic "six-pack" icon menu.
33696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */
34696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellpublic class IconMenuPresenter extends BaseMenuPresenter {
35696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private IconMenuItemView mMoreView;
36696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private int mMaxItems = -1;
37696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
3811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    int mOpenSubMenuId;
3911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    SubMenuPresenterCallback mSubMenuPresenterCallback = new SubMenuPresenterCallback();
4011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    MenuDialogHelper mOpenSubMenu;
4111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
42696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    private static final String VIEWS_TAG = "android:menu:icon";
4311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    private static final String OPEN_SUBMENU_KEY = "android:menu:icon:submenu";
44696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
45538e565c06e915b91e7e3a901f872ccdd9bccdd3Adam Powell    public IconMenuPresenter(Context context) {
46f2894659e8df625783afcd3fa17462ab23d29145Adam Powell        super(new ContextThemeWrapper(context, com.android.internal.R.style.Theme_IconMenu),
47f2894659e8df625783afcd3fa17462ab23d29145Adam Powell                com.android.internal.R.layout.icon_menu_layout,
48696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                com.android.internal.R.layout.icon_menu_item_layout);
49696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
50696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
51696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
52696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void initForMenu(Context context, MenuBuilder menu) {
53f2894659e8df625783afcd3fa17462ab23d29145Adam Powell        super.initForMenu(context, menu);
54696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mMaxItems = -1;
55696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
56696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
57696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
58696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void bindItemView(MenuItemImpl item, ItemView itemView) {
59696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final IconMenuItemView view = (IconMenuItemView) itemView;
60696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        view.setItemData(item);
61696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
62696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        view.initialize(item.getTitleForItemView(view), item.getIcon());
63696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
64696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        view.setVisibility(item.isVisible() ? View.VISIBLE : View.GONE);
65696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        view.setEnabled(view.isEnabled());
66696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        view.setLayoutParams(view.getTextAppropriateLayoutParams());
67696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
68696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
69696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
70696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) {
71696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final ArrayList<MenuItemImpl> itemsToShow = mMenu.getNonActionItems();
72696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        boolean fits = (itemsToShow.size() == mMaxItems && childIndex < mMaxItems) ||
73696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                childIndex < mMaxItems - 1;
74696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return fits && !item.isActionButton();
75696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
76696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
77696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
78696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    protected void addItemView(View itemView, int childIndex) {
79696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final IconMenuItemView v = (IconMenuItemView) itemView;
80696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final IconMenuView parent = (IconMenuView) mMenuView;
81696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
82696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        v.setIconMenuView(parent);
83696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        v.setItemInvoker(parent);
84696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        v.setBackgroundDrawable(parent.getItemBackgroundDrawable());
85696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        super.addItemView(itemView, childIndex);
86696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
87696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
88696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
89696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
90696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (!subMenu.hasVisibleItems()) return false;
91696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
92696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        // The window manager will give us a token.
9311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        MenuDialogHelper helper = new MenuDialogHelper(subMenu);
9411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        helper.setPresenterCallback(mSubMenuPresenterCallback);
9511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        helper.show(null);
9611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        mOpenSubMenu = helper;
9711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        mOpenSubMenuId = subMenu.getItem().getItemId();
98696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        super.onSubMenuSelected(subMenu);
99696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return true;
100696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
101696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
102696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
103696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void updateMenuView(boolean cleared) {
104696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final IconMenuView menuView = (IconMenuView) mMenuView;
105696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mMaxItems < 0) mMaxItems = menuView.getMaxItems();
106696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final ArrayList<MenuItemImpl> itemsToShow = mMenu.getNonActionItems();
107696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final boolean needsMore = itemsToShow.size() > mMaxItems;
108696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        super.updateMenuView(cleared);
109696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
110696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (needsMore && (mMoreView == null || mMoreView.getParent() != menuView)) {
111696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            if (mMoreView == null) {
112696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                mMoreView = menuView.createMoreItemView();
113696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                mMoreView.setBackgroundDrawable(menuView.getItemBackgroundDrawable());
114696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            }
115696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            menuView.addView(mMoreView);
116696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        } else if (!needsMore && mMoreView != null) {
117696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            menuView.removeView(mMoreView);
118696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
119696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
120696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        menuView.setNumActualItemsShown(needsMore ? mMaxItems - 1 : itemsToShow.size());
121696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
122696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
123696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
124696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    protected boolean filterLeftoverView(ViewGroup parent, int childIndex) {
125696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (parent.getChildAt(childIndex) != mMoreView) {
126696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            return super.filterLeftoverView(parent, childIndex);
127696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
128696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return false;
129696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
130696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
131696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public int getNumActualItemsShown() {
132696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return ((IconMenuView) mMenuView).getNumActualItemsShown();
133696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
134696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
135696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void saveHierarchyState(Bundle outState) {
136696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        SparseArray<Parcelable> viewStates = new SparseArray<Parcelable>();
137696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (mMenuView != null) {
138696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            ((View) mMenuView).saveHierarchyState(viewStates);
139696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
140696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        outState.putSparseParcelableArray(VIEWS_TAG, viewStates);
141696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
142696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
143696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void restoreHierarchyState(Bundle inState) {
144696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        SparseArray<Parcelable> viewStates = inState.getSparseParcelableArray(VIEWS_TAG);
145696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (viewStates != null) {
146696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            ((View) mMenuView).restoreHierarchyState(viewStates);
147696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
14811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        int subMenuId = inState.getInt(OPEN_SUBMENU_KEY, 0);
14911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        if (subMenuId > 0 && mMenu != null) {
15011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            MenuItem item = mMenu.findItem(subMenuId);
15111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            if (item != null) {
15211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell                onSubMenuSelected((SubMenuBuilder) item.getSubMenu());
15311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            }
15411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
15511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    }
15611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
15711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    @Override
15811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    public Parcelable onSaveInstanceState() {
15911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        if (mMenuView == null) {
16011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            return null;
16111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
16211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
16311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        Bundle state = new Bundle();
16411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        saveHierarchyState(state);
16511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        if (mOpenSubMenuId > 0) {
16611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            state.putInt(OPEN_SUBMENU_KEY, mOpenSubMenuId);
16711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
16811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        return state;
16911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    }
17011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
17111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    @Override
17211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    public void onRestoreInstanceState(Parcelable state) {
17311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        restoreHierarchyState((Bundle) state);
17411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    }
17511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
17611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell    class SubMenuPresenterCallback implements MenuPresenter.Callback {
17711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        @Override
17811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
17911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            mOpenSubMenuId = 0;
1809837d6d02fc0968614efe5260a176e0c406fe93cAdam Powell            if (mOpenSubMenu != null) {
1819837d6d02fc0968614efe5260a176e0c406fe93cAdam Powell                mOpenSubMenu.dismiss();
1829837d6d02fc0968614efe5260a176e0c406fe93cAdam Powell                mOpenSubMenu = null;
1839837d6d02fc0968614efe5260a176e0c406fe93cAdam Powell            }
18411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
18511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
18611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        @Override
18711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        public boolean onOpenSubMenu(MenuBuilder subMenu) {
188823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            if (subMenu != null) {
189823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell                mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
190823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell            }
19111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell            return false;
19211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell        }
19311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell
194696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
195696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell}
196