Add funtional animation for SplitSelect from Grid.
Long ways to go to final UI - TODO(b/186800707)
Add comments to grid layout code,
no functional changes at all.
Bug: 181705607
Test: Enter split screen from overview task menu
in grid and carousel. Able to select all items
and enter split.
Change-Id: Ib62f1b286acf0781ec47862fa31b670e6ff1892a
diff --git a/quickstep/res/layout/overview_panel.xml b/quickstep/res/layout/overview_panel.xml
index d7bcd9e..f303f31 100644
--- a/quickstep/res/layout/overview_panel.xml
+++ b/quickstep/res/layout/overview_panel.xml
@@ -15,12 +15,6 @@
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <com.android.quickstep.views.SplitPlaceholderView
- android:id="@+id/split_placeholder"
- android:layout_width="match_parent"
- android:layout_height="@dimen/split_placeholder_size"
- android:background="@android:color/darker_gray"
- android:visibility="gone" />
<com.android.quickstep.views.LauncherRecentsView
android:id="@+id/overview_panel"
@@ -31,6 +25,13 @@
android:clipToPadding="false"
android:visibility="invisible" />
+ <com.android.quickstep.views.SplitPlaceholderView
+ android:id="@+id/split_placeholder"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/split_placeholder_size"
+ android:background="@android:color/darker_gray"
+ android:visibility="gone" />
+
<include
android:id="@+id/overview_actions_view"
layout="@layout/overview_actions_container" />
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 01616d4..b3374f3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -22,12 +22,12 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_OFFSET;
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
-import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_TRANSLATION;
+import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_SPLIT_TRANSLATION;
+import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_SPLIT_TRANSLATION;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
import android.util.FloatProperty;
@@ -97,10 +97,10 @@
PagedOrientationHandler orientationHandler =
((RecentsView) mLauncher.getOverviewPanel()).getPagedOrientationHandler();
FloatProperty taskViewsFloat = orientationHandler.getSplitSelectTaskOffset(
- TASK_PRIMARY_TRANSLATION, TASK_SECONDARY_TRANSLATION, mLauncher.getDeviceProfile());
+ TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
+ mLauncher.getDeviceProfile());
setter.setFloat(mRecentsView, taskViewsFloat,
- toState.getOverviewSecondaryTranslation(mLauncher),
- config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
+ toState.getOverviewSecondaryTranslation(mLauncher), LINEAR);
setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 01d51f8..3d33e57 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -25,6 +25,7 @@
import android.animation.AnimatorSet;
import android.app.ActivityOptions;
import android.content.res.Resources;
+import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -64,6 +65,7 @@
private final SystemUiProxy mSystemUiProxy;
private TaskView mInitialTaskView;
private SplitPositionOption mInitialPosition;
+ private Rect mInitialBounds;
private final Handler mHandler;
public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy) {
@@ -74,9 +76,11 @@
/**
* To be called after first task selected
*/
- public void setInitialTaskSelect(TaskView taskView, SplitPositionOption positionOption) {
+ public void setInitialTaskSelect(TaskView taskView, SplitPositionOption positionOption,
+ Rect initialBounds) {
mInitialTaskView = taskView;
mInitialPosition = positionOption;
+ mInitialBounds = initialBounds;
}
/**
@@ -220,9 +224,14 @@
public void resetState() {
mInitialTaskView = null;
mInitialPosition = null;
+ mInitialBounds = null;
}
public boolean isSplitSelectActive() {
return mInitialTaskView != null;
}
+
+ public Rect getInitialBounds() {
+ return mInitialBounds;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index f5a8ff8..2c5f661 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -245,8 +245,8 @@
if (mActivity.isInState(OVERVIEW_SPLIT_SELECT)) {
// We want to keep the tasks translations in this temporary state
// after resetting the rest above
- setTaskViewsResistanceTranslation(mTaskViewsSecondaryTranslation);
- setTaskViewsPrimaryTranslation(mTaskViewsPrimaryTranslation);
+ setTaskViewsPrimarySplitTranslation(mTaskViewsPrimarySplitTranslation);
+ setTaskViewsSecondarySplitTranslation(mTaskViewsSecondarySplitTranslation);
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 53f880f..206f71b 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -254,16 +254,29 @@
* more specific, we'd want to create a similar FloatProperty just for a TaskView's
* offsetX/Y property
*/
- public static final FloatProperty<RecentsView> TASK_PRIMARY_TRANSLATION =
- new FloatProperty<RecentsView>("taskPrimaryTranslation") {
+ public static final FloatProperty<RecentsView> TASK_PRIMARY_SPLIT_TRANSLATION =
+ new FloatProperty<RecentsView>("taskPrimarySplitTranslation") {
@Override
public void setValue(RecentsView recentsView, float v) {
- recentsView.setTaskViewsPrimaryTranslation(v);
+ recentsView.setTaskViewsPrimarySplitTranslation(v);
}
@Override
public Float get(RecentsView recentsView) {
- return recentsView.mTaskViewsPrimaryTranslation;
+ return recentsView.mTaskViewsPrimarySplitTranslation;
+ }
+ };
+
+ public static final FloatProperty<RecentsView> TASK_SECONDARY_SPLIT_TRANSLATION =
+ new FloatProperty<RecentsView>("taskSecondarySplitTranslation") {
+ @Override
+ public void setValue(RecentsView recentsView, float v) {
+ recentsView.setTaskViewsSecondarySplitTranslation(v);
+ }
+
+ @Override
+ public Float get(RecentsView recentsView) {
+ return recentsView.mTaskViewsSecondarySplitTranslation;
}
};
@@ -279,7 +292,6 @@
view.mLiveTileTaskViewSimulator.recentsViewScale.value = scale;
view.updatePageOffsets();
view.setTaskViewsResistanceTranslation(view.mTaskViewsSecondaryTranslation);
- view.setTaskViewsPrimaryTranslation(view.mTaskViewsPrimaryTranslation);
}
@Override
@@ -363,7 +375,8 @@
private float mAdjacentPageOffset = 0;
protected float mTaskViewsSecondaryTranslation = 0;
- protected float mTaskViewsPrimaryTranslation = 0;
+ protected float mTaskViewsPrimarySplitTranslation = 0;
+ protected float mTaskViewsSecondarySplitTranslation = 0;
// Progress from 0 to 1 where 0 is a carousel and 1 is a 2 row grid.
private float mGridProgress = 0;
private final IntSet mTopRowIdSet = new IntSet();
@@ -1839,15 +1852,28 @@
final int boxLength = Math.max(mLastComputedGridTaskSize.width(),
mLastComputedGridTaskSize.height());
int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
- float heightOffset = (boxLength + taskTopMargin) + mRowSpacing;
- float taskGridVerticalDiff = mLastComputedGridTaskSize.top - mLastComputedTaskSize.top;
+
+ /*
+ * taskGridVerticalDiff is used to position the top of a task in the top row of the grid
+ * heightOffset is the vertical space one grid task takes + space between top and
+ * bottom row
+ * Summed together they provide the top position for bottom row of grid tasks
+ */
+ final float taskGridVerticalDiff =
+ mLastComputedGridTaskSize.top - mLastComputedTaskSize.top;
+ final float heightOffset = (boxLength + taskTopMargin) + mRowSpacing;
int topRowWidth = 0;
int bottomRowWidth = 0;
float topAccumulatedTranslationX = 0;
float bottomAccumulatedTranslationX = 0;
+
+ // Contains whether the child index is in top or bottom of grid (for non-focused task)
+ // Different from mTopRowIdSet, which contains the taskId of what task is in top row
IntSet topSet = new IntSet();
IntSet bottomSet = new IntSet();
+
+ // Horizontal grid translation for each task
float[] gridTranslations = new float[taskCount];
int focusedTaskIndex = Integer.MAX_VALUE;
@@ -1901,7 +1927,6 @@
boolean isTopRow = isTaskDismissal ? mTopRowIdSet.contains(taskId)
: topRowWidth <= bottomRowWidth;
if (isTopRow) {
- gridTranslations[i] += topAccumulatedTranslationX;
topRowWidth += taskWidthAndSpacing;
topSet.add(i);
mTopRowIdSet.add(taskId);
@@ -1917,11 +1942,10 @@
widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
}
- float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
- gridTranslations[i] += gridTranslationX;
- topAccumulatedTranslationX += gridTranslationX;
+ float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
+ gridTranslations[i] += topAccumulatedTranslationX + currentTaskTranslationX;
+ topAccumulatedTranslationX += currentTaskTranslationX;
} else {
- gridTranslations[i] += bottomAccumulatedTranslationX;
bottomRowWidth += taskWidthAndSpacing;
bottomSet.add(i);
@@ -1937,9 +1961,9 @@
widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
}
- float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
- gridTranslations[i] += gridTranslationX;
- bottomAccumulatedTranslationX += gridTranslationX;
+ float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
+ gridTranslations[i] += bottomAccumulatedTranslationX + currentTaskTranslationX;
+ bottomAccumulatedTranslationX += currentTaskTranslationX;
}
if (taskView == snappedTaskView) {
snappedTaskRowWidth = isTopRow ? topRowWidth : bottomRowWidth;
@@ -2130,18 +2154,43 @@
// Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's
// alpha is set to 0 so that it can be recycled in the view pool properly
anim.setFloat(taskView, VIEW_ALPHA, 0, ACCEL_2);
- FloatProperty<TaskView> secondaryViewTranslate =
- taskView.getSecondaryDissmissTranslationProperty();
- int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView);
- int verticalFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor();
+ SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
ResourceProvider rp = DynamicResource.provider(mActivity);
SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_START)
.setDampingRatio(rp.getFloat(R.dimen.dismiss_task_trans_y_damping_ratio))
.setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_y_stiffness));
+ FloatProperty<TaskView> dismissingTaskViewTranslate =
+ taskView.getSecondaryDissmissTranslationProperty();;
+ // TODO(b/186800707) translate entire grid size distance
+ int translateDistance = mOrientationHandler.getSecondaryDimension(taskView);
+ int positiveNegativeFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor();
+ if (splitController.isSplitSelectActive()) {
+ // Have the task translate towards whatever side was just pinned
+ int dir = mOrientationHandler.getSplitTaskViewDismissDirection(splitController
+ .getActiveSplitPositionOption(), mActivity.getDeviceProfile());
+ switch (dir) {
+ case PagedOrientationHandler.SPLIT_TRANSLATE_SECONDARY_NEGATIVE:
+ dismissingTaskViewTranslate = taskView
+ .getSecondaryDissmissTranslationProperty();
+ positiveNegativeFactor = -1;
+ break;
- anim.add(ObjectAnimator.ofFloat(taskView, secondaryViewTranslate,
- verticalFactor * secondaryTaskDimension).setDuration(duration), LINEAR, sp);
+ case PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_POSITIVE:
+ dismissingTaskViewTranslate = taskView.getPrimaryDismissTranslationProperty();
+ positiveNegativeFactor = 1;
+ break;
+
+ case PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_NEGATIVE:
+ dismissingTaskViewTranslate = taskView.getPrimaryDismissTranslationProperty();
+ positiveNegativeFactor = -1;
+ break;
+ default:
+ throw new IllegalStateException("Invalid split task translation: " + dir);
+ }
+ }
+ anim.add(ObjectAnimator.ofFloat(taskView, dismissingTaskViewTranslate,
+ positiveNegativeFactor * translateDistance).setDuration(duration), LINEAR, sp);
if (LIVE_TILE.get() && taskView.isRunningTask()) {
anim.addOnFrameCallback(() -> {
@@ -2206,18 +2255,6 @@
}
}
- // Additional offset for fake landscape, if the pinning happens to the right or
- // left, we need to scroll all the tasks away from the direction of the splaceholder
- // view
- if (isSplitSelectionActive()) {
- int splitPosition = getSplitPlaceholder().getSplitController()
- .getActiveSplitPositionOption().mStagePosition;
- int direction = mOrientationHandler
- .getSplitTranslationDirectionFactor(splitPosition);
- int splitOffset = mOrientationHandler.getSplitAnimationTranslation(
- mSplitPlaceholderView.getHeight(), mActivity.getDeviceProfile());
- offset += direction * splitOffset;
- }
int scrollDiff = newScroll[i] - oldScroll[i] + offset;
if (scrollDiff != 0) {
FloatProperty translationProperty = child instanceof TaskView
@@ -2768,13 +2805,20 @@
mLiveTileTaskViewSimulator.recentsViewSecondaryTranslation.value = translation;
}
- protected void setTaskViewsPrimaryTranslation(float translation) {
- mTaskViewsPrimaryTranslation = translation;
+ protected void setTaskViewsPrimarySplitTranslation(float translation) {
+ mTaskViewsPrimarySplitTranslation = translation;
for (int i = 0; i < getTaskViewCount(); i++) {
TaskView task = getTaskViewAt(i);
- task.getPrimaryDismissTranslationProperty().set(task, translation / getScaleY());
+ task.getPrimarySplitTranslationProperty().set(task, translation);
}
- mLiveTileTaskViewSimulator.recentsViewPrimaryTranslation.value = translation;
+ }
+
+ protected void setTaskViewsSecondarySplitTranslation(float translation) {
+ mTaskViewsSecondarySplitTranslation = translation;
+ for (int i = 0; i < getTaskViewCount(); i++) {
+ TaskView task = getTaskViewAt(i);
+ task.getSecondarySplitTranslationProperty().set(task, translation);
+ }
}
/**
@@ -2797,8 +2841,9 @@
public void initiateSplitSelect(TaskView taskView, SplitPositionOption splitPositionOption) {
mSplitHiddenTaskView = taskView;
SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
- splitController.setInitialTaskSelect(taskView,
- splitPositionOption);
+ Rect initialBounds = new Rect(taskView.getLeft(), taskView.getTop(), taskView.getRight(),
+ taskView.getBottom());
+ splitController.setInitialTaskSelect(taskView, splitPositionOption, initialBounds);
mSplitHiddenTaskViewIndex = indexOfChild(taskView);
mSplitPlaceholderView.setLayoutParams(
splitController.getLayoutParamsForActivePosition(getResources(),
@@ -2818,7 +2863,10 @@
}
public PendingAnimation cancelSplitSelect(boolean animate) {
- mSplitPlaceholderView.getSplitController().resetState();
+ SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
+ SplitPositionOption splitOption = splitController.getActiveSplitPositionOption();
+ Rect initialBounds = splitController.getInitialBounds();
+ splitController.resetState();
int duration = mActivity.getStateManager().getState().getTransitionDuration(getContext());
PendingAnimation pendingAnim = new PendingAnimation(duration);
if (!animate) {
@@ -2833,8 +2881,6 @@
getPageScrolls(oldScroll, false,
view -> view.getVisibility() != GONE && view != mSplitHiddenTaskView);
- // x is correct, y is before tasks move up
- int[] locationOnScreen = mSplitHiddenTaskView.getLocationOnScreen();
int[] newScroll = new int[getChildCount()];
getPageScrolls(newScroll, false, SIMPLE_SCROLL_LOGIC);
@@ -2842,20 +2888,42 @@
for (int i = mSplitHiddenTaskViewIndex; i >= 0; i--) {
View child = getChildAt(i);
if (child == mSplitHiddenTaskView) {
+ TaskView taskView = (TaskView) child;
- int left = newScroll[i] + getPaddingStart();
- int topMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
- int top = -mSplitHiddenTaskView.getHeight() - locationOnScreen[1];
- mSplitHiddenTaskView.layout(left, top,
- left + mSplitHiddenTaskView.getWidth(),
- top + mSplitHiddenTaskView.getHeight());
- pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView, TRANSLATION_Y,
- -top + mSplitPlaceholderView.getHeight() - topMargin));
+ int dir = mOrientationHandler.getSplitTaskViewDismissDirection(splitOption,
+ mActivity.getDeviceProfile());
+ FloatProperty<TaskView> dismissingTaskViewTranslate;
+ Rect hiddenBounds = new Rect(taskView.getLeft(), taskView.getTop(),
+ taskView.getRight(), taskView.getBottom());
+ int distanceDelta = 0;
+ if (dir == PagedOrientationHandler.SPLIT_TRANSLATE_SECONDARY_NEGATIVE) {
+ dismissingTaskViewTranslate = taskView
+ .getSecondaryDissmissTranslationProperty();
+ distanceDelta = initialBounds.top - hiddenBounds.top;
+ taskView.layout(initialBounds.left, hiddenBounds.top, initialBounds.right,
+ hiddenBounds.bottom);
+ } else {
+ dismissingTaskViewTranslate = taskView
+ .getPrimaryDismissTranslationProperty();
+ distanceDelta = initialBounds.left - hiddenBounds.left;
+ taskView.layout(hiddenBounds.left, initialBounds.top, hiddenBounds.right,
+ initialBounds.bottom);
+ if (dir == PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_POSITIVE) {
+ distanceDelta *= -1;
+ }
+ }
+ pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView,
+ dismissingTaskViewTranslate,
+ distanceDelta));
pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView, ALPHA, 1));
} else {
// If insertion is on last index (furthest from clear all), we directly add the view
// else we translate all views to the right of insertion index further right,
// ignore views to left
+ if (showAsGrid()) {
+ // TODO(b/186800707) handle more elegantly for grid
+ continue;
+ }
int scrollDiff = newScroll[i] - oldScroll[i];
if (scrollDiff != 0) {
FloatProperty translationProperty = child instanceof TaskView
@@ -2881,6 +2949,12 @@
pendingAnim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
+ // TODO(b/186800707) Figure out how to undo for grid view
+ // Need to handle cases where dismissed task is
+ // * Top Row
+ // * Bottom Row
+ // * Focused Task
+ updateGridProperties();
resetFromSplitSelectionState();
}
});
@@ -2890,13 +2964,16 @@
private void resetFromSplitSelectionState() {
mSplitHiddenTaskView.setTranslationY(0);
- int pageToSnapTo = mCurrentPage;
- if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
- pageToSnapTo += 1;
- } else {
- pageToSnapTo = mSplitHiddenTaskViewIndex;
+ if (!showAsGrid()) {
+ // TODO(b/186800707)
+ int pageToSnapTo = mCurrentPage;
+ if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
+ pageToSnapTo += 1;
+ } else {
+ pageToSnapTo = mSplitHiddenTaskViewIndex;
+ }
+ snapToPageImmediately(pageToSnapTo);
}
- snapToPageImmediately(pageToSnapTo);
onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom());
resetTaskVisuals();
mSplitHiddenTaskView = null;
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 45bcdc3..079d24b 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -172,6 +172,32 @@
}
};
+ private static final FloatProperty<TaskView> SPLIT_SELECT_TRANSLATION_X =
+ new FloatProperty<TaskView>("splitSelectTranslationX") {
+ @Override
+ public void setValue(TaskView taskView, float v) {
+ taskView.setSplitSelectTranslationX(v);
+ }
+
+ @Override
+ public Float get(TaskView taskView) {
+ return taskView.mSplitSelectTranslationX;
+ }
+ };
+
+ private static final FloatProperty<TaskView> SPLIT_SELECT_TRANSLATION_Y =
+ new FloatProperty<TaskView>("splitSelectTranslationY") {
+ @Override
+ public void setValue(TaskView taskView, float v) {
+ taskView.setSplitSelectTranslationY(v);
+ }
+
+ @Override
+ public Float get(TaskView taskView) {
+ return taskView.mSplitSelectTranslationY;
+ }
+ };
+
private static final FloatProperty<TaskView> DISMISS_TRANSLATION_X =
new FloatProperty<TaskView>("dismissTranslationX") {
@Override
@@ -345,6 +371,9 @@
// The following grid translations scales with mGridProgress.
private float mGridTranslationX;
private float mGridTranslationY;
+ // Used when in SplitScreenSelectState
+ private float mSplitSelectTranslationY;
+ private float mSplitSelectTranslationX;
private ObjectAnimator mIconAndDimAnimator;
private float mIconScaleAnimStartProgress = 0;
@@ -825,8 +854,10 @@
protected void resetViewTransforms() {
// fullscreenTranslation and accumulatedTranslation should not be reset, as
// resetViewTransforms is called during Quickswitch scrolling.
- mDismissTranslationX = mTaskOffsetTranslationX = mTaskResistanceTranslationX = 0f;
- mDismissTranslationY = mTaskOffsetTranslationY = mTaskResistanceTranslationY = 0f;
+ mDismissTranslationX = mTaskOffsetTranslationX = mTaskResistanceTranslationX =
+ mSplitSelectTranslationX = 0f;
+ mDismissTranslationY = mTaskOffsetTranslationY = mTaskResistanceTranslationY =
+ mSplitSelectTranslationY = 0f;
applyTranslationX();
applyTranslationY();
setTranslationZ(0);
@@ -956,6 +987,15 @@
setScaleY(scale);
}
+ private void setSplitSelectTranslationX(float x) {
+ mSplitSelectTranslationX = x;
+ applyTranslationX();
+ }
+
+ private void setSplitSelectTranslationY(float y) {
+ mSplitSelectTranslationY = y;
+ applyTranslationY();
+ }
private void setDismissTranslationX(float x) {
mDismissTranslationX = x;
applyTranslationX();
@@ -1056,12 +1096,12 @@
private void applyTranslationX() {
setTranslationX(mDismissTranslationX + mTaskOffsetTranslationX + mTaskResistanceTranslationX
- + getPersistentTranslationX());
+ + mSplitSelectTranslationX + getPersistentTranslationX());
}
private void applyTranslationY() {
setTranslationY(mDismissTranslationY + mTaskOffsetTranslationY + mTaskResistanceTranslationY
- + getPersistentTranslationY());
+ + mSplitSelectTranslationY + getPersistentTranslationY());
}
/**
@@ -1085,6 +1125,16 @@
+ getGridTrans(mGridTranslationY);
}
+ public FloatProperty<TaskView> getPrimarySplitTranslationProperty() {
+ return getPagedOrientationHandler().getPrimaryValue(
+ SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y);
+ }
+
+ public FloatProperty<TaskView> getSecondarySplitTranslationProperty() {
+ return getPagedOrientationHandler().getSecondaryValue(
+ SPLIT_SELECT_TRANSLATION_X, SPLIT_SELECT_TRANSLATION_Y);
+ }
+
public FloatProperty<TaskView> getPrimaryDismissTranslationProperty() {
return getPagedOrientationHandler().getPrimaryValue(
DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y);
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 2fd5efc..44e55e1 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -160,6 +160,19 @@
}
@Override
+ public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
+ DeviceProfile dp) {
+ // Don't use device profile here because we know we're in fake landscape, only split option
+ // available is top/left
+ if (splitPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+ // Top (visually left) side
+ return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
+ }
+ throw new IllegalStateException("Invalid split stage position: " +
+ splitPosition.mStagePosition);
+ }
+
+ @Override
public int getPrimaryScroll(View view) {
return view.getScrollY();
}
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index 6c2f17e..d8e5a48 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -42,6 +42,10 @@
*/
public interface PagedOrientationHandler {
+ int SPLIT_TRANSLATE_PRIMARY_POSITIVE = 0;
+ int SPLIT_TRANSLATE_PRIMARY_NEGATIVE = 1;
+ int SPLIT_TRANSLATE_SECONDARY_NEGATIVE = 2;
+
PagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler();
PagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler();
PagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler();
@@ -71,6 +75,13 @@
int getSecondaryDimension(View view);
FloatProperty<View> getPrimaryViewTranslate();
FloatProperty<View> getSecondaryViewTranslate();
+
+ /**
+ * @param splitPosition The position where the view to be split will go
+ * @return {@link #SPLIT_TRANSLATE_*} constants to indicate which direction the
+ * dismissal should happen
+ */
+ int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition, DeviceProfile dp);
int getPrimaryScroll(View view);
float getPrimaryScale(View view);
int getChildStart(View view);
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index f6a6448..01897d7 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -156,6 +156,25 @@
}
@Override
+ public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
+ DeviceProfile dp) {
+ if (splitPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+ if (dp.isLandscape) {
+ // Left side
+ return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
+ } else {
+ // Top side
+ return SPLIT_TRANSLATE_SECONDARY_NEGATIVE;
+ }
+ } else if (splitPosition.mStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+ // We don't have a bottom option, so should be right
+ return SPLIT_TRANSLATE_PRIMARY_POSITIVE;
+ }
+ throw new IllegalStateException("Invalid split stage position: " +
+ splitPosition.mStagePosition);
+ }
+
+ @Override
public int getPrimaryScroll(View view) {
return view.getScrollX();
}