Merge "Inflate LauncherAppWidgetHostView directly in DragView" into sc-dev
This commit is contained in:
@@ -61,7 +61,6 @@ import com.android.launcher3.LauncherSettings.Favorites;
|
||||
import com.android.launcher3.accessibility.DragAndDropAccessibilityDelegate;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dragndrop.AppWidgetHostViewDrawable;
|
||||
import com.android.launcher3.folder.PreviewBackground;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.util.CellAndSpan;
|
||||
@@ -70,6 +69,7 @@ import com.android.launcher3.util.ParcelableSparseArray;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -1065,15 +1065,14 @@ public class CellLayout extends ViewGroup {
|
||||
private void applyColorExtractionOnWidget(DropTarget.DragObject dragObject, int[] targetCell,
|
||||
int spanX, int spanY) {
|
||||
// Apply local extracted color if the DragView is an AppWidgetHostViewDrawable.
|
||||
Drawable drawable = dragObject.dragView.getDrawable();
|
||||
if (drawable instanceof AppWidgetHostViewDrawable) {
|
||||
View view = dragObject.dragView.getContentView();
|
||||
if (view instanceof LauncherAppWidgetHostView) {
|
||||
Workspace workspace =
|
||||
Launcher.getLauncher(dragObject.dragView.getContext()).getWorkspace();
|
||||
int screenId = workspace.getIdForScreen(this);
|
||||
int pageId = workspace.getPageIndexForScreenId(screenId);
|
||||
AppWidgetHostViewDrawable hostViewDrawable = ((AppWidgetHostViewDrawable) drawable);
|
||||
cellToRect(targetCell[0], targetCell[1], spanX, spanY, mTempRect);
|
||||
hostViewDrawable.getAppWidgetHostView().handleDrag(mTempRect, pageId);
|
||||
((LauncherAppWidgetHostView) view).handleDrag(mTempRect, pageId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,6 @@ import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dot.FolderDotInfo;
|
||||
import com.android.launcher3.dragndrop.AppWidgetHostViewDrawable;
|
||||
import com.android.launcher3.dragndrop.DragController;
|
||||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
@@ -414,7 +413,9 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
}
|
||||
|
||||
if (mDragInfo != null && mDragInfo.cell != null) {
|
||||
CellLayout layout = (CellLayout) mDragInfo.cell.getParent().getParent();
|
||||
CellLayout layout = (CellLayout) (mDragInfo.cell instanceof LauncherAppWidgetHostView
|
||||
? dragObject.dragView.getContentViewParent().getParent()
|
||||
: mDragInfo.cell.getParent().getParent());
|
||||
layout.markCellsAsUnoccupiedForView(mDragInfo.cell);
|
||||
}
|
||||
|
||||
@@ -1527,10 +1528,19 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
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 = previewProvider.createDrawable();
|
||||
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;
|
||||
float scale = previewProvider.getScaleAndPosition(drawable, mTempXY);
|
||||
int dragLayerX = mTempXY[0];
|
||||
int dragLayerY = mTempXY[1];
|
||||
|
||||
@@ -1556,21 +1566,37 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
}
|
||||
}
|
||||
|
||||
if (drawable instanceof AppWidgetHostViewDrawable) {
|
||||
mDragController.addDragListener(new AppWidgetHostViewDragListener(mLauncher));
|
||||
final DragView dv;
|
||||
if (contentView instanceof View) {
|
||||
if (contentView instanceof LauncherAppWidgetHostView) {
|
||||
mDragController.addDragListener(new AppWidgetHostViewDragListener(mLauncher));
|
||||
}
|
||||
dv = mDragController.startDrag(
|
||||
contentView,
|
||||
draggableView,
|
||||
dragLayerX,
|
||||
dragLayerY,
|
||||
source,
|
||||
dragObject,
|
||||
dragVisualizeOffset,
|
||||
dragRect,
|
||||
scale * iconScale,
|
||||
scale,
|
||||
dragOptions);
|
||||
} else {
|
||||
dv = mDragController.startDrag(
|
||||
drawable,
|
||||
draggableView,
|
||||
dragLayerX,
|
||||
dragLayerY,
|
||||
source,
|
||||
dragObject,
|
||||
dragVisualizeOffset,
|
||||
dragRect,
|
||||
scale * iconScale,
|
||||
scale,
|
||||
dragOptions);
|
||||
}
|
||||
DragView dv = mDragController.startDrag(
|
||||
drawable,
|
||||
draggableView,
|
||||
dragLayerX,
|
||||
dragLayerY,
|
||||
source,
|
||||
dragObject,
|
||||
dragVisualizeOffset,
|
||||
dragRect,
|
||||
scale * iconScale,
|
||||
scale,
|
||||
dragOptions);
|
||||
return dv;
|
||||
}
|
||||
|
||||
@@ -1900,6 +1926,8 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
CellLayout parentCell = getParentCellLayoutForView(cell);
|
||||
if (parentCell != null) {
|
||||
parentCell.removeView(cell);
|
||||
} else if (mDragInfo.cell instanceof LauncherAppWidgetHostView) {
|
||||
d.dragView.detachContentView(/* reattachToPreviousParent= */ false);
|
||||
} else if (FeatureFlags.IS_STUDIO_BUILD) {
|
||||
throw new NullPointerException("mDragInfo.cell has null parent");
|
||||
}
|
||||
@@ -1938,6 +1966,9 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
if (!returnToOriginalCellToPreventShuffling) {
|
||||
onNoCellFound(dropTargetLayout);
|
||||
}
|
||||
if (mDragInfo.cell instanceof LauncherAppWidgetHostView) {
|
||||
d.dragView.detachContentView(/* reattachToPreviousParent= */ true);
|
||||
}
|
||||
|
||||
// If we can't find a drop location, we return the item to its original position
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
|
||||
@@ -2636,10 +2667,6 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
}
|
||||
|
||||
private Drawable createWidgetDrawable(ItemInfo widgetInfo, View layout) {
|
||||
if (layout instanceof LauncherAppWidgetHostView) {
|
||||
return new AppWidgetHostViewDrawable((LauncherAppWidgetHostView) layout);
|
||||
}
|
||||
|
||||
int[] unScaledSize = estimateItemSize(widgetInfo);
|
||||
int visibility = layout.getVisibility();
|
||||
layout.setVisibility(VISIBLE);
|
||||
@@ -2720,7 +2747,9 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
|
||||
boolean isWidget = info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET ||
|
||||
info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
|
||||
if ((animationType == ANIMATE_INTO_POSITION_AND_RESIZE || external) && finalView != null) {
|
||||
if ((animationType == ANIMATE_INTO_POSITION_AND_RESIZE || external)
|
||||
&& finalView != null
|
||||
&& dragView.getContentView() != finalView) {
|
||||
Drawable crossFadeDrawable = createWidgetDrawable(info, finalView);
|
||||
dragView.crossFadeContent(crossFadeDrawable, (int) (duration * 0.8f));
|
||||
} else if (isWidget && external) {
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||
|
||||
/**
|
||||
* A drawable which renders {@link LauncherAppWidgetHostView} to a canvas.
|
||||
*
|
||||
* TODO(b/183609936) Stop using that class and remove it.
|
||||
*/
|
||||
public final class AppWidgetHostViewDrawable extends Drawable {
|
||||
|
||||
private final LauncherAppWidgetHostView mAppWidgetHostView;
|
||||
private Paint mPaint = new Paint();
|
||||
|
||||
public AppWidgetHostViewDrawable(LauncherAppWidgetHostView appWidgetHostView) {
|
||||
mAppWidgetHostView = appWidgetHostView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
int saveCount = canvas.saveLayer(0, 0, getIntrinsicWidth(), getIntrinsicHeight(), mPaint);
|
||||
mAppWidgetHostView.draw(canvas);
|
||||
canvas.restoreToCount(saveCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return mAppWidgetHostView.getMeasuredWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return mAppWidgetHostView.getMeasuredHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
// This is up to app widget provider. We don't know if the host view will cover anything
|
||||
// behind the drawable.
|
||||
return PixelFormat.UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mPaint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAlpha() {
|
||||
return mPaint.getAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter colorFilter) {
|
||||
mPaint.setColorFilter(colorFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorFilter getColorFilter() {
|
||||
return mPaint.getColorFilter();
|
||||
}
|
||||
|
||||
/** Returns the {@link LauncherAppWidgetHostView}. */
|
||||
public LauncherAppWidgetHostView getAppWidgetHostView() {
|
||||
return mAppWidgetHostView;
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,8 @@ import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.DragSource;
|
||||
import com.android.launcher3.DropTarget;
|
||||
@@ -125,20 +127,23 @@ public class DragController implements DragDriver.EventListener, TouchController
|
||||
|
||||
/**
|
||||
* Starts a drag.
|
||||
* When the drag is started, the UI automatically goes into spring loaded mode. On a successful
|
||||
* drop, it is the responsibility of the {@link DropTarget} to exit out of the spring loaded
|
||||
* mode. If the drop was cancelled for some reason, the UI will automatically exit out of this mode.
|
||||
*
|
||||
* <p>When the drag is started, the UI automatically goes into spring loaded mode. On a
|
||||
* successful drop, it is the responsibility of the {@link DropTarget} to exit out of the spring
|
||||
* loaded mode. If the drop was cancelled for some reason, the UI will automatically exit out of
|
||||
* this mode.
|
||||
*
|
||||
* @param drawable The drawable to be displayed in the drag view. It will be re-scaled to the
|
||||
* enlarged size.
|
||||
* @param originalView The source view (ie. icon, widget etc.) that is being dragged
|
||||
* and which the DragView represents
|
||||
* enlarged size.
|
||||
* @param originalView The source view (ie. icon, widget etc.) that is being dragged and which
|
||||
* the DragView represents
|
||||
* @param dragLayerX The x position in the DragLayer of the left-top of the bitmap.
|
||||
* @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 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
|
||||
* Makes dragging feel more precise, e.g. you can clip out a transparent
|
||||
* border
|
||||
*/
|
||||
public DragView startDrag(
|
||||
Drawable drawable,
|
||||
@@ -152,6 +157,61 @@ public class DragController implements DragDriver.EventListener, TouchController
|
||||
float initialDragViewScale,
|
||||
float dragViewScaleOnDrop,
|
||||
DragOptions options) {
|
||||
return startDrag(drawable, /* view= */ null, originalView, dragLayerX, dragLayerY,
|
||||
source, dragInfo, dragOffset, dragRegion, initialDragViewScale, dragViewScaleOnDrop,
|
||||
options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a drag.
|
||||
*
|
||||
* <p>When the drag is started, the UI automatically goes into spring loaded mode. On a
|
||||
* successful drop, it is the responsibility of the {@link DropTarget} to exit out of the spring
|
||||
* loaded mode. If the drop was cancelled for some reason, the UI will automatically exit out of
|
||||
* this mode.
|
||||
*
|
||||
* @param view The view to be displayed in the drag view. It will be re-scaled to the
|
||||
* enlarged size.
|
||||
* @param originalView The source view (ie. icon, widget etc.) that is being dragged and which
|
||||
* the DragView represents
|
||||
* @param dragLayerX The x position in the DragLayer of the left-top of the bitmap.
|
||||
* @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 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
|
||||
*/
|
||||
public DragView startDrag(
|
||||
View view,
|
||||
DraggableView originalView,
|
||||
int dragLayerX,
|
||||
int dragLayerY,
|
||||
DragSource source,
|
||||
ItemInfo dragInfo,
|
||||
Point dragOffset,
|
||||
Rect dragRegion,
|
||||
float initialDragViewScale,
|
||||
float dragViewScaleOnDrop,
|
||||
DragOptions options) {
|
||||
return startDrag(/* drawable= */ null, view, originalView, dragLayerX, dragLayerY,
|
||||
source, dragInfo, dragOffset, dragRegion, initialDragViewScale, dragViewScaleOnDrop,
|
||||
options);
|
||||
}
|
||||
|
||||
private 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 (PROFILE_DRAWING_DURING_DRAG) {
|
||||
android.os.Debug.startMethodTracing("Launcher");
|
||||
}
|
||||
@@ -182,14 +242,25 @@ public class DragController implements DragDriver.EventListener, TouchController
|
||||
final Resources res = mLauncher.getResources();
|
||||
final float scaleDps = mIsInPreDrag
|
||||
? res.getDimensionPixelSize(R.dimen.pre_drag_view_scale) : 0f;
|
||||
final DragView dragView = mDragObject.dragView = new DragView(
|
||||
mLauncher,
|
||||
drawable,
|
||||
registrationX,
|
||||
registrationY,
|
||||
initialDragViewScale,
|
||||
dragViewScaleOnDrop,
|
||||
scaleDps);
|
||||
final DragView dragView = mDragObject.dragView = drawable != null
|
||||
? new DragView(
|
||||
mLauncher,
|
||||
drawable,
|
||||
registrationX,
|
||||
registrationY,
|
||||
initialDragViewScale,
|
||||
dragViewScaleOnDrop,
|
||||
scaleDps)
|
||||
: new DragView(
|
||||
mLauncher,
|
||||
view,
|
||||
view.getMeasuredWidth(),
|
||||
view.getMeasuredHeight(),
|
||||
registrationX,
|
||||
registrationY,
|
||||
initialDragViewScale,
|
||||
dragViewScaleOnDrop,
|
||||
scaleDps);
|
||||
dragView.setItemInfo(dragInfo);
|
||||
mDragObject.dragComplete = false;
|
||||
|
||||
|
||||
@@ -42,9 +42,11 @@ import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.dynamicanimation.animation.FloatPropertyCompat;
|
||||
import androidx.dynamicanimation.animation.SpringAnimation;
|
||||
import androidx.dynamicanimation.animation.SpringForce;
|
||||
@@ -69,6 +71,10 @@ public class DragView extends FrameLayout implements StateListener<LauncherState
|
||||
public static final int VIEW_ZOOM_DURATION = 150;
|
||||
|
||||
private final View mContent;
|
||||
// The following are only used for rendering mContent directly during drag-n-drop.
|
||||
@Nullable private ViewGroup.LayoutParams mContentViewLayoutParams;
|
||||
@Nullable private ViewGroup mContentViewParent;
|
||||
private int mContentViewInParentViewIndex = -1;
|
||||
private final int mWidth;
|
||||
private final int mHeight;
|
||||
|
||||
@@ -135,6 +141,13 @@ public class DragView extends FrameLayout implements StateListener<LauncherState
|
||||
mContent = content;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mContentViewLayoutParams = mContent.getLayoutParams();
|
||||
if (mContent.getParent() instanceof ViewGroup) {
|
||||
mContentViewParent = (ViewGroup) mContent.getParent();
|
||||
mContentViewInParentViewIndex = mContentViewParent.indexOfChild(mContent);
|
||||
mContentViewParent.removeView(mContent);
|
||||
}
|
||||
|
||||
addView(content, new LayoutParams(width, height));
|
||||
|
||||
final float scale = (width + finalScaleDps) / width;
|
||||
@@ -372,6 +385,12 @@ public class DragView extends FrameLayout implements StateListener<LauncherState
|
||||
BaseDragLayer.LayoutParams lp = new BaseDragLayer.LayoutParams(mWidth, mHeight);
|
||||
lp.customPosition = true;
|
||||
setLayoutParams(lp);
|
||||
|
||||
if (mContent != null) {
|
||||
// At the drag start, the source view visibility is set to invisible.
|
||||
mContent.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
move(touchX, touchY);
|
||||
// Post the animation to skip other expensive work happening on the first frame
|
||||
post(mAnim::start);
|
||||
@@ -430,6 +449,33 @@ public class DragView extends FrameLayout implements StateListener<LauncherState
|
||||
setTranslationY(mLastTouchY - mRegistrationY + mAnimatedShiftY);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detaches {@link #mContent}, if previously attached, from this view.
|
||||
*
|
||||
* <p>In the case of no change in the drop position, sets {@code reattachToPreviousParent} to
|
||||
* {@code true} to attach the {@link #mContent} back to its previous parent.
|
||||
*/
|
||||
public void detachContentView(boolean reattachToPreviousParent) {
|
||||
if (mContent != null && mContentViewParent != null && mContentViewInParentViewIndex >= 0) {
|
||||
removeView(mContent);
|
||||
mContent.setLayoutParams(mContentViewLayoutParams);
|
||||
if (reattachToPreviousParent) {
|
||||
mContentViewParent.addView(mContent, mContentViewInParentViewIndex);
|
||||
}
|
||||
mContentViewParent = null;
|
||||
mContentViewInParentViewIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes this view from the {@link DragLayer}.
|
||||
*
|
||||
* <p>If the drag content is a {@link #mContent}, this call doesn't reattach the
|
||||
* {@link #mContent} back to its previous parent. To reattach to previous parent, the caller
|
||||
* should call {@link #detachContentView} with {@code reattachToPreviousParent} sets to true
|
||||
* before this call.
|
||||
*/
|
||||
public void remove() {
|
||||
if (getParent() != null) {
|
||||
mDragLayer.removeView(DragView.this);
|
||||
@@ -449,9 +495,18 @@ public class DragView extends FrameLayout implements StateListener<LauncherState
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns the current {@link Drawable} that is rendered in this view. */
|
||||
public Drawable getDrawable() {
|
||||
return mContent instanceof ImageView ? ((ImageView) mContent).getDrawable() : null;
|
||||
/** Returns the current content view that is rendered in the drag view. */
|
||||
public View getContentView() {
|
||||
return mContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the previous {@link ViewGroup} parent of the {@link #mContent} before the drag
|
||||
* content is attached to this view.
|
||||
*/
|
||||
@Nullable
|
||||
public ViewGroup getContentViewParent() {
|
||||
return mContentViewParent;
|
||||
}
|
||||
|
||||
private static class SpringFloatValue {
|
||||
|
||||
@@ -29,11 +29,12 @@ import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dragndrop.AppWidgetHostViewDrawable;
|
||||
import com.android.launcher3.dragndrop.DraggableView;
|
||||
import com.android.launcher3.icons.BitmapRenderer;
|
||||
import com.android.launcher3.icons.FastBitmapDrawable;
|
||||
@@ -95,7 +96,7 @@ public class DragPreviewProvider {
|
||||
*/
|
||||
public Drawable createDrawable() {
|
||||
if (mView instanceof LauncherAppWidgetHostView) {
|
||||
return new AppWidgetHostViewDrawable((LauncherAppWidgetHostView) mView);
|
||||
return null;
|
||||
}
|
||||
|
||||
int width = 0;
|
||||
@@ -116,6 +117,18 @@ public class DragPreviewProvider {
|
||||
height + blurSizeOutline, (c) -> drawDragView(c, scale)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content view if the content should be rendered directly in
|
||||
* {@link com.android.launcher3.dragndrop.DragView}. Otherwise, returns null.
|
||||
*/
|
||||
@Nullable
|
||||
public View getContentView() {
|
||||
if (mView instanceof LauncherAppWidgetHostView) {
|
||||
return mView;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public final void generateDragOutline(Bitmap preview) {
|
||||
if (FeatureFlags.IS_STUDIO_BUILD && mOutlineGeneratorCallback != null) {
|
||||
throw new RuntimeException("Drag outline generated twice");
|
||||
@@ -152,6 +165,22 @@ public class DragPreviewProvider {
|
||||
return scale;
|
||||
}
|
||||
|
||||
/** Returns the scale and position of a given view for drag-n-drop. */
|
||||
public float getScaleAndPosition(View view, int[] outPos) {
|
||||
float scale = Launcher.getLauncher(mView.getContext())
|
||||
.getDragLayer().getLocationInDragLayer(mView, outPos);
|
||||
if (mView instanceof LauncherAppWidgetHostView) {
|
||||
// App widgets are technically scaled, but are drawn at their expected size -- so the
|
||||
// app widget scale should not affect the scale of the preview.
|
||||
scale /= ((LauncherAppWidgetHostView) mView).getScaleToFit();
|
||||
}
|
||||
|
||||
outPos[0] = Math.round(outPos[0]
|
||||
- (view.getWidth() - scale * mView.getWidth() * mView.getScaleX()) / 2);
|
||||
outPos[1] = Math.round(outPos[1] - (1 - scale) * view.getHeight() / 2 - previewPadding / 2);
|
||||
return scale;
|
||||
}
|
||||
|
||||
protected Bitmap convertPreviewToAlphaBitmap(Bitmap preview) {
|
||||
return preview.copy(Bitmap.Config.ALPHA_8, true);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.PendingAddItemInfo;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.dragndrop.AppWidgetHostViewDrawable;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
import com.android.launcher3.dragndrop.DraggableView;
|
||||
import com.android.launcher3.graphics.DragPreviewProvider;
|
||||
@@ -93,6 +92,8 @@ public class PendingItemDragHelper extends DragPreviewProvider {
|
||||
LauncherAppState app = LauncherAppState.getInstance(launcher);
|
||||
|
||||
Drawable preview = null;
|
||||
final int previewWidth;
|
||||
final int previewHeight;
|
||||
final float scale;
|
||||
final Point dragOffset;
|
||||
final Rect dragRegion;
|
||||
@@ -114,12 +115,11 @@ public class PendingItemDragHelper extends DragPreviewProvider {
|
||||
createWidgetInfo.info, maxWidth, previewSizeBeforeScale));
|
||||
}
|
||||
if (mAppWidgetHostViewPreview != null) {
|
||||
preview = new AppWidgetHostViewDrawable(mAppWidgetHostViewPreview);
|
||||
previewSizeBeforeScale[0] = mAppWidgetHostViewPreview.getMeasuredWidth();
|
||||
launcher.getDragController()
|
||||
.addDragListener(new AppWidgetHostViewDragListener(launcher));
|
||||
}
|
||||
if (preview == null) {
|
||||
if (preview == null && mAppWidgetHostViewPreview == null) {
|
||||
Drawable p = new FastBitmapDrawable(
|
||||
app.getWidgetCache().generateWidgetPreview(launcher,
|
||||
createWidgetInfo.info, maxWidth, null,
|
||||
@@ -140,7 +140,14 @@ public class PendingItemDragHelper extends DragPreviewProvider {
|
||||
previewBounds.left += padding;
|
||||
previewBounds.right -= padding;
|
||||
}
|
||||
scale = previewBounds.width() / (float) preview.getIntrinsicWidth();
|
||||
if (mAppWidgetHostViewPreview != null) {
|
||||
previewWidth = mAppWidgetHostViewPreview.getMeasuredWidth();
|
||||
previewHeight = mAppWidgetHostViewPreview.getMeasuredHeight();
|
||||
} else {
|
||||
previewWidth = preview.getIntrinsicWidth();
|
||||
previewHeight = preview.getIntrinsicHeight();
|
||||
}
|
||||
scale = previewBounds.width() / (float) previewWidth;
|
||||
launcher.getDragController().addDragListener(new WidgetHostViewLoader(launcher, mView));
|
||||
|
||||
dragOffset = null;
|
||||
@@ -152,8 +159,10 @@ public class PendingItemDragHelper extends DragPreviewProvider {
|
||||
LauncherIcons li = LauncherIcons.obtain(launcher);
|
||||
preview = new FastBitmapDrawable(
|
||||
li.createScaledBitmapWithoutShadow(icon, 0));
|
||||
previewWidth = preview.getIntrinsicWidth();
|
||||
previewHeight = preview.getIntrinsicHeight();
|
||||
li.recycle();
|
||||
scale = ((float) launcher.getDeviceProfile().iconSizePx) / preview.getIntrinsicWidth();
|
||||
scale = ((float) launcher.getDeviceProfile().iconSizePx) / previewWidth;
|
||||
|
||||
dragOffset = new Point(previewPadding / 2, previewPadding / 2);
|
||||
|
||||
@@ -181,13 +190,19 @@ public class PendingItemDragHelper extends DragPreviewProvider {
|
||||
launcher.getWorkspace().prepareDragWithProvider(this);
|
||||
|
||||
int dragLayerX = screenPos.x + previewBounds.left
|
||||
+ (int) ((scale * preview.getIntrinsicWidth() - preview.getIntrinsicWidth()) / 2);
|
||||
+ (int) ((scale * previewWidth - previewWidth) / 2);
|
||||
int dragLayerY = screenPos.y + previewBounds.top
|
||||
+ (int) ((scale * preview.getIntrinsicHeight() - preview.getIntrinsicHeight()) / 2);
|
||||
+ (int) ((scale * previewHeight - previewHeight) / 2);
|
||||
|
||||
// Start the drag
|
||||
launcher.getDragController().startDrag(preview, draggableView, dragLayerX, dragLayerY,
|
||||
source, mAddInfo, dragOffset, dragRegion, scale, scale, options);
|
||||
if (mAppWidgetHostViewPreview != null) {
|
||||
launcher.getDragController().startDrag(mAppWidgetHostViewPreview, draggableView,
|
||||
dragLayerX, dragLayerY, source, mAddInfo, dragOffset, dragRegion, scale, scale,
|
||||
options);
|
||||
} else {
|
||||
launcher.getDragController().startDrag(preview, draggableView, dragLayerX, dragLayerY,
|
||||
source, mAddInfo, dragOffset, dragRegion, scale, scale, options);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.android.launcher3.widget.dragndrop;
|
||||
|
||||
import com.android.launcher3.DropTarget;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.dragndrop.AppWidgetHostViewDrawable;
|
||||
import com.android.launcher3.dragndrop.DragController;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||
@@ -26,7 +25,6 @@ import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||
public final class AppWidgetHostViewDragListener implements DragController.DragListener {
|
||||
private final Launcher mLauncher;
|
||||
private DropTarget.DragObject mDragObject;
|
||||
private AppWidgetHostViewDrawable mAppWidgetHostViewDrawable;
|
||||
private LauncherAppWidgetHostView mAppWidgetHostView;
|
||||
|
||||
public AppWidgetHostViewDragListener(Launcher launcher) {
|
||||
@@ -35,11 +33,9 @@ public final class AppWidgetHostViewDragListener implements DragController.DragL
|
||||
|
||||
@Override
|
||||
public void onDragStart(DropTarget.DragObject dragObject, DragOptions unused) {
|
||||
if (dragObject.dragView.getDrawable() instanceof AppWidgetHostViewDrawable) {
|
||||
if (dragObject.dragView.getContentView() instanceof LauncherAppWidgetHostView) {
|
||||
mDragObject = dragObject;
|
||||
mAppWidgetHostViewDrawable =
|
||||
(AppWidgetHostViewDrawable) mDragObject.dragView.getDrawable();
|
||||
mAppWidgetHostView = mAppWidgetHostViewDrawable.getAppWidgetHostView();
|
||||
mAppWidgetHostView = (LauncherAppWidgetHostView) dragObject.dragView.getContentView();
|
||||
mAppWidgetHostView.startDrag(this);
|
||||
} else {
|
||||
mLauncher.getDragController().removeDragListener(this);
|
||||
|
||||
Reference in New Issue
Block a user