Merge "Import revised translations."
diff --git a/src/com/android/launcher2/CellLayoutChildren.java b/src/com/android/launcher2/CellLayoutChildren.java
index 555bef7..ac8c2ca 100644
--- a/src/com/android/launcher2/CellLayoutChildren.java
+++ b/src/com/android/launcher2/CellLayoutChildren.java
@@ -150,7 +150,7 @@
             final View view = getChildAt(i);
             view.setDrawingCacheEnabled(enabled);
             // Update the drawing caches
-            if (!view.isHardwareAccelerated()) {
+            if (!view.isHardwareAccelerated() && enabled) {
                 view.buildDrawingCache(true);
             }
         }
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index eb0db69..28c53d1 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -483,14 +483,14 @@
                 mScrollState = SCROLL_WAITING_IN_ZONE;
                 mScrollRunnable.setDirection(SCROLL_LEFT);
                 mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
-                mDragScroller.onEnterScrollArea(SCROLL_LEFT);
+                mDragScroller.onEnterScrollArea(x, y, SCROLL_LEFT);
             }
         } else if (!inDeleteRegion && x > mScrollView.getWidth() - mScrollZone) {
             if (mScrollState == SCROLL_OUTSIDE_ZONE && mDistanceSinceScroll > slop) {
                 mScrollState = SCROLL_WAITING_IN_ZONE;
                 mScrollRunnable.setDirection(SCROLL_RIGHT);
                 mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
-                mDragScroller.onEnterScrollArea(SCROLL_RIGHT);
+                mDragScroller.onEnterScrollArea(x, y, SCROLL_RIGHT);
             }
         } else {
             if (mScrollState == SCROLL_WAITING_IN_ZONE) {
diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java
index 809a651..7fbde54 100644
--- a/src/com/android/launcher2/DragLayer.java
+++ b/src/com/android/launcher2/DragLayer.java
@@ -342,11 +342,16 @@
         final int fromY = r.top;
 
         animateViewIntoPosition(dragView, fromX, fromY, pos[0], pos[1], scale,
-                onFinishRunnable, true);
+                onFinishRunnable, true, -1);
     }
 
     public void animateViewIntoPosition(DragView dragView, final View child,
             final Runnable onFinishAnimationRunnable) {
+        animateViewIntoPosition(dragView, child, -1, onFinishAnimationRunnable);
+    }
+
+    public void animateViewIntoPosition(DragView dragView, final View child, int duration,
+            final Runnable onFinishAnimationRunnable) {
         ((CellLayoutChildren) child.getParent()).measureChild(child);
         CellLayout.LayoutParams lp =  (CellLayout.LayoutParams) child.getLayoutParams();
 
@@ -396,16 +401,17 @@
                 oa.start();
             }
         };
-        animateViewIntoPosition(dragView, fromX, fromY, toX, toY, scale, onCompleteRunnable, true);
+        animateViewIntoPosition(dragView, fromX, fromY, toX, toY, scale,
+                onCompleteRunnable, true, duration);
     }
 
     private void animateViewIntoPosition(final View view, final int fromX, final int fromY,
             final int toX, final int toY, float finalScale, Runnable onCompleteRunnable,
-            boolean fadeOut) {
+            boolean fadeOut, int duration) {
         Rect from = new Rect(fromX, fromY, fromX +
                 view.getMeasuredWidth(), fromY + view.getMeasuredHeight());
         Rect to = new Rect(toX, toY, toX + view.getMeasuredWidth(), toY + view.getMeasuredHeight());
-        animateView(view, from, to, 1f, finalScale, -1, null, null, onCompleteRunnable, true);
+        animateView(view, from, to, 1f, finalScale, duration, null, null, onCompleteRunnable, true);
     }
 
     /**
diff --git a/src/com/android/launcher2/DragScroller.java b/src/com/android/launcher2/DragScroller.java
index 6ef4bd8..894b06b 100644
--- a/src/com/android/launcher2/DragScroller.java
+++ b/src/com/android/launcher2/DragScroller.java
@@ -30,7 +30,7 @@
      *
      * @param direction The scroll direction
      */
-    void onEnterScrollArea(int direction);
+    void onEnterScrollArea(int x, int y, int direction);
 
     /**
      * The touch point has left the scroll area.
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index 45730e0..641e0f7 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -243,12 +243,14 @@
 
     public void doneEditingFolderName(boolean commit) {
         mFolderName.setHint(sHintText);
-        mInfo.setTitle(mFolderName.getText());
         LauncherModel.updateItemInDatabase(mLauncher, mInfo);
         mFolderName.setCursorVisible(false);
         mFolderName.clearFocus();
         Selection.setSelection((Spannable) mFolderName.getText(), 0, 0);
         mIsEditingName = false;
+        // Convert to a string here to ensure that no other state associated with the text field
+        // gets saved.
+        mInfo.setTitle(mFolderName.getText().toString());
     }
 
     public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
diff --git a/src/com/android/launcher2/SpringLoadedDragController.java b/src/com/android/launcher2/SpringLoadedDragController.java
index 7b4adf3..358362c 100644
--- a/src/com/android/launcher2/SpringLoadedDragController.java
+++ b/src/com/android/launcher2/SpringLoadedDragController.java
@@ -18,7 +18,8 @@
 
 public class SpringLoadedDragController implements OnAlarmListener {
     // how long the user must hover over a mini-screen before it unshrinks
-    final long ENTER_SPRING_LOAD_HOVER_TIME = 1000;
+    final long ENTER_SPRING_LOAD_HOVER_TIME = 550;
+    final long ENTER_SPRING_LOAD_CANCEL_HOVER_TIME = 950;
     final long EXIT_SPRING_LOAD_HOVER_TIME = 200;
 
     Alarm mAlarm;
@@ -40,7 +41,8 @@
     // Set a new alarm to expire for the screen that we are hovering over now
     public void setAlarm(CellLayout cl) {
         mAlarm.cancelAlarm();
-        mAlarm.setAlarm(ENTER_SPRING_LOAD_HOVER_TIME);
+        mAlarm.setAlarm((cl == null) ? ENTER_SPRING_LOAD_CANCEL_HOVER_TIME :
+            ENTER_SPRING_LOAD_HOVER_TIME);
         mScreen = cl;
     }
 
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index ecc5483..11528e4 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -97,6 +97,8 @@
     private static final int BACKGROUND_FADE_OUT_DURATION = 350;
     private static final int BACKGROUND_FADE_IN_DURATION = 350;
 
+    private static final int ADJACENT_SCREEN_DROP_DURATION = 300;
+
     // These animators are used to fade the children's outlines
     private ObjectAnimator mChildrenOutlineFadeInAnimation;
     private ObjectAnimator mChildrenOutlineFadeOutAnimation;
@@ -213,6 +215,9 @@
     final static float TOUCH_SLOP_DAMPING_FACTOR = 4;
 
     // These variables are used for storing the initial and final values during workspace animations
+    private int mSavedScrollX;
+    private float mSavedRotationY;
+    private float mSavedTranslationX;
     private float mCurrentScaleX;
     private float mCurrentScaleY;
     private float mCurrentRotationY;
@@ -1289,6 +1294,10 @@
         for (int i = 0; i < screenCount; i++) {
             final CellLayout layout = (CellLayout) getChildAt(i);
             layout.setChildrenDrawnWithCacheEnabled(false);
+            // In software mode, we don't want the items to continue to be drawn into bitmaps
+            if (!isHardwareAccelerated()) {
+                layout.setChildrenDrawingCacheEnabled(false);
+            }
         }
     }
 
@@ -1530,14 +1539,6 @@
                         cl.setFastAlpha(a * mOldAlphas[i] + b * mNewAlphas[i]);
                         cl.setFastRotationY(a * mOldRotationYs[i] + b * mNewRotationYs[i]);
                     }
-
-                    // Shrink the hotset the same amount we are shrinking the screens
-                    if (shrinkState == State.SPRING_LOADED && mLauncher.getHotseat() != null) {
-                        View hotseat = mLauncher.getHotseat().getLayout();
-                        hotseat.fastInvalidate();
-                        hotseat.setFastScaleX(a * mOldScaleXs[0] + b * mNewScaleXs[0]);
-                        hotseat.setFastScaleY(a * mOldScaleXs[0] + b * mNewScaleXs[0]);
-                    }
                 }
             });
             mAnimator.playTogether(animWithInterpolator);
@@ -1811,6 +1812,14 @@
                     mUnshrinkAnimationListener.onAnimationEnd(null);
                 }
             }
+
+            // Unshrink the hotset the same amount we are unshrinking the screens
+            if (mLauncher.getHotseat() != null) {
+                View hotseat = mLauncher.getHotseat().getLayout();
+                hotseat.setScaleX(finalScaleFactor);
+                hotseat.setScaleY(finalScaleFactor);
+            }
+
             Display display = mLauncher.getWindowManager().getDefaultDisplay();
             boolean isLandscape = display.getWidth() > display.getHeight();
             // on phones, don't scroll the wallpaper horizontally or vertically when switching
@@ -1879,14 +1888,6 @@
                                     b * mNewBackgroundAlphaMultipliers[i]);
                             cl.setFastAlpha(a * mOldAlphas[i] + b * mNewAlphas[i]);
                         }
-
-                        // Unshrink the hotset the same amount we are unshrinking the screens
-                        if (mLauncher.getHotseat() != null) {
-                            View hotseat = mLauncher.getHotseat().getLayout();
-                            hotseat.fastInvalidate();
-                            hotseat.setFastScaleX(a * mOldScaleXs[0] + b * mNewScaleXs[0]);
-                            hotseat.setFastScaleY(a * mOldScaleXs[0] + b * mNewScaleXs[0]);
-                        }
                     }
                 });
 
@@ -2289,6 +2290,7 @@
         }
         CellLayout dropTargetLayout = mDragTargetLayout;
 
+        int snapScreen = -1;
         if (d.dragSource != this) {
             final int[] touchXY = new int[] { (int) mDragViewVisualCenter[0],
                     (int) mDragViewVisualCenter[1] };
@@ -2323,8 +2325,7 @@
                         mDragViewVisualCenter[1], spanX, spanY, dropTargetLayout, mTargetCell);
                 // If the item being dropped is a shortcut and the nearest drop
                 // cell also contains a shortcut, then create a folder with the two shortcuts.
-                boolean dropInscrollArea = hasMovedLayouts && !hasMovedIntoHotseat;
-                if (!dropInscrollArea && createUserFolderIfNecessary(cell, container,
+                if (!mInScrollArea && createUserFolderIfNecessary(cell, container,
                         dropTargetLayout, mTargetCell, false, d.dragView, null)) {
                     return;
                 }
@@ -2339,11 +2340,11 @@
                         (int) mDragViewVisualCenter[1], mDragInfo.spanX, mDragInfo.spanY, cell,
                         dropTargetLayout, mTargetCell);
 
-                if (dropInscrollArea && mState != State.SPRING_LOADED) {
+                if (mInScrollArea && !hasMovedIntoHotseat && mState != State.SPRING_LOADED) {
+                    snapScreen = screen;
                     snapToPage(screen);
                 }
 
-
                 if (mTargetCell[0] >= 0 && mTargetCell[1] >= 0) {
                     if (hasMovedLayouts) {
                         // Reparent the view
@@ -2406,8 +2407,11 @@
             };
             mAnimatingViewIntoPlace = true;
             if (d.dragView.hasDrawn()) {
-                mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, cell,
+                int duration = snapScreen < 0 ? -1 : ADJACENT_SCREEN_DROP_DURATION;
+                setFinalScrollForPageChange(snapScreen);
+                mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, cell, duration,
                         disableHardwareLayersRunnable);
+                resetFinalScrollForPageChange(snapScreen);
             } else {
                 cell.setVisibility(VISIBLE);
             }
@@ -2415,6 +2419,28 @@
         }
     }
 
+    public void setFinalScrollForPageChange(int screen) {
+        if (screen >= 0) {
+            mSavedScrollX = getScrollX();
+            CellLayout cl = (CellLayout) getChildAt(screen);
+            mSavedTranslationX = cl.getTranslationX();
+            mSavedRotationY = cl.getRotationY();
+            final int newX = getChildOffset(screen) - getRelativeChildOffset(screen);
+            setScrollX(newX);
+            cl.setTranslationX(0f);
+            cl.setRotationY(0f);
+        }
+    }
+
+    public void resetFinalScrollForPageChange(int screen) {
+        if (screen >= 0) {
+            CellLayout cl = (CellLayout) getChildAt(screen);
+            setScrollX(mSavedScrollX);
+            cl.setTranslationX(mSavedTranslationX);
+            cl.setRotationY(mSavedRotationY);
+        }
+    }
+
     public void getViewLocationRelativeToSelf(View v, int[] location) {
         getLocationInWindow(location);
         int x = location[0];
@@ -3269,7 +3295,16 @@
     }
 
     @Override
-    public void onEnterScrollArea(int direction) {
+    public void onEnterScrollArea(int x, int y, int direction) {
+        // Ignore the scroll area if we are dragging over the hot seat
+        if (mLauncher.getHotseat() != null) {
+            Rect r = new Rect();
+            mLauncher.getHotseat().getHitRect(r);
+            if (r.contains(x, y)) {
+                return;
+            }
+        }
+
         if (!isSmall() && !mIsSwitchingState) {
             mInScrollArea = true;