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

Commit 381cb272 authored by ryanlwlin's avatar ryanlwlin Committed by Shubham Basu
Browse files

Fix preview icon tapping behavior when magnifying the screen

We user the unscaled coordinate to determine whether the event is
in the bounds of the view. It doesn't work in magnification scenario
because the view size is not changed and getRawX()/getRawY() is the actual
position on the screen.

To fix it, we determine it in the parent's coordinate. In our case
the event is dispatched from RecyclerView, so the calculation is in
Recyclerview's coordinate

Bug: 152265995
Test: manual test
Change-Id: If6e2497641d16b92542f3fc6576929c52fe48fbb
parent 5cbf2448
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -81,7 +81,8 @@ final class GridDirectoryHolder extends DocumentHolder {

    @Override
    public boolean inSelectRegion(MotionEvent event) {
        return mAction == State.ACTION_BROWSE ? Views.isEventOver(event, mIconLayout) : false;
        return mAction == State.ACTION_BROWSE ? Views.isEventOver(event, itemView.getParent(),
                mIconLayout) : false;
    }

    /**
+2 −2
Original line number Diff line number Diff line
@@ -137,12 +137,12 @@ final class GridDocumentHolder extends DocumentHolder {

    @Override
    public boolean inSelectRegion(MotionEvent event) {
        return Views.isEventOver(event, mIconLayout);
        return Views.isEventOver(event, itemView.getParent(), mIconLayout);
    }

    @Override
    public boolean inPreviewIconRegion(MotionEvent event) {
        return Views.isEventOver(event, mPreviewIcon);
        return Views.isEventOver(event, itemView.getParent(), mPreviewIcon);
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ final class GridPhotoHolder extends DocumentHolder {

    @Override
    public boolean inPreviewIconRegion(MotionEvent event) {
        return Views.isEventOver(event, mPreviewIcon);
        return Views.isEventOver(event, itemView.getParent(), mPreviewIcon);
    }

    /**
+2 −2
Original line number Diff line number Diff line
@@ -180,12 +180,12 @@ final class ListDocumentHolder extends DocumentHolder {
    @Override
    public boolean inSelectRegion(MotionEvent event) {
        return (mDoc.isDirectory() && !(mAction == State.ACTION_BROWSE)) ?
                false : Views.isEventOver(event, mIconLayout);
                false : Views.isEventOver(event, itemView.getParent(), mIconLayout);
    }

    @Override
    public boolean inPreviewIconRegion(MotionEvent event) {
        return Views.isEventOver(event, mPreviewIcon);
        return Views.isEventOver(event, itemView.getParent(), mPreviewIcon);
    }

    /**
+29 −5
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.documentsui.ui;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

/**
 * A utility class for working with Views.
@@ -28,22 +30,44 @@ public final class Views {
    private Views() {}

    /**
     * Return whether the event is in the view's region
     *
     * Return whether the event is in the view's region. We determine it with in the coordinate
     * of the parent view that dispatches the motion event.
     * @param event the motion event
     * @param eventSource the view dispatching the motion events.
     * @param view the view to check the selection region
     * @return True, if the event is in the region. Otherwise, return false.
     */
    public static boolean isEventOver(MotionEvent event, View view) {

    public static boolean isEventOver(MotionEvent event, ViewParent eventSource, View view) {
        if (view == null || event == null || !view.isAttachedToWindow()) {
            return false;
        }

        View parent = null;
        if (eventSource instanceof ViewGroup) {
            parent = (View) eventSource;
        }

        final Rect viewBoundsOnGlobalCoordinate = getBoundsOnScreen(view);

        // If the parent is null, it means view is the view root of the window, so the event
        // should be from view itself, in this case we don't need any offset.
        final int[] viewParentCoord = new int[2];
        if (parent != null) {
            parent.getLocationOnScreen(viewParentCoord);
        }

        Rect viewBoundsOnParentViewCoordinate = new Rect(viewBoundsOnGlobalCoordinate);
        viewBoundsOnParentViewCoordinate.offset(-viewParentCoord[0], -viewParentCoord[1]);
        return viewBoundsOnParentViewCoordinate.contains((int) event.getX(), (int) event.getY());
    }

    private static Rect getBoundsOnScreen(View view) {
        final int[] coord = new int[2];
        view.getLocationOnScreen(coord);

        final Rect viewRect = new Rect(coord[0], coord[1], coord[0] + view.getMeasuredWidth(),
        return new Rect(coord[0], coord[1], coord[0] + view.getMeasuredWidth(),
                coord[1] + view.getMeasuredHeight());

        return viewRect.contains((int) event.getRawX(), (int) event.getRawY());
    }
}