Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d06bb89 authored by Tracy Zhou's avatar Tracy Zhou Committed by Android (Google) Code Review
Browse files

Merge "Update initial staged split UX." into tm-dev

parents 6c7b0f7d 4ff3615b
Loading
Loading
Loading
Loading
+3 −10
Original line number Diff line number Diff line
@@ -42,8 +42,6 @@ public class FloatingTaskThumbnailView extends View {
    private @Nullable BitmapShader mBitmapShader;
    private @Nullable Bitmap mBitmap;

    private FloatingTaskView.FullscreenDrawParams mFullscreenParams;

    public FloatingTaskThumbnailView(Context context) {
        this(context, null);
    }
@@ -58,7 +56,7 @@ public class FloatingTaskThumbnailView extends View {

    @Override
    protected void onDraw(Canvas canvas) {
        if (mFullscreenParams == null || mBitmap == null) {
        if (mBitmap == null) {
            return;
        }

@@ -67,9 +65,8 @@ public class FloatingTaskThumbnailView extends View {
        mMatrix.postScale(scale, scale);
        mBitmapShader.setLocalMatrix(mMatrix);

        canvas.drawRoundRect(0, 0, getMeasuredWidth(),  getMeasuredHeight(),
                mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleX,
                mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleY, mPaint);
        FloatingTaskView parent = (FloatingTaskView) getParent();
        parent.drawRoundedRect(canvas, mPaint);
    }

    public void setThumbnail(Bitmap bitmap) {
@@ -79,8 +76,4 @@ public class FloatingTaskThumbnailView extends View {
            mPaint.setShader(mBitmapShader);
        }
    }

    public void setFullscreenParams(FloatingTaskView.FullscreenDrawParams fullscreenParams) {
        mFullscreenParams = fullscreenParams;
    }
}
+43 −32
Original line number Diff line number Diff line
@@ -3,11 +3,12 @@ package com.android.quickstep.views;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
@@ -31,15 +32,13 @@ import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.TaskCornerRadius;
import com.android.systemui.shared.system.QuickStepContract;

import java.util.function.Consumer;

/**
 * Create an instance via
 * {@link #getFloatingTaskView(StatefulActivity, View, Bitmap, Drawable, RectF, Consumer)} to
 * {@link #getFloatingTaskView(StatefulActivity, View, Bitmap, Drawable, RectF)} to
 * which will have the thumbnail from the provided existing TaskView overlaying the taskview itself.
 *
 * Can then animate the taskview using
 * {@link #addAnimation(PendingAnimation, RectF, Rect, View, boolean)}
 * {@link #addAnimation(PendingAnimation, RectF, Rect, boolean, boolean)}
 * giving a starting and ending bounds. Currently this is set to use the split placeholder view,
 * but it could be generified.
 *
@@ -47,13 +46,13 @@ import java.util.function.Consumer;
 */
public class FloatingTaskView extends FrameLayout {

    private FloatingTaskThumbnailView mThumbnailView;
    private SplitPlaceholderView mSplitPlaceholderView;
    private RectF mStartingPosition;
    private final StatefulActivity mActivity;
    private final boolean mIsRtl;
    private final FullscreenDrawParams mCurrentFullscreenParams;
    private final FullscreenDrawParams mFullscreenParams;
    private PagedOrientationHandler mOrientationHandler;
    private FloatingTaskThumbnailView mThumbnailView;

    public FloatingTaskView(Context context) {
        this(context, null);
@@ -67,17 +66,15 @@ public class FloatingTaskView extends FrameLayout {
        super(context, attrs, defStyleAttr);
        mActivity = BaseActivity.fromContext(context);
        mIsRtl = Utilities.isRtl(getResources());
        mCurrentFullscreenParams = new FullscreenDrawParams(context);
        mFullscreenParams = new FullscreenDrawParams(context);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mThumbnailView = findViewById(R.id.thumbnail);
        mThumbnailView.setFullscreenParams(mCurrentFullscreenParams);
        mSplitPlaceholderView = findViewById(R.id.split_placeholder);
        mSplitPlaceholderView.setAlpha(0);
        mSplitPlaceholderView.setFullscreenParams(mCurrentFullscreenParams);
    }

    private void init(StatefulActivity launcher, View originalView, @Nullable Bitmap thumbnail,
@@ -97,17 +94,13 @@ public class FloatingTaskView extends FrameLayout {
        RecentsView recentsView = launcher.getOverviewPanel();
        mOrientationHandler = recentsView.getPagedOrientationHandler();
        mSplitPlaceholderView.setIcon(icon,
                launcher.getDeviceProfile().overviewTaskIconDrawableSizePx);
                mContext.getResources().getDimensionPixelSize(R.dimen.split_placeholder_icon_size));
        mSplitPlaceholderView.getIconView().setRotation(mOrientationHandler.getDegreesRotated());
    }

    /**
     * Configures and returns a an instance of {@link FloatingTaskView} initially matching the
     * appearance of {@code originalView}.
     *
     * @param additionalOffsetter optional, to set additional offsets to the FloatingTaskView
     *                               to account for translations. If {@code null} then the
     *                               translation values from originalView will be used
     */
    public static FloatingTaskView getFloatingTaskView(StatefulActivity launcher,
            View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut) {
@@ -133,21 +126,22 @@ public class FloatingTaskView extends FrameLayout {
        setLayoutParams(lp);
    }

    public void update(RectF position, float progress) {
    public void update(RectF bounds, float progress) {
        MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();

        float dX = position.left - mStartingPosition.left;
        float dY = position.top - lp.topMargin;
        float scaleX = position.width() / lp.width;
        float scaleY = position.height() / lp.height;
        float dX = bounds.left - mStartingPosition.left;
        float dY = bounds.top - lp.topMargin;
        float scaleX = bounds.width() / lp.width;
        float scaleY = bounds.height() / lp.height;

        mCurrentFullscreenParams.updateParams(position, progress, scaleX, scaleY);
        mFullscreenParams.updateParams(bounds, progress, scaleX, scaleY);

        setTranslationX(dX);
        setTranslationY(dY);
        setScaleX(scaleX);
        setScaleY(scaleY);
        mSplitPlaceholderView.invalidate();
        mThumbnailView.invalidate();

        float childScaleX = 1f / scaleX;
        float childScaleY = 1f / scaleY;
@@ -178,8 +172,8 @@ public class FloatingTaskView extends FrameLayout {
    }

    public void addAnimation(PendingAnimation animation, RectF startingBounds, Rect endBounds,
            boolean fadeWithThumbnail, boolean isInitialSplit) {
        mCurrentFullscreenParams.setIsInitialSplit(isInitialSplit);
            boolean fadeWithThumbnail, boolean isStagedTask) {
        mFullscreenParams.setIsStagedTask(isStagedTask);
        final BaseDragLayer dragLayer = mActivity.getDragLayer();
        int[] dragLayerBounds = new int[2];
        dragLayer.getLocationOnScreen(dragLayerBounds);
@@ -219,6 +213,25 @@ public class FloatingTaskView extends FrameLayout {
        transitionAnimator.addUpdateListener(listener);
    }

    public void drawRoundedRect(Canvas canvas, Paint paint) {
        if (mFullscreenParams == null) {
            return;
        }

        canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(),
                mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleX,
                mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleY,
                paint);
    }

    public float getFullscreenScaleX() {
        return mFullscreenParams.mScaleX;
    }

    public float getFullscreenScaleY() {
        return mFullscreenParams.mScaleY;
    }

    private static class SplitOverlayProperties {

        private final float finalTaskViewScaleX;
@@ -247,9 +260,8 @@ public class FloatingTaskView extends FrameLayout {

        private final float mCornerRadius;
        private final float mWindowCornerRadius;

        public boolean mIsInitialSplit = true;
        public final RectF mFloatingTaskViewBounds = new RectF();
        public boolean mIsStagedTask;
        public final RectF mBounds = new RectF();
        public float mCurrentDrawnCornerRadius;
        public float mScaleX = 1;
        public float mScaleY = 1;
@@ -261,17 +273,16 @@ public class FloatingTaskView extends FrameLayout {
            mCurrentDrawnCornerRadius = mCornerRadius;
        }

        public void updateParams(RectF floatingTaskViewBounds, float progress, float scaleX,
                float scaleY) {
            mFloatingTaskViewBounds.set(floatingTaskViewBounds);
        public void updateParams(RectF bounds, float progress, float scaleX, float scaleY) {
            mBounds.set(bounds);
            mScaleX = scaleX;
            mScaleY = scaleY;
            mCurrentDrawnCornerRadius = mIsInitialSplit ? 0 :
            mCurrentDrawnCornerRadius = mIsStagedTask ? mWindowCornerRadius :
                    Utilities.mapRange(progress, mCornerRadius, mWindowCornerRadius);
        }

        public void setIsInitialSplit(boolean isInitialSplit) {
            mIsInitialSplit = isInitialSplit;
        public void setIsStagedTask(boolean isStagedTask) {
            mIsStagedTask = isStagedTask;
        }
    }
}
+9 −7
Original line number Diff line number Diff line
@@ -425,6 +425,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
    private final int mScrollHapticMinGapMillis;
    private final RecentsModel mModel;
    private final int mSplitPlaceholderSize;
    private final int mSplitPlaceholderInset;
    private final ClearAllButton mClearAllButton;
    private final Rect mClearAllButtonDeadZoneRect = new Rect();
    private final Rect mTaskViewDeadZoneRect = new Rect();
@@ -697,6 +698,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
        setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
        mSplitPlaceholderSize = getResources().getDimensionPixelSize(
                R.dimen.split_placeholder_size);
        mSplitPlaceholderInset = getResources().getDimensionPixelSize(
                R.dimen.split_placeholder_inset);
        mSquaredTouchSlop = squaredTouchSlop(context);

        mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
@@ -2702,7 +2705,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
     */
    private void createInitialSplitSelectAnimation(PendingAnimation anim) {
        mOrientationHandler.getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
                mActivity.getDeviceProfile(),
                mSplitPlaceholderInset, mActivity.getDeviceProfile(),
                mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);

        RectF startingTaskRect = new RectF();
@@ -2714,7 +2717,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
                    mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect);
            mFirstFloatingTaskView.setAlpha(1);
            mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
                    mTempRect, true /* fadeWithThumbnail */, true /* isInitialSplit */);
                    mTempRect, true /* fadeWithThumbnail */, true /* isStagedTask */);
        } else {
            mSplitSelectSource.view.setVisibility(INVISIBLE);
            mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
@@ -2722,7 +2725,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
                    mSplitSelectSource.drawable, startingTaskRect);
            mFirstFloatingTaskView.setAlpha(1);
            mFirstFloatingTaskView.addAnimation(anim, startingTaskRect,
                    mTempRect, true /* fadeWithThumbnail */, true /* isInitialSplit */);
                    mTempRect, true /* fadeWithThumbnail */, true /* isStagedTask */);
        }
        anim.addEndListener(success -> {
            if (success) {
@@ -4002,14 +4005,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
        mFirstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);
        mFirstFloatingTaskView.addAnimation(pendingAnimation,
                new RectF(firstTaskStartingBounds), firstTaskEndingBounds,
                false /* fadeWithThumbnail */, false /* isInitialSplit */);
                false /* fadeWithThumbnail */, true /* isStagedTask */);

        mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
                thumbnailView, thumbnailView.getThumbnail(),
                iconView.getDrawable(), secondTaskStartingBounds);
        mSecondFloatingTaskView.setAlpha(1);
        mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
                secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isInitialSplit */);
                secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */);
        pendingAnimation.addEndListener(aBoolean ->
                mSplitSelectStateController.setSecondTask(
                        task, aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
@@ -4077,10 +4080,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T

    protected void onRotateInSplitSelectionState() {
        mOrientationHandler.getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
                mActivity.getDeviceProfile(),
                mSplitPlaceholderInset, mActivity.getDeviceProfile(),
                mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
        mTempRectF.set(mTempRect);
        // TODO(194414938) set correct corner radius
        mFirstFloatingTaskView.updateOrientationHandler(mOrientationHandler);
        mFirstFloatingTaskView.update(mTempRectF, /*progress=*/1f);

+20 −18
Original line number Diff line number Diff line
@@ -19,11 +19,11 @@ package com.android.quickstep.views;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.FrameLayout;

import androidx.annotation.Nullable;
@@ -31,8 +31,7 @@ import androidx.annotation.Nullable;
public class SplitPlaceholderView extends FrameLayout {

    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private FloatingTaskView.FullscreenDrawParams mFullscreenParams;
    private final Rect mTempRect = new Rect();

    public static final FloatProperty<SplitPlaceholderView> ALPHA_FLOAT =
            new FloatProperty<SplitPlaceholderView>("SplitViewAlpha") {
@@ -54,7 +53,7 @@ public class SplitPlaceholderView extends FrameLayout {
    public SplitPlaceholderView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mPaint.setColor(getThemePrimaryColor(context));
        mPaint.setColor(getThemeBackgroundColor(context));
        setWillNotDraw(false);
    }

@@ -64,6 +63,19 @@ public class SplitPlaceholderView extends FrameLayout {
        drawBackground(canvas);

        super.dispatchDraw(canvas);

        if (mIconView != null) {
            // Center the icon view in the visible area.
            getLocalVisibleRect(mTempRect);
            FloatingTaskView parent = (FloatingTaskView) getParent();
            FrameLayout.LayoutParams params =
                    (FrameLayout.LayoutParams) mIconView.getLayoutParams();
            params.leftMargin = Math.round(mTempRect.centerX() / parent.getFullscreenScaleX()
                    - 1.0f * mIconView.getDrawableWidth() / 2);
            params.topMargin = Math.round(mTempRect.centerY() / parent.getFullscreenScaleY()
                    - 1.0f * mIconView.getDrawableHeight() / 2);
            mIconView.setLayoutParams(params);
        }
    }

    @Nullable
@@ -71,10 +83,6 @@ public class SplitPlaceholderView extends FrameLayout {
        return mIconView;
    }

    public void setFullscreenParams(FloatingTaskView.FullscreenDrawParams fullscreenParams) {
        mFullscreenParams = fullscreenParams;
    }

    public void setIcon(Drawable drawable, int iconSize) {
        if (mIconView == null) {
            mIconView = new IconView(getContext());
@@ -83,23 +91,17 @@ public class SplitPlaceholderView extends FrameLayout {
        mIconView.setDrawable(drawable);
        mIconView.setDrawableSize(iconSize, iconSize);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(iconSize, iconSize);
        params.gravity = Gravity.CENTER;
        mIconView.setLayoutParams(params);
    }

    private void drawBackground(Canvas canvas) {
        if (mFullscreenParams == null) {
            return;
        }

        canvas.drawRoundRect(0, 0, getMeasuredWidth(),  getMeasuredHeight(),
                mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleX,
                mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleY, mPaint);
        FloatingTaskView parent = (FloatingTaskView) getParent();
        parent.drawRoundedRect(canvas, mPaint);
    }

    private static int getThemePrimaryColor(Context context) {
    private static int getThemeBackgroundColor(Context context) {
        final TypedValue value = new TypedValue();
        context.getTheme().resolveAttribute(android.R.attr.colorPrimary, value, true);
        context.getTheme().resolveAttribute(android.R.attr.colorBackground, value, true);
        return value.data;
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -359,7 +359,9 @@
    <dimen name="overview_grid_side_margin">0dp</dimen>
    <dimen name="overview_grid_row_spacing">0dp</dimen>
    <dimen name="overview_page_spacing">0dp</dimen>
    <dimen name="split_placeholder_size">110dp</dimen>
    <dimen name="split_placeholder_size">72dp</dimen>
    <dimen name="split_placeholder_inset">16dp</dimen>
    <dimen name="split_placeholder_icon_size">44dp</dimen>
    <dimen name="task_menu_width_grid">200dp</dimen>


Loading