Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35aecd58 authored by Adam Powell's avatar Adam Powell
Browse files

Updates for action menus

Sync with UX designs for action menus in split action bar mode.
Layout is now based on a grid cell scheme.

Tweak action menu item layouts.

Fix some bugs with drawing LinearLayout dividers.

Rename config resources to follow convention.

Action bar menu items now show text in ALL CAPS. This is done in a
locale-dependent manner, but if it produces problems in specific
locales the config resource config_actionMenuItemAllCaps should be set
to false for that locale.

Change-Id: I064c2dd85e012e89551f29153efcfc17f9106333
parent 6f2e4d10
Loading
Loading
Loading
Loading
+24 −18
Original line number Diff line number Diff line
@@ -301,49 +301,55 @@ public class LinearLayout extends ViewGroup {

    void drawDividersVertical(Canvas canvas) {
        final int count = getVirtualChildCount();
        int top = getPaddingTop();
        for (int i = 0; i < count; i++) {
            final View child = getVirtualChildAt(i);

            if (child == null) {
                top += measureNullChild(i);
            } else if (child.getVisibility() != GONE) {
            if (child != null && child.getVisibility() != GONE) {
                if (hasDividerBeforeChildAt(i)) {
                    final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                    final int top = child.getTop() - lp.topMargin;
                    drawHorizontalDivider(canvas, top);
                    top += mDividerHeight;
                }

                LayoutParams lp = (LayoutParams) child.getLayoutParams();
                top += lp.topMargin + child.getHeight() + lp.bottomMargin;
            }
        }

        if (hasDividerBeforeChildAt(count)) {
            drawHorizontalDivider(canvas, top);
            final View child = getVirtualChildAt(count - 1);
            int bottom = 0;
            if (child == null) {
                bottom = getHeight() - getPaddingBottom() - mDividerHeight;
            } else {
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                bottom = child.getBottom() + lp.bottomMargin;
            }
            drawHorizontalDivider(canvas, bottom);
        }
    }

    void drawDividersHorizontal(Canvas canvas) {
        final int count = getVirtualChildCount();
        int left = getPaddingLeft();
        for (int i = 0; i < count; i++) {
            final View child = getVirtualChildAt(i);

            if (child == null) {
                left += measureNullChild(i);
            } else if (child.getVisibility() != GONE) {
            if (child != null && child.getVisibility() != GONE) {
                if (hasDividerBeforeChildAt(i)) {
                    final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                    final int left = child.getLeft() - lp.leftMargin;
                    drawVerticalDivider(canvas, left);
                    left += mDividerWidth;
                }

                LayoutParams lp = (LayoutParams) child.getLayoutParams();
                left += lp.leftMargin + child.getWidth() + lp.rightMargin;
            }
        }

        if (hasDividerBeforeChildAt(count)) {
            drawVerticalDivider(canvas, left);
            final View child = getVirtualChildAt(count - 1);
            int right = 0;
            if (child == null) {
                right = getWidth() - getPaddingRight() - mDividerWidth;
            } else {
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                right = child.getRight() + lp.rightMargin;
            }
            drawVerticalDivider(canvas, right);
        }
    }

+1 −1
Original line number Diff line number Diff line
@@ -8901,7 +8901,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            TypedArray styledAttributes = mContext.obtainStyledAttributes(R.styleable.Theme);

            boolean allowText = getContext().getResources().getBoolean(
                    com.android.internal.R.bool.allow_action_menu_item_text_with_icon);
                    com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);

            mode.setTitle(allowText ? 
                    mContext.getString(com.android.internal.R.string.textSelectionCABTitle) : null);
+27 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.view.menu;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -38,17 +39,24 @@ public class ActionMenuItemView extends LinearLayout

    private ImageButton mImageButton;
    private Button mTextButton;
    private boolean mAllowTextWithIcon;
    private boolean mShowTextAllCaps;
    private boolean mExpandedFormat;

    public ActionMenuItemView(Context context) {
        this(context, null);
    }

    public ActionMenuItemView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this(context, attrs, 0);
    }

    public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        final Resources res = context.getResources();
        mAllowTextWithIcon = res.getBoolean(
                com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
        mShowTextAllCaps = res.getBoolean(com.android.internal.R.bool.config_actionMenuItemAllCaps);
    }

    @Override
@@ -104,9 +112,20 @@ public class ActionMenuItemView extends LinearLayout
        // TODO Support checkable action items
    }

    public void setExpandedFormat(boolean expandedFormat) {
        if (mExpandedFormat != expandedFormat) {
            mExpandedFormat = expandedFormat;
            if (mItemData != null) {
                mItemData.actionFormatChanged();
            }
        }
    }

    private void updateTextButtonVisibility() {
        boolean visible = !TextUtils.isEmpty(mTextButton.getText());
        visible = visible && (mImageButton.getDrawable() == null || mItemData.showsTextAsAction());
        visible &= mImageButton.getDrawable() == null ||
                (mItemData.showsTextAsAction() && (mAllowTextWithIcon || mExpandedFormat));

        mTextButton.setVisibility(visible ? VISIBLE : GONE);
    }

@@ -135,7 +154,12 @@ public class ActionMenuItemView extends LinearLayout
        // populate accessibility description with title
        setContentDescription(title);

        if (mShowTextAllCaps) {
            mTextButton.setText(title.toString().toUpperCase(
                    getContext().getResources().getConfiguration().locale));
        } else {
            mTextButton.setText(mTitle);
        }

        updateTextButtonVisibility();
    }
+58 −24
Original line number Diff line number Diff line
@@ -19,8 +19,8 @@ package com.android.internal.view.menu;
import com.android.internal.view.menu.ActionMenuView.ActionMenuChildView;

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.MenuItem;
import android.view.SoundEffectConstants;
@@ -48,6 +48,8 @@ public class ActionMenuPresenter extends BaseMenuPresenter {
    private boolean mStrictWidthLimit;
    private boolean mWidthLimitSet;

    private int mMinCellSize;

    // Group IDs that have been added as actions - used temporarily, allocated here for reuse.
    private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray();

@@ -96,6 +98,8 @@ public class ActionMenuPresenter extends BaseMenuPresenter {

        mActionItemWidthLimit = width;

        mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density);

        // Drop a scrap view as it may no longer reflect the proper context/config.
        mScrapActionButtonView = null;
    }
@@ -126,16 +130,30 @@ public class ActionMenuPresenter extends BaseMenuPresenter {
    @Override
    public View getItemView(MenuItemImpl item, View convertView, ViewGroup parent) {
        View actionView = item.getActionView();
        actionView = actionView != null && !item.hasCollapsibleActionView() ?
                actionView : super.getItemView(item, convertView, parent);
        if (actionView == null || item.hasCollapsibleActionView()) {
            if (!(convertView instanceof ActionMenuItemView)) {
                convertView = null;
            }
            actionView = super.getItemView(item, convertView, parent);
        }
        actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE);

        final ActionMenuView menuParent = (ActionMenuView) parent;
        final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
        if (!menuParent.checkLayoutParams(lp)) {
            actionView.setLayoutParams(menuParent.generateLayoutParams(lp));
        }
        return actionView;
    }

    @Override
    public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) {
        itemView.initialize(item, 0);
        ((ActionMenuItemView) itemView).setItemInvoker((ActionMenuView) mMenuView);

        final ActionMenuView menuView = (ActionMenuView) mMenuView;
        ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
        actionItemView.setItemInvoker(menuView);
        if (false) actionItemView.setExpandedFormat(menuView.isExpandedFormat());
    }

    @Override
@@ -150,15 +168,14 @@ public class ActionMenuPresenter extends BaseMenuPresenter {
        if (mReserveOverflow && mMenu.getNonActionItems().size() > 0) {
            if (mOverflowButton == null) {
                mOverflowButton = new OverflowMenuButton(mContext);
                mOverflowButton.setLayoutParams(
                        ((ActionMenuView) mMenuView).generateOverflowButtonLayoutParams());
            }
            ViewGroup parent = (ViewGroup) mOverflowButton.getParent();
            if (parent != mMenuView) {
                if (parent != null) {
                    parent.removeView(mOverflowButton);
                }
                ((ViewGroup) mMenuView).addView(mOverflowButton);
                ActionMenuView menuView = (ActionMenuView) mMenuView;
                menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams());
            }
        } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) {
            ((ViewGroup) mMenuView).removeView(mOverflowButton);
@@ -313,19 +330,29 @@ public class ActionMenuPresenter extends BaseMenuPresenter {
        final SparseBooleanArray seenGroups = mActionButtonGroups;
        seenGroups.clear();

        int cellSize = 0;
        int cellsRemaining = 0;
        if (mStrictWidthLimit) {
            cellsRemaining = widthLimit / mMinCellSize;
            final int cellSizeRemaining = widthLimit % mMinCellSize;
            cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining;
        }

        // Flag as many more requested items as will fit.
        for (int i = 0; i < itemsSize; i++) {
            MenuItemImpl item = visibleItems.get(i);

            if (item.requiresActionButton()) {
                View v = item.getActionView();
                if (v == null || item.hasCollapsibleActionView()) {
                    v = getItemView(item, mScrapActionButtonView, parent);
                View v = getItemView(item, mScrapActionButtonView, parent);
                if (mScrapActionButtonView == null) {
                    mScrapActionButtonView = v;
                }
                }
                if (mStrictWidthLimit) {
                    cellsRemaining -= ActionMenuView.measureChildForCells(v,
                            cellSize, cellsRemaining, querySpec, 0);
                } else {
                    v.measure(querySpec, querySpec);
                }
                final int measuredWidth = v.getMeasuredWidth();
                widthLimit -= measuredWidth;
                if (firstActionWidth == 0) {
@@ -341,18 +368,25 @@ public class ActionMenuPresenter extends BaseMenuPresenter {
                // can break the max actions rule, but not the width limit.
                final int groupId = item.getGroupId();
                final boolean inGroup = seenGroups.get(groupId);
                boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0;
                boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 &&
                        (!mStrictWidthLimit || cellsRemaining > 0);
                maxActions--;

                if (isAction) {
                    View v = item.getActionView();
                    if (v == null || item.hasCollapsibleActionView()) {
                        v = getItemView(item, mScrapActionButtonView, parent);
                    View v = getItemView(item, mScrapActionButtonView, parent);
                    if (mScrapActionButtonView == null) {
                        mScrapActionButtonView = v;
                    }
                    if (mStrictWidthLimit) {
                        final int cells = ActionMenuView.measureChildForCells(v,
                                cellSize, cellsRemaining, querySpec, 0);
                        cellsRemaining -= cells;
                        if (cells == 0) {
                            isAction = false;
                        }
                    } else {
                        v.measure(querySpec, querySpec);
                    }
                    final int measuredWidth = v.getMeasuredWidth();
                    widthLimit -= measuredWidth;
                    if (firstActionWidth == 0) {
@@ -360,10 +394,10 @@ public class ActionMenuPresenter extends BaseMenuPresenter {
                    }

                    if (mStrictWidthLimit) {
                        isAction = widthLimit >= 0;
                        isAction &= widthLimit >= 0;
                    } else {
                        // Did this push the entire first item past the limit?
                        isAction = widthLimit + firstActionWidth > 0;
                        isAction &= widthLimit + firstActionWidth > 0;
                    }
                }

@@ -414,7 +448,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter {
        }

        public boolean needsDividerBefore() {
            return true;
            return false;
        }

        public boolean needsDividerAfter() {
+217 −11

File changed.

Preview size limit exceeded, changes collapsed.

Loading