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

Commit 8375d639 authored by Alan Viverette's avatar Alan Viverette
Browse files

Reduce CascadingMenuPopup's reliance on internal ListView state

Bundles cascading menu information and stores it in a stack representing
the hierarchy of added menus.

Bug: 23970448
Change-Id: Icc0a96ea2dd4320fd4dae9626435ed82a6165480
parent 3e832afe
Loading
Loading
Loading
Loading
+0 −17
Original line number Diff line number Diff line
@@ -159,23 +159,6 @@ public class DropDownListView extends ListView {
        return super.onHoverEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final int x = (int) event.getX();
        final int y = (int) event.getY();
        final int position = pointToPosition(x, y);
        if (position == INVALID_POSITION) {
            return super.onTouchEvent(event);
        }

        if (position != mSelectedPosition) {
            setSelectedPositionInt(position);
            setNextSelectedPositionInt(position);
        }

        return super.onTouchEvent(event);
    }

    /**
     * Handles forwarded events.
     *
+20 −1
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@ package android.widget;

import com.android.internal.view.menu.MenuBuilder;

import android.annotation.NonNull;

/**
 * An interface notified when a menu item is hovered. Useful for cases when hover should trigger
 * some behavior at a higher level, like managing the opening and closing of submenus.
@@ -9,5 +11,22 @@ import com.android.internal.view.menu.MenuBuilder;
 * @hide
 */
public interface MenuItemHoverListener {
    public void onItemHovered(MenuBuilder menu, int position);
    /**
     * Called when hover exits a menu item.
     * <p>
     * If hover is moving to another item, this method will be called before
     * {@link #onItemHoverEnter(MenuBuilder, int)} for the newly-hovered item.
     *
     * @param menu the item's parent menu
     * @param position the position of the item within the menu
     */
    void onItemHoverExit(@NonNull MenuBuilder menu, int position);

    /**
     * Called when hover enters a menu item.
     *
     * @param menu the item's parent menu
     * @param position the position of the item within the menu
     */
    void onItemHoverEnter(@NonNull MenuBuilder menu, int position);
}
+32 −21
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.widget;

import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -72,10 +73,18 @@ public class MenuPopupWindow extends ListPopupWindow implements MenuItemHoverLis
    }

    @Override
    public void onItemHovered(MenuBuilder menu, int position) {
    public void onItemHoverEnter(@NonNull MenuBuilder menu, int position) {
        // Forward up the chain
        if (mHoverListener != null) {
            mHoverListener.onItemHovered(menu, position);
            mHoverListener.onItemHoverEnter(menu, position);
        }
    }

    @Override
    public void onItemHoverExit(@NonNull MenuBuilder menu, int position) {
        // Forward up the chain
        if (mHoverListener != null) {
            mHoverListener.onItemHoverExit(menu, position);
        }
    }

@@ -88,6 +97,8 @@ public class MenuPopupWindow extends ListPopupWindow implements MenuItemHoverLis

        private MenuItemHoverListener mHoverListener;

        private int mPreviouslyHoveredPosition = INVALID_POSITION;

        public MenuDropDownListView(Context context, boolean hijackFocus) {
            super(context, hijackFocus);

@@ -135,25 +146,17 @@ public class MenuPopupWindow extends ListPopupWindow implements MenuItemHoverLis

        @Override
        public boolean onHoverEvent(MotionEvent ev) {
            boolean dispatchHover = false;
            final int position = pointToPosition((int) ev.getX(), (int) ev.getY());

            final int action = ev.getActionMasked();
            if (action == MotionEvent.ACTION_HOVER_ENTER
                    || action == MotionEvent.ACTION_HOVER_MOVE) {
                if (position != INVALID_POSITION && position != mSelectedPosition) {
                    final View hoveredItem = getChildAt(position - getFirstVisiblePosition());
                    if (hoveredItem.isEnabled()) {
                        dispatchHover = true;
                    }
                }
            final int position;
            if (ev.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
                position = INVALID_POSITION;
            } else {
                position = pointToPosition((int) ev.getX(), (int) ev.getY());
            }

            boolean superVal = super.onHoverEvent(ev);

            if (dispatchHover && mHoverListener != null) {
                ListAdapter adapter = getAdapter();
                MenuAdapter menuAdapter;
            // Dispatch any changes in hovered position to the listener.
            if (mHoverListener != null && mPreviouslyHoveredPosition != position) {
                final ListAdapter adapter = getAdapter();
                final MenuAdapter menuAdapter;
                if (adapter instanceof HeaderViewListAdapter) {
                    menuAdapter = (MenuAdapter) ((HeaderViewListAdapter) adapter)
                            .getWrappedAdapter();
@@ -161,10 +164,18 @@ public class MenuPopupWindow extends ListPopupWindow implements MenuItemHoverLis
                    menuAdapter = (MenuAdapter) adapter;
                }

                mHoverListener.onItemHovered(menuAdapter.getAdapterMenu(), position);
                final MenuBuilder menu = menuAdapter.getAdapterMenu();
                if (mPreviouslyHoveredPosition != INVALID_POSITION) {
                    mHoverListener.onItemHoverExit(menu, mPreviouslyHoveredPosition);
                }
                if (position != INVALID_POSITION) {
                    mHoverListener.onItemHoverEnter(menu, position);
                }
            }

            mPreviouslyHoveredPosition = position;

            return superVal;
            return super.onHoverEvent(ev);
        }
    }
}
 No newline at end of file
+279 −197

File changed.

Preview size limit exceeded, changes collapsed.

+8 −9
Original line number Diff line number Diff line
@@ -936,15 +936,14 @@ public class MenuBuilder implements Menu {
    }
    
    /**
     * Closes the visible menu.
     * Closes the menu.
     *
     * @param allMenusAreClosing Whether the menus are completely closing (true),
     *            or whether there is another menu coming in this menu's place
     *            (false). For example, if the menu is closing because a
     *            sub menu is about to be shown, <var>allMenusAreClosing</var>
     *            is false.
     * @param closeAllMenus {@code true} if all displayed menus and submenus
     *                      should be completely closed (as when a menu item is
     *                      selected) or {@code false} if only this menu should
     *                      be closed
     */
    public final void close(boolean allMenusAreClosing) {
    public final void close(boolean closeAllMenus) {
        if (mIsClosing) return;

        mIsClosing = true;
@@ -953,7 +952,7 @@ public class MenuBuilder implements Menu {
            if (presenter == null) {
                mPresenters.remove(ref);
            } else {
                presenter.onCloseMenu(this, allMenusAreClosing);
                presenter.onCloseMenu(this, closeAllMenus);
            }
        }
        mIsClosing = false;
Loading