Search in sources :

Example 1 with DragLayer

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);
    }
}
Also used : AllAppsContainerView(com.android.launcher3.allapps.AllAppsContainerView) Rect(android.graphics.Rect) ArrayList(java.util.ArrayList) DragView(com.android.launcher3.dragndrop.DragView) DeviceProfile(com.android.launcher3.DeviceProfile) DragLayer(com.android.launcher3.dragndrop.DragLayer) Launcher(com.android.launcher3.Launcher) Workspace(com.android.launcher3.Workspace) WorkspaceItemInfo(com.android.launcher3.model.data.WorkspaceItemInfo)

Example 2 with DragLayer

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());
}
Also used : BaseDragLayer(com.android.launcher3.views.BaseDragLayer) Animator(android.animation.Animator) AnimatorListenerAdapter(android.animation.AnimatorListenerAdapter) SuppressLint(android.annotation.SuppressLint) AnimatorSet(android.animation.AnimatorSet) SuppressLint(android.annotation.SuppressLint)

Example 3 with DragLayer

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();
}
Also used : DragLayer(com.android.launcher3.dragndrop.DragLayer)

Example 4 with DragLayer

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;
    }
}
Also used : Rect(android.graphics.Rect) FrameLayout(android.widget.FrameLayout) InsettableFrameLayout(com.android.launcher3.InsettableFrameLayout) InsettableFrameLayout(com.android.launcher3.InsettableFrameLayout)

Example 5 with DragLayer

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;
}
Also used : DragLayer(com.android.launcher3.dragndrop.DragLayer) Rect(android.graphics.Rect)

Aggregations

DragLayer (com.android.launcher3.dragndrop.DragLayer)13 Rect (android.graphics.Rect)8 BaseDragLayer (com.android.launcher3.views.BaseDragLayer)3 AnimatorSet (android.animation.AnimatorSet)2 SuppressLint (android.annotation.SuppressLint)2 Resources (android.content.res.Resources)2 Drawable (android.graphics.drawable.Drawable)2 ViewGroup (android.view.ViewGroup)2 DeviceProfile (com.android.launcher3.DeviceProfile)2 DragView (com.android.launcher3.dragndrop.DragView)2 ItemInfo (com.android.launcher3.model.data.ItemInfo)2 Animator (android.animation.Animator)1 AnimatorListenerAdapter (android.animation.AnimatorListenerAdapter)1 ObjectAnimator (android.animation.ObjectAnimator)1 AppWidgetHostView (android.appwidget.AppWidgetHostView)1 Point (android.graphics.Point)1 GradientDrawable (android.graphics.drawable.GradientDrawable)1 Bundle (android.os.Bundle)1 View (android.view.View)1 OnDrawListener (android.view.ViewTreeObserver.OnDrawListener)1