diff options
author | 2023-11-27 16:18:42 -0600 | |
---|---|---|
committer | 2023-11-27 16:36:44 -0600 | |
commit | 6890893a247bf650c14d70f9aafd19d921d0b7fe (patch) | |
tree | 6f611d52ed89d6f756ed7f914a35b757690f863a | |
parent | 0bb6034f7443227026088fcefba56dd7adea7ce7 (diff) |
Moving rearrangementExists to ReorderLogic since it's only used there
Also, simplify copyCurrentStateToSolution since it always gets false
as the second parameter.
Flag: NA
Bug: 229292911
Test: ReorderAlgorithmUnitTest
Change-Id: I025566897246fa59ca513cb7de9a12465054498f
-rw-r--r-- | src/com/android/launcher3/CellLayout.java | 86 | ||||
-rw-r--r-- | src/com/android/launcher3/MultipageCellLayout.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/celllayout/ReorderAlgorithm.java | 79 |
3 files changed, 83 insertions, 84 deletions
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index 7257d86ddc..17e4a5b2dd 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -89,8 +89,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; -import java.util.Comparator; -import java.util.List; import java.util.Stack; public class CellLayout extends ViewGroup { @@ -1811,7 +1809,7 @@ public class CellLayout extends ViewGroup { return bestXY; } - private boolean addViewToTempLocation(View v, Rect rectOccupiedByPotentialDrop, + public boolean addViewToTempLocation(View v, Rect rectOccupiedByPotentialDrop, int[] direction, ItemConfiguration currentState) { CellAndSpan c = currentState.map.get(v); boolean success = false; @@ -1830,7 +1828,7 @@ public class CellLayout extends ViewGroup { return success; } - private boolean pushViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop, + public boolean pushViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop, int[] direction, View dragView, ItemConfiguration currentState) { ViewCluster cluster = new ViewCluster(this, views, currentState); @@ -1928,7 +1926,7 @@ public class CellLayout extends ViewGroup { // This method tries to find a reordering solution which satisfies the push mechanic by trying // to push items in each of the cardinal directions, in an order based on the direction vector // passed. - private boolean attemptPushInDirection(ArrayList<View> intersectingViews, Rect occupied, + public boolean attemptPushInDirection(ArrayList<View> intersectingViews, Rect occupied, int[] direction, View ignoreView, ItemConfiguration solution) { if ((Math.abs(direction[0]) + Math.abs(direction[1])) > 1) { // If the direction vector has two non-zero components, we try pushing @@ -2089,7 +2087,7 @@ public class CellLayout extends ViewGroup { } } - private boolean addViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop, + public boolean addViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop, int[] direction, View dragView, ItemConfiguration currentState) { if (views.size() == 0) return true; @@ -2140,71 +2138,6 @@ public class CellLayout extends ViewGroup { return success; } - public boolean rearrangementExists(int cellX, int cellY, int spanX, int spanY, int[] direction, - View ignoreView, ItemConfiguration solution) { - // Return early if get invalid cell positions - if (cellX < 0 || cellY < 0) return false; - - mIntersectingViews.clear(); - mOccupiedRect.set(cellX, cellY, cellX + spanX, cellY + spanY); - - // Mark the desired location of the view currently being dragged. - if (ignoreView != null) { - CellAndSpan c = solution.map.get(ignoreView); - if (c != null) { - c.cellX = cellX; - c.cellY = cellY; - } - } - Rect r0 = new Rect(cellX, cellY, cellX + spanX, cellY + spanY); - Rect r1 = new Rect(); - // The views need to be sorted so that the results are deterministic on the views positions - // and not by the views hash which is "random". - // The views are sorted twice, once for the X position and a second time for the Y position - // to ensure same order everytime. - Comparator comparator = Comparator.comparing(view -> - ((CellLayoutLayoutParams) ((View) view).getLayoutParams()).getCellX()) - .thenComparing(view -> - ((CellLayoutLayoutParams) ((View) view).getLayoutParams()).getCellY()); - List<View> views = solution.map.keySet().stream().sorted(comparator).toList(); - for (View child : views) { - if (child == ignoreView) continue; - CellAndSpan c = solution.map.get(child); - CellLayoutLayoutParams lp = (CellLayoutLayoutParams) child.getLayoutParams(); - r1.set(c.cellX, c.cellY, c.cellX + c.spanX, c.cellY + c.spanY); - if (Rect.intersects(r0, r1)) { - if (!lp.canReorder) { - return false; - } - mIntersectingViews.add(child); - } - } - - solution.intersectingViews = new ArrayList<>(mIntersectingViews); - - // First we try to find a solution which respects the push mechanic. That is, - // we try to find a solution such that no displaced item travels through another item - // without also displacing that item. - if (attemptPushInDirection(mIntersectingViews, mOccupiedRect, direction, ignoreView, - solution)) { - return true; - } - - // Next we try moving the views as a block, but without requiring the push mechanic. - if (addViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction, ignoreView, - solution)) { - return true; - } - - // Ok, they couldn't move as a block, let's move them individually - for (View v : mIntersectingViews) { - if (!addViewToTempLocation(v, mOccupiedRect, direction, solution)) { - return false; - } - } - return true; - } - public ReorderAlgorithm createReorderAlgorithm() { return new ReorderAlgorithm(this); } @@ -2216,18 +2149,13 @@ public class CellLayout extends ViewGroup { spanX, spanY, direction, dragView, decX, solution); } - public void copyCurrentStateToSolution(ItemConfiguration solution, boolean temp) { + public void copyCurrentStateToSolution(ItemConfiguration solution) { int childCount = mShortcutsAndWidgets.getChildCount(); for (int i = 0; i < childCount; i++) { View child = mShortcutsAndWidgets.getChildAt(i); CellLayoutLayoutParams lp = (CellLayoutLayoutParams) child.getLayoutParams(); - CellAndSpan c; - if (temp) { - c = new CellAndSpan(lp.getTmpCellX(), lp.getTmpCellY(), lp.cellHSpan, lp.cellVSpan); - } else { - c = new CellAndSpan(lp.getCellX(), lp.getCellY(), lp.cellHSpan, lp.cellVSpan); - } - solution.add(child, c); + solution.add(child, + new CellAndSpan(lp.getCellX(), lp.getCellY(), lp.cellHSpan, lp.cellVSpan)); } } diff --git a/src/com/android/launcher3/MultipageCellLayout.java b/src/com/android/launcher3/MultipageCellLayout.java index 123e8ca1e3..5c5d71c635 100644 --- a/src/com/android/launcher3/MultipageCellLayout.java +++ b/src/com/android/launcher3/MultipageCellLayout.java @@ -120,7 +120,7 @@ public class MultipageCellLayout extends CellLayout { } @Override - public void copyCurrentStateToSolution(ItemConfiguration solution, boolean temp) { + public void copyCurrentStateToSolution(ItemConfiguration solution) { int childCount = mShortcutsAndWidgets.getChildCount(); for (int i = 0; i < childCount; i++) { View child = mShortcutsAndWidgets.getChildAt(i); diff --git a/src/com/android/launcher3/celllayout/ReorderAlgorithm.java b/src/com/android/launcher3/celllayout/ReorderAlgorithm.java index 05bd13da81..535dfe57a6 100644 --- a/src/com/android/launcher3/celllayout/ReorderAlgorithm.java +++ b/src/com/android/launcher3/celllayout/ReorderAlgorithm.java @@ -19,7 +19,11 @@ import android.graphics.Rect; import android.view.View; import com.android.launcher3.CellLayout; +import com.android.launcher3.util.CellAndSpan; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; import java.util.Map.Entry; /** @@ -63,7 +67,7 @@ public class ReorderAlgorithm { int minSpanY, int spanX, int spanY, int[] direction, View dragView, boolean decX, ItemConfiguration solution) { // Copy the current state into the solution. This solution will be manipulated as necessary. - mCellLayout.copyCurrentStateToSolution(solution, false); + mCellLayout.copyCurrentStateToSolution(solution); // Copy the current occupied array into the temporary occupied array. This array will be // manipulated as necessary to find a solution. mCellLayout.getOccupied().copyTo(mCellLayout.mTmpOccupied); @@ -76,7 +80,7 @@ public class ReorderAlgorithm { boolean success; // First we try the exact nearest position of the item being dragged, // we will then want to try to move this around to other neighbouring positions - success = mCellLayout.rearrangementExists(result[0], result[1], spanX, spanY, direction, + success = rearrangementExists(result[0], result[1], spanX, spanY, direction, dragView, solution); if (!success) { @@ -100,6 +104,73 @@ public class ReorderAlgorithm { return solution; } + private boolean rearrangementExists(int cellX, int cellY, int spanX, int spanY, int[] direction, + View ignoreView, ItemConfiguration solution) { + // Return early if get invalid cell positions + if (cellX < 0 || cellY < 0) return false; + + ArrayList<View> intersectingViews = new ArrayList<>(); + Rect occupiedRect = new Rect(cellX, cellY, cellX + spanX, cellY + spanY); + + // Mark the desired location of the view currently being dragged. + if (ignoreView != null) { + CellAndSpan c = solution.map.get(ignoreView); + if (c != null) { + c.cellX = cellX; + c.cellY = cellY; + } + } + Rect r0 = new Rect(cellX, cellY, cellX + spanX, cellY + spanY); + Rect r1 = new Rect(); + // The views need to be sorted so that the results are deterministic on the views positions + // and not by the views hash which is "random". + // The views are sorted twice, once for the X position and a second time for the Y position + // to ensure same order everytime. + Comparator comparator = Comparator.comparing(view -> + ((CellLayoutLayoutParams) ((View) view).getLayoutParams()).getCellX()) + .thenComparing(view -> + ((CellLayoutLayoutParams) ((View) view).getLayoutParams()).getCellY()); + List<View> views = solution.map.keySet().stream().sorted(comparator).toList(); + for (View child : views) { + if (child == ignoreView) continue; + CellAndSpan c = solution.map.get(child); + CellLayoutLayoutParams lp = (CellLayoutLayoutParams) child.getLayoutParams(); + r1.set(c.cellX, c.cellY, c.cellX + c.spanX, c.cellY + c.spanY); + if (Rect.intersects(r0, r1)) { + if (!lp.canReorder) { + return false; + } + intersectingViews.add(child); + } + } + + solution.intersectingViews = intersectingViews; + + // First we try to find a solution which respects the push mechanic. That is, + // we try to find a solution such that no displaced item travels through another item + // without also displacing that item. + if (mCellLayout.attemptPushInDirection(intersectingViews, occupiedRect, direction, + ignoreView, + solution)) { + return true; + } + + // Next we try moving the views as a block, but without requiring the push mechanic. + if (mCellLayout.addViewsToTempLocation(intersectingViews, occupiedRect, direction, + ignoreView, + solution)) { + return true; + } + + // Ok, they couldn't move as a block, let's move them individually + for (View v : intersectingViews) { + if (!mCellLayout.addViewToTempLocation(v, occupiedRect, direction, solution)) { + return false; + } + } + return true; + } + /** * Returns a "reorder" if there is empty space without rearranging anything. * @@ -115,7 +186,7 @@ public class ReorderAlgorithm { int[] result = mCellLayout.findNearestAreaIgnoreOccupied(pixelX, pixelY, spanX, spanY, new int[2]); ItemConfiguration solution = new ItemConfiguration(); - mCellLayout.copyCurrentStateToSolution(solution, false); + mCellLayout.copyCurrentStateToSolution(solution); solution.isSolution = !isConfigurationRegionOccupied( new Rect(result[0], result[1], result[0] + spanX, result[1] + spanY), @@ -161,7 +232,7 @@ public class ReorderAlgorithm { mCellLayout.findNearestVacantArea(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY, result, resultSpan); if (result[0] >= 0 && result[1] >= 0) { - mCellLayout.copyCurrentStateToSolution(solution, false); + mCellLayout.copyCurrentStateToSolution(solution); solution.cellX = result[0]; solution.cellY = result[1]; solution.spanX = resultSpan[0]; |