content: /*
   * 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.annotation.NonNull;
  import android.annotation.Nullable;
  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(@NonNull Context context, @Nullable 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;
          }
  
      }
  }
  