summaryrefslogtreecommitdiffstats
path: root/quickstep
diff options
context:
space:
mode:
Diffstat (limited to 'quickstep')
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java182
-rw-r--r--quickstep/res/values/dimens.xml3
2 files changed, 136 insertions, 49 deletions
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 673beff85..21ddfc015 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
@@ -15,74 +15,131 @@
*/
package com.android.launcher3.uioverrides.touchcontrollers;
+import static android.view.View.TRANSLATION_X;
+
+import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
+import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
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.touch.AbstractStateChangeTouchController.SUCCESS_TRANSITION_PROGRESS;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.view.MotionEvent;
-import android.view.View;
import android.view.animation.Interpolator;
+import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager.AnimationConfig;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsTransitionController;
+import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SwipeDetector;
import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Command;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.util.TouchController;
import com.android.quickstep.views.RecentsView;
/**
- * Handles swiping up on the nav bar to go home from overview or all apps.
+ * Handles swiping up on the nav bar to go home from launcher, e.g. overview or all apps.
*/
-public class NavBarToHomeTouchController extends AbstractStateChangeTouchController {
+public class NavBarToHomeTouchController implements TouchController, SwipeDetector.Listener {
private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL_3;
+ private final Launcher mLauncher;
+ private final SwipeDetector mSwipeDetector;
+ private final float mPullbackDistance;
+
+ private boolean mNoIntercept;
+ private LauncherState mStartState;
+ private LauncherState mEndState = NORMAL;
+ private AnimatorPlaybackController mCurrentAnimation;
+
public NavBarToHomeTouchController(Launcher launcher) {
- super(launcher, SwipeDetector.VERTICAL);
+ mLauncher = launcher;
+ mSwipeDetector = new SwipeDetector(mLauncher, this, SwipeDetector.VERTICAL);
+ mPullbackDistance = mLauncher.getResources().getDimension(R.dimen.home_pullback_distance);
}
@Override
- protected boolean canInterceptTouch(MotionEvent ev) {
+ public final boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ mStartState = mLauncher.getStateManager().getState();
+ mNoIntercept = !canInterceptTouch(ev);
+ if (mNoIntercept) {
+ return false;
+ }
+ mSwipeDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_POSITIVE, false);
+ }
+
+ if (mNoIntercept) {
+ return false;
+ }
+
+ onControllerTouchEvent(ev);
+ return mSwipeDetector.isDraggingOrSettling();
+ }
+
+ private boolean canInterceptTouch(MotionEvent ev) {
boolean cameFromNavBar = (ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) != 0;
- return cameFromNavBar && (mLauncher.isInState(OVERVIEW) || mLauncher.isInState(ALL_APPS));
+ if (!cameFromNavBar) {
+ return false;
+ }
+ if (mStartState == OVERVIEW || mStartState == ALL_APPS) {
+ return true;
+ }
+ if (!mLauncher.hasWindowFocus()) {
+ return true;
+ }
+ if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
+ return true;
+ }
+ return false;
}
@Override
- protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
- return isDragTowardPositive ? NORMAL : fromState;
+ public final boolean onControllerTouchEvent(MotionEvent ev) {
+ return mSwipeDetector.onTouchEvent(ev);
+ }
+
+ private float getShiftRange() {
+ return mLauncher.getDeviceProfile().heightPx;
}
@Override
- protected float initCurrentAnimation(int animComponents) {
+ public void onDragStart(boolean start) {
+ initCurrentAnimation();
+ }
+
+ private void initCurrentAnimation() {
long accuracy = (long) (getShiftRange() * 2);
- final AnimatorSet anim;
- if (mFromState == OVERVIEW) {
- anim = new AnimatorSet();
+ final AnimatorSet anim = new AnimatorSet();
+ if (mStartState == OVERVIEW) {
RecentsView recentsView = mLauncher.getOverviewPanel();
- float pullbackDistance = recentsView.getPaddingStart() / 2;
+ float pullbackDist = mPullbackDistance;
if (!recentsView.isRtl()) {
- pullbackDistance = -pullbackDistance;
+ pullbackDist = -pullbackDist;
}
- anim.play(ObjectAnimator.ofFloat(recentsView, View.TRANSLATION_X, pullbackDistance));
- anim.setInterpolator(PULLBACK_INTERPOLATOR);
- } else { // if (mFromState == ALL_APPS)
+ Animator pullback = ObjectAnimator.ofFloat(recentsView, TRANSLATION_X, pullbackDist);
+ pullback.setInterpolator(PULLBACK_INTERPOLATOR);
+ anim.play(pullback);
+ } else if (mStartState == ALL_APPS) {
AnimatorSetBuilder builder = new AnimatorSetBuilder();
AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
- final float pullbackDistance = mLauncher.getDeviceProfile().allAppsIconSizePx / 2;
Animator allAppsProgress = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS,
- -pullbackDistance / allAppsController.getShiftRange());
+ -mPullbackDistance / allAppsController.getShiftRange());
allAppsProgress.setInterpolator(PULLBACK_INTERPOLATOR);
builder.play(allAppsProgress);
// Slightly fade out all apps content to further distinguish from scrolling.
@@ -90,52 +147,79 @@ public class NavBarToHomeTouchController extends AbstractStateChangeTouchControl
.mapToProgress(PULLBACK_INTERPOLATOR, 0, 0.5f));
AnimationConfig config = new AnimationConfig();
config.duration = accuracy;
- allAppsController.setAlphas(mToState.getVisibleElements(mLauncher), config, builder);
- anim = builder.build();
+ allAppsController.setAlphas(mEndState.getVisibleElements(mLauncher), config, builder);
+ anim.play(builder.build());
+ }
+ AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mLauncher);
+ if (topView != null) {
+ Animator hintCloseAnim = topView.createHintCloseAnim(mPullbackDistance);
+ if (hintCloseAnim != null) {
+ hintCloseAnim.setInterpolator(PULLBACK_INTERPOLATOR);
+ anim.play(hintCloseAnim);
+ }
}
anim.setDuration(accuracy);
mCurrentAnimation = AnimatorPlaybackController.wrap(anim, accuracy, this::clearState);
- return -1 / getShiftRange();
+ }
+
+ private void clearState() {
+ mCurrentAnimation = null;
+ mSwipeDetector.finishedScrolling();
+ mSwipeDetector.setDetectableScrollConditions(0, false);
}
@Override
- public void onDragStart(boolean start) {
- super.onDragStart(start);
- mStartContainerType = LauncherLogProto.ContainerType.NAVBAR;
+ public boolean onDrag(float displacement) {
+ // Only allow swipe up.
+ displacement = Math.min(0, displacement);
+ float progress = Utilities.getProgress(displacement, 0, getShiftRange());
+ mCurrentAnimation.setPlayFraction(progress);
+ return true;
}
@Override
public void onDragEnd(float velocity, boolean fling) {
final int logAction = fling ? Touch.FLING : Touch.SWIPE;
- float interpolatedProgress = PULLBACK_INTERPOLATOR.getInterpolation(
- mCurrentAnimation.getProgressFraction());
- if (interpolatedProgress >= SUCCESS_TRANSITION_PROGRESS || velocity < 0 && fling) {
- mLauncher.getStateManager().goToState(mToState, true,
- () -> onSwipeInteractionCompleted(mToState, logAction));
+ float progress = mCurrentAnimation.getProgressFraction();
+ float interpolatedProgress = PULLBACK_INTERPOLATOR.getInterpolation(progress);
+ boolean success = interpolatedProgress >= SUCCESS_TRANSITION_PROGRESS
+ || (velocity < 0 && fling);
+ if (success) {
+ mLauncher.getStateManager().goToState(mEndState, true,
+ () -> onSwipeInteractionCompleted(mEndState));
+ if (mStartState != mEndState) {
+ logStateChange(mStartState.containerType, logAction);
+ }
+ AbstractFloatingView topOpenView = AbstractFloatingView.getTopOpenView(mLauncher);
+ if (topOpenView != null) {
+ AbstractFloatingView.closeAllOpenViews(mLauncher);
+ logStateChange(topOpenView.getLogContainerType(), logAction);
+ }
} else {
// Quickly return to the state we came from (we didn't move far).
- AnimatorPlaybackController anim = mLauncher.getStateManager()
- .createAnimationToNewWorkspace(mFromState, 80);
- anim.setEndAction(() -> onSwipeInteractionCompleted(mFromState, logAction));
- anim.start();
+ ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
+ anim.setFloatValues(progress, 0);
+ anim.addListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ onSwipeInteractionCompleted(mStartState);
+ }
+ });
+ anim.setDuration(80).start();
}
- mCurrentAnimation.dispatchOnCancel();
- }
-
- @Override
- protected int getDirectionForLog() {
- return LauncherLogProto.Action.Direction.UP;
}
- @Override
- protected boolean goingBetweenNormalAndOverview(LauncherState fromState,
- LauncherState toState) {
- // We don't want to create an atomic animation to/from overview.
- return false;
+ private void onSwipeInteractionCompleted(LauncherState targetState) {
+ clearState();
+ mLauncher.getStateManager().goToState(targetState, false /* animated */);
}
- @Override
- protected int getLogContainerTypeForNormalState() {
- return LauncherLogProto.ContainerType.NAVBAR;
+ private void logStateChange(int startContainerType, int logAction) {
+ mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
+ LauncherLogProto.Action.Direction.UP,
+ LauncherLogProto.ContainerType.NAVBAR,
+ startContainerType,
+ mEndState.containerType,
+ mLauncher.getWorkspace().getCurrentPage());
}
}
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 97f2de762..9e1833c75 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -68,4 +68,7 @@
<!-- Assistant Gestures -->
<dimen name="gestures_assistant_size">28dp</dimen>
<dimen name="gestures_assistant_drag_threshold">70dp</dimen>
+
+ <!-- Distance to move elements when swiping up to go home from launcher -->
+ <dimen name="home_pullback_distance">28dp</dimen>
</resources>