Merge "Add shortcut drag/drop support to the taskbar."
This commit is contained in:
committed by
Android (Google) Code Review
commit
d55644d3af
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user