Loading src/com/android/launcher3/shortcuts/DeepShortcutView.java +0 −70 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; } } src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java +11 −53 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); } Loading Loading @@ -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); Loading @@ -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); Loading @@ -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) { Loading Loading
src/com/android/launcher3/shortcuts/DeepShortcutView.java +0 −70 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; } }
src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java +11 −53 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); } Loading Loading @@ -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); Loading @@ -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); Loading @@ -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) { Loading