When placing a widget, go to a page with enough space.
The search for this page starts at the current one and
continues to the right (on LTR) until a page is found that
can accomodate the widget, taking possible resizing and
reordering into account.
Bug: 11338870
Change-Id: I2e9a310eb8f74024dca9150f55a525e1309c2f07
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 653ee7e..700bf9e 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -2966,6 +2966,26 @@
return Utilities.findVacantCell(outXY, spanX, spanY, mCountX, mCountY, mOccupied);
}
+ /**
+ * Returns whether an item can be placed in this CellLayout (after rearranging and/or resizing
+ * if necessary).
+ */
+ public boolean hasReorderSolution(ItemInfo itemInfo) {
+ int[] cellPoint = new int[2];
+ // Check for a solution starting at every cell.
+ for (int cellX = 0; cellX < getCountX(); cellX++) {
+ for (int cellY = 0; cellY < getCountY(); cellY++) {
+ cellToPoint(cellX, cellY, cellPoint);
+ if (findReorderSolution(cellPoint[0], cellPoint[1], itemInfo.minSpanX,
+ itemInfo.minSpanY, itemInfo.spanX, itemInfo.spanY, mDirectionVector, null,
+ true, new ItemConfiguration()).isSolution) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
public boolean isRegionVacant(int x, int y, int spanX, int spanY) {
int x2 = x + spanX - 1;
int y2 = y + spanY - 1;
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 5f54e1d..e4d6448 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -441,7 +441,7 @@
Math.min(newPage, mTempVisiblePagesRange[1]));
}
// Ensure that it is clamped by the actual set of children in all cases
- validatedPage = Math.max(0, Math.min(validatedPage, getPageCount() - 1));
+ validatedPage = Utilities.boundInRange(validatedPage, 0, getPageCount() - 1);
return validatedPage;
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 5c8c402..58209c3 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1927,6 +1927,17 @@
}
public void onDragStartedWithItem(PendingAddItemInfo info, Bitmap b, boolean clipAlpha) {
+ // Find a page that has enough space to place this widget (after rearranging/resizing).
+ // Start at the current page and search right (on LTR) until finding a page with enough
+ // space. Since an empty screen is the furthest right, a page must be found.
+ for (int pageIndex = getCurrentPage(); pageIndex <= getPageCount(); pageIndex++) {
+ CellLayout page = (CellLayout) getPageAt(pageIndex);
+ if (page.hasReorderSolution(info)) {
+ setCurrentPage(pageIndex);
+ break;
+ }
+ }
+
int[] size = estimateItemSize(info, false);
// The outline is used to visualize where the item will land if dropped
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
index e6059d5..81a8465 100644
--- a/src/com/android/launcher3/widget/WidgetsContainerView.java
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -253,9 +253,11 @@
// Start the drag
mLauncher.lockScreenOrientation();
- mLauncher.getWorkspace().onDragStartedWithItem(createItemInfo, preview, clipAlpha);
mDragController.startDrag(image, preview, this, createItemInfo,
bounds, DragController.DRAG_ACTION_COPY, scale);
+ // This call expects the extra empty screen to already be created, which is why we call it
+ // after mDragController.startDrag().
+ mLauncher.getWorkspace().onDragStartedWithItem(createItemInfo, preview, clipAlpha);
preview.recycle();
return true;