Merge "Add taskbar stashing feedforward, i.e. hint at upcoming stash/unstash" into sc-v2-dev
This commit is contained in:
@@ -233,11 +233,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongPressToUnstashTaskbar() {
|
||||
return mControllers.taskbarStashController.onLongPressToUnstashTaskbar();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ev MotionEvent in screen coordinates.
|
||||
* @return Whether any Taskbar item could handle the given MotionEvent if given the chance.
|
||||
|
||||
@@ -40,6 +40,8 @@ public class StashedHandleViewController {
|
||||
private final int mStashedHandleHeight;
|
||||
private final AnimatedFloat mTaskbarStashedHandleAlpha = new AnimatedFloat(
|
||||
this::updateStashedHandleAlpha);
|
||||
private final AnimatedFloat mTaskbarStashedHandleHintScale = new AnimatedFloat(
|
||||
this::updateStashedHandleHintScale);
|
||||
|
||||
// Initialized in init.
|
||||
private TaskbarControllers mControllers;
|
||||
@@ -64,6 +66,7 @@ public class StashedHandleViewController {
|
||||
mStashedHandleView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarSize;
|
||||
|
||||
updateStashedHandleAlpha();
|
||||
mTaskbarStashedHandleHintScale.updateValue(1f);
|
||||
|
||||
final int stashedTaskbarHeight = mControllers.taskbarStashController.getStashedHeight();
|
||||
mStashedHandleView.setOutlineProvider(new ViewOutlineProvider() {
|
||||
@@ -80,12 +83,24 @@ public class StashedHandleViewController {
|
||||
outline.setRoundRect(mStashedHandleBounds, mStashedHandleRadius);
|
||||
}
|
||||
});
|
||||
|
||||
mStashedHandleView.addOnLayoutChangeListener((view, i, i1, i2, i3, i4, i5, i6, i7) -> {
|
||||
final int stashedCenterX = view.getWidth() / 2;
|
||||
final int stashedCenterY = view.getHeight() - stashedTaskbarHeight / 2;
|
||||
|
||||
view.setPivotX(stashedCenterX);
|
||||
view.setPivotY(stashedCenterY);
|
||||
});
|
||||
}
|
||||
|
||||
public AnimatedFloat getStashedHandleAlpha() {
|
||||
return mTaskbarStashedHandleAlpha;
|
||||
}
|
||||
|
||||
public AnimatedFloat getStashedHandleHintScale() {
|
||||
return mTaskbarStashedHandleHintScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a {@link RevealOutlineAnimation} Animator that updates the stashed handle
|
||||
* shape and size. When stashed, the shape is a thin rounded pill. When unstashed, the shape
|
||||
@@ -105,4 +120,9 @@ public class StashedHandleViewController {
|
||||
protected void updateStashedHandleAlpha() {
|
||||
mStashedHandleView.setAlpha(mTaskbarStashedHandleAlpha.value);
|
||||
}
|
||||
|
||||
protected void updateStashedHandleHintScale() {
|
||||
mStashedHandleView.setScaleX(mTaskbarStashedHandleHintScale.value);
|
||||
mStashedHandleView.setScaleY(mTaskbarStashedHandleHintScale.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,4 +332,20 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
|
||||
AbstractFloatingView.closeAllOpenViews(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when we detect a long press in the nav region before passing the gesture slop.
|
||||
* @return Whether taskbar handled the long press, and thus should cancel the gesture.
|
||||
*/
|
||||
public boolean onLongPressToUnstashTaskbar() {
|
||||
return mControllers.taskbarStashController.onLongPressToUnstashTaskbar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when we detect a motion down or up/cancel in the nav region while stashed.
|
||||
* @param animateForward Whether to animate towards the unstashed hint state or back to stashed.
|
||||
*/
|
||||
public void startTaskbarUnstashHint(boolean animateForward) {
|
||||
mControllers.taskbarStashController.startUnstashHint(animateForward);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.hardware.display.DisplayManager;
|
||||
import android.view.Display;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
@@ -188,4 +189,8 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen
|
||||
mDisplayController.removeChangeListener(this);
|
||||
mSysUINavigationMode.removeModeChangeListener(this);
|
||||
}
|
||||
|
||||
public @Nullable TaskbarActivityContext getCurrentActivityContext() {
|
||||
return mTaskbarActivityContext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.animation.AnimatorSet;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
@@ -46,6 +47,22 @@ public class TaskbarStashController {
|
||||
*/
|
||||
private static final float STASHED_TASKBAR_SCALE = 0.5f;
|
||||
|
||||
/**
|
||||
* How long the hint animation plays, starting on motion down.
|
||||
*/
|
||||
private static final long TASKBAR_HINT_STASH_DURATION =
|
||||
ViewConfiguration.DEFAULT_LONG_PRESS_TIMEOUT;
|
||||
|
||||
/**
|
||||
* The scale that TaskbarView animates to when hinting towards the stashed state.
|
||||
*/
|
||||
private static final float STASHED_TASKBAR_HINT_SCALE = 0.9f;
|
||||
|
||||
/**
|
||||
* The scale that the stashed handle animates to when hinting towards the unstashed state.
|
||||
*/
|
||||
private static final float UNSTASHED_TASKBAR_HANDLE_HINT_SCALE = 1.1f;
|
||||
|
||||
/**
|
||||
* The SharedPreferences key for whether user has manually stashed the taskbar.
|
||||
*/
|
||||
@@ -71,6 +88,7 @@ public class TaskbarStashController {
|
||||
private AnimatedFloat mIconTranslationYForStash;
|
||||
// Stashed handle properties.
|
||||
private AnimatedFloat mTaskbarStashedHandleAlpha;
|
||||
private AnimatedFloat mTaskbarStashedHandleHintScale;
|
||||
|
||||
/** Whether the user has manually invoked taskbar stashing, which we persist. */
|
||||
private boolean mIsStashedInApp;
|
||||
@@ -102,6 +120,7 @@ public class TaskbarStashController {
|
||||
StashedHandleViewController stashedHandleController =
|
||||
controllers.stashedHandleViewController;
|
||||
mTaskbarStashedHandleAlpha = stashedHandleController.getStashedHandleAlpha();
|
||||
mTaskbarStashedHandleHintScale = stashedHandleController.getStashedHandleHintScale();
|
||||
|
||||
mIsStashedInApp = supportsStashing()
|
||||
&& mPrefs.getBoolean(SHARED_PREFS_STASHED_KEY, DEFAULT_STASHED_PREF);
|
||||
@@ -246,6 +265,9 @@ public class TaskbarStashController {
|
||||
if (stashedHandleRevealAnim != null) {
|
||||
fullLengthAnimatorSet.play(stashedHandleRevealAnim);
|
||||
}
|
||||
// Return the stashed handle to its default scale in case it was changed as part of the
|
||||
// feedforward hint. Note that the reveal animation above also visually scales it.
|
||||
fullLengthAnimatorSet.play(mTaskbarStashedHandleHintScale.animateToValue(1f));
|
||||
|
||||
fullLengthAnimatorSet.setDuration(duration);
|
||||
firstHalfAnimatorSet.setDuration((long) (duration * firstHalfDurationScale));
|
||||
@@ -271,4 +293,36 @@ public class TaskbarStashController {
|
||||
});
|
||||
return mAnimator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and starts a partial stash animation, hinting at the new state that will trigger when
|
||||
* long press is detected.
|
||||
* @param animateForward Whether we are going towards the new stashed state or returning to the
|
||||
* unstashed state.
|
||||
*/
|
||||
public void startStashHint(boolean animateForward) {
|
||||
if (isStashed() || !supportsStashing()) {
|
||||
// Already stashed, no need to hint in that direction.
|
||||
return;
|
||||
}
|
||||
mIconScaleForStash.animateToValue(
|
||||
animateForward ? STASHED_TASKBAR_HINT_SCALE : 1)
|
||||
.setDuration(TASKBAR_HINT_STASH_DURATION).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and starts a partial unstash animation, hinting at the new state that will trigger
|
||||
* when long press is detected.
|
||||
* @param animateForward Whether we are going towards the new unstashed state or returning to
|
||||
* the stashed state.
|
||||
*/
|
||||
public void startUnstashHint(boolean animateForward) {
|
||||
if (!isStashed()) {
|
||||
// Already unstashed, no need to hint in that direction.
|
||||
return;
|
||||
}
|
||||
mTaskbarStashedHandleHintScale.animateToValue(
|
||||
animateForward ? UNSTASHED_TASKBAR_HANDLE_HINT_SCALE : 1)
|
||||
.setDuration(TASKBAR_HINT_STASH_DURATION).start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,4 @@ public class TaskbarUIController {
|
||||
}
|
||||
|
||||
protected void updateContentInsets(Rect outContentInsets) { }
|
||||
|
||||
protected boolean onLongPressToUnstashTaskbar() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,6 +222,15 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (!mTouchEnabled) {
|
||||
return true;
|
||||
}
|
||||
mControllerCallbacks.onTouchEvent(event);
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public void setTouchesEnabled(boolean touchEnabled) {
|
||||
this.mTouchEnabled = touchEnabled;
|
||||
}
|
||||
|
||||
@@ -17,14 +17,17 @@ package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.Utilities.squaredHypot;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.quickstep.AnimatedFloat.VALUE;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
@@ -188,6 +191,11 @@ public class TaskbarViewController {
|
||||
* Callbacks for {@link TaskbarView} to interact with its controller.
|
||||
*/
|
||||
public class TaskbarViewCallbacks {
|
||||
private final float mSquaredTouchSlop = Utilities.squaredTouchSlop(mActivity);
|
||||
|
||||
private float mDownX, mDownY;
|
||||
private boolean mCanceledStashHint;
|
||||
|
||||
public View.OnClickListener getIconOnClickListener() {
|
||||
return mActivity::onTaskbarIconClicked;
|
||||
}
|
||||
@@ -199,5 +207,33 @@ public class TaskbarViewController {
|
||||
public View.OnLongClickListener getBackgroundOnLongClickListener() {
|
||||
return view -> mControllers.taskbarStashController.updateAndAnimateIsStashedInApp(true);
|
||||
}
|
||||
|
||||
public void onTouchEvent(MotionEvent motionEvent) {
|
||||
final float x = motionEvent.getRawX();
|
||||
final float y = motionEvent.getRawY();
|
||||
switch (motionEvent.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mDownX = x;
|
||||
mDownY = y;
|
||||
mControllers.taskbarStashController.startStashHint(/* animateForward = */ true);
|
||||
mCanceledStashHint = false;
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (!mCanceledStashHint
|
||||
&& squaredHypot(mDownX - x, mDownY - y) > mSquaredTouchSlop) {
|
||||
mControllers.taskbarStashController.startStashHint(
|
||||
/* animateForward= */ false);
|
||||
mCanceledStashHint = true;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
if (!mCanceledStashHint) {
|
||||
mControllers.taskbarStashController.startStashHint(
|
||||
/* animateForward= */ false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,14 +363,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when we detect a long press in the nav region before passing the gesture slop.
|
||||
* @return Whether taskbar handled the long press, and thus should cancel the gesture.
|
||||
*/
|
||||
public boolean onLongPressToUnstashTaskbar() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color of the scrim behind overview when at rest in this state.
|
||||
* Return {@link Color#TRANSPARENT} for no scrim.
|
||||
|
||||
@@ -317,15 +317,6 @@ public final class LauncherActivityInterface extends
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongPressToUnstashTaskbar() {
|
||||
LauncherTaskbarUIController taskbarController = getTaskbarController();
|
||||
if (taskbarController == null) {
|
||||
return super.onLongPressToUnstashTaskbar();
|
||||
}
|
||||
return taskbarController.onLongPressToUnstashTaskbar();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getOverviewScrimColorForState(BaseQuickstepLauncher launcher,
|
||||
LauncherState state) {
|
||||
|
||||
@@ -680,7 +680,7 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||
StatefulActivity activity = activityInterface.getCreatedActivity();
|
||||
if (activity != null && activity.getDeviceProfile().isTaskbarPresent) {
|
||||
base = new TaskbarStashInputConsumer(this, base, mInputMonitorCompat,
|
||||
activityInterface);
|
||||
mTaskbarManager.getCurrentActivityContext());
|
||||
}
|
||||
|
||||
if (FeatureFlags.ENABLE_QUICK_CAPTURE_GESTURE.get()) {
|
||||
|
||||
@@ -15,12 +15,15 @@
|
||||
*/
|
||||
package com.android.quickstep.inputconsumers;
|
||||
|
||||
import static com.android.launcher3.Utilities.squaredHypot;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.quickstep.BaseActivityInterface;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.taskbar.TaskbarActivityContext;
|
||||
import com.android.quickstep.InputConsumer;
|
||||
import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
|
||||
@@ -29,13 +32,18 @@ import com.android.systemui.shared.system.InputMonitorCompat;
|
||||
*/
|
||||
public class TaskbarStashInputConsumer extends DelegateInputConsumer {
|
||||
|
||||
private final BaseActivityInterface mActivityInterface;
|
||||
private final TaskbarActivityContext mTaskbarActivityContext;
|
||||
private final GestureDetector mLongPressDetector;
|
||||
private final float mSquaredTouchSlop;
|
||||
|
||||
private float mDownX, mDownY;
|
||||
private boolean mCanceledUnstashHint;
|
||||
|
||||
public TaskbarStashInputConsumer(Context context, InputConsumer delegate,
|
||||
InputMonitorCompat inputMonitor, BaseActivityInterface activityInterface) {
|
||||
InputMonitorCompat inputMonitor, TaskbarActivityContext taskbarActivityContext) {
|
||||
super(delegate, inputMonitor);
|
||||
mActivityInterface = activityInterface;
|
||||
mTaskbarActivityContext = taskbarActivityContext;
|
||||
mSquaredTouchSlop = Utilities.squaredTouchSlop(context);
|
||||
|
||||
mLongPressDetector = new GestureDetector(context, new SimpleOnGestureListener() {
|
||||
@Override
|
||||
@@ -55,11 +63,41 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer {
|
||||
mLongPressDetector.onTouchEvent(ev);
|
||||
if (mState != STATE_ACTIVE) {
|
||||
mDelegate.onMotionEvent(ev);
|
||||
|
||||
if (mTaskbarActivityContext != null) {
|
||||
final float x = ev.getRawX();
|
||||
final float y = ev.getRawY();
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mDownX = x;
|
||||
mDownY = y;
|
||||
mTaskbarActivityContext.startTaskbarUnstashHint(
|
||||
/* animateForward = */ true);
|
||||
mCanceledUnstashHint = false;
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (!mCanceledUnstashHint
|
||||
&& squaredHypot(mDownX - x, mDownY - y) > mSquaredTouchSlop) {
|
||||
mTaskbarActivityContext.startTaskbarUnstashHint(
|
||||
/* animateForward = */ false);
|
||||
mCanceledUnstashHint = true;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
if (!mCanceledUnstashHint) {
|
||||
mTaskbarActivityContext.startTaskbarUnstashHint(
|
||||
/* animateForward = */ false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onLongPressDetected(MotionEvent motionEvent) {
|
||||
if (mActivityInterface.onLongPressToUnstashTaskbar()) {
|
||||
if (mTaskbarActivityContext != null
|
||||
&& mTaskbarActivityContext.onLongPressToUnstashTaskbar()) {
|
||||
setActive(motionEvent);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user