Defining various modes for CellLayout: Workspace, Hotseat & Folder

> Moving the definition of modes to xml
> Defining attributes in xml

Change-Id: I7a569fdbeb833d569eeeef2f2cbc8214e608ad11
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 3564cec..af22cfa 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -24,6 +24,7 @@
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -35,6 +36,7 @@
 import android.graphics.drawable.TransitionDrawable;
 import android.os.Build;
 import android.os.Parcelable;
+import android.support.annotation.IntDef;
 import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -60,6 +62,8 @@
 import com.android.launcher3.util.ParcelableSparseArray;
 import com.android.launcher3.util.Thunk;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -145,8 +149,16 @@
     private TimeInterpolator mEaseOutInterpolator;
     private ShortcutAndWidgetContainer mShortcutsAndWidgets;
 
-    private boolean mIsHotseat = false;
-    private float mHotseatScale = 1f;
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({WORKSPACE, HOTSEAT, FOLDER})
+    public @interface ContainerType{}
+    public static final int WORKSPACE = 0;
+    public static final int HOTSEAT = 1;
+    public static final int FOLDER = 2;
+
+    @ContainerType private final int mContainerType;
+
+    private final float mChildScale;
 
     public static final int MODE_SHOW_REORDER_HINT = 0;
     public static final int MODE_DRAG_OVER = 1;
@@ -158,7 +170,7 @@
 
     private static final float REORDER_PREVIEW_MAGNITUDE = 0.12f;
     private static final int REORDER_ANIMATION_DURATION = 150;
-    @Thunk float mReorderPreviewAnimationMagnitude;
+    @Thunk final float mReorderPreviewAnimationMagnitude;
 
     private ArrayList<View> mIntersectingViews = new ArrayList<View>();
     private Rect mOccupiedRect = new Rect();
@@ -184,6 +196,9 @@
 
     public CellLayout(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0);
+        mContainerType = a.getInteger(R.styleable.CellLayout_containerType, WORKSPACE);
+        a.recycle();
 
         // A ViewGroup usually does not draw, but CellLayout needs to draw a rectangle to show
         // the user where a dragged item will land when dropped.
@@ -207,9 +222,10 @@
         mFolderLeaveBehind.delegateCellX = -1;
         mFolderLeaveBehind.delegateCellY = -1;
 
+        mChildScale = mContainerType == HOTSEAT ? grid.inv.hotseatScale : 1f;
+
         setAlwaysDrawnWithCacheEnabled(false);
         final Resources res = getResources();
-        mHotseatScale = (float) grid.hotseatIconSizePx / grid.iconSizePx;
 
         mBackground = (TransitionDrawable) res.getDrawable(
                 FeatureFlags.LAUNCHER3_LEGACY_WORKSPACE_DND ? R.drawable.bg_screenpanel
@@ -217,8 +233,7 @@
         mBackground.setCallback(this);
         mBackground.setAlpha((int) (mBackgroundAlpha * 255));
 
-        mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE *
-                grid.iconSizePx);
+        mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE * grid.iconSizePx);
 
         // Initialize the data structures used for the drag visualization.
         mEaseOutInterpolator = new DecelerateInterpolator(2.5f); // Quint ease out
@@ -276,7 +291,7 @@
             mDragOutlineAnims[i] = anim;
         }
 
-        mShortcutsAndWidgets = new ShortcutAndWidgetContainer(context);
+        mShortcutsAndWidgets = new ShortcutAndWidgetContainer(context, mContainerType);
         mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY);
 
         mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
@@ -355,10 +370,6 @@
         mShortcutsAndWidgets.buildLayer();
     }
 
-    public float getChildrenScale() {
-        return mIsHotseat ? mHotseatScale : 1.0f;
-    }
-
     public void setCellDimensions(int width, int height) {
         mFixedCellWidth = mCellWidth = width;
         mFixedCellHeight = mCellHeight = height;
@@ -603,15 +614,8 @@
         return mCountY;
     }
 
-    public void setIsHotseat(boolean isHotseat) {
-        mIsHotseat = isHotseat;
-        mShortcutsAndWidgets.setContainerType(isHotseat
-                ? ShortcutAndWidgetContainer.HOTSEAT
-                : ShortcutAndWidgetContainer.DEFAULT);
-    }
-
-    public boolean isHotseat() {
-        return mIsHotseat;
+    public boolean acceptsWidget() {
+        return mContainerType == WORKSPACE;
     }
 
     public boolean addViewToCellLayout(View child, int index, int childId, LayoutParams params,
@@ -621,11 +625,11 @@
         // Hotseat icons - remove text
         if (child instanceof BubbleTextView) {
             BubbleTextView bubbleChild = (BubbleTextView) child;
-            bubbleChild.setTextVisibility(!mIsHotseat);
+            bubbleChild.setTextVisibility(mContainerType != HOTSEAT);
         }
 
-        child.setScaleX(getChildrenScale());
-        child.setScaleY(getChildrenScale());
+        child.setScaleX(mChildScale);
+        child.setScaleY(mChildScale);
 
         // Generate an id for each view, this assumes we have at most 256x256 cells
         // per workspace screen
@@ -1061,24 +1065,26 @@
                 r.set(left, top, left + dragOutline.getWidth(), top + dragOutline.getHeight());
             }
 
-            Utilities.scaleRectAboutCenter(r, getChildrenScale());
+            Utilities.scaleRectAboutCenter(r, mChildScale);
             mDragOutlineAnims[mDragOutlineCurrent].setTag(dragOutline);
             mDragOutlineAnims[mDragOutlineCurrent].animateIn();
 
             if (dragObject.stateAnnouncer != null) {
-                String msg;
-                if (isHotseat()) {
-                    msg = getContext().getString(R.string.move_to_hotseat_position,
-                            Math.max(cellX, cellY) + 1);
-                } else {
-                    msg = getContext().getString(R.string.move_to_empty_cell,
-                            cellY + 1, cellX + 1);
-                }
-                dragObject.stateAnnouncer.announce(msg);
+                dragObject.stateAnnouncer.announce(getItemMoveDescription(cellX, cellY));
             }
         }
     }
 
+    public String getItemMoveDescription(int cellX, int cellY) {
+        if (mContainerType == HOTSEAT) {
+            return getContext().getString(R.string.move_to_hotseat_position,
+                    Math.max(cellX, cellY) + 1);
+        } else {
+            return getContext().getString(R.string.move_to_empty_cell,
+                    cellY + 1, cellX + 1);
+        }
+    }
+
     public void clearDragOutlines() {
         final int oldIndex = mDragOutlineCurrent;
         mDragOutlineAnims[oldIndex].animateOut();
@@ -2011,7 +2017,7 @@
             this.mode = mode;
             initDeltaX = child.getTranslationX();
             initDeltaY = child.getTranslationY();
-            finalScale = getChildrenScale() - 4.0f / child.getWidth();
+            finalScale = mChildScale - 4.0f / child.getWidth();
             initScale = child.getScaleX();
             this.child = child;
         }
@@ -2061,7 +2067,7 @@
                     // We make sure to end only after a full period
                     initDeltaX = 0;
                     initDeltaY = 0;
-                    initScale = getChildrenScale();
+                    initScale = mChildScale;
                     repeating = true;
                 }
             });
@@ -2081,8 +2087,8 @@
             }
 
             a = new LauncherViewPropertyAnimator(child)
-                .scaleX(getChildrenScale())
-                .scaleY(getChildrenScale())
+                .scaleX(mChildScale)
+                .scaleY(mChildScale)
                 .translationX(0)
                 .translationY(0)
                 .setDuration(REORDER_ANIMATION_DURATION);
@@ -2104,7 +2110,7 @@
         long screenId = mLauncher.getWorkspace().getIdForScreen(this);
         int container = Favorites.CONTAINER_DESKTOP;
 
-        if (mLauncher.isHotseatLayout(this)) {
+        if (mContainerType == HOTSEAT) {
             screenId = -1;
             container = Favorites.CONTAINER_HOTSEAT;
         }
@@ -2127,7 +2133,7 @@
                 info.spanY = lp.cellVSpan;
 
                 if (requiresDbUpdate) {
-                    LauncherModel.modifyItemInDatabase(mLauncher, info, container, screenId,
+                    LauncherModel.modifyItemInDatabase(getContext(), info, container, screenId,
                             info.cellX, info.cellY, info.spanX, info.spanY);
                 }
             }
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 59ec56a..b38109c 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -29,6 +29,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.widget.FrameLayout;
 
+import com.android.launcher3.CellLayout.ContainerType;
 import com.android.launcher3.config.FeatureFlags;
 
 import java.util.ArrayList;
@@ -610,6 +611,19 @@
                 : Math.max(widthPx, heightPx);
     }
 
+    public int getCellHeight(@ContainerType int containerType) {
+        switch (containerType) {
+            case CellLayout.WORKSPACE:
+                return cellHeightPx;
+            case CellLayout.FOLDER:
+                return folderCellHeightPx;
+            case CellLayout.HOTSEAT:
+                return hotseatCellHeightPx;
+            default:
+                // ??
+                return 0;
+        }
+    }
 
     /**
      * @return the left/right paddings for all containers.
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index b93c6df..7cddabb 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -113,12 +113,11 @@
         super.onFinishInflate();
         DeviceProfile grid = mLauncher.getDeviceProfile();
         mContent = (CellLayout) findViewById(R.id.layout);
-        if (grid.isLandscape && !grid.isLargeTablet) {
-            mContent.setGridSize(1, (int) grid.inv.numHotseatIcons);
+        if (grid.isVerticalBarLayout()) {
+            mContent.setGridSize(1, grid.inv.numHotseatIcons);
         } else {
-            mContent.setGridSize((int) grid.inv.numHotseatIcons, 1);
+            mContent.setGridSize(grid.inv.numHotseatIcons, 1);
         }
-        mContent.setIsHotseat(true);
 
         resetLayout();
     }
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 38545e2..1b0e5b3 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -85,6 +85,7 @@
      */
     public int numHotseatIcons;
     float hotseatIconSize;
+    public float hotseatScale;
     int defaultLayoutId;
 
     DeviceProfile landscapeProfile;
@@ -117,6 +118,8 @@
         numHotseatIcons = hs;
         hotseatIconSize = his;
         defaultLayoutId = dlId;
+
+        hotseatScale = hotseatIconSize / iconSize;
     }
 
     @TargetApi(23)
@@ -158,6 +161,8 @@
         // Supported overrides: numRows, numColumns, iconSize
         applyPartnerDeviceProfileOverrides(context, dm);
 
+        hotseatScale = hotseatIconSize / iconSize;
+
         Point realSize = new Point();
         display.getRealSize(realSize);
         // The real size never changes. smallSide and largeSide will remain the
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index f7d1f4a..2f51054 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2784,6 +2784,7 @@
     }
 
     boolean isHotseatLayout(View layout) {
+        // TODO: Remove this method
         return mHotseat != null && layout != null &&
                 (layout instanceof CellLayout) && (layout == mHotseat.getLayout());
     }
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 5f89af6..9568d57 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -19,29 +19,19 @@
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.graphics.Rect;
-import android.support.annotation.IntDef;
 import android.view.View;
 import android.view.ViewGroup;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import com.android.launcher3.CellLayout.ContainerType;
 
 public class ShortcutAndWidgetContainer extends ViewGroup {
     static final String TAG = "ShortcutAndWidgetContainer";
 
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({DEFAULT, HOTSEAT, FOLDER})
-    public @interface ContainerType{}
-    public static final int DEFAULT = 0;
-    public static final int HOTSEAT = 1;
-    public static final int FOLDER = 2;
-
-    private int mContainerType = DEFAULT;
-
     // These are temporary variables to prevent having to allocate a new object just to
     // return an (x, y) value from helper functions. Do NOT use them to maintain other state.
     private final int[] mTmpCellXY = new int[2];
 
+    @ContainerType private final int mContainerType;
     private final WallpaperManager mWallpaperManager;
 
     private int mCellWidth;
@@ -50,13 +40,13 @@
     private int mCountX;
 
     private Launcher mLauncher;
-
     private boolean mInvertIfRtl = false;
 
-    public ShortcutAndWidgetContainer(Context context) {
+    public ShortcutAndWidgetContainer(Context context, @ContainerType int containerType) {
         super(context);
         mLauncher = Launcher.getLauncher(context);
         mWallpaperManager = WallpaperManager.getInstance(context);
+        mContainerType = containerType;
     }
 
     public void setCellDimensions(int cellWidth, int cellHeight, int countX, int countY) {
@@ -104,19 +94,9 @@
         mInvertIfRtl = invert;
     }
 
-    public void setContainerType(@ContainerType int containerType) {
-        mContainerType = containerType;
-    }
-
     int getCellContentHeight() {
-        final DeviceProfile grid = mLauncher.getDeviceProfile();
-        int cellContentHeight = grid.cellHeightPx;
-        if (mContainerType == HOTSEAT) {
-            cellContentHeight = grid.hotseatCellHeightPx;
-        } else if (mContainerType == FOLDER) {
-            cellContentHeight = grid.folderCellHeightPx;
-        }
-        return Math.min(getMeasuredHeight(), cellContentHeight);
+        return Math.min(getMeasuredHeight(),
+                mLauncher.getDeviceProfile().getCellHeight(mContainerType));
     }
 
     public void measureChild(View child) {
diff --git a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
index c71307d..9a23aa8 100644
--- a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
@@ -57,7 +57,7 @@
         int y = id / mCountX;
         LauncherAccessibilityDelegate.DragInfo dragInfo = mDelegate.getDragInfo();
 
-        if (dragInfo.dragType == DragType.WIDGET && mView.isHotseat()) {
+        if (dragInfo.dragType == DragType.WIDGET && !mView.acceptsWidget()) {
             return INVALID_POSITION;
         }
 
@@ -161,11 +161,7 @@
 
         View child = mView.getChildAt(x, y);
         if (child == null || child == dragInfo.item) {
-            if (mView.isHotseat()) {
-                return mContext.getString(R.string.move_to_hotseat_position, id + 1);
-            } else {
-                return mContext.getString(R.string.move_to_empty_cell, y + 1, x + 1);
-            }
+            return mView.getItemMoveDescription(x, y);
         } else {
             return getDescriptionForDropOver(child, mContext);
         }
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index e71c5e9..8aaeb9e 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -253,11 +253,9 @@
 
     private CellLayout createAndAddNewPage() {
         DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
-        CellLayout page = new CellLayout(getContext());
+        CellLayout page = (CellLayout) mInflater.inflate(R.layout.folder_page, this, false);
         page.setCellDimensions(grid.folderCellWidthPx, grid.folderCellHeightPx);
         page.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false);
-        page.getShortcutsAndWidgets().setContainerType(ShortcutAndWidgetContainer.FOLDER);
-        page.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
         page.setInvertIfRtl(true);
         page.setGridSize(mGridCountX, mGridCountY);
 
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 293585d..07f59a5 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -29,11 +29,9 @@
 import android.widget.TextView;
 
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.SimpleOnStylusPressListener;
 import com.android.launcher3.R;
+import com.android.launcher3.SimpleOnStylusPressListener;
 import com.android.launcher3.StylusEventHelper;
 import com.android.launcher3.WidgetPreviewLoader;
 import com.android.launcher3.WidgetPreviewLoader.PreviewLoadRequest;
@@ -182,14 +180,6 @@
         ensurePreview();
     }
 
-    public int getActualItemWidth() {
-        ItemInfo info = (ItemInfo) getTag();
-        int[] size = getPreviewSize();
-        int cellWidth = mLauncher.getDeviceProfile().cellWidthPx;
-
-        return Math.min(size[0], info.spanX * cellWidth);
-    }
-
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         boolean handled = super.onTouchEvent(ev);