Project: cow
/*
 * 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.actionbarsherlock.internal.view.menu; 
 
import java.util.ArrayList; 
 
import android.content.Context; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
 
/**
 * Base class for MenuPresenters that have a consistent container view and item 
 * views. Behaves similarly to an AdapterView in that existing item views will 
 * be reused if possible when items change. 
 */
 
public abstract class BaseMenuPresenter implements MenuPresenter { 
    protected Context mSystemContext; 
    protected Context mContext; 
    protected MenuBuilder mMenu; 
    protected LayoutInflater mSystemInflater; 
    protected LayoutInflater mInflater; 
    private Callback mCallback; 
 
    private int mMenuLayoutRes; 
    private int mItemLayoutRes; 
 
    protected MenuView mMenuView; 
 
    private int mId; 
 
    /**
     * Construct a new BaseMenuPresenter. 
     * 
     * @param context Context for generating system-supplied views 
     * @param menuLayoutRes Layout resource ID for the menu container view 
     * @param itemLayoutRes Layout resource ID for a single item view 
     */
 
    public BaseMenuPresenter(Context context, int menuLayoutRes, int itemLayoutRes) { 
        mSystemContext = context; 
        mSystemInflater = LayoutInflater.from(context); 
        mMenuLayoutRes = menuLayoutRes; 
        mItemLayoutRes = itemLayoutRes; 
    } 
 
    @Override 
    public void initForMenu(Context context, MenuBuilder menu) { 
        mContext = context; 
        mInflater = LayoutInflater.from(mContext); 
        mMenu = menu; 
    } 
 
    @Override 
    public MenuView getMenuView(ViewGroup root) { 
        if (mMenuView == null) { 
            mMenuView = (MenuView) mSystemInflater.inflate(mMenuLayoutRes, root, false); 
            mMenuView.initialize(mMenu); 
            updateMenuView(true); 
        } 
 
        return mMenuView; 
    } 
 
    /**
     * Reuses item views when it can 
     */
 
    public void updateMenuView(boolean cleared) { 
        final ViewGroup parent = (ViewGroup) mMenuView; 
        if (parent == nullreturn
 
        int childIndex = 0
        if (mMenu != null) { 
            mMenu.flagActionItems(); 
            ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems(); 
            final int itemCount = visibleItems.size(); 
            for (int i = 0; i < itemCount; i++) { 
                MenuItemImpl item = visibleItems.get(i); 
                if (shouldIncludeItem(childIndex, item)) { 
                    final View convertView = parent.getChildAt(childIndex); 
                    final View itemView = getItemView(item, convertView, parent); 
                    if (itemView != convertView) { 
                        addItemView(itemView, childIndex); 
                    } 
                    childIndex++; 
                } 
            } 
        } 
 
        // Remove leftover views. 
        while (childIndex < parent.getChildCount()) { 
            if (!filterLeftoverView(parent, childIndex)) { 
                childIndex++; 
            } 
        } 
    } 
 
    /**
     * Add an item view at the given index. 
     * 
     * @param itemView View to add 
     * @param childIndex Index within the parent to insert at 
     */
 
    protected void addItemView(View itemView, int childIndex) { 
        final ViewGroup currentParent = (ViewGroup) itemView.getParent(); 
        if (currentParent != null) { 
            currentParent.removeView(itemView); 
        } 
        ((ViewGroup) mMenuView).addView(itemView, childIndex); 
    } 
 
    /**
     * Filter the child view at index and remove it if appropriate. 
     * @param parent Parent to filter from 
     * @param childIndex Index to filter 
     * @return true if the child view at index was removed 
     */
 
    protected boolean filterLeftoverView(ViewGroup parent, int childIndex) { 
        parent.removeViewAt(childIndex); 
        return true
    } 
 
    public void setCallback(Callback cb) { 
        mCallback = cb; 
    } 
 
    /**
     * Create a new item view that can be re-bound to other item data later. 
     * 
     * @return The new item view 
     */
 
    public MenuView.ItemView createItemView(ViewGroup parent) { 
        return (MenuView.ItemView) mSystemInflater.inflate(mItemLayoutRes, parent, false); 
    } 
 
    /**
     * Prepare an item view for use. See AdapterView for the basic idea at work here. 
     * This may require creating a new item view, but well-behaved implementations will 
     * re-use the view passed as convertView if present. The returned view will be populated 
     * with data from the item parameter. 
     * 
     * @param item Item to present 
     * @param convertView Existing view to reuse 
     * @param parent Intended parent view - use for inflation. 
     * @return View that presents the requested menu item 
     */
 
    public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) { 
        MenuView.ItemView itemView; 
        if (convertView instanceof MenuView.ItemView) { 
            itemView = (MenuView.ItemView) convertView; 
        } else { 
            itemView = createItemView(parent); 
        } 
        bindItemView(item, itemView); 
        return (View) itemView; 
    } 
 
    /**
     * Bind item data to an existing item view. 
     * 
     * @param item Item to bind 
     * @param itemView View to populate with item data 
     */
 
    public abstract void bindItemView(MenuItemImpl item, MenuView.ItemView itemView); 
 
    /**
     * Filter item by child index and item data. 
     * 
     * @param childIndex Intended presentation index of this item 
     * @param item Item to present 
     * @return true if this item should be included in this menu presentation; false otherwise 
     */
 
    public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) { 
        return true
    } 
 
    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 
        if (mCallback != null) { 
            mCallback.onCloseMenu(menu, allMenusAreClosing); 
        } 
    } 
 
    public boolean onSubMenuSelected(SubMenuBuilder menu) { 
        if (mCallback != null) { 
            return mCallback.onOpenSubMenu(menu); 
        } 
        return false
    } 
 
    public boolean flagActionItems() { 
        return false
    } 
 
    public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item) { 
        return false
    } 
 
    public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) { 
        return false
    } 
 
    public int getId() { 
        return mId; 
    } 
 
    public void setId(int id) { 
        mId = id; 
    } 
}