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

Commit 55807c97 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Anchor a cascading submenu to its parent menu item"

parents 424c8c17 b40e61b7
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ public class ListPopupWindow implements ShowableListMenu {
    private int mDropDownWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
    private boolean mDropDownVerticalOffsetSet;
    private boolean mIsAnimatedFromAnchor = true;
    private boolean mOverlapAnchor;

    private int mDropDownGravity = Gravity.NO_GRAVITY;

@@ -672,6 +673,7 @@ public class ListPopupWindow implements ShowableListMenu {
            mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible);
            mPopup.setTouchInterceptor(mTouchInterceptor);
            mPopup.setEpicenterBounds(mEpicenterBounds);
            mPopup.setOverlapAnchor(mOverlapAnchor);
            mPopup.showAsDropDown(getAnchorView(), mDropDownHorizontalOffset,
                    mDropDownVerticalOffset, mDropDownGravity);
            mDropDownList.setSelection(ListView.INVALID_POSITION);
@@ -1245,6 +1247,13 @@ public class ListPopupWindow implements ShowableListMenu {
        return listContent + otherHeights;
    }

    /**
     * @hide
     */
    public void setOverlapAnchor(boolean overlap) {
        mOverlapAnchor = overlap;
    }

    private class PopupDataSetObserver extends DataSetObserver {
        @Override
        public void onChanged() {
+33 −8
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
import android.view.WindowManagerGlobal;

import com.android.internal.R;

@@ -137,6 +138,7 @@ public class PopupWindow {

    private final int[] mTmpDrawingLocation = new int[2];
    private final int[] mTmpScreenLocation = new int[2];
    private final int[] mTmpAppLocation = new int[2];
    private final Rect mTempRect = new Rect();

    private Context mContext;
@@ -242,6 +244,9 @@ public class PopupWindow {

    private final OnScrollChangedListener mOnScrollChangedListener = this::alignToAnchor;

    private final View.OnLayoutChangeListener mOnLayoutChangeListener =
            (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> alignToAnchor();

    private int mAnchorXoff;
    private int mAnchorYoff;
    private int mAnchoredGravity;
@@ -1238,7 +1243,8 @@ public class PopupWindow {
        mIsShowing = true;
        mIsDropdown = true;

        final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken());
        final WindowManager.LayoutParams p =
                createPopupLayoutParams(anchor.getApplicationWindowToken());
        preparePopup(p);

        final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff,
@@ -1547,13 +1553,21 @@ public class PopupWindow {
        }

        // Initially, align to the bottom-left corner of the anchor plus offsets.
        final int[] appScreenLocation = mTmpAppLocation;
        final View appRootView = getAppRootView(anchor);
        appRootView.getLocationOnScreen(appScreenLocation);

        final int[] screenLocation = mTmpScreenLocation;
        anchor.getLocationOnScreen(screenLocation);

        final int[] drawingLocation = mTmpDrawingLocation;
        anchor.getLocationInWindow(drawingLocation);
        drawingLocation[0] = screenLocation[0] - appScreenLocation[0];
        drawingLocation[1] = screenLocation[1] - appScreenLocation[1];
        outParams.x = drawingLocation[0] + xOffset;
        outParams.y = drawingLocation[1] + anchorHeight + yOffset;

        final Rect displayFrame = new Rect();
        anchor.getWindowVisibleDisplayFrame(displayFrame);
        appRootView.getWindowVisibleDisplayFrame(displayFrame);
        if (width == MATCH_PARENT) {
            width = displayFrame.right - displayFrame.left;
        }
@@ -1574,9 +1588,6 @@ public class PopupWindow {
            outParams.x -= width - anchorWidth;
        }

        final int[] screenLocation = mTmpScreenLocation;
        anchor.getLocationOnScreen(screenLocation);

        // First, attempt to fit the popup vertically without resizing.
        final boolean fitsVertical = tryFitVertical(outParams, yOffset, height,
                anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top,
@@ -1595,7 +1606,9 @@ public class PopupWindow {
                    scrollY + height + anchorHeight + yOffset);
            if (allowScroll && anchor.requestRectangleOnScreen(r, true)) {
                // Reset for the new anchor position.
                anchor.getLocationInWindow(drawingLocation);
                anchor.getLocationOnScreen(screenLocation);
                drawingLocation[0] = screenLocation[0] - appScreenLocation[0];
                drawingLocation[1] = screenLocation[1] - appScreenLocation[1];
                outParams.x = drawingLocation[0] + xOffset;
                outParams.y = drawingLocation[1] + anchorHeight + yOffset;

@@ -1793,7 +1806,8 @@ public class PopupWindow {
        Rect displayFrame = null;
        final Rect visibleDisplayFrame = new Rect();

        anchor.getWindowVisibleDisplayFrame(visibleDisplayFrame);
        final View appView = getAppRootView(anchor);
        appView.getWindowVisibleDisplayFrame(visibleDisplayFrame);
        if (ignoreBottomDecorations) {
            // In the ignore bottom decorations case we want to
            // still respect all other decorations so we use the inset visible
@@ -2240,6 +2254,7 @@ public class PopupWindow {
        final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null;
        if (anchorRoot != null) {
            anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
            anchorRoot.removeOnLayoutChangeListener(mOnLayoutChangeListener);
        }

        mAnchor = null;
@@ -2258,6 +2273,7 @@ public class PopupWindow {

        final View anchorRoot = anchor.getRootView();
        anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener);
        anchorRoot.addOnLayoutChangeListener(mOnLayoutChangeListener);

        mAnchor = new WeakReference<>(anchor);
        mAnchorRoot = new WeakReference<>(anchorRoot);
@@ -2281,6 +2297,15 @@ public class PopupWindow {
        }
    }

    private View getAppRootView(View anchor) {
        final View appWindowView = WindowManagerGlobal.getInstance().getWindowView(
                anchor.getApplicationWindowToken());
        if (appWindowView != null) {
            return appWindowView;
        }
        return anchor.getRootView();
    }

    private class PopupDecorView extends FrameLayout {
        private TransitionListenerAdapter mPendingExitListener;

+10 −21
Original line number Diff line number Diff line
@@ -381,6 +381,7 @@ final class CascadingMenuPopup extends MenuPopup implements MenuPresenter, OnKey

        if (parentView != null) {
            // This menu is a cascading submenu anchored to a parent view.
            popupWindow.setAnchorView(parentView);
            popupWindow.setTouchModal(false);
            popupWindow.setEnterTransition(null);

@@ -388,42 +389,30 @@ final class CascadingMenuPopup extends MenuPopup implements MenuPresenter, OnKey
            final boolean showOnRight = nextMenuPosition == HORIZ_POSITION_RIGHT;
            mLastPosition = nextMenuPosition;

            // A popup anchored to mAnchorView with (0,0) offset would be shown at this position.
            final int[] offsetOrigin = new int[2];
            mAnchorView.getLocationOnScreen(offsetOrigin);
            offsetOrigin[1] += mAnchorView.getHeight();

            final int[] parentViewScreenLocation = new int[2];
            parentView.getLocationOnScreen(parentViewScreenLocation);

            // Translate the parent view location into the offset coordinate space.
            // If used as horizontal/vertical offsets, these values would position the submenu
            // at the exact same position as the parent item.
            final int parentOffsetLeft = parentViewScreenLocation[0] - offsetOrigin[0];
            final int parentOffsetTop = parentViewScreenLocation[1] - offsetOrigin[1];

            // Adjust the horizontal offset to display the submenu to the right or to the left
            // Compute the horizontal offset to display the submenu to the right or to the left
            // of the parent item.
            // By now, mDropDownGravity is the resolved absolute gravity, so
            // this should work in both LTR and RTL.
            final int x;
            if ((mDropDownGravity & Gravity.RIGHT) == Gravity.RIGHT) {
                if (showOnRight) {
                    x = parentOffsetLeft + menuWidth;
                    x = menuWidth;
                } else {
                    x = parentOffsetLeft - parentView.getWidth();
                    x = -parentView.getWidth();
                }
            } else {
                if (showOnRight) {
                    x = parentOffsetLeft + parentView.getWidth();
                    x = parentView.getWidth();
                } else {
                    x = parentOffsetLeft - menuWidth;
                    x = -menuWidth;
                }
            }
            popupWindow.setHorizontalOffset(x);

            // Use the same vertical offset as the parent item.
            popupWindow.setVerticalOffset(parentOffsetTop);
            // Align with the top edge of the parent view (or the bottom edge when the submenu is
            // flipped vertically).
            popupWindow.setOverlapAnchor(true);
            popupWindow.setVerticalOffset(0);
        } else {
            if (mHasXOffset) {
                popupWindow.setHorizontalOffset(mXOffset);