Modifying AppsCustomize behaviour to use springloaded mode.

Change-Id: I21d181ad3d245731ee8402915f8918b91bfc4553
diff --git a/res/drawable-hdpi/all_apps_bg_gradient.png b/res/drawable-hdpi/all_apps_bg_gradient.png
new file mode 100644
index 0000000..c420ca5
--- /dev/null
+++ b/res/drawable-hdpi/all_apps_bg_gradient.png
Binary files differ
diff --git a/res/drawable-hdpi/homescreen_large_blue.9.png b/res/drawable-hdpi/homescreen_large_blue.9.png
new file mode 100644
index 0000000..416514d
--- /dev/null
+++ b/res/drawable-hdpi/homescreen_large_blue.9.png
Binary files differ
diff --git a/res/drawable-hdpi/homescreen_large_blue_strong.9.png b/res/drawable-hdpi/homescreen_large_blue_strong.9.png
new file mode 100644
index 0000000..d7e32e7
--- /dev/null
+++ b/res/drawable-hdpi/homescreen_large_blue_strong.9.png
Binary files differ
diff --git a/res/drawable-hdpi/homescreen_large_green.9.png b/res/drawable-hdpi/homescreen_large_green.9.png
new file mode 100644
index 0000000..60042c2
--- /dev/null
+++ b/res/drawable-hdpi/homescreen_large_green.9.png
Binary files differ
diff --git a/res/drawable-hdpi/homescreen_large_green_strong.9.png b/res/drawable-hdpi/homescreen_large_green_strong.9.png
new file mode 100644
index 0000000..c40b98e
--- /dev/null
+++ b/res/drawable-hdpi/homescreen_large_green_strong.9.png
Binary files differ
diff --git a/res/drawable-hdpi/homescreen_small_blue.9.png b/res/drawable-hdpi/homescreen_small_blue.9.png
new file mode 100644
index 0000000..ddc458b
--- /dev/null
+++ b/res/drawable-hdpi/homescreen_small_blue.9.png
Binary files differ
diff --git a/res/drawable-hdpi/homescreen_small_blue_strong.9.png b/res/drawable-hdpi/homescreen_small_blue_strong.9.png
new file mode 100644
index 0000000..8f5a74e
--- /dev/null
+++ b/res/drawable-hdpi/homescreen_small_blue_strong.9.png
Binary files differ
diff --git a/res/drawable-hdpi/homescreen_small_green_strong.9.png b/res/drawable-hdpi/homescreen_small_green_strong.9.png
new file mode 100644
index 0000000..77baa52
--- /dev/null
+++ b/res/drawable-hdpi/homescreen_small_green_strong.9.png
Binary files differ
diff --git a/res/drawable-large-hdpi/homescreen_large_blue.9.png b/res/drawable-large-hdpi/homescreen_large_blue.9.png
deleted file mode 100644
index 6ce3d29..0000000
--- a/res/drawable-large-hdpi/homescreen_large_blue.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-large-hdpi/homescreen_large_blue_strong.9.png b/res/drawable-large-hdpi/homescreen_large_blue_strong.9.png
deleted file mode 100644
index 8110148..0000000
--- a/res/drawable-large-hdpi/homescreen_large_blue_strong.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-large-hdpi/homescreen_large_green.9.png b/res/drawable-large-hdpi/homescreen_large_green.9.png
deleted file mode 100644
index 4a6546e..0000000
--- a/res/drawable-large-hdpi/homescreen_large_green.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-large-hdpi/homescreen_large_green_strong.9.png b/res/drawable-large-hdpi/homescreen_large_green_strong.9.png
deleted file mode 100644
index 5ba9ebe..0000000
--- a/res/drawable-large-hdpi/homescreen_large_green_strong.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-large-hdpi/homescreen_small_blue.9.png b/res/drawable-large-hdpi/homescreen_small_blue.9.png
deleted file mode 100644
index db93b3c..0000000
--- a/res/drawable-large-hdpi/homescreen_small_blue.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-large-hdpi/homescreen_small_blue_strong.9.png b/res/drawable-large-hdpi/homescreen_small_blue_strong.9.png
deleted file mode 100644
index 32bd857..0000000
--- a/res/drawable-large-hdpi/homescreen_small_blue_strong.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-large-hdpi/homescreen_small_green.9.png b/res/drawable-large-hdpi/homescreen_small_green.9.png
deleted file mode 100644
index 00baae9..0000000
--- a/res/drawable-large-hdpi/homescreen_small_green.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-large-hdpi/homescreen_small_green_strong.9.png b/res/drawable-large-hdpi/homescreen_small_green_strong.9.png
deleted file mode 100644
index e1e64c5..0000000
--- a/res/drawable-large-hdpi/homescreen_small_green_strong.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-large-mdpi/homescreen_small_green.9.png b/res/drawable-large-mdpi/homescreen_small_green.9.png
deleted file mode 100644
index 58698ea..0000000
--- a/res/drawable-large-mdpi/homescreen_small_green.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/all_apps_bg_gradient.png b/res/drawable-mdpi/all_apps_bg_gradient.png
new file mode 100644
index 0000000..c420ca5
--- /dev/null
+++ b/res/drawable-mdpi/all_apps_bg_gradient.png
Binary files differ
diff --git a/res/drawable-large-mdpi/homescreen_large_blue.9.png b/res/drawable-mdpi/homescreen_large_blue.9.png
similarity index 100%
rename from res/drawable-large-mdpi/homescreen_large_blue.9.png
rename to res/drawable-mdpi/homescreen_large_blue.9.png
Binary files differ
diff --git a/res/drawable-large-mdpi/homescreen_large_green.9.png b/res/drawable-mdpi/homescreen_large_green.9.png
similarity index 100%
rename from res/drawable-large-mdpi/homescreen_large_green.9.png
rename to res/drawable-mdpi/homescreen_large_green.9.png
Binary files differ
diff --git a/res/drawable-large-mdpi/homescreen_large_green_strong.9.png b/res/drawable-mdpi/homescreen_large_green_strong.9.png
similarity index 100%
rename from res/drawable-large-mdpi/homescreen_large_green_strong.9.png
rename to res/drawable-mdpi/homescreen_large_green_strong.9.png
Binary files differ
diff --git a/res/drawable-large-mdpi/homescreen_small_blue.9.png b/res/drawable-mdpi/homescreen_small_blue.9.png
similarity index 100%
rename from res/drawable-large-mdpi/homescreen_small_blue.9.png
rename to res/drawable-mdpi/homescreen_small_blue.9.png
Binary files differ
diff --git a/res/drawable-large-mdpi/homescreen_small_blue_strong.9.png b/res/drawable-mdpi/homescreen_small_blue_strong.9.png
similarity index 100%
rename from res/drawable-large-mdpi/homescreen_small_blue_strong.9.png
rename to res/drawable-mdpi/homescreen_small_blue_strong.9.png
Binary files differ
diff --git a/res/drawable-large-mdpi/homescreen_small_green_strong.9.png b/res/drawable-mdpi/homescreen_small_green_strong.9.png
similarity index 100%
rename from res/drawable-large-mdpi/homescreen_small_green_strong.9.png
rename to res/drawable-mdpi/homescreen_small_green_strong.9.png
Binary files differ
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
index 604dff4..f3ecb48 100644
--- a/res/layout/apps_customize_pane.xml
+++ b/res/layout/apps_customize_pane.xml
@@ -16,11 +16,14 @@
 <com.android.launcher2.AppsCustomizeTabHost
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher">
+    <com.android.launcher2.AllAppsBackground
+        android:id="@+id/all_apps_background"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
     <LinearLayout
         android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="#FF000000">
+        android:layout_height="match_parent">
         <!-- The layout_width of the tab bar gets overriden to align the content
              with the text in the tabs in AppsCustomizeTabHost. -->
         <FrameLayout
diff --git a/res/values-large/config.xml b/res/values-large/config.xml
index 8b77696..dca8282 100644
--- a/res/values-large/config.xml
+++ b/res/values-large/config.xml
@@ -6,6 +6,8 @@
     <integer name="config_customizeZoomOutTime">600</integer>
     <integer name="config_customizeZoomScaleFactor">7</integer>
     <integer name="config_customizeFadeInTime">800</integer>
+    <!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
+    <integer name="config_workspaceSpringLoadShrinkPercentage">70</integer>
 
     <!-- The slope, in percent, of the drag movement needed to drag an item out of
          Customize (y / x * 100%)  -->
@@ -24,12 +26,4 @@
     <!-- When shrinking the workspace, this is the percentage of its original size. -->
     <integer name="config_workspaceShrinkPercent">17</integer>
 
-    <!-- When items are dropped on the mini screens in customize mode, we have a bounce animation
-         of the bright green hover outline, and then fade out the outline at the end. These are
-         the values used in that animation -->
-    <integer name="config_screenOnDropScalePercent">120</integer>
-    <integer name="config_screenOnDropScaleUpDuration">200</integer>
-    <integer name="config_screenOnDropScaleDownDuration">200</integer>
-    <integer name="config_screenOnDropAlphaFadeDelay">350</integer>
-    <integer name="config_screenOnDropAlphaFadeDuration">50</integer>
 </resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 44ba589..394ff8a 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -5,6 +5,16 @@
     <integer name="config_dragAppsCustomizeIconFadeOutDuration">200</integer>
     <integer name="config_dragAppsCustomizeIconFadeAlpha">100</integer>
     <integer name="config_workspaceUnshrinkTime">650</integer>
+    <!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
+    <integer name="config_workspaceSpringLoadShrinkPercentage">80</integer>
+    <!-- When items are dropped on the mini screens in customize mode, we have a bounce animation
+         of the bright green hover outline, and then fade out the outline at the end. These are
+         the values used in that animation -->
+    <integer name="config_screenOnDropScalePercent">120</integer>
+    <integer name="config_screenOnDropScaleUpDuration">200</integer>
+    <integer name="config_screenOnDropScaleDownDuration">200</integer>
+    <integer name="config_screenOnDropAlphaFadeDelay">350</integer>
+    <integer name="config_screenOnDropAlphaFadeDuration">50</integer>
 
     <!-- Fade/zoom in/out duration & scale in the AllApps transition.
          Note: This should be less than the workspaceShrinkTime as they happen together. -->
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 62a8936..464bb44 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -410,9 +410,6 @@
     protected boolean beginDragging(View v) {
         if (!super.beginDragging(v)) return false;
 
-        // Hide the pane so that the user can drop onto the workspace, we must do this first,
-        // due to how the drop target layout is computed when we start dragging to the workspace.
-        mLauncher.showWorkspace(true);
 
         if (v instanceof PagedViewIcon) {
             beginDraggingApplication(v);
@@ -420,6 +417,10 @@
             beginDraggingWidget(v);
         }
 
+        // Go into spring loaded mode
+        int currentPageIndex = mLauncher.getWorkspace().getCurrentPage();
+        CellLayout currentPage = (CellLayout) mLauncher.getWorkspace().getChildAt(currentPageIndex);
+        mLauncher.enterSpringLoadedDragMode(currentPage);
         return true;
     }
     private void endDragging(boolean success) {
@@ -439,8 +440,10 @@
                 if (allAppsInfoButton != null) allAppsInfoButton.setDragAndDropEnabled(false);
             }
         });
+        mLauncher.exitSpringLoadedDragMode();
         mLauncher.getWorkspace().onDragStopped(success);
         mLauncher.unlockScreenOrientation();
+
     }
 
     /*
@@ -781,6 +784,34 @@
         return mContentWidth;
     }
 
+    @Override
+    protected void onPageBeginMoving() {
+        /* TO BE ENABLED LATER
+        setChildrenDrawnWithCacheEnabled(true);
+        for (int i = 0; i < getChildCount(); ++i) {
+            View v = getChildAt(i);
+            if (v instanceof PagedViewCellLayout) {
+                ((PagedViewCellLayout) v).setChildrenDrawingCacheEnabled(true);
+            }
+        }
+        */
+        super.onPageBeginMoving();
+    }
+
+    @Override
+    protected void onPageEndMoving() {
+        /* TO BE ENABLED LATER
+        for (int i = 0; i < getChildCount(); ++i) {
+            View v = getChildAt(i);
+            if (v instanceof PagedViewCellLayout) {
+                ((PagedViewCellLayout) v).setChildrenDrawingCacheEnabled(false);
+            }
+        }
+        setChildrenDrawnWithCacheEnabled(false);
+        */
+        super.onPageEndMoving();
+    }
+
     /*
      * AllAppsView implementation
      */
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 12b0158..e5aa7a9 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -167,24 +167,22 @@
 
         final Resources res = getResources();
 
-        if (LauncherApplication.isScreenLarge()) {
-            mNormalBackground = res.getDrawable(R.drawable.homescreen_large_blue);
-            mActiveBackground = res.getDrawable(R.drawable.homescreen_large_green);
-            mActiveGlowBackground = res.getDrawable(R.drawable.homescreen_large_green_strong);
+        mNormalBackground = res.getDrawable(R.drawable.homescreen_large_blue);
+        mActiveBackground = res.getDrawable(R.drawable.homescreen_large_green);
+        mActiveGlowBackground = res.getDrawable(R.drawable.homescreen_large_green_strong);
 
-            mNormalBackgroundMini = res.getDrawable(R.drawable.homescreen_small_blue);
-            mNormalGlowBackgroundMini = res.getDrawable(R.drawable.homescreen_small_blue_strong);
-            mActiveBackgroundMini = res.getDrawable(R.drawable.homescreen_small_green);
-            mActiveGlowBackgroundMini = res.getDrawable(R.drawable.homescreen_small_green_strong);
+        mNormalBackgroundMini = res.getDrawable(R.drawable.homescreen_small_blue);
+        mNormalGlowBackgroundMini = res.getDrawable(R.drawable.homescreen_small_blue_strong);
+        mActiveBackgroundMini = res.getDrawable(R.drawable.homescreen_small_green);
+        mActiveGlowBackgroundMini = res.getDrawable(R.drawable.homescreen_small_green_strong);
 
-            mNormalBackground.setFilterBitmap(true);
-            mActiveBackground.setFilterBitmap(true);
-            mActiveGlowBackground.setFilterBitmap(true);
-            mNormalBackgroundMini.setFilterBitmap(true);
-            mNormalGlowBackgroundMini.setFilterBitmap(true);
-            mActiveBackgroundMini.setFilterBitmap(true);
-            mActiveGlowBackgroundMini.setFilterBitmap(true);
-        }
+        mNormalBackground.setFilterBitmap(true);
+        mActiveBackground.setFilterBitmap(true);
+        mActiveGlowBackground.setFilterBitmap(true);
+        mNormalBackgroundMini.setFilterBitmap(true);
+        mNormalGlowBackgroundMini.setFilterBitmap(true);
+        mActiveBackgroundMini.setFilterBitmap(true);
+        mActiveGlowBackgroundMini.setFilterBitmap(true);
 
         // Initialize the data structures used for the drag visualization.
 
@@ -383,35 +381,33 @@
     }
 
     void animateDrop() {
-        if (LauncherApplication.isScreenLarge()) {
-            Resources res = getResources();
-            float onDropScale = res.getInteger(R.integer.config_screenOnDropScalePercent) / 100.0f;
-            ObjectAnimator scaleUp = ObjectAnimator.ofFloat(this, "hoverScale", onDropScale);
-            scaleUp.setDuration(res.getInteger(R.integer.config_screenOnDropScaleUpDuration));
-            ObjectAnimator scaleDown = ObjectAnimator.ofFloat(this, "hoverScale", 1.0f);
-            scaleDown.setDuration(res.getInteger(R.integer.config_screenOnDropScaleDownDuration));
-            ObjectAnimator alphaFadeOut = ObjectAnimator.ofFloat(this, "hoverAlpha", 0.0f);
+        Resources res = getResources();
+        float onDropScale = res.getInteger(R.integer.config_screenOnDropScalePercent) / 100.0f;
+        ObjectAnimator scaleUp = ObjectAnimator.ofFloat(this, "hoverScale", onDropScale);
+        scaleUp.setDuration(res.getInteger(R.integer.config_screenOnDropScaleUpDuration));
+        ObjectAnimator scaleDown = ObjectAnimator.ofFloat(this, "hoverScale", 1.0f);
+        scaleDown.setDuration(res.getInteger(R.integer.config_screenOnDropScaleDownDuration));
+        ObjectAnimator alphaFadeOut = ObjectAnimator.ofFloat(this, "hoverAlpha", 0.0f);
 
-            alphaFadeOut.setStartDelay(res.getInteger(R.integer.config_screenOnDropAlphaFadeDelay));
-            alphaFadeOut.setDuration(res.getInteger(R.integer.config_screenOnDropAlphaFadeDelay));
+        alphaFadeOut.setStartDelay(res.getInteger(R.integer.config_screenOnDropAlphaFadeDelay));
+        alphaFadeOut.setDuration(res.getInteger(R.integer.config_screenOnDropAlphaFadeDuration));
 
-            AnimatorSet bouncer = new AnimatorSet();
-            bouncer.play(scaleUp).before(scaleDown);
-            bouncer.play(scaleUp).with(alphaFadeOut);
-            bouncer.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    setIsDragOverlapping(true);
-                }
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    setIsDragOverlapping(false);
-                    setHoverScale(1.0f);
-                    setHoverAlpha(1.0f);
-                }
-            });
-            bouncer.start();
-        }
+        AnimatorSet bouncer = new AnimatorSet();
+        bouncer.play(scaleUp).before(scaleDown);
+        bouncer.play(scaleUp).with(alphaFadeOut);
+        bouncer.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                setIsDragOverlapping(true);
+            }
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                setIsDragOverlapping(false);
+                setHoverScale(1.0f);
+                setHoverAlpha(1.0f);
+            }
+        });
+        bouncer.start();
     }
 
     @Override
@@ -421,7 +417,7 @@
         // When we're small, we are either drawn normally or in the "accepts drops" state (during
         // a drag). However, we also drag the mini hover background *over* one of those two
         // backgrounds
-        if (LauncherApplication.isScreenLarge() && mBackgroundAlpha > 0.0f) {
+        if (mBackgroundAlpha > 0.0f) {
             Drawable bg;
             boolean mini = getScaleX() < 0.5f;
 
diff --git a/src/com/android/launcher2/DeleteDropTarget.java b/src/com/android/launcher2/DeleteDropTarget.java
index 5c67793..4986a31 100644
--- a/src/com/android/launcher2/DeleteDropTarget.java
+++ b/src/com/android/launcher2/DeleteDropTarget.java
@@ -126,7 +126,7 @@
     public void onDragExit(DragObject d) {
         super.onDragExit(d);
 
-        mIcon.reverseTransition(sTransitionDuration);
+        mIcon.resetTransition();
         setTextColor(mDefaultTextColor);
     }
 
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 22ce003..b9c2f09 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -168,7 +168,7 @@
 
     /** The different states that Launcher can be in. */
     private enum State { WORKSPACE, APPS_CUSTOMIZE, ALL_APPS, CUSTOMIZE,
-        CUSTOMIZE_SPRING_LOADED, ALL_APPS_SPRING_LOADED };
+        APPS_CUSTOMIZE_SPRING_LOADED };
     private State mState = State.WORKSPACE;
     private AnimatorSet mStateAnimation;
 
@@ -2667,7 +2667,16 @@
         setPivotsForZoom(toView, toState, scale);
 
         if (toAllApps) {
-            if (!springLoaded) {
+            if (springLoaded) {
+                if (toState == State.APPS_CUSTOMIZE) {
+                    // Shrink workspaces away if going back to AppsCustomize from spring loaded mode
+                    mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated);
+                } else {
+                    // Shrink workspaces to bottom if going back to AllApps from spring loaded mode
+                    mWorkspace.shrink(ShrinkState.BOTTOM_VISIBLE, animated);
+                }
+            } else {
+                // Shrink workspaces away if going to AllApps/AppsCustomize from workspace
                 mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated);
 
                 if (LauncherApplication.isScreenLarge()) {
@@ -2675,10 +2684,9 @@
                     // controls when it should hide/show the mini workspaces
                     mAllAppsPagedView.resetSuccessfulDropFlag();
                 }
-            } else {
-                mWorkspace.shrink(ShrinkState.BOTTOM_VISIBLE, animated);
             }
         } else {
+            // In Customize mode, shrink the workspaces to the top
             mWorkspace.shrink(ShrinkState.TOP, animated);
         }
 
@@ -2897,39 +2905,25 @@
     }
 
     void enterSpringLoadedDragMode(CellLayout layout) {
+        // Enter spring loaded mode on a new layout
         mWorkspace.enterSpringLoadedDragMode(layout);
-        if (mState == State.ALL_APPS || mState == State.APPS_CUSTOMIZE) {
-            mState = State.ALL_APPS_SPRING_LOADED;
-            if (LauncherApplication.isScreenLarge()) {
-                cameraZoomIn(State.ALL_APPS, true, true);
-            } else {
-                cameraZoomIn(State.APPS_CUSTOMIZE, true, true);
-            }
-        } else if (mState == State.CUSTOMIZE) {
-            mState = State.CUSTOMIZE_SPRING_LOADED;
-            cameraZoomIn(State.CUSTOMIZE, true, true);
-        }/* else {
-            // we're already in spring loaded mode; don't do anything
-        }*/
+
+        if (mState == State.APPS_CUSTOMIZE) {
+            mState = State.APPS_CUSTOMIZE_SPRING_LOADED;
+            cameraZoomIn(State.APPS_CUSTOMIZE, true, true);
+        } else {
+            // Do nothing
+        }
     }
 
     void exitSpringLoadedDragMode() {
-        if (mState == State.ALL_APPS_SPRING_LOADED) {
-            mWorkspace.exitSpringLoadedDragMode(Workspace.ShrinkState.BOTTOM_VISIBLE);
-            if (LauncherApplication.isScreenLarge()) {
-                cameraZoomOut(State.ALL_APPS, true, true);
-                mState = State.ALL_APPS;
-            } else {
-                cameraZoomOut(State.APPS_CUSTOMIZE, true, true);
-                mState = State.APPS_CUSTOMIZE;
-            }
-        } else if (mState == State.CUSTOMIZE_SPRING_LOADED) {
-            mWorkspace.exitSpringLoadedDragMode(Workspace.ShrinkState.TOP);
-            cameraZoomOut(State.CUSTOMIZE, true, true);
-            mState = State.CUSTOMIZE;
-        }/* else {
-            // we're not in spring loaded mode; don't do anything
-        }*/
+        if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {
+            mWorkspace.exitSpringLoadedDragMode(Workspace.ShrinkState.BOTTOM_HIDDEN);
+            cameraZoomOut(State.APPS_CUSTOMIZE, true, true);
+            mState = State.APPS_CUSTOMIZE;
+        } else {
+            // Do nothing
+        }
     }
 
     void showAllApps(boolean animated) {
@@ -3001,7 +2995,7 @@
      */
     void closeAllApps(boolean animated) {
         if (LauncherApplication.isScreenLarge()) {
-            if (mState == State.ALL_APPS || mState == State.ALL_APPS_SPRING_LOADED) {
+            if (mState == State.ALL_APPS) {
                 mWorkspace.setVisibility(View.VISIBLE);
                 cameraZoomIn(State.ALL_APPS, animated, false);
 
@@ -3009,7 +3003,7 @@
                 findViewById(R.id.all_apps_button).requestFocus();
             }
         } else {
-            if (mState == State.APPS_CUSTOMIZE || mState == State.ALL_APPS_SPRING_LOADED) {
+            if (mState == State.APPS_CUSTOMIZE || mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {
                 mWorkspace.setVisibility(View.VISIBLE);
                 cameraZoomIn(State.APPS_CUSTOMIZE, animated, false);
 
@@ -3045,7 +3039,7 @@
 
     // Hide the customization drawer (only exists in x-large configuration)
     void hideCustomizationDrawer(boolean animated) {
-        if (mState == State.CUSTOMIZE || mState == State.CUSTOMIZE_SPRING_LOADED) {
+        if (mState == State.CUSTOMIZE) {
             cameraZoomIn(State.CUSTOMIZE, animated, false);
 
             // Set focus to the customize button
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 8ee3810..79f0d56 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -62,7 +62,7 @@
     private static final int PAGE_SNAP_ANIMATION_DURATION = 550;
     protected static final float NANOTIME_DIV = 1000000000.0f;
 
-    private static final float OVERSCROLL_DAMP_FACTOR = 0.08f;
+    private static final float OVERSCROLL_DAMP_FACTOR = 0.14f;
     private static final int MINIMUM_SNAP_VELOCITY = 2200;
     private static final int MIN_FLING_VELOCITY = 250;
     private static final float RETURN_TO_ORIGINAL_PAGE_THRESHOLD = 0.33f;
@@ -470,12 +470,18 @@
             childrenX[i] = child.getX();
             childrenY[i] = child.getY();
         }
-        onLayout(false, mLeft, mTop, mRight, mBottom);
+        // Trigger a full re-layout (never just call onLayout directly!)
+        int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);
+        int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY);
+        requestLayout();
+        measure(widthSpec, heightSpec);
+        layout(mLeft, mTop, mRight, mBottom);
         for (int i = 0; i < childCount; i++) {
             final View child = getChildAt(i);
             child.setX(childrenX[i]);
             child.setY(childrenY[i]);
         }
+
         // Also, the page offset has changed  (since the pages are now smaller);
         // update the page offset, but again preserving absolute X and Y coordinates
         scrollToNewPageWithoutMovingPages(mCurrentPage);
diff --git a/src/com/android/launcher2/SmoothPagedView.java b/src/com/android/launcher2/SmoothPagedView.java
index 8b0a835..fe763f5 100644
--- a/src/com/android/launcher2/SmoothPagedView.java
+++ b/src/com/android/launcher2/SmoothPagedView.java
@@ -87,7 +87,7 @@
     }
 
     protected int getScrollMode() {
-        return DEFAULT_MODE;
+        return X_LARGE_MODE;
     }
 
     /**
diff --git a/src/com/android/launcher2/SpringLoadedDragController.java b/src/com/android/launcher2/SpringLoadedDragController.java
index 9007581..37a94d4 100644
--- a/src/com/android/launcher2/SpringLoadedDragController.java
+++ b/src/com/android/launcher2/SpringLoadedDragController.java
@@ -26,8 +26,6 @@
     // the screen the user is currently hovering over, if any
     private CellLayout mScreen;
     private Launcher mLauncher;
-    boolean mFinishedAnimation = false;
-    boolean mWaitingToReenter = false;
 
     public SpringLoadedDragController(Launcher launcher) {
         mLauncher = launcher;
@@ -35,35 +33,25 @@
         mAlarm.setOnAlarmListener(this);
     }
 
-    public void onDragEnter(CellLayout cl, boolean isSpringLoaded) {
+    public void cancel() {
+        mAlarm.cancelAlarm();
+    }
+
+    // Set a new alarm to expire for the screen that we are hovering over now
+    public void setAlarm(CellLayout cl) {
+        if (mScreen != cl) {
+            mAlarm.setAlarm(ENTER_SPRING_LOAD_HOVER_TIME);
+        }
         mScreen = cl;
-        mAlarm.setAlarm(ENTER_SPRING_LOAD_HOVER_TIME);
-        mFinishedAnimation = isSpringLoaded;
-        mWaitingToReenter = false;
-    }
-
-    public void onEnterSpringLoadedMode(boolean waitToReenter) {
-        mFinishedAnimation = true;
-        mWaitingToReenter = waitToReenter;
-    }
-
-    public void onDragExit() {
-        if (mScreen != null) {
-            mScreen.onDragExit();
-        }
-        mScreen = null;
-        if (mFinishedAnimation && !mWaitingToReenter) {
-            mAlarm.setAlarm(EXIT_SPRING_LOAD_HOVER_TIME);
-        }
     }
 
     // this is called when our timer runs out
     public void onAlarm(Alarm alarm) {
         if (mScreen != null) {
-            // we're currently hovering over a screen
-            mLauncher.enterSpringLoadedDragMode(mScreen);
-        } else {
-            mLauncher.exitSpringLoadedDragMode();
+            // Snap to the screen that we are hovering over now
+            Workspace w = mLauncher.getWorkspace();
+            int page = w.indexOfChild(mScreen);
+            w.snapToPage(page);
         }
     }
 }
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 812763f..fee6b5b 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -16,13 +16,17 @@
 
 package com.android.launcher2;
 
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
 import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
-import android.animation.Animator.AnimatorListener;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.app.AlertDialog;
 import android.app.WallpaperManager;
@@ -48,6 +52,7 @@
 import android.os.IBinder;
 import android.os.Parcelable;
 import android.util.AttributeSet;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Pair;
 import android.view.Display;
@@ -65,10 +70,6 @@
 import com.android.launcher2.FolderIcon.FolderRingAnimator;
 import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
 
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
 /**
  * The workspace is a wide area with a wallpaper and a finite number of pages.
  * Each page contains a number of icons, folders or widgets the user can
@@ -80,9 +81,6 @@
     @SuppressWarnings({"UnusedDeclaration"})
     private static final String TAG = "Launcher.Workspace";
 
-    // How much the screens shrink when we enter spring loaded drag mode
-    private static final float SPRING_LOADED_DRAG_SHRINK_FACTOR = 0.7f;
-
     // Y rotation to apply to the workspace screens
     private static final float WORKSPACE_ROTATION = 12.5f;
 
@@ -161,6 +159,7 @@
     private int[] mTempLocation = new int[2];
 
     private SpringLoadedDragController mSpringLoadedDragController;
+    private float mSpringLoadedShrinkFactor;
 
     private static final int DEFAULT_CELL_COUNT_X = 4;
     private static final int DEFAULT_CELL_COUNT_Y = 4;
@@ -176,7 +175,6 @@
     private AnimatorListener mUnshrinkAnimationListener;
     enum ShrinkState { TOP, SPRING_LOADED, MIDDLE, BOTTOM_HIDDEN, BOTTOM_VISIBLE };
     private ShrinkState mShrinkState;
-    private boolean mWasSpringLoadedOnDragExit = false;
     private boolean mWaitingToShrink = false;
     private ShrinkState mWaitingToShrinkState;
     private AnimatorSet mAnimator;
@@ -271,12 +269,15 @@
         TypedArray a = context.obtainStyledAttributes(attrs,
                 R.styleable.Workspace, defStyle, 0);
 
+        final Resources res = context.getResources();
         if (LauncherApplication.isScreenLarge()) {
             // Determine number of rows/columns dynamically
             // TODO: This code currently fails on tablets with an aspect ratio < 1.3.
             // Around that ratio we should make cells the same size in portrait and
             // landscape
-            final Resources res = context.getResources();
+            final DisplayMetrics dm = res.getDisplayMetrics();
+            float widthDp = dm.widthPixels / dm.density;
+            float heightDp = dm.heightPixels / dm.density;
 
             TypedArray actionBarSizeTypedArray =
                 context.obtainStyledAttributes(new int[] { android.R.attr.actionBarSize });
@@ -296,6 +297,9 @@
             }
         }
 
+        mSpringLoadedShrinkFactor =
+            res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f;
+
         // if the value is manually specified, use that instead
         cellCountX = a.getInt(R.styleable.Workspace_cellCountX, cellCountX);
         cellCountY = a.getInt(R.styleable.Workspace_cellCountY, cellCountY);
@@ -341,14 +345,7 @@
             public void onAnimationEnd(Animator animation) {
                 mIsInUnshrinkAnimation = false;
                 mSyncWallpaperOffsetWithScroll = true;
-                if (mShrinkState == ShrinkState.SPRING_LOADED) {
-                    View layout = null;
-                    if (mLastDragView != null) {
-                        layout = findMatchingPageForDragOver(mLastDragView, mLastDragOriginX,
-                                mLastDragOriginY, mLastDragXOffset, mLastDragYOffset);
-                    }
-                    mSpringLoadedDragController.onEnterSpringLoadedMode(layout == null);
-                } else {
+                if (mShrinkState != ShrinkState.SPRING_LOADED) {
                     mDrawCustomizeTrayBackground = false;
                 }
                 mWallpaperOffset.setOverrideHorizontalCatchupConstant(false);
@@ -373,11 +370,7 @@
 
     @Override
     protected int getScrollMode() {
-        if (LauncherApplication.isScreenLarge()) {
-            return SmoothPagedView.X_LARGE_MODE;
-        } else {
-            return SmoothPagedView.DEFAULT_MODE;
-        }
+        return SmoothPagedView.X_LARGE_MODE;
     }
 
     private void onAddView(View child) {
@@ -1917,7 +1910,7 @@
         int newCurrentPage = indexOfChild(clThatWasClicked);
         if (mIsSmall) {
             if (springLoaded) {
-                setLayoutScale(SPRING_LOADED_DRAG_SHRINK_FACTOR);
+                setLayoutScale(mSpringLoadedShrinkFactor);
             }
             scrollToNewPageWithoutMovingPages(newCurrentPage);
             unshrink(true, springLoaded);
@@ -1928,13 +1921,17 @@
     public void enterSpringLoadedDragMode(CellLayout clThatWasClicked) {
         mShrinkState = ShrinkState.SPRING_LOADED;
         unshrink(clThatWasClicked, true);
+        mDragTargetLayout = getCurrentDropLayout();
         mDragTargetLayout.onDragEnter();
+        mDragTargetLayout.setIsDragOverlapping(true);
+        showOutlines();
     }
 
     public void exitSpringLoadedDragMode(ShrinkState shrinkState) {
         shrink(shrinkState);
         if (mDragTargetLayout != null) {
             mDragTargetLayout.onDragExit();
+            mDragTargetLayout = null;
         }
     }
 
@@ -1953,7 +1950,7 @@
             float finalScaleFactor = 1.0f;
             float finalBackgroundAlpha = 0.0f;
             if (springLoaded) {
-                finalScaleFactor = SPRING_LOADED_DRAG_SHRINK_FACTOR;
+                finalScaleFactor = mSpringLoadedShrinkFactor;
                 finalBackgroundAlpha = 1.0f;
             } else {
                 mIsSmall = false;
@@ -2001,9 +1998,7 @@
                     // alpha.  See screenScrolled().
                     finalAlphaValue = 1f;
                 }
-                float finalAlphaMultiplierValue =
-                        ((i == mCurrentPage) && (mShrinkState != ShrinkState.SPRING_LOADED)) ?
-                        0.0f : 1.0f;
+                float finalAlphaMultiplierValue = 1f;
 
                 float translation = 0f;
 
@@ -2650,8 +2645,7 @@
             // Prepare it to be animated into its new position
             // This must be called after the view has been re-parented
             setPositionForDropAnimation(d.dragView, loc[0], loc[1], parent, cell);
-            boolean animateDrop = !mWasSpringLoadedOnDragExit;
-            parent.onDropChild(cell, animateDrop);
+            parent.onDropChild(cell, true);
         }
     }
 
@@ -2669,8 +2663,12 @@
     }
 
     public void onDragEnter(DragObject d) {
-        mDragTargetLayout = null; // Reset the drag state
         mLastDragOverView = null;
+        if (mDragTargetLayout != null) {
+            mDragTargetLayout.onDragExit();
+            mDragTargetLayout = null; // Reset the drag state
+        }
+
         if (!mIsSmall) {
             mDragTargetLayout = getCurrentDropLayout();
             mDragTargetLayout.onDragEnter();
@@ -3050,24 +3048,21 @@
                 if (layout != null && layout != mDragTargetLayout) {
                     if (mDragTargetLayout != null) {
                         mDragTargetLayout.setIsDragOverlapping(false);
-                        mSpringLoadedDragController.onDragExit();
+                        mDragTargetLayout.clearDragOutlines();
                     }
                     mDragTargetLayout = layout;
 
-                    // Workaround the fact that we don't actually want spring-loaded mode in phone
-                    // UI yet.
-                    if (LauncherApplication.isScreenLarge()) {
-                        // In spring-loaded mode, we still want the user to be able to hover over a
-                        // full screen (which is traditionally set to not accept drops) if they want
-                        // to get to pages beyond the screen that is full.
-                        boolean allowDragOver = (mDragTargetLayout != null) &&
-                                (mDragTargetLayout.getAcceptsDrops() ||
-                                        (mShrinkState == ShrinkState.SPRING_LOADED));
-                        if (allowDragOver) {
-                            mDragTargetLayout.setIsDragOverlapping(true);
-                            mSpringLoadedDragController.onDragEnter(
-                                    mDragTargetLayout, mShrinkState == ShrinkState.SPRING_LOADED);
+                    // In spring-loaded mode, we still want the user to be able to hover over a
+                    // full screen (which is traditionally set to not accept drops) if they want
+                    // to get to pages beyond the screen that is full.
+                    boolean isInSpringLoadedMode = (mShrinkState == ShrinkState.SPRING_LOADED);
+                    boolean allowDragOver = (mDragTargetLayout != null) &&
+                            (mDragTargetLayout.getAcceptsDrops() || isInSpringLoadedMode);
+                    if (allowDragOver) {
+                        if (isInSpringLoadedMode) {
+                            mSpringLoadedDragController.setAlarm(mDragTargetLayout);
                         }
+                        mDragTargetLayout.setIsDragOverlapping(true);
                     }
                 }
             } else {
@@ -3185,7 +3180,6 @@
     }
 
     private void doDragExit(DragObject d) {
-        mWasSpringLoadedOnDragExit = mShrinkState == ShrinkState.SPRING_LOADED;
         if (mDragFolderRingAnimator != null && mCreateUserFolderOnDrop) {
             mDragFolderRingAnimator.animateToNaturalState();
         }
@@ -3202,9 +3196,6 @@
         if (!mIsPageMoving) {
             hideOutlines();
         }
-        if (mShrinkState == ShrinkState.SPRING_LOADED) {
-            mLauncher.exitSpringLoadedDragMode();
-        }
         clearAllHovers();
     }
 
@@ -3311,8 +3302,7 @@
             }
             addInScreen(view, indexOfChild(cellLayout), mTargetCell[0],
                     mTargetCell[1], info.spanX, info.spanY, insertAtFirst);
-            boolean animateDrop = !mWasSpringLoadedOnDragExit;
-            cellLayout.onDropChild(view, animateDrop);
+            cellLayout.onDropChild(view, false);
             cellLayout.animateDrop();
             CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
             cellLayout.getChildrenLayout().measureChild(view);
@@ -3467,7 +3457,6 @@
         for (int i = 0; i < childCount; i++) {
             ((CellLayout) getChildAt(i)).setIsDragOverlapping(false);
         }
-        mSpringLoadedDragController.onDragExit();
 
         // In portrait, workspace is responsible for drawing the edge glow on adjacent pages,
         // so we need to redraw the workspace when this may have changed.