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

Commit bc6c050f authored by Chet Haase's avatar Chet Haase Committed by Android (Google) Code Review
Browse files

Merge "Fix touch processing for Overlay views" into jb-mr2-dev

parents 51163e3b 9c17fe69
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -18,9 +18,10 @@ package android.view;
import android.graphics.drawable.Drawable;

/**
 * An overlay is an extra layer that sits on top of a View (the "host view") which is drawn after
 * all other content in that view (including children, if the view is a ViewGroup). Interaction
 * with the overlay layer is done in terms of adding/removing views and drawables.
 * An overlay is an extra layer that sits on top of a View (the "host view")
 * which is drawn after all other content in that view (including children,
 * if the view is a ViewGroup). Interaction with the overlay layer is done in
 * terms of adding/removing views and drawables.
 *
 * @see android.view.View#getOverlay()
 */
@@ -47,10 +48,16 @@ public interface Overlay {
    void remove(Drawable drawable);

    /**
     * Adds a View to the overlay. The bounds of the added view should be relative to
     * the host view. Any view added to the overlay should be removed when it is no longer
     * needed or no longer visible. The view must not be parented elsewhere when it is added
     * to the overlay.
     * Adds a View to the overlay. The bounds of the added view should be
     * relative to the host view. Any view added to the overlay should be
     * removed when it is no longer needed or no longer visible.
     *
     * <p>If the view has a parent, the view will be removed from that parent
     * before being added to the overlay. Also, the view will be repositioned
     * such that it is in the same relative location inside the activity. For
     * example, if the view's current parent lies 100 pixels to the right
     * and 200 pixels down from the origin of the overlay's
     * host view, then the view will be offset by (100, 200).</p>
     *
     * @param view The View to be added to the overlay. The added view will be
     * drawn when the overlay is drawn.
+2 −2
Original line number Diff line number Diff line
@@ -12098,7 +12098,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        //System.out.println("Attached! " + this);
        mAttachInfo = info;
        if (mOverlay != null) {
            mOverlay.mAttachInfo = info;
            mOverlay.dispatchAttachedToWindow(info, visibility);
        }
        mWindowAttachCount++;
        // We will need to evaluate the drawable state at least once.
@@ -12169,7 +12169,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        mAttachInfo = null;
        if (mOverlay != null) {
            mOverlay.mAttachInfo = null;
            mOverlay.dispatchDetachedFromWindow();
        }
    }
+28 −25
Original line number Diff line number Diff line
@@ -1868,13 +1868,37 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                    // have become out of sync.
                    removePointersFromTouchTargets(idBitsToAssign);

                    final float x = ev.getX(actionIndex);
                    final float y = ev.getY(actionIndex);

                    if (mOverlay != null) {
                        ViewOverlay overlay = (ViewOverlay) mOverlay;
                        // Check to see whether the overlay can handle the event
                        final View child = mOverlay;
                        if (canViewReceivePointerEvents(child) &&
                                isTransformedTouchPointInView(x, y, child, null)) {
                            newTouchTarget = getTouchTarget(child);
                            if (newTouchTarget != null) {
                                newTouchTarget.pointerIdBits |= idBitsToAssign;
                            } else {
                                resetCancelNextUpFlag(child);
                                if (dispatchTransformedTouchEvent(ev, false, child,
                                        idBitsToAssign)) {
                                    mLastTouchDownTime = ev.getDownTime();
                                    mLastTouchDownX = ev.getX();
                                    mLastTouchDownY = ev.getY();
                                    newTouchTarget = addTouchTarget(child, idBitsToAssign);
                                    alreadyDispatchedToNewTouchTarget = true;
                                }
                            }
                        }
                    }

                    final int childrenCount = mChildrenCount;
                    if (childrenCount != 0 || mOverlay != null) {
                    if (newTouchTarget == null && childrenCount != 0) {
                        // Find a child that can receive the event.
                        // Scan children from front to back.
                        final View[] children = mChildren;
                        final float x = ev.getX(actionIndex);
                        final float y = ev.getY(actionIndex);

                        final boolean customOrder = isChildrenDrawingOrderEnabled();
                        for (int i = childrenCount - 1; i >= 0; i--) {
@@ -1906,27 +1930,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                                break;
                            }
                        }
                        if (mOverlay != null && newTouchTarget == null) {
                            // Check to see whether the overlay can handle the event
                            final View child = mOverlay;
                            if (canViewReceivePointerEvents(child) &&
                                    isTransformedTouchPointInView(x, y, child, null)) {
                                newTouchTarget = getTouchTarget(child);
                                if (newTouchTarget != null) {
                                    newTouchTarget.pointerIdBits |= idBitsToAssign;
                                } else {
                                    resetCancelNextUpFlag(child);
                                    if (dispatchTransformedTouchEvent(ev, false, child,
                                            idBitsToAssign)) {
                                        mLastTouchDownTime = ev.getDownTime();
                                        mLastTouchDownX = ev.getX();
                                        mLastTouchDownY = ev.getY();
                                        newTouchTarget = addTouchTarget(child, idBitsToAssign);
                                        alreadyDispatchedToNewTouchTarget = true;
                                    }
                                }
                            }
                        }
                    }

                    if (newTouchTarget == null && mFirstTouchTarget != null) {
+38 −11
Original line number Diff line number Diff line
@@ -23,17 +23,21 @@ import android.graphics.drawable.Drawable;
import java.util.ArrayList;

/**
 * ViewOverlay is a container that View uses to host all objects (views and drawables) that
 * are added to its "overlay", gotten through {@link View#getOverlay()}. Views and drawables are
 * added to the overlay via the add/remove methods in this class. These views and drawables are
 * drawn whenever the view itself is drawn; first the view draws its own content (and children,
 * if it is a ViewGroup), then it draws its overlay (if it has one).
 * ViewOverlay is a container that View uses to host all objects (views and
 * drawables) that are added to its "overlay", gotten through
 * {@link View#getOverlay()}. Views and drawables are added to the overlay
 * via the add/remove methods in this class. These views and drawables are
 * drawn whenever the view itself is drawn; first the view draws its own
 * content (and children, if it is a ViewGroup), then it draws its overlay
 * (if it has one).
 *
 * Besides managing and drawing the list of drawables, this class serves two purposes:
 * Besides managing and drawing the list of drawables, this class serves
 * two purposes:
 * (1) it noops layout calls because children are absolutely positioned and
 * (2) it forwards all invalidation calls to its host view. The invalidation redirect is
 * necessary because the overlay is not a child of the host view and invalidation cannot
 * therefore follow the normal path up through the parent hierarchy.
 * (2) it forwards all invalidation calls to its host view. The invalidation
 * redirect is necessary because the overlay is not a child of the host view
 * and invalidation cannot therefore follow the normal path up through the
 * parent hierarchy.
 *
 * @hide
 */
@@ -85,6 +89,22 @@ class ViewOverlay extends ViewGroup implements Overlay {

    @Override
    public void add(View child) {
        int deltaX = 0;
        int deltaY = 0;
        if (child.getParent() instanceof ViewGroup) {
            ViewGroup parent = (ViewGroup) child.getParent();
            if (parent != mHostView) {
                // Moving to different container; figure out how to position child such that
                // it is in the same location on the screen
                int[] parentLocation = new int[2];
                int[] hostViewLocation = new int[2];
                parent.getLocationOnScreen(parentLocation);
                mHostView.getLocationOnScreen(hostViewLocation);
                child.offsetLeftAndRight(parentLocation[0] - hostViewLocation[0]);
                child.offsetTopAndBottom(parentLocation[1] - hostViewLocation[1]);
            }
            parent.removeView(child);
        }
        super.addView(child);
    }

@@ -133,7 +153,6 @@ class ViewOverlay extends ViewGroup implements Overlay {
    public void invalidate(Rect dirty) {
        super.invalidate(dirty);
        if (mHostView != null) {
            dirty.offset(getLeft(), getTop());
            mHostView.invalidate(dirty);
        }
    }
@@ -203,7 +222,15 @@ class ViewOverlay extends ViewGroup implements Overlay {
    @Override
    public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
        if (mHostView != null) {
            mHostView.invalidate(dirty);
            dirty.offset(location[0], location[1]);
            if (mHostView instanceof ViewGroup) {
                location[0] = 0;
                location[1] = 0;
                super.invalidateChildInParent(location, dirty);
                return ((ViewGroup) mHostView).invalidateChildInParent(location, dirty);
            } else {
                invalidate(dirty);
            }
        }
        return null;
    }