diff options
Diffstat (limited to 'src/com/android/launcher3/CellLayout.java')
-rw-r--r-- | src/com/android/launcher3/CellLayout.java | 216 |
1 files changed, 127 insertions, 89 deletions
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index d48873762..b8b41443e 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -18,14 +18,12 @@ package com.android.launcher3; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.animation.AnimatorSet; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.annotation.TargetApi; import android.content.Context; import android.content.res.Resources; -import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; @@ -52,9 +50,12 @@ import android.widget.Toast; import com.android.launcher3.BubbleTextView.BubbleTextShadowHandler; import com.android.launcher3.FolderIcon.FolderRingAnimator; +import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.accessibility.DragAndDropAccessibilityDelegate; import com.android.launcher3.accessibility.FolderAccessibilityHelper; import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper; +import com.android.launcher3.config.ProviderConfig; +import com.android.launcher3.util.ParcelableSparseArray; import com.android.launcher3.util.Thunk; import java.util.ArrayList; @@ -86,6 +87,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { private int mMaxGap; private boolean mDropPending = false; private boolean mIsDragTarget = true; + private boolean mJailContent = true; // These are temporary variables to prevent having to allocate a new object just to // return an (x, y) value from helper functions. Do NOT use them to maintain other state. @@ -189,7 +191,6 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { mLauncher = (Launcher) context; DeviceProfile grid = mLauncher.getDeviceProfile(); - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyle, 0); mCellWidth = mCellHeight = -1; mFixedCellWidth = mFixedCellHeight = -1; @@ -203,10 +204,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { mPreviousReorderDirection[0] = INVALID_DIRECTION; mPreviousReorderDirection[1] = INVALID_DIRECTION; - a.recycle(); - setAlwaysDrawnWithCacheEnabled(false); - final Resources res = getResources(); mHotseatScale = (float) grid.hotseatIconSizePx / grid.iconSizePx; @@ -278,7 +276,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap, mCountX, mCountY); - mStylusEventHelper = new StylusEventHelper(this); + mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); mTouchFeedbackView = new ClickShadowView(context); addView(mTouchFeedbackView); @@ -340,7 +338,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { // enabled to allow rearranging the different home screens. So check what mode // the workspace is in, and only perform stylus button presses while in overview mode. if (mLauncher.mWorkspace.isInOverviewMode() - && mStylusEventHelper.checkAndPerformStylusEvent(ev)) { + && mStylusEventHelper.onMotionEvent(ev)) { return true; } return handled; @@ -406,7 +404,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { mIsDragTarget = false; } - boolean isDragTarget() { + public boolean isDragTarget() { return mIsDragTarget; } @@ -426,7 +424,33 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { } } - boolean getIsDragOverlapping() { + public void disableJailContent() { + mJailContent = false; + } + + @Override + protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) { + if (mJailContent) { + ParcelableSparseArray jail = getJailedArray(container); + super.dispatchSaveInstanceState(jail); + container.put(R.id.cell_layout_jail_id, jail); + } else { + super.dispatchSaveInstanceState(container); + } + } + + @Override + protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) { + super.dispatchRestoreInstanceState(mJailContent ? getJailedArray(container) : container); + } + + private ParcelableSparseArray getJailedArray(SparseArray<Parcelable> container) { + final Parcelable parcelable = container.get(R.id.cell_layout_jail_id); + return parcelable instanceof ParcelableSparseArray ? + (ParcelableSparseArray) parcelable : new ParcelableSparseArray(); + } + + public boolean getIsDragOverlapping() { return mIsDragOverlapping; } @@ -449,12 +473,9 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { for (int i = 0; i < mDragOutlines.length; i++) { final float alpha = mDragOutlineAlphas[i]; if (alpha > 0) { - final Rect r = mDragOutlines[i]; - mTempRect.set(r); - Utilities.scaleRectAboutCenter(mTempRect, getChildrenScale()); final Bitmap b = (Bitmap) mDragOutlineAnims[i].getTag(); paint.setAlpha((int)(alpha + .5f)); - canvas.drawBitmap(b, null, mTempRect, paint); + canvas.drawBitmap(b, null, mDragOutlines[i], paint); } } @@ -569,7 +590,7 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { try { dispatchRestoreInstanceState(states); } catch (IllegalArgumentException ex) { - if (LauncherAppState.isDogfoodBuild()) { + if (ProviderConfig.IS_DOGFOOD_BUILD) { throw ex; } // Mismatched viewId / viewType preventing restore. Skip restore on production builds. @@ -1032,53 +1053,57 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { if (cellX != oldDragCellX || cellY != oldDragCellY) { mDragCell[0] = cellX; mDragCell[1] = cellY; - // Find the top left corner of the rect the object will occupy - final int[] topLeft = mTmpPoint; - cellToPoint(cellX, cellY, topLeft); - - int left = topLeft[0]; - int top = topLeft[1]; - - if (v != null && dragOffset == null) { - // When drawing the drag outline, it did not account for margin offsets - // added by the view's parent. - MarginLayoutParams lp = (MarginLayoutParams) v.getLayoutParams(); - left += lp.leftMargin; - top += lp.topMargin; - - // Offsets due to the size difference between the View and the dragOutline. - // There is a size difference to account for the outer blur, which may lie - // outside the bounds of the view. - top += (v.getHeight() - dragOutline.getHeight()) / 2; - // We center about the x axis - left += ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap) - - dragOutline.getWidth()) / 2; - } else { - if (dragOffset != null && dragRegion != null) { - // Center the drag region *horizontally* in the cell and apply a drag - // outline offset - left += dragOffset.x + ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap) - - dragRegion.width()) / 2; - int cHeight = getShortcutsAndWidgets().getCellContentHeight(); - int cellPaddingY = (int) Math.max(0, ((mCellHeight - cHeight) / 2f)); - top += dragOffset.y + cellPaddingY; - } else { - // Center the drag outline in the cell - left += ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap) - - dragOutline.getWidth()) / 2; - top += ((mCellHeight * spanY) + ((spanY - 1) * mHeightGap) - - dragOutline.getHeight()) / 2; - } - } + final int oldIndex = mDragOutlineCurrent; mDragOutlineAnims[oldIndex].animateOut(); mDragOutlineCurrent = (oldIndex + 1) % mDragOutlines.length; Rect r = mDragOutlines[mDragOutlineCurrent]; - r.set(left, top, left + dragOutline.getWidth(), top + dragOutline.getHeight()); + if (resize) { cellToRect(cellX, cellY, spanX, spanY, r); + } else { + // Find the top left corner of the rect the object will occupy + final int[] topLeft = mTmpPoint; + cellToPoint(cellX, cellY, topLeft); + + int left = topLeft[0]; + int top = topLeft[1]; + + if (v != null && dragOffset == null) { + // When drawing the drag outline, it did not account for margin offsets + // added by the view's parent. + MarginLayoutParams lp = (MarginLayoutParams) v.getLayoutParams(); + left += lp.leftMargin; + top += lp.topMargin; + + // Offsets due to the size difference between the View and the dragOutline. + // There is a size difference to account for the outer blur, which may lie + // outside the bounds of the view. + top += (v.getHeight() - dragOutline.getHeight()) / 2; + // We center about the x axis + left += ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap) + - dragOutline.getWidth()) / 2; + } else { + if (dragOffset != null && dragRegion != null) { + // Center the drag region *horizontally* in the cell and apply a drag + // outline offset + left += dragOffset.x + ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap) + - dragRegion.width()) / 2; + int cHeight = getShortcutsAndWidgets().getCellContentHeight(); + int cellPaddingY = (int) Math.max(0, ((mCellHeight - cHeight) / 2f)); + top += dragOffset.y + cellPaddingY; + } else { + // Center the drag outline in the cell + left += ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap) + - dragOutline.getWidth()) / 2; + top += ((mCellHeight * spanY) + ((spanY - 1) * mHeightGap) + - dragOutline.getHeight()) / 2; + } + } + r.set(left, top, left + dragOutline.getWidth(), top + dragOutline.getHeight()); } + Utilities.scaleRectAboutCenter(r, getChildrenScale()); mDragOutlineAnims[mDragOutlineCurrent].setTag(dragOutline); mDragOutlineAnims[mDragOutlineCurrent].animateIn(); } @@ -1096,23 +1121,6 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { * * @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 spanX Horizontal span of the object. - * @param spanY Vertical span of the object. - * @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. - */ - int[] findNearestVacantArea(int pixelX, int pixelY, int spanX, int spanY, int[] result) { - return findNearestVacantArea(pixelX, pixelY, spanX, spanY, spanX, spanY, result, null); - } - - /** - * Find a vacant area that will fit the given bounds nearest the requested - * cell location. Uses Euclidean distance to score multiple vacant areas. - * - * @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 spanX Horizontal span of the object. @@ -2187,17 +2195,14 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { a.cancel(); } - AnimatorSet s = LauncherAnimUtils.createAnimatorSet(); - a = s; - s.playTogether( - LauncherAnimUtils.ofFloat(child, "scaleX", getChildrenScale()), - LauncherAnimUtils.ofFloat(child, "scaleY", getChildrenScale()), - LauncherAnimUtils.ofFloat(child, "translationX", 0f), - LauncherAnimUtils.ofFloat(child, "translationY", 0f) - ); - s.setDuration(REORDER_ANIMATION_DURATION); - s.setInterpolator(new android.view.animation.DecelerateInterpolator(1.5f)); - s.start(); + a = new LauncherViewPropertyAnimator(child) + .scaleX(getChildrenScale()) + .scaleY(getChildrenScale()) + .translationX(0) + .translationY(0) + .setDuration(REORDER_ANIMATION_DURATION); + a.setInterpolator(new android.view.animation.DecelerateInterpolator(1.5f)); + a.start(); } } @@ -2214,6 +2219,15 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { mOccupied[i][j] = mTmpOccupied[i][j]; } } + + long screenId = mLauncher.getWorkspace().getIdForScreen(this); + int container = Favorites.CONTAINER_DESKTOP; + + if (mLauncher.isHotseatLayout(this)) { + screenId = -1; + container = Favorites.CONTAINER_HOTSEAT; + } + int childCount = mShortcutsAndWidgets.getChildCount(); for (int i = 0; i < childCount; i++) { View child = mShortcutsAndWidgets.getChildAt(i); @@ -2222,17 +2236,21 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { // We do a null check here because the item info can be null in the case of the // AllApps button in the hotseat. if (info != null) { - if (info.cellX != lp.tmpCellX || info.cellY != lp.tmpCellY || - info.spanX != lp.cellHSpan || info.spanY != lp.cellVSpan) { - info.requiresDbUpdate = true; - } + final boolean requiresDbUpdate = (info.cellX != lp.tmpCellX + || info.cellY != lp.tmpCellY || info.spanX != lp.cellHSpan + || info.spanY != lp.cellVSpan); + info.cellX = lp.cellX = lp.tmpCellX; info.cellY = lp.cellY = lp.tmpCellY; info.spanX = lp.cellHSpan; info.spanY = lp.cellVSpan; + + if (requiresDbUpdate) { + LauncherModel.modifyItemInDatabase(mLauncher, info, container, screenId, + info.cellX, info.cellY, info.spanX, info.spanY); + } } } - mLauncher.getWorkspace().updateItemLocationsInDatabase(this); } private void setUseTempCoords(boolean useTempCoords) { @@ -2820,10 +2838,10 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { // X coordinate of the view in the layout. @ViewDebug.ExportedProperty - int x; + public int x; // Y coordinate of the view in the layout. @ViewDebug.ExportedProperty - int y; + public int y; boolean dropped; @@ -2949,6 +2967,26 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler { 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; |