Modifying wallpapers customization page to look like widgets.

- Disallowing touch handling when there are no children

Change-Id: I925d6f1f862f8c7994a80c4eaacc80f8d59f6ab2
diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java
index c432f37..14b2429 100644
--- a/src/com/android/launcher2/CustomizePagedView.java
+++ b/src/com/android/launcher2/CustomizePagedView.java
@@ -77,12 +77,18 @@
     // The mapping between the pages and the widgets that will be laid out on them
     private ArrayList<ArrayList<AppWidgetProviderInfo>> mWidgetPages;
 
-    // The max dimensions for the ImageView we use for displaying the widget
+    // The max dimensions for the ImageView we use for displaying a widget
     private int mMaxWidgetWidth;
 
-    // The max number of widget cells to take a "page" of widget
+    // The max number of widget cells to take a "page" of widgets
     private int mMaxWidgetsCellHSpan;
 
+    // The size of the items on the wallpaper tab
+    private int mWallpaperCellHSpan;
+
+    // The max dimensions for the ImageView we use for displaying a wallpaper
+    private int mMaxWallpaperWidth;
+
     // The raw sources of data for each of the different tabs of the customization page
     private List<AppWidgetProviderInfo> mWidgetList;
     private List<ResolveInfo> mShortcutList;
@@ -112,15 +118,15 @@
         super(context, attrs, defStyle);
 
         TypedArray a;
-        a = context.obtainStyledAttributes(attrs, R.styleable.CustomizePagedView,
-                defStyle, 0);
+        a = context.obtainStyledAttributes(attrs, R.styleable.CustomizePagedView, defStyle, 0);
+        mWallpaperCellHSpan = a.getInt(R.styleable.CustomizePagedView_wallpaperCellSpanX, 4);
         mMaxWidgetsCellHSpan = a.getInt(R.styleable.CustomizePagedView_widgetCellCountX, 8);
         a.recycle();
         a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, defStyle, 0);
         mCellCountX = a.getInt(R.styleable.PagedView_cellCountX, 7);
         mCellCountY = a.getInt(R.styleable.PagedView_cellCountY, 4);
-
         a.recycle();
+
         mCustomizationType = CustomizationType.WidgetCustomization;
         mWidgetPages = new ArrayList<ArrayList<AppWidgetProviderInfo>>();
         mWorkspaceWidgetLayout = new PagedViewCellLayout(context);
@@ -449,21 +455,58 @@
     /**
      * Helper function to draw a drawable to the specified canvas with the specified bounds.
      */
-    private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int l, int t, int r, int b) {
+    private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h) {
         if (bitmap != null) mCanvas.setBitmap(bitmap);
         mCanvas.save();
-        d.setBounds(l, t, r, b);
+        d.setBounds(x, y, x+w, y+h);
         d.draw(mCanvas);
         mCanvas.restore();
     }
 
     /**
+     * This method will extract the preview image specified by the wallpaper source provider (if it
+     * exists) otherwise, it will try to generate a default image preview.
+     */
+    private Drawable getWallpaperPreview(ResolveInfo info) {
+        // To be implemented later: resolving the up-to-date wallpaper thumbnail
+
+        final int minDim = mWorkspaceWidgetLayout.estimateCellWidth(1);
+        final int dim = mWorkspaceWidgetLayout.estimateCellWidth(mWallpaperCellHSpan);
+        Resources resources = mLauncher.getResources();
+
+        // Create a new bitmap to hold the widget preview
+        int width = (int) (dim * sScaleFactor);
+        int height = (int) (dim * sScaleFactor);
+        final Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
+        final Drawable background = resources.getDrawable(R.drawable.default_widget_preview);
+        renderDrawableToBitmap(background, bitmap, 0, 0, width, height);
+
+        // Draw the icon flush left
+        try {
+            final IconCache iconCache =
+                ((LauncherApplication) mLauncher.getApplication()).getIconCache();
+            Drawable icon = new FastBitmapDrawable(Utilities.createIconBitmap(
+                    iconCache.getFullResIcon(info, mPackageManager), mContext));
+
+            final int iconSize = minDim / 2;
+            final int offset = iconSize / 4;
+            renderDrawableToBitmap(icon, null, offset, offset, iconSize, iconSize);
+        } catch (Resources.NotFoundException e) {
+            // if we can't find the icon, then just don't draw it
+        }
+
+        Drawable drawable = new FastBitmapDrawable(bitmap);
+        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+        return drawable;
+    }
+
+    /**
      * This method will extract the preview image specified by the widget developer (if it exists),
      * otherwise, it will try to generate a default image preview with the widget's package icon.
-     * @return the drawable will be used and sized in the ImageView to represent the widget
+     * @return the drawable that will be used and sized in the ImageView to represent the widget
      */
     private Drawable getWidgetPreview(AppWidgetProviderInfo info) {
-        PackageManager packageManager = mLauncher.getPackageManager();
+        final PackageManager packageManager = mPackageManager;
         String packageName = info.provider.getPackageName();
         Drawable drawable = null;
         if (info.previewImage != 0) {
@@ -487,9 +530,8 @@
             final Drawable background = resources.getDrawable(R.drawable.default_widget_preview);
             renderDrawableToBitmap(background, bitmap, 0, 0, width, height);
 
-            // Draw the icon vertically centered, flush left
+            // Draw the icon flush left
             try {
-                Rect tmpRect = new Rect();
                 Drawable icon = null;
                 if (info.icon > 0) {
                     icon = packageManager.getDrawable(packageName, info.icon, null);
@@ -497,12 +539,10 @@
                 if (icon == null) {
                     icon = resources.getDrawable(R.drawable.ic_launcher_application);
                 }
-                background.getPadding(tmpRect);
 
                 final int iconSize = minDim / 2;
                 final int offset = iconSize / 4;
-                final int offsetIconSize = offset + iconSize;
-                renderDrawableToBitmap(icon, null, offset, offset, offsetIconSize, offsetIconSize);
+                renderDrawableToBitmap(icon, null, offset, offset, iconSize, iconSize);
             } catch (Resources.NotFoundException e) {
                 // if we can't find the icon, then just don't draw it
             }
@@ -548,6 +588,7 @@
         mWorkspaceWidgetLayout.setPadding(20, 10, 20, 0);
 
         mMaxWidgetWidth = mWorkspaceWidgetLayout.estimateCellWidth(sMaxWidgetCellHSpan);
+        mMaxWallpaperWidth = mWorkspaceWidgetLayout.estimateCellWidth(mWallpaperCellHSpan);
     }
 
     private void syncWidgetPages() {
@@ -557,7 +598,7 @@
         removeAllViews();
         int numPages = relayoutWidgets();
         for (int i = 0; i < numPages; ++i) {
-            LinearLayout layout = new PagedViewWidgetLayout(getContext());
+            LinearLayout layout = new PagedViewExtendedLayout(getContext());
             layout.setGravity(Gravity.CENTER_HORIZONTAL);
             layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
                     mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
@@ -610,6 +651,58 @@
         }
     }
 
+    private void syncWallpaperPages() {
+        if (mWallpaperList == null) return;
+
+        // We need to repopulate the LinearLayout for the wallpaper pages
+        removeAllViews();
+        int numPages = (int) Math.ceil((float) (mWallpaperList.size() * mWallpaperCellHSpan) /
+                mMaxWidgetsCellHSpan);
+        for (int i = 0; i < numPages; ++i) {
+            LinearLayout layout = new PagedViewExtendedLayout(getContext());
+            layout.setGravity(Gravity.CENTER_HORIZONTAL);
+            layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
+                    mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
+
+            // Temporary change to prevent the last page from being too small (and items bleeding
+            // onto it).  We can remove this once we properly fix the fading algorithm
+            if (i < numPages - 1) {
+                addView(layout, new LinearLayout.LayoutParams(
+                        LinearLayout.LayoutParams.WRAP_CONTENT,
+                        LinearLayout.LayoutParams.MATCH_PARENT));
+            } else {
+                addView(layout, new LinearLayout.LayoutParams(
+                        LinearLayout.LayoutParams.MATCH_PARENT,
+                        LinearLayout.LayoutParams.MATCH_PARENT));
+            }
+        }
+    }
+
+    private void syncWallpaperPageItems(int page) {
+        // Load the items on to the pages
+        LinearLayout layout = (LinearLayout) getChildAt(page);
+        layout.removeAllViews();
+        final int count = mWallpaperList.size();
+        for (int i = 0; i < count; ++i) {
+            final ResolveInfo info = mWallpaperList.get(i);
+
+            LinearLayout l = (LinearLayout) mInflater.inflate(
+                    R.layout.customize_paged_view_wallpaper, layout, false);
+            l.setTag(info);
+            l.setOnClickListener(this);
+
+            final Drawable icon = getWallpaperPreview(info);
+
+            ImageView image = (ImageView) l.findViewById(R.id.wallpaper_preview);
+            image.setMaxWidth(mMaxWidgetWidth);
+            image.setImageDrawable(icon);
+            TextView name = (TextView) l.findViewById(R.id.wallpaper_name);
+            name.setText(info.loadLabel(mPackageManager));
+
+            layout.addView(l);
+        }
+    }
+
     private void syncListPages(List<ResolveInfo> list) {
         // we need to repopulate with PagedViewCellLayouts
         removeAllViews();
@@ -716,8 +809,7 @@
             centerPagedViewCellLayouts = true;
             break;
         case WallpaperCustomization:
-            syncListPages(mWallpaperList);
-            centerPagedViewCellLayouts = true;
+            syncWallpaperPages();
             break;
         case ApplicationCustomization:
             syncAppPages();
@@ -757,7 +849,7 @@
             syncListPageItems(page, mShortcutList);
             break;
         case WallpaperCustomization:
-            syncListPageItems(page, mWallpaperList);
+            syncWallpaperPageItems(page);
             break;
         case ApplicationCustomization:
             syncAppPageItems(page);
diff --git a/src/com/android/launcher2/FastBitmapDrawable.java b/src/com/android/launcher2/FastBitmapDrawable.java
index 1cafa09..1aa8b35 100644
--- a/src/com/android/launcher2/FastBitmapDrawable.java
+++ b/src/com/android/launcher2/FastBitmapDrawable.java
@@ -16,12 +16,13 @@
 
 package com.android.launcher2;
 
-import android.graphics.drawable.Drawable;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 
 class FastBitmapDrawable extends Drawable {
     private Bitmap mBitmap;
@@ -41,7 +42,8 @@
 
     @Override
     public void draw(Canvas canvas) {
-        canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
+        final Rect r = getBounds();
+        canvas.drawBitmap(mBitmap, r.left, r.top, mPaint);
     }
 
     @Override
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 0622aae..70746b3 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -621,6 +621,9 @@
          * scrolling there.
          */
 
+        // Skip touch handling if there are no pages to swipe
+        if (getChildCount() <= 0) return super.onInterceptTouchEvent(ev);
+
         /*
          * Shortcut the most recurring case: the user is in the dragging
          * state and he is moving his finger.  We want to intercept this
@@ -775,6 +778,9 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
+        // Skip touch handling if there are no pages to swipe
+        if (getChildCount() <= 0) return super.onTouchEvent(ev);
+
         acquireVelocityTrackerAndAddMovement(ev);
 
         final int action = ev.getAction();
diff --git a/src/com/android/launcher2/PagedViewWidgetLayout.java b/src/com/android/launcher2/PagedViewExtendedLayout.java
similarity index 85%
rename from src/com/android/launcher2/PagedViewWidgetLayout.java
rename to src/com/android/launcher2/PagedViewExtendedLayout.java
index 4666873..52df9f1 100644
--- a/src/com/android/launcher2/PagedViewWidgetLayout.java
+++ b/src/com/android/launcher2/PagedViewExtendedLayout.java
@@ -22,20 +22,20 @@
 import android.widget.LinearLayout;
 
 /**
- * The linear layout used strictly for the widget tab of the customization tray
+ * The linear layout used strictly for the widget/wallpaper tab of the customization tray
  */
-public class PagedViewWidgetLayout extends LinearLayout {
+public class PagedViewExtendedLayout extends LinearLayout {
     static final String TAG = "PagedViewWidgetLayout";
 
-    public PagedViewWidgetLayout(Context context) {
+    public PagedViewExtendedLayout(Context context) {
         this(context, null);
     }
 
-    public PagedViewWidgetLayout(Context context, AttributeSet attrs) {
+    public PagedViewExtendedLayout(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
 
-    public PagedViewWidgetLayout(Context context, AttributeSet attrs, int defStyle) {
+    public PagedViewExtendedLayout(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
     }
 
diff --git a/src/com/android/launcher2/PagedViewWidgetIcon.java b/src/com/android/launcher2/PagedViewWidgetIcon.java
deleted file mode 100644
index f285dab..0000000
--- a/src/com/android/launcher2/PagedViewWidgetIcon.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher2;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.Checkable;
-import android.widget.LinearLayout;
-
-import com.android.launcher.R;
-
-/**
- * An widget icon for use specifically in the CustomizePagedView.  In class form so that
- * we can add logic for how it will look when checked/unchecked.
- */
-public class PagedViewWidgetIcon extends LinearLayout implements Checkable {
-    private static final String TAG = "PagedViewIcon";
-
-    // Holographic outline
-    private final Paint mPaint = new Paint();
-    private static HolographicOutlineHelper sHolographicOutlineHelper;
-    private final Paint mErasePaint = new Paint();
-    private Bitmap mCheckedOutline;
-    private Canvas mHolographicOutlineCanvas;
-    private boolean mIsHolographicUpdatePass;
-
-    private int mAlpha;
-
-    private boolean mIsChecked;
-
-    // Highlight colours
-    private int mCheckedBlurColor;
-    private int mCheckedOutlineColor;
-
-
-    public PagedViewWidgetIcon(Context context) {
-        this(context, null);
-    }
-
-    public PagedViewWidgetIcon(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public PagedViewWidgetIcon(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedViewWidgetIcon,
-                defStyle, 0);
-        mCheckedBlurColor = a.getColor(R.styleable.PagedViewWidgetIcon_checkedBlurColor, 0);
-        mCheckedOutlineColor = a.getColor(R.styleable.PagedViewWidgetIcon_checkedOutlineColor, 0);
-        mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
-        mErasePaint.setFilterBitmap(true);
-        a.recycle();
-
-        if (sHolographicOutlineHelper == null) {
-            sHolographicOutlineHelper = new HolographicOutlineHelper();
-        }
-
-        setWillNotDraw(false);
-    }
-
-    public void invalidateCheckedImage() {
-        if (mCheckedOutline != null) {
-            mCheckedOutline.recycle();
-            mCheckedOutline = null;
-        }
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        // Draw the view itself
-        if (mIsHolographicUpdatePass) {
-            canvas.save();
-            final float alpha = getAlpha();
-            super.setAlpha(1.0f);
-            super.onDraw(canvas);
-            super.setAlpha(alpha);
-            canvas.restore();
-        } else {
-            if (mAlpha > 0) {
-                super.onDraw(canvas);
-            }
-        }
-
-        // Draw the holographic checked overlay if necessary
-        if (!mIsHolographicUpdatePass) {
-            if (mCheckedOutline != null) {
-                mPaint.setAlpha(255);
-                canvas.drawBitmap(mCheckedOutline, 0, 0, mPaint);
-            }
-        }
-    }
-
-    @Override
-    public boolean isChecked() {
-        return mIsChecked;
-    }
-
-    @Override
-    public void setChecked(boolean checked) {
-        if (mIsChecked != checked) {
-            mIsChecked = checked;
-
-            if (mIsChecked) {
-                // set a flag to indicate that we are going to draw the view at full alpha
-                mIsHolographicUpdatePass = true;
-                final int width = getMeasuredWidth();
-                final int height = getMeasuredHeight();
-                mCheckedOutline = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-                mHolographicOutlineCanvas = new Canvas(mCheckedOutline);
-                mHolographicOutlineCanvas.concat(getMatrix());
-                draw(mHolographicOutlineCanvas);
-                sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(mCheckedOutline,
-                        mHolographicOutlineCanvas, mCheckedBlurColor, mCheckedOutlineColor);
-
-                // Unlike PagedViewIcon, we can't seem to properly set the clip rect for all the
-                // children to respect when drawing... so for now, we erase over those parts in the
-                // checked highlight image
-                mHolographicOutlineCanvas.drawRect(0, findViewById(R.id.divider).getTop(),
-                        width, height, mErasePaint);
-
-                mIsHolographicUpdatePass = false;
-                mHolographicOutlineCanvas = null;
-            } else {
-                invalidateCheckedImage();
-            }
-
-            invalidate();
-        }
-    }
-
-    @Override
-    public void toggle() {
-        setChecked(!mIsChecked);
-    }
-}