Layout tweaks in Launcher

-Removed All apps and Configure toolbar buttons
from Customization Drawer, removed Configure
button from All apps and added Market icon
to All apps
-Changed spacing of CellLayouts when scrolling
-Modified gap spacing in workspace layout
-Made workspace invisible in All apps but touching
the place where the workspace was takes you back
to workspace

Change-Id: I6e2579bfebeb8f1f80fdae07da442f6d399abe33
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java
index 351384f..f472600 100644
--- a/src/com/android/launcher2/AllAppsPagedView.java
+++ b/src/com/android/launcher2/AllAppsPagedView.java
@@ -498,8 +498,10 @@
             }
         });
 
-        menu.add(0, MENU_APP_INFO, 0, R.string.cab_menu_app_info).setActionView(infoButton);
         menu.add(0, MENU_DELETE_APP, 0, R.string.cab_menu_delete_app).setActionView(deleteZone);
+        menu.add(0, MENU_APP_INFO, 0, R.string.cab_menu_app_info).setActionView(infoButton);
+
+        mLauncher.getWorkspace().shrinkToBottomVisible();
 
         return true;
     }
@@ -531,6 +533,8 @@
 
         mDragController.removeDropTarget(this);
         endChoiceMode();
+
+        mLauncher.getWorkspace().shrinkToBottomHidden();
     }
 
     @Override
diff --git a/src/com/android/launcher2/AllAppsTabbed.java b/src/com/android/launcher2/AllAppsTabbed.java
index a6e21b9..0e32461 100644
--- a/src/com/android/launcher2/AllAppsTabbed.java
+++ b/src/com/android/launcher2/AllAppsTabbed.java
@@ -25,6 +25,7 @@
 import android.content.res.Resources;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.MotionEvent;
 import android.view.View;
 import android.widget.TabHost;
 
@@ -169,4 +170,12 @@
     public void surrender() {
         mAllApps.surrender();
     }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        if (ev.getY() > mAllApps.getBottom()) {
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/src/com/android/launcher2/ApplicationInfoDropTarget.java b/src/com/android/launcher2/ApplicationInfoDropTarget.java
index 3e5ebd5..c2922ab 100644
--- a/src/com/android/launcher2/ApplicationInfoDropTarget.java
+++ b/src/com/android/launcher2/ApplicationInfoDropTarget.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher2;
 
+import com.android.launcher.R;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.Paint;
@@ -133,11 +135,16 @@
             // In that case, this icon is more tightly spaced next to the delete icon so we want
             // it to have a smaller drag region. When the new drag&drop system comes in, we'll
             // dispatch the drag/drop by calculating what target you're overlapping
-            final int dragPadding = mManageVisibility ? 50 : 10;
-            outRect.top -= dragPadding;
-            outRect.left -= dragPadding;
-            outRect.bottom += dragPadding;
-            outRect.right += dragPadding;
+            final int minPadding = R.dimen.delete_zone_min_padding;
+            final int maxPadding = R.dimen.delete_zone_max_padding;
+            final int outerDragPadding =
+                    getResources().getDimensionPixelSize(R.dimen.delete_zone_size);
+            final int innerDragPadding = getResources().getDimensionPixelSize(
+                    mManageVisibility ? maxPadding : minPadding);
+            outRect.top -= outerDragPadding;
+            outRect.left -= innerDragPadding;
+            outRect.bottom += outerDragPadding;
+            outRect.right += outerDragPadding;
         }
     }
 
diff --git a/src/com/android/launcher2/DeleteZone.java b/src/com/android/launcher2/DeleteZone.java
index 4acde1c..be651b2 100644
--- a/src/com/android/launcher2/DeleteZone.java
+++ b/src/com/android/launcher2/DeleteZone.java
@@ -210,56 +210,72 @@
             // In that case, this icon is more tightly spaced next to the delete icon so we want
             // it to have a smaller drag region. When the new drag&drop system comes in, we'll
             // dispatch the drag/drop by calculating what target you're overlapping
-            final int dragPadding = mManageVisibility ? 50 : 10;
-            outRect.top -= dragPadding;
-            outRect.left -= dragPadding;
-            outRect.bottom += dragPadding;
-            outRect.right += dragPadding;
+            final int minPadding = R.dimen.delete_zone_min_padding;
+            final int maxPadding = R.dimen.delete_zone_max_padding;
+            final int outerDragPadding =
+                    getResources().getDimensionPixelSize(R.dimen.delete_zone_size);
+            final int innerDragPadding = getResources().getDimensionPixelSize(
+                    mManageVisibility ? maxPadding : minPadding);
+            outRect.top -= outerDragPadding;
+            outRect.left -= innerDragPadding;
+            outRect.bottom += outerDragPadding;
+            outRect.right += innerDragPadding;
         }
     }
 
     private void createAnimations() {
-        if (mInAnimation == null) {
-            mInAnimation = new FastAnimationSet();
-            final AnimationSet animationSet = mInAnimation;
-            animationSet.setInterpolator(new AccelerateInterpolator());
-            animationSet.addAnimation(new AlphaAnimation(0.0f, 1.0f));
-            if (mOrientation == ORIENTATION_HORIZONTAL) {
-                animationSet.addAnimation(new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f,
-                        Animation.RELATIVE_TO_SELF, 0.0f));
-            } else {
-                animationSet.addAnimation(new TranslateAnimation(Animation.RELATIVE_TO_SELF,
-                        1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f));
-            }
-            animationSet.setDuration(ANIMATION_DURATION);
-        }
         if (mHandleInAnimation == null) {
             mHandleInAnimation = new AlphaAnimation(0.0f, 1.0f);
             mHandleInAnimation.setDuration(ANIMATION_DURATION);
         }
-        if (mOutAnimation == null) {
-            mOutAnimation = new FastAnimationSet();
-            final AnimationSet animationSet = mOutAnimation;
-            animationSet.setInterpolator(new AccelerateInterpolator());
-            animationSet.addAnimation(new AlphaAnimation(1.0f, 0.0f));
-            if (mOrientation == ORIENTATION_HORIZONTAL) {
-                animationSet.addAnimation(new FastTranslateAnimation(Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
-                        Animation.RELATIVE_TO_SELF, 1.0f));
+
+        if (mInAnimation == null) {
+            mInAnimation = new FastAnimationSet();
+            if (!LauncherApplication.isScreenXLarge()) {
+                final AnimationSet animationSet = mInAnimation;
+                animationSet.setInterpolator(new AccelerateInterpolator());
+                animationSet.addAnimation(new AlphaAnimation(0.0f, 1.0f));
+                if (mOrientation == ORIENTATION_HORIZONTAL) {
+                    animationSet.addAnimation(new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
+                            Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f,
+                            Animation.RELATIVE_TO_SELF, 0.0f));
+                } else {
+                    animationSet.addAnimation(new TranslateAnimation(Animation.RELATIVE_TO_SELF,
+                            1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.ABSOLUTE, 0.0f,
+                            Animation.ABSOLUTE, 0.0f));
+                }
+                animationSet.setDuration(ANIMATION_DURATION);
             } else {
-                animationSet.addAnimation(new FastTranslateAnimation(Animation.RELATIVE_TO_SELF,
-                        0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.ABSOLUTE, 0.0f,
-                        Animation.ABSOLUTE, 0.0f));
+                mInAnimation.addAnimation(mHandleInAnimation);
             }
-            animationSet.setDuration(ANIMATION_DURATION);
         }
+
         if (mHandleOutAnimation == null) {
             mHandleOutAnimation = new AlphaAnimation(1.0f, 0.0f);
             mHandleOutAnimation.setFillAfter(true);
             mHandleOutAnimation.setDuration(ANIMATION_DURATION);
         }
+
+        if (mOutAnimation == null) {
+            mOutAnimation = new FastAnimationSet();
+            if (!LauncherApplication.isScreenXLarge()) {
+                final AnimationSet animationSet = mOutAnimation;
+                animationSet.setInterpolator(new AccelerateInterpolator());
+                animationSet.addAnimation(new AlphaAnimation(1.0f, 0.0f));
+                if (mOrientation == ORIENTATION_HORIZONTAL) {
+                    animationSet.addAnimation(new FastTranslateAnimation(Animation.ABSOLUTE, 0.0f,
+                            Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
+                            Animation.RELATIVE_TO_SELF, 1.0f));
+                } else {
+                    animationSet.addAnimation(new FastTranslateAnimation(Animation.RELATIVE_TO_SELF,
+                            0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.ABSOLUTE, 0.0f,
+                            Animation.ABSOLUTE, 0.0f));
+                }
+                animationSet.setDuration(ANIMATION_DURATION);
+            } else {
+                mOutAnimation.addAnimation(mHandleOutAnimation);
+            }
+        }
     }
 
     void setLauncher(Launcher launcher) {
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index d796fbe..272bf8b 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -20,7 +20,6 @@
 
 import android.content.Context;
 import android.graphics.Bitmap;
-import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.Handler;
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 464ea64..9954f39 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -312,7 +312,6 @@
             String shortcutsLabel = getString(R.string.shortcuts_tab_label);
             mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(SHORTCUTS_TAG)
                     .setIndicator(shortcutsLabel).setContent(contentFactory));
-
             mHomeCustomizationDrawer.setOnTabChangedListener(new OnTabChangeListener() {
                 public void onTabChanged(String tabId) {
                     // animate the changing of the tab content by fading pages in and out
@@ -876,6 +875,7 @@
         }
 
         mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace);
+
         final Workspace workspace = mWorkspace;
         workspace.setHapticFeedbackEnabled(false);
 
@@ -2479,7 +2479,6 @@
     private void hideAndShowToolbarButtons(State newState, AnimatorSet showSeq, AnimatorSet hideSeq) {
         final View searchButton = findViewById(R.id.search_button);
         final View allAppsButton = findViewById(R.id.all_apps_button);
-        final View marketButton = findViewById(R.id.market_button);
         final View configureButton = findViewById(R.id.configure_button);
 
         switch (newState) {
@@ -2487,20 +2486,16 @@
             hideOrShowToolbarButton(true, searchButton, showSeq);
             hideOrShowToolbarButton(true, allAppsButton, showSeq);
             hideOrShowToolbarButton(true, configureButton, showSeq);
-            hideOrShowToolbarButton(false, marketButton, hideSeq);
             mDeleteZone.setHandle(allAppsButton);
             break;
         case ALL_APPS:
-            hideOrShowToolbarButton(true, configureButton, showSeq);
-            hideOrShowToolbarButton(true, marketButton, showSeq);
+            hideOrShowToolbarButton(false, configureButton, hideSeq);
             hideOrShowToolbarButton(false, searchButton, hideSeq);
             hideOrShowToolbarButton(false, allAppsButton, hideSeq);
-            mDeleteZone.setHandle(marketButton);
             break;
         case CUSTOMIZE:
-            hideOrShowToolbarButton(true, allAppsButton, showSeq);
+            hideOrShowToolbarButton(false, allAppsButton, hideSeq);
             hideOrShowToolbarButton(false, searchButton, hideSeq);
-            hideOrShowToolbarButton(false, marketButton, hideSeq);
             hideOrShowToolbarButton(false, configureButton, hideSeq);
             mDeleteZone.setHandle(allAppsButton);
             break;
@@ -2544,7 +2539,7 @@
         setPivotsForZoom(toView, toState, scale);
 
         if (toAllApps) {
-            mWorkspace.shrinkToBottom(animated);
+            mWorkspace.shrinkToBottomHidden(animated);
         } else {
             mWorkspace.shrinkToTop(animated);
         }
@@ -2683,7 +2678,7 @@
         mAllAppsPagedView.endChoiceMode();
 
         if (toState == State.ALL_APPS) {
-            mWorkspace.shrinkToBottom(animated);
+            mWorkspace.shrinkToBottomHidden(animated);
         } else {
             mWorkspace.shrinkToTop(animated);
         }
@@ -2754,6 +2749,7 @@
 
         // TODO: fade these two too
         mDeleteZone.setVisibility(View.GONE);
+
         // Change the state *after* we've called all the transition code
         mState = State.ALL_APPS;
     }
@@ -2774,6 +2770,7 @@
         } else if (mState == State.CUSTOMIZE) {
             hideCustomizationDrawer(animated);
         }
+
         // Change the state *after* we've called all the transition code
         mState = State.WORKSPACE;
     }
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index d4dffe6..fb8b7d6 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -349,11 +349,16 @@
             throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
         }
 
+        /* Allow the height to be set as WRAP_CONTENT. This allows the particular case
+         * of the All apps view on XLarge displays to not take up more space then it needs. Width
+         * is still not allowed to be set as WRAP_CONTENT since many parts of the code expect
+         * each page to have the same width.
+         */
         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-        if (heightMode != MeasureSpec.EXACTLY) {
-            throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
-        }
+        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+        int maxChildHeight = 0;
+
+        final int verticalPadding = mPaddingTop + mPaddingBottom;
 
         // The children are given the same width and height as the workspace
         // unless they were set to WRAP_CONTENT
@@ -380,9 +385,14 @@
             final int childWidthMeasureSpec =
                 MeasureSpec.makeMeasureSpec(widthSize, childWidthMode);
             final int childHeightMeasureSpec =
-                MeasureSpec.makeMeasureSpec(heightSize, childHeightMode);
+                MeasureSpec.makeMeasureSpec(heightSize - verticalPadding, childHeightMode);
 
             child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+            maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
+        }
+
+        if (heightMode == MeasureSpec.AT_MOST) {
+            heightSize = maxChildHeight + verticalPadding;
         }
 
         setMeasuredDimension(widthSize, heightSize);
@@ -399,6 +409,7 @@
             mFirstLayout = false;
         }
 
+        final int verticalPadding = mPaddingTop + mPaddingBottom;
         final int childCount = getChildCount();
         int childLeft = 0;
         if (childCount > 0) {
@@ -409,10 +420,13 @@
             final View child = getChildAt(i);
             if (child.getVisibility() != View.GONE) {
                 final int childWidth = child.getMeasuredWidth();
-                final int childHeight = (mCenterPagesVertically ?
-                        (getMeasuredHeight() - child.getMeasuredHeight()) / 2 : 0);
-                child.layout(childLeft, childHeight,
-                        childLeft + childWidth, childHeight + child.getMeasuredHeight());
+                final int childHeight = child.getMeasuredHeight();
+                int childTop = mPaddingTop;
+                if (mCenterPagesVertically) {
+                    childTop += ((getMeasuredHeight() - verticalPadding) - childHeight) / 2;
+                }
+                child.layout(childLeft, childTop,
+                        childLeft + childWidth, childTop + childHeight);
                 childLeft += childWidth + mPageSpacing;
             }
         }
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 7e33a2c..b5b0c56 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -43,6 +43,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
+import android.graphics.Camera;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.Paint;
@@ -83,6 +84,7 @@
 
     // Y rotation to apply to the workspace screens
     private static final float WORKSPACE_ROTATION = 12.5f;
+    private static final float WORKSPACE_TRANSLATION = 50.0f;
 
     // These are extra scale factors to apply to the mini home screens
     // so as to achieve the desired transform
@@ -154,7 +156,6 @@
     private AnimatorSet mAnimator;
 
     private boolean mInScrollArea = false;
-    private boolean mInDragMode = false;
 
     private final HolographicOutlineHelper mOutlineHelper = new HolographicOutlineHelper();
     private Bitmap mDragOutline = null;
@@ -172,6 +173,11 @@
     /** Used to trigger an animation as soon as the workspace stops scrolling. */
     private Animator mAnimOnPageEndMoving = null;
 
+    // Camera and Matrix used to determine the final position of a neighboring CellLayout
+    private final Matrix mMatrix = new Matrix();
+    private final Camera mCamera = new Camera();
+    private final float mTempFloat2[] = new float[2];
+
     /**
      * Used to inflate the Workspace from XML.
      *
@@ -414,7 +420,10 @@
     public boolean onTouch(View v, MotionEvent event) {
         // this is an intercepted event being forwarded from a cell layout
         if (mIsSmall || mIsInUnshrinkAnimation) {
-            mLauncher.onWorkspaceClick((CellLayout) v);
+            // Only allow clicks on a CellLayout if it is visible
+            if (mShrunkenState != ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) {
+                mLauncher.onWorkspaceClick((CellLayout) v);
+            }
             return true;
         } else if (!mPageMoving) {
             if (v == getChildAt(mCurrentPage - 1)) {
@@ -444,7 +453,12 @@
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         if (mIsSmall || mIsInUnshrinkAnimation) {
-            // when the home screens are shrunken, shouldn't allow side-scrolling
+            if (mLauncher.isAllAppsVisible() &&
+                    mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) {
+                // Intercept this event so we can show the workspace in full view
+                // when it is clicked on and it is small
+                return true;
+            }
             return false;
         }
         return super.onInterceptTouchEvent(ev);
@@ -550,6 +564,31 @@
         return mBackgroundAlpha;
     }
 
+    /**
+     * Due to 3D transformations, if two CellLayouts are theoretically touching each other,
+     * on the xy plane, when one is rotated along the y-axis, the gap between them is perceived
+     * as being larger. This method computes what offset the rotated view should be translated
+     * in order to minimize this perceived gap.
+     * @param degrees Angle of the view
+     * @param width Width of the view
+     * @param height Height of the view
+     * @return Offset to be used in a View.setTranslationX() call
+     */
+    private float getOffsetXForRotation(float degrees, int width, int height) {
+        mMatrix.reset();
+        mCamera.save();
+        mCamera.rotateY(Math.abs(degrees));
+        mCamera.getMatrix(mMatrix);
+        mCamera.restore();
+
+        mMatrix.preTranslate(-width * 0.5f, -height * 0.5f);
+        mMatrix.postTranslate(width * 0.5f, height * 0.5f);
+        mTempFloat2[0] = width;
+        mTempFloat2[1] = height;
+        mMatrix.mapPoints(mTempFloat2);
+        return (width - mTempFloat2[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
+    }
+
     @Override
     protected void screenScrolled(int screenCenter) {
         final int halfScreenSize = getMeasuredWidth() / 2;
@@ -567,6 +606,8 @@
                 cl.setBackgroundAlphaMultiplier(Math.abs(scrollProgress));
 
                 float rotation = WORKSPACE_ROTATION * scrollProgress;
+                float translationX = getOffsetXForRotation(rotation, cl.getWidth(), cl.getHeight());
+                cl.setTranslationX(translationX);
                 cl.setRotationY(rotation);
             }
         }
@@ -681,6 +722,7 @@
                 return false;
             }
         }
+
         return super.dispatchTouchEvent(ev);
     }
 
@@ -719,7 +761,14 @@
                 mScroller.abortAnimation();
             }
             setCurrentPage(mCurrentPage);
-            return false; // We don't want the events.  Let them fall through to the all apps view.
+
+            if (mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) {
+                mLauncher.showWorkspace(true);
+                // Let the events fall through to the CellLayouts because if they are not
+                // hit, then we get a crash due to a missing ACTION_DOWN touch event
+            }
+
+            return false; // We don't want the events
         }
 
         return super.onTouchEvent(ev);
@@ -737,14 +786,22 @@
         shrink(ShrinkPosition.SHRINK_TO_MIDDLE, true);
     }
 
-    void shrinkToBottom() {
-        shrinkToBottom(true);
+    void shrinkToBottomHidden() {
+        shrinkToBottomHidden(true);
     }
 
-    void shrinkToBottom(boolean animated) {
+    void shrinkToBottomVisible() {
+        shrinkToBottomVisible(true);
+    }
+
+    void shrinkToBottomHidden(boolean animated) {
         shrink(ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN, animated);
     }
 
+    void shrinkToBottomVisible(boolean animated) {
+        shrink(ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE, animated);
+    }
+
     private float getYScaleForScreen(int screen) {
         int x = Math.abs(screen - 2);
 
@@ -813,7 +870,7 @@
             // We shrink and disappear to nothing in the case of all apps
             // (which is when we shrink to the bottom)
             newY = screenHeight - newY - scaledPageHeight;
-            finalAlpha = 0.25f;
+            finalAlpha = 0.0f;
         } else if (shrinkPosition == ShrinkPosition.SHRINK_TO_MIDDLE) {
             newY = screenHeight / 2 - scaledPageHeight / 2;
             finalAlpha = 1.0f;
@@ -985,14 +1042,11 @@
      * start a drag in Launcher, regardless of whether the drag has ever entered the Workspace
      *
      * These methods mark the appropriate pages as accepting drops (which alters their visual
-     * appearance) and, if the pages are hidden, makes them visible.
+     * appearance).
      *
      */
     public void onDragStartedWithItemSpans(int spanX, int spanY) {
         updateWhichPagesAcceptDropsDuringDrag(mShrunkenState, spanX, spanY);
-        if (mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) {
-            shrink(ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE, true);
-        }
     }
 
     public void onDragStartedWithItemMinSize(int minWidth, int minHeight) {
@@ -1004,9 +1058,6 @@
     // never dragged over
     public void onDragStopped() {
         updateWhichPagesAcceptDrops(mShrunkenState);
-        if (mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE) {
-            shrink(ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN, true);
-        }
     }
 
     // We call this when we trigger an unshrink by clicking on the CellLayout cl
@@ -1051,6 +1102,7 @@
             if (mAnimator != null) {
                 mAnimator.cancel();
             }
+
             mAnimator = new AnimatorSet();
             final int screenCount = getChildCount();
 
@@ -1066,10 +1118,11 @@
                     rotation = -WORKSPACE_ROTATION;
                 }
 
-                if (animated) {
+                float translation = getOffsetXForRotation(rotation, cl.getWidth(), cl.getHeight());
 
+                if (animated) {
                     ObjectAnimator animWithInterpolator = ObjectAnimator.ofPropertyValuesHolder(cl,
-                            PropertyValuesHolder.ofFloat("translationX", 0.0f),
+                            PropertyValuesHolder.ofFloat("translationX", translation),
                             PropertyValuesHolder.ofFloat("translationY", 0.0f),
                             PropertyValuesHolder.ofFloat("scaleX", 1.0f),
                             PropertyValuesHolder.ofFloat("scaleY", 1.0f),
@@ -1080,7 +1133,7 @@
                     animWithInterpolator.setInterpolator(mZoomInInterpolator);
                     mAnimator.playTogether(animWithInterpolator);
                 } else {
-                    cl.setTranslationX(0.0f);
+                    cl.setTranslationX(translation);
                     cl.setTranslationY(0.0f);
                     cl.setScaleX(1.0f);
                     cl.setScaleY(1.0f);
@@ -1089,6 +1142,7 @@
                     cl.setRotationY(rotation);
                 }
             }
+
             if (animated) {
                 // If we call this when we're not animated, onAnimationEnd is never called on
                 // the listener; make sure we only use the listener when we're actually animating
@@ -1418,7 +1472,6 @@
             mDragTargetLayout = getCurrentDropLayout();
             mDragTargetLayout.onDragEnter();
             showOutlines();
-            mInDragMode = true;
         }
     }
 
@@ -1823,7 +1876,6 @@
         }
         if (!mIsPageMoving) {
             hideOutlines();
-            mInDragMode = false;
         }
         clearAllHovers();
     }