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

Commit e9381d60 authored by Tony Wickham's avatar Tony Wickham Committed by Android (Google) Code Review
Browse files

Merge "Remove hover-to-launch gesture for shortcuts." into ub-launcher3-calgary

parents 984c260a bf0ee9a3
Loading
Loading
Loading
Loading
+0 −70
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.support.annotation.IntDef;
import android.util.AttributeSet;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
@@ -40,26 +39,8 @@ import com.android.launcher3.util.PillRevealOutlineProvider;
 */
public class DeepShortcutView extends FrameLayout {

    private static final float HOVER_SCALE = 1.05f;

    // The direction this view should translate when animating the hover state.
    // This allows hovered shortcuts to "push" other shortcuts away.
    @IntDef({DIRECTION_UP, DIRECTION_NONE, DIRECTION_DOWN})
    public @interface TranslationDirection {}

    public static final int DIRECTION_UP = -1;
    public static final int DIRECTION_NONE = 0;
    public static final int DIRECTION_DOWN = 1;

    @TranslationDirection
    private int mTranslationDirection = DIRECTION_NONE;

    private int mSpacing;
    private int mRadius;
    private Rect mPillRect;
    private int mTop;
    private boolean mIsHoveringOver = false;
    private LauncherViewPropertyAnimator mHoverAnimator;

    private BubbleTextView mBubbleText;

@@ -74,10 +55,8 @@ public class DeepShortcutView extends FrameLayout {
    public DeepShortcutView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mSpacing = getResources().getDimensionPixelSize(R.dimen.deep_shortcuts_spacing);
        mRadius = getResources().getDimensionPixelSize(R.dimen.bg_pill_radius);
        mPillRect = new Rect();
        mHoverAnimator = new LauncherViewPropertyAnimator(this);
    }

    @Override
@@ -146,53 +125,4 @@ public class DeepShortcutView extends FrameLayout {
        openAnimation.setInterpolator(new DecelerateInterpolator());
        return openAnimation;
    }

    /**
     * Updates the state of this view based on touches over the container before user lifts finger.
     *
     * @param containerContainsTouch whether the {@link DeepShortcutsContainer} this shortcut
     *                               is inside contains the current touch
     * @param isBelowHoveredShortcut whether a sibling shortcut before this one in the
     *                               view hierarchy is being hovered over
     * @param touchY the y coordinate of the touch, relative to the {@link DeepShortcutsContainer}
     *               this shortcut is inside
     * @return whether this shortcut is being hovered over
     */
    public boolean updateHoverState(boolean containerContainsTouch, boolean isBelowHoveredShortcut,
            float touchY) {
        if (!containerContainsTouch) {
            mIsHoveringOver = false;
            mTranslationDirection = DIRECTION_NONE;
        } else if (isBelowHoveredShortcut) {
            mIsHoveringOver = false;
            mTranslationDirection = DIRECTION_DOWN;
        } else {
            // Include space around the view when determining hover state to avoid gaps.
            mTop = (int) (getY() - getTranslationY());
            mIsHoveringOver = (touchY >= mTop - mSpacing / 2)
                    && (touchY < mTop + getHeight() + mSpacing / 2);
            mTranslationDirection = mIsHoveringOver ? DIRECTION_NONE : DIRECTION_UP;
        }
        animateHoverState();
        return mIsHoveringOver;
    }

    /**
     * If this shortcut is being hovered over, we scale it up. If another shortcut is being hovered
     * over, we translate this one away from it to account for its increased size.
     */
    private void animateHoverState() {
        if (mHoverAnimator.isRunning()) {
            return;
        }
        float scale = mIsHoveringOver ? HOVER_SCALE : 1f;
        float translateY = (HOVER_SCALE - 1f) * getHeight() * mTranslationDirection;
        mHoverAnimator.scaleX(scale).scaleY(scale).translationY(translateY)
                .setDuration(getResources().getInteger(R.integer.config_deepShortcutHoverDuration))
                .start();
    }

    public boolean isHoveringOver() {
        return mIsHoveringOver;
    }
}
+11 −53
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.launcher3.shortcuts;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.content.ComponentName;
@@ -90,7 +88,6 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC
    private Point mIconLastTouchPos = new Point();
    private boolean mIsLeftAligned;
    private boolean mIsAboveIcon;
    private boolean mIsAnimatingOpen;

    private boolean mSrcIconDragStarted;

@@ -234,13 +231,6 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC
            int animationIndex = mIsAboveIcon ? numShortcuts - i - 1 : i;
            shortcutAnims.play(deepShortcutView.createOpenAnimation(animationIndex, mIsAboveIcon));
        }
        shortcutAnims.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mIsAnimatingOpen = false;
            }
        });
        mIsAnimatingOpen = true;
        shortcutAnims.start();
    }

@@ -349,7 +339,6 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC
        Utilities.translateEventCoordinates(this, mLauncher.getDragLayer(), ev);
        final int dragLayerX = (int) ev.getX();
        final int dragLayerY = (int) ev.getY();
        int childCount = getChildCount();
        if (action == MotionEvent.ACTION_MOVE) {
            if (mLastX != 0 || mLastY != 0) {
                mDistanceDragged += Math.hypot(mLastX - x, mLastY - y);
@@ -357,48 +346,22 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC
            mLastX = x;
            mLastY = y;

            boolean containerContainsTouch = x >= 0 && y >= 0 && x < getWidth() && y < getHeight();
            if (shouldStartDeferredDrag((int) x, (int) y, containerContainsTouch)) {
            if (shouldStartDeferredDrag((int) x, (int) y)) {
                mSrcIconDragStarted = true;
                cleanupDeferredDrag(true);
                mDeferredDragIcon.getParent().requestDisallowInterceptTouchEvent(false);
                mDeferredDragIcon.getOnLongClickListener().onLongClick(mDeferredDragIcon);
                mLauncher.getDragController().onTouchEvent(ev);
                return true;
            } else {
                // Determine whether touch is over a shortcut.
                boolean hoveringOverShortcut = false;
                for (int i = 0; i < childCount && !mIsAnimatingOpen; i++) {
                    DeepShortcutView shortcut = getShortcutAt(i);
                    if (shortcut.updateHoverState(containerContainsTouch, hoveringOverShortcut, y)) {
                        hoveringOverShortcut = true;
                    }
                }

                if (!hoveringOverShortcut && mDistanceDragged > mDragDeadzone) {
            } else if (mDistanceDragged > mDragDeadzone) {
                // After dragging further than a small deadzone,
                // have the drag view follow the user's finger.
                mDragView.setVisibility(VISIBLE);
                mDragView.move(dragLayerX, dragLayerY);
                mDeferredDragIcon.setVisibility(INVISIBLE);
                } else if (hoveringOverShortcut) {
                    // Jump drag view back to original place on grid,
                    // so user doesn't think they are still dragging.
                    // TODO: can we improve this interaction? maybe with a ghost icon or similar?
                    mDragView.setVisibility(INVISIBLE);
                    mDeferredDragIcon.setVisibility(VISIBLE);
                }
            }
        } else if (action == MotionEvent.ACTION_UP) {
            cleanupDeferredDrag(true);
            // Launch a shortcut if user was hovering over it.
            for (int i = 0; i < childCount; i++) {
                DeepShortcutView shortcut = getShortcutAt(i);
                if (shortcut.isHoveringOver()) {
                    shortcut.getBubbleText().performClick();
                    break;
                }
            }
        } else if (action == MotionEvent.ACTION_CANCEL) {
            // Do not change the source icon visibility if we are already dragging the source icon.
            cleanupDeferredDrag(!mSrcIconDragStarted);
@@ -411,19 +374,14 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC
     * relative to the original icon and the shortcuts container.
     *
     * Current behavior:
     * - Compute distance from original touch down to closest container edge.
     * - Compute distance from latest touch (given x and y) and compare to original distance;
     *   if the new distance is larger than a threshold, the deferred drag should start.
     * - Never defer the drag if this container contains the touch.
     * - Start the drag if the touch passes a certain distance from the original touch down.
     *
     * @param x the x touch coordinate relative to this container
     * @param y the y touch coordinate relative to this container
     */
    private boolean shouldStartDeferredDrag(int x, int y, boolean containerContainsTouch) {
        int closestEdgeY = mIsAboveIcon ? getMeasuredHeight() : 0;
        double distToEdge = Math.abs(mTouchDown[1] - closestEdgeY);
        double newDistToEdge = Math.hypot(x - mTouchDown[0], y - closestEdgeY);
        return !containerContainsTouch && (newDistToEdge - distToEdge > mStartDragThreshold);
    private boolean shouldStartDeferredDrag(int x, int y) {
        double distFromTouchDown = Math.hypot(x - mTouchDown[0], y - mTouchDown[1]);
        return distFromTouchDown > mStartDragThreshold;
    }

    public void cleanupDeferredDrag(boolean updateSrcVisibility) {