Adding folder icon visualization

-> Added new temp assets

Change-Id: If1d7e8ce867b473920f40cd1cc02d189be62b8bf
diff --git a/res/drawable-hdpi/box_launcher_top_normal.9.png b/res/drawable-hdpi/box_launcher_top_normal.9.png
index 98997ad..af04b07 100644
--- a/res/drawable-hdpi/box_launcher_top_normal.9.png
+++ b/res/drawable-hdpi/box_launcher_top_normal.9.png
Binary files differ
diff --git a/res/drawable-hdpi/box_launcher_top_pressed.9.png b/res/drawable-hdpi/box_launcher_top_pressed.9.png
index f52fd48..af04b07 100644
--- a/res/drawable-hdpi/box_launcher_top_pressed.9.png
+++ b/res/drawable-hdpi/box_launcher_top_pressed.9.png
Binary files differ
diff --git a/res/drawable-hdpi/box_launcher_top_selected.9.png b/res/drawable-hdpi/box_launcher_top_selected.9.png
index 8cacf0e..af04b07 100644
--- a/res/drawable-hdpi/box_launcher_top_selected.9.png
+++ b/res/drawable-hdpi/box_launcher_top_selected.9.png
Binary files differ
diff --git a/res/drawable-hdpi/folder_bg.9.png b/res/drawable-hdpi/folder_bg.9.png
new file mode 100644
index 0000000..6f1bbe5
--- /dev/null
+++ b/res/drawable-hdpi/folder_bg.9.png
Binary files differ
diff --git a/res/drawable-mdpi/box_launcher_top_normal.9.png b/res/drawable-mdpi/box_launcher_top_normal.9.png
index 8adf2cf..af04b07 100644
--- a/res/drawable-mdpi/box_launcher_top_normal.9.png
+++ b/res/drawable-mdpi/box_launcher_top_normal.9.png
Binary files differ
diff --git a/res/drawable-mdpi/box_launcher_top_pressed.9.png b/res/drawable-mdpi/box_launcher_top_pressed.9.png
index 7a20c54..af04b07 100644
--- a/res/drawable-mdpi/box_launcher_top_pressed.9.png
+++ b/res/drawable-mdpi/box_launcher_top_pressed.9.png
Binary files differ
diff --git a/res/drawable-mdpi/box_launcher_top_selected.9.png b/res/drawable-mdpi/box_launcher_top_selected.9.png
index 9e636f0..af04b07 100644
--- a/res/drawable-mdpi/box_launcher_top_selected.9.png
+++ b/res/drawable-mdpi/box_launcher_top_selected.9.png
Binary files differ
diff --git a/res/drawable-mdpi/folder_bg.9.png b/res/drawable-mdpi/folder_bg.9.png
new file mode 100644
index 0000000..6f1bbe5
--- /dev/null
+++ b/res/drawable-mdpi/folder_bg.9.png
Binary files differ
diff --git a/res/layout-land/user_folder.xml b/res/layout-land/user_folder.xml
index 975fffd..b814462 100644
--- a/res/layout-land/user_folder.xml
+++ b/res/layout-land/user_folder.xml
@@ -17,7 +17,8 @@
 <com.android.launcher2.Folder
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
-    android:orientation="vertical">
+    android:orientation="vertical"
+    android:background="@drawable/folder_bg">
     
     <Button
         android:id="@+id/folder_close"
@@ -32,8 +33,7 @@
     <FrameLayout
          android:layout_width="match_parent"
          android:layout_height="0dip"
-         android:layout_weight="1"
-         android:background="@drawable/box_launcher_bottom">
+         android:layout_weight="1">
 
         <com.android.launcher2.CellLayout
              android:id="@id/folder_content"
diff --git a/res/layout-port/user_folder.xml b/res/layout-port/user_folder.xml
index 589663a..4901eb2 100644
--- a/res/layout-port/user_folder.xml
+++ b/res/layout-port/user_folder.xml
@@ -17,11 +17,12 @@
 <com.android.launcher2.Folder
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
-    android:orientation="vertical">
-        
+    android:orientation="vertical"
+    android:background="@drawable/folder_bg">
+
     <Button
         android:id="@+id/folder_close"
-   		android:background="@drawable/box_launcher_top"
+	android:background="@drawable/box_launcher_top"
         android:gravity="left|center_vertical"
         android:textSize="14sp"
         android:textColor="#404040"
@@ -32,8 +33,8 @@
     <FrameLayout
          android:layout_width="match_parent"
          android:layout_height="0dip"
-         android:layout_weight="1"
-         android:background="@drawable/box_launcher_bottom">
+         android:layout_weight="1">
+
         <com.android.launcher2.CellLayout
              android:id="@id/folder_content"
              android:layout_width="match_parent"
@@ -54,7 +55,7 @@
              android:listSelector="@drawable/grid_selector"
 
              android:verticalSpacing="10dip"
-             android:numColumns="4" />
+             android:numColumns="5" />
     </FrameLayout>
 
 </com.android.launcher2.Folder>
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index 4c8d03a..5a4358d 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -39,12 +39,13 @@
 import android.widget.AdapterView.OnItemLongClickListener;
 
 import com.android.launcher.R;
+import com.android.launcher2.FolderInfo.FolderListener;
 
 /**
  * Represents a set of icons chosen by the user or generated by the system.
  */
 public class Folder extends LinearLayout implements DragSource, OnItemLongClickListener,
-        OnItemClickListener, OnClickListener, View.OnLongClickListener, DropTarget {
+        OnItemClickListener, OnClickListener, View.OnLongClickListener, DropTarget, FolderListener {
 
     protected DragController mDragController;
 
@@ -71,6 +72,7 @@
     private final LayoutInflater mInflater;
     private final IconCache mIconCache;
     private int mState = STATE_NONE;
+    private int[] mDragItemPosition = new int[2];
 
     /**
      * Used to inflate the Workspace from XML.
@@ -131,7 +133,8 @@
 
             mLauncher.getWorkspace().onDragStartedWithItem(v);
             mDragController.startDrag(v, this, item, DragController.DRAG_ACTION_COPY);
-
+            mDragItemPosition[0] = item.cellX;
+            mDragItemPosition[1] = item.cellY;
             mLauncher.closeFolder(this);
             mDragItem = item;
         } else {
@@ -198,6 +201,7 @@
             }
             createAndAddShortcut((ShortcutInfo) children.get(i));
         }
+        mInfo.addListener(this);
     }
 
     /**
@@ -409,4 +413,25 @@
             DragView dragView, Object dragInfo) {
         return null;
     }
+
+    public void onAdd(ShortcutInfo item) {
+        if ((item.cellX == -1 && item.cellY == -1) ||
+                mContent.isOccupied(item.cellX, item.cellY)) {
+            findAndSetEmptyCells(item);
+        }
+        createAndAddShortcut(item);
+    }
+
+    public int getItemCount() {
+        return mContent.getChildrenLayout().getChildCount();
+    }
+
+    public View getItemAt(int index) {
+        return mContent.getChildrenLayout().getChildAt(index);
+    }
+
+    public void onRemove(ShortcutInfo item) {
+        View v = mContent.getChildAt(mDragItemPosition[0], mDragItemPosition[1]);
+        mContent.removeView(v);
+    }
 }
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index cf7e3cd..b770cd6 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -18,21 +18,27 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.TextView;
 
 import com.android.launcher.R;
+import com.android.launcher2.FolderInfo.FolderListener;
 
 /**
  * An icon that can appear on in the workspace representing an {@link UserFolder}.
  */
-public class FolderIcon extends BubbleTextView implements DropTarget {
-    private FolderInfo mInfo;
+public class FolderIcon extends FrameLayout implements DropTarget, FolderListener {
     private Launcher mLauncher;
-    private Drawable mCloseIcon;
-    private Drawable mOpenIcon;
+    Folder mFolder;
+    FolderInfo mInfo;
+
+    private static final int NUM_ITEMS_IN_PREVIEW = 4;
+    private static final float ICON_ANGLE = 15f;
 
     public FolderIcon(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -55,16 +61,21 @@
         FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false);
 
         final Resources resources = launcher.getResources();
-        Drawable d = iconCache.getFullResIcon(resources, R.drawable.ic_launcher_folder);
-        icon.mCloseIcon = d;
-        icon.mOpenIcon = iconCache.getFullResIcon(resources, R.drawable.ic_launcher_folder_open);
-        icon.setCompoundDrawablesWithIntrinsicBounds(null, d, null, null);
-        icon.setText(folderInfo.title);
+        Drawable d = iconCache.getFullResIcon(resources, R.drawable.folder_bg);
+        icon.setBackgroundDrawable(d);
         icon.setTag(folderInfo);
         icon.setOnClickListener(launcher);
         icon.mInfo = folderInfo;
         icon.mLauncher = launcher;
-        
+
+        Folder folder = Folder.fromXml(launcher);
+        folder.setDragController(launcher.getDragController());
+        folder.setLauncher(launcher);
+        folder.bind(folderInfo);
+        icon.mFolder = folder;
+
+        folderInfo.addListener(icon);
+
         return icon;
     }
 
@@ -79,7 +90,7 @@
 
     public void addItem(ShortcutInfo item) {
         mInfo.add(item);
-        LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, 0, 0);
+        LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
     }
 
     public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
@@ -98,9 +109,6 @@
 
     public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
             DragView dragView, Object dragInfo) {
-        if (acceptDrop(source, x, y, xOffset, yOffset, dragView, dragInfo)) {
-            setCompoundDrawablesWithIntrinsicBounds(null, mOpenIcon, null, null);
-        }
     }
 
     public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
@@ -109,7 +117,6 @@
 
     public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
             DragView dragView, Object dragInfo) {
-        setCompoundDrawablesWithIntrinsicBounds(null, mCloseIcon, null, null);
     }
 
     @Override
@@ -117,4 +124,49 @@
             DragView dragView, Object dragInfo) {
         return null;
     }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        if (mFolder == null) return;
+        if (mFolder.getItemCount() == 0) return;
+
+        canvas.save();
+        TextView v = (TextView) mFolder.getItemAt(0);
+        Drawable d = v.getCompoundDrawables()[1];
+
+        canvas.translate( (getMeasuredWidth() - d.getIntrinsicWidth()) / 2,
+                (getMeasuredHeight() - d.getIntrinsicHeight()) / 2);
+
+        canvas.translate(d.getIntrinsicWidth() / 2, d.getIntrinsicHeight() / 2);
+        canvas.rotate(ICON_ANGLE);
+
+        canvas.translate(-d.getIntrinsicWidth() / 2, -d.getIntrinsicHeight() / 2);
+
+        for (int i = Math.max(0, mFolder.getItemCount() - NUM_ITEMS_IN_PREVIEW);
+                i < mFolder.getItemCount(); i++) {
+            v = (TextView) mFolder.getItemAt(i);
+            d = v.getCompoundDrawables()[1];
+
+            if (d != null) {
+                d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
+                d.draw(canvas);
+            }
+
+            canvas.translate(d.getIntrinsicWidth() / 2, d.getIntrinsicHeight() / 2);
+            canvas.rotate(-ICON_ANGLE);
+            canvas.translate(-d.getIntrinsicWidth() / 2, -d.getIntrinsicHeight() / 2);
+        }
+
+        canvas.restore();
+    }
+
+    public void onAdd(ShortcutInfo item) {
+        invalidate();
+        requestLayout();
+    }
+
+    public void onRemove(ShortcutInfo item) {
+        invalidate();
+        requestLayout();
+    }
 }
diff --git a/src/com/android/launcher2/FolderInfo.java b/src/com/android/launcher2/FolderInfo.java
index a82b699..12ed27c 100644
--- a/src/com/android/launcher2/FolderInfo.java
+++ b/src/com/android/launcher2/FolderInfo.java
@@ -40,6 +40,8 @@
      */
     ArrayList<ShortcutInfo> contents = new ArrayList<ShortcutInfo>();
 
+    ArrayList<FolderListener> listeners = new ArrayList<FolderListener>();
+
     FolderInfo() {
         itemType = LauncherSettings.Favorites.ITEM_TYPE_FOLDER;
     }
@@ -51,6 +53,9 @@
      */
     public void add(ShortcutInfo item) {
         contents.add(item);
+        for (int i = 0; i < listeners.size(); i++) {
+            listeners.get(i).onAdd(item);
+        }
     }
 
     /**
@@ -60,6 +65,9 @@
      */
     public void remove(ShortcutInfo item) {
         contents.remove(item);
+        for (int i = 0; i < listeners.size(); i++) {
+            listeners.get(i).onRemove(item);
+        }
     }
 
     @Override
@@ -67,4 +75,19 @@
         super.onAddToDatabase(values);
         values.put(LauncherSettings.Favorites.TITLE, title.toString());
     }
+
+    void addListener(FolderListener listener) {
+        listeners.add(listener);
+    }
+
+    void removeListener(FolderListener listener) {
+        if (listeners.contains(listener)) {
+            listeners.remove(listener);
+        }
+    }
+
+    interface FolderListener {
+        public void onAdd(ShortcutInfo item);
+        public void onRemove(ShortcutInfo item);
+    }
 }
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 701dc66..b32237a 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -1543,6 +1543,10 @@
         ValueAnimator.clearAllAnimations();
     }
 
+    public DragController getDragController() {
+        return mDragController;
+    }
+
     @Override
     public void startActivityForResult(Intent intent, int requestCode) {
         if (requestCode >= 0) mWaitingForResult = true;
@@ -1964,7 +1968,10 @@
                 mWaitingForResume.setStayPressed(true);
             }
         } else if (tag instanceof FolderInfo) {
-            handleFolderClick((FolderInfo) tag);
+            if (v instanceof FolderIcon) {
+                FolderIcon fi = (FolderIcon) v;
+                handleFolderClick(fi);
+            }
         } else if (v == mHandleView) {
             if (mState == State.ALL_APPS) {
                 showWorkspace(true);
@@ -2086,15 +2093,16 @@
         }
     }
 
-    private void handleFolderClick(FolderInfo folderInfo) {
-        if (!folderInfo.opened) {
+    private void handleFolderClick(FolderIcon folderIcon) {
+        final FolderInfo info = folderIcon.mInfo;
+        if (!info.opened) {
             // Close any open folder
             closeFolder();
             // Open the requested folder
-            openFolder(folderInfo);
+            openFolder(folderIcon);
         } else {
             // Find the open folder...
-            Folder openFolder = mWorkspace.getFolderForTag(folderInfo);
+            Folder openFolder = mWorkspace.getFolderForTag(info);
             int folderScreen;
             if (openFolder != null) {
                 folderScreen = mWorkspace.getPageForView(openFolder);
@@ -2104,7 +2112,7 @@
                     // Close any folder open on the current screen
                     closeFolder();
                     // Pull the folder onto this screen
-                    openFolder(folderInfo);
+                    openFolder(folderIcon);
                 }
             }
         }
@@ -2117,19 +2125,15 @@
      *
      * @param folderInfo The FolderInfo describing the folder to open.
      */
-    public void openFolder(FolderInfo folderInfo) {
-        Folder openFolder = Folder.fromXml(this);
+    public void openFolder(FolderIcon folderIcon) {
+        Folder folder = folderIcon.mFolder;
+        FolderInfo info = folder.mInfo;
 
-        openFolder.setDragController(mDragController);
-        openFolder.setLauncher(this);
+        info.opened = true;
 
-        openFolder.bind(folderInfo);
-        folderInfo.opened = true;
-
-        mWorkspace.addInFullScreen(openFolder, folderInfo.screen);
-        openFolder.animateOpen();
-
-        openFolder.onOpen();
+        mWorkspace.addInFullScreen(folder, info.screen);
+        folder.animateOpen();
+        folder.onOpen();
     }
 
     public boolean onLongClick(View v) {
@@ -2469,7 +2473,9 @@
                     final FolderIcon folderIcon = (FolderIcon)
                             mWorkspace.getViewForTag(mFolderInfo);
                     if (folderIcon != null) {
-                        folderIcon.setText(name);
+                        // TODO: At some point we'll probably want some version of setting
+                        // the text for a folder icon.
+                        //folderIcon.setText(name);
                         getWorkspace().requestLayout();
                     } else {
                         lockAllApps();
@@ -3461,8 +3467,10 @@
             if (folders != null) {
                 for (long folderId : folders) {
                     final FolderInfo info = sFolders.get(folderId);
-                    if (info != null) {
-                        openFolder(info);
+                    final FolderIcon folderIcon = (FolderIcon)
+                        mWorkspace.getViewForTag(info);
+                    if (folderIcon != null) {
+                        openFolder(folderIcon);
                     }
                 }
                 final Folder openFolder = mWorkspace.getOpenFolder();
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index dc22d84..31ac11b 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -2035,7 +2035,8 @@
         v.getDrawingRect(clipRect);
 
         // For a TextView, adjust the clip rect so that we don't include the text label
-        if (v instanceof BubbleTextView) {
+        if (v instanceof FolderIcon) {
+        } else if (v instanceof BubbleTextView) {
             final BubbleTextView tv = (BubbleTextView) v;
             clipRect.bottom = tv.getExtendedPaddingTop() - (int) BubbleTextView.PADDING_V +
                     tv.getLayout().getLineTop(0);
@@ -2172,7 +2173,7 @@
         final int screenY = (int) mTempXY[1] + (child.getHeight() - bmpHeight) / 2;
 
         Rect dragRect = null;
-        if (child instanceof BubbleTextView) {
+        if ((child instanceof BubbleTextView) && !(child instanceof FolderIcon)) {
             int iconSize = getResources().getDimensionPixelSize(R.dimen.app_icon_size);
             int top = child.getPaddingTop();
             int left = (bmpWidth - iconSize) / 2;
@@ -2363,6 +2364,10 @@
 
             target.removeView(v);
             FolderIcon fi = mLauncher.addFolder(screen, mTargetCell[0], mTargetCell[1]);
+            destInfo.cellX = -1;
+            destInfo.cellY = -1;
+            sourceInfo.cellX = -1;
+            sourceInfo.cellY = -1;
             fi.addItem(destInfo);
             fi.addItem(sourceInfo);
             return true;