From 4abc5bdfdfc7021d8519c0b7e1bffe0728ff1d9d Mon Sep 17 00:00:00 2001 From: Adam Cohen Date: Tue, 29 May 2012 21:06:03 -0700 Subject: Improve reordering by always using the "push mechanic" if possible (issue 6275309) Change-Id: I51450c1b1f6b439c87194a6084d82fb9989154a7 --- src/com/android/launcher2/CellLayout.java | 114 ++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 13 deletions(-) diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java index a96b5b168..c028ff1dc 100644 --- a/src/com/android/launcher2/CellLayout.java +++ b/src/com/android/launcher2/CellLayout.java @@ -1704,6 +1704,102 @@ public class CellLayout extends ViewGroup { markCellsForView(r.left, r.top, r.width(), r.height(), occupied, value); } + // 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 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 + // separately in each of the components. + int temp = direction[1]; + direction[1] = 0; + if (addViewsToTempLocation(intersectingViews, occupied, direction, true, + ignoreView, solution)) { + return true; + } + direction[1] = temp; + temp = direction[0]; + direction[0] = 0; + if (addViewsToTempLocation(intersectingViews, occupied, direction, true, + ignoreView, solution)) { + return true; + } + // Revert the direction + direction[0] = temp; + + // Now we try pushing in each component of the opposite direction + direction[0] *= -1; + direction[1] *= -1; + temp = direction[1]; + direction[1] = 0; + if (addViewsToTempLocation(intersectingViews, occupied, direction, true, + ignoreView, solution)) { + return true; + } + + direction[1] = temp; + temp = direction[0]; + direction[0] = 0; + if (addViewsToTempLocation(intersectingViews, occupied, direction, true, + ignoreView, solution)) { + return true; + } + // revert the direction + direction[0] = temp; + direction[0] *= -1; + direction[1] *= -1; + + } else { + // If the direction vector has a single non-zero component, we push first in the + // direction of the vector + if (addViewsToTempLocation(intersectingViews, occupied, direction, true, + ignoreView, solution)) { + return true; + } + + // Then we try the opposite direction + direction[0] *= -1; + direction[1] *= -1; + if (addViewsToTempLocation(intersectingViews, occupied, direction, true, + ignoreView, solution)) { + return true; + } + // Switch the direction back + direction[0] *= -1; + direction[1] *= -1; + + // If we have failed to find a push solution with the above, then we try + // to find a solution by pushing along the perpendicular axis. + + // Swap the components + int temp = direction[1]; + direction[1] = direction[0]; + direction[0] = temp; + if (addViewsToTempLocation(intersectingViews, occupied, direction, true, + ignoreView, solution)) { + return true; + } + + // Then we try the opposite direction + direction[0] *= -1; + direction[1] *= -1; + if (addViewsToTempLocation(intersectingViews, occupied, direction, true, + ignoreView, solution)) { + return true; + } + // Switch the direction back + direction[0] *= -1; + direction[1] *= -1; + + // Swap the components back + temp = direction[1]; + direction[1] = direction[0]; + direction[0] = temp; + } + return false; + } + private boolean rearrangementExists(int cellX, int cellY, int spanX, int spanY, int[] direction, View ignoreView, ItemConfiguration solution) { // Return early if get invalid cell positions @@ -1735,23 +1831,15 @@ public class CellLayout extends ViewGroup { } } - // We try to move the intersecting views as a block using the push mechanic - if (addViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction, true, ignoreView, - solution)) { - return true; - } - // Try the opposite direction - direction[0] *= -1; - direction[1] *= -1; - if (addViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction, true, ignoreView, + // 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; } - // Switch the direction back - direction[0] *= -1; - direction[1] *= -1; - // Next we try moving the views as a block , but without requiring the push mechanic + // Next we try moving the views as a block, but without requiring the push mechanic. if (addViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction, false, ignoreView, solution)) { return true; -- cgit v1.2.3