use of com.android.launcher3.dragndrop.DragLayer in project android_packages_apps_Launcher3 by ProtonAOSP.
the class Workspace method animateWidgetDrop.
public void animateWidgetDrop(ItemInfo info, CellLayout cellLayout, final DragView dragView, final Runnable onCompleteRunnable, int animationType, final View finalView, boolean external) {
int[] finalPos = new int[2];
float[] scaleXY = new float[2];
boolean scalePreview = !(info instanceof PendingAddShortcutInfo);
getFinalPositionForDropAnimation(finalPos, scaleXY, dragView, cellLayout, info, mTargetCell, scalePreview);
Resources res = mLauncher.getResources();
final int duration = res.getInteger(R.integer.config_dropAnimMaxDuration) - 200;
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 && dragView.getContentView() != finalView) {
Drawable crossFadeDrawable = createWidgetDrawable(info, finalView);
dragView.crossFadeContent(crossFadeDrawable, (int) (duration * 0.8f));
} else if (isWidget && external) {
scaleXY[0] = scaleXY[1] = Math.min(scaleXY[0], scaleXY[1]);
}
DragLayer dragLayer = mLauncher.getDragLayer();
if (animationType == CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION) {
mLauncher.getDragLayer().animateViewIntoPosition(dragView, finalPos, 0f, 0.1f, 0.1f, DragLayer.ANIMATION_END_DISAPPEAR, onCompleteRunnable, duration);
} else {
int endStyle;
if (animationType == ANIMATE_INTO_POSITION_AND_REMAIN) {
endStyle = DragLayer.ANIMATION_END_REMAIN_VISIBLE;
} else {
endStyle = DragLayer.ANIMATION_END_DISAPPEAR;
}
Runnable onComplete = new Runnable() {
@Override
public void run() {
if (finalView != null) {
finalView.setVisibility(VISIBLE);
}
if (onCompleteRunnable != null) {
onCompleteRunnable.run();
}
}
};
dragLayer.animateViewIntoPosition(dragView, finalPos[0], finalPos[1], 1, scaleXY[0], scaleXY[1], onComplete, endStyle, duration, this);
}
}
use of com.android.launcher3.dragndrop.DragLayer in project android_packages_apps_Launcher3 by ProtonAOSP.
the class AbsSwipeUpHandler method onLauncherStart.
private void onLauncherStart() {
final T activity = mActivityInterface.getCreatedActivity();
if (mActivity != activity) {
return;
}
if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
return;
}
// RecentsView never updates the display rotation until swipe-up, force update
// RecentsOrientedState before passing to TaskViewSimulator.
mRecentsView.updateRecentsRotation();
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator().setOrientationState(mRecentsView.getPagedViewOrientedState()));
// as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
if (mGestureState.getEndTarget() != HOME) {
Runnable initAnimFactory = () -> {
mAnimationFactory = mActivityInterface.prepareRecentsUI(mDeviceState, mWasLauncherAlreadyVisible, this::onAnimatorPlaybackControllerCreated);
maybeUpdateRecentsAttachedState(false);
if (mGestureState.getEndTarget() != null) {
// Update the end target in case the gesture ended before we init.
mAnimationFactory.setEndTarget(mGestureState.getEndTarget());
}
};
if (mWasLauncherAlreadyVisible) {
// Launcher is visible, but might be about to stop. Thus, if we prepare recents
// now, it might get overridden by moveToRestState() in onStop(). To avoid this,
// wait until the next gesture (and possibly launcher) starts.
mStateCallback.runOnceAtState(STATE_GESTURE_STARTED, initAnimFactory);
} else {
initAnimFactory.run();
}
}
AbstractFloatingView.closeAllOpenViewsExcept(activity, mWasLauncherAlreadyVisible, AbstractFloatingView.TYPE_LISTENER);
if (mWasLauncherAlreadyVisible) {
mStateCallback.setState(STATE_LAUNCHER_DRAWN);
} else {
Object traceToken = TraceHelper.INSTANCE.beginSection("WTS-init");
View dragLayer = activity.getDragLayer();
dragLayer.getViewTreeObserver().addOnDrawListener(new OnDrawListener() {
boolean mHandled = false;
@Override
public void onDraw() {
if (mHandled) {
return;
}
mHandled = true;
TraceHelper.INSTANCE.endSection(traceToken);
dragLayer.post(() -> dragLayer.getViewTreeObserver().removeOnDrawListener(this));
if (activity != mActivity) {
return;
}
mStateCallback.setState(STATE_LAUNCHER_DRAWN);
}
});
}
activity.getRootView().setOnApplyWindowInsetsListener(this);
mStateCallback.setState(STATE_LAUNCHER_STARTED);
}
use of com.android.launcher3.dragndrop.DragLayer in project android_packages_apps_Launcher3 by ProtonAOSP.
the class FolderIcon method onDrop.
private void onDrop(final WorkspaceItemInfo item, DragObject d, Rect finalRect, float scaleRelativeToDragLayer, int index, boolean itemReturnedOnFailedDrop) {
item.cellX = -1;
item.cellY = -1;
DragView animateView = d.dragView;
// will not have a view to animate
if (animateView != null && mActivity instanceof Launcher) {
final Launcher launcher = (Launcher) mActivity;
DragLayer dragLayer = launcher.getDragLayer();
Rect to = finalRect;
if (to == null) {
to = new Rect();
Workspace workspace = launcher.getWorkspace();
// Set cellLayout and this to it's final state to compute final animation locations
workspace.setFinalTransitionTransform();
float scaleX = getScaleX();
float scaleY = getScaleY();
setScaleX(1.0f);
setScaleY(1.0f);
scaleRelativeToDragLayer = dragLayer.getDescendantRectRelativeToSelf(this, to);
// Finished computing final animation locations, restore current state
setScaleX(scaleX);
setScaleY(scaleY);
workspace.resetTransitionTransform();
}
int numItemsInPreview = Math.min(MAX_NUM_ITEMS_IN_PREVIEW, index + 1);
boolean itemAdded = false;
if (itemReturnedOnFailedDrop || index >= MAX_NUM_ITEMS_IN_PREVIEW) {
List<WorkspaceItemInfo> oldPreviewItems = new ArrayList<>(mCurrentPreviewItems);
mInfo.add(item, index, false);
mCurrentPreviewItems.clear();
mCurrentPreviewItems.addAll(getPreviewItemsOnPage(0));
if (!oldPreviewItems.equals(mCurrentPreviewItems)) {
int newIndex = mCurrentPreviewItems.indexOf(item);
if (newIndex >= 0) {
// If the item dropped is going to be in the preview, we update the
// index here to reflect its position in the preview.
index = newIndex;
}
mPreviewItemManager.hidePreviewItem(index, true);
mPreviewItemManager.onDrop(oldPreviewItems, mCurrentPreviewItems, item);
itemAdded = true;
} else {
removeItem(item, false);
}
}
if (!itemAdded) {
mInfo.add(item, index, true);
}
int[] center = new int[2];
float scale = getLocalCenterForIndex(index, numItemsInPreview, center);
center[0] = Math.round(scaleRelativeToDragLayer * center[0]);
center[1] = Math.round(scaleRelativeToDragLayer * center[1]);
to.offset(center[0] - animateView.getMeasuredWidth() / 2, center[1] - animateView.getMeasuredHeight() / 2);
float finalAlpha = index < MAX_NUM_ITEMS_IN_PREVIEW ? 1f : 0f;
float finalScale = scale * scaleRelativeToDragLayer;
// Account for potentially different icon sizes with non-default grid settings
if (d.dragSource instanceof AllAppsContainerView) {
DeviceProfile grid = mActivity.getDeviceProfile();
float containerScale = (1f * grid.iconSizePx / grid.allAppsIconSizePx);
finalScale *= containerScale;
}
final int finalIndex = index;
dragLayer.animateView(animateView, to, finalAlpha, finalScale, finalScale, DROP_IN_ANIMATION_DURATION, Interpolators.DEACCEL_2, () -> {
mPreviewItemManager.hidePreviewItem(finalIndex, false);
mFolder.showItem(item);
}, DragLayer.ANIMATION_END_DISAPPEAR, null);
mFolder.hideItem(item);
if (!itemAdded)
mPreviewItemManager.hidePreviewItem(index, true);
FolderNameInfos nameInfos = new FolderNameInfos();
if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
Executors.MODEL_EXECUTOR.post(() -> {
d.folderNameProvider.getSuggestedFolderName(getContext(), mInfo.contents, nameInfos);
showFinalView(finalIndex, item, nameInfos, d.logInstanceId);
});
} else {
showFinalView(finalIndex, item, nameInfos, d.logInstanceId);
}
} else {
addItem(item);
}
}
use of com.android.launcher3.dragndrop.DragLayer in project android_packages_apps_Launcher3 by ProtonAOSP.
the class Folder method animateOpen.
/**
* Opens the user folder described by the specified tag. The opening of the folder
* is animated relative to the specified View. If the View is null, no animation
* is played.
*/
private void animateOpen(List<WorkspaceItemInfo> items, int pageNo) {
Folder openFolder = getOpen(mActivityContext);
if (openFolder != null && openFolder != this) {
// Close any open folder before opening a folder.
openFolder.close(true);
}
mContent.bindItems(items);
centerAboutIcon();
mItemsInvalidated = true;
updateTextViewFocus();
mIsOpen = true;
BaseDragLayer dragLayer = mActivityContext.getDragLayer();
// There was a one-off crash where the folder had a parent already.
if (getParent() == null) {
dragLayer.addView(this);
mDragController.addDropTarget(this);
} else {
if (FeatureFlags.IS_STUDIO_BUILD) {
Log.e(TAG, "Opening folder (" + this + ") which already has a parent:" + getParent());
}
}
mContent.completePendingPageChanges();
mContent.setCurrentPage(pageNo);
// This is set to true in close(), but isn't reset to false until onDropCompleted(). This
// leads to an inconsistent state if you drag out of the folder and drag back in without
// dropping. One resulting issue is that replaceFolderWithFinalItem() can be called twice.
mDeleteFolderOnDropCompleted = false;
cancelRunningAnimations();
FolderAnimationManager fam = new FolderAnimationManager(this, true);
AnimatorSet anim = fam.getAnimator();
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mFolderIcon.setIconVisible(false);
mFolderIcon.drawLeaveBehindIfExists();
}
@Override
public void onAnimationEnd(Animator animation) {
mState = STATE_OPEN;
announceAccessibilityChanges();
AccessibilityManagerCompat.sendFolderOpenedEventToTest(getContext());
mContent.setFocusOnFirstChild();
}
});
// Footer animation
if (mContent.getPageCount() > 1 && !mInfo.hasOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION)) {
int footerWidth = mContent.getDesiredWidth() - mFooter.getPaddingLeft() - mFooter.getPaddingRight();
float textWidth = mFolderName.getPaint().measureText(mFolderName.getText().toString());
float translation = (footerWidth - textWidth) / 2;
mFolderName.setTranslationX(mContent.mIsRtl ? -translation : translation);
mPageIndicator.prepareEntryAnimation();
// Do not update the flag if we are in drag mode. The flag will be updated, when we
// actually drop the icon.
final boolean updateAnimationFlag = !mDragInProgress;
anim.addListener(new AnimatorListenerAdapter() {
@SuppressLint("InlinedApi")
@Override
public void onAnimationEnd(Animator animation) {
mFolderName.animate().setDuration(FOLDER_NAME_ANIMATION_DURATION).translationX(0).setInterpolator(AnimationUtils.loadInterpolator(getContext(), android.R.interpolator.fast_out_slow_in));
mPageIndicator.playEntryAnimation();
if (updateAnimationFlag) {
mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true, mLauncherDelegate.getModelWriter());
}
}
});
} else {
mFolderName.setTranslationX(0);
}
mPageIndicator.stopAllAnimations();
startAnimation(anim);
// Because t=0 has the folder match the folder icon, we can skip the
// first frame and have the same movement one frame earlier.
anim.setCurrentPlayTime(Math.min(getSingleFrameMs(getContext()), anim.getTotalDuration()));
// Make sure the folder picks up the last drag move even if the finger doesn't move.
if (mDragController.isDragging()) {
mDragController.forceTouchMove();
}
mContent.verifyVisibleHighResIcons(mContent.getNextPage());
}
use of com.android.launcher3.dragndrop.DragLayer in project android_packages_apps_Launcher3 by ProtonAOSP.
the class Launcher method addAppWidgetFromDrop.
/**
* Process a widget drop.
*/
private void addAppWidgetFromDrop(PendingAddWidgetInfo info) {
AppWidgetHostView hostView = info.boundWidget;
final int appWidgetId;
WidgetAddFlowHandler addFlowHandler = info.getHandler();
if (hostView != null) {
// In the case where we've prebound the widget, we remove it from the DragLayer
if (LOGD) {
Log.d(TAG, "Removing widget view from drag layer and setting boundWidget to null");
}
getDragLayer().removeView(hostView);
appWidgetId = hostView.getAppWidgetId();
addAppWidgetFromDropImpl(appWidgetId, info, hostView, addFlowHandler);
// Clear the boundWidget so that it doesn't get destroyed.
info.boundWidget = null;
} else {
// the widget, or we need to start an activity to configure the widget, or both.
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET) {
appWidgetId = CustomWidgetManager.INSTANCE.get(this).getWidgetIdForCustomProvider(info.componentName);
} else {
appWidgetId = getAppWidgetHost().allocateAppWidgetId();
}
Bundle options = info.bindOptions;
boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, info.info, options);
if (success) {
addAppWidgetFromDropImpl(appWidgetId, info, null, addFlowHandler);
} else {
addFlowHandler.startBindFlow(this, appWidgetId, info, REQUEST_BIND_APPWIDGET);
}
}
}
Aggregations