More PagedView cleanup

-> Custom content screen is now full screen (with some padding inserted for now)
-> Hiding the hotseat and page indicators when scrolling to the
   custom content screen
-> Adding background scrim fade in to custom content space.

Change-Id: I28921318a38af46f11fa836020a590c70d5d96ed
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 561bd16..bf9773a 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -839,6 +839,11 @@
         mWorkspace.addCustomContentToLeft(customContent);
     }
 
+    // The custom content needs to offset its content to account for the QSB
+    public int getTopOffsetForCustomContent() {
+        return mWorkspace.getPaddingTop();
+    }
+
     @Override
     public Object onRetainNonConfigurationInstance() {
         // Flag the loader to stop early before switching
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 8027fa1..e97bf8d 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -121,8 +121,8 @@
     protected float mLastMotionY;
     protected float mTotalMotionX;
     private int mLastScreenCenter = -1;
-    private int[] mChildOffsets;
-    private int[] mChildRelativeOffsets;
+
+    private int[] mPageScrolls;
 
     protected final static int TOUCH_STATE_REST = 0;
     protected final static int TOUCH_STATE_SCROLLING = 1;
@@ -397,6 +397,10 @@
         return (getMeasuredHeight() - getViewportHeight()) / 2;
     }
 
+    PageIndicator getPageIndicator() {
+        return mPageIndicator;
+    }
+
     public void setPageSwitchListener(PageSwitchListener pageSwitchListener) {
         mPageSwitchListener = pageSwitchListener;
         if (mPageSwitchListener != null) {
@@ -457,9 +461,7 @@
         // If the current page is invalid, just reset the scroll position to zero
         int newX = 0;
         if (0 <= mCurrentPage && mCurrentPage < getPageCount()) {
-            int offset = getChildOffset(mCurrentPage);
-            int relOffset = getRelativeChildOffset(mCurrentPage);
-            newX = offset - relOffset;
+            newX = getScrollForPage(mCurrentPage);
         }
         scrollTo(newX, 0);
         mScroller.setFinalX(newX);
@@ -663,7 +665,7 @@
         return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
     }
 
-    public void addFullScreenPage(View page, int width, int height) {
+    public void addFullScreenPage(View page) {
         LayoutParams lp = generateDefaultLayoutParams();
         lp.isFullScreenPage = true;
         super.addView(page, 0, lp);
@@ -761,22 +763,14 @@
         }
         setMeasuredDimension(scaledWidthSize, scaledHeightSize);
 
-        // We can't call getChildOffset/getRelativeChildOffset until we set the measured dimensions.
-        // We also wait until we set the measured dimensions before flushing the cache as well, to
-        // ensure that the cache is filled with good values.
-        invalidateCachedOffsets();
-
         if (childCount > 0) {
-            if (DEBUG) Log.d(TAG, "getRelativeChildOffset(): " + getViewportWidth() + ", "
-                    + getChildWidth(0));
-
             // Calculate the variable page spacing if necessary
             if (mAutoComputePageSpacing && mRecomputePageSpacing) {
                 // The gap between pages in the PagedView should be equal to the gap from the page
                 // to the edge of the screen (so it is not visible in the current screen).  To
                 // account for unequal padding on each side of the paged view, we take the maximum
                 // of the left/right gap and use that as the gap between each page.
-                int offset = getRelativeChildOffset(0);
+                int offset = (getViewportWidth() - getChildWidth(0)) / 2;
                 int spacing = Math.max(offset, widthSize - offset -
                         getChildAt(0).getMeasuredWidth());
                 setPageSpacing(spacing);
@@ -787,7 +781,7 @@
 
     public void setPageSpacing(int pageSpacing) {
         mPageSpacing = pageSpacing;
-        invalidateCachedOffsets();
+        requestLayout();
     }
 
     @Override
@@ -799,6 +793,8 @@
         if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
         final int childCount = getChildCount();
 
+        int screenWidth = getViewportWidth();
+
         int offsetX = getViewportOffsetX();
         int offsetY = getViewportOffsetY();
 
@@ -812,7 +808,12 @@
         final int delta = isRtl ? -1 : 1;
 
         int verticalPadding = getPaddingTop() + getPaddingBottom();
-        int childLeft = offsetX + getRelativeChildOffset(startIndex);
+        int childLeft = offsetX + (screenWidth - getChildWidth(startIndex)) / 2;
+
+        if (mPageScrolls == null || getChildCount() != mChildCountOnLastLayout) {
+            mPageScrolls = new int[getChildCount()];
+        }
+
         for (int i = startIndex; i != endIndex; i += delta) {
             final View child = getPageAt(i);
             LayoutParams lp = (LayoutParams) child.getLayoutParams();
@@ -834,6 +835,12 @@
                 if (DEBUG) Log.d(TAG, "\tlayout-child" + i + ": " + childLeft + ", " + childTop);
                 child.layout(childLeft, childTop,
                         childLeft + child.getMeasuredWidth(), childTop + childHeight);
+
+                // We assume the left and right padding are equal, and hence center the pages
+                // horizontally
+                int scrollOffset = false ? 0 : (getViewportWidth() - childWidth) / 2;
+                mPageScrolls[i] = childLeft - scrollOffset - offsetX;
+
                 childLeft += childWidth + mPageSpacing;
             }
         }
@@ -847,7 +854,7 @@
 
         if (childCount > 0) {
             final int index = isLayoutRtl() ? 0 : childCount - 1;
-            mMaxScrollX = getChildOffset(index) - getRelativeChildOffset(index);
+            mMaxScrollX = getScrollForPage(index);
         } else {
             mMaxScrollX = 0;
         }
@@ -889,14 +896,12 @@
         mRecomputePageSpacing = true;
 
         invalidate();
-        invalidateCachedOffsets();
     }
 
     @Override
     public void onChildViewRemoved(View parent, View child) {
         mForceScreenScrolled = true;
         invalidate();
-        invalidateCachedOffsets();
     }
 
     private void removeMarkerForView(int index) {
@@ -939,19 +944,6 @@
         super.removeAllViewsInLayout();
     }
 
-    protected void invalidateCachedOffsets() {
-        int count = getChildCount();
-        if (count == 0) {
-            mChildRelativeOffsets = null;
-            return;
-        }
-
-        mChildRelativeOffsets = new int[count];
-        for (int i = 0; i < count; i++) {
-            mChildRelativeOffsets[i] = -1;
-        }
-    }
-
     protected int getChildOffset(int index) {
         if (index < 0 || index > getChildCount() - 1) return 0;
 
@@ -963,22 +955,6 @@
         return offset;
     }
 
-    protected int getRelativeChildOffset(int index) {
-        if (index < 0 || index > getChildCount() - 1) return 0;
-
-        if (mChildRelativeOffsets != null && mChildRelativeOffsets[index] != -1) {
-            return mChildRelativeOffsets[index];
-        } else {
-            final int padding = getPaddingLeft() + getPaddingRight();
-            final int offset = getPaddingLeft() +
-                    (getViewportWidth() - padding - getChildWidth(index)) / 2;
-            if (mChildRelativeOffsets != null) {
-                mChildRelativeOffsets[index] = offset;
-            }
-            return offset;
-        }
-    }
-
     void boundByReorderablePages(boolean isReordering, int[] range) {
         // Do nothing
     }
@@ -1179,22 +1155,24 @@
      * Return true if a tap at (x, y) should trigger a flip to the previous page.
      */
     protected boolean hitsPreviousPage(float x, float y) {
+        int offset = (getViewportWidth() - getChildWidth(mCurrentPage)) / 2;
         if (isLayoutRtl()) {
             return (x > (getViewportOffsetX() + getViewportWidth() -
-                    getRelativeChildOffset(mCurrentPage) + mPageSpacing));
+                    offset + mPageSpacing));
         }
-        return (x < getViewportOffsetX() + getRelativeChildOffset(mCurrentPage) - mPageSpacing);
+        return (x < getViewportOffsetX() + offset - mPageSpacing);
     }
 
     /**
      * Return true if a tap at (x, y) should trigger a flip to the next page.
      */
     protected boolean hitsNextPage(float x, float y) {
+        int offset = (getViewportWidth() - getChildWidth(mCurrentPage)) / 2;
         if (isLayoutRtl()) {
-            return (x < getViewportOffsetX() + getRelativeChildOffset(mCurrentPage) - mPageSpacing);
+            return (x < getViewportOffsetX() + offset - mPageSpacing);
         }
         return  (x > (getViewportOffsetX() + getViewportWidth() -
-                getRelativeChildOffset(mCurrentPage) + mPageSpacing));
+                offset + mPageSpacing));
     }
 
     /** Returns whether x and y originated within the buffered viewport */
@@ -1412,8 +1390,7 @@
         final int halfScreenSize = getViewportWidth() / 2;
 
         int totalDistance = v.getMeasuredWidth() + mPageSpacing;
-        int delta = screenCenter - (getChildOffset(page) -
-                getRelativeChildOffset(page) + halfScreenSize);
+        int delta = screenCenter - (getScrollForPage(page) + halfScreenSize);
 
         float scrollProgress = delta / (totalDistance * 1.0f);
         scrollProgress = Math.min(scrollProgress, getMaxScrollProgress());
@@ -1421,6 +1398,14 @@
         return scrollProgress;
     }
 
+    public int getScrollForPage(int index) {
+        if (mPageScrolls == null || index >= mPageScrolls.length) {
+            return 0;
+        } else {
+            return mPageScrolls[index];
+        }
+    }
+
     // This curve determines how the effect of scrolling over the limits of the page dimishes
     // as the user pulls further and further from the bounds
     private float overScrollInfluenceCurve(float f) {
@@ -1619,8 +1604,7 @@
                             public void run() {
                                 // Update the down scroll position to account for the fact that the
                                 // current page is moved
-                                mDownScrollX = getChildOffset(pageUnderPointIndex)
-                                        - getRelativeChildOffset(pageUnderPointIndex);
+                                mDownScrollX = getScrollForPage(pageUnderPointIndex);
 
                                 // Setup the scroll to the correct page before we swap the views
                                 snapToPage(pageUnderPointIndex);
@@ -1941,10 +1925,7 @@
         whichPage = Math.max(0, Math.min(whichPage, getChildCount() - 1));
         int halfScreenSize = getViewportWidth() / 2;
 
-        if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
-        if (DEBUG) Log.d(TAG, "snapToPageWithVelocity.getRelativeChildOffset(): "
-                + getViewportWidth() + ", " + getChildWidth(whichPage));
-        final int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
+        final int newX = getScrollForPage(whichPage);
         int delta = newX - mUnboundedScrollX;
         int duration = 0;
 
@@ -1989,10 +1970,7 @@
     protected void snapToPage(int whichPage, int duration, boolean immediate) {
         whichPage = Math.max(0, Math.min(whichPage, getPageCount() - 1));
 
-        if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
-        if (DEBUG) Log.d(TAG, "snapToPage.getRelativeChildOffset(): " + getViewportWidth() + ", "
-                + getChildWidth(whichPage));
-        int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
+        int newX = getScrollForPage(whichPage);
         final int sX = mUnboundedScrollX;
         final int delta = newX - sX;
         snapToPage(whichPage, delta, duration, immediate);
diff --git a/src/com/android/launcher3/SmoothPagedView.java b/src/com/android/launcher3/SmoothPagedView.java
index 1beffac..a45dbbf 100644
--- a/src/com/android/launcher3/SmoothPagedView.java
+++ b/src/com/android/launcher3/SmoothPagedView.java
@@ -130,7 +130,7 @@
         whichPage = Math.max(0, Math.min(whichPage, getChildCount() - 1));
 
         final int screenDelta = Math.max(1, Math.abs(whichPage - mCurrentPage));
-        final int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
+        final int newX = getScrollForPage(whichPage);
         final int delta = newX - mUnboundedScrollX;
         int duration = (screenDelta + 1) * 100;
 
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index ebf7619..7129325 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -523,11 +523,17 @@
 
         Rect p = new Rect();
         AppWidgetHostView.getDefaultPaddingForWidget(mLauncher, mLauncher.getComponentName(), p);
-        customContent.setPadding(p.left, p.top, p.right, p.bottom);
+
+        // For now we force top padding on the entire custom content screen. The intention
+        // is for the hosted content to get this offset and account for it so that upon scrolling
+        // it can use the entire space.
+        customContent.setPadding(p.left, mLauncher.getTopOffsetForCustomContent(),
+                p.right, p.bottom);
 
         mWorkspaceScreens.put(CUSTOM_CONTENT_SCREEN_ID, customScreen);
         mScreenOrder.add(0, CUSTOM_CONTENT_SCREEN_ID);
-        addView(customScreen, 0);
+
+        addFullScreenPage(customScreen);
 
         // Ensure that the current page and default page are maintained.
         mDefaultPage++;
@@ -1290,15 +1296,37 @@
         }
     }
 
+    private boolean hasCustomContent() {
+        return (mScreenOrder.size() > 0 && mScreenOrder.get(0) == CUSTOM_CONTENT_SCREEN_ID);
+    }
+
+    private void updateStateForCustomContent(int screenCenter) {
+        if (hasCustomContent()) {
+            CellLayout customContent = getScreenWithId(CUSTOM_CONTENT_SCREEN_ID);
+            int index = mScreenOrder.indexOf(CUSTOM_CONTENT_SCREEN_ID);
+
+            int scrollDelta = getScrollForPage(index + 1) - getScrollX();
+            float translationX = Math.max(scrollDelta, 0);
+
+            float progress = (1.0f * scrollDelta) /
+                    (getScrollForPage(index + 1) - getScrollForPage(index));
+
+            setBackgroundAlpha(progress * 0.8f);
+            mLauncher.getHotseat().setTranslationX(translationX);
+            getPageIndicator().setTranslationX(translationX);
+        }
+    }
+
     @Override
     protected void screenScrolled(int screenCenter) {
         final boolean isRtl = isLayoutRtl();
         super.screenScrolled(screenCenter);
 
         updatePageAlphaValues(screenCenter);
+        updateStateForCustomContent(screenCenter);
         enableHwLayersOnVisiblePages();
 
-        if (mOverScrollX < 0 || mOverScrollX > mMaxScrollX) {
+        if ((mOverScrollX < 0 && !hasCustomContent()) || mOverScrollX > mMaxScrollX) {
             int index = 0;
             float pivotX = 0f;
             final float leftBiasedPivot = 0.25f;
@@ -2444,7 +2472,7 @@
             mSavedScrollX = getScrollX();
             mSavedTranslationX = cl.getTranslationX();
             mSavedRotationY = cl.getRotationY();
-            final int newX = getChildOffset(pageIndex) - getRelativeChildOffset(pageIndex);
+            final int newX = getScrollForPage(pageIndex);
             setScrollX(newX);
             cl.setTranslationX(0f);
             cl.setRotationY(0f);