merge in jb-release history after reset to master
diff --git a/res/values/config.xml b/res/values/config.xml
index 31ef18a..2a75af8 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -39,7 +39,7 @@
<bool name="config_workspaceFadeAdjacentScreens">false</bool>
<!-- The transition duration for the background of the drop targets -->
- <integer name="config_dropTargetBgTransitionDuration">100</integer>
+ <integer name="config_dropTargetBgTransitionDuration">0</integer>
<integer name="config_crosshairsFadeInTime">600</integer>
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 3fcff72..a7ff309 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -760,6 +760,10 @@
mDraggingWidget = false;
}
+ public boolean supportsFlingToDelete() {
+ return false;
+ }
+
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
diff --git a/src/com/android/launcher2/BubbleTextView.java b/src/com/android/launcher2/BubbleTextView.java
index 4a3a7a4..a775ed5 100644
--- a/src/com/android/launcher2/BubbleTextView.java
+++ b/src/com/android/launcher2/BubbleTextView.java
@@ -247,8 +247,8 @@
}
void setCellLayoutPressedOrFocusedIcon() {
- if (getParent() instanceof CellLayoutChildren) {
- CellLayoutChildren parent = (CellLayoutChildren) getParent();
+ if (getParent() instanceof ShortcutAndWidgetContainer) {
+ ShortcutAndWidgetContainer parent = (ShortcutAndWidgetContainer) getParent();
if (parent != null) {
CellLayout layout = (CellLayout) parent.getParent();
layout.setPressedOrFocusedIcon((mPressedOrFocusedBackground != null) ? this : null);
diff --git a/src/com/android/launcher2/ButtonDropTarget.java b/src/com/android/launcher2/ButtonDropTarget.java
index dc34d88..e9f8ce8 100644
--- a/src/com/android/launcher2/ButtonDropTarget.java
+++ b/src/com/android/launcher2/ButtonDropTarget.java
@@ -18,7 +18,7 @@
import android.content.Context;
import android.content.res.Resources;
-import android.graphics.Paint;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.TextView;
@@ -71,6 +71,10 @@
public void onDrop(DragObject d) {
}
+ public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
+ // Do nothing
+ }
+
public void onDragEnter(DragObject d) {
d.dragView.setColor(mHoverColor);
}
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index d30940e..5969f98 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -137,7 +137,7 @@
private boolean mItemLocationsDirty = false;
private TimeInterpolator mEaseOutInterpolator;
- private CellLayoutChildren mChildren;
+ private ShortcutAndWidgetContainer mShortcutsAndWidgets;
private boolean mIsHotseat = false;
private float mChildScale = 1f;
@@ -281,9 +281,9 @@
mBackgroundRect = new Rect();
mForegroundRect = new Rect();
- mChildren = new CellLayoutChildren(context);
- mChildren.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap);
- addView(mChildren);
+ mShortcutsAndWidgets = new ShortcutAndWidgetContainer(context);
+ mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap);
+ addView(mShortcutsAndWidgets);
}
static int widthInPortrait(Resources r, int numCells) {
@@ -309,7 +309,7 @@
}
public void enableHardwareLayers() {
- mChildren.enableHardwareLayers();
+ mShortcutsAndWidgets.enableHardwareLayers();
}
public void setGridSize(int x, int y) {
@@ -353,13 +353,6 @@
}
}
- public CellLayoutChildren getChildrenLayout() {
- if (getChildCount() > 0) {
- return (CellLayoutChildren) getChildAt(0);
- }
- return null;
- }
-
void setIsDragOverlapping(boolean isDragOverlapping) {
if (mIsDragOverlapping != isDragOverlapping) {
mIsDragOverlapping = isDragOverlapping;
@@ -616,7 +609,7 @@
// (this happens if we're being dropped from all-apps
if (bubbleChild.getLayoutParams() instanceof LayoutParams &&
(bubbleChild.getMeasuredWidth() | bubbleChild.getMeasuredHeight()) == 0) {
- getChildrenLayout().measureChild(bubbleChild);
+ getShortcutsAndWidgets().measureChild(bubbleChild);
}
int measuredWidth = bubbleChild.getMeasuredWidth();
int measuredHeight = bubbleChild.getMeasuredHeight();
@@ -667,7 +660,7 @@
child.setId(childId);
- mChildren.addView(child, index, lp);
+ mShortcutsAndWidgets.addView(child, index, lp);
if (markCells) markCellsAsOccupiedForView(child);
@@ -679,61 +672,53 @@
@Override
public void removeAllViews() {
clearOccupiedCells();
- mChildren.removeAllViews();
+ mShortcutsAndWidgets.removeAllViews();
}
@Override
public void removeAllViewsInLayout() {
- if (mChildren.getChildCount() > 0) {
+ if (mShortcutsAndWidgets.getChildCount() > 0) {
clearOccupiedCells();
- mChildren.removeAllViewsInLayout();
+ mShortcutsAndWidgets.removeAllViewsInLayout();
}
}
public void removeViewWithoutMarkingCells(View view) {
- mChildren.removeView(view);
+ mShortcutsAndWidgets.removeView(view);
}
@Override
public void removeView(View view) {
markCellsAsUnoccupiedForView(view);
- mChildren.removeView(view);
+ mShortcutsAndWidgets.removeView(view);
}
@Override
public void removeViewAt(int index) {
- markCellsAsUnoccupiedForView(mChildren.getChildAt(index));
- mChildren.removeViewAt(index);
+ markCellsAsUnoccupiedForView(mShortcutsAndWidgets.getChildAt(index));
+ mShortcutsAndWidgets.removeViewAt(index);
}
@Override
public void removeViewInLayout(View view) {
markCellsAsUnoccupiedForView(view);
- mChildren.removeViewInLayout(view);
+ mShortcutsAndWidgets.removeViewInLayout(view);
}
@Override
public void removeViews(int start, int count) {
for (int i = start; i < start + count; i++) {
- markCellsAsUnoccupiedForView(mChildren.getChildAt(i));
+ markCellsAsUnoccupiedForView(mShortcutsAndWidgets.getChildAt(i));
}
- mChildren.removeViews(start, count);
+ mShortcutsAndWidgets.removeViews(start, count);
}
@Override
public void removeViewsInLayout(int start, int count) {
for (int i = start; i < start + count; i++) {
- markCellsAsUnoccupiedForView(mChildren.getChildAt(i));
+ markCellsAsUnoccupiedForView(mShortcutsAndWidgets.getChildAt(i));
}
- mChildren.removeViewsInLayout(start, count);
- }
-
- public void drawChildren(Canvas canvas) {
- mChildren.draw(canvas);
- }
-
- void buildChildrenLayer() {
- mChildren.buildLayer();
+ mShortcutsAndWidgets.removeViewsInLayout(start, count);
}
@Override
@@ -747,11 +732,11 @@
Rect frame = mRect;
final int x = touchX + mScrollX;
final int y = touchY + mScrollY;
- final int count = mChildren.getChildCount();
+ final int count = mShortcutsAndWidgets.getChildCount();
boolean found = false;
for (int i = count - 1; i >= 0; i--) {
- final View child = mChildren.getChildAt(i);
+ final View child = mShortcutsAndWidgets.getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
if ((child.getVisibility() == VISIBLE || child.getAnimation() != null) &&
@@ -888,11 +873,25 @@
* @param result Array of 2 ints to hold the x and y coordinate of the point
*/
void cellToCenterPoint(int cellX, int cellY, int[] result) {
+ regionToCenterPoint(cellX, cellY, 1, 1, result);
+ }
+
+ /**
+ * Given a cell coordinate and span return the point that represents the center of the regio
+ *
+ * @param cellX X coordinate of the cell
+ * @param cellY Y coordinate of the cell
+ *
+ * @param result Array of 2 ints to hold the x and y coordinate of the point
+ */
+ void regionToCenterPoint(int cellX, int cellY, int spanX, int spanY, int[] result) {
final int hStartPadding = getPaddingLeft();
final int vStartPadding = getPaddingTop();
- result[0] = hStartPadding + cellX * (mCellWidth + mWidthGap) + mCellWidth / 2;
- result[1] = vStartPadding + cellY * (mCellHeight + mHeightGap) + mCellHeight / 2;
+ result[0] = hStartPadding + cellX * (mCellWidth + mWidthGap) +
+ (spanX * mCellWidth + (spanX - 1) * mWidthGap) / 2;
+ result[1] = vStartPadding + cellY * (mCellHeight + mHeightGap) +
+ (spanY * mCellHeight + (spanY - 1) * mHeightGap) / 2;
}
public float getDistanceFromCell(float x, float y, int[] cell) {
@@ -954,7 +953,7 @@
int vFreeSpace = vSpace - (mCountY * mOriginalCellHeight);
mWidthGap = Math.min(mMaxGap, numWidthGaps > 0 ? (hFreeSpace / numWidthGaps) : 0);
mHeightGap = Math.min(mMaxGap,numHeightGaps > 0 ? (vFreeSpace / numHeightGaps) : 0);
- mChildren.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap);
+ mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap);
} else {
mWidthGap = mOriginalWidthGap;
mHeightGap = mOriginalHeightGap;
@@ -1003,12 +1002,12 @@
@Override
protected void setChildrenDrawingCacheEnabled(boolean enabled) {
- mChildren.setChildrenDrawingCacheEnabled(enabled);
+ mShortcutsAndWidgets.setChildrenDrawingCacheEnabled(enabled);
}
@Override
protected void setChildrenDrawnWithCacheEnabled(boolean enabled) {
- mChildren.setChildrenDrawnWithCacheEnabled(enabled);
+ mShortcutsAndWidgets.setChildrenDrawnWithCacheEnabled(enabled);
}
public float getBackgroundAlpha() {
@@ -1030,34 +1029,27 @@
}
}
- // Need to return true to let the view system know we know how to handle alpha-- this is
- // because when our children have an alpha of 0.0f, they are still rendering their "dimmed"
- // versions
- @Override
- protected boolean onSetAlpha(int alpha) {
- return true;
- }
-
- @Override
- public void setAlpha(float alpha) {
- setChildrenAlpha(alpha);
- super.setAlpha(alpha);
- }
-
- private void setChildrenAlpha(float alpha) {
+ public void setShortcutAndWidgetAlpha(float alpha) {
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
getChildAt(i).setAlpha(alpha);
}
}
+ public ShortcutAndWidgetContainer getShortcutsAndWidgets() {
+ if (getChildCount() > 0) {
+ return (ShortcutAndWidgetContainer) getChildAt(0);
+ }
+ return null;
+ }
+
public View getChildAt(int x, int y) {
- return mChildren.getChildAt(x, y);
+ return mShortcutsAndWidgets.getChildAt(x, y);
}
public boolean animateChildToPosition(final View child, int cellX, int cellY, int duration,
int delay, boolean permanent, boolean adjustOccupied) {
- CellLayoutChildren clc = getChildrenLayout();
+ ShortcutAndWidgetContainer clc = getShortcutsAndWidgets();
boolean[][] occupied = mOccupied;
if (!permanent) {
occupied = mTmpOccupied;
@@ -1472,20 +1464,23 @@
* desired location. This method computers distance based on unit grid distances,
* not pixel distances.
*
- * @param pixelX The X location at which you want to search for a vacant area.
- * @param pixelY The Y location at which you want to search for a vacant area.
- * @param minSpanX The minimum horizontal span required
- * @param minSpanY The minimum vertical span required
+ * @param cellX The X cell nearest to which you want to search for a vacant area.
+ * @param cellY The Y cell nearest which you want to search for a vacant area.
* @param spanX Horizontal span of the object.
* @param spanY Vertical span of the object.
- * @param ignoreOccupied If true, the result can be an occupied cell
+ * @param direction The favored direction in which the views should move from x, y
+ * @param exactDirectionOnly If this parameter is true, then only solutions where the direction
+ * matches exactly. Otherwise we find the best matching direction.
+ * @param occoupied The array which represents which cells in the CellLayout are occupied
+ * @param blockOccupied The array which represents which cells in the specified block (cellX,
+ * cellY, spanX, spanY) are occupied. This is used when try to move a group of views.
* @param result Array in which to place the result, or null (in which case a new array will
* be allocated)
* @return The X, Y cell of a vacant area that can contain this object,
* nearest the requested location.
*/
private int[] findNearestArea(int cellX, int cellY, int spanX, int spanY, int[] direction,
- boolean[][] occupied, int[] result) {
+ boolean[][] occupied, boolean blockOccupied[][], int[] result) {
// Keep track of best-scoring drop area
final int[] bestXY = result != null ? result : new int[2];
float bestDistance = Float.MAX_VALUE;
@@ -1500,7 +1495,7 @@
// First, let's see if this thing fits anywhere
for (int i = 0; i < spanX; i++) {
for (int j = 0; j < spanY; j++) {
- if (occupied[x + i][y + j]) {
+ if (occupied[x + i][y + j] && (blockOccupied == null || blockOccupied[i][j])) {
continue inner;
}
}
@@ -1509,11 +1504,16 @@
float distance = (float)
Math.sqrt((x - cellX) * (x - cellX) + (y - cellY) * (y - cellY));
int[] curDirection = mTmpPoint;
- computeDirectionVector(cellX, cellY, x, y, curDirection);
+ computeDirectionVector(x - cellX, y - cellY, curDirection);
+ // The direction score is just the dot product of the two candidate direction
+ // and that passed in.
int curDirectionScore = direction[0] * curDirection[0] +
direction[1] * curDirection[1];
-
- if (Float.compare(distance, bestDistance) < 0 || (Float.compare(distance,
+ boolean exactDirectionOnly = false;
+ boolean directionMatches = direction[0] == curDirection[0] &&
+ direction[0] == curDirection[0];
+ if ((directionMatches || !exactDirectionOnly) &&
+ Float.compare(distance, bestDistance) < 0 || (Float.compare(distance,
bestDistance) == 0 && curDirectionScore > bestDirectionScore)) {
bestDistance = distance;
bestDirectionScore = curDirectionScore;
@@ -1531,6 +1531,48 @@
return bestXY;
}
+ private int[] findNearestAreaInDirection(int cellX, int cellY, int spanX, int spanY,
+ int[] direction,boolean[][] occupied,
+ boolean blockOccupied[][], int[] result) {
+ // Keep track of best-scoring drop area
+ final int[] bestXY = result != null ? result : new int[2];
+ bestXY[0] = -1;
+ bestXY[1] = -1;
+ float bestDistance = Float.MAX_VALUE;
+
+ // We use this to march in a single direction
+ if (direction[0] != 0 && direction[1] != 0) {
+ return bestXY;
+ }
+
+ // This will only incrememnet one of x or y based on the assertion above
+ int x = cellX + direction[0];
+ int y = cellY + direction[1];
+ while (x >= 0 && x + spanX <= mCountX && y >= 0 && y + spanY <= mCountY) {
+
+ boolean fail = false;
+ for (int i = 0; i < spanX; i++) {
+ for (int j = 0; j < spanY; j++) {
+ if (occupied[x + i][y + j] && (blockOccupied == null || blockOccupied[i][j])) {
+ fail = true;
+ }
+ }
+ }
+ if (!fail) {
+ float distance = (float)
+ Math.sqrt((x - cellX) * (x - cellX) + (y - cellY) * (y - cellY));
+ if (Float.compare(distance, bestDistance) < 0) {
+ bestDistance = distance;
+ bestXY[0] = x;
+ bestXY[1] = y;
+ }
+ }
+ x += direction[0];
+ y += direction[1];
+ }
+ return bestXY;
+ }
+
private boolean addViewToTempLocation(View v, Rect rectOccupiedByPotentialDrop,
int[] direction) {
LayoutParams lp = (LayoutParams) v.getLayoutParams();
@@ -1540,7 +1582,7 @@
markCellsForRect(rectOccupiedByPotentialDrop, mTmpOccupied, true);
findNearestArea(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan, lp.cellVSpan,
- direction, mTmpOccupied, mTempLocation);
+ direction, mTmpOccupied, null, mTempLocation);
if (mTempLocation[0] >= 0 && mTempLocation[1] >= 0) {
lp.tmpCellX = mTempLocation[0];
@@ -1553,6 +1595,124 @@
return success;
}
+ // This method looks in the specified direction to see if there is an additional view
+ // immediately adjecent in that direction
+ private boolean addViewInDirection(ArrayList<View> views, Rect boundingRect, int[] direction,
+ boolean[][] occupied) {
+ boolean found = false;
+
+ int childCount = mShortcutsAndWidgets.getChildCount();
+ Rect r0 = new Rect(boundingRect);
+ Rect r1 = new Rect();
+
+ int deltaX = 0;
+ int deltaY = 0;
+ if (direction[1] < 0) {
+ r0.set(r0.left, r0.top - 1, r0.right, r0.bottom);
+ deltaY = -1;
+ } else if (direction[1] > 0) {
+ r0.set(r0.left, r0.top, r0.right, r0.bottom + 1);
+ deltaY = 1;
+ } else if (direction[0] < 0) {
+ r0.set(r0.left - 1, r0.top, r0.right, r0.bottom);
+ deltaX = -1;
+ } else if (direction[0] > 0) {
+ r0.set(r0.left, r0.top, r0.right + 1, r0.bottom);
+ deltaX = 1;
+ }
+
+ for (int i = 0; i < childCount; i++) {
+ View child = mShortcutsAndWidgets.getChildAt(i);
+ if (views.contains(child)) continue;
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+ r1.set(lp.tmpCellX, lp.tmpCellY, lp.tmpCellX + lp.cellHSpan, lp.tmpCellY + lp.cellVSpan);
+ if (Rect.intersects(r0, r1)) {
+ if (!lp.canReorder) {
+ return false;
+ }
+ boolean pushed = false;
+ for (int x = lp.tmpCellX; x < lp.tmpCellX + lp.cellHSpan; x++) {
+ for (int y = lp.tmpCellY; y < lp.tmpCellY + lp.cellVSpan; y++) {
+ boolean inBounds = x - deltaX >= 0 && x -deltaX < mCountX
+ && y - deltaY >= 0 && y - deltaY < mCountY;
+ if (inBounds && occupied[x - deltaX][y - deltaY]) {
+ pushed = true;
+ }
+ }
+ }
+ if (pushed) {
+ views.add(child);
+ boundingRect.union(lp.tmpCellX, lp.tmpCellY, lp.tmpCellX + lp.cellHSpan,
+ lp.tmpCellY + lp.cellVSpan);
+ found = true;
+ }
+ }
+ }
+ return found;
+ }
+
+ private boolean pushViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop,
+ int[] direction) {
+ if (views.size() == 0) return true;
+
+
+ boolean success = false;
+
+ // We construct a rect which represents the entire group of views
+ Rect boundingRect = null;
+ for (View v: views) {
+ LayoutParams lp = (LayoutParams) v.getLayoutParams();
+ if (boundingRect == null) {
+ boundingRect = new Rect(lp.tmpCellX, lp.tmpCellY, lp.tmpCellX + lp.cellHSpan,
+ lp.tmpCellY + lp.cellVSpan);
+ } else {
+ boundingRect.union(lp.tmpCellX, lp.tmpCellY, lp.tmpCellX + lp.cellHSpan,
+ lp.tmpCellY + lp.cellVSpan);
+ }
+ }
+
+ ArrayList<View> dup = (ArrayList<View>) views.clone();
+ while (addViewInDirection(dup, boundingRect, direction, mTmpOccupied)) {
+ }
+ for (View v: dup) {
+ LayoutParams lp = (LayoutParams) v.getLayoutParams();
+ markCellsForView(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan,
+ lp.cellVSpan, mTmpOccupied, false);
+ }
+
+ boolean[][] blockOccupied = new boolean[boundingRect.width()][boundingRect.height()];
+ int top = boundingRect.top;
+ int left = boundingRect.left;
+ for (View v: dup) {
+ LayoutParams lp = (LayoutParams) v.getLayoutParams();
+ markCellsForView(lp.tmpCellX - left, lp.tmpCellY - top, lp.cellHSpan,
+ lp.cellVSpan, blockOccupied, true);
+ }
+
+ markCellsForRect(rectOccupiedByPotentialDrop, mTmpOccupied, true);
+
+ findNearestAreaInDirection(boundingRect.left, boundingRect.top, boundingRect.width(),
+ boundingRect.height(), direction, mTmpOccupied, blockOccupied, mTempLocation);
+
+ int deltaX = mTempLocation[0] - boundingRect.left;
+ int deltaY = mTempLocation[1] - boundingRect.top;
+ if (mTempLocation[0] >= 0 && mTempLocation[1] >= 0) {
+ for (View v: dup) {
+ LayoutParams lp = (LayoutParams) v.getLayoutParams();
+ lp.tmpCellX += deltaX;
+ lp.tmpCellY += deltaY;
+ }
+ success = true;
+ }
+ for (View v: dup) {
+ LayoutParams lp = (LayoutParams) v.getLayoutParams();
+ markCellsForView(lp.tmpCellX, lp.tmpCellY, lp.cellHSpan,
+ lp.cellVSpan, mTmpOccupied, true);
+ }
+ return success;
+ }
+
private boolean addViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop,
int[] direction) {
if (views.size() == 0) return true;
@@ -1572,12 +1732,21 @@
lp.tmpCellY + lp.cellVSpan);
}
}
+ boolean[][] blockOccupied = new boolean[boundingRect.width()][boundingRect.height()];
+ int top = boundingRect.top;
+ int left = boundingRect.left;
+ for (View v: views) {
+ LayoutParams lp = (LayoutParams) v.getLayoutParams();
+ markCellsForView(lp.tmpCellX - left, lp.tmpCellY - top, lp.cellHSpan,
+ lp.cellVSpan, blockOccupied, true);
+ }
+
markCellsForRect(rectOccupiedByPotentialDrop, mTmpOccupied, true);
// TODO: this bounding rect may not be completely filled, lets be more precise about this
// check.
- findNearestArea(boundingRect.left, boundingRect.top, boundingRect.width(), boundingRect.height(),
- direction, mTmpOccupied, mTempLocation);
+ findNearestArea(boundingRect.left, boundingRect.top, boundingRect.width(),
+ boundingRect.height(), direction, mTmpOccupied, blockOccupied, mTempLocation);
int deltaX = mTempLocation[0] - boundingRect.left;
int deltaY = mTempLocation[1] - boundingRect.top;
@@ -1606,7 +1775,6 @@
mIntersectingViews.clear();
mOccupiedRect.set(cellX, cellY, cellX + spanX, cellY + spanY);
- markCellsForRect(mOccupiedRect, mTmpOccupied, true);
if (ignoreView != null) {
LayoutParams lp = (LayoutParams) ignoreView.getLayoutParams();
@@ -1614,11 +1782,11 @@
lp.tmpCellY = cellY;
}
- int childCount = mChildren.getChildCount();
+ int childCount = mShortcutsAndWidgets.getChildCount();
Rect r0 = new Rect(cellX, cellY, cellX + spanX, cellY + spanY);
Rect r1 = new Rect();
for (int i = 0; i < childCount; i++) {
- View child = mChildren.getChildAt(i);
+ View child = mShortcutsAndWidgets.getChildAt(i);
if (child == ignoreView) continue;
LayoutParams lp = (LayoutParams) child.getLayoutParams();
r1.set(lp.cellX, lp.cellY, lp.cellX + lp.cellHSpan, lp.cellY + lp.cellVSpan);
@@ -1629,10 +1797,25 @@
mIntersectingViews.add(child);
}
}
+
+ if (pushViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction)) {
+ return true;
+ }
+ // Try the opposite direction
+ direction[0] *= -1;
+ direction[1] *= -1;
+ if (pushViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction)) {
+ return true;
+ }
+ // Switch the direction back
+ direction[0] *= -1;
+ direction[1] *= -1;
+
// First we try moving the views as a block
if (addViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction)) {
return true;
}
+
// Ok, they couldn't move as a block, let's move them individually
for (View v : mIntersectingViews) {
if (!addViewToTempLocation(v, mOccupiedRect, direction)) {
@@ -1646,10 +1829,7 @@
* Returns a pair (x, y), where x,y are in {-1, 0, 1} corresponding to vector between
* the provided point and the provided cell
*/
- private void computeDirectionVector(int x0, int y0, int x1, int y1, int[] result) {
- int deltaX = x1 - x0;
- int deltaY = y1 - y0;
-
+ private void computeDirectionVector(float deltaX, float deltaY, int[] result) {
double angle = Math.atan(((float) deltaY) / deltaX);
result[0] = 0;
@@ -1701,9 +1881,9 @@
}
private void copyCurrentStateToSolution(ItemConfiguration solution, boolean temp) {
- int childCount = mChildren.getChildCount();
+ int childCount = mShortcutsAndWidgets.getChildCount();
for (int i = 0; i < childCount; i++) {
- View child = mChildren.getChildAt(i);
+ View child = mShortcutsAndWidgets.getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
Point p;
if (temp) {
@@ -1722,9 +1902,9 @@
}
}
- int childCount = mChildren.getChildCount();
+ int childCount = mShortcutsAndWidgets.getChildCount();
for (int i = 0; i < childCount; i++) {
- View child = mChildren.getChildAt(i);
+ View child = mShortcutsAndWidgets.getChildAt(i);
if (child == dragView) continue;
LayoutParams lp = (LayoutParams) child.getLayoutParams();
Point p = solution.map.get(child);
@@ -1749,9 +1929,9 @@
}
}
- int childCount = mChildren.getChildCount();
+ int childCount = mShortcutsAndWidgets.getChildCount();
for (int i = 0; i < childCount; i++) {
- View child = mChildren.getChildAt(i);
+ View child = mShortcutsAndWidgets.getChildAt(i);
if (child == dragView) continue;
LayoutParams lp = (LayoutParams) child.getLayoutParams();
Point p = solution.map.get(child);
@@ -1774,18 +1954,18 @@
mOccupied[i][j] = mTmpOccupied[i][j];
}
}
- int childCount = mChildren.getChildCount();
+ int childCount = mShortcutsAndWidgets.getChildCount();
for (int i = 0; i < childCount; i++) {
- LayoutParams lp = (LayoutParams) mChildren.getChildAt(i).getLayoutParams();
+ LayoutParams lp = (LayoutParams) mShortcutsAndWidgets.getChildAt(i).getLayoutParams();
lp.cellX = lp.tmpCellX;
lp.cellY = lp.tmpCellY;
}
}
public void setUseTempCoords(boolean useTempCoords) {
- int childCount = mChildren.getChildCount();
+ int childCount = mShortcutsAndWidgets.getChildCount();
for (int i = 0; i < childCount; i++) {
- LayoutParams lp = (LayoutParams) mChildren.getChildAt(i).getLayoutParams();
+ LayoutParams lp = (LayoutParams) mShortcutsAndWidgets.getChildAt(i).getLayoutParams();
lp.useTmpCoords = useTempCoords;
}
}
@@ -1796,9 +1976,9 @@
mTmpOccupied[i][j] = mOccupied[i][j];
}
}
- int childCount = mChildren.getChildCount();
+ int childCount = mShortcutsAndWidgets.getChildCount();
for (int i = 0; i < childCount; i++) {
- View child = mChildren.getChildAt(i);
+ View child = mShortcutsAndWidgets.getChildAt(i);
if (child == ignoreView) continue;
LayoutParams lp = (LayoutParams) child.getLayoutParams();
lp.tmpCellX = lp.cellX;
@@ -1827,25 +2007,22 @@
public void prepareChildForDrag(View child) {
markCellsAsUnoccupiedForView(child);
- LayoutParams lp = (LayoutParams) child.getLayoutParams();
- lp.cellX = -1;
- lp.cellY = -1;
-
}
int[] createArea(int pixelX, int pixelY, int minSpanX, int minSpanY, int spanX, int spanY,
View dragView, int[] result, int resultSpan[], int mode) {
// First we determine if things have moved enough to cause a different layout
- result = findNearestArea(pixelX, pixelY, 1, 1, result);
+ result = findNearestArea(pixelX, pixelY, spanX, spanY, result);
if (resultSpan == null) {
resultSpan = new int[2];
}
// We attempt the first algorithm
- cellToCenterPoint(result[0], result[1], mTmpPoint);
- computeDirectionVector(pixelX, pixelY, mTmpPoint[0], mTmpPoint[1], mDirectionVector);
+ regionToCenterPoint(result[0], result[1], spanX, spanY, mTmpPoint);
+ computeDirectionVector((mTmpPoint[0] - pixelX) / spanX, (mTmpPoint[1] - pixelY) / spanY,
+ mDirectionVector);
ItemConfiguration swapSolution = simpleSwap(pixelX, pixelY, minSpanX, minSpanY,
spanX, spanY, mDirectionVector, dragView, true, new ItemConfiguration());
@@ -1895,7 +2072,7 @@
}
boolean[][] occupied = mOccupied;
- mChildren.requestLayout();
+ mShortcutsAndWidgets.requestLayout();
return result;
}
@@ -2343,7 +2520,7 @@
markCellsAsOccupiedForView(view, mOccupied);
}
public void markCellsAsOccupiedForView(View view, boolean[][] occupied) {
- if (view == null || view.getParent() != mChildren) return;
+ if (view == null || view.getParent() != mShortcutsAndWidgets) return;
LayoutParams lp = (LayoutParams) view.getLayoutParams();
markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, occupied, true);
}
@@ -2352,7 +2529,7 @@
markCellsAsUnoccupiedForView(view, mOccupied);
}
public void markCellsAsUnoccupiedForView(View view, boolean occupied[][]) {
- if (view == null || view.getParent() != mChildren) return;
+ if (view == null || view.getParent() != mShortcutsAndWidgets) return;
LayoutParams lp = (LayoutParams) view.getLayoutParams();
markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, occupied, false);
}
diff --git a/src/com/android/launcher2/DeleteDropTarget.java b/src/com/android/launcher2/DeleteDropTarget.java
index 4621dea..6f45590 100644
--- a/src/com/android/launcher2/DeleteDropTarget.java
+++ b/src/com/android/launcher2/DeleteDropTarget.java
@@ -16,24 +16,33 @@
package com.android.launcher2;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.TransitionDrawable;
import android.util.AttributeSet;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
+import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import com.android.launcher.R;
public class DeleteDropTarget extends ButtonDropTarget {
+ private static int DELETE_ANIMATION_DURATION = 285;
+ private static int MODE_FLING_DELETE_TO_TRASH = 0;
+ private static int MODE_FLING_DELETE_ALONG_VECTOR = 1;
- private static int DELETE_ANIMATION_DURATION = 300;
+ private final int mFlingDeleteMode = MODE_FLING_DELETE_ALONG_VECTOR;
+
private ColorStateList mOriginalTextColor;
private TransitionDrawable mUninstallDrawable;
private TransitionDrawable mRemoveDrawable;
@@ -223,4 +232,175 @@
public void onDrop(DragObject d) {
animateToTrashAndCompleteDrop(d);
}
+
+ /**
+ * Creates an animation from the current drag view to the delete trash icon.
+ */
+ private AnimatorUpdateListener createFlingToTrashAnimatorListener(final DragLayer dragLayer,
+ DragObject d, PointF vel, ViewConfiguration config) {
+ final Rect to = getIconRect(d.dragView.getMeasuredWidth(), d.dragView.getMeasuredHeight(),
+ mCurrentDrawable.getIntrinsicWidth(), mCurrentDrawable.getIntrinsicHeight());
+ final Rect from = new Rect();
+ dragLayer.getViewRectRelativeToSelf(d.dragView, from);
+
+ // Calculate how far along the velocity vector we should put the intermediate point on
+ // the bezier curve
+ float velocity = Math.abs(vel.length());
+ float vp = Math.min(1f, velocity / (config.getScaledMaximumFlingVelocity() / 2f));
+ int offsetY = (int) (-from.top * vp);
+ int offsetX = (int) (offsetY / (vel.y / vel.x));
+ final float y2 = from.top + offsetY; // intermediate t/l
+ final float x2 = from.left + offsetX;
+ final float x1 = from.left; // drag view t/l
+ final float y1 = from.top;
+ final float x3 = to.left; // delete target t/l
+ final float y3 = to.top;
+
+ final TimeInterpolator scaleAlphaInterpolator = new TimeInterpolator() {
+ @Override
+ public float getInterpolation(float t) {
+ return t * t * t * t * t * t * t * t;
+ }
+ };
+ return new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ final DragView dragView = (DragView) dragLayer.getAnimatedView();
+ float t = ((Float) animation.getAnimatedValue()).floatValue();
+ float tp = scaleAlphaInterpolator.getInterpolation(t);
+ float initialScale = dragView.getInitialScale();
+ float finalAlpha = 0.5f;
+ float scale = dragView.getScaleX();
+ float x1o = ((1f - scale) * dragView.getMeasuredWidth()) / 2f;
+ float y1o = ((1f - scale) * dragView.getMeasuredHeight()) / 2f;
+ float x = (1f - t) * (1f - t) * (x1 - x1o) + 2 * (1f - t) * t * (x2 - x1o) +
+ (t * t) * x3;
+ float y = (1f - t) * (1f - t) * (y1 - y1o) + 2 * (1f - t) * t * (y2 - x1o) +
+ (t * t) * y3;
+
+ dragView.setTranslationX(x);
+ dragView.setTranslationY(y);
+ dragView.setScaleX(initialScale * (1f - tp));
+ dragView.setScaleY(initialScale * (1f - tp));
+ dragView.setAlpha(finalAlpha + (1f - finalAlpha) * (1f - tp));
+ }
+ };
+ }
+
+ /**
+ * Creates an animation from the current drag view along its current velocity vector.
+ * For this animation, the alpha runs for a fixed duration and we update the position
+ * progressively.
+ */
+ private static class FlingAlongVectorAnimatorUpdateListener implements AnimatorUpdateListener {
+ private static float FRICTION = 0.93f;
+
+ private DragLayer mDragLayer;
+ private PointF mVelocity;
+ private Rect mFrom;
+ private long mPrevTime;
+ private boolean mHasOffsetForScale;
+
+ private final TimeInterpolator mAlphaInterpolator = new DecelerateInterpolator(1.5f);
+
+ public FlingAlongVectorAnimatorUpdateListener(DragLayer dragLayer, PointF vel, Rect from,
+ long startTime) {
+ mDragLayer = dragLayer;
+ mVelocity = vel;
+ mFrom = from;
+ mPrevTime = startTime;
+ }
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ final DragView dragView = (DragView) mDragLayer.getAnimatedView();
+ float t = ((Float) animation.getAnimatedValue()).floatValue();
+ long curTime = AnimationUtils.currentAnimationTimeMillis();
+
+ if (!mHasOffsetForScale) {
+ mHasOffsetForScale = true;
+ float scale = dragView.getScaleX();
+ float xOffset = ((scale - 1f) * dragView.getMeasuredWidth()) / 2f;
+ float yOffset = ((scale - 1f) * dragView.getMeasuredHeight()) / 2f;
+
+ mFrom.left += xOffset;
+ mFrom.top += yOffset;
+ }
+
+ mFrom.left += (mVelocity.x * (curTime - mPrevTime) / 1000f);
+ mFrom.top += (mVelocity.y * (curTime - mPrevTime) / 1000f);
+
+ dragView.setTranslationX(mFrom.left);
+ dragView.setTranslationY(mFrom.top);
+ dragView.setAlpha(1f - mAlphaInterpolator.getInterpolation(t));
+
+ mVelocity.x *= FRICTION;
+ mVelocity.y *= FRICTION;
+ mPrevTime = curTime;
+ }
+ };
+ private AnimatorUpdateListener createFlingAlongVectorAnimatorListener(final DragLayer dragLayer,
+ DragObject d, PointF vel, final long startTime, final int duration,
+ ViewConfiguration config) {
+ final Rect from = new Rect();
+ dragLayer.getViewRectRelativeToSelf(d.dragView, from);
+
+ return new FlingAlongVectorAnimatorUpdateListener(dragLayer, vel, from, startTime);
+ }
+
+ public void onFlingToDelete(final DragObject d, int x, int y, PointF vel) {
+ // Don't highlight the icon as it's animating
+ d.dragView.setColor(0);
+ d.dragView.updateInitialScaleToCurrentScale();
+
+ if (mFlingDeleteMode == MODE_FLING_DELETE_TO_TRASH) {
+ // Defer animating out the drop target if we are animating to it
+ mSearchDropTargetBar.deferOnDragEnd();
+ mSearchDropTargetBar.finishAnimations();
+ }
+
+ final ViewConfiguration config = ViewConfiguration.get(mLauncher);
+ final DragLayer dragLayer = mLauncher.getDragLayer();
+ final int duration = DELETE_ANIMATION_DURATION;
+ final long startTime = AnimationUtils.currentAnimationTimeMillis();
+
+ // NOTE: Because it takes time for the first frame of animation to actually be
+ // called and we expect the animation to be a continuation of the fling, we have
+ // to account for the time that has elapsed since the fling finished. And since
+ // we don't have a startDelay, we will always get call to update when we call
+ // start() (which we want to ignore).
+ final TimeInterpolator tInterpolator = new TimeInterpolator() {
+ private int mCount = -1;
+ private float mOffset = 0f;
+
+ @Override
+ public float getInterpolation(float t) {
+ if (mCount < 0) {
+ mCount++;
+ } else if (mCount == 0) {
+ mOffset = Math.min(0.5f, (float) (AnimationUtils.currentAnimationTimeMillis() -
+ startTime) / duration);
+ mCount++;
+ }
+ return Math.min(1f, mOffset + t);
+ }
+ };
+ AnimatorUpdateListener updateCb = null;
+ if (mFlingDeleteMode == MODE_FLING_DELETE_TO_TRASH) {
+ updateCb = createFlingToTrashAnimatorListener(dragLayer, d, vel, config);
+ } else if (mFlingDeleteMode == MODE_FLING_DELETE_ALONG_VECTOR) {
+ updateCb = createFlingAlongVectorAnimatorListener(dragLayer, d, vel, startTime,
+ duration, config);
+ }
+ Runnable onAnimationEndRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mSearchDropTargetBar.onDragEnd();
+ mLauncher.exitSpringLoadedDragMode();
+ completeDrop(d);
+ }
+ };
+ dragLayer.animateView(d.dragView, updateCb, duration, tInterpolator, onAnimationEndRunnable,
+ DragLayer.ANIMATION_END_DISAPPEAR, null);
+ }
}
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index 019a749..2a88925 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
@@ -26,6 +27,7 @@
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.inputmethod.InputMethodManager;
@@ -60,6 +62,9 @@
static final int SCROLL_LEFT = 0;
static final int SCROLL_RIGHT = 1;
+ private static final float MAX_FLING_DEGREES = 35f;
+ private static final int FLING_TO_DELETE_THRESHOLD_Y_VELOCITY = -1400;
+
private Launcher mLauncher;
private Handler mHandler;
private final Vibrator mVibrator = new Vibrator();
@@ -86,8 +91,8 @@
/** Who can receive drop events */
private ArrayList<DropTarget> mDropTargets = new ArrayList<DropTarget>();
-
private ArrayList<DragListener> mListeners = new ArrayList<DragListener>();
+ private DropTarget mFlingToDeleteDropTarget;
/** The window token used as the parent for the DragView. */
private IBinder mWindowToken;
@@ -111,6 +116,9 @@
private int mTmpPoint[] = new int[2];
private Rect mDragLayerRect = new Rect();
+ protected int mFlingToDeleteThresholdVelocity;
+ private VelocityTracker mVelocityTracker;
+
/**
* Interface to receive notifications when a drag starts or stops
*/
@@ -141,6 +149,10 @@
mLauncher = launcher;
mHandler = new Handler();
mScrollZone = launcher.getResources().getDimensionPixelSize(R.dimen.scroll_zone);
+ mVelocityTracker = VelocityTracker.obtain();
+
+ float density = launcher.getResources().getDisplayMetrics().density;
+ mFlingToDeleteThresholdVelocity = (int) (FLING_TO_DELETE_THRESHOLD_Y_VELOCITY * density);
}
public boolean dragging() {
@@ -378,15 +390,35 @@
if (mDragging) {
mDragging = false;
clearScrollRunnable();
- for (DragListener listener : mListeners) {
- listener.onDragEnd();
- }
+ boolean isDeferred = false;
if (mDragObject.dragView != null) {
- if (!mDragObject.deferDragViewCleanupPostAnimation) {
+ isDeferred = mDragObject.deferDragViewCleanupPostAnimation;
+ if (!isDeferred) {
mDragObject.dragView.remove();
}
mDragObject.dragView = null;
}
+
+ // Only end the drag if we are not deferred
+ if (!isDeferred) {
+ for (DragListener listener : mListeners) {
+ listener.onDragEnd();
+ }
+ }
+ }
+
+ releaseVelocityTracker();
+ }
+
+ /**
+ * This only gets called as a result of drag view cleanup being deferred in endDrag();
+ */
+ void onDeferredEndDrag(DragView dragView) {
+ dragView.remove();
+
+ // If we skipped calling onDragEnd() before, do it now
+ for (DragListener listener : mListeners) {
+ listener.onDragEnd();
}
}
@@ -408,8 +440,11 @@
Log.d(Launcher.TAG, "DragController.onInterceptTouchEvent " + ev + " mDragging="
+ mDragging);
}
- final int action = ev.getAction();
+ // Update the velocity tracker
+ acquireVelocityTrackerAndAddMovement(ev);
+
+ final int action = ev.getAction();
final int[] dragLayerPos = getClampedDragLayerPos(ev.getX(), ev.getY());
final int dragLayerX = dragLayerPos[0];
final int dragLayerY = dragLayerPos[1];
@@ -425,7 +460,12 @@
break;
case MotionEvent.ACTION_UP:
if (mDragging) {
- drop(dragLayerX, dragLayerY);
+ PointF vec = isFlingingToDelete(mDragObject.dragSource);
+ if (vec != null) {
+ dropOnFlingToDeleteTarget(dragLayerX, dragLayerY, vec);
+ } else {
+ drop(dragLayerX, dragLayerY);
+ }
}
endDrag();
break;
@@ -529,6 +569,9 @@
return false;
}
+ // Update the velocity tracker
+ acquireVelocityTrackerAndAddMovement(ev);
+
final int action = ev.getAction();
final int[] dragLayerPos = getClampedDragLayerPos(ev.getX(), ev.getY());
final int dragLayerX = dragLayerPos[0];
@@ -553,10 +596,15 @@
case MotionEvent.ACTION_UP:
// Ensure that we've processed a move event at the current pointer location.
handleMoveEvent(dragLayerX, dragLayerY);
-
mHandler.removeCallbacks(mScrollRunnable);
+
if (mDragging) {
- drop(dragLayerX, dragLayerY);
+ PointF vec = isFlingingToDelete(mDragObject.dragSource);
+ if (vec != null) {
+ dropOnFlingToDeleteTarget(dragLayerX, dragLayerY, vec);
+ } else {
+ drop(dragLayerX, dragLayerY);
+ }
}
endDrag();
break;
@@ -569,6 +617,58 @@
return true;
}
+ /**
+ * Determines whether the user flung the current item to delete it.
+ *
+ * @return the vector at which the item was flung, or null if no fling was detected.
+ */
+ private PointF isFlingingToDelete(DragSource source) {
+ if (mFlingToDeleteDropTarget == null) return null;
+ if (!source.supportsFlingToDelete()) return null;
+
+ ViewConfiguration config = ViewConfiguration.get(mLauncher);
+ mVelocityTracker.computeCurrentVelocity(1000, config.getScaledMaximumFlingVelocity());
+
+ if (mVelocityTracker.getYVelocity() < mFlingToDeleteThresholdVelocity) {
+ // Do a quick dot product test to ensure that we are flinging upwards
+ PointF vel = new PointF(mVelocityTracker.getXVelocity(),
+ mVelocityTracker.getYVelocity());
+ PointF upVec = new PointF(0f, -1f);
+ float theta = (float) Math.acos(((vel.x * upVec.x) + (vel.y * upVec.y)) /
+ (vel.length() * upVec.length()));
+ if (theta <= Math.toRadians(MAX_FLING_DEGREES)) {
+ return vel;
+ }
+ }
+ return null;
+ }
+
+ private void dropOnFlingToDeleteTarget(float x, float y, PointF vel) {
+ final int[] coordinates = mCoordinatesTemp;
+
+ mDragObject.x = coordinates[0];
+ mDragObject.y = coordinates[1];
+ mDragObject.dragComplete = true;
+
+ // Clean up dragging on the target if it's not the current fling delete target otherwise,
+ // start dragging to it.
+ if (mLastDropTarget != null && mFlingToDeleteDropTarget != mLastDropTarget) {
+ mLastDropTarget.onDragExit(mDragObject);
+ }
+
+ // Drop onto the fling-to-delete target
+ boolean accepted = false;
+ mFlingToDeleteDropTarget.onDragEnter(mDragObject);
+ mFlingToDeleteDropTarget.onDragExit(mDragObject);
+ if (mFlingToDeleteDropTarget.acceptDrop(mDragObject)) {
+ mFlingToDeleteDropTarget.onFlingToDelete(mDragObject, mDragObject.x, mDragObject.y,
+ vel);
+ accepted = true;
+ }
+ mDragObject.dragSource.onDropCompleted((View) mFlingToDeleteDropTarget, mDragObject,
+ accepted);
+ }
+
private void drop(float x, float y) {
final int[] coordinates = mCoordinatesTemp;
final DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates);
@@ -659,6 +759,27 @@
}
/**
+ * Sets the current fling-to-delete drop target.
+ */
+ public void setFlingToDeleteDropTarget(DropTarget target) {
+ mFlingToDeleteDropTarget = target;
+ }
+
+ private void acquireVelocityTrackerAndAddMovement(MotionEvent ev) {
+ if (mVelocityTracker == null) {
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+ mVelocityTracker.addMovement(ev);
+ }
+
+ private void releaseVelocityTracker() {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ }
+
+ /**
* Set which view scrolls for touch events near the edge of the screen.
*/
public void setScrollView(View v) {
diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java
index ce5c8c5..9452857 100644
--- a/src/com/android/launcher2/DragLayer.java
+++ b/src/com/android/launcher2/DragLayer.java
@@ -18,15 +18,15 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PointF;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -34,6 +34,7 @@
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
+import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
@@ -433,7 +434,7 @@
public void animateViewIntoPosition(DragView dragView, final View child, int duration,
final Runnable onFinishAnimationRunnable, View anchorView) {
- CellLayoutChildren parentChildren = (CellLayoutChildren) child.getParent();
+ ShortcutAndWidgetContainer parentChildren = (ShortcutAndWidgetContainer) child.getParent();
CellLayout parent = (CellLayout) (CellLayout) parentChildren.getParent();
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
parentChildren.measureChild(child);
@@ -542,35 +543,17 @@
duration = Math.max(duration, res.getInteger(R.integer.config_dropAnimMinDuration));
}
- if (mDropAnim != null) {
- mDropAnim.cancel();
- }
-
- if (mFadeOutAnim != null) {
- mFadeOutAnim.cancel();
- }
-
- // Show the drop view if it was previously hidden
- mDropView = view;
- mDropView.cancelAnimation();
- mDropView.resetLayoutParams();
- mDropAnim = new ValueAnimator();
+ // Fall back to cubic ease out interpolator for the animation if none is specified
+ TimeInterpolator interpolator = null;
if (alphaInterpolator == null || motionInterpolator == null) {
- mDropAnim.setInterpolator(mCubicEaseOutInterpolator);
+ interpolator = mCubicEaseOutInterpolator;
}
- if (anchorView != null) {
- mAnchorViewInitialScrollX = anchorView.getScrollX();
- }
- mAnchorView = anchorView;
-
+ // Animate the view
final float initAlpha = view.getAlpha();
- final float dropViewScale = mDropView.getScaleX();
-
- mDropAnim.setDuration(duration);
- mDropAnim.setFloatValues(0.0f, 1.0f);
- mDropAnim.removeAllUpdateListeners();
- mDropAnim.addUpdateListener(new AnimatorUpdateListener() {
+ final float dropViewScale = view.getScaleX();
+ AnimatorUpdateListener updateCb = new AnimatorUpdateListener() {
+ @Override
public void onAnimationUpdate(ValueAnimator animation) {
final float percent = (Float) animation.getAnimatedValue();
final int width = view.getMeasuredWidth();
@@ -603,7 +586,35 @@
mDropView.setScaleY(scaleY);
mDropView.setAlpha(alpha);
}
- });
+ };
+ animateView(view, updateCb, duration, interpolator, onCompleteRunnable, animationEndStyle,
+ anchorView);
+ }
+
+ public void animateView(final DragView view, AnimatorUpdateListener updateCb, int duration,
+ TimeInterpolator interpolator, final Runnable onCompleteRunnable,
+ final int animationEndStyle, View anchorView) {
+ // Clean up the previous animations
+ if (mDropAnim != null) mDropAnim.cancel();
+ if (mFadeOutAnim != null) mFadeOutAnim.cancel();
+
+ // Show the drop view if it was previously hidden
+ mDropView = view;
+ mDropView.cancelAnimation();
+ mDropView.resetLayoutParams();
+
+ // Set the anchor view if the page is scrolling
+ if (anchorView != null) {
+ mAnchorViewInitialScrollX = anchorView.getScrollX();
+ }
+ mAnchorView = anchorView;
+
+ // Create and start the animation
+ mDropAnim = new ValueAnimator();
+ mDropAnim.setInterpolator(interpolator);
+ mDropAnim.setDuration(duration);
+ mDropAnim.setFloatValues(0f, 1f);
+ mDropAnim.addUpdateListener(updateCb);
mDropAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
if (onCompleteRunnable != null) {
@@ -629,7 +640,7 @@
mDropAnim.cancel();
}
if (mDropView != null) {
- mDropView.remove();
+ mDragController.onDeferredEndDrag(mDropView);
}
mDropView = null;
invalidate();
@@ -655,7 +666,7 @@
mFadeOutAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
if (mDropView != null) {
- mDropView.remove();
+ mDragController.onDeferredEndDrag(mDropView);
}
mDropView = null;
invalidate();
diff --git a/src/com/android/launcher2/DragSource.java b/src/com/android/launcher2/DragSource.java
index 06f5ee1..a654b93 100644
--- a/src/com/android/launcher2/DragSource.java
+++ b/src/com/android/launcher2/DragSource.java
@@ -25,5 +25,6 @@
*
*/
public interface DragSource {
+ boolean supportsFlingToDelete();
void onDropCompleted(View target, DragObject d, boolean success);
}
diff --git a/src/com/android/launcher2/DragView.java b/src/com/android/launcher2/DragView.java
index 3090e8f..5636f99 100644
--- a/src/com/android/launcher2/DragView.java
+++ b/src/com/android/launcher2/DragView.java
@@ -51,6 +51,7 @@
ValueAnimator mAnim;
private float mOffsetX = 0.0f;
private float mOffsetY = 0.0f;
+ private float mInitialScale = 1f;
/**
* Construct the drag view.
@@ -67,6 +68,7 @@
int left, int top, int width, int height, final float initialScale) {
super(launcher);
mDragLayer = launcher.getDragLayer();
+ mInitialScale = initialScale;
final Resources res = getResources();
final float offsetX = res.getDimensionPixelSize(R.dimen.dragViewOffsetX);
@@ -151,6 +153,14 @@
return mDragRegion;
}
+ public float getInitialScale() {
+ return mInitialScale;
+ }
+
+ public void updateInitialScaleToCurrentScale() {
+ mInitialScale = getScaleX();
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight());
@@ -233,6 +243,11 @@
*/
public void show(int touchX, int touchY) {
mDragLayer.addView(this);
+
+ // Enable hw-layers on this view
+ setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+ // Start the pick-up animation
DragLayer.LayoutParams lp = new DragLayer.LayoutParams(0, 0);
lp.width = mBitmap.getWidth();
lp.height = mBitmap.getHeight();
@@ -267,6 +282,9 @@
void remove() {
if (getParent() != null) {
+ // Disable hw-layers on this view
+ setLayerType(View.LAYER_TYPE_NONE, null);
+
mDragLayer.removeView(DragView.this);
}
}
diff --git a/src/com/android/launcher2/DropTarget.java b/src/com/android/launcher2/DropTarget.java
index e49f782..fb714c6 100644
--- a/src/com/android/launcher2/DropTarget.java
+++ b/src/com/android/launcher2/DropTarget.java
@@ -16,6 +16,7 @@
package com.android.launcher2;
+import android.graphics.PointF;
import android.graphics.Rect;
/**
@@ -92,6 +93,13 @@
void onDragExit(DragObject dragObject);
/**
+ * Handle an object being dropped as a result of flinging to delete and will be called in place
+ * of onDrop(). (This is only called on objects that are set as the DragController's
+ * fling-to-delete target.
+ */
+ void onFlingToDelete(DragObject dragObject, int x, int y, PointF vec);
+
+ /**
* Allows a DropTarget to delegate drag and drop events to another object.
*
* Most subclasses will should just return null from this method.
diff --git a/src/com/android/launcher2/FocusHelper.java b/src/com/android/launcher2/FocusHelper.java
index 7807b5d..ecc9d9c 100644
--- a/src/com/android/launcher2/FocusHelper.java
+++ b/src/com/android/launcher2/FocusHelper.java
@@ -534,7 +534,7 @@
if (handleKeyEvent) {
// Select the first bubble text view in the current page of the workspace
final CellLayout layout = (CellLayout) workspace.getChildAt(pageIndex);
- final CellLayoutChildren children = layout.getChildrenLayout();
+ final ShortcutAndWidgetContainer children = layout.getShortcutsAndWidgets();
final View newIcon = getIconInDirection(layout, children, -1, 1);
if (newIcon != null) {
newIcon.requestFocus();
@@ -556,9 +556,10 @@
/**
* Private helper method to get the CellLayoutChildren given a CellLayout index.
*/
- private static CellLayoutChildren getCellLayoutChildrenForIndex(ViewGroup container, int i) {
+ private static ShortcutAndWidgetContainer getCellLayoutChildrenForIndex(
+ ViewGroup container, int i) {
ViewGroup parent = (ViewGroup) container.getChildAt(i);
- return (CellLayoutChildren) parent.getChildAt(0);
+ return (ShortcutAndWidgetContainer) parent.getChildAt(0);
}
/**
@@ -664,7 +665,7 @@
* Handles key events in a Workspace containing.
*/
static boolean handleIconKeyEvent(View v, int keyCode, KeyEvent e) {
- CellLayoutChildren parent = (CellLayoutChildren) v.getParent();
+ ShortcutAndWidgetContainer parent = (ShortcutAndWidgetContainer) v.getParent();
final CellLayout layout = (CellLayout) parent.getParent();
final Workspace workspace = (Workspace) layout.getParent();
final ViewGroup launcher = (ViewGroup) workspace.getParent();
@@ -819,7 +820,7 @@
* Handles key events for items in a Folder.
*/
static boolean handleFolderKeyEvent(View v, int keyCode, KeyEvent e) {
- CellLayoutChildren parent = (CellLayoutChildren) v.getParent();
+ ShortcutAndWidgetContainer parent = (ShortcutAndWidgetContainer) v.getParent();
final CellLayout layout = (CellLayout) parent.getParent();
final Folder folder = (Folder) layout.getParent();
View title = folder.mFolderName;
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index 07e76c9..6856a09 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -22,6 +22,7 @@
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.InputType;
@@ -35,7 +36,6 @@
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
-import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.inputmethod.EditorInfo;
@@ -148,7 +148,7 @@
super.onFinishInflate();
mContent = (CellLayout) findViewById(R.id.folder_content);
mContent.setGridSize(0, 0);
- mContent.getChildrenLayout().setMotionEventSplittingEnabled(false);
+ mContent.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false);
mFolderName = (FolderEditText) findViewById(R.id.folder_name);
mFolderName.setFolder(this);
mFolderName.setOnFocusChangeListener(this);
@@ -653,6 +653,10 @@
updateItemLocationsInDatabase();
}
+ public boolean supportsFlingToDelete() {
+ return true;
+ }
+
private void updateItemLocationsInDatabase() {
ArrayList<View> list = getItemsInReadingOrder();
for (int i = 0; i < list.size(); i++) {
@@ -731,7 +735,7 @@
mLauncher.getWorkspace().setFinalScrollForPageChange(currentPage);
// We first fetch the currently visible CellLayoutChildren
CellLayout currentLayout = (CellLayout) mLauncher.getWorkspace().getChildAt(currentPage);
- CellLayoutChildren boundingLayout = currentLayout.getChildrenLayout();
+ ShortcutAndWidgetContainer boundingLayout = currentLayout.getShortcutsAndWidgets();
Rect bounds = new Rect();
parent.getDescendantRectRelativeToSelf(boundingLayout, bounds);
// We reset the workspaces scroll
@@ -822,11 +826,11 @@
}
public int getItemCount() {
- return mContent.getChildrenLayout().getChildCount();
+ return mContent.getShortcutsAndWidgets().getChildCount();
}
public View getItemAt(int index) {
- return mContent.getChildrenLayout().getChildAt(index);
+ return mContent.getShortcutsAndWidgets().getChildAt(index);
}
private void onCloseComplete() {
@@ -924,6 +928,10 @@
mInfo.add(item);
}
+ public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
+ // Do nothing
+ }
+
public void onAdd(ShortcutInfo item) {
mItemsInvalidated = true;
// If the item was dropped onto this open folder, we have done the work associated
diff --git a/src/com/android/launcher2/SearchDropTargetBar.java b/src/com/android/launcher2/SearchDropTargetBar.java
index 03ca38f..76d7076 100644
--- a/src/com/android/launcher2/SearchDropTargetBar.java
+++ b/src/com/android/launcher2/SearchDropTargetBar.java
@@ -69,6 +69,7 @@
dragController.addDragListener(mDeleteDropTarget);
dragController.addDropTarget(mInfoDropTarget);
dragController.addDropTarget(mDeleteDropTarget);
+ dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
mInfoDropTarget.setLauncher(launcher);
mDeleteDropTarget.setLauncher(launcher);
}
@@ -153,6 +154,13 @@
});
}
+ public void finishAnimations() {
+ mDropTargetBarFadeInAnim.end();
+ mDropTargetBarFadeOutAnim.end();
+ mQSBSearchBarFadeInAnim.end();
+ mQSBSearchBarFadeOutAnim.end();
+ }
+
private void cancelAnimations() {
mDropTargetBarFadeInAnim.cancel();
mDropTargetBarFadeOutAnim.cancel();
diff --git a/src/com/android/launcher2/CellLayoutChildren.java b/src/com/android/launcher2/ShortcutAndWidgetContainer.java
similarity index 97%
rename from src/com/android/launcher2/CellLayoutChildren.java
rename to src/com/android/launcher2/ShortcutAndWidgetContainer.java
index 4ca44ed..7e5e940 100644
--- a/src/com/android/launcher2/CellLayoutChildren.java
+++ b/src/com/android/launcher2/ShortcutAndWidgetContainer.java
@@ -26,7 +26,7 @@
import com.android.launcher2.CellLayout.LayoutParams;
-public class CellLayoutChildren extends ViewGroup {
+public class ShortcutAndWidgetContainer extends ViewGroup {
static final String TAG = "CellLayoutChildren";
// These are temporary variables to prevent having to allocate a new object just to
@@ -41,7 +41,7 @@
private int mWidthGap;
private int mHeightGap;
- public CellLayoutChildren(Context context) {
+ public ShortcutAndWidgetContainer(Context context) {
super(context);
mWallpaperManager = WallpaperManager.getInstance(context);
}
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 76070c4..8f11612 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -38,6 +38,7 @@
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
@@ -363,7 +364,7 @@
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
CellLayout cl = (CellLayout) getChildAt(i);
- cl.buildChildrenLayer();
+ cl.getShortcutsAndWidgets().buildLayer();
}
}
}
@@ -377,7 +378,7 @@
int count = getChildCount();
for (int i = 0; i < count; i++) {
CellLayout cl = (CellLayout) getPageAt(i);
- cl.getChildrenLayout().animate().alpha(mDragFadeOutAlpha)
+ cl.getShortcutsAndWidgets().animate().alpha(mDragFadeOutAlpha)
.setInterpolator(new AccelerateInterpolator(1.5f))
.setDuration(mDragFadeOutDuration)
.start();
@@ -393,7 +394,7 @@
int count = getChildCount();
for (int i = 0; i < count; i++) {
CellLayout cl = (CellLayout) getPageAt(i);
- cl.getChildrenLayout().animate().alpha(1f)
+ cl.getShortcutsAndWidgets().animate().alpha(1f)
.setInterpolator(new DecelerateInterpolator(1.5f))
.setDuration(mDragFadeOutDuration)
.start();
@@ -722,7 +723,7 @@
// user scrolls while we are transitioning (should not affect dispatchDraw optimizations)
if (!mFadeInAdjacentScreens) {
for (int i = 0; i < getChildCount(); ++i) {
- getPageAt(i).setAlpha(1f);
+ ((CellLayout) getPageAt(i)).setShortcutAndWidgetAlpha(1f);
}
}
@@ -1205,7 +1206,7 @@
cl.setRotationY(rotation);
if (mFadeInAdjacentScreens && !isSmall()) {
float alpha = 1 - Math.abs(scrollProgress);
- cl.setAlpha(alpha);
+ cl.setShortcutAndWidgetAlpha(alpha);
}
}
}
@@ -1657,7 +1658,7 @@
cl.setScaleY(finalScaleFactor);
cl.setBackgroundAlpha(finalBackgroundAlpha);
cl.setBackgroundAlphaMultiplier(finalAlphaMultiplierValue);
- cl.setAlpha(finalAlpha);
+ cl.setShortcutAndWidgetAlpha(finalAlpha);
cl.setRotationY(rotation);
}
}
@@ -1673,7 +1674,7 @@
cl.setScaleY(mNewScaleYs[i]);
cl.setBackgroundAlpha(mNewBackgroundAlphas[i]);
cl.setBackgroundAlphaMultiplier(mNewBackgroundAlphaMultipliers[i]);
- cl.setAlpha(mNewAlphas[i]);
+ cl.setShortcutAndWidgetAlpha(mNewAlphas[i]);
cl.setRotationY(mNewRotationYs[i]);
} else {
LauncherViewPropertyAnimator a = new LauncherViewPropertyAnimator(cl);
@@ -1683,10 +1684,16 @@
.scaleY(mNewScaleYs[i])
.setDuration(duration)
.setInterpolator(mZoomInInterpolator);
- if (mOldAlphas[i] != mNewAlphas[i]) {
- a.alpha(mNewAlphas[i]);
- }
anim.play(a);
+
+ LauncherViewPropertyAnimator alphaAnim =
+ new LauncherViewPropertyAnimator(cl.getShortcutsAndWidgets());
+ if (mOldAlphas[i] != mNewAlphas[i]) {
+ alphaAnim.alpha(mNewAlphas[i])
+ .setDuration(duration)
+ .setInterpolator(mZoomInInterpolator);
+ anim.play(alphaAnim);
+ }
if (mOldRotationYs[i] != 0 || mNewRotationYs[i] != 0) {
ValueAnimator rotate = ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
rotate.setInterpolator(new DecelerateInterpolator(2.0f));
@@ -1755,7 +1762,7 @@
if (!mFadeInAdjacentScreens) {
for (int i = 0; i < getChildCount(); i++) {
final CellLayout cl = (CellLayout) getChildAt(i);
- cl.setAlpha(1f);
+ cl.setShortcutAndWidgetAlpha(1f);
}
}
}
@@ -2333,6 +2340,10 @@
}
}
+ public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
+ // Do nothing
+ }
+
public void setFinalScrollForPageChange(int screen) {
if (screen >= 0) {
mSavedScrollX = getScrollX();
@@ -3075,7 +3086,7 @@
info.spanY, insertAtFirst);
cellLayout.onDropChild(view);
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
- cellLayout.getChildrenLayout().measureChild(view);
+ cellLayout.getShortcutsAndWidgets().measureChild(view);
LauncherModel.addOrMoveItemInDatabase(mLauncher, info, container, screen,
@@ -3314,10 +3325,10 @@
}
private void updateItemLocationsInDatabase(CellLayout cl) {
- int count = cl.getChildrenLayout().getChildCount();
+ int count = cl.getShortcutsAndWidgets().getChildCount();
int screen = indexOfChild(cl);
for (int i = 0; i < count; i++) {
- View v = cl.getChildrenLayout().getChildAt(i);
+ View v = cl.getShortcutsAndWidgets().getChildAt(i);
ItemInfo info = (ItemInfo) v.getTag();
LauncherModel.moveItemInDatabase(mLauncher, info, Favorites.CONTAINER_DESKTOP, screen,
@@ -3325,6 +3336,10 @@
}
}
+ public boolean supportsFlingToDelete() {
+ return true;
+ }
+
public boolean isDropEnabled() {
return true;
}
@@ -3434,7 +3449,7 @@
CellLayout getParentCellLayoutForView(View v) {
ArrayList<CellLayout> layouts = getWorkspaceAndHotseatCellLayouts();
for (CellLayout layout : layouts) {
- if (layout.getChildrenLayout().indexOfChild(v) > -1) {
+ if (layout.getShortcutsAndWidgets().indexOfChild(v) > -1) {
return layout;
}
}
@@ -3458,23 +3473,26 @@
/**
* We should only use this to search for specific children. Do not use this method to modify
- * CellLayoutChildren directly.
+ * ShortcutsAndWidgetsContainer directly. Includes ShortcutAndWidgetContainers from
+ * the hotseat and workspace pages
*/
- ArrayList<CellLayoutChildren> getWorkspaceAndHotseatCellLayoutChildren() {
- ArrayList<CellLayoutChildren> childrenLayouts = new ArrayList<CellLayoutChildren>();
+ ArrayList<ShortcutAndWidgetContainer> getAllShortcutAndWidgetContainers() {
+ ArrayList<ShortcutAndWidgetContainer> childrenLayouts =
+ new ArrayList<ShortcutAndWidgetContainer>();
int screenCount = getChildCount();
for (int screen = 0; screen < screenCount; screen++) {
- childrenLayouts.add(((CellLayout) getChildAt(screen)).getChildrenLayout());
+ childrenLayouts.add(((CellLayout) getChildAt(screen)).getShortcutsAndWidgets());
}
if (mLauncher.getHotseat() != null) {
- childrenLayouts.add(mLauncher.getHotseat().getLayout().getChildrenLayout());
+ childrenLayouts.add(mLauncher.getHotseat().getLayout().getShortcutsAndWidgets());
}
return childrenLayouts;
}
public Folder getFolderForTag(Object tag) {
- ArrayList<CellLayoutChildren> childrenLayouts = getWorkspaceAndHotseatCellLayoutChildren();
- for (CellLayoutChildren layout: childrenLayouts) {
+ ArrayList<ShortcutAndWidgetContainer> childrenLayouts =
+ getAllShortcutAndWidgetContainers();
+ for (ShortcutAndWidgetContainer layout: childrenLayouts) {
int count = layout.getChildCount();
for (int i = 0; i < count; i++) {
View child = layout.getChildAt(i);
@@ -3490,8 +3508,9 @@
}
public View getViewForTag(Object tag) {
- ArrayList<CellLayoutChildren> childrenLayouts = getWorkspaceAndHotseatCellLayoutChildren();
- for (CellLayoutChildren layout: childrenLayouts) {
+ ArrayList<ShortcutAndWidgetContainer> childrenLayouts =
+ getAllShortcutAndWidgetContainers();
+ for (ShortcutAndWidgetContainer layout: childrenLayouts) {
int count = layout.getChildCount();
for (int i = 0; i < count; i++) {
View child = layout.getChildAt(i);
@@ -3504,8 +3523,9 @@
}
void clearDropTargets() {
- ArrayList<CellLayoutChildren> childrenLayouts = getWorkspaceAndHotseatCellLayoutChildren();
- for (CellLayoutChildren layout: childrenLayouts) {
+ ArrayList<ShortcutAndWidgetContainer> childrenLayouts =
+ getAllShortcutAndWidgetContainers();
+ for (ShortcutAndWidgetContainer layout: childrenLayouts) {
int childCount = layout.getChildCount();
for (int j = 0; j < childCount; j++) {
View v = layout.getChildAt(j);
@@ -3527,7 +3547,7 @@
ArrayList<CellLayout> cellLayouts = getWorkspaceAndHotseatCellLayouts();
for (final CellLayout layoutParent: cellLayouts) {
- final ViewGroup layout = layoutParent.getChildrenLayout();
+ final ViewGroup layout = layoutParent.getShortcutsAndWidgets();
// Avoid ANRs by treating each screen separately
post(new Runnable() {
@@ -3613,8 +3633,8 @@
}
void updateShortcuts(ArrayList<ApplicationInfo> apps) {
- ArrayList<CellLayoutChildren> childrenLayouts = getWorkspaceAndHotseatCellLayoutChildren();
- for (CellLayoutChildren layout: childrenLayouts) {
+ ArrayList<ShortcutAndWidgetContainer> childrenLayouts = getAllShortcutAndWidgetContainers();
+ for (ShortcutAndWidgetContainer layout: childrenLayouts) {
int childCount = layout.getChildCount();
for (int j = 0; j < childCount; j++) {
final View view = layout.getChildAt(j);