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.annotation.NonNull;
     21 import android.annotation.Nullable;
     22 import android.content.Context;
     23 import android.os.Bundle;
     24 import android.os.Parcelable;
     25 import android.util.SparseArray;
     26 import android.view.ContextThemeWrapper;
     27 import android.view.MenuItem;
     28 import android.view.View;
     29 import android.view.ViewGroup;
     30 
     31 import java.util.ArrayList;
     32 
     33 /**
     34  * MenuPresenter for the classic "six-pack" icon menu.
     35  */
     36 public class IconMenuPresenter extends BaseMenuPresenter {
     37     private IconMenuItemView mMoreView;
     38     private int mMaxItems = -1;
     39 
     40     int mOpenSubMenuId;
     41     SubMenuPresenterCallback mSubMenuPresenterCallback = new SubMenuPresenterCallback();
     42     MenuDialogHelper mOpenSubMenu;
     43 
     44     private static final String VIEWS_TAG = "android:menu:icon";
     45     private static final String OPEN_SUBMENU_KEY = "android:menu:icon:submenu";
     46 
     47     public IconMenuPresenter(Context context) {
     48         super(new ContextThemeWrapper(context, com.android.internal.R.style.Theme_IconMenu),
     49                 com.android.internal.R.layout.icon_menu_layout,
     50                 com.android.internal.R.layout.icon_menu_item_layout);
     51     }
     52 
     53     @Override
     54     public void initForMenu(@NonNull Context context, @Nullable MenuBuilder menu) {
     55         super.initForMenu(context, menu);
     56         mMaxItems = -1;
     57     }
     58 
     59     @Override
     60     public void bindItemView(MenuItemImpl item, ItemView itemView) {
     61         final IconMenuItemView view = (IconMenuItemView) itemView;
     62         view.setItemData(item);
     63 
     64         view.initialize(item.getTitleForItemView(view), item.getIcon());
     65 
     66         view.setVisibility(item.isVisible() ? View.VISIBLE : View.GONE);
     67         view.setEnabled(view.isEnabled());
     68         view.setLayoutParams(view.getTextAppropriateLayoutParams());
     69     }
     70 
     71     @Override
     72     public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) {
     73         final ArrayList<MenuItemImpl> itemsToShow = mMenu.getNonActionItems();
     74         boolean fits = (itemsToShow.size() == mMaxItems && childIndex < mMaxItems) ||
     75                 childIndex < mMaxItems - 1;
     76         return fits && !item.isActionButton();
     77     }
     78 
     79     @Override
     80     protected void addItemView(View itemView, int childIndex) {
     81         final IconMenuItemView v = (IconMenuItemView) itemView;
     82         final IconMenuView parent = (IconMenuView) mMenuView;
     83 
     84         v.setIconMenuView(parent);
     85         v.setItemInvoker(parent);
     86         v.setBackgroundDrawable(parent.getItemBackgroundDrawable());
     87         super.addItemView(itemView, childIndex);
     88     }
     89 
     90     @Override
     91     public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
     92         if (!subMenu.hasVisibleItems()) return false;
     93 
     94         // The window manager will give us a token.
     95         MenuDialogHelper helper = new MenuDialogHelper(subMenu);
     96         helper.setPresenterCallback(mSubMenuPresenterCallback);
     97         helper.show(null);
     98         mOpenSubMenu = helper;
     99         mOpenSubMenuId = subMenu.getItem().getItemId();
    100         super.onSubMenuSelected(subMenu);
    101         return true;
    102     }
    103 
    104     @Override
    105     public void updateMenuView(boolean cleared) {
    106         final IconMenuView menuView = (IconMenuView) mMenuView;
    107         if (mMaxItems < 0) mMaxItems = menuView.getMaxItems();
    108         final ArrayList<MenuItemImpl> itemsToShow = mMenu.getNonActionItems();
    109         final boolean needsMore = itemsToShow.size() > mMaxItems;
    110         super.updateMenuView(cleared);
    111 
    112         if (needsMore && (mMoreView == null || mMoreView.getParent() != menuView)) {
    113             if (mMoreView == null) {
    114                 mMoreView = menuView.createMoreItemView();
    115                 mMoreView.setBackgroundDrawable(menuView.getItemBackgroundDrawable());
    116             }
    117             menuView.addView(mMoreView);
    118         } else if (!needsMore && mMoreView != null) {
    119             menuView.removeView(mMoreView);
    120         }
    121 
    122         menuView.setNumActualItemsShown(needsMore ? mMaxItems - 1 : itemsToShow.size());
    123     }
    124 
    125     @Override
    126     protected boolean filterLeftoverView(ViewGroup parent, int childIndex) {
    127         if (parent.getChildAt(childIndex) != mMoreView) {
    128             return super.filterLeftoverView(parent, childIndex);
    129         }
    130         return false;
    131     }
    132 
    133     public int getNumActualItemsShown() {
    134         return ((IconMenuView) mMenuView).getNumActualItemsShown();
    135     }
    136 
    137     public void saveHierarchyState(Bundle outState) {
    138         SparseArray<Parcelable> viewStates = new SparseArray<Parcelable>();
    139         if (mMenuView != null) {
    140             ((View) mMenuView).saveHierarchyState(viewStates);
    141         }
    142         outState.putSparseParcelableArray(VIEWS_TAG, viewStates);
    143     }
    144 
    145     public void restoreHierarchyState(Bundle inState) {
    146         SparseArray<Parcelable> viewStates = inState.getSparseParcelableArray(VIEWS_TAG);
    147         if (viewStates != null) {
    148             ((View) mMenuView).restoreHierarchyState(viewStates);
    149         }
    150         int subMenuId = inState.getInt(OPEN_SUBMENU_KEY, 0);
    151         if (subMenuId > 0 && mMenu != null) {
    152             MenuItem item = mMenu.findItem(subMenuId);
    153             if (item != null) {
    154                 onSubMenuSelected((SubMenuBuilder) item.getSubMenu());
    155             }
    156         }
    157     }
    158 
    159     @Override
    160     public Parcelable onSaveInstanceState() {
    161         if (mMenuView == null) {
    162             return null;
    163         }
    164 
    165         Bundle state = new Bundle();
    166         saveHierarchyState(state);
    167         if (mOpenSubMenuId > 0) {
    168             state.putInt(OPEN_SUBMENU_KEY, mOpenSubMenuId);
    169         }
    170         return state;
    171     }
    172 
    173     @Override
    174     public void onRestoreInstanceState(Parcelable state) {
    175         restoreHierarchyState((Bundle) state);
    176     }
    177 
    178     class SubMenuPresenterCallback implements MenuPresenter.Callback {
    179         @Override
    180         public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
    181             mOpenSubMenuId = 0;
    182             if (mOpenSubMenu != null) {
    183                 mOpenSubMenu.dismiss();
    184                 mOpenSubMenu = null;
    185             }
    186         }
    187 
    188         @Override
    189         public boolean onOpenSubMenu(MenuBuilder subMenu) {
    190             if (subMenu != null) {
    191                 mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
    192             }
    193             return false;
    194         }
    195 
    196     }
    197 }
    198