use of com.android.launcher3.dragndrop.DragLayer in project android_packages_apps_Launcher3 by crdroidandroid.
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 from = new Rect();
dragLayer.getViewRectRelativeToSelf(animateView, from);
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, from, to, finalAlpha, 1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION, Interpolators.DEACCEL_2, Interpolators.ACCEL_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 crdroidandroid.
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();
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 crdroidandroid.
the class LauncherAppWidgetHostView method onInterceptTouchEvent.
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
DragLayer dragLayer = mLauncher.getDragLayer();
if (mIsScrollable) {
dragLayer.requestDisallowInterceptTouchEvent(true);
}
dragLayer.setTouchCompleteListener(this);
}
mLongPressHelper.onTouchEvent(ev);
return mLongPressHelper.hasPerformedLongPress();
}
use of com.android.launcher3.dragndrop.DragLayer in project android_packages_apps_Launcher3 by crdroidandroid.
the class ArrowPopup method orientAboutObject.
/**
* @see #orientAboutObject()
*
* @param allowAlignLeft Set to false if we already tried aligning left and didn't have room.
* @param allowAlignRight Set to false if we already tried aligning right and didn't have room.
* TODO: Can we test this with all permutations of widths/heights and icon locations + RTL?
*/
private void orientAboutObject(boolean allowAlignLeft, boolean allowAlignRight) {
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
int extraVerticalSpace = mArrowHeight + mArrowOffsetVertical + getResources().getDimensionPixelSize(R.dimen.popup_vertical_padding);
// The margins are added after we call this method, so we need to account for them here.
int numVisibleChildren = 0;
for (int i = getChildCount() - 1; i >= 0; --i) {
if (getChildAt(i).getVisibility() == VISIBLE) {
numVisibleChildren++;
}
}
int childMargins = (numVisibleChildren - 1) * mMargin;
int height = getMeasuredHeight() + extraVerticalSpace + childMargins;
int width = getMeasuredWidth() + getPaddingLeft() + getPaddingRight();
getTargetObjectLocation(mTempRect);
InsettableFrameLayout dragLayer = getPopupContainer();
Rect insets = dragLayer.getInsets();
// Align left (right in RTL) if there is room.
int leftAlignedX = mTempRect.left;
int rightAlignedX = mTempRect.right - width;
mIsLeftAligned = !mIsRtl ? allowAlignLeft : !allowAlignRight;
int x = mIsLeftAligned ? leftAlignedX : rightAlignedX;
// Offset x so that the arrow and shortcut icons are center-aligned with the original icon.
int iconWidth = mTempRect.width();
int xOffset = iconWidth / 2 - mArrowOffsetHorizontal - mArrowWidth / 2;
x += mIsLeftAligned ? xOffset : -xOffset;
// Check whether we can still align as we originally wanted, now that we've calculated x.
if (!allowAlignLeft && !allowAlignRight) {
// We've already tried both ways and couldn't make it fit. onLayout() will set the
// gravity to CENTER_HORIZONTAL, but continue below to update y.
} else {
boolean canBeLeftAligned = x + width + insets.left < dragLayer.getWidth() - insets.right;
boolean canBeRightAligned = x > insets.left;
boolean alignmentStillValid = mIsLeftAligned && canBeLeftAligned || !mIsLeftAligned && canBeRightAligned;
if (!alignmentStillValid) {
// Try again, but don't allow this alignment we already know won't work.
orientAboutObject(allowAlignLeft && !mIsLeftAligned, /* allowAlignLeft */
allowAlignRight && mIsLeftAligned);
return;
}
}
// Open above icon if there is room.
int iconHeight = mTempRect.height();
int y = mTempRect.top - height;
mIsAboveIcon = y > dragLayer.getTop() + insets.top;
if (!mIsAboveIcon) {
y = mTempRect.top + iconHeight + extraVerticalSpace;
}
// Insets are added later, so subtract them now.
x -= insets.left;
y -= insets.top;
mGravity = 0;
if (y + height > dragLayer.getBottom() - insets.bottom) {
// The container is opening off the screen, so just center it in the drag layer instead.
mGravity = Gravity.CENTER_VERTICAL;
// Put the container next to the icon, preferring the right side in ltr (left in rtl).
int rightSide = leftAlignedX + iconWidth - insets.left;
int leftSide = rightAlignedX - iconWidth - insets.left;
if (!mIsRtl) {
if (rightSide + width < dragLayer.getRight()) {
x = rightSide;
mIsLeftAligned = true;
} else {
x = leftSide;
mIsLeftAligned = false;
}
} else {
if (leftSide > dragLayer.getLeft()) {
x = leftSide;
mIsLeftAligned = false;
} else {
x = rightSide;
mIsLeftAligned = true;
}
}
mIsAboveIcon = true;
}
setX(x);
if (Gravity.isVertical(mGravity)) {
return;
}
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
FrameLayout.LayoutParams arrowLp = (FrameLayout.LayoutParams) mArrow.getLayoutParams();
if (mIsAboveIcon) {
arrowLp.gravity = lp.gravity = Gravity.BOTTOM;
lp.bottomMargin = getPopupContainer().getHeight() - y - getMeasuredHeight() - insets.top;
arrowLp.bottomMargin = lp.bottomMargin - arrowLp.height - mArrowOffsetVertical - insets.bottom;
} else {
arrowLp.gravity = lp.gravity = Gravity.TOP;
lp.topMargin = y + insets.top;
arrowLp.topMargin = lp.topMargin - insets.top - arrowLp.height - mArrowOffsetVertical;
}
}
use of com.android.launcher3.dragndrop.DragLayer in project android_packages_apps_Launcher3 by crdroidandroid.
the class ButtonDropTarget method getIconRect.
public Rect getIconRect(DragObject dragObject) {
int viewWidth = dragObject.dragView.getMeasuredWidth();
int viewHeight = dragObject.dragView.getMeasuredHeight();
int drawableWidth = mDrawable.getIntrinsicWidth();
int drawableHeight = mDrawable.getIntrinsicHeight();
DragLayer dragLayer = mLauncher.getDragLayer();
// Find the rect to animate to (the view is center aligned)
Rect to = new Rect();
dragLayer.getViewRectRelativeToSelf(this, to);
final int width = drawableWidth;
final int height = drawableHeight;
final int left;
final int right;
if (Utilities.isRtl(getResources())) {
right = to.right - getPaddingRight();
left = right - width;
} else {
left = to.left + getPaddingLeft();
right = left + width;
}
final int top = to.top + (getMeasuredHeight() - height) / 2;
final int bottom = top + height;
to.set(left, top, right, bottom);
// Center the destination rect about the trash icon
final int xOffset = -(viewWidth - width) / 2;
final int yOffset = -(viewHeight - height) / 2;
to.offset(xOffset, yOffset);
return to;
}
Aggregations