Home | History | Annotate | Download | only in menu
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.internal.view.menu;
     17 
     18 import com.android.internal.view.menu.MenuView.ItemView;
     19 
     20 import android.content.Context;
     21 import android.os.Bundle;
     22 import android.os.Parcelable;
     23 import android.util.SparseArray;
     24 import android.view.ContextThemeWrapper;
     25 import android.view.MenuItem;
     26 import android.view.View;
     27 import android.view.ViewGroup;
     28 
     29 import java.util.ArrayList;
     30 
     31 /**
     32  * MenuPresenter for the classic "six-pack" icon menu.
     33  */
     34 public class IconMenuPresenter extends BaseMenuPresenter {
     35     private IconMenuItemView mMoreView;
     36     private int mMaxItems = -1;
     37 
     38     int mOpenSubMenuId;
     39     SubMenuPresenterCallback mSubMenuPresenterCallback = new SubMenuPresenterCallback();
     40     MenuDialogHelper mOpenSubMenu;
     41 
     42     private static final String VIEWS_TAG = "android:menu:icon";
     43     private static final String OPEN_SUBMENU_KEY = "android:menu:icon:submenu";
     44 
     45     public IconMenuPresenter(Context context) {
     46         super(new ContextThemeWrapper(context, com.android.internal.R.style.Theme_IconMenu),
     47                 com.android.internal.R.layout.icon_menu_layout,
     48                 com.android.internal.R.layout.icon_menu_item_layout);
     49     }
     50 
     51     @Override
     52     public void initForMenu(Context context, MenuBuilder menu) {
     53         super.initForMenu(context, menu);
     54         mMaxItems = -1;
     55     }
     56 
     57     @Override
     58     public void bindItemView(MenuItemImpl item, ItemView itemView) {
     59         final IconMenuItemView view = (IconMenuItemView) itemView;
     60         view.setItemData(item);
     61 
     62         view.initialize(item.getTitleForItemView(view), item.getIcon());
     63 
     64         view.setVisibility(item.isVisible() ? View.VISIBLE : View.GONE);
     65         view.setEnabled(view.isEnabled());
     66         view.setLayoutParams(view.getTextAppropriateLayoutParams());
     67     }
     68 
     69     @Override
     70     public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) {
     71         final ArrayList<MenuItemImpl> itemsToShow = mMenu.getNonActionItems();
     72         boolean fits = (itemsToShow.size() == mMaxItems && childIndex < mMaxItems) ||
     73                 childIndex < mMaxItems - 1;
     74         return fits && !item.isActionButton();
     75     }
     76 
     77     @Override
     78     protected void addItemView(View itemView, int childIndex) {
     79         final IconMenuItemView v = (IconMenuItemView) itemView;
     80         final IconMenuView parent = (IconMenuView) mMenuView;
     81 
     82         v.setIconMenuView(parent);
     83         v.setItemInvoker(parent);
     84         v.setBackgroundDrawable(parent.getItemBackgroundDrawable());
     85         super.addItemView(itemView, childIndex);
     86     }
     87 
     88     @Override
     89     public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
     90         if (!subMenu.hasVisibleItems()) return false;
     91 
     92         // The window manager will give us a token.
     93         MenuDialogHelper helper = new MenuDialogHelper(subMenu);
     94         helper.setPresenterCallback(mSubMenuPresenterCallback);
     95         helper.show(null);
     96         mOpenSubMenu = helper;
     97         mOpenSubMenuId = subMenu.getItem().getItemId();
     98         super.onSubMenuSelected(subMenu);
     99         return true;
    100     }
    101 
    102     @Override
    103     public void updateMenuView(boolean cleared) {
    104         final IconMenuView menuView = (IconMenuView) mMenuView;
    105         if (mMaxItems < 0) mMaxItems = menuView.getMaxItems();
    106         final ArrayList<MenuItemImpl> itemsToShow = mMenu.getNonActionItems();
    107         final boolean needsMore = itemsToShow.size() > mMaxItems;
    108         super.updateMenuView(cleared);
    109 
    110         if (needsMore && (mMoreView == null || mMoreView.getParent() != menuView)) {
    111             if (mMoreView == null) {
    112                 mMoreView = menuView.createMoreItemView();
    113                 mMoreView.setBackgroundDrawable(menuView.getItemBackgroundDrawable());
    114             }
    115             menuView.addView(mMoreView);
    116         } else if (!needsMore && mMoreView != null) {
    117             menuView.removeView(mMoreView);
    118         }
    119 
    120         menuView.setNumActualItemsShown(needsMore ? mMaxItems - 1 : itemsToShow.size());
    121     }
    122 
    123     @Override
    124     protected boolean filterLeftoverView(ViewGroup parent, int childIndex) {
    125         if (parent.getChildAt(childIndex) != mMoreView) {
    126             return super.filterLeftoverView(parent, childIndex);
    127         }
    128         return false;
    129     }
    130 
    131     public int getNumActualItemsShown() {
    132         return ((IconMenuView) mMenuView).getNumActualItemsShown();
    133     }
    134 
    135     public void saveHierarchyState(Bundle outState) {
    136         SparseArray<Parcelable> viewStates = new SparseArray<Parcelable>();
    137         if (mMenuView != null) {
    138             ((View) mMenuView).saveHierarchyState(viewStates);
    139         }
    140         outState.putSparseParcelableArray(VIEWS_TAG, viewStates);
    141     }
    142 
    143     public void restoreHierarchyState(Bundle inState) {
    144         SparseArray<Parcelable> viewStates = inState.getSparseParcelableArray(VIEWS_TAG);
    145         if (viewStates != null) {
    146             ((View) mMenuView).restoreHierarchyState(viewStates);
    147         }
    148         int subMenuId = inState.getInt(OPEN_SUBMENU_KEY, 0);
    149         if (subMenuId > 0 && mMenu != null) {
    150             MenuItem item = mMenu.findItem(subMenuId);
    151             if (item != null) {
    152                 onSubMenuSelected((SubMenuBuilder) item.getSubMenu());
    153             }
    154         }
    155     }
    156 
    157     @Override
    158     public Parcelable onSaveInstanceState() {
    159         if (mMenuView == null) {
    160             return null;
    161         }
    162 
    163         Bundle state = new Bundle();
    164         saveHierarchyState(state);
    165         if (mOpenSubMenuId > 0) {
    166             state.putInt(OPEN_SUBMENU_KEY, mOpenSubMenuId);
    167         }
    168         return state;
    169     }
    170 
    171     @Override
    172     public void onRestoreInstanceState(Parcelable state) {
    173         restoreHierarchyState((Bundle) state);
    174     }
    175 
    176     class SubMenuPresenterCallback implements MenuPresenter.Callback {
    177         @Override
    178         public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
    179             mOpenSubMenuId = 0;
    180             if (mOpenSubMenu != null) {
    181                 mOpenSubMenu.dismiss();
    182                 mOpenSubMenu = null;
    183             }
    184         }
    185 
    186         @Override
    187         public boolean onOpenSubMenu(MenuBuilder subMenu) {
    188             if (subMenu != null) {
    189                 mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
    190             }
    191             return false;
    192         }
    193 
    194     }
    195 }
    196