summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/launcher3/DeleteDropTarget.java1
-rw-r--r--src/com/android/launcher3/DeviceProfile.java2
-rw-r--r--src/com/android/launcher3/dragndrop/DragController.java25
-rw-r--r--src/com/android/launcher3/util/FlingAnimation.java32
4 files changed, 47 insertions, 13 deletions
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 9a9b57aed..6d8fa6bd0 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -19,7 +19,6 @@ package com.android.launcher3;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.graphics.PointF;
-import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AnimationUtils;
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 66cf2dfea..69ef82683 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -372,7 +372,7 @@ public class DeviceProfile {
* When {@code true}, hotseat is on the bottom row when in landscape mode.
* If {@code false}, hotseat is on the right column when in landscape mode.
*/
- boolean isVerticalBarLayout() {
+ public boolean isVerticalBarLayout() {
return isLandscape && transposeLayoutWithOrientation;
}
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index e72f3415a..4a39e6be1 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -42,7 +42,6 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.PagedView;
import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.Utilities;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.R;
@@ -657,21 +656,29 @@ public class DragController implements DragDriver.EventListener {
ViewConfiguration config = ViewConfiguration.get(mLauncher);
mVelocityTracker.computeCurrentVelocity(1000, config.getScaledMaximumFlingVelocity());
-
+ PointF vel = new PointF(mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
+ float theta = MAX_FLING_DEGREES + 1;
if (mVelocityTracker.getYVelocity() < mFlingToDeleteThresholdVelocity) {
// Do a quick dot product test to ensure that we are flinging upwards
- PointF vel = new PointF(mVelocityTracker.getXVelocity(),
- mVelocityTracker.getYVelocity());
PointF upVec = new PointF(0f, -1f);
- float theta = (float) Math.acos(((vel.x * upVec.x) + (vel.y * upVec.y)) /
- (vel.length() * upVec.length()));
- if (theta <= Math.toRadians(MAX_FLING_DEGREES)) {
- return vel;
- }
+ theta = getAngleBetweenVectors(vel, upVec);
+ } else if (mLauncher.getDeviceProfile().isVerticalBarLayout() &&
+ mVelocityTracker.getXVelocity() < mFlingToDeleteThresholdVelocity) {
+ // Remove icon is on left side instead of top, so check if we are flinging to the left.
+ PointF leftVec = new PointF(-1f, 0f);
+ theta = getAngleBetweenVectors(vel, leftVec);
+ }
+ if (theta <= Math.toRadians(MAX_FLING_DEGREES)) {
+ return vel;
}
return null;
}
+ private float getAngleBetweenVectors(PointF vec1, PointF vec2) {
+ return (float) Math.acos(((vec1.x * vec2.x) + (vec1.y * vec2.y)) /
+ (vec1.length() * vec2.length()));
+ }
+
void drop(DropTarget dropTarget, float x, float y, PointF flingVel) {
final int[] coordinates = mCoordinatesTemp;
diff --git a/src/com/android/launcher3/util/FlingAnimation.java b/src/com/android/launcher3/util/FlingAnimation.java
index f82038bf2..da8bae712 100644
--- a/src/com/android/launcher3/util/FlingAnimation.java
+++ b/src/com/android/launcher3/util/FlingAnimation.java
@@ -51,7 +51,7 @@ public class FlingAnimation implements AnimatorUpdateListener {
mFrom.top += yOffset;
mFrom.bottom -= yOffset;
- mDuration = initDuration();
+ mDuration = Math.abs(vel.y) > Math.abs(vel.x) ? initFlingUpDuration() : initFlingLeftDuration();
mAnimationTimeFraction = ((float) mDuration) / (mDuration + DRAG_END_DELAY);
}
@@ -62,7 +62,7 @@ public class FlingAnimation implements AnimatorUpdateListener {
* - Calculate a constant acceleration in x direction such that the object reaches
* {@link #mIconRect} in the given time.
*/
- protected int initDuration() {
+ protected int initFlingUpDuration() {
float sY = -mFrom.bottom;
float d = mUY * mUY + 2 * sY * MAX_ACCELERATION;
@@ -83,6 +83,34 @@ public class FlingAnimation implements AnimatorUpdateListener {
return (int) Math.round(t);
}
+ /**
+ * The fling animation is based on the following system
+ * - Apply a constant force in the x direction to causing the fling to decelerate.
+ * - The animation runs for the time taken by the object to go out of the screen.
+ * - Calculate a constant acceleration in y direction such that the object reaches
+ * {@link #mIconRect} in the given time.
+ */
+ protected int initFlingLeftDuration() {
+ float sX = -mFrom.right;
+
+ float d = mUX * mUX + 2 * sX * MAX_ACCELERATION;
+ if (d >= 0) {
+ // sX can be reached under the MAX_ACCELERATION. Use MAX_ACCELERATION for x direction.
+ mAX = MAX_ACCELERATION;
+ } else {
+ // sX is not reachable, decrease the acceleration so that sX is almost reached.
+ d = 0;
+ mAX = mUX * mUX / (2 * -sX);
+ }
+ double t = (-mUX - Math.sqrt(d)) / mAX;
+
+ float sY = -mFrom.exactCenterY() + mIconRect.exactCenterY();
+
+ // Find vertical acceleration such that: u*t + a*t*t/2 = s
+ mAY = (float) ((sY - t * mUY) * 2 / (t * t));
+ return (int) Math.round(t);
+ }
+
public final int getDuration() {
return mDuration + DRAG_END_DELAY;
}