/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.view.menu; import com.android.internal.view.menu.MenuView.ItemView; import android.content.Context; import android.os.Bundle; import android.os.Parcelable; import android.util.SparseArray; import android.view.ContextThemeWrapper; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; /** * MenuPresenter for the classic "six-pack" icon menu. */ public class IconMenuPresenter extends BaseMenuPresenter { private IconMenuItemView mMoreView; private int mMaxItems = -1; int mOpenSubMenuId; SubMenuPresenterCallback mSubMenuPresenterCallback = new SubMenuPresenterCallback(); MenuDialogHelper mOpenSubMenu; private static final String VIEWS_TAG = "android:menu:icon"; private static final String OPEN_SUBMENU_KEY = "android:menu:icon:submenu"; public IconMenuPresenter(Context context) { super(new ContextThemeWrapper(context, com.android.internal.R.style.Theme_IconMenu), com.android.internal.R.layout.icon_menu_layout, com.android.internal.R.layout.icon_menu_item_layout); } @Override public void initForMenu(Context context, MenuBuilder menu) { super.initForMenu(context, menu); mMaxItems = -1; } @Override public void bindItemView(MenuItemImpl item, ItemView itemView) { final IconMenuItemView view = (IconMenuItemView) itemView; view.setItemData(item); view.initialize(item.getTitleForItemView(view), item.getIcon()); view.setVisibility(item.isVisible() ? View.VISIBLE : View.GONE); view.setEnabled(view.isEnabled()); view.setLayoutParams(view.getTextAppropriateLayoutParams()); } @Override public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { final ArrayList<MenuItemImpl> itemsToShow = mMenu.getNonActionItems(); boolean fits = (itemsToShow.size() == mMaxItems && childIndex < mMaxItems) || childIndex < mMaxItems - 1; return fits && !item.isActionButton(); } @Override protected void addItemView(View itemView, int childIndex) { final IconMenuItemView v = (IconMenuItemView) itemView; final IconMenuView parent = (IconMenuView) mMenuView; v.setIconMenuView(parent); v.setItemInvoker(parent); v.setBackgroundDrawable(parent.getItemBackgroundDrawable()); super.addItemView(itemView, childIndex); } @Override public boolean onSubMenuSelected(SubMenuBuilder subMenu) { if (!subMenu.hasVisibleItems()) return false; // The window manager will give us a token. MenuDialogHelper helper = new MenuDialogHelper(subMenu); helper.setPresenterCallback(mSubMenuPresenterCallback); helper.show(null); mOpenSubMenu = helper; mOpenSubMenuId = subMenu.getItem().getItemId(); super.onSubMenuSelected(subMenu); return true; } @Override public void updateMenuView(boolean cleared) { final IconMenuView menuView = (IconMenuView) mMenuView; if (mMaxItems < 0) mMaxItems = menuView.getMaxItems(); final ArrayList<MenuItemImpl> itemsToShow = mMenu.getNonActionItems(); final boolean needsMore = itemsToShow.size() > mMaxItems; super.updateMenuView(cleared); if (needsMore && (mMoreView == null || mMoreView.getParent() != menuView)) { if (mMoreView == null) { mMoreView = menuView.createMoreItemView(); mMoreView.setBackgroundDrawable(menuView.getItemBackgroundDrawable()); } menuView.addView(mMoreView); } else if (!needsMore && mMoreView != null) { menuView.removeView(mMoreView); } menuView.setNumActualItemsShown(needsMore ? mMaxItems - 1 : itemsToShow.size()); } @Override protected boolean filterLeftoverView(ViewGroup parent, int childIndex) { if (parent.getChildAt(childIndex) != mMoreView) { return super.filterLeftoverView(parent, childIndex); } return false; } public int getNumActualItemsShown() { return ((IconMenuView) mMenuView).getNumActualItemsShown(); } public void saveHierarchyState(Bundle outState) { SparseArray<Parcelable> viewStates = new SparseArray<Parcelable>(); if (mMenuView != null) { ((View) mMenuView).saveHierarchyState(viewStates); } outState.putSparseParcelableArray(VIEWS_TAG, viewStates); } public void restoreHierarchyState(Bundle inState) { SparseArray<Parcelable> viewStates = inState.getSparseParcelableArray(VIEWS_TAG); if (viewStates != null) { ((View) mMenuView).restoreHierarchyState(viewStates); } int subMenuId = inState.getInt(OPEN_SUBMENU_KEY, 0); if (subMenuId > 0 && mMenu != null) { MenuItem item = mMenu.findItem(subMenuId); if (item != null) { onSubMenuSelected((SubMenuBuilder) item.getSubMenu()); } } } @Override public Parcelable onSaveInstanceState() { if (mMenuView == null) { return null; } Bundle state = new Bundle(); saveHierarchyState(state); if (mOpenSubMenuId > 0) { state.putInt(OPEN_SUBMENU_KEY, mOpenSubMenuId); } return state; } @Override public void onRestoreInstanceState(Parcelable state) { restoreHierarchyState((Bundle) state); } class SubMenuPresenterCallback implements MenuPresenter.Callback { @Override public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { mOpenSubMenuId = 0; if (mOpenSubMenu != null) { mOpenSubMenu.dismiss(); mOpenSubMenu = null; } } @Override public boolean onOpenSubMenu(MenuBuilder subMenu) { if (subMenu != null) { mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId(); } return false; } } }