Merge "Drag from appDrawer & pin onto secondary display homescreen" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ddbe35cc87
@@ -299,6 +299,10 @@ public final class FeatureFlags {
|
||||
public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag(
|
||||
"ENABLE_TRANSIENT_TASKBAR", false, "Enables transient taskbar.");
|
||||
|
||||
public static final BooleanFlag SECONDARY_DRAG_N_DROP_TO_PIN = getDebugFlag(
|
||||
"SECONDARY_DRAG_N_DROP_TO_PIN", false,
|
||||
"Enable dragging and dropping to pin apps within secondary display");
|
||||
|
||||
public static void initialize(Context context) {
|
||||
synchronized (sDebugFlags) {
|
||||
for (DebugFlag flag : sDebugFlags) {
|
||||
|
||||
@@ -168,15 +168,18 @@ public class PinnedAppsAdapter extends BaseAdapter implements OnSharedPreference
|
||||
mPrefs.unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
private void update(ItemInfo info, Function<ComponentKey, Boolean> op) {
|
||||
/**
|
||||
* Pins or unpins apps from home screen
|
||||
*/
|
||||
public void update(ItemInfo info, Function<ComponentKey, Boolean> op) {
|
||||
ComponentKey key = new ComponentKey(info.getTargetComponent(), info.user);
|
||||
if (op.apply(key)) {
|
||||
createFilteredAppsList();
|
||||
Set<ComponentKey> copy = new HashSet<>(mPinnedApps);
|
||||
Executors.MODEL_EXECUTOR.submit(() ->
|
||||
mPrefs.edit().putStringSet(PINNED_APPS_KEY,
|
||||
copy.stream().map(this::encode).collect(Collectors.toSet()))
|
||||
.apply());
|
||||
copy.stream().map(this::encode).collect(Collectors.toSet()))
|
||||
.apply());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,6 +213,13 @@ public class PinnedAppsAdapter extends BaseAdapter implements OnSharedPreference
|
||||
mPinnedApps.contains(new ComponentKey(info.getTargetComponent(), info.user)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pins app to home screen
|
||||
*/
|
||||
public void addPinnedApp(ItemInfo info) {
|
||||
update(info, mPinnedApps::add);
|
||||
}
|
||||
|
||||
private class PinUnPinShortcut extends SystemShortcut<SecondaryDisplayLauncher> {
|
||||
|
||||
private final boolean mIsPinned;
|
||||
|
||||
@@ -18,6 +18,9 @@ package com.android.launcher3.secondarydisplay;
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
@@ -26,6 +29,9 @@ import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.DragSource;
|
||||
import com.android.launcher3.DropTarget;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherModel;
|
||||
@@ -33,6 +39,11 @@ import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
|
||||
import com.android.launcher3.dragndrop.DragController;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
import com.android.launcher3.dragndrop.DraggableView;
|
||||
import com.android.launcher3.graphics.DragPreviewProvider;
|
||||
import com.android.launcher3.icons.FastBitmapDrawable;
|
||||
import com.android.launcher3.model.BgDataModel;
|
||||
import com.android.launcher3.model.StringCache;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
@@ -52,11 +63,11 @@ import java.util.HashMap;
|
||||
* Launcher activity for secondary displays
|
||||
*/
|
||||
public class SecondaryDisplayLauncher extends BaseDraggingActivity
|
||||
implements BgDataModel.Callbacks {
|
||||
implements BgDataModel.Callbacks, DragController.DragListener {
|
||||
|
||||
private LauncherModel mModel;
|
||||
|
||||
private BaseDragLayer mDragLayer;
|
||||
private SecondaryDragController mDragController;
|
||||
private ActivityAllAppsContainerView<SecondaryDisplayLauncher> mAppsView;
|
||||
private View mAppsButton;
|
||||
|
||||
@@ -69,10 +80,13 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
|
||||
private boolean mBindingItems = false;
|
||||
private SecondaryDisplayPredictions mSecondaryDisplayPredictions;
|
||||
|
||||
private final int[] mTempXY = new int[2];
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mModel = LauncherAppState.getInstance(this).getModel();
|
||||
mDragController = new SecondaryDragController(this);
|
||||
mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
|
||||
mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this);
|
||||
if (getWindow().getDecorView().isAttachedToWindow()) {
|
||||
@@ -86,6 +100,12 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
|
||||
initUi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
this.getDragController().removeDragListener(this);
|
||||
}
|
||||
|
||||
private void initUi() {
|
||||
if (mDragLayer != null) {
|
||||
return;
|
||||
@@ -106,12 +126,19 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
|
||||
mAppsView = findViewById(R.id.apps_view);
|
||||
mAppsButton = findViewById(R.id.all_apps_button);
|
||||
|
||||
mDragController.addDragListener(this);
|
||||
mPopupDataProvider = new PopupDataProvider(
|
||||
mAppsView.getAppsStore()::updateNotificationDots);
|
||||
|
||||
mModel.addCallbacksAndLoad(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
mDragController.cancelDrag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
@@ -129,12 +156,21 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
|
||||
showAppDrawer(false);
|
||||
}
|
||||
|
||||
public DragController getDragController() {
|
||||
return mDragController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (finishAutoCancelActionMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mDragController.isDragging()) {
|
||||
mDragController.cancelDrag();
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: There should be at most one log per method call. This is enforced implicitly
|
||||
// by using if-else statements.
|
||||
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this);
|
||||
@@ -202,7 +238,7 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
|
||||
float closeR = Themes.getDialogCornerRadius(this);
|
||||
float startR = mAppsButton.getWidth() / 2f;
|
||||
|
||||
float[] buttonPos = new float[] { startR, startR};
|
||||
float[] buttonPos = new float[]{startR, startR};
|
||||
mDragLayer.getDescendantCoordRelativeToSelf(mAppsButton, buttonPos);
|
||||
mDragLayer.mapCoordInSelfToDescendant(mAppsView, buttonPos);
|
||||
final Animator animator = ViewAnimationUtils.createCircularReveal(mAppsView,
|
||||
@@ -236,6 +272,7 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
|
||||
@Override
|
||||
public void startBinding() {
|
||||
mBindingItems = true;
|
||||
mDragController.cancelDrag();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -308,4 +345,101 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
|
||||
startActivitySafely(v, intent, item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Core functionality for beginning a drag operation for an item that will be dropped within
|
||||
* the secondary display grid home screen
|
||||
*/
|
||||
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 "
|
||||
+ "will cause a crash (issue 11627249) down the line. "
|
||||
+ "View: " + child + " tag: " + child.getTag();
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
beginDragShared(child, source, (ItemInfo) dragObject,
|
||||
new DragPreviewProvider(child), options);
|
||||
}
|
||||
|
||||
private void beginDragShared(View child, DragSource source,
|
||||
ItemInfo dragObject, DragPreviewProvider previewProvider, DragOptions options) {
|
||||
|
||||
float iconScale = 1f;
|
||||
if (child instanceof BubbleTextView) {
|
||||
FastBitmapDrawable icon = ((BubbleTextView) child).getIcon();
|
||||
if (icon != null) {
|
||||
iconScale = icon.getAnimatedScale();
|
||||
}
|
||||
}
|
||||
|
||||
// clear pressed state if necessary
|
||||
child.clearFocus();
|
||||
child.setPressed(false);
|
||||
if (child instanceof BubbleTextView) {
|
||||
BubbleTextView icon = (BubbleTextView) child;
|
||||
icon.clearPressedBackground();
|
||||
}
|
||||
|
||||
DraggableView draggableView = null;
|
||||
if (child instanceof DraggableView) {
|
||||
draggableView = (DraggableView) child;
|
||||
}
|
||||
|
||||
final View contentView = previewProvider.getContentView();
|
||||
final float scale;
|
||||
// The draggable drawable follows the touch point around on the screen
|
||||
final Drawable drawable;
|
||||
if (contentView == null) {
|
||||
drawable = previewProvider.createDrawable();
|
||||
scale = previewProvider.getScaleAndPosition(drawable, mTempXY);
|
||||
} else {
|
||||
drawable = null;
|
||||
scale = previewProvider.getScaleAndPosition(contentView, mTempXY);
|
||||
}
|
||||
int halfPadding = previewProvider.previewPadding / 2;
|
||||
int dragLayerX = mTempXY[0];
|
||||
int dragLayerY = mTempXY[1];
|
||||
|
||||
Point dragVisualizeOffset = null;
|
||||
Rect dragRect = new Rect();
|
||||
if (draggableView != null) {
|
||||
draggableView.getSourceVisualDragBounds(dragRect);
|
||||
dragLayerY += dragRect.top;
|
||||
dragVisualizeOffset = new Point(-halfPadding, halfPadding);
|
||||
}
|
||||
if (contentView != null) {
|
||||
mDragController.startDrag(
|
||||
contentView,
|
||||
draggableView,
|
||||
dragLayerX,
|
||||
dragLayerY,
|
||||
source,
|
||||
dragObject,
|
||||
dragVisualizeOffset,
|
||||
dragRect,
|
||||
scale * iconScale,
|
||||
scale,
|
||||
options);
|
||||
} else {
|
||||
mDragController.startDrag(
|
||||
drawable,
|
||||
draggableView,
|
||||
dragLayerX,
|
||||
dragLayerY,
|
||||
source,
|
||||
dragObject,
|
||||
dragVisualizeOffset,
|
||||
dragRect,
|
||||
scale * iconScale,
|
||||
scale,
|
||||
options);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { }
|
||||
|
||||
@Override
|
||||
public void onDragEnd() { }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.secondarydisplay;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Log;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.DragSource;
|
||||
import com.android.launcher3.DropTarget;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
|
||||
import com.android.launcher3.dragndrop.DragController;
|
||||
import com.android.launcher3.dragndrop.DragDriver;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
import com.android.launcher3.dragndrop.DragView;
|
||||
import com.android.launcher3.dragndrop.DraggableView;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.testing.shared.TestProtocol;
|
||||
|
||||
/**
|
||||
* Drag controller for Secondary Launcher activity
|
||||
*/
|
||||
public class SecondaryDragController extends DragController<SecondaryDisplayLauncher> {
|
||||
|
||||
private static final boolean PROFILE_DRAWING_DURING_DRAG = false;
|
||||
|
||||
public SecondaryDragController(SecondaryDisplayLauncher secondaryLauncher) {
|
||||
super(secondaryLauncher);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DragView startDrag(@Nullable Drawable drawable, @Nullable View view,
|
||||
DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source,
|
||||
ItemInfo dragInfo, Point dragOffset, Rect dragRegion, float initialDragViewScale,
|
||||
float dragViewScaleOnDrop, DragOptions options) {
|
||||
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
Log.d(TestProtocol.NO_DROP_TARGET, "5");
|
||||
}
|
||||
|
||||
if (PROFILE_DRAWING_DURING_DRAG) {
|
||||
android.os.Debug.startMethodTracing("Launcher");
|
||||
}
|
||||
mActivity.hideKeyboard();
|
||||
|
||||
mOptions = options;
|
||||
if (mOptions.simulatedDndStartPoint != null) {
|
||||
mLastTouch.x = mMotionDown.x = mOptions.simulatedDndStartPoint.x;
|
||||
mLastTouch.y = mMotionDown.y = mOptions.simulatedDndStartPoint.y;
|
||||
}
|
||||
|
||||
final int registrationX = mMotionDown.x - dragLayerX;
|
||||
final int registrationY = mMotionDown.y - dragLayerY;
|
||||
|
||||
final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left;
|
||||
final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top;
|
||||
|
||||
mLastDropTarget = null;
|
||||
|
||||
mDragObject = new DropTarget.DragObject(mActivity.getApplicationContext());
|
||||
mDragObject.originalView = originalView;
|
||||
|
||||
mIsInPreDrag = mOptions.preDragCondition != null
|
||||
&& !mOptions.preDragCondition.shouldStartDrag(0);
|
||||
|
||||
final Resources res = mActivity.getResources();
|
||||
final float scaleDps = mIsInPreDrag
|
||||
? res.getDimensionPixelSize(R.dimen.pre_drag_view_scale) : 0f;
|
||||
|
||||
final DragView dragView = mDragObject.dragView = drawable != null
|
||||
? new SecondaryDragView(
|
||||
mActivity,
|
||||
drawable,
|
||||
registrationX,
|
||||
registrationY,
|
||||
initialDragViewScale,
|
||||
dragViewScaleOnDrop,
|
||||
scaleDps)
|
||||
: new SecondaryDragView(
|
||||
mActivity,
|
||||
view,
|
||||
view.getMeasuredWidth(),
|
||||
view.getMeasuredHeight(),
|
||||
registrationX,
|
||||
registrationY,
|
||||
initialDragViewScale,
|
||||
dragViewScaleOnDrop,
|
||||
scaleDps);
|
||||
dragView.setItemInfo(dragInfo);
|
||||
mDragObject.dragComplete = false;
|
||||
|
||||
mDragObject.xOffset = mMotionDown.x - (dragLayerX + dragRegionLeft);
|
||||
mDragObject.yOffset = mMotionDown.y - (dragLayerY + dragRegionTop);
|
||||
|
||||
mDragDriver = DragDriver.create(this, mOptions, ev -> {
|
||||
});
|
||||
if (!mOptions.isAccessibleDrag) {
|
||||
mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView);
|
||||
}
|
||||
|
||||
mDragObject.dragSource = source;
|
||||
mDragObject.dragInfo = dragInfo;
|
||||
mDragObject.originalDragInfo = mDragObject.dragInfo.makeShallowCopy();
|
||||
|
||||
if (dragOffset != null) {
|
||||
dragView.setDragVisualizeOffset(new Point(dragOffset));
|
||||
}
|
||||
if (dragRegion != null) {
|
||||
dragView.setDragRegion(new Rect(dragRegion));
|
||||
}
|
||||
|
||||
mActivity.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
dragView.show(mLastTouch.x, mLastTouch.y);
|
||||
mDistanceSinceScroll = 0;
|
||||
|
||||
if (!mIsInPreDrag) {
|
||||
callOnDragStart();
|
||||
} else if (mOptions.preDragCondition != null) {
|
||||
mOptions.preDragCondition.onPreDragStart(mDragObject);
|
||||
}
|
||||
|
||||
handleMoveEvent(mLastTouch.x, mLastTouch.y);
|
||||
return dragView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void exitDrag() { }
|
||||
|
||||
@Override
|
||||
protected DropTarget getDefaultDropTarget(int[] dropCoordinates) {
|
||||
DropTarget target = new DropTarget() {
|
||||
@Override
|
||||
public boolean isDropEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrop(DragObject dragObject, DragOptions options) {
|
||||
((SecondaryDragLayer) mActivity.getDragLayer()).getPinnedAppsAdapter().addPinnedApp(
|
||||
dragObject.dragInfo);
|
||||
dragObject.dragView.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragEnter(DragObject dragObject) {
|
||||
if (getDistanceDragged() > mActivity.getResources().getDimensionPixelSize(
|
||||
R.dimen.drag_distanceThreshold)) {
|
||||
mActivity.showAppDrawer(false);
|
||||
AbstractFloatingView.closeAllOpenViews(mActivity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragOver(DragObject dragObject) { }
|
||||
|
||||
@Override
|
||||
public void onDragExit(DragObject dragObject) { }
|
||||
|
||||
@Override
|
||||
public boolean acceptDrop(DragObject dragObject) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareAccessibilityDrop() { }
|
||||
|
||||
@Override
|
||||
public void getHitRectRelativeToDragLayer(Rect outRect) { }
|
||||
};
|
||||
return target;
|
||||
}
|
||||
}
|
||||
@@ -29,8 +29,12 @@ import android.widget.GridView;
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.DropTarget;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
import com.android.launcher3.dragndrop.DragView;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.popup.PopupContainerWithArrow;
|
||||
import com.android.launcher3.popup.PopupDataProvider;
|
||||
@@ -59,7 +63,8 @@ public class SecondaryDragLayer extends BaseDragLayer<SecondaryDisplayLauncher>
|
||||
|
||||
@Override
|
||||
public void recreateControllers() {
|
||||
mControllers = new TouchController[] {new CloseAllAppsTouchController()};
|
||||
mControllers = new TouchController[]{new CloseAllAppsTouchController(),
|
||||
mActivity.getDragController()};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,6 +171,10 @@ public class SecondaryDragLayer extends BaseDragLayer<SecondaryDisplayLauncher>
|
||||
}
|
||||
}
|
||||
|
||||
public PinnedAppsAdapter getPinnedAppsAdapter() {
|
||||
return mPinnedAppsAdapter;
|
||||
}
|
||||
|
||||
private boolean onIconLongClicked(View v) {
|
||||
if (!(v instanceof BubbleTextView)) {
|
||||
return false;
|
||||
@@ -183,6 +192,7 @@ public class SecondaryDragLayer extends BaseDragLayer<SecondaryDisplayLauncher>
|
||||
if (popupDataProvider == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PopupContainerWithArrow container =
|
||||
(PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
|
||||
R.layout.popup_container, mActivity.getDragLayer(), false);
|
||||
@@ -192,7 +202,42 @@ public class SecondaryDragLayer extends BaseDragLayer<SecondaryDisplayLauncher>
|
||||
Collections.emptyList(),
|
||||
Arrays.asList(mPinnedAppsAdapter.getSystemShortcut(item, v),
|
||||
APP_INFO.getShortcut(mActivity, item, v)));
|
||||
v.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
container.requestFocus();
|
||||
|
||||
if (!FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.get() || !mActivity.isAppDrawerShown()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DragOptions options = new DragOptions();
|
||||
DeviceProfile grid = mActivity.getDeviceProfile();
|
||||
options.intrinsicIconScaleFactor = (float) grid.allAppsIconSizePx / grid.iconSizePx;
|
||||
options.preDragCondition = container.createPreDragCondition(false);
|
||||
if (options.preDragCondition == null) {
|
||||
options.preDragCondition = new DragOptions.PreDragCondition() {
|
||||
private DragView<SecondaryDisplayLauncher> mDragView;
|
||||
|
||||
@Override
|
||||
public boolean shouldStartDrag(double distanceDragged) {
|
||||
return mDragView != null && mDragView.isAnimationFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreDragStart(DropTarget.DragObject dragObject) {
|
||||
mDragView = dragObject.dragView;
|
||||
if (!shouldStartDrag(0)) {
|
||||
mDragView.setOnAnimationEndCallback(() -> {
|
||||
mActivity.beginDragShared(v, mActivity.getAppsView(), options);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreDragEnd(DropTarget.DragObject dragObject, boolean dragStarted) {
|
||||
mDragView = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
mActivity.beginDragShared(v, mActivity.getAppsView(), options);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.secondarydisplay;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.dragndrop.DragView;
|
||||
|
||||
/**
|
||||
* A DragView drawn/used by the Secondary Launcher activity.
|
||||
*/
|
||||
public class SecondaryDragView extends DragView<SecondaryDisplayLauncher> {
|
||||
|
||||
public SecondaryDragView(SecondaryDisplayLauncher launcher,
|
||||
Drawable drawable,
|
||||
int registrationX, int registrationY, float initialScale, float scaleOnDrop,
|
||||
float finalScaleDps) {
|
||||
super(launcher, drawable, registrationX, registrationY, initialScale, scaleOnDrop,
|
||||
finalScaleDps);
|
||||
}
|
||||
|
||||
public SecondaryDragView(SecondaryDisplayLauncher launcher, View content, int width, int height,
|
||||
int registrationX, int registrationY, float initialScale, float scaleOnDrop,
|
||||
float finalScaleDps) {
|
||||
super(launcher, content, width, height, registrationX, registrationY, initialScale,
|
||||
scaleOnDrop, finalScaleDps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animateTo(int toTouchX, int toTouchY, Runnable onCompleteRunnable, int duration) {
|
||||
Runnable onAnimationEnd = () -> {
|
||||
if (onCompleteRunnable != null) {
|
||||
onCompleteRunnable.run();
|
||||
}
|
||||
mActivity.getDragLayer().removeView(this);
|
||||
};
|
||||
|
||||
duration = Math.max(duration,
|
||||
getResources().getInteger(R.integer.config_dropAnimMinDuration));
|
||||
|
||||
animate()
|
||||
.translationX(toTouchX - mRegistrationX)
|
||||
.translationY(toTouchY - mRegistrationY)
|
||||
.scaleX(mScaleOnDrop)
|
||||
.scaleY(mScaleOnDrop)
|
||||
.withEndAction(onAnimationEnd)
|
||||
.setDuration(duration)
|
||||
.start();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user