IconMenuPresenter.java revision 823f074a73cfc23c40a7b576c71daa096ee9ed6a
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; 25696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.LayoutInflater; 2611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powellimport android.view.MenuItem; 27696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.View; 28696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport android.view.ViewGroup; 29696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 30696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellimport java.util.ArrayList; 31696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 32696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell/** 33696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell * MenuPresenter for the classic "six-pack" icon menu. 34696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell */ 35696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellpublic class IconMenuPresenter extends BaseMenuPresenter { 36696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private IconMenuItemView mMoreView; 37696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private int mMaxItems = -1; 38696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 3911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell int mOpenSubMenuId; 4011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell SubMenuPresenterCallback mSubMenuPresenterCallback = new SubMenuPresenterCallback(); 4111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell MenuDialogHelper mOpenSubMenu; 4211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 43696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell private static final String VIEWS_TAG = "android:menu:icon"; 4411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell private static final String OPEN_SUBMENU_KEY = "android:menu:icon:submenu"; 45696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 46696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public IconMenuPresenter() { 47696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super(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) { 53696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mContext = new ContextThemeWrapper(context, com.android.internal.R.style.Theme_IconMenu); 54696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mInflater = LayoutInflater.from(mContext); 55696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mMenu = menu; 56696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mMaxItems = -1; 57696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 58696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 59696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 60696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void bindItemView(MenuItemImpl item, ItemView itemView) { 61696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final IconMenuItemView view = (IconMenuItemView) itemView; 62696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell view.setItemData(item); 63696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 64696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell view.initialize(item.getTitleForItemView(view), item.getIcon()); 65696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 66696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell view.setVisibility(item.isVisible() ? View.VISIBLE : View.GONE); 67696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell view.setEnabled(view.isEnabled()); 68696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell view.setLayoutParams(view.getTextAppropriateLayoutParams()); 69696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 70696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 71696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 72696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { 73696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final ArrayList<MenuItemImpl> itemsToShow = mMenu.getNonActionItems(); 74696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell boolean fits = (itemsToShow.size() == mMaxItems && childIndex < mMaxItems) || 75696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell childIndex < mMaxItems - 1; 76696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return fits && !item.isActionButton(); 77696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 78696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 79696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 80696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell protected void addItemView(View itemView, int childIndex) { 81696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final IconMenuItemView v = (IconMenuItemView) itemView; 82696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final IconMenuView parent = (IconMenuView) mMenuView; 83696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 84696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell v.setIconMenuView(parent); 85696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell v.setItemInvoker(parent); 86696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell v.setBackgroundDrawable(parent.getItemBackgroundDrawable()); 87696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super.addItemView(itemView, childIndex); 88696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 89696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 90696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 91696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean onSubMenuSelected(SubMenuBuilder subMenu) { 92696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (!subMenu.hasVisibleItems()) return false; 93696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 94696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell // The window manager will give us a token. 9511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell MenuDialogHelper helper = new MenuDialogHelper(subMenu); 9611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell helper.setPresenterCallback(mSubMenuPresenterCallback); 9711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell helper.show(null); 9811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell mOpenSubMenu = helper; 9911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell mOpenSubMenuId = subMenu.getItem().getItemId(); 100696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super.onSubMenuSelected(subMenu); 101696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return true; 102696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 103696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 104696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 105696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void updateMenuView(boolean cleared) { 106696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final IconMenuView menuView = (IconMenuView) mMenuView; 107696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (mMaxItems < 0) mMaxItems = menuView.getMaxItems(); 108696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final ArrayList<MenuItemImpl> itemsToShow = mMenu.getNonActionItems(); 109696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final boolean needsMore = itemsToShow.size() > mMaxItems; 110696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell super.updateMenuView(cleared); 111696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 112696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (needsMore && (mMoreView == null || mMoreView.getParent() != menuView)) { 113696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (mMoreView == null) { 114696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mMoreView = menuView.createMoreItemView(); 115696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mMoreView.setBackgroundDrawable(menuView.getItemBackgroundDrawable()); 116696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 117696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell menuView.addView(mMoreView); 118696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } else if (!needsMore && mMoreView != null) { 119696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell menuView.removeView(mMoreView); 120696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 121696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 122696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell menuView.setNumActualItemsShown(needsMore ? mMaxItems - 1 : itemsToShow.size()); 123696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 124696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 125696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 126696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell protected boolean filterLeftoverView(ViewGroup parent, int childIndex) { 127696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (parent.getChildAt(childIndex) != mMoreView) { 128696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return super.filterLeftoverView(parent, childIndex); 129696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 130696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return false; 131696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 132696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 133696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public int getNumActualItemsShown() { 134696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return ((IconMenuView) mMenuView).getNumActualItemsShown(); 135696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 136696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 137696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void saveHierarchyState(Bundle outState) { 138696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell SparseArray<Parcelable> viewStates = new SparseArray<Parcelable>(); 139696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (mMenuView != null) { 140696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell ((View) mMenuView).saveHierarchyState(viewStates); 141696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 142696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell outState.putSparseParcelableArray(VIEWS_TAG, viewStates); 143696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 144696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 145696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void restoreHierarchyState(Bundle inState) { 146696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell SparseArray<Parcelable> viewStates = inState.getSparseParcelableArray(VIEWS_TAG); 147696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (viewStates != null) { 148696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell ((View) mMenuView).restoreHierarchyState(viewStates); 149696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 15011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell int subMenuId = inState.getInt(OPEN_SUBMENU_KEY, 0); 15111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell if (subMenuId > 0 && mMenu != null) { 15211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell MenuItem item = mMenu.findItem(subMenuId); 15311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell if (item != null) { 15411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell onSubMenuSelected((SubMenuBuilder) item.getSubMenu()); 15511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 15611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 15711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 15811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 15911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell @Override 16011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public Parcelable onSaveInstanceState() { 16111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell if (mMenuView == null) { 16211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell return null; 16311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 16411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 16511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell Bundle state = new Bundle(); 16611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell saveHierarchyState(state); 16711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell if (mOpenSubMenuId > 0) { 16811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell state.putInt(OPEN_SUBMENU_KEY, mOpenSubMenuId); 16911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 17011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell return state; 17111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 17211ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 17311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell @Override 17411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public void onRestoreInstanceState(Parcelable state) { 17511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell restoreHierarchyState((Bundle) state); 17611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 17711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 17811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell class SubMenuPresenterCallback implements MenuPresenter.Callback { 17911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell @Override 18011ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 18111ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell mOpenSubMenuId = 0; 1829837d6d02fc0968614efe5260a176e0c406fe93cAdam Powell if (mOpenSubMenu != null) { 1839837d6d02fc0968614efe5260a176e0c406fe93cAdam Powell mOpenSubMenu.dismiss(); 1849837d6d02fc0968614efe5260a176e0c406fe93cAdam Powell mOpenSubMenu = null; 1859837d6d02fc0968614efe5260a176e0c406fe93cAdam Powell } 18611ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 18711ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 18811ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell @Override 18911ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell public boolean onOpenSubMenu(MenuBuilder subMenu) { 190823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell if (subMenu != null) { 191823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); 192823f074a73cfc23c40a7b576c71daa096ee9ed6aAdam Powell } 19311ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell return false; 19411ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell } 19511ed1d6cae9214335c92ac38498a4e6c7d1c8324Adam Powell 196696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 197696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell} 198