OverviewActions - Use launcher state to track modal state.
Test:local
Change-Id: I44e25b95095b9a7aac4b4172c9c91fbfbf4d9ec7
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 87ca2b6..e074b03 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -17,6 +17,7 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import android.content.Intent;
@@ -219,7 +220,12 @@
@Override
protected boolean isRecentsInteractive() {
- return mActivity.isInState(OVERVIEW);
+ return mActivity.isInState(OVERVIEW) || mActivity.isInState(OVERVIEW_MODAL_TASK);
+ }
+
+ @Override
+ protected boolean isRecentsModal() {
+ return mActivity.isInState(OVERVIEW_MODAL_TASK);
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 2f55fda..a1cc60e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -19,6 +19,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
+import static com.android.quickstep.views.RecentsView.TASK_MODALNESS;
import android.annotation.TargetApi;
import android.os.Build;
@@ -88,6 +89,11 @@
}
@Override
+ FloatProperty<RecentsView> getTaskModalnessProperty() {
+ return TASK_MODALNESS;
+ }
+
+ @Override
FloatProperty<RecentsView> getContentAlphaProperty() {
return CONTENT_ALPHA;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
new file mode 100644
index 0000000..b238200
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.uioverrides.states;
+
+import android.content.res.Resources;
+import android.graphics.Rect;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.quickstep.views.RecentsView;
+
+/**
+ * An Overview state that shows the current task in a modal fashion. Modal state is where the
+ * current task is shown on its own without other tasks visible.
+ */
+public class OverviewModalTaskState extends OverviewState {
+
+ private static final int STATE_FLAGS =
+ FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY;
+
+ public OverviewModalTaskState(int id) {
+ super(id, ContainerType.OVERVIEW, STATE_FLAGS);
+ }
+
+ @Override
+ public int getTransitionDuration(Launcher launcher) {
+ return 100;
+ }
+
+ @Override
+ public int getVisibleElements(Launcher launcher) {
+ return OVERVIEW_BUTTONS;
+ }
+
+ @Override
+ public float[] getOverviewScaleAndOffset(Launcher launcher) {
+ Resources res = launcher.getBaseContext().getResources();
+
+ Rect out = new Rect();
+ launcher.<RecentsView>getOverviewPanel().getTaskSize(out);
+ int taskHeight = out.height();
+
+ float topMargin = res.getDimension(R.dimen.task_thumbnail_top_margin);
+ float bottomMargin = res.getDimension(R.dimen.task_thumbnail_bottom_margin_with_actions);
+ float newHeight = taskHeight + topMargin + bottomMargin;
+ float scale = newHeight / taskHeight;
+
+ return new float[] {scale, 0};
+ }
+
+ @Override
+ public float getOverviewModalness() {
+ return 1.0f;
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
index e44f59f..fad9ea5 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -259,4 +259,11 @@
public static OverviewState newSwitchState(int id) {
return new QuickSwitchState(id);
}
+
+ /**
+ * New Overview substate that represents the overview in modal mode (one task shown on its own)
+ */
+ public static OverviewState newModalTaskState(int id) {
+ return new OverviewModalTaskState(id);
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index 2b456ec..06a481b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -17,7 +17,6 @@
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
@@ -99,7 +98,7 @@
if (!cameFromNavBar) {
return false;
}
- if (mStartState == OVERVIEW || mStartState == ALL_APPS) {
+ if (mStartState.overviewUi || mStartState == ALL_APPS) {
return true;
}
if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
@@ -129,7 +128,7 @@
private void initCurrentAnimation() {
long accuracy = (long) (getShiftRange() * 2);
final PendingAnimation builder = new PendingAnimation(accuracy);
- if (mStartState == OVERVIEW) {
+ if (mStartState.overviewUi) {
RecentsView recentsView = mLauncher.getOverviewPanel();
builder.setFloat(recentsView, ADJACENT_PAGE_OFFSET,
-mPullbackDistance / recentsView.getPageOffsetScale(), PULLBACK_INTERPOLATOR);
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
index f6f892b..1f3b82c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
@@ -96,6 +96,9 @@
protected abstract boolean isRecentsInteractive();
+ /** Is recents view showing a single task in a modal way. */
+ protected abstract boolean isRecentsModal();
+
protected void onUserControlledAnimationCreated(AnimatorPlaybackController animController) {
}
@@ -134,7 +137,7 @@
if (mRecentsView.isTaskViewVisible(view) && mActivity.getDragLayer()
.isEventOverView(view, ev)) {
// Disable swiping up and down if the task overlay is modal.
- if (view.isTaskOverlayModal()) {
+ if (isRecentsModal()) {
mTaskBeingDragged = null;
break;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
index 147f933..b44d6df 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java
@@ -131,13 +131,6 @@
}
/**
- * Whether the overlay is modal, which means only tapping is enabled, but no swiping.
- */
- public boolean isOverlayModal() {
- return false;
- }
-
- /**
* Gets the task snapshot as it is displayed on the screen.
*
* @return the bounds of the snapshot in screen coordinates.
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsTaskController.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsTaskController.java
index a113604..d7458d2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsTaskController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsTaskController.java
@@ -28,4 +28,9 @@
protected boolean isRecentsInteractive() {
return mActivity.hasWindowFocus();
}
+
+ @Override
+ protected boolean isRecentsModal() {
+ return false;
+ }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 0b6d340..9005651 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -20,6 +20,7 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_BUTTONS;
+import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.ALL_APPS_PROGRESS_OFF_SCREEN;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
@@ -284,7 +285,7 @@
// Clean-up logic that occurs when recents is no longer in use/visible.
reset();
}
- setOverlayEnabled(finalState == OVERVIEW);
+ setOverlayEnabled(finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK);
setFreezeViewVisibility(false);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 6041917..cd3abed 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -70,7 +70,6 @@
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.FloatProperty;
-import android.util.Log;
import android.util.Property;
import android.util.SparseBooleanArray;
import android.view.HapticFeedbackConstants;
@@ -173,13 +172,26 @@
}
};
+ public static final FloatProperty<RecentsView> TASK_MODALNESS =
+ new FloatProperty<RecentsView>("taskModalness") {
+ @Override
+ public void setValue(RecentsView recentsView, float v) {
+ recentsView.setTaskModalness(v);
+ }
+
+ @Override
+ public Float get(RecentsView recentsView) {
+ return recentsView.mTaskModalness;
+ }
+ };
+
public static final FloatProperty<RecentsView> ADJACENT_PAGE_OFFSET =
new FloatProperty<RecentsView>("adjacentPageOffset") {
@Override
public void setValue(RecentsView recentsView, float v) {
if (recentsView.mAdjacentPageOffset != v) {
recentsView.mAdjacentPageOffset = v;
- recentsView.updateAdjacentPageOffset();
+ recentsView.updatePageOffsets();
}
}
@@ -327,6 +339,12 @@
protected float mContentAlpha = 1;
@ViewDebug.ExportedProperty(category = "launcher")
protected float mFullscreenProgress = 0;
+ /**
+ * How modal is the current task to be displayed, 1 means the task is fully modal and no other
+ * tasks are show. 0 means the task is displays in context in the list with other tasks.
+ */
+ @ViewDebug.ExportedProperty(category = "launcher")
+ protected float mTaskModalness = 0;
// Keeps track of task id whose visual state should not be reset
private int mIgnoreResetTaskId = -1;
@@ -647,7 +665,7 @@
@Override
protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) {
// Enables swiping to the left or right only if the task overlay is not modal.
- if (getCurrentPageTaskView() == null || !getCurrentPageTaskView().isTaskOverlayModal()) {
+ if (mTaskModalness == 0f) {
super.determineScrollingStart(ev, touchSlopScale);
}
}
@@ -735,25 +753,6 @@
return taskViewCount;
}
- /**
- * Updates UI for a modal task, including hiding other tasks.
- */
- public void updateUiForModalTask(TaskView taskView, boolean isTaskOverlayModal) {
- int currentIndex = indexOfChild(taskView);
- TaskView previousTask = getTaskViewAt(currentIndex - 1);
- TaskView nextTask = getTaskViewAt(currentIndex + 1);
- float alpha = isTaskOverlayModal ? 0.0f : 1.0f;
- if (previousTask != null) {
- previousTask.animate().alpha(alpha)
- .translationX(isTaskOverlayModal ? previousTask.getWidth() / 2 : 0);
- }
- if (nextTask != null) {
- nextTask.animate().alpha(alpha)
- .translationX(isTaskOverlayModal ? -nextTask.getWidth() / 2 : 0);
-
- }
- }
-
protected void onTaskStackUpdated() { }
public void resetTaskVisuals() {
@@ -776,6 +775,7 @@
updateCurveProperties();
// Update the set of visible task's data
loadVisibleTaskData();
+ setTaskModalness(0);
}
public void setFullscreenProgress(float fullscreenProgress) {
@@ -1653,21 +1653,27 @@
mTempRect, mActivity.getDeviceProfile(), mTempPointF);
setPivotX(mTempPointF.x);
setPivotY(mTempPointF.y);
- updateAdjacentPageOffset();
+ updatePageOffsets();
}
- private void updateAdjacentPageOffset() {
+ private void updatePageOffsets() {
float offset = mAdjacentPageOffset * getWidth();
+ float modalOffset = mTaskModalness * getWidth();
if (mIsRtl) {
offset = -offset;
+ modalOffset = -modalOffset;
}
int count = getChildCount();
TaskView runningTask = mRunningTaskId == -1 ? null : getTaskView(mRunningTaskId);
int midPoint = runningTask == null ? -1 : indexOfChild(runningTask);
+ int currentPage = getCurrentPage();
for (int i = 0; i < count; i++) {
- getChildAt(i).setTranslationX(i == midPoint ? 0 : (i < midPoint ? -offset : offset));
+ float translation = i == midPoint ? 0 : (i < midPoint ? -offset : offset);
+ float modalTranslation =
+ i == currentPage ? 0 : (i < currentPage ? -modalOffset : modalOffset);
+ getChildAt(i).setTranslationX(translation + modalTranslation);
}
updateCurveProperties();
}
@@ -2113,6 +2119,18 @@
}
}
+ /**
+ * The current task is fully modal (modalness = 1) when it is shown on its own in a modal
+ * way. Modalness 0 means the task is shown in context with all the other tasks.
+ */
+ private void setTaskModalness(float modalness) {
+ mTaskModalness = modalness;
+ updatePageOffsets();
+ if (getCurrentPageTaskView() != null) {
+ getCurrentPageTaskView().setModalness(modalness);
+ }
+ }
+
@Nullable
protected DepthController getDepthController() {
return null;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index 4275933..aea5b8e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -25,6 +25,7 @@
import static android.widget.Toast.LENGTH_SHORT;
import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION;
+import static com.android.launcher3.Utilities.comp;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
@@ -165,10 +166,10 @@
private ObjectAnimator mIconAndDimAnimator;
private float mIconScaleAnimStartProgress = 0;
private float mFocusTransitionProgress = 1;
+ private float mModalness = 0;
private float mStableAlpha = 1;
private boolean mShowScreenshot;
- private boolean mRunningModalAnimation = false;
// The current background requests to load the task thumbnail and icon
private TaskThumbnailCache.ThumbnailLoadRequest mThumbnailLoadRequest;
@@ -239,59 +240,24 @@
mIconView = findViewById(R.id.icon);
}
- public boolean isTaskOverlayModal() {
- return mSnapshotView.getTaskOverlay().isOverlayModal();
- }
-
- /** Updates UI based on whether the task is modal. */
- public void updateUiForModalTask() {
- boolean isOverlayModal = isTaskOverlayModal();
- mRunningModalAnimation = true;
- if (getRecentsView() != null) {
- getRecentsView().updateUiForModalTask(this, isOverlayModal);
+ /**
+ * The modalness of this view is how it should be displayed when it is shown on its own in the
+ * modal state of overview.
+ *
+ * @param modalness [0, 1] 0 being in context with other tasks, 1 being shown on its own.
+ */
+ public void setModalness(float modalness) {
+ mModalness = modalness;
+ mIconView.setAlpha(comp(modalness));
+ if (mContextualChip != null) {
+ mContextualChip.setScaleX(comp(modalness));
+ mContextualChip.setScaleY(comp(modalness));
+ }
+ if (mContextualChipWrapper != null) {
+ mContextualChipWrapper.setAlpha(comp(modalness));
}
- // Hides footers and icon when overlay is modal.
- if (isOverlayModal) {
- for (FooterWrapper footer : mFooters) {
- if (footer != null) {
- footer.animateHide();
- }
- }
- if (mContextualChipWrapper != null) {
- mContextualChipWrapper.animate().alpha(0f).setDuration(300);
- }
- if (mContextualChip != null) {
- mContextualChip.animate().scaleX(0f).scaleY(0f).setDuration(300);
- }
-
- mIconView.animate().alpha(0.0f);
- } else {
- if (mContextualChip != null) {
- mContextualChip.animate().scaleX(1f).scaleY(1f).setDuration(300);
- }
- if (mContextualChipWrapper != null) {
- mContextualChipWrapper.animate().alpha(1f).setDuration(300);
- }
- mIconView.animate().alpha(1.0f);
- }
-
- // Sets animations for modal UI. We will remove the margins to zoom in the snapshot.
- float topMargin = getResources().getDimension(R.dimen.task_thumbnail_top_margin);
- float bottomMargin =
- getResources().getDimension(R.dimen.task_thumbnail_bottom_margin_with_actions);
- float newHeight = mSnapshotView.getHeight() + topMargin + bottomMargin;
- float scale = isOverlayModal ? newHeight / mSnapshotView.getHeight() : 1.0f;
- float centerDifference = (bottomMargin - topMargin) / 2;
- float translationY = isOverlayModal ? centerDifference : 0;
- this.animate().scaleX(scale).scaleY(scale).translationY(translationY)
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- setCurveScale(scale);
- mRunningModalAnimation = false;
- }
- });
+ updateFooterVerticalOffset(mFooterVerticalOffset);
}
public TaskMenuView getMenuView() {
@@ -535,12 +501,7 @@
mIconView.setScaleX(scale);
mIconView.setScaleY(scale);
- mFooterVerticalOffset = 1.0f - scale;
- for (FooterWrapper footer : mFooters) {
- if (footer != null) {
- footer.updateFooterOffset();
- }
- }
+ updateFooterVerticalOffset(1.0f - scale);
}
public void setIconScaleAnimStartProgress(float startProgress) {
@@ -586,6 +547,7 @@
public void resetVisualProperties() {
resetViewTransforms();
setFullscreenProgress(0);
+ setModalness(0);
}
public void setStableAlpha(float parentAlpha) {
@@ -606,7 +568,7 @@
@Override
public void onPageScroll(ScrollState scrollState) {
// Don't do anything if it's modal.
- if (mRunningModalAnimation || isTaskOverlayModal()) {
+ if (mModalness > 0) {
return;
}
@@ -759,6 +721,12 @@
mStackHeight += footer.mView.getHeight();
}
}
+ updateFooterVerticalOffset(0);
+ }
+
+ private void updateFooterVerticalOffset(float offset) {
+ mFooterVerticalOffset = offset;
+
for (FooterWrapper footer : mFooters) {
if (footer != null) {
footer.updateFooterOffset();
@@ -857,7 +825,8 @@
}
void updateFooterOffset() {
- mAnimationOffset = Math.round(mStackHeight * mFooterVerticalOffset);
+ float offset = Utilities.or(mFooterVerticalOffset, mModalness);
+ mAnimationOffset = Math.round(mStackHeight * offset);
mView.setTranslationY(mAnimationOffset + mEntryAnimationOffset
+ mCurrentFullscreenParams.mCurrentDrawnInsets.bottom
+ mCurrentFullscreenParams.mCurrentDrawnInsets.top);
@@ -880,22 +849,6 @@
animator.setDuration(100);
animator.start();
}
-
- void animateHide() {
- ValueAnimator animator = ValueAnimator.ofFloat(0.0f, 1.0f);
- animator.addUpdateListener(anim -> {
- mFooterVerticalOffset = anim.getAnimatedFraction();
- updateFooterOffset();
- });
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- removeView(mView);
- }
- });
- animator.setDuration(100);
- animator.start();
- }
}
private int getExpectedViewHeight(View view) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 33011ac..ac50d6d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.graphics.Scrim.SCRIM_PROGRESS;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
+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_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
@@ -66,6 +67,7 @@
getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim();
SCRIM_PROGRESS.set(scrim, state.getOverviewScrimAlpha(mLauncher));
+ getTaskModalnessProperty().set(mRecentsView, state.getOverviewModalness());
}
@Override
@@ -101,8 +103,15 @@
OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim();
setter.setFloat(scrim, SCRIM_PROGRESS, toState.getOverviewScrimAlpha(mLauncher),
config.getInterpolator(ANIM_OVERVIEW_SCRIM_FADE, LINEAR));
+
+ setter.setFloat(
+ mRecentsView, getTaskModalnessProperty(),
+ toState.getOverviewModalness(),
+ config.getInterpolator(ANIM_OVERVIEW_MODAL, AGGRESSIVE_EASE_IN_OUT));
}
+ abstract FloatProperty getTaskModalnessProperty();
+
/**
* Get property for content alpha for the recents view.
*
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 54d8f0d..e2b867e 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -36,6 +36,7 @@
import static com.android.launcher3.testing.TestProtocol.BACKGROUND_APP_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.NORMAL_STATE_ORDINAL;
+import static com.android.launcher3.testing.TestProtocol.OVERVIEW_MODAL_TASK_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_PEEK_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.QUICK_SWITCH_STATE_ORDINAL;
@@ -101,7 +102,7 @@
}
};
- private static final LauncherState[] sAllStates = new LauncherState[8];
+ private static final LauncherState[] sAllStates = new LauncherState[9];
/**
* TODO: Create a separate class for NORMAL state.
@@ -128,6 +129,8 @@
public static final LauncherState OVERVIEW = new OverviewState(OVERVIEW_STATE_ORDINAL);
public static final LauncherState OVERVIEW_PEEK =
OverviewState.newPeekState(OVERVIEW_PEEK_STATE_ORDINAL);
+ public static final LauncherState OVERVIEW_MODAL_TASK = OverviewState.newModalTaskState(
+ OVERVIEW_MODAL_TASK_STATE_ORDINAL);
public static final LauncherState QUICK_SWITCH =
OverviewState.newSwitchState(QUICK_SWITCH_STATE_ORDINAL);
public static final LauncherState BACKGROUND_APP =
@@ -280,6 +283,14 @@
}
/**
+ * For this state, how modal should over view been shown. 0 modalness means all tasks drawn,
+ * 1 modalness means the current task is show on its own.
+ */
+ public float getOverviewModalness() {
+ return 0;
+ }
+
+ /**
* The amount of blur and wallpaper zoom to apply to the background of either the app
* or Launcher surface in this state. Should be a number between 0 and 1, inclusive.
*
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 3c3ab6c..d95ccb4 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -340,6 +340,30 @@
}
/**
+ * Bounds parameter to the range [0, 1]
+ */
+ public static float saturate(float a) {
+ return boundToRange(a, 0, 1.0f);
+ }
+
+ /**
+ * Returns the compliment (1 - a) of the parameter.
+ */
+ public static float comp(float a) {
+ return 1 - a;
+ }
+
+ /**
+ * Returns the "probabilistic or" of a and b. (a + b - ab).
+ * Useful beyond probability, can be used to combine two unit progresses for example.
+ */
+ public static float or(float a, float b) {
+ float satA = saturate(a);
+ float satB = saturate(b);
+ return satA + satB - (satA * satB);
+ }
+
+ /**
* Trims the string, removing all whitespace at the beginning and end of the string.
* Non-breaking whitespaces are also removed.
*/
diff --git a/src/com/android/launcher3/states/StateAnimationConfig.java b/src/com/android/launcher3/states/StateAnimationConfig.java
index 8dccbd3..1c49867 100644
--- a/src/com/android/launcher3/states/StateAnimationConfig.java
+++ b/src/com/android/launcher3/states/StateAnimationConfig.java
@@ -69,6 +69,7 @@
ANIM_ALL_APPS_FADE,
ANIM_OVERVIEW_SCRIM_FADE,
ANIM_ALL_APPS_HEADER_FADE,
+ ANIM_OVERVIEW_MODAL
})
@Retention(RetentionPolicy.SOURCE)
public @interface AnimType {}
@@ -85,8 +86,9 @@
public static final int ANIM_ALL_APPS_FADE = 10;
public static final int ANIM_OVERVIEW_SCRIM_FADE = 11;
public static final int ANIM_ALL_APPS_HEADER_FADE = 12; // e.g. predictions
+ public static final int ANIM_OVERVIEW_MODAL = 13;
- private static final int ANIM_TYPES_COUNT = 13;
+ private static final int ANIM_TYPES_COUNT = 14;
private final Interpolator[] mInterpolators = new Interpolator[ANIM_TYPES_COUNT];
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index a5a06b4..fba6269 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -28,10 +28,11 @@
public static final int SPRING_LOADED_STATE_ORDINAL = 1;
public static final int OVERVIEW_STATE_ORDINAL = 2;
public static final int OVERVIEW_PEEK_STATE_ORDINAL = 3;
- public static final int QUICK_SWITCH_STATE_ORDINAL = 4;
- public static final int ALL_APPS_STATE_ORDINAL = 5;
- public static final int BACKGROUND_APP_STATE_ORDINAL = 6;
- public static final int HINT_STATE_ORDINAL = 7;
+ public static final int OVERVIEW_MODAL_TASK_STATE_ORDINAL = 4;
+ public static final int QUICK_SWITCH_STATE_ORDINAL = 5;
+ public static final int ALL_APPS_STATE_ORDINAL = 6;
+ public static final int BACKGROUND_APP_STATE_ORDINAL = 7;
+ public static final int HINT_STATE_ORDINAL = 8;
public static final String TAPL_EVENTS_TAG = "TaplEvents";
public static final String SEQUENCE_MAIN = "Main";
public static final String SEQUENCE_TIS = "TIS";
@@ -47,6 +48,8 @@
return "Overview";
case OVERVIEW_PEEK_STATE_ORDINAL:
return "OverviewPeek";
+ case OVERVIEW_MODAL_TASK_STATE_ORDINAL:
+ return "OverviewModalState";
case QUICK_SWITCH_STATE_ORDINAL:
return "QuickSwitch";
case ALL_APPS_STATE_ORDINAL:
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
index e20b2ca..507ff59 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -44,4 +44,11 @@
public static OverviewState newSwitchState(int id) {
return new OverviewState(id);
}
+
+ /**
+ * New Overview substate that represents the overview in modal mode (one task shown on its own)
+ */
+ public static OverviewState newModalTaskState(int id) {
+ return new OverviewState(id);
+ }
}