Moving the state changes during drag-n-drop from startDrag to onDragStart
This will allow drag controller to optinally defer drag, based on some threshold, by simply deferring the callback onDragStart Change-Id: I17c06a15e2092b9797c7e57529b12a53d2acae6e
This commit is contained in:
@@ -54,6 +54,7 @@ import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.config.ProviderConfig;
|
||||
import com.android.launcher3.folder.FolderIcon;
|
||||
import com.android.launcher3.graphics.DragPreviewProvider;
|
||||
import com.android.launcher3.util.CellAndSpan;
|
||||
import com.android.launcher3.util.GridOccupancy;
|
||||
import com.android.launcher3.util.ParcelableSparseArray;
|
||||
@@ -1047,15 +1048,16 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
void visualizeDropLocation(View v, Bitmap dragOutline, int cellX, int cellY, int spanX,
|
||||
int spanY, boolean resize, DropTarget.DragObject dragObject) {
|
||||
void visualizeDropLocation(View v, DragPreviewProvider outlineProvider, int cellX, int cellY,
|
||||
int spanX, int spanY, boolean resize, DropTarget.DragObject dragObject) {
|
||||
final int oldDragCellX = mDragCell[0];
|
||||
final int oldDragCellY = mDragCell[1];
|
||||
|
||||
if (dragOutline == null && v == null) {
|
||||
if (outlineProvider == null || outlineProvider.gerenatedDragOutline == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Bitmap dragOutline = outlineProvider.gerenatedDragOutline;
|
||||
if (cellX != oldDragCellX || cellY != oldDragCellY) {
|
||||
Point dragOffset = dragObject.dragView.getDragVisualizeOffset();
|
||||
Rect dragRegion = dragObject.dragView.getDragRegion();
|
||||
|
||||
@@ -84,7 +84,7 @@ public class HolographicOutlineHelper {
|
||||
applyExpensiveOutlineWithBlur(srcDst, srcDstCanvas, color, outlineColor, true);
|
||||
}
|
||||
|
||||
void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
|
||||
public void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
|
||||
int outlineColor, boolean clipAlpha) {
|
||||
|
||||
// We start by removing most of the alpha channel so as to ignore shadows, and
|
||||
|
||||
@@ -2809,7 +2809,7 @@ public class Launcher extends Activity
|
||||
mDragLayer.onAccessibilityStateChanged(enabled);
|
||||
}
|
||||
|
||||
public void onDragStarted(View view) {
|
||||
public void onDragStarted() {
|
||||
if (isOnCustomContent()) {
|
||||
// Custom content screen doesn't participate in drag and drop. If on custom
|
||||
// content screen, move to default.
|
||||
|
||||
@@ -69,12 +69,12 @@ import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.config.ProviderConfig;
|
||||
import com.android.launcher3.dragndrop.DragController;
|
||||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.graphics.DragPreviewProvider;
|
||||
import com.android.launcher3.dragndrop.DragScroller;
|
||||
import com.android.launcher3.dragndrop.DragView;
|
||||
import com.android.launcher3.dragndrop.SpringLoadedDragController;
|
||||
import com.android.launcher3.folder.Folder;
|
||||
import com.android.launcher3.folder.FolderIcon;
|
||||
import com.android.launcher3.graphics.DragPreviewProvider;
|
||||
import com.android.launcher3.logging.UserEventDispatcher;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutsContainerListener;
|
||||
@@ -247,8 +247,7 @@ public class Workspace extends PagedView
|
||||
/** Is the user is dragging an item near the edge of a page? */
|
||||
private boolean mInScrollArea = false;
|
||||
|
||||
private HolographicOutlineHelper mOutlineHelper;
|
||||
@Thunk Bitmap mDragOutline = null;
|
||||
private DragPreviewProvider mOutlineProvider = null;
|
||||
public static final int DRAG_BITMAP_PADDING = DragPreviewProvider.DRAG_BITMAP_PADDING;
|
||||
private boolean mWorkspaceFadeInAdjacentScreens;
|
||||
|
||||
@@ -343,8 +342,6 @@ public class Workspace extends PagedView
|
||||
public Workspace(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
mOutlineHelper = HolographicOutlineHelper.obtain(context);
|
||||
|
||||
mLauncher = (Launcher) context;
|
||||
mStateTransitionAnimation = new WorkspaceStateTransitionAnimation(mLauncher, this);
|
||||
final Resources res = getResources();
|
||||
@@ -417,7 +414,13 @@ public class Workspace extends PagedView
|
||||
enfoceDragParity("onDragStart", 0, 0);
|
||||
}
|
||||
|
||||
if (mOutlineProvider != null) {
|
||||
// The outline is used to visualize where the item will land if dropped
|
||||
mOutlineProvider.generateDragOutline(mCanvas);
|
||||
}
|
||||
|
||||
updateChildrenLayersEnabled(false);
|
||||
mLauncher.onDragStarted();
|
||||
mLauncher.lockScreenOrientation();
|
||||
mLauncher.onInteractionBegin();
|
||||
// Prevent any Un/InstallShortcutReceivers from updating the db while we are dragging
|
||||
@@ -426,6 +429,27 @@ public class Workspace extends PagedView
|
||||
if (mAddNewPageOnDrag) {
|
||||
mDeferRemoveExtraEmptyScreen = false;
|
||||
addExtraEmptyScreenOnDrag();
|
||||
|
||||
if (source != this && info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET) {
|
||||
// When dragging a widget from different source, move to a page which has
|
||||
// enough space to place this widget (after rearranging/resizing). We special case
|
||||
// widgets as they cannot be placed inside a folder.
|
||||
// Start at the current page and search right (on LTR) until finding a page with
|
||||
// enough space. Since an empty screen is the furthest right, a page must be found.
|
||||
int currentPage = getPageNearestToCenterOfScreen();
|
||||
for (int pageIndex = currentPage; pageIndex < getPageCount(); pageIndex++) {
|
||||
CellLayout page = (CellLayout) getPageAt(pageIndex);
|
||||
if (page.hasReorderSolution(info)) {
|
||||
setCurrentPage(pageIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!FeatureFlags.LAUNCHER3_LEGACY_WORKSPACE_DND) {
|
||||
// Always enter the spring loaded mode
|
||||
mLauncher.enterSpringLoadedDragMode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1999,23 +2023,8 @@ public class Workspace extends PagedView
|
||||
position[0], position[1], 0, null);
|
||||
}
|
||||
|
||||
public void onDragStartedWithItem(PendingAddItemInfo info, Bitmap b, boolean clipAlpha) {
|
||||
// Find a page that has enough space to place this widget (after rearranging/resizing).
|
||||
// Start at the current page and search right (on LTR) until finding a page with enough
|
||||
// space. Since an empty screen is the furthest right, a page must be found.
|
||||
int currentPageInOverview = getPageNearestToCenterOfScreen();
|
||||
for (int pageIndex = currentPageInOverview; pageIndex < getPageCount(); pageIndex++) {
|
||||
CellLayout page = (CellLayout) getPageAt(pageIndex);
|
||||
if (page.hasReorderSolution(info)) {
|
||||
setCurrentPage(pageIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int[] size = estimateItemSize(info, false);
|
||||
|
||||
// The outline is used to visualize where the item will land if dropped
|
||||
mDragOutline = createDragOutline(b, DRAG_BITMAP_PADDING, size[0], size[1], clipAlpha);
|
||||
public void prepareDragWithProvider(DragPreviewProvider outlineProvider) {
|
||||
mOutlineProvider = outlineProvider;
|
||||
}
|
||||
|
||||
public void exitWidgetResizeMode() {
|
||||
@@ -2271,34 +2280,6 @@ public class Workspace extends PagedView
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new bitmap to be used as the object outline, e.g. to visualize the drop location.
|
||||
* Responsibility for the bitmap is transferred to the caller.
|
||||
*/
|
||||
private Bitmap createDragOutline(Bitmap orig, int padding, int w, int h,
|
||||
boolean clipAlpha) {
|
||||
final int outlineColor = getResources().getColor(R.color.outline_color);
|
||||
final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||
mCanvas.setBitmap(b);
|
||||
|
||||
Rect src = new Rect(0, 0, orig.getWidth(), orig.getHeight());
|
||||
float scaleFactor = Math.min((w - padding) / (float) orig.getWidth(),
|
||||
(h - padding) / (float) orig.getHeight());
|
||||
int scaledWidth = (int) (scaleFactor * orig.getWidth());
|
||||
int scaledHeight = (int) (scaleFactor * orig.getHeight());
|
||||
Rect dst = new Rect(0, 0, scaledWidth, scaledHeight);
|
||||
|
||||
// center the image
|
||||
dst.offset((w - scaledWidth) / 2, (h - scaledHeight) / 2);
|
||||
|
||||
mCanvas.drawBitmap(orig, src, dst, null);
|
||||
mOutlineHelper.applyExpensiveOutlineWithBlur(b, mCanvas, outlineColor, outlineColor,
|
||||
clipAlpha);
|
||||
mCanvas.setBitmap(null);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
public void startDrag(CellLayout.CellInfo cellInfo) {
|
||||
startDrag(cellInfo, false);
|
||||
}
|
||||
@@ -2337,11 +2318,8 @@ public class Workspace extends PagedView
|
||||
ItemInfo dragObject, DragPreviewProvider previewProvider) {
|
||||
child.clearFocus();
|
||||
child.setPressed(false);
|
||||
mOutlineProvider = previewProvider;
|
||||
|
||||
// The outline is used to visualize where the item will land if dropped
|
||||
mDragOutline = previewProvider.createDragOutline(mCanvas);
|
||||
|
||||
mLauncher.onDragStarted(child);
|
||||
// The drag bitmap follows the touch point around on the screen
|
||||
final Bitmap b = previewProvider.createDragBitmap(mCanvas);
|
||||
int halfPadding = previewProvider.previewPadding / 2;
|
||||
@@ -2384,12 +2362,7 @@ public class Workspace extends PagedView
|
||||
dragObject, DragController.DRAG_ACTION_MOVE, dragVisualizeOffset,
|
||||
dragRect, scale, accessible);
|
||||
dv.setIntrinsicIconScaleFactor(source.getIntrinsicIconScaleFactor());
|
||||
|
||||
b.recycle();
|
||||
|
||||
if (!FeatureFlags.LAUNCHER3_LEGACY_WORKSPACE_DND) {
|
||||
mLauncher.enterSpringLoadedDragMode();
|
||||
}
|
||||
return dv;
|
||||
}
|
||||
|
||||
@@ -3180,7 +3153,7 @@ public class Workspace extends PagedView
|
||||
item.spanY, child, mTargetCell);
|
||||
|
||||
if (!nearestDropOccupied) {
|
||||
mDragTargetLayout.visualizeDropLocation(child, mDragOutline,
|
||||
mDragTargetLayout.visualizeDropLocation(child, mOutlineProvider,
|
||||
mTargetCell[0], mTargetCell[1], item.spanX, item.spanY, false, d);
|
||||
} else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
|
||||
&& !mReorderAlarm.alarmPending() && (mLastReorderX != reorderX ||
|
||||
@@ -3325,7 +3298,7 @@ public class Workspace extends PagedView
|
||||
}
|
||||
|
||||
boolean resize = resultSpan[0] != spanX || resultSpan[1] != spanY;
|
||||
mDragTargetLayout.visualizeDropLocation(child, mDragOutline,
|
||||
mDragTargetLayout.visualizeDropLocation(child, mOutlineProvider,
|
||||
mTargetCell[0], mTargetCell[1], resultSpan[0], resultSpan[1], resize, dragObject);
|
||||
}
|
||||
}
|
||||
@@ -3716,7 +3689,7 @@ public class Workspace extends PagedView
|
||||
&& mDragInfo.cell != null) {
|
||||
mDragInfo.cell.setVisibility(VISIBLE);
|
||||
}
|
||||
mDragOutline = null;
|
||||
mOutlineProvider = null;
|
||||
mDragInfo = null;
|
||||
|
||||
if (!isFlingToDelete) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.PreloadIconDrawable;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.config.ProviderConfig;
|
||||
import com.android.launcher3.folder.FolderIcon;
|
||||
|
||||
/**
|
||||
@@ -45,6 +46,8 @@ public class DragPreviewProvider {
|
||||
// The padding added to the drag view during the preview generation.
|
||||
public final int previewPadding;
|
||||
|
||||
public Bitmap gerenatedDragOutline;
|
||||
|
||||
public DragPreviewProvider(View view) {
|
||||
mView = view;
|
||||
|
||||
@@ -118,6 +121,14 @@ public class DragPreviewProvider {
|
||||
return b;
|
||||
}
|
||||
|
||||
public final void generateDragOutline(Canvas canvas) {
|
||||
if (ProviderConfig.IS_DOGFOOD_BUILD && gerenatedDragOutline != null) {
|
||||
throw new RuntimeException("Drag outline generated twice");
|
||||
}
|
||||
|
||||
gerenatedDragOutline = createDragOutline(canvas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new bitmap to be used as the object outline, e.g. to visualize the drop location.
|
||||
* Responsibility for the bitmap is transferred to the caller.
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3.widget;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.HolographicOutlineHelper;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.PendingAddItemInfo;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.graphics.DragPreviewProvider;
|
||||
|
||||
/**
|
||||
* Extension of {@link DragPreviewProvider} with logic specific to pending widgets/shortcuts
|
||||
* dragged from the widget tray.
|
||||
*/
|
||||
public class PendingItemPreviewProvider extends DragPreviewProvider {
|
||||
|
||||
private final PendingAddItemInfo mAddInfo;
|
||||
private final Bitmap mPreviewBitmap;
|
||||
|
||||
public PendingItemPreviewProvider(View view, PendingAddItemInfo addInfo, Bitmap preview) {
|
||||
super(view);
|
||||
mAddInfo = addInfo;
|
||||
mPreviewBitmap = preview;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap createDragOutline(Canvas canvas) {
|
||||
Workspace workspace = Launcher.getLauncher(mView.getContext()).getWorkspace();
|
||||
int[] size = workspace.estimateItemSize(mAddInfo, false);
|
||||
|
||||
int w = size[0];
|
||||
int h = size[1];
|
||||
final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||
canvas.setBitmap(b);
|
||||
|
||||
Rect src = new Rect(0, 0, mPreviewBitmap.getWidth(), mPreviewBitmap.getHeight());
|
||||
float scaleFactor = Math.min((w - DRAG_BITMAP_PADDING) / (float) mPreviewBitmap.getWidth(),
|
||||
(h - DRAG_BITMAP_PADDING) / (float) mPreviewBitmap.getHeight());
|
||||
int scaledWidth = (int) (scaleFactor * mPreviewBitmap.getWidth());
|
||||
int scaledHeight = (int) (scaleFactor * mPreviewBitmap.getHeight());
|
||||
Rect dst = new Rect(0, 0, scaledWidth, scaledHeight);
|
||||
|
||||
// center the image
|
||||
dst.offset((w - scaledWidth) / 2, (h - scaledHeight) / 2);
|
||||
|
||||
canvas.drawBitmap(mPreviewBitmap, src, dst, null);
|
||||
|
||||
// Don't clip alpha values for the drag outline if we're using the default widget preview
|
||||
boolean clipAlpha = !(mAddInfo instanceof PendingAddWidgetInfo &&
|
||||
(((PendingAddWidgetInfo) mAddInfo).previewImage == 0));
|
||||
final int outlineColor = mView.getResources().getColor(R.color.outline_color);
|
||||
HolographicOutlineHelper.obtain(mView.getContext())
|
||||
.applyExpensiveOutlineWithBlur(b, canvas, outlineColor, outlineColor, clipAlpha);
|
||||
canvas.setBitmap(null);
|
||||
|
||||
return b;
|
||||
}
|
||||
}
|
||||
@@ -205,7 +205,7 @@ public class WidgetsContainerView extends BaseContainerView
|
||||
|
||||
// Compose the drag image
|
||||
Bitmap preview;
|
||||
float scale = 1f;
|
||||
final float scale;
|
||||
final Rect bounds = image.getBitmapBounds();
|
||||
|
||||
if (createItemInfo instanceof PendingAddWidgetInfo) {
|
||||
@@ -242,19 +242,14 @@ public class WidgetsContainerView extends BaseContainerView
|
||||
scale = ((float) mLauncher.getDeviceProfile().iconSizePx) / preview.getWidth();
|
||||
}
|
||||
|
||||
// Don't clip alpha values for the drag outline if we're using the default widget preview
|
||||
boolean clipAlpha = !(createItemInfo instanceof PendingAddWidgetInfo &&
|
||||
(((PendingAddWidgetInfo) createItemInfo).previewImage == 0));
|
||||
// Since we are not going through the workspace for starting the drag, set drag related
|
||||
// information on the workspace before starting the drag.
|
||||
mLauncher.getWorkspace().prepareDragWithProvider(
|
||||
new PendingItemPreviewProvider(v, createItemInfo, preview));
|
||||
|
||||
// Start the drag
|
||||
mLauncher.lockScreenOrientation();
|
||||
mDragController.startDrag(image, preview, this, createItemInfo,
|
||||
bounds, DragController.DRAG_ACTION_COPY, scale);
|
||||
// This call expects the extra empty screen to already be created, which is why we call it
|
||||
// after mDragController.startDrag().
|
||||
mLauncher.getWorkspace().onDragStartedWithItem(createItemInfo, preview, clipAlpha);
|
||||
|
||||
preview.recycle();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user