Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e74e899 authored by Tony Wickham's avatar Tony Wickham Committed by Tony
Browse files

Refactor shortcuts drag and drop.

- Instead of creating our own drag view within the container, and
  handling logic to determine when to start a real drag, we start
  the drag immediately and just defer onDragStart().
- To determine when the deferred drag should start, we add a
  DeferDragCondition to DragOptions. The default DeferDragCondition
  never defers a drag, but is overridden for apps with shortcuts
  to defer until the icon is dragged a given distance.
- Because the drag is handled in DragController, including checking
  when to start the deferred drag, DeepShortcutsContainer no longer
  needs to handle touch events and ShortcutsContainerListener has
  been removed.

This change has several immediate benefits:
- The code is much cleaner, because it allows touch handling to be
  done by the DragController through the normal drag flow, without
  recreating logic in ShortcutsContainerListener/DeepShortcutContainer.
- The janky second haptic feedback has been removed (now it vibrates
  when you long press, like everywhere else, but not again when the
  shortcuts close after dragging a distance).
- Drops are animated, instead of just popping the icon back into place.

Bug: 30769920
Bug: 30465972
Bug: 31533078
Change-Id: I679b412b72fbf6c3895d76963311eb5010c8e8db
parent 00341907
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -164,7 +164,7 @@
    <dimen name="bg_pill_height">48dp</dimen>
    <dimen name="bg_pill_radius">24dp</dimen>
    <dimen name="deep_shortcuts_spacing">4dp</dimen>
    <dimen name="deep_shortcuts_drag_view_scale">6dp</dimen>
    <dimen name="deferred_drag_view_scale">6dp</dimen>
    <!-- an icon with shortcuts must be dragged this far before the container is removed. -->
    <dimen name="deep_shortcuts_start_drag_threshold">16dp</dimen>
    <dimen name="deep_shortcut_icon_size">36dp</dimen>
+11 −1
Original line number Diff line number Diff line
@@ -3109,7 +3109,17 @@ public class Launcher extends Activity
                                        longClickCellInfo.cellX, longClickCellInfo.cellY));
                if (!(itemUnderLongClick instanceof Folder || isAllAppsButton)) {
                    // User long pressed on an item
                    mWorkspace.startDrag(longClickCellInfo, new DragOptions());
                    DragOptions dragOptions = new DragOptions();
                    if (itemUnderLongClick instanceof BubbleTextView) {
                        BubbleTextView icon = (BubbleTextView) itemUnderLongClick;
                        if (icon.hasDeepShortcuts()) {
                            DeepShortcutsContainer dsc = DeepShortcutsContainer.showForIcon(icon);
                            if (dsc != null) {
                                dragOptions.deferDragCondition = dsc.createDeferDragCondition(null);
                            }
                        }
                    }
                    mWorkspace.startDrag(longClickCellInfo, dragOptions);
                }
            }
        }
+0 −6
Original line number Diff line number Diff line
@@ -74,8 +74,6 @@ 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.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutsContainerListener;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.ItemInfoMatcher;
@@ -1175,10 +1173,6 @@ public class Workspace extends PagedView
        if (!(child instanceof Folder)) {
            child.setHapticFeedbackEnabled(false);
            child.setOnLongClickListener(mLongClickListener);
            if (child instanceof BubbleTextView && DeepShortcutManager.supportsShortcuts(info)) {
                // TODO: only add this listener if the item has shortcuts associated with it.
                child.setOnTouchListener(new ShortcutsContainerListener((BubbleTextView) child));
            }
        }
        if (child instanceof DropTarget) {
            mDragController.addDropTarget((DropTarget) child);
+26 −5
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.view.ViewGroup;

import com.android.launcher3.AppInfo;
import com.android.launcher3.BaseContainerView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeleteDropTarget;
import com.android.launcher3.DeviceProfile;
@@ -53,6 +54,7 @@ import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.graphics.TintedDrawableSpan;
import com.android.launcher3.keyboard.FocusedItemDecorator;
import com.android.launcher3.shortcuts.DeepShortcutsContainer;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.ComponentKey;

@@ -542,13 +544,32 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc

        if (!mLauncher.isAppsViewVisible() ||
                mLauncher.getWorkspace().isSwitchingState()) return false;
        // Return if global dragging is not enabled
        // Return if global dragging is not enabled or we are already dragging
        if (!mLauncher.isDraggingEnabled()) return false;
        if (mLauncher.getDragController().isDragging()) return false;

        // Start the drag
        mLauncher.getWorkspace().beginDragShared(v, this, new DragOptions());
        // Enter spring loaded mode
        DragOptions dragOptions = new DragOptions();
        if (v instanceof BubbleTextView) {
            final BubbleTextView icon = (BubbleTextView) v;
            if (icon.hasDeepShortcuts()) {
                DeepShortcutsContainer dsc = DeepShortcutsContainer.showForIcon(icon);
                if (dsc != null) {
                    dragOptions.deferDragCondition = dsc.createDeferDragCondition(new Runnable() {
                        @Override
                        public void run() {
                            icon.setVisibility(VISIBLE);
                        }
                    });
                }
            }
        }
        mLauncher.getWorkspace().beginDragShared(v, this, dragOptions);
        if (FeatureFlags.LAUNCHER3_LEGACY_WORKSPACE_DND) {
            // Enter spring loaded mode (the new workspace does this in
            // onDragStart(), so we don't want to do it here)
            mLauncher.enterSpringLoadedDragMode();
        }

        return false;
    }
@@ -598,7 +619,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
        // target layout we were dropping on.
        if (!success) {
            boolean showOutOfSpaceMessage = false;
            if (target instanceof Workspace) {
            if (target instanceof Workspace && !mLauncher.getDragController().isDeferringDrag()) {
                int currentScreen = mLauncher.getCurrentWorkspaceScreen();
                Workspace workspace = (Workspace) target;
                CellLayout layout = (CellLayout) workspace.getChildAt(currentScreen);
+0 −10
Original line number Diff line number Diff line
@@ -42,8 +42,6 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutsContainerListener;

import java.util.HashMap;
import java.util.List;
@@ -503,10 +501,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
                AppInfo info = mApps.getAdapterItems().get(position).appInfo;
                BubbleTextView icon = (BubbleTextView) holder.mContent;
                icon.applyFromApplicationInfo(info);
                if (DeepShortcutManager.supportsShortcuts(info)) {
                    // TODO: only add this listener if the item has shortcuts associated with it.
                    icon.setOnTouchListener(new ShortcutsContainerListener(icon));
                }
                icon.setAccessibilityDelegate(mLauncher.getAccessibilityDelegate());
                break;
            }
@@ -514,10 +508,6 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
                AppInfo info = mApps.getAdapterItems().get(position).appInfo;
                BubbleTextView icon = (BubbleTextView) holder.mContent;
                icon.applyFromApplicationInfo(info);
                if (DeepShortcutManager.supportsShortcuts(info)) {
                    // TODO: only add this listener if the item has shortcuts associated with it.
                    icon.setOnTouchListener(new ShortcutsContainerListener(icon));
                }
                icon.setAccessibilityDelegate(mLauncher.getAccessibilityDelegate());
                break;
            }
Loading