From 94b510cc683a6436ae82c6d323cbd8b429561b06 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 16 Aug 2016 15:36:48 -0700 Subject: Some drag and drop code refactor: 1) Adding DragOptions to easily extend drap functionality 2) Changing onDragStarted signature to send more information 3) Updating states for dropTargetButton based on drag event directly 4) Removing folder item based on onDragStarted and not startDrag Change-Id: I65b684e092ddc081d086bfe2c8c1973ed170eaeb --- src/com/android/launcher3/ButtonDropTarget.java | 14 ++-- src/com/android/launcher3/DeleteDropTarget.java | 7 +- src/com/android/launcher3/DropTargetBar.java | 9 +-- src/com/android/launcher3/Launcher.java | 3 +- src/com/android/launcher3/Workspace.java | 83 ++++++++++------------ .../AccessibileDragListenerAdapter.java | 66 +++++++++++++++++ .../LauncherAccessibilityDelegate.java | 36 ++++------ .../launcher3/allapps/AllAppsContainerView.java | 3 +- .../launcher3/dragndrop/DragController.java | 71 ++++++------------ .../android/launcher3/dragndrop/DragOptions.java | 26 +++++++ src/com/android/launcher3/folder/Folder.java | 65 +++++++++-------- .../shortcuts/DeepShortcutsContainer.java | 7 +- .../launcher3/widget/WidgetHostViewLoader.java | 4 +- .../launcher3/widget/WidgetsContainerView.java | 3 +- 14 files changed, 224 insertions(+), 173 deletions(-) create mode 100644 src/com/android/launcher3/accessibility/AccessibileDragListenerAdapter.java create mode 100644 src/com/android/launcher3/dragndrop/DragOptions.java (limited to 'src/com/android') diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java index 0f6073eee..2dde7caa6 100644 --- a/src/com/android/launcher3/ButtonDropTarget.java +++ b/src/com/android/launcher3/ButtonDropTarget.java @@ -43,6 +43,7 @@ import android.widget.TextView; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.util.Thunk; @@ -199,8 +200,8 @@ public abstract class ButtonDropTarget extends TextView } @Override - public void onDragStart(DragSource source, ItemInfo info, int dragAction) { - mActive = supportsDrop(source, info); + public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { + mActive = supportsDrop(dragObject.dragSource, dragObject.dragInfo); mDrawable.setColorFilter(null); if (mCurrentColorAnim != null) { mCurrentColorAnim.cancel(); @@ -209,6 +210,9 @@ public abstract class ButtonDropTarget extends TextView setTextColor(mOriginalTextColor); (mHideParentOnDisable ? ((ViewGroup) getParent()) : this) .setVisibility(mActive ? View.VISIBLE : View.GONE); + + mAccessibleDrag = options.isAccessibleDrag; + setOnClickListener(mAccessibleDrag ? this : null); } @Override @@ -227,6 +231,7 @@ public abstract class ButtonDropTarget extends TextView @Override public void onDragEnd() { mActive = false; + setOnClickListener(null); } /** @@ -308,11 +313,6 @@ public abstract class ButtonDropTarget extends TextView return to; } - public void enableAccessibleDrag(boolean enable) { - mAccessibleDrag = enable; - setOnClickListener(enable ? this : null); - } - @Override public void onClick(View v) { mLauncher.getAccessibilityDelegate().handleAccessibleDrop(this, null, null); diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java index f24e00b5c..705f84101 100644 --- a/src/com/android/launcher3/DeleteDropTarget.java +++ b/src/com/android/launcher3/DeleteDropTarget.java @@ -25,6 +25,7 @@ import android.view.View; import android.view.animation.AnimationUtils; import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.folder.Folder; import com.android.launcher3.util.FlingAnimation; import com.android.launcher3.util.Thunk; @@ -49,9 +50,9 @@ public class DeleteDropTarget extends ButtonDropTarget { } @Override - public void onDragStart(DragSource source, ItemInfo info, int dragAction) { - super.onDragStart(source, info, dragAction); - setTextBasedOnDragSource(source); + public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { + super.onDragStart(dragObject, options); + setTextBasedOnDragSource(dragObject.dragSource); } /** @return true for items that should have a "Remove" action in accessibility. */ diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java index 5966af51c..42bab4705 100644 --- a/src/com/android/launcher3/DropTargetBar.java +++ b/src/com/android/launcher3/DropTargetBar.java @@ -27,6 +27,7 @@ import android.view.animation.AccelerateInterpolator; import android.widget.LinearLayout; import com.android.launcher3.dragndrop.DragController; +import com.android.launcher3.dragndrop.DragOptions; /* * The top bar containing various drop targets: Delete/App Info/Uninstall. @@ -120,17 +121,11 @@ public class DropTargetBar extends LinearLayout implements DragController.DragLi } } - public void enableAccessibleDrag(boolean enable) { - mDeleteDropTarget.enableAccessibleDrag(enable); - mAppInfoDropTarget.enableAccessibleDrag(enable); - mUninstallDropTarget.enableAccessibleDrag(enable); - } - /* * DragController.DragListener implementation */ @Override - public void onDragStart(DragSource source, ItemInfo info, int dragAction) { + public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { animateToVisibility(true); } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index c919db8b7..7bcd63172 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -102,6 +102,7 @@ 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.dragndrop.DragOptions; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.dynamicui.ExtractedColors; import com.android.launcher3.folder.Folder; @@ -3222,7 +3223,7 @@ public class Launcher extends Activity longClickCellInfo.cellX, longClickCellInfo.cellY)); if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) { // User long pressed on an item - mWorkspace.startDrag(longClickCellInfo); + mWorkspace.startDrag(longClickCellInfo, new DragOptions()); } } } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 66745abab..947aa5062 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -59,7 +59,7 @@ import android.widget.TextView; import com.android.launcher3.Launcher.CustomContentCallbacks; import com.android.launcher3.Launcher.LauncherOverlay; import com.android.launcher3.UninstallDropTarget.DropTargetSource; -import com.android.launcher3.accessibility.LauncherAccessibilityDelegate.AccessibilityDragSource; +import com.android.launcher3.accessibility.AccessibileDragListenerAdapter; import com.android.launcher3.accessibility.OverviewAccessibilityDelegate; import com.android.launcher3.accessibility.OverviewScreenAccessibilityDelegate; import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper; @@ -69,6 +69,7 @@ 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.dragndrop.DragOptions; import com.android.launcher3.dragndrop.DragScroller; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.dragndrop.SpringLoadedDragController; @@ -100,7 +101,7 @@ import java.util.HashSet; public class Workspace extends PagedView implements DropTarget, DragSource, DragScroller, View.OnTouchListener, DragController.DragListener, LauncherTransitionable, ViewGroup.OnHierarchyChangeListener, - Insettable, DropTargetSource, AccessibilityDragSource { + Insettable, DropTargetSource { private static final String TAG = "Launcher.Workspace"; private static boolean ENFORCE_DRAG_EVENT_ORDER = false; @@ -134,7 +135,6 @@ public class Workspace extends PagedView @Thunk Runnable mRemoveEmptyScreenRunnable; @Thunk boolean mDeferRemoveExtraEmptyScreen = false; - @Thunk boolean mAddNewPageOnDrag = true; /** * CellInfo for the cell that is currently being dragged @@ -409,7 +409,7 @@ public class Workspace extends PagedView } @Override - public void onDragStart(final DragSource source, ItemInfo info, int dragAction) { + public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { if (ENFORCE_DRAG_EVENT_ORDER) { enfoceDragParity("onDragStart", 0, 0); } @@ -426,11 +426,19 @@ public class Workspace extends PagedView // Prevent any Un/InstallShortcutReceivers from updating the db while we are dragging InstallShortcutReceiver.enableInstallQueue(); - if (mAddNewPageOnDrag) { + // Do not add a new page if it is a accessible drag which was not started by the workspace. + // We do not support accessibility drag from other sources and instead provide a direct + // action for move/add to homescreen. + // When a accessible drag is started by the folder, we only allow rearranging withing the + // folder. + boolean addNewPage = !(options.isAccessibleDrag && dragObject.dragSource != this); + + if (addNewPage) { mDeferRemoveExtraEmptyScreen = false; addExtraEmptyScreenOnDrag(); - if (source != this && info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET) { + if (dragObject.dragInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET + && dragObject.dragSource != this) { // 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. @@ -439,7 +447,7 @@ public class Workspace extends PagedView int currentPage = getPageNearestToCenterOfScreen(); for (int pageIndex = currentPage; pageIndex < getPageCount(); pageIndex++) { CellLayout page = (CellLayout) getPageAt(pageIndex); - if (page.hasReorderSolution(info)) { + if (page.hasReorderSolution(dragObject.dragInfo)) { setCurrentPage(pageIndex); break; } @@ -453,10 +461,6 @@ public class Workspace extends PagedView } } - public void setAddNewPageOnDrag(boolean addPage) { - mAddNewPageOnDrag = addPage; - } - public void deferRemoveExtraEmptyScreen() { mDeferRemoveExtraEmptyScreen = true; } @@ -1722,26 +1726,6 @@ public class Workspace extends PagedView } } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - @Override - public void enableAccessibleDrag(boolean enable) { - for (int i = 0; i < getChildCount(); i++) { - CellLayout child = (CellLayout) getChildAt(i); - child.enableAccessibleDrag(enable, CellLayout.WORKSPACE_ACCESSIBILITY_DRAG); - } - - if (enable) { - // We need to allow our individual children to become click handlers in this case - setOnClickListener(null); - } else { - // Reset our click listener - setOnClickListener(mLauncher); - } - mLauncher.getDropTargetBar().enableAccessibleDrag(enable); - mLauncher.getHotseat().getLayout() - .enableAccessibleDrag(enable, CellLayout.WORKSPACE_ACCESSIBILITY_DRAG); - } - public boolean hasCustomContent() { return (mScreenOrder.size() > 0 && mScreenOrder.get(0) == CUSTOM_CONTENT_SCREEN_ID); } @@ -2280,12 +2264,7 @@ public class Workspace extends PagedView return null; } - public void startDrag(CellLayout.CellInfo cellInfo) { - startDrag(cellInfo, false); - } - - @Override - public void startDrag(CellLayout.CellInfo cellInfo, boolean accessible) { + public void startDrag(CellLayout.CellInfo cellInfo, DragOptions options) { View child = cellInfo.cell; // Make sure the drag was started by a long press as opposed to a long click. @@ -2298,10 +2277,25 @@ public class Workspace extends PagedView CellLayout layout = (CellLayout) child.getParent().getParent(); layout.prepareChildForDrag(child); - beginDragShared(child, this, accessible); + if (options.isAccessibleDrag) { + mDragController.addDragListener(new AccessibileDragListenerAdapter( + this, CellLayout.WORKSPACE_ACCESSIBILITY_DRAG) { + @Override + protected void enableAccessibleDrag(boolean enable) { + super.enableAccessibleDrag(enable); + setEnableForLayout(mLauncher.getHotseat().getLayout(),enable); + + // We need to allow our individual children to become click handlers in this + // case, so temporarily unset the click handlers. + setOnClickListener(enable ? null : mLauncher); + } + }); + } + + beginDragShared(child, this, options); } - public void beginDragShared(View child, DragSource source, boolean accessible) { + public void beginDragShared(View child, DragSource source, DragOptions options) { Object dragObject = child.getTag(); if (!(dragObject instanceof ItemInfo)) { String msg = "Drag started with a view that has no tag set. This " @@ -2309,13 +2303,13 @@ public class Workspace extends PagedView + "View: " + child + " tag: " + child.getTag(); throw new IllegalStateException(msg); } - beginDragShared(child, source, accessible, (ItemInfo) dragObject, - new DragPreviewProvider(child)); + beginDragShared(child, source, (ItemInfo) dragObject, + new DragPreviewProvider(child), options); } - public DragView beginDragShared(View child, DragSource source, boolean accessible, - ItemInfo dragObject, DragPreviewProvider previewProvider) { + public DragView beginDragShared(View child, DragSource source, ItemInfo dragObject, + DragPreviewProvider previewProvider, DragOptions dragOptions) { child.clearFocus(); child.setPressed(false); mOutlineProvider = previewProvider; @@ -2359,8 +2353,7 @@ public class Workspace extends PagedView } DragView dv = mDragController.startDrag(b, dragLayerX, dragLayerY, source, - dragObject, DragController.DRAG_ACTION_MOVE, dragVisualizeOffset, - dragRect, scale, accessible); + dragObject, dragVisualizeOffset, dragRect, scale, dragOptions); dv.setIntrinsicIconScaleFactor(source.getIntrinsicIconScaleFactor()); b.recycle(); return dv; diff --git a/src/com/android/launcher3/accessibility/AccessibileDragListenerAdapter.java b/src/com/android/launcher3/accessibility/AccessibileDragListenerAdapter.java new file mode 100644 index 000000000..62a9a6d19 --- /dev/null +++ b/src/com/android/launcher3/accessibility/AccessibileDragListenerAdapter.java @@ -0,0 +1,66 @@ +/* + * 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.accessibility; + +import android.view.ViewGroup; + +import com.android.launcher3.CellLayout; +import com.android.launcher3.DropTarget.DragObject; +import com.android.launcher3.Launcher; +import com.android.launcher3.dragndrop.DragController.DragListener; +import com.android.launcher3.dragndrop.DragOptions; + +/** + * Utility listener to enable/disable accessibility drag flags for a ViewGroup + * containing CellLayouts + */ +public class AccessibileDragListenerAdapter implements DragListener { + + private final ViewGroup mViewGroup; + private final int mDragType; + + /** + * @param parent + * @param dragType either {@link CellLayout#WORKSPACE_ACCESSIBILITY_DRAG} or + * {@link CellLayout#FOLDER_ACCESSIBILITY_DRAG} + */ + public AccessibileDragListenerAdapter(ViewGroup parent, int dragType) { + mViewGroup = parent; + mDragType = dragType; + } + + @Override + public void onDragStart(DragObject dragObject, DragOptions options) { + enableAccessibleDrag(true); + } + + @Override + public void onDragEnd() { + enableAccessibleDrag(false); + Launcher.getLauncher(mViewGroup.getContext()).getDragController().removeDragListener(this); + } + + protected void enableAccessibleDrag(boolean enable) { + for (int i = 0; i < mViewGroup.getChildCount(); i++) { + setEnableForLayout((CellLayout) mViewGroup.getChildAt(i), enable); + } + } + + protected final void setEnableForLayout(CellLayout layout, boolean enable) { + layout.enableAccessibleDrag(enable, mDragType); + } +} diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java index 0562cf54b..173aad044 100644 --- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java @@ -22,6 +22,8 @@ import com.android.launcher3.BubbleTextView; import com.android.launcher3.CellLayout; import com.android.launcher3.DeleteDropTarget; import com.android.launcher3.DragSource; +import com.android.launcher3.DropTarget.DragObject; +import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.folder.Folder; import com.android.launcher3.FolderInfo; import com.android.launcher3.InfoDropTarget; @@ -73,7 +75,6 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme @Thunk final Launcher mLauncher; private DragInfo mDragInfo = null; - private AccessibilityDragSource mDragSource = null; public LauncherAccessibilityDelegate(Launcher launcher) { mLauncher = launcher; @@ -372,26 +373,25 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme Folder folder = workspace.getOpenFolder(); if (folder != null) { - if (folder.getItemsInReadingOrder().contains(item)) { - mDragSource = folder; - } else { + if (!folder.getItemsInReadingOrder().contains(item)) { mLauncher.closeFolder(); + folder = null; } } - if (mDragSource == null) { - mDragSource = workspace; - } - mDragSource.enableAccessibleDrag(true); - mDragSource.startDrag(cellInfo, true); - if (mLauncher.getDragController().isDragging()) { - mLauncher.getDragController().addDragListener(this); + mLauncher.getDragController().addDragListener(this); + + DragOptions options = new DragOptions(); + options.isAccessibleDrag = true; + if (folder != null) { + folder.startDrag(cellInfo.cell, options); + } else { + workspace.startDrag(cellInfo, options); } } - @Override - public void onDragStart(DragSource source, ItemInfo info, int dragAction) { + public void onDragStart(DragObject dragObject, DragOptions options) { // No-op } @@ -399,16 +399,6 @@ public class LauncherAccessibilityDelegate extends AccessibilityDelegate impleme public void onDragEnd() { mLauncher.getDragController().removeDragListener(this); mDragInfo = null; - if (mDragSource != null) { - mDragSource.enableAccessibleDrag(false); - mDragSource = null; - } - } - - public static interface AccessibilityDragSource { - void startDrag(CellLayout.CellInfo cellInfo, boolean accessible); - - void enableAccessibleDrag(boolean enable); } /** diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index a8e2140c2..a3786fa3f 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -48,6 +48,7 @@ import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.folder.Folder; import com.android.launcher3.graphics.TintedDrawableSpan; import com.android.launcher3.keyboard.FocusedItemDecorator; @@ -539,7 +540,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc if (!mLauncher.isDraggingEnabled()) return false; // Start the drag - mLauncher.getWorkspace().beginDragShared(v, this, false); + mLauncher.getWorkspace().beginDragShared(v, this, new DragOptions()); // Enter spring loaded mode mLauncher.enterSpringLoadedDragMode(); diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index b57f5bf06..b67d3b8bc 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -57,12 +57,6 @@ import java.util.ArrayList; public class DragController implements DragDriver.EventListener, TouchController { private static final String TAG = "Launcher.DragController"; - /** Indicates the drag is a move. */ - public static int DRAG_ACTION_MOVE = 0; - - /** Indicates the drag is a copy. */ - public static int DRAG_ACTION_COPY = 1; - public static final int SCROLL_DELAY = 500; public static final int RESCROLL_DELAY = PagedView.PAGE_SNAP_ANIMATION_DURATION + 150; @@ -91,8 +85,8 @@ public class DragController implements DragDriver.EventListener, TouchController */ private DragDriver mDragDriver = null; - /** Whether or not an accessible drag operation is in progress. */ - private boolean mIsAccessibleDrag; + /** Options controlling the drag behavior. */ + private DragOptions mOptions; /** X coordinate of the down event. */ private int mMotionDownX; @@ -145,12 +139,10 @@ public class DragController implements DragDriver.EventListener, TouchController /** * A drag has begun * - * @param source An object representing where the drag originated - * @param info The data associated with the object that is being dragged - * @param dragAction The drag action: either {@link DragController#DRAG_ACTION_MOVE} - * or {@link DragController#DRAG_ACTION_COPY} + * @param dragObject The object being dragged + * @param options Options used to start the drag */ - void onDragStart(DragSource source, ItemInfo info, int dragAction); + void onDragStart(DropTarget.DragObject dragObject, DragOptions options); /** * The drag has ended @@ -160,8 +152,6 @@ public class DragController implements DragDriver.EventListener, TouchController /** * Used to create a new DragLayer from XML. - * - * @param context The application's context. */ public DragController(Launcher launcher) { Resources r = launcher.getResources(); @@ -183,11 +173,9 @@ public class DragController implements DragDriver.EventListener, TouchController * @param source An object representing where the drag originated * @param dragInfo The data associated with the object that is being dragged * @param viewImageBounds the position of the image inside the view - * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or - * {@link #DRAG_ACTION_COPY} */ public void startDrag(View v, Bitmap bmp, DragSource source, ItemInfo dragInfo, - Rect viewImageBounds, int dragAction, float initialDragViewScale) { + Rect viewImageBounds, float initialDragViewScale, DragOptions options) { int[] loc = mCoordinatesTemp; mLauncher.getDragLayer().getLocationInDragLayer(v, loc); int dragLayerX = loc[0] + viewImageBounds.left @@ -195,12 +183,8 @@ public class DragController implements DragDriver.EventListener, TouchController int dragLayerY = loc[1] + viewImageBounds.top + (int) ((initialDragViewScale * bmp.getHeight() - bmp.getHeight()) / 2); - startDrag(bmp, dragLayerX, dragLayerY, source, dragInfo, dragAction, null, - null, initialDragViewScale, false); - - if (dragAction == DRAG_ACTION_MOVE) { - v.setVisibility(View.GONE); - } + startDrag(bmp, dragLayerX, dragLayerY, source, dragInfo, null, + null, initialDragViewScale, options); } /** @@ -212,15 +196,12 @@ public class DragController implements DragDriver.EventListener, TouchController * @param dragLayerY The y position in the DragLayer of the left-top of the bitmap. * @param source An object representing where the drag originated * @param dragInfo The data associated with the object that is being dragged - * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or - * {@link #DRAG_ACTION_COPY} * @param dragRegion Coordinates within the bitmap b for the position of item being dragged. * Makes dragging feel more precise, e.g. you can clip out a transparent border - * @param accessible whether this drag should occur in accessibility mode */ public DragView startDrag(Bitmap b, int dragLayerX, int dragLayerY, - DragSource source, ItemInfo dragInfo, int dragAction, Point dragOffset, Rect dragRegion, - float initialDragViewScale, boolean accessible) { + DragSource source, ItemInfo dragInfo, Point dragOffset, Rect dragRegion, + float initialDragViewScale, DragOptions options) { if (PROFILE_DRAWING_DURING_DRAG) { android.os.Debug.startMethodTracing("Launcher"); } @@ -232,19 +213,15 @@ public class DragController implements DragDriver.EventListener, TouchController } mInputMethodManager.hideSoftInputFromWindow(mWindowToken, 0); - for (DragListener listener : mListeners) { - listener.onDragStart(source, dragInfo, dragAction); - } - final int registrationX = mMotionDownX - dragLayerX; final int registrationY = mMotionDownY - dragLayerY; final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left; final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top; - mIsAccessibleDrag = accessible; mLastDropTarget = null; + mOptions = options; mDragObject = new DropTarget.DragObject(); final Resources res = mLauncher.getResources(); @@ -254,7 +231,7 @@ public class DragController implements DragDriver.EventListener, TouchController registrationY, initialDragViewScale, scaleDps); mDragObject.dragComplete = false; - if (mIsAccessibleDrag) { + if (mOptions.isAccessibleDrag) { // For an accessible drag, we assume the view is being dragged from the center. mDragObject.xOffset = b.getWidth() / 2; mDragObject.yOffset = b.getHeight() / 2; @@ -282,6 +259,11 @@ public class DragController implements DragDriver.EventListener, TouchController mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); dragView.show(mMotionDownX, mMotionDownY); mDistanceSinceScroll = 0; + + for (DragListener listener : mListeners) { + listener.onDragStart(mDragObject, mOptions); + } + mLastTouch[0] = mMotionDownX; mLastTouch[1] = mMotionDownY; handleMoveEvent(mMotionDownX, mMotionDownY); @@ -308,7 +290,7 @@ public class DragController implements DragDriver.EventListener, TouchController } public boolean isDragging() { - return mDragDriver != null || mIsAccessibleDrag; + return mDragDriver != null || (mOptions != null && mOptions.isAccessibleDrag); } /** @@ -343,7 +325,7 @@ public class DragController implements DragDriver.EventListener, TouchController private void endDrag() { if (isDragging()) { mDragDriver = null; - mIsAccessibleDrag = false; + mOptions = null; clearScrollRunnable(); boolean isDeferred = false; if (mDragObject.dragView != null) { @@ -422,10 +404,6 @@ public class DragController implements DragDriver.EventListener, TouchController @Override public void onDriverDragEnd(float x, float y, DropTarget dropTargetOverride) { - final int[] dragLayerPos = getClampedDragLayerPos(x, y); - final int dragLayerX = dragLayerPos[0]; - final int dragLayerY = dragLayerPos[1]; - DropTarget dropTarget; PointF vec = null; @@ -454,14 +432,7 @@ public class DragController implements DragDriver.EventListener, TouchController * Call this from a drag source view. */ public boolean onInterceptTouchEvent(MotionEvent ev) { - @SuppressWarnings("all") // suppress dead code warning - final boolean debug = false; - if (debug) { - Log.d(Launcher.TAG, "DragController.onInterceptTouchEvent " + ev + " Dragging=" - + (mDragDriver != null)); - } - - if (mIsAccessibleDrag) { + if (mOptions != null && mOptions.isAccessibleDrag) { return false; } @@ -604,7 +575,7 @@ public class DragController implements DragDriver.EventListener, TouchController * Call this from a drag source view. */ public boolean onTouchEvent(MotionEvent ev) { - if (mDragDriver == null || mIsAccessibleDrag) { + if (mDragDriver == null || mOptions == null || mOptions.isAccessibleDrag) { return false; } diff --git a/src/com/android/launcher3/dragndrop/DragOptions.java b/src/com/android/launcher3/dragndrop/DragOptions.java new file mode 100644 index 000000000..a7f28726a --- /dev/null +++ b/src/com/android/launcher3/dragndrop/DragOptions.java @@ -0,0 +1,26 @@ +/* + * 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.dragndrop; + +/** + * Set of options to control the drag and drop behavior. + */ +public class DragOptions { + + /** Whether or not an accessible drag operation is in progress. */ + public boolean isAccessibleDrag = false; +} diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 5450423a2..1e87202f0 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -71,11 +71,12 @@ import com.android.launcher3.ShortcutInfo; import com.android.launcher3.UninstallDropTarget.DropTargetSource; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace.ItemOperator; -import com.android.launcher3.accessibility.LauncherAccessibilityDelegate.AccessibilityDragSource; +import com.android.launcher3.accessibility.AccessibileDragListenerAdapter; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragController.DragListener; import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.logging.UserEventDispatcher.LaunchSourceProvider; import com.android.launcher3.pageindicators.PageIndicatorDots; import com.android.launcher3.userevent.nano.LauncherLogProto; @@ -92,7 +93,7 @@ import java.util.Comparator; */ public class Folder extends LinearLayout implements DragSource, View.OnClickListener, View.OnLongClickListener, DropTarget, FolderListener, TextView.OnEditorActionListener, - View.OnFocusChangeListener, DragListener, DropTargetSource, AccessibilityDragSource { + View.OnFocusChangeListener, DragListener, DropTargetSource { private static final String TAG = "Launcher.Folder"; /** @@ -282,10 +283,10 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList public boolean onLongClick(View v) { // Return if global dragging is not enabled if (!mLauncher.isDraggingEnabled()) return true; - return beginDrag(v, false); + return startDrag(v, new DragOptions()); } - private boolean beginDrag(View v, boolean accessible) { + public boolean startDrag(View v, DragOptions options) { Object tag = v.getTag(); if (tag instanceof ShortcutInfo) { ShortcutInfo item = (ShortcutInfo) tag; @@ -293,35 +294,48 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList return false; } - mLauncher.getWorkspace().beginDragShared(v, this, accessible); - mCurrentDragInfo = item; mEmptyCellRank = item.rank; mCurrentDragView = v; - mContent.removeItem(mCurrentDragView); - mInfo.remove(mCurrentDragInfo, true); - mDragInProgress = true; - mItemAddedBackToSelfViaIcon = false; + mDragController.addDragListener(this); + if (options.isAccessibleDrag) { + mDragController.addDragListener(new AccessibileDragListenerAdapter( + mContent, CellLayout.FOLDER_ACCESSIBILITY_DRAG) { + + @Override + protected void enableAccessibleDrag(boolean enable) { + super.enableAccessibleDrag(enable); + mFooter.setImportantForAccessibility(enable + ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS + : IMPORTANT_FOR_ACCESSIBILITY_AUTO); + } + }); + } + + mLauncher.getWorkspace().beginDragShared(v, this, options); } return true; } @Override - public void startDrag(CellInfo cellInfo, boolean accessible) { - beginDrag(cellInfo.cell, accessible); + public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { + if (dragObject.dragSource != this) { + return; + } + + mContent.removeItem(mCurrentDragView); + mInfo.remove(mCurrentDragInfo, true); + mDragInProgress = true; + mItemAddedBackToSelfViaIcon = false; } @Override - public void enableAccessibleDrag(boolean enable) { - mLauncher.getDropTargetBar().enableAccessibleDrag(enable); - for (int i = 0; i < mContent.getChildCount(); i++) { - mContent.getPageAt(i).enableAccessibleDrag(enable, CellLayout.FOLDER_ACCESSIBILITY_DRAG); + public void onDragEnd() { + if (mIsExternalDrag && mDragInProgress) { + completeDragExit(); } - - mFooter.setImportantForAccessibility(enable ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS : - IMPORTANT_FOR_ACCESSIBILITY_AUTO); - mLauncher.getWorkspace().setAddNewPageOnDrag(!enable); + mDragController.removeDragListener(this); } public boolean isEditingName() { @@ -661,17 +675,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList mDragController.addDragListener(this); } - @Override - public void onDragStart(DragSource source, ItemInfo info, int dragAction) { } - - @Override - public void onDragEnd() { - if (mIsExternalDrag && mDragInProgress) { - completeDragExit(); - } - mDragController.removeDragListener(this); - } - @Thunk void sendCustomAccessibilityEvent(int type, String text) { AccessibilityManager accessibilityManager = (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java index 0ff13a780..4100795cc 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutsContainer.java @@ -62,6 +62,7 @@ import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.graphics.TriangleShape; import com.android.launcher3.logging.UserEventDispatcher; @@ -515,8 +516,8 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC mIconShift.y = mIconLastTouchPos.y - mLauncher.getDeviceProfile().iconSizePx; DragView dv = mLauncher.getWorkspace().beginDragShared( - sv.getBubbleText(), this, false, sv.getFinalInfo(), - new ShortcutDragPreviewProvider(sv.getIconView(), mIconShift)); + sv.getBubbleText(), this, sv.getFinalInfo(), + new ShortcutDragPreviewProvider(sv.getIconView(), mIconShift), new DragOptions()); dv.animateShift(-mIconShift.x, -mIconShift.y); // TODO: support dragging from within folder without having to close it @@ -560,7 +561,7 @@ public class DeepShortcutsContainer extends LinearLayout implements View.OnLongC } @Override - public void onDragStart(DragSource source, ItemInfo info, int dragAction) { + public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { // Either the original icon or one of the shortcuts was dragged. // Hide the container, but don't remove it yet because that interferes with touch events. animateClose(); diff --git a/src/com/android/launcher3/widget/WidgetHostViewLoader.java b/src/com/android/launcher3/widget/WidgetHostViewLoader.java index 297505be2..049871f98 100644 --- a/src/com/android/launcher3/widget/WidgetHostViewLoader.java +++ b/src/com/android/launcher3/widget/WidgetHostViewLoader.java @@ -11,6 +11,7 @@ import android.view.View; import com.android.launcher3.AppWidgetResizeFrame; import com.android.launcher3.DragSource; +import com.android.launcher3.DropTarget; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppWidgetProviderInfo; @@ -18,6 +19,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.util.Thunk; public class WidgetHostViewLoader implements DragController.DragListener { @@ -47,7 +49,7 @@ public class WidgetHostViewLoader implements DragController.DragListener { } @Override - public void onDragStart(DragSource source, ItemInfo info, int dragAction) { } + public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { } @Override public void onDragEnd() { diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java index 4b2be1816..70b2945f5 100644 --- a/src/com/android/launcher3/widget/WidgetsContainerView.java +++ b/src/com/android/launcher3/widget/WidgetsContainerView.java @@ -33,6 +33,7 @@ import com.android.launcher3.CellLayout; import com.android.launcher3.DeleteDropTarget; import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget.DragObject; +import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.folder.Folder; import com.android.launcher3.IconCache; import com.android.launcher3.ItemInfo; @@ -251,7 +252,7 @@ public class WidgetsContainerView extends BaseContainerView // Start the drag mDragController.startDrag(image, preview, this, createItemInfo, - bounds, DragController.DRAG_ACTION_COPY, scale); + bounds, scale, new DragOptions()); return true; } -- cgit v1.2.3