Implement swipe gesture for staged split in landscape
* Maintain task split percentages when swiping up.
* Split percentages not maintained in GroupedTaskView, however.
That is a TODO.
Bug: 181704764, 181705607
Test: Swiped up in landscape with home rotation on/off.
Portrait still works.
Change-Id: Iec62abae34f6ccadf98e2afdc9409cf3160f8223
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index e2ef3bc..6298bb8 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -53,7 +53,6 @@
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.views.ScrimView;
import com.android.quickstep.SysUINavigationMode.Mode;
@@ -203,33 +202,6 @@
}
/**
- * Sets the task size in {@param outRect} taking split screened windows into account.
- * We assume combined height of both tasks will be same as one normal task, then we'll modify
- * the task height/width based on the ratio of task screen space bounds from
- * {@param splitInfo}
- *
- * @param desiredStageBounds whether task size for top/left or bottom/right needs to be computed
- */
- public final void calculateStagedSplitTaskSize(Context context, DeviceProfile dp, Rect outRect,
- SplitConfigurationOptions.StagedSplitBounds splitInfo,
- @SplitConfigurationOptions.StagePosition int desiredStageBounds) {
- calculateTaskSize(context, dp, outRect);
-
- // TODO(b/181705607) Change for landscape vs portrait
- float totalHeight = splitInfo.mLeftTopBounds.height()
- + splitInfo.mRightBottomBounds.height()
- + splitInfo.mDividerBounds.height() / 2f;
- float topTaskPercent = splitInfo.mLeftTopBounds.height() / totalHeight;
- if (desiredStageBounds == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
- float diff = outRect.height() * (1f - topTaskPercent);
- outRect.bottom -= diff;
- } else {
- float diff = outRect.height() * topTaskPercent;
- outRect.top += diff;
- }
- }
-
- /**
* Calculates the taskView size for the provided device configuration.
*/
public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect) {
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 7b1c62e..760f665 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -145,8 +145,9 @@
// The task rect changes according to the staged split task sizes, but recents
// fullscreen scale and pivot remains the same since the task fits into the existing
// sized task space bounds
- mSizeStrategy.calculateStagedSplitTaskSize(mContext, mDp, mTaskRect, mStagedSplitBounds,
- mStagePosition);
+ mSizeStrategy.calculateTaskSize(mContext, mDp, mTaskRect);
+ mOrientationState.getOrientationHandler()
+ .setSplitTaskSwipeRect(mDp, mTaskRect, mStagedSplitBounds, mStagePosition);
} else {
mTaskRect.set(fullTaskSize);
}
@@ -277,13 +278,9 @@
getFullScreenScale();
mThumbnailData.rotation = mOrientationState.getDisplayRotation();
- // TODO(b/195145340) handle non 50-50 split scenarios
if (mStagedSplitBounds != null) {
- if (mStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
- // The preview set is for the bottom/right, inset by top/left task
- mSplitOffset.y = mStagedSplitBounds.mLeftTopBounds.height() +
- mStagedSplitBounds.mDividerBounds.height() / 2;
- }
+ mOrientationState.getOrientationHandler().setLeashSplitOffset(mSplitOffset, mDp,
+ mStagedSplitBounds, mStagePosition);
}
// mIsRecentsRtl is the inverse of TaskView RTL.
@@ -331,7 +328,7 @@
applyWindowToHomeRotation(mMatrix);
// Move lower/right split window into correct position
- mMatrix.postTranslate(0, mSplitOffset.y);
+ mMatrix.postTranslate(mSplitOffset.x, mSplitOffset.y);
// Crop rect is the inverse of thumbnail matrix
mTempRectF.set(-insets.left, -insets.top,
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 816e5dc..f386ac1 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -26,6 +26,7 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
import android.content.res.Resources;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -41,6 +42,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.views.BaseDragLayer;
@@ -382,6 +384,28 @@
}
@Override
+ public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+ float diff;
+ if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
+ diff = outRect.height() * (1f - splitInfo.mLeftTaskPercent);
+ outRect.bottom -= diff;
+ } else {
+ diff = outRect.height() * splitInfo.mLeftTaskPercent;
+ outRect.top += diff;
+ }
+ }
+
+ @Override
+ public void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+ if (desiredStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+ // The preview set is for the bottom/right, inset by top/left task
+ splitOffset.x = splitInfo.mLeftTopBounds.width() + splitInfo.mDividerBounds.width() / 2;
+ }
+ }
+
+ @Override
public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
DeviceProfile deviceProfile) {
return primary;
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index dae2dde..28ce92b 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -19,6 +19,7 @@
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -31,6 +32,7 @@
import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
@@ -133,6 +135,31 @@
void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
SplitPositionOption initialSplitOption, Rect out1, Rect out2);
+ /**
+ * @param outRect This is expected to be the rect that has the dimensions for a non-split,
+ * fullscreen task in overview. This will directly be modified.
+ * @param desiredStagePosition Which stage position (topLeft/rightBottom) we want to resize
+ * outRect for
+ */
+ void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo,
+ @SplitConfigurationOptions.StagePosition int desiredStagePosition);
+
+ /**
+ * It's important to note that {@link #setSplitTaskSwipeRect(DeviceProfile, Rect,
+ * SplitConfigurationOptions.StagedSplitBounds, int)} above operates on the outRect based on
+ * launcher's coordinate system, meaning it will treat the outRect as portrait if home rotation
+ * is not allowed.
+ *
+ * However, here the splitOffset is from perspective of TaskViewSimulator, which is in display
+ * orientation coordinates. So, for example, for the fake landscape scenario, even though
+ * launcher is portrait, we inset the bottom/right task by an X coordinate instead of the
+ * usual Y
+ */
+ void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo,
+ @SplitConfigurationOptions.StagePosition int desiredStagePosition);
+
// Overview TaskMenuView methods
float getTaskMenuX(float x, View thumbnailView, int overScroll);
float getTaskMenuY(float y, View thumbnailView, int overScroll);
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 1253589..ef6fe53 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -25,6 +25,7 @@
import android.content.res.Resources;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -40,6 +41,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.views.BaseDragLayer;
@@ -468,6 +470,44 @@
}
@Override
+ public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+ boolean isLandscape = dp.isLandscape;
+ float diff;
+ if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
+ if (isLandscape) {
+ diff = outRect.width() * (1f - splitInfo.mLeftTaskPercent);
+ outRect.right -= diff;
+ } else {
+ diff = outRect.height() * (1f - splitInfo.mTopTaskPercent);
+ outRect.bottom -= diff;
+ }
+ } else {
+ if (isLandscape) {
+ diff = outRect.width() * splitInfo.mLeftTaskPercent;
+ outRect.left += diff;
+ } else {
+ diff = outRect.height() * splitInfo.mTopTaskPercent;
+ outRect.top += diff;
+ }
+ }
+ }
+
+ @Override
+ public void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+ SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+ if (desiredStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+ if (dp.isLandscape) {
+ splitOffset.x = splitInfo.mLeftTopBounds.width() +
+ splitInfo.mDividerBounds.width() / 2;
+ } else {
+ splitOffset.y = splitInfo.mLeftTopBounds.height() +
+ splitInfo.mDividerBounds.height() / 2;
+ }
+ }
+ }
+
+ @Override
public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
DeviceProfile dp) {
if (dp.isLandscape) { // or seascape
diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java
index 1f1db9d..b07c21f 100644
--- a/src/com/android/launcher3/util/SplitConfigurationOptions.java
+++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java
@@ -89,12 +89,24 @@
public final Rect mLeftTopBounds;
public final Rect mRightBottomBounds;
public final Rect mDividerBounds;
+ // This class is orientation-agnostic, so we compute both for later use
+ public final float mTopTaskPercent;
+ public final float mLeftTaskPercent;
public StagedSplitBounds(Rect leftTopBounds, Rect rightBottomBounds, Rect dividerBounds) {
mLeftTopBounds = leftTopBounds;
mRightBottomBounds = rightBottomBounds;
mDividerBounds = dividerBounds;
+ float totalHeight = mLeftTopBounds.height()
+ + mRightBottomBounds.height()
+ + mDividerBounds.height();
+ float totalWidth = mLeftTopBounds.width()
+ + mRightBottomBounds.width()
+ + mDividerBounds.width();
+
+ mLeftTaskPercent = mLeftTopBounds.width() / totalWidth;
+ mTopTaskPercent = mLeftTopBounds.height() / totalHeight;
}
}