IconMenuView.java revision 189ee18d6c6483ad63cc864267328259e2e00b95
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.view.menu;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.menu.MenuBuilder.ItemInvoker;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcelable;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewConfiguration;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The icon menu view is an icon-based menu usually with a subset of all the menu items.
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * It is opened as the default menu, and shows either the first five or all six of the menu items
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with text and icon.  In the situation of there being more than six items, the first five items
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will be accompanied with a 'More' button that opens an {@link ExpandedMenuView} which lists
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * all the menu items.
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#IconMenuView_rowHeight
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#IconMenuView_maxRows
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#IconMenuView_maxItemsPerRow
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class IconMenuView extends ViewGroup implements ItemInvoker, MenuView, Runnable {
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int ITEM_CAPTION_CYCLE_DELAY = 1000;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private MenuBuilder mMenu;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Height of each row */
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mRowHeight;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Maximum number of rows to be shown */
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mMaxRows;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Maximum number of items to show in the icon menu. */
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mMaxItems;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Maximum number of items per row */
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mMaxItemsPerRow;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Actual number of items (the 'More' view does not count as an item) shown */
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mNumActualItemsShown;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Divider that is drawn between all rows */
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mHorizontalDivider;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Height of the horizontal divider */
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mHorizontalDividerHeight;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Set of horizontal divider positions where the horizontal divider will be drawn */
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ArrayList<Rect> mHorizontalDividerRects;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Divider that is drawn between all columns */
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mVerticalDivider;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Width of the vertical divider */
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mVerticalDividerWidth;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Set of vertical divider positions where the vertical divider will be drawn */
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ArrayList<Rect> mVerticalDividerRects;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Icon for the 'More' button */
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mMoreIcon;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Item view for the 'More' button */
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private IconMenuItemView mMoreItemView;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Background of each item (should contain the selected and focused states) */
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Drawable mItemBackground;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Default animations for this menu */
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mAnimations;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Whether this IconMenuView has stale children and needs to update them.
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set true by {@link #markStaleChildren()} and reset to false by
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onMeasure(int, int)}
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mHasStaleChildren;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Longpress on MENU (while this is shown) switches to shortcut caption
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * mode. When the user releases the longpress, we do not want to pass the
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * key-up event up since that will dismiss the menu.
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mMenuBeingLongpressed = false;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * While {@link #mMenuBeingLongpressed}, we toggle the children's caption
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * mode between each's title and its shortcut. This is the last caption mode
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * we broadcasted to children.
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mLastChildrenCaptionMode;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The layout to use for menu items. Each index is the row number (0 is the
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * top-most). Each value contains the number of items in that row.
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The length of this array should not be used to get the number of rows in
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the current layout, instead use {@link #mLayoutNumRows}.
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int[] mLayout;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The number of rows in the current layout.
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mLayoutNumRows;
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Instantiates the IconMenuView that is linked with the provided MenuBuilder.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IconMenuView(Context context, AttributeSet attrs) {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(context, attrs);
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        TypedArray a =
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.IconMenuView, 0, 0);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRowHeight = a.getDimensionPixelSize(com.android.internal.R.styleable.IconMenuView_rowHeight, 64);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMaxRows = a.getInt(com.android.internal.R.styleable.IconMenuView_maxRows, 2);
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMaxItems = a.getInt(com.android.internal.R.styleable.IconMenuView_maxItems, 6);
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMaxItemsPerRow = a.getInt(com.android.internal.R.styleable.IconMenuView_maxItemsPerRow, 3);
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMoreIcon = a.getDrawable(com.android.internal.R.styleable.IconMenuView_moreIcon);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.MenuView, 0, 0);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mItemBackground = a.getDrawable(com.android.internal.R.styleable.MenuView_itemBackground);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHorizontalDivider = a.getDrawable(com.android.internal.R.styleable.MenuView_horizontalDivider);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHorizontalDividerRects = new ArrayList<Rect>();
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mVerticalDivider =  a.getDrawable(com.android.internal.R.styleable.MenuView_verticalDivider);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mVerticalDividerRects = new ArrayList<Rect>();
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAnimations = a.getResourceId(com.android.internal.R.styleable.MenuView_windowAnimationStyle, 0);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        a.recycle();
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mHorizontalDivider != null) {
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHorizontalDividerHeight = mHorizontalDivider.getIntrinsicHeight();
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Make sure to have some height for the divider
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mHorizontalDividerHeight == -1) mHorizontalDividerHeight = 1;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mVerticalDivider != null) {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mVerticalDividerWidth = mVerticalDivider.getIntrinsicWidth();
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Make sure to have some width for the divider
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mVerticalDividerWidth == -1) mVerticalDividerWidth = 1;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayout = new int[mMaxRows];
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // This view will be drawing the dividers
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setWillNotDraw(false);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // This is so we'll receive the MENU key in touch mode
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setFocusableInTouchMode(true);
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // This is so our children can still be arrow-key focused
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Figures out the layout for the menu items.
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width The available width for the icon menu.
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void layoutItems(int width) {
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numItems = getChildCount();
18222cb2f46fdbb9a904ac394f488278fb47e2d4734Adam Powell        if (numItems == 0) {
18322cb2f46fdbb9a904ac394f488278fb47e2d4734Adam Powell            mLayoutNumRows = 0;
18422cb2f46fdbb9a904ac394f488278fb47e2d4734Adam Powell            return;
18522cb2f46fdbb9a904ac394f488278fb47e2d4734Adam Powell        }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Start with the least possible number of rows
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int curNumRows =
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Math.min((int) Math.ceil(numItems / (float) mMaxItemsPerRow), mMaxRows);
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Increase the number of rows until we find a configuration that fits
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * all of the items' titles. Worst case, we use mMaxRows.
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (; curNumRows <= mMaxRows; curNumRows++) {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            layoutItemsUsingGravity(curNumRows, numItems);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (curNumRows >= numItems) {
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Can't have more rows than items
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (doItemsFit()) {
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // All the items fit, so this is a good configuration
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Figures out the layout for the menu items by equally distributing, and
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * adding any excess items equally to lower rows.
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param numRows The total number of rows for the menu view
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param numItems The total number of items (across all rows) contained in
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            the menu view
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return int[] Where the value of index i contains the number of items for row i
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void layoutItemsUsingGravity(int numRows, int numItems) {
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numBaseItemsPerRow = numItems / numRows;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numLeftoverItems = numItems % numRows;
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The bottom rows will each get a leftover item. Rows (indexed at 0)
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * that are >= this get a leftover item. Note: if there are 0 leftover
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * items, no rows will get them since this value will be greater than
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the last row.
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int rowsThatGetALeftoverItem = numRows - numLeftoverItems;
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int[] layout = mLayout;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < numRows; i++) {
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            layout[i] = numBaseItemsPerRow;
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Fill the bottom rows with a leftover item each
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (i >= rowsThatGetALeftoverItem) {
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                layout[i]++;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLayoutNumRows = numRows;
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Checks whether each item's title is fully visible using the current
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * layout.
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return True if the items fit (each item's text is fully visible), false
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         otherwise.
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean doItemsFit() {
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int itemPos = 0;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int[] layout = mLayout;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numRows = mLayoutNumRows;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int row = 0; row < numRows; row++) {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int numItemsOnRow = layout[row];
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /*
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * If there is only one item on this row, increasing the
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * number of rows won't help.
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             */
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (numItemsOnRow == 1) {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                itemPos++;
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int itemsOnRowCounter = numItemsOnRow; itemsOnRowCounter > 0;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    itemsOnRowCounter--) {
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                View child = getChildAt(itemPos++);
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                LayoutParams lp = (LayoutParams) child.getLayoutParams();
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (lp.maxNumItemsOnRow < numItemsOnRow) {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return false;
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Adds an IconMenuItemView to this icon menu view.
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param itemView The item's view to add
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
284105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    private void addItemView(IconMenuItemView itemView) {
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set ourselves on the item view
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        itemView.setIconMenuView(this);
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Apply the background to the item view
289c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn        itemView.setBackgroundDrawable(
290c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn                mItemBackground.getConstantState().newDrawable(
291c2974809373697147cbe5754835cc871fb93aef1Dianne Hackborn                        getContext().getResources()));
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // This class is the invoker for all its item views
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        itemView.setItemInvoker(this);
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
296105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        addView(itemView, itemView.getTextAppropriateLayoutParams());
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Creates the item view for the 'More' button which is used to switch to
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the expanded menu view. This button is a special case since it does not
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * have a MenuItemData backing it.
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The IconMenuItemView for the 'More' button
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private IconMenuItemView createMoreItemView() {
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LayoutInflater inflater = mMenu.getMenuType(MenuBuilder.TYPE_ICON).getInflater();
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final IconMenuItemView itemView = (IconMenuItemView) inflater.inflate(
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                com.android.internal.R.layout.icon_menu_item_layout, null);
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Resources r = getContext().getResources();
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        itemView.initialize(r.getText(com.android.internal.R.string.more_item_label), mMoreIcon);
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set up a click listener on the view since there will be no invocation sequence
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // due to the lack of a MenuItemData this view
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        itemView.setOnClickListener(new OnClickListener() {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void onClick(View v) {
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Switches the menu to expanded mode
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                MenuBuilder.Callback cb = mMenu.getCallback();
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (cb != null) {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Call callback
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    cb.onMenuModeChange(mMenu);
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        });
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return itemView;
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void initialize(MenuBuilder menu, int menuType) {
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMenu = menu;
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateChildren(true);
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void updateChildren(boolean cleared) {
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // This method does a clear refresh of children
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        removeAllViews();
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3408028dd32a4a04154050220dd0693583d5b750330Adam Powell        // IconMenuView never wants content sorted for an overflow action button, since
3418028dd32a4a04154050220dd0693583d5b750330Adam Powell        // it is never used in the presence of an overflow button.
3428028dd32a4a04154050220dd0693583d5b750330Adam Powell        final ArrayList<MenuItemImpl> itemsToShow = mMenu.getNonActionItems(false);
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int numItems = itemsToShow.size();
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int numItemsThatCanFit = mMaxItems;
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Minimum of the num that can fit and the num that we have
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int minFitMinus1AndNumItems = Math.min(numItemsThatCanFit - 1, numItems);
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MenuItemImpl itemData;
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Traverse through all but the last item that can fit since that last item can either
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // be a 'More' button or a sixth item
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < minFitMinus1AndNumItems; i++) {
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            itemData = itemsToShow.get(i);
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            addItemView((IconMenuItemView) itemData.getItemView(MenuBuilder.TYPE_ICON, this));
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (numItems > numItemsThatCanFit) {
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If there are more items than we can fit, show the 'More' button to
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // switch to expanded mode
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mMoreItemView == null) {
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mMoreItemView = createMoreItemView();
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            addItemView(mMoreItemView);
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // The last view is the more button, so the actual number of items is one less than
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // the number that can fit
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mNumActualItemsShown = numItemsThatCanFit - 1;
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (numItems == numItemsThatCanFit) {
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // There are exactly the number we can show, so show the last item
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final MenuItemImpl lastItemData = itemsToShow.get(numItemsThatCanFit - 1);
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            addItemView((IconMenuItemView) lastItemData.getItemView(MenuBuilder.TYPE_ICON, this));
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // The items shown fit exactly
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mNumActualItemsShown = numItemsThatCanFit;
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The positioning algorithm that gets called from onMeasure.  It
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * just computes positions for each child, and then stores them in the child's layout params.
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param menuWidth The width of this menu to assume for positioning
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param menuHeight The height of this menu to assume for positioning
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void positionChildren(int menuWidth, int menuHeight) {
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Clear the containers for the positions where the dividers should be drawn
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mHorizontalDivider != null) mHorizontalDividerRects.clear();
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mVerticalDivider != null) mVerticalDividerRects.clear();
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Get the minimum number of rows needed
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int numRows = mLayoutNumRows;
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int numRowsMinus1 = numRows - 1;
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int numItemsForRow[] = mLayout;
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The item position across all rows
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int itemPos = 0;
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        View child;
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IconMenuView.LayoutParams childLayoutParams = null;
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Use float for this to get precise positions (uniform item widths
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // instead of last one taking any slack), and then convert to ints at last opportunity
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float itemLeft;
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float itemTop = 0;
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Since each row can have a different number of items, this will be computed per row
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        float itemWidth;
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Subtract the space needed for the horizontal dividers
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final float itemHeight = (menuHeight - mHorizontalDividerHeight * (numRows - 1))
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                / (float)numRows;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int row = 0; row < numRows; row++) {
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Start at the left
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            itemLeft = 0;
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Subtract the space needed for the vertical dividers, and divide by the number of items
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            itemWidth = (menuWidth - mVerticalDividerWidth * (numItemsForRow[row] - 1))
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    / (float)numItemsForRow[row];
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int itemPosOnRow = 0; itemPosOnRow < numItemsForRow[row]; itemPosOnRow++) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Tell the child to be exactly this size
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                child = getChildAt(itemPos);
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                child.measure(MeasureSpec.makeMeasureSpec((int) itemWidth, MeasureSpec.EXACTLY),
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        MeasureSpec.makeMeasureSpec((int) itemHeight, MeasureSpec.EXACTLY));
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Remember the child's position for layout
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                childLayoutParams = (IconMenuView.LayoutParams) child.getLayoutParams();
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                childLayoutParams.left = (int) itemLeft;
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                childLayoutParams.right = (int) (itemLeft + itemWidth);
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                childLayoutParams.top = (int) itemTop;
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                childLayoutParams.bottom = (int) (itemTop + itemHeight);
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Increment by item width
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                itemLeft += itemWidth;
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                itemPos++;
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Add a vertical divider to draw
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mVerticalDivider != null) {
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mVerticalDividerRects.add(new Rect((int) itemLeft,
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (int) itemTop, (int) (itemLeft + mVerticalDividerWidth),
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (int) (itemTop + itemHeight)));
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Increment by divider width (even if we're not computing
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // dividers, since we need to leave room for them when
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // calculating item positions)
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                itemLeft += mVerticalDividerWidth;
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Last child on each row should extend to very right edge
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (childLayoutParams != null) {
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                childLayoutParams.right = menuWidth;
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            itemTop += itemHeight;
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Add a horizontal divider to draw
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ((mHorizontalDivider != null) && (row < numRowsMinus1)) {
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mHorizontalDividerRects.add(new Rect(0, (int) itemTop, menuWidth,
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        (int) (itemTop + mHorizontalDividerHeight)));
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                itemTop += mHorizontalDividerHeight;
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mHasStaleChildren) {
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHasStaleChildren = false;
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If we have stale data, resync with the menu
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            updateChildren(false);
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int measuredWidth = resolveSize(Integer.MAX_VALUE, widthMeasureSpec);
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        calculateItemFittingMetadata(measuredWidth);
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        layoutItems(measuredWidth);
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Get the desired height of the icon menu view (last row of items does
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // not have a divider below)
47922cb2f46fdbb9a904ac394f488278fb47e2d4734Adam Powell        final int layoutNumRows = mLayoutNumRows;
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int desiredHeight = (mRowHeight + mHorizontalDividerHeight) *
48122cb2f46fdbb9a904ac394f488278fb47e2d4734Adam Powell                layoutNumRows - mHorizontalDividerHeight;
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Maximum possible width and desired height
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setMeasuredDimension(measuredWidth,
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                resolveSize(desiredHeight, heightMeasureSpec));
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Position the children
48822cb2f46fdbb9a904ac394f488278fb47e2d4734Adam Powell        if (layoutNumRows > 0) {
489189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn            positionChildren(getMeasuredWidth(), getMeasuredHeight());
49022cb2f46fdbb9a904ac394f488278fb47e2d4734Adam Powell        }
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onLayout(boolean changed, int l, int t, int r, int b) {
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        View child;
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IconMenuView.LayoutParams childLayoutParams;
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = getChildCount() - 1; i >= 0; i--) {
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            child = getChildAt(i);
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            childLayoutParams = (IconMenuView.LayoutParams)child
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    .getLayoutParams();
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Layout children according to positions set during the measure
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            child.layout(childLayoutParams.left, childLayoutParams.top, childLayoutParams.right,
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    childLayoutParams.bottom);
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onDraw(Canvas canvas) {
512809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy        Drawable drawable = mHorizontalDivider;
513809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy        if (drawable != null) {
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If we have a horizontal divider to draw, draw it at the remembered positions
515809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy            final ArrayList<Rect> rects = mHorizontalDividerRects;
516809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy            for (int i = rects.size() - 1; i >= 0; i--) {
517809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy                drawable.setBounds(rects.get(i));
518809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy                drawable.draw(canvas);
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
521809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy
522809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy        drawable = mVerticalDivider;
523809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy        if (drawable != null) {
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If we have a vertical divider to draw, draw it at the remembered positions
525809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy            final ArrayList<Rect> rects = mVerticalDividerRects;
526809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy            for (int i = rects.size() - 1; i >= 0; i--) {
527809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy                drawable.setBounds(rects.get(i));
528809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy                drawable.draw(canvas);
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean invokeItem(MenuItemImpl item) {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mMenu.performItemAction(item, 0);
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
538809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy    public LayoutParams generateLayoutParams(AttributeSet attrs) {
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new IconMenuView.LayoutParams(getContext(), attrs);
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
543809a7f6080312f3e12f1a3a30eacf0e0c7627305Romain Guy    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Override to allow type-checking of LayoutParams.
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return p instanceof IconMenuView.LayoutParams;
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Marks as having stale children.
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void markStaleChildren() {
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mHasStaleChildren) {
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHasStaleChildren = true;
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            requestLayout();
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The number of actual items shown (those that are backed by an
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         {@link MenuView.ItemView} implementation--eg: excludes More
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         item).
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int getNumActualItemsShown() {
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mNumActualItemsShown;
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getWindowAnimations() {
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mAnimations;
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the number of items per row.
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This should only be used for testing.
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The length of the array is the number of rows. A value at a
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         position is the number of items in that row.
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int[] getLayout() {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayout;
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the number of rows in the layout.
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This should only be used for testing.
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The length of the array is the number of rows. A value at a
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         position is the number of items in that row.
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getLayoutNumRows() {
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mLayoutNumRows;
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean dispatchKeyEvent(KeyEvent event) {
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (event.getKeyCode() == KeyEvent.KEYCODE_MENU) {
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                removeCallbacks(this);
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                postDelayed(this, ViewConfiguration.getLongPressTimeout());
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (event.getAction() == KeyEvent.ACTION_UP) {
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mMenuBeingLongpressed) {
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // It was in cycle mode, so reset it (will also remove us
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // from being called back)
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setCycleShortcutCaptionMode(false);
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return true;
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Just remove us from being called back
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    removeCallbacks(this);
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Fall through to normal processing too
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return super.dispatchKeyEvent(event);
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onAttachedToWindow() {
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onAttachedToWindow();
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        requestFocus();
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onDetachedFromWindow() {
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        setCycleShortcutCaptionMode(false);
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onDetachedFromWindow();
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onWindowFocusChanged(boolean hasWindowFocus) {
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!hasWindowFocus) {
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setCycleShortcutCaptionMode(false);
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onWindowFocusChanged(hasWindowFocus);
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the shortcut caption mode for IconMenuView. This mode will
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * continuously cycle between a child's shortcut and its title.
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param cycleShortcutAndNormal Whether to go into cycling shortcut mode,
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *        or to go back to normal.
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void setCycleShortcutCaptionMode(boolean cycleShortcutAndNormal) {
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!cycleShortcutAndNormal) {
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /*
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * We're setting back to title, so remove any callbacks for setting
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * to shortcut
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             */
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            removeCallbacks(this);
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setChildrenCaptionMode(false);
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMenuBeingLongpressed = false;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Set it the first time (the cycle will be started in run()).
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setChildrenCaptionMode(true);
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * When this method is invoked if the menu is currently not being
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * longpressed, it means that the longpress has just been reached (so we set
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * longpress flag, and start cycling). If it is being longpressed, we cycle
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to the next mode.
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void run() {
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mMenuBeingLongpressed) {
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Cycle to other caption mode on the children
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setChildrenCaptionMode(!mLastChildrenCaptionMode);
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Switch ourselves to continuously cycle the items captions
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMenuBeingLongpressed = true;
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setCycleShortcutCaptionMode(true);
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // We should run again soon to cycle to the other caption mode
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        postDelayed(this, ITEM_CAPTION_CYCLE_DELAY);
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Iterates children and sets the desired shortcut mode. Only
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #setCycleShortcutCaptionMode(boolean)} and {@link #run()} should call
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this.
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param shortcut Whether to show shortcut or the title.
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void setChildrenCaptionMode(boolean shortcut) {
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set the last caption mode pushed to children
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mLastChildrenCaptionMode = shortcut;
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = getChildCount() - 1; i >= 0; i--) {
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ((IconMenuItemView) getChildAt(i)).setCaptionMode(shortcut);
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For each item, calculates the most dense row that fully shows the item's
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * title.
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param width The available width of the icon menu.
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void calculateItemFittingMetadata(int width) {
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int maxNumItemsPerRow = mMaxItemsPerRow;
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int numItems = getChildCount();
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < numItems; i++) {
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LayoutParams lp = (LayoutParams) getChildAt(i).getLayoutParams();
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Start with 1, since that case does not get covered in the loop below
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            lp.maxNumItemsOnRow = 1;
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int curNumItemsPerRow = maxNumItemsPerRow; curNumItemsPerRow > 0;
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    curNumItemsPerRow--) {
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Check whether this item can fit into a row containing curNumItemsPerRow
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (lp.desiredWidth < width / curNumItemsPerRow) {
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // It can, mark this value as the most dense row it can fit into
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    lp.maxNumItemsOnRow = curNumItemsPerRow;
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    break;
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected Parcelable onSaveInstanceState() {
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcelable superState = super.onSaveInstanceState();
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        View focusedView = getFocusedChild();
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = getChildCount() - 1; i >= 0; i--) {
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (getChildAt(i) == focusedView) {
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return new SavedState(superState, i);
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new SavedState(superState, -1);
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void onRestoreInstanceState(Parcelable state) {
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SavedState ss = (SavedState) state;
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onRestoreInstanceState(ss.getSuperState());
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ss.focusedPosition >= getChildCount()) {
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        View v = getChildAt(ss.focusedPosition);
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (v != null) {
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            v.requestFocus();
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static class SavedState extends BaseSavedState {
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int focusedPosition;
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Constructor called from {@link IconMenuView#onSaveInstanceState()}
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public SavedState(Parcelable superState, int focusedPosition) {
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(superState);
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            this.focusedPosition = focusedPosition;
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Constructor called from {@link #CREATOR}
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private SavedState(Parcel in) {
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(in);
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            focusedPosition = in.readInt();
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void writeToParcel(Parcel dest, int flags) {
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super.writeToParcel(dest, flags);
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            dest.writeInt(focusedPosition);
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public SavedState createFromParcel(Parcel in) {
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return new SavedState(in);
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public SavedState[] newArray(int size) {
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return new SavedState[size];
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        };
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Layout parameters specific to IconMenuView (stores the left, top, right, bottom from the
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * measure pass).
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class LayoutParams extends ViewGroup.MarginLayoutParams
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int left, top, right, bottom;
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int desiredWidth;
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int maxNumItemsOnRow;
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public LayoutParams(Context c, AttributeSet attrs) {
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(c, attrs);
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public LayoutParams(int width, int height) {
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(width, height);
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
825