Merge "Update initial staged split UX." into tm-dev
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java
index cfb0056..98e50f6 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java
@@ -42,8 +42,6 @@
private @Nullable BitmapShader mBitmapShader;
private @Nullable Bitmap mBitmap;
- private FloatingTaskView.FullscreenDrawParams mFullscreenParams;
-
public FloatingTaskThumbnailView(Context context) {
this(context, null);
}
@@ -58,7 +56,7 @@
@Override
protected void onDraw(Canvas canvas) {
- if (mFullscreenParams == null || mBitmap == null) {
+ if (mBitmap == null) {
return;
}
@@ -67,9 +65,8 @@
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 @@
mPaint.setShader(mBitmapShader);
}
}
-
- public void setFullscreenParams(FloatingTaskView.FullscreenDrawParams fullscreenParams) {
- mFullscreenParams = fullscreenParams;
- }
}
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index c59dc18..93a3a9f 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -3,11 +3,12 @@
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.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 @@
*/
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 @@
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 @@
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 @@
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 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 @@
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 @@
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 @@
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;
}
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 3c10e21..395bfb1 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -425,6 +425,7 @@
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 @@
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 @@
*/
private void createInitialSplitSelectAnimation(PendingAnimation anim) {
mOrientationHandler.getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
- mActivity.getDeviceProfile(),
+ mSplitPlaceholderInset, mActivity.getDeviceProfile(),
mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
RectF startingTaskRect = new RectF();
@@ -2714,7 +2717,7 @@
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 @@
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 @@
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 @@
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);
diff --git a/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java b/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
index d37dfbf..7444217 100644
--- a/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
@@ -19,11 +19,11 @@
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 @@
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 SplitPlaceholderView(Context context, AttributeSet attrs) {
super(context, attrs);
- mPaint.setColor(getThemePrimaryColor(context));
+ mPaint.setColor(getThemeBackgroundColor(context));
setWillNotDraw(false);
}
@@ -64,6 +63,19 @@
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 @@
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 @@
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;
}
}
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a6abee2..0615053 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -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>
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 217a558..4fcba18 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -394,12 +394,21 @@
}
@Override
- public void getInitialSplitPlaceholderBounds(int placeholderHeight, DeviceProfile dp,
- @StagePosition int stagePosition, Rect out) {
+ public void getInitialSplitPlaceholderBounds(int placeholderHeight, int placeholderInset,
+ DeviceProfile dp, @StagePosition int stagePosition, Rect out) {
// In fake land/seascape, the placeholder always needs to go to the "top" of the device,
// which is the same bounds as 0 rotation.
int width = dp.widthPx;
out.set(0, 0, width, placeholderHeight);
+ out.inset(placeholderInset, 0);
+
+ // Adjust the top to account for content off screen. This will help to animate the view in
+ // with rounded corners.
+ int screenWidth = dp.widthPx;
+ int screenHeight = dp.heightPx;
+ int totalHeight = (int) (1.0f * screenHeight / 2 * (screenWidth - 2 * placeholderInset)
+ / screenWidth);
+ out.top -= (totalHeight - placeholderHeight);
}
@Override
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index 1b17126..850eaaf 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -110,10 +110,10 @@
int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect);
List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp);
/**
- * @param splitholderSize height of placeholder view in portrait, width in landscape
+ * @param placeholderHeight height of placeholder view in portrait, width in landscape
*/
- void getInitialSplitPlaceholderBounds(int splitholderSize, DeviceProfile dp,
- @StagePosition int stagePosition, Rect out);
+ void getInitialSplitPlaceholderBounds(int placeholderHeight, int placeholderInset,
+ DeviceProfile dp, @StagePosition int stagePosition, Rect out);
/**
* @param splitDividerSize height of split screen drag handle in portrait, width in landscape
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 7e1cb25..d132901 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -436,29 +436,48 @@
}
@Override
- public void getInitialSplitPlaceholderBounds(int placeholderHeight, DeviceProfile dp,
- @StagePosition int stagePosition, Rect out) {
- int width = dp.widthPx;
- out.set(0, 0, width, placeholderHeight);
+ public void getInitialSplitPlaceholderBounds(int placeholderHeight, int placeholderInset,
+ DeviceProfile dp, @StagePosition int stagePosition, Rect out) {
+ int screenWidth = dp.widthPx;
+ int screenHeight = dp.heightPx;
+ out.set(0, 0, screenWidth, placeholderHeight);
if (!dp.isLandscape) {
// portrait, phone or tablet - spans width of screen, nothing else to do
+ out.inset(placeholderInset, 0);
+
+ // Adjust the top to account for content off screen. This will help to animate the view
+ // in with rounded corners.
+ int totalHeight = (int) (1.0f * screenHeight / 2 * (screenWidth - 2 * placeholderInset)
+ / screenWidth);
+ out.top -= (totalHeight - placeholderHeight);
return;
}
// Now we rotate the portrait rect depending on what side we want pinned
boolean pinToRight = stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
- int screenHeight = dp.heightPx;
- float postRotateScale = (float) screenHeight / width;
+ float postRotateScale = (float) screenHeight / screenWidth;
mTmpMatrix.reset();
mTmpMatrix.postRotate(pinToRight ? 90 : 270);
- mTmpMatrix.postTranslate(pinToRight ? width : 0, pinToRight ? 0 : width);
+ mTmpMatrix.postTranslate(pinToRight ? screenWidth : 0, pinToRight ? 0 : screenWidth);
// The placeholder height stays constant after rotation, so we don't change width scale
mTmpMatrix.postScale(1, postRotateScale);
mTmpRectF.set(out);
mTmpMatrix.mapRect(mTmpRectF);
+ mTmpRectF.inset(0, placeholderInset);
mTmpRectF.roundOut(out);
+
+ // Adjust the top to account for content off screen. This will help to animate the view in
+ // with rounded corners.
+ int totalWidth = (int) (1.0f * screenWidth / 2 * (screenHeight - 2 * placeholderInset)
+ / screenHeight);
+ int width = out.width();
+ if (pinToRight) {
+ out.right += totalWidth - width;
+ } else {
+ out.left -= totalWidth - width;
+ }
}
@Override