Unifying overscroll btw phone and tablet

-> Using separate assets for removing and uninstalling

Change-Id: I183967c3ca482531ae28f71cd9053b673c6a8d03
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 8ef758d..5382ef3 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -1265,7 +1265,7 @@
                         scale = 1.0f;
                         alpha = 1.0f;
                         // On the first page, we don't want the page to have any lateral motion
-                        translationX = getScrollX();
+                        translationX = 0;
                     } else if (i == getChildCount() - 1 && scrollProgress > 0) {
                         // Overscroll to the right
                         v.setPivotX((1 - TRANSITION_PIVOT) * pageWidth);
@@ -1273,7 +1273,7 @@
                         scale = 1.0f;
                         alpha = 1.0f;
                         // On the last page, we don't want the page to have any lateral motion.
-                        translationX =  getScrollX() - mMaxScrollX;
+                        translationX = 0;
                     } else {
                         v.setPivotY(pageHeight / 2.0f);
                         v.setPivotX(pageWidth / 2.0f);
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 2d75493..6e60280 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -36,7 +36,6 @@
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.graphics.RectF;
-import android.graphics.Region;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.NinePatchDrawable;
 import android.util.AttributeSet;
@@ -72,6 +71,7 @@
     private int mWidthGap;
     private int mHeightGap;
     private int mMaxGap;
+    private boolean mScrollingTransformsDirty = false;
 
     private final Rect mRect = new Rect();
     private final CellInfo mCellInfo = new CellInfo();
@@ -345,6 +345,23 @@
         return mIsDragOverlapping;
     }
 
+    protected void setOverscrollTransformsDirty(boolean dirty) {
+        mScrollingTransformsDirty = dirty;
+    }
+
+    protected void resetOverscrollTransforms() {
+        if (mScrollingTransformsDirty) {
+            setOverscrollTransformsDirty(false);
+            setTranslationX(0);
+            setRotationY(0);
+            // It doesn't matter if we pass true or false here, the important thing is that we
+            // pass 0, which results in the overscroll drawable not being drawn any more.
+            setOverScrollAmount(0, false);
+            setPivotX(getMeasuredWidth() / 2);
+            setPivotY(getMeasuredHeight() / 2);
+        }
+    }
+
     @Override
     protected void onDraw(Canvas canvas) {
         // When we're large, we are either drawn in a "hover" state (ie when dragging an item to
diff --git a/src/com/android/launcher2/DeleteDropTarget.java b/src/com/android/launcher2/DeleteDropTarget.java
index 1553d3c..4e93b22 100644
--- a/src/com/android/launcher2/DeleteDropTarget.java
+++ b/src/com/android/launcher2/DeleteDropTarget.java
@@ -23,6 +23,7 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.TransitionDrawable;
 import android.util.AttributeSet;
 import android.view.View;
@@ -35,8 +36,10 @@
 
     private static int DELETE_ANIMATION_DURATION = 250;
     private ColorStateList mOriginalTextColor;
-    private TransitionDrawable mDrawable;
     private int mHoverColor = 0xFFFF0000;
+    private TransitionDrawable mUninstallDrawable;
+    private TransitionDrawable mRemoveDrawable;
+    private TransitionDrawable mCurrentDrawable;
 
     public DeleteDropTarget(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
@@ -58,8 +61,16 @@
         mHoverColor = r.getColor(R.color.delete_target_hover_tint);
         mHoverPaint.setColorFilter(new PorterDuffColorFilter(
                 mHoverColor, PorterDuff.Mode.SRC_ATOP));
-        mDrawable = (TransitionDrawable) getCompoundDrawables()[0];
-        mDrawable.setCrossFadeEnabled(true);
+        mUninstallDrawable = (TransitionDrawable) 
+                r.getDrawable(R.drawable.uninstall_target_selector);
+        mRemoveDrawable = (TransitionDrawable) r.getDrawable(R.drawable.remove_target_selector);
+
+        mRemoveDrawable.setCrossFadeEnabled(true);
+        mUninstallDrawable.setCrossFadeEnabled(true);
+
+        // The current drawable is set to either the remove drawable or the uninstall drawable 
+        // and is initially set to the remove drawable, as set in the layout xml.
+        mCurrentDrawable = (TransitionDrawable) getCompoundDrawables()[0];
 
         // Remove the text in the Phone UI in landscape
         int orientation = getResources().getConfiguration().orientation;
@@ -116,8 +127,15 @@
             }
         }
 
+        if (isUninstall) {
+            setCompoundDrawablesWithIntrinsicBounds(mUninstallDrawable, null, null, null);
+        } else {
+            setCompoundDrawablesWithIntrinsicBounds(mRemoveDrawable, null, null, null);
+        }
+        mCurrentDrawable = (TransitionDrawable) getCompoundDrawables()[0];
+
         mActive = isVisible;
-        mDrawable.resetTransition();
+        mCurrentDrawable.resetTransition();
         setTextColor(mOriginalTextColor);
         ((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
         if (getText().length() > 0) {
@@ -135,7 +153,7 @@
     public void onDragEnter(DragObject d) {
         super.onDragEnter(d);
 
-        mDrawable.startTransition(mTransitionDuration);
+        mCurrentDrawable.startTransition(mTransitionDuration);
         setTextColor(mHoverColor);
     }
 
@@ -143,7 +161,7 @@
         super.onDragExit(d);
 
         if (!d.dragComplete) {
-            mDrawable.resetTransition();
+            mCurrentDrawable.resetTransition();
             setTextColor(mOriginalTextColor);
         }
     }
@@ -155,8 +173,8 @@
         dragLayer.getViewRectRelativeToSelf(d.dragView, from);
         dragLayer.getViewRectRelativeToSelf(this, to);
 
-        int width = mDrawable.getIntrinsicWidth();
-        int height = mDrawable.getIntrinsicHeight();
+        int width = mCurrentDrawable.getIntrinsicWidth();
+        int height = mCurrentDrawable.getIntrinsicHeight();
         to.set(to.left + getPaddingLeft(), to.top + getPaddingTop(),
                 to.left + getPaddingLeft() + width, to.bottom);
 
diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java
index 433db50..3c626d4 100644
--- a/src/com/android/launcher2/DragLayer.java
+++ b/src/com/android/launcher2/DragLayer.java
@@ -70,7 +70,7 @@
     private boolean mHoverPointClosesFolder = false;
     private Rect mHitRect = new Rect();
     private int mWorkspaceIndex = -1;
-    private int mHotseatIndex = -1;
+    private int mQsbIndex = -1;
 
     /**
      * Used to create a new DragLayer from XML.
@@ -627,13 +627,13 @@
     private void updateChildIndices() {
         if (mLauncher != null) {
             mWorkspaceIndex = indexOfChild(mLauncher.getWorkspace());
-            mHotseatIndex = indexOfChild(mLauncher.getHotseat());
+            mQsbIndex = indexOfChild(mLauncher.getSearchBar());
         }
     }
 
     @Override
     protected int getChildDrawingOrder(int childCount, int i) {
-        if (mWorkspaceIndex == -1 || mHotseatIndex == -1 || 
+        if (mWorkspaceIndex == -1 || mQsbIndex == -1 || 
                 mLauncher.getWorkspace().isDrawingBackgroundGradient()) {
             return i;
         }
@@ -641,10 +641,10 @@
         // This ensures that the workspace is drawn above the hotseat and qsb,
         // except when the workspace is drawing a background gradient, in which
         // case we want the workspace to stay behind these elements.
-        if (i == mHotseatIndex) {
+        if (i == mQsbIndex) {
             return mWorkspaceIndex;
         } else if (i == mWorkspaceIndex) {
-            return mHotseatIndex;
+            return mQsbIndex;
         } else {
             return i;
         }
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 664b597..f91a471 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -1956,6 +1956,9 @@
     Hotseat getHotseat() {
         return mHotseat;
     }
+    SearchDropTargetBar getSearchBar() {
+        return mSearchDropTargetBar;
+    }
 
     /**
      * Returns the CellLayout of the specified container at the specified screen.
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index ad88a89..14ef53f 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -129,6 +129,11 @@
     protected int mUnboundedScrollX;
     protected int[] mTempVisiblePagesRange = new int[2];
 
+    // mOverScrollX is equal to mScrollX when we're within the normal scroll range. Otherwise
+    // it is equal to the scaled overscroll position. We use a separate value so as to prevent
+    // the screens from continuing to translate beyond the normal bounds.
+    protected int mOverScrollX;
+
     // parameter that adjusts the layout to be optimized for pages with that scale factor
     protected float mLayoutScale = 1.0f;
 
@@ -377,6 +382,7 @@
                 overScroll(x - mMaxScrollX);
             }
         } else {
+            mOverScrollX = x;
             super.scrollTo(x, y);
         }
 
@@ -730,7 +736,9 @@
     @Override
     protected void dispatchDraw(Canvas canvas) {
         int halfScreenSize = getMeasuredWidth() / 2;
-        int screenCenter = mScrollX + halfScreenSize;
+        // mOverScrollX is equal to mScrollX when we're within the normal scroll range. Otherwise
+        // it is equal to the scaled overscroll position.
+        int screenCenter = mOverScrollX + halfScreenSize;
 
         if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
             screenScrolled(screenCenter);
@@ -1077,9 +1085,11 @@
 
         int overScrollAmount = (int) Math.round(f * screenSize);
         if (amount < 0) {
-            mScrollX = overScrollAmount;
+            mOverScrollX = overScrollAmount;
+            mScrollX = 0;
         } else {
-            mScrollX = mMaxScrollX + overScrollAmount;
+            mOverScrollX = mMaxScrollX + overScrollAmount;
+            mScrollX = mMaxScrollX;
         }
         invalidate();
     }
@@ -1099,9 +1109,11 @@
 
         int overScrollAmount = (int) Math.round(OVERSCROLL_DAMP_FACTOR * f * screenSize);
         if (amount < 0) {
-            mScrollX = overScrollAmount;
+            mOverScrollX = overScrollAmount;
+            mScrollX = 0;
         } else {
-            mScrollX = mMaxScrollX + overScrollAmount;
+            mOverScrollX = mMaxScrollX + overScrollAmount;
+            mScrollX = mMaxScrollX;
         }
         invalidate();
     }
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index b6b90f4..4ad441d 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -1101,6 +1101,7 @@
     }
 
     private void screenScrolledLargeUI(int screenCenter) {
+        boolean isInOverscroll = false;
         for (int i = 0; i < getChildCount(); i++) {
             CellLayout cl = (CellLayout) getChildAt(i);
             if (cl != null) {
@@ -1111,11 +1112,17 @@
                 // If the current page (i) is being over scrolled, we use a different
                 // set of rules for setting the background alpha multiplier.
                 if (!isSmall()) {
-                    if ((mScrollX < 0 && i == 0) || (mScrollX > mMaxScrollX &&
-                            i == getChildCount() -1 )) {
+                    if ((mOverScrollX < 0 && i == 0) || (mOverScrollX > mMaxScrollX &&
+                            i == getChildCount() -1)) {
+                        isInOverscroll = true;
+                        rotation *= -1;
                         cl.setBackgroundAlphaMultiplier(
                                 overScrollBackgroundAlphaInterpolator(Math.abs(scrollProgress)));
                         mOverScrollPageIndex = i;
+                        cl.setOverScrollAmount(Math.abs(scrollProgress), i == 0);
+                        cl.setPivotX(cl.getMeasuredWidth() * (i == 0 ? 0.75f : 0.25f));
+                        cl.setPivotY(cl.getMeasuredHeight() * 0.5f);
+                        cl.setOverscrollTransformsDirty(true);
                     } else if (mOverScrollPageIndex != i) {
                         cl.setBackgroundAlphaMultiplier(
                                 backgroundAlphaInterpolator(Math.abs(scrollProgress)));
@@ -1130,29 +1137,25 @@
                 cl.fastInvalidate();
             }
         }
+        if (!isSwitchingState() && !isInOverscroll) {
+            ((CellLayout) getChildAt(0)).resetOverscrollTransforms();
+            ((CellLayout) getChildAt(getChildCount() - 1)).resetOverscrollTransforms();
+        }
         invalidate();
     }
 
-    private void resetCellLayoutTransforms(CellLayout cl, boolean left) {
-        cl.setTranslationX(0);
-        cl.setRotationY(0);
-        cl.setOverScrollAmount(0, left);
-        cl.setPivotX(cl.getMeasuredWidth() / 2);
-        cl.setPivotY(cl.getMeasuredHeight() / 2);
-    }
-
     private void screenScrolledStandardUI(int screenCenter) {
-        if (mScrollX < 0 || mScrollX > mMaxScrollX) {
-            int index = mScrollX < 0 ? 0 : getChildCount() - 1;
+        if (mOverScrollX < 0 || mOverScrollX > mMaxScrollX) {
+            int index = mOverScrollX < 0 ? 0 : getChildCount() - 1;
             CellLayout cl = (CellLayout) getChildAt(index);
             float scrollProgress = getScrollProgress(screenCenter, cl, index);
             cl.setOverScrollAmount(Math.abs(scrollProgress), index == 0);
-            float translationX = index == 0 ? mScrollX : - (mMaxScrollX - mScrollX);
             float rotation = - WORKSPACE_OVERSCROLL_ROTATION * scrollProgress;
             cl.setCameraDistance(mDensity * CAMERA_DISTANCE);
             cl.setPivotX(cl.getMeasuredWidth() * (index == 0 ? 0.75f : 0.25f));
-            cl.setTranslationX(translationX);
+            cl.setPivotY(cl.getMeasuredHeight() * 0.5f);
             cl.setRotationY(rotation);
+            cl.setOverscrollTransformsDirty(true);
             setFadeForOverScroll(Math.abs(scrollProgress));
         } else {
             if (mOverscrollFade != 0) {
@@ -1160,8 +1163,8 @@
             }
             // We don't want to mess with the translations during transitions
             if (!isSwitchingState()) {
-                resetCellLayoutTransforms((CellLayout) getChildAt(0), true);
-                resetCellLayoutTransforms((CellLayout) getChildAt(getChildCount() - 1), false);
+                ((CellLayout) getChildAt(0)).resetOverscrollTransforms();
+                ((CellLayout) getChildAt(getChildCount() - 1)).resetOverscrollTransforms();
             }
         }
     }