Merge "Add shortcut drag/drop support to the taskbar."

This commit is contained in:
TreeHugger Robot
2021-12-01 00:17:59 +00:00
committed by Android (Google) Code Review
6 changed files with 107 additions and 14 deletions
@@ -51,6 +51,8 @@ import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ClipDescriptionCompat;
import com.android.systemui.shared.system.LauncherAppsCompat;
@@ -88,6 +90,21 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
* @return Whether {@link View#startDragAndDrop} started successfully.
*/
protected boolean startDragOnLongClick(View view) {
return startDragOnLongClick(view, null, null);
}
protected boolean startDragOnLongClick(
DeepShortcutView shortcutView, Point iconShift) {
return startDragOnLongClick(
shortcutView.getBubbleText(),
new ShortcutDragPreviewProvider(shortcutView.getIconView(), iconShift),
iconShift);
}
private boolean startDragOnLongClick(
View view,
@Nullable DragPreviewProvider dragPreviewProvider,
@Nullable Point iconShift) {
if (!(view instanceof BubbleTextView)) {
return false;
}
@@ -96,7 +113,10 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
mActivity.setTaskbarWindowFullscreen(true);
btv.post(() -> {
startInternalDrag(btv);
DragView dragView = startInternalDrag(btv, dragPreviewProvider);
if (iconShift != null) {
dragView.animateShift(-iconShift.x, -iconShift.y);
}
btv.getIcon().setIsDisabled(true);
mControllers.taskbarAutohideSuspendController.updateFlag(
TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING, true);
@@ -104,7 +124,8 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
return true;
}
private void startInternalDrag(BubbleTextView btv) {
private DragView startInternalDrag(
BubbleTextView btv, @Nullable DragPreviewProvider dragPreviewProvider) {
float iconScale = btv.getIcon().getAnimatedScale();
// Clear the pressed state if necessary
@@ -112,7 +133,8 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
btv.setPressed(false);
btv.clearPressedBackground();
final DragPreviewProvider previewProvider = new DragPreviewProvider(btv);
final DragPreviewProvider previewProvider = dragPreviewProvider == null
? new DragPreviewProvider(btv) : dragPreviewProvider;
final Drawable drawable = previewProvider.createDrawable();
final float scale = previewProvider.getScaleAndPosition(drawable, mTempXY);
int dragLayerX = mTempXY[0];
@@ -149,7 +171,7 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
}
}
startDrag(
return startDrag(
drawable,
/* view = */ null,
/* originalView = */ btv,
@@ -241,7 +263,8 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
@Override
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
shadowSize.set(mDragIconSize, mDragIconSize);
int iconSize = Math.max(mDragIconSize, btv.getWidth());
shadowSize.set(iconSize, iconSize);
// The registration point was taken before the icon scaled to mDragIconSize, so
// offset the registration to where the touch is on the new size.
int offsetX = (mDragIconSize - mDragObject.dragView.getDragRegionWidth()) / 2;
@@ -273,6 +296,12 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
});
intent = new Intent();
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
intent.putExtra(ClipDescriptionCompat.EXTRA_PENDING_INTENT,
launcherApps.getShortcutIntent(
item.getIntent().getPackage(),
item.getDeepShortcutId(),
null,
item.user));
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, item.getIntent().getPackage());
intent.putExtra(Intent.EXTRA_SHORTCUT_ID, item.getDeepShortcutId());
} else {
@@ -15,6 +15,10 @@
*/
package com.android.launcher3.taskbar;
import android.graphics.Point;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import com.android.launcher3.BubbleTextView;
@@ -30,6 +34,7 @@ import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.popup.PopupLiveUpdateHandler;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.launcher3.util.PackageUserKey;
@@ -131,8 +136,14 @@ public class TaskbarPopupController {
(PopupContainerWithArrow) context.getLayoutInflater().inflate(
R.layout.popup_container, context.getDragLayer(), false);
container.addOnAttachStateChangeListener(
new PopupLiveUpdateHandler<>(mContext, container));
new PopupLiveUpdateHandler<TaskbarActivityContext>(mContext, container) {
@Override
protected void showPopupContainerForIcon(BubbleTextView originalIcon) {
showForIcon(originalIcon);
}
});
// TODO (b/198438631): configure for taskbar/context
container.setPopupItemDragHandler(new TaskbarPopupItemDragHandler());
container.populateAndShow(icon,
mPopupDataProvider.getShortcutCountForItem(item),
@@ -145,4 +156,43 @@ public class TaskbarPopupController {
container.requestFocus();
return container;
}
private class TaskbarPopupItemDragHandler implements
PopupContainerWithArrow.PopupItemDragHandler {
protected final Point mIconLastTouchPos = new Point();
TaskbarPopupItemDragHandler() {}
@Override
public boolean onTouch(View view, MotionEvent ev) {
// Touched a shortcut, update where it was touched so we can drag from there on
// long click.
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
mIconLastTouchPos.set((int) ev.getX(), (int) ev.getY());
break;
}
return false;
}
@Override
public boolean onLongClick(View v) {
// Return early if not the correct view
if (!(v.getParent() instanceof DeepShortcutView)) return false;
DeepShortcutView sv = (DeepShortcutView) v.getParent();
sv.setWillDrawIcon(false);
// Move the icon to align with the center-top of the touch point
Point iconShift = new Point();
iconShift.x = mIconLastTouchPos.x - sv.getIconCenter().x;
iconShift.y = mIconLastTouchPos.y - mContext.getDeviceProfile().iconSizePx;
mControllers.taskbarDragController.startDragOnLongClick(sv, iconShift);
return false;
}
}
}
@@ -18,6 +18,7 @@ package com.android.launcher3.popup;
import android.view.View;
import android.view.ViewGroup;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.model.data.ItemInfo;
@@ -86,4 +87,9 @@ public class LauncherPopupLiveUpdateHandler extends PopupLiveUpdateHandler<Launc
}
}
}
@Override
protected void showPopupContainerForIcon(BubbleTextView originalIcon) {
PopupContainerWithArrow.showForIcon(originalIcon);
}
}
@@ -152,6 +152,10 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
};
}
public void setPopupItemDragHandler(PopupItemDragHandler popupItemDragHandler) {
mPopupItemDragHandler = popupItemDragHandler;
}
public PopupItemDragHandler getItemDragHandler() {
return mPopupItemDragHandler;
}
@@ -20,6 +20,7 @@ import static android.view.View.GONE;
import android.content.Context;
import android.view.View;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.notification.NotificationContainer;
@@ -36,7 +37,7 @@ import java.util.function.Predicate;
*
* @param <T> The activity on which the popup shows
*/
public class PopupLiveUpdateHandler<T extends Context & ActivityContext> implements
public abstract class PopupLiveUpdateHandler<T extends Context & ActivityContext> implements
PopupDataProvider.PopupDataChangeListener, View.OnAttachStateChangeListener {
protected final T mContext;
@@ -103,6 +104,8 @@ public class PopupLiveUpdateHandler<T extends Context & ActivityContext> impleme
@Override
public void onSystemShortcutsUpdated() {
mPopupContainerWithArrow.close(true);
PopupContainerWithArrow.showForIcon(mPopupContainerWithArrow.getOriginalIcon());
showPopupContainerForIcon(mPopupContainerWithArrow.getOriginalIcon());
}
protected abstract void showPopupContainerForIcon(BubbleTextView originalIcon);
}
@@ -23,12 +23,12 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;
import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.views.ActivityContext;
/**
* Extension of {@link DragPreviewProvider} which generates bitmaps scaled to the default icon size.
@@ -45,7 +45,8 @@ public class ShortcutDragPreviewProvider extends DragPreviewProvider {
@Override
public Drawable createDrawable() {
if (FeatureFlags.ENABLE_DEEP_SHORTCUT_ICON_CACHE.get()) {
int size = Launcher.getLauncher(mView.getContext()).getDeviceProfile().iconSizePx;
int size = ActivityContext.lookupContext(mView.getContext())
.getDeviceProfile().iconSizePx;
return new FastBitmapDrawable(
BitmapRenderer.createHardwareBitmap(
size + blurSizeOutline,
@@ -59,7 +60,7 @@ public class ShortcutDragPreviewProvider extends DragPreviewProvider {
private Bitmap createDragBitmapLegacy() {
Drawable d = mView.getBackground();
Rect bounds = getDrawableBounds(d);
int size = Launcher.getLauncher(mView.getContext()).getDeviceProfile().iconSizePx;
int size = ActivityContext.lookupContext(mView.getContext()).getDeviceProfile().iconSizePx;
final Bitmap b = Bitmap.createBitmap(
size + blurSizeOutline,
size + blurSizeOutline,
@@ -84,9 +85,9 @@ public class ShortcutDragPreviewProvider extends DragPreviewProvider {
@Override
public float getScaleAndPosition(Drawable preview, int[] outPos) {
Launcher launcher = Launcher.getLauncher(mView.getContext());
ActivityContext context = ActivityContext.lookupContext(mView.getContext());
int iconSize = getDrawableBounds(mView.getBackground()).width();
float scale = launcher.getDragLayer().getLocationInDragLayer(mView, outPos);
float scale = context.getDragLayer().getLocationInDragLayer(mView, outPos);
int iconLeft = mView.getPaddingStart();
if (Utilities.isRtl(mView.getResources())) {
@@ -98,7 +99,7 @@ public class ShortcutDragPreviewProvider extends DragPreviewProvider {
+ mPositionShift.x);
outPos[1] += Math.round((scale * mView.getHeight() - preview.getIntrinsicHeight()) / 2
+ mPositionShift.y);
float size = launcher.getDeviceProfile().iconSizePx;
float size = context.getDeviceProfile().iconSizePx;
return scale * iconSize / size;
}
}