Making launcher update widgets with min/max extents

Change-Id: Iba9325eeb95a8a8256ef6f59f4010aff09767892
diff --git a/src/com/android/launcher2/AppWidgetResizeFrame.java b/src/com/android/launcher2/AppWidgetResizeFrame.java
index 9df6f32..7281a6f 100644
--- a/src/com/android/launcher2/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher2/AppWidgetResizeFrame.java
@@ -307,11 +307,38 @@
             lp.cellVSpan = spanY;
             mRunningVInc += vSpanDelta;
             mRunningHInc += hSpanDelta;
+            if (!onDismiss) {
+                updateWidgetSizeRanges(mWidgetView, mLauncher, spanX, spanY);
+            }
         }
-
         mWidgetView.requestLayout();
     }
 
+    static void updateWidgetSizeRanges(AppWidgetHostView widgetView, Launcher launcher,
+            int spanX, int spanY) {
+        Rect landMetrics = Workspace.getCellLayoutMetrics(launcher, CellLayout.LANDSCAPE);
+        Rect portMetrics = Workspace.getCellLayoutMetrics(launcher, CellLayout.PORTRAIT);
+        final float density = launcher.getResources().getDisplayMetrics().density;
+
+        // Compute landscape size
+        int cellWidth = landMetrics.left;
+        int cellHeight = landMetrics.top;
+        int widthGap = landMetrics.right;
+        int heightGap = landMetrics.bottom;
+        int landWidth = (int) ((spanX * cellWidth + (spanX - 1) * widthGap) / density);
+        int landHeight = (int) ((spanY * cellHeight + (spanY - 1) * heightGap) / density);
+
+        // Compute portrait size
+        cellWidth = portMetrics.left;
+        cellHeight = portMetrics.top;
+        widthGap = portMetrics.right;
+        heightGap = portMetrics.bottom;
+        int portWidth = (int) ((spanX * cellWidth + (spanX - 1) * widthGap) / density);
+        int portHeight = (int) ((spanY * cellHeight + (spanY - 1) * heightGap) / density);
+
+        widgetView.updateAppWidgetSize(null, portWidth, landHeight, landWidth, portHeight);
+    }
+
     /**
      * This is the final step of the resize. Here we save the new widget size and position
      * to LauncherModel and animate the resize frame.
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 24e4047..2772d5c 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -146,6 +146,9 @@
     private static final boolean DESTRUCTIVE_REORDER = false;
     private static final boolean DEBUG_VISUALIZE_OCCUPIED = false;
 
+    static final int LANDSCAPE = 0;
+    static final int PORTRAIT = 1;
+
     private static final float REORDER_HINT_MAGNITUDE = 0.27f;
     private static final int REORDER_ANIMATION_DURATION = 150;
     private float mReorderHintAnimationMagnitude;
@@ -910,11 +913,10 @@
         return r;
     }
 
-    final int LANDSCAPE = 0;
-    final int PORTRAIT = 1;
-    void getCellLayoutMetrics(int measureWidth, int measureHeight, int orientation, Rect metrics) {
-        int numWidthGaps = mCountX - 1;
-        int numHeightGaps = mCountY - 1;
+    static void getMetrics(Rect metrics, Resources res, int measureWidth, int measureHeight,
+            int countX, int countY, int orientation) {
+        int numWidthGaps = countX - 1;
+        int numHeightGaps = countY - 1;
 
         int widthGap;
         int heightGap;
@@ -925,7 +927,7 @@
         int paddingTop;
         int paddingBottom;
 
-        Resources res = getContext().getResources();
+        int maxGap = res.getDimensionPixelSize(R.dimen.workspace_max_gap);
         if (orientation == LANDSCAPE) {
             cellWidth = res.getDimensionPixelSize(R.dimen.workspace_cell_width_land);
             cellHeight = res.getDimensionPixelSize(R.dimen.workspace_cell_height_land);
@@ -950,18 +952,16 @@
         if (widthGap < 0 || heightGap < 0) {
             int hSpace = measureWidth - paddingLeft - paddingRight;
             int vSpace = measureHeight - paddingTop - paddingBottom;
-            int hFreeSpace = hSpace - (mCountX * cellWidth);
-            int vFreeSpace = vSpace - (mCountY * cellHeight);
-            widthGap = Math.min(mMaxGap, numWidthGaps > 0 ? (hFreeSpace / numWidthGaps) : 0);
-            heightGap = Math.min(mMaxGap, numHeightGaps > 0 ? (vFreeSpace / numHeightGaps) : 0);
+            int hFreeSpace = hSpace - (countX * cellWidth);
+            int vFreeSpace = vSpace - (countY * cellHeight);
+            widthGap = Math.min(maxGap, numWidthGaps > 0 ? (hFreeSpace / numWidthGaps) : 0);
+            heightGap = Math.min(maxGap, numHeightGaps > 0 ? (vFreeSpace / numHeightGaps) : 0);
         }
         metrics.set(cellWidth, cellHeight, widthGap, heightGap);
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        // TODO: currently ignoring padding
-
         int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
         int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
 
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index fb27d02..f0ad546 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -1100,6 +1100,8 @@
 
             launcherInfo.hostView.setTag(launcherInfo);
             launcherInfo.hostView.setVisibility(View.VISIBLE);
+            AppWidgetResizeFrame.updateWidgetSizeRanges(launcherInfo.hostView,
+                    this, launcherInfo.spanX, launcherInfo.spanY);
             mWorkspace.addInScreen(launcherInfo.hostView, container, screen, cellXY[0], cellXY[1],
                     launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());
 
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index e9dffc5..b6378a7 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -122,6 +122,9 @@
     private int mDragOverX = -1;
     private int mDragOverY = -1;
 
+    static Rect mLandscapeCellLayoutMetrics = null;
+    static Rect mPortraitCellLayoutMetrics = null;
+
     /**
      * The CellLayout that is currently being dragged over
      */
@@ -2389,6 +2392,44 @@
         }
     }
 
+    static Rect getCellLayoutMetrics(Launcher launcher, int orientation) {
+        Resources res = launcher.getResources();
+        Display display = launcher.getWindowManager().getDefaultDisplay();
+        Point smallestSize = new Point();
+        Point largestSize = new Point();
+        display.getCurrentSizeRange(smallestSize, largestSize);
+        if (orientation == CellLayout.LANDSCAPE) {
+            if (mLandscapeCellLayoutMetrics == null) {
+                int paddingLeft = res.getDimensionPixelSize(R.dimen.workspace_left_padding_land);
+                int paddingRight = res.getDimensionPixelSize(R.dimen.workspace_right_padding_land);
+                int paddingTop = res.getDimensionPixelSize(R.dimen.workspace_top_padding_land);
+                int paddingBottom = res.getDimensionPixelSize(R.dimen.workspace_bottom_padding_land);
+                int width = largestSize.x - paddingLeft - paddingRight;
+                int height = smallestSize.y - paddingTop - paddingBottom;
+                mLandscapeCellLayoutMetrics = new Rect();
+                CellLayout.getMetrics(mLandscapeCellLayoutMetrics, res,
+                        width, height, LauncherModel.getCellCountX(), LauncherModel.getCellCountY(),
+                        orientation);
+            }
+            return mLandscapeCellLayoutMetrics;
+        } else if (orientation == CellLayout.PORTRAIT) {
+            if (mPortraitCellLayoutMetrics == null) {
+                int paddingLeft = res.getDimensionPixelSize(R.dimen.workspace_left_padding_land);
+                int paddingRight = res.getDimensionPixelSize(R.dimen.workspace_right_padding_land);
+                int paddingTop = res.getDimensionPixelSize(R.dimen.workspace_top_padding_land);
+                int paddingBottom = res.getDimensionPixelSize(R.dimen.workspace_bottom_padding_land);
+                int width = smallestSize.x - paddingLeft - paddingRight;
+                int height = largestSize.y - paddingTop - paddingBottom;
+                mPortraitCellLayoutMetrics = new Rect();
+                CellLayout.getMetrics(mPortraitCellLayoutMetrics, res,
+                        width, height, LauncherModel.getCellCountX(), LauncherModel.getCellCountY(),
+                        orientation);
+            }
+            return mPortraitCellLayoutMetrics;
+        }
+        return null;
+    }
+
     public void onDragExit(DragObject d) {
         mDragEnforcer.onDragExit();