Determine # of rows/columns based on screen size

Change-Id: I8b1266bd7a66d4a73d4a09570357688333e03d13
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 8efb6ce..fdef18d 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -267,6 +267,60 @@
         addView(mChildren);
     }
 
+    static int widthInPortrait(Resources r, int numCells) {
+        // We use this method from Workspace to figure out how many rows/columns Launcher should
+        // have. We ignore the left/right padding on CellLayout because it turns out in our design
+        // the padding extends outside the visible screen size, but it looked fine anyway.
+        // However, we make sure there's at least enough space for the crosshairs at either
+        // edge to be rendered (half the crosshair is sticking out on either side)
+        int cellWidth = r.getDimensionPixelSize(R.dimen.workspace_cell_width);
+        int widthGap = r.getDimensionPixelSize(R.dimen.workspace_width_gap_port);
+        int crosshairsSize = r.getDrawable(R.drawable.gardening_crosshairs).getIntrinsicWidth();
+
+        return  widthGap * (numCells - 1) + cellWidth * numCells + crosshairsSize;
+    }
+
+    static int widthInLandscape(Resources r, int numCells) {
+        // We use this method from Workspace to figure out how many rows/columns Launcher should
+        // have. We ignore the left/right padding on CellLayout because it turns out in our design
+        // the padding extends outside the visible screen size, but it looked fine anyway.
+        // However, we make sure there's at least enough space for the crosshairs at either
+        // edge to be rendered (half the crosshair is sticking out on either side)
+        int cellWidth = r.getDimensionPixelSize(R.dimen.workspace_cell_width);
+        int widthGap = r.getDimensionPixelSize(R.dimen.workspace_width_gap_land);
+        int crosshairsSize = r.getDrawable(R.drawable.gardening_crosshairs).getIntrinsicWidth();
+
+        return widthGap * (numCells - 1) + cellWidth * numCells + crosshairsSize;
+    }
+
+    static int heightInPortrait(Resources r, int numCells) {
+        // We use this method from Workspace to figure out how many rows/columns Launcher should
+        // have. We ignore the left/right padding on CellLayout because it turns out in our design
+        // the padding extends outside the visible screen size, but it looked fine anyway.
+        // However, we make sure there's at least enough space for the crosshairs at the bottom
+        // to be rendered (half the crosshair is sticking out); we don't worry about the top
+        // crosshair since it can bleed into the action bar space
+        int cellHeight = r.getDimensionPixelSize(R.dimen.workspace_cell_height);
+        int heightGap = r.getDimensionPixelSize(R.dimen.workspace_height_gap_port);
+        int crosshairsSize = r.getDrawable(R.drawable.gardening_crosshairs).getIntrinsicHeight();
+
+        return heightGap * (numCells - 1) + cellHeight * numCells + (crosshairsSize + 1) / 2;
+    }
+
+    static int heightInLandscape(Resources r, int numCells) {
+        // We use this method from Workspace to figure out how many rows/columns Launcher should
+        // have. We ignore the left/right padding on CellLayout because it turns out in our design
+        // the padding extends outside the visible screen size, but it looked fine anyway.
+        // However, we make sure there's at least enough space for the crosshairs at the bottom
+        // to be rendered (half the crosshair is sticking out); we don't worry about the top
+        // crosshair since it can bleed into the action bar space
+        int cellHeight = r.getDimensionPixelSize(R.dimen.workspace_cell_height);
+        int heightGap = r.getDimensionPixelSize(R.dimen.workspace_height_gap_land);
+        int crosshairsSize = r.getDrawable(R.drawable.gardening_crosshairs).getIntrinsicHeight();
+
+        return heightGap * (numCells - 1) + cellHeight * numCells + (crosshairsSize + 1) / 2;
+    }
+
     private void invalidateBubbleTextView(BubbleTextView icon) {
         final int padding = icon.getPressedOrFocusedBackgroundPadding();
         invalidate(icon.getLeft() + getLeftPadding() - padding,
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 1373996..70de0a4 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -52,6 +52,7 @@
 import android.os.IBinder;
 import android.os.Parcelable;
 import android.util.AttributeSet;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Pair;
 import android.view.Display;
@@ -255,10 +256,54 @@
 
         mWallpaperManager = WallpaperManager.getInstance(context);
 
+        int cellCountX = DEFAULT_CELL_COUNT_X;
+        int cellCountY = DEFAULT_CELL_COUNT_Y;
+
         TypedArray a = context.obtainStyledAttributes(attrs,
                 R.styleable.Workspace, defStyle, 0);
-        int cellCountX = a.getInt(R.styleable.Workspace_cellCountX, DEFAULT_CELL_COUNT_X);
-        int cellCountY = a.getInt(R.styleable.Workspace_cellCountY, DEFAULT_CELL_COUNT_Y);
+
+        if (LauncherApplication.isScreenLarge()) {
+            final Resources res = context.getResources();
+            final DisplayMetrics dm = res.getDisplayMetrics();
+            float widthDp = dm.widthPixels / dm.density;
+            float heightDp = dm.heightPixels / dm.density;
+
+            final float statusBarHeight = res.getDimension(R.dimen.status_bar_height);
+            TypedArray actionBarSizeTypedArray =
+                context.obtainStyledAttributes(new int[] { android.R.attr.actionBarSize });
+            float actionBarHeight = actionBarSizeTypedArray.getDimension(0, 0f);
+
+            if (heightDp > widthDp) {
+                float temp = widthDp;
+                widthDp = heightDp;
+                heightDp = temp;
+            }
+            int cellCountXLand = 1;
+            int cellCountXPort = 1;
+            while (2*mPageSpacing + CellLayout.widthInLandscape(res, cellCountXLand + 1) <= widthDp) {
+                cellCountXLand++;
+            }
+            while (CellLayout.widthInPortrait(res, cellCountXPort + 1) <= heightDp) {
+                cellCountXPort++;
+            }
+            cellCountX = Math.min(cellCountXLand, cellCountXPort);
+
+            int cellCountYLand = 1;
+            int cellCountYPort = 1;
+            while (statusBarHeight + actionBarHeight +
+                    CellLayout.heightInLandscape(res, cellCountYLand + 1) <= heightDp) {
+                cellCountYLand++;
+            }
+            while (statusBarHeight + actionBarHeight +
+                    CellLayout.heightInPortrait(res, cellCountYPort + 1) <= widthDp) {
+                cellCountYPort++;
+            }
+            cellCountY = Math.min(cellCountYLand, cellCountYPort);
+        }
+
+        // if the value is manually specified, use that instead
+        cellCountX = a.getInt(R.styleable.Workspace_cellCountX, cellCountX);
+        cellCountY = a.getInt(R.styleable.Workspace_cellCountY, cellCountY);
         mDefaultPage = a.getInt(R.styleable.Workspace_defaultScreen, 1);
         a.recycle();