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

Commit 878f6d38 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Fixing FloatingIconView position and rotation in rotated layout

Bug: 131360075
Change-Id: I4e39f35df99a07e00f3e86865b330d91e9461da0
parent a3c0a082
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ public final class Utilities {
    public static float getDescendantCoordRelativeToAncestor(
            View descendant, View ancestor, float[] coord, boolean includeRootScroll) {
        return getDescendantCoordRelativeToAncestor(descendant, ancestor, coord, includeRootScroll,
                false);
                false, null);
    }

    /**
@@ -180,12 +180,15 @@ public final class Utilities {
     * @param includeRootScroll Whether or not to account for the scroll of the descendant:
     *          sometimes this is relevant as in a child's coordinates within the descendant.
     * @param ignoreTransform If true, view transform is ignored
     * @param outRotation If not null, and {@param ignoreTransform} is true, this is set to the
     *                   overall rotation of the view in degrees.
     * @return The factor by which this descendant is scaled relative to this DragLayer. Caution
     *         this scale factor is assumed to be equal in X and Y, and so if at any point this
     *         assumption fails, we will need to return a pair of scale factors.
     */
    public static float getDescendantCoordRelativeToAncestor(View descendant, View ancestor,
            float[] coord, boolean includeRootScroll, boolean ignoreTransform) {
            float[] coord, boolean includeRootScroll, boolean ignoreTransform,
            float[] outRotation) {
        float scale = 1.0f;
        View v = descendant;
        while(v != ancestor && v != null) {
@@ -201,6 +204,10 @@ public final class Utilities {
                    if (m.isTransposed) {
                        sMatrix.setRotate(m.surfaceRotation, v.getPivotX(), v.getPivotY());
                        sMatrix.mapPoints(coord);

                        if (outRotation != null) {
                            outRotation[0] += m.surfaceRotation;
                        }
                    }
                }
            } else {
+41 −58
Original line number Diff line number Diff line
@@ -15,8 +15,6 @@
 */
package com.android.launcher3.views;

import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
import static com.android.launcher3.Utilities.mapToRange;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
@@ -86,6 +84,7 @@ public class FloatingIconView extends View implements Animator.AnimatorListener,

    private @Nullable Drawable mForeground;
    private @Nullable Drawable mBackground;
    private float mRotation;
    private ValueAnimator mRevealAnimator;
    private final Rect mStartRevealRect = new Rect();
    private final Rect mEndRevealRect = new Rect();
@@ -190,7 +189,7 @@ public class FloatingIconView extends View implements Animator.AnimatorListener,
     * @param positionOut Rect that will hold the size and position of v.
     */
    private void matchPositionOf(Launcher launcher, View v, RectF positionOut) {
        getLocationBoundsForView(launcher, v, positionOut);
        mRotation = getLocationBoundsForView(launcher, v, positionOut);
        final LayoutParams lp = new LayoutParams(
                Math.round(positionOut.width()),
                Math.round(positionOut.height()));
@@ -207,54 +206,43 @@ public class FloatingIconView extends View implements Animator.AnimatorListener,
    }

    /**
     * Returns the location bounds of a view.
     * Gets the location bounds of a view and returns the overall rotation.
     * - For DeepShortcutView, we return the bounds of the icon view.
     * - For BubbleTextView, we return the icon bounds.
     */
    private void getLocationBoundsForView(Launcher launcher, View v, RectF outRect) {
        final boolean isBubbleTextView = v instanceof BubbleTextView;
        final boolean isFolderIcon = v instanceof FolderIcon;

        // Deep shortcut views have their icon drawn in a separate view.
        final boolean fromDeepShortcutView = v.getParent() instanceof DeepShortcutView;

        final View targetView;
        boolean ignoreTransform = false;

    private float getLocationBoundsForView(Launcher launcher, View v, RectF outRect) {
        boolean ignoreTransform = true;
        if (v instanceof DeepShortcutView) {
            targetView = ((DeepShortcutView) v).getIconView();
        } else if (fromDeepShortcutView) {
            DeepShortcutView view = (DeepShortcutView) v.getParent();
            targetView = view.getIconView();
        } else if ((isBubbleTextView || isFolderIcon) && v.getTag() instanceof ItemInfo
                && (((ItemInfo) v.getTag()).container == CONTAINER_DESKTOP
                || ((ItemInfo) v.getTag()).container == CONTAINER_HOTSEAT)) {
            targetView = v;
            ignoreTransform = true;
        } else {
            targetView = v;
            v = ((DeepShortcutView) v).getBubbleText();
            ignoreTransform = false;
        } else if (v.getParent() instanceof DeepShortcutView) {
            v = ((DeepShortcutView) v.getParent()).getIconView();
            ignoreTransform = false;
        }
        if (v == null) {
            return 0;
        }

        float[] points = new float[] {0, 0, targetView.getWidth(), targetView.getHeight()};
        Utilities.getDescendantCoordRelativeToAncestor(targetView, launcher.getDragLayer(), points,
                false, ignoreTransform);

        float viewLocationLeft = Math.min(points[0], points[2]);
        float viewLocationTop = Math.min(points[1], points[3]);

        final Rect iconRect = new Rect();
        if (isBubbleTextView && !fromDeepShortcutView) {
            ((BubbleTextView) v).getIconBounds(iconRect);
        } else if (isFolderIcon) {
            ((FolderIcon) v).getPreviewBounds(iconRect);
        Rect iconBounds = new Rect();
        if (v instanceof BubbleTextView) {
            ((BubbleTextView) v).getIconBounds(iconBounds);
        } else if (v instanceof FolderIcon) {
            ((FolderIcon) v).getPreviewBounds(iconBounds);
        } else {
            iconRect.set(0, 0, Math.abs(Math.round(points[2] - points[0])),
                    Math.abs(Math.round(points[3] - points[1])));
            iconBounds.set(0, 0, v.getWidth(), v.getHeight());
        }
        viewLocationLeft += iconRect.left;
        viewLocationTop += iconRect.top;
        outRect.set(viewLocationLeft, viewLocationTop, viewLocationLeft + iconRect.width(),
                viewLocationTop + iconRect.height());

        float[] points = new float[] {iconBounds.left, iconBounds.top, iconBounds.right,
                iconBounds.bottom};
        float[] rotation = new float[] {0};
        Utilities.getDescendantCoordRelativeToAncestor(v, launcher.getDragLayer(), points,
                false, ignoreTransform, rotation);
        outRect.set(
                Math.min(points[0], points[2]),
                Math.min(points[1], points[3]),
                Math.max(points[0], points[2]),
                Math.max(points[1], points[3]));
        return rotation[0];
    }

    @WorkerThread
@@ -425,28 +413,23 @@ public class FloatingIconView extends View implements Animator.AnimatorListener,
        invalidate();
    }

    private void drawAdaptiveIconIfExists(Canvas canvas) {
    @Override
    public void draw(Canvas canvas) {
        int count = canvas.save();
        canvas.rotate(mRotation,
                mFinalDrawableBounds.exactCenterX(), mFinalDrawableBounds.exactCenterY());
        if (mClipPath != null) {
            canvas.clipPath(mClipPath);
        }
        super.draw(canvas);
        if (mBackground != null) {
            mBackground.draw(canvas);
        }
        if (mForeground != null) {
            mForeground.draw(canvas);
        }
    }

    @Override
    public void draw(Canvas canvas) {
        if (mClipPath == null) {
            super.draw(canvas);
            drawAdaptiveIconIfExists(canvas);
        } else {
            int count = canvas.save();
            canvas.clipPath(mClipPath);
            super.draw(canvas);
            drawAdaptiveIconIfExists(canvas);
        canvas.restoreToCount(count);
    }
    }

    public void onListenerViewClosed() {
        // Fast finish here.