From 882072baacaee4ecd43f0209b691a9af746462f2 Mon Sep 17 00:00:00 2001 From: Winson Date: Mon, 12 Oct 2015 11:26:33 -0700 Subject: [PATCH] Allowing multiple preferred drag regions for tablets. Change-Id: I514e501d185f4139ce21798fc92bc931626c8239 --- .../systemui/recents/model/TaskStack.java | 37 ++++++++- .../systemui/recents/views/RecentsView.java | 82 +++++++++++-------- .../views/RecentsViewTouchHandler.java | 25 ++++-- 3 files changed, 98 insertions(+), 46 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java index 48a12ed5a0255..65981121d9d67 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java @@ -16,11 +16,13 @@ package com.android.systemui.recents.model; +import android.animation.ObjectAnimator; import android.app.ActivityManager; import android.content.Context; import android.graphics.Color; import android.graphics.Rect; import android.graphics.RectF; +import android.graphics.drawable.ColorDrawable; import com.android.systemui.R; import com.android.systemui.recents.Constants; import com.android.systemui.recents.misc.NamedCounter; @@ -193,10 +195,37 @@ public class TaskStack { BOTTOM(DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, 192, new RectF(0, 0.7f, 1, 1), new RectF(0, 0.7f, 1, 1), new RectF(0, 0, 1, 0.3f)); + // Represents the view state of this dock state + public class ViewState { + public final int dockAreaAlpha; + public final ColorDrawable dockAreaOverlay; + private ObjectAnimator dockAreaOverlayAnimator; + + private ViewState(int alpha) { + dockAreaAlpha = alpha; + dockAreaOverlay = new ColorDrawable(0xFFffffff); + dockAreaOverlay.setAlpha(0); + } + + /** + * Creates a new alpha animation. + */ + public void startAlphaAnimation(int alpha, int duration) { + if (dockAreaOverlay.getAlpha() != alpha) { + if (dockAreaOverlayAnimator != null) { + dockAreaOverlayAnimator.cancel(); + } + dockAreaOverlayAnimator = ObjectAnimator.ofInt(dockAreaOverlay, "alpha", alpha); + dockAreaOverlayAnimator.setDuration(duration); + dockAreaOverlayAnimator.start(); + } + } + } + public final int createMode; - public final int dockAreaAlpha; - private final RectF touchArea; + public final ViewState viewState; private final RectF dockArea; + private final RectF touchArea; private final RectF stackArea; /** @@ -207,9 +236,9 @@ public class TaskStack { DockState(int createMode, int dockAreaAlpha, RectF touchArea, RectF dockArea, RectF stackArea) { this.createMode = createMode; - this.dockAreaAlpha = dockAreaAlpha; - this.touchArea = touchArea; + this.viewState = new ViewState(dockAreaAlpha); this.dockArea = dockArea; + this.touchArea = touchArea; this.stackArea = stackArea; } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index f12042178f139..126612074a1be 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -16,19 +16,17 @@ package com.android.systemui.recents.views; -import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; import android.app.ActivityManager; import android.app.ActivityOptions; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Rect; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.IRemoteCallback; import android.os.RemoteException; +import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; import android.util.SparseArray; @@ -38,7 +36,6 @@ import android.view.MotionEvent; import android.view.View; import android.view.WindowInsets; import android.view.WindowManagerGlobal; -import android.view.animation.AccelerateInterpolator; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.FrameLayout; @@ -91,8 +88,12 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV RecentsViewTouchHandler mTouchHandler; DragView mDragView; - ColorDrawable mDockRegionOverlay; - ObjectAnimator mDockRegionOverlayAnimator; + TaskStack.DockState[] mVisibleDockStates = { + TaskStack.DockState.LEFT, + TaskStack.DockState.TOP, + TaskStack.DockState.RIGHT, + TaskStack.DockState.BOTTOM, + }; Interpolator mFastOutSlowInInterpolator; @@ -118,9 +119,6 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, com.android.internal.R.interpolator.fast_out_slow_in); mTouchHandler = new RecentsViewTouchHandler(this); - mDockRegionOverlay = new ColorDrawable(0xFFffffff); - mDockRegionOverlay.setAlpha(0); - mDockRegionOverlay.setCallback(this); } /** Sets the callbacks */ @@ -383,14 +381,23 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); - if (mDockRegionOverlay.getAlpha() > 0) { - mDockRegionOverlay.draw(canvas); + for (int i = mVisibleDockStates.length - 1; i >= 0; i--) { + Drawable d = mVisibleDockStates[i].viewState.dockAreaOverlay; + if (d.getAlpha() > 0) { + d.draw(canvas); + } } } @Override protected boolean verifyDrawable(Drawable who) { - return super.verifyDrawable(who) || who == mDockRegionOverlay; + for (int i = mVisibleDockStates.length - 1; i >= 0; i--) { + Drawable d = mVisibleDockStates[i].viewState.dockAreaOverlay; + if (d == who) { + return true; + } + } + return super.verifyDrawable(who); } /** Notifies each task view of the user interaction. */ @@ -775,11 +782,17 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV mDragView = event.dragView; addView(mDragView); - updateDockRegion(TaskStack.DockState.NONE); + updateVisibleDockRegions(mTouchHandler.getDockStatesForCurrentOrientation(), + TaskStack.DockState.NONE.viewState.dockAreaAlpha); } public final void onBusEvent(DragDockStateChangedEvent event) { - updateDockRegion(event.dockState); + if (event.dockState == TaskStack.DockState.NONE) { + updateVisibleDockRegions(mTouchHandler.getDockStatesForCurrentOrientation(), + TaskStack.DockState.NONE.viewState.dockAreaAlpha); + } else { + updateVisibleDockRegions(new TaskStack.DockState[] {event.dockState}, -1); + } } public final void onBusEvent(final DragEndEvent event) { @@ -790,8 +803,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV // Remove the drag view removeView(mDragView); mDragView = null; - mDockRegionOverlay.setAlpha(0); - invalidate(); + updateVisibleDockRegions(null, -1); // Dock the new task if we are hovering over a valid dock state if (event.dockState != TaskStack.DockState.NONE) { @@ -818,7 +830,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV .start(); // Animate the overlay alpha back to 0 - updateDockRegionAlpha(0); + updateVisibleDockRegions(null, -1); } else { event.postAnimationTrigger.decrement(); } @@ -827,24 +839,26 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV /** * Updates the dock region to match the specified dock state. */ - private void updateDockRegion(TaskStack.DockState dockState) { - TaskStack.DockState boundsDockState = dockState; - if (dockState == TaskStack.DockState.NONE) { - // If the dock state is null, then use the bounds of the preferred dock state for this - // orientation - boundsDockState = mTouchHandler.getPreferredDockStateForCurrentOrientation(); + private void updateVisibleDockRegions(TaskStack.DockState[] newDockStates, int overrideAlpha) { + ArraySet newDockStatesSet = new ArraySet<>(); + if (newDockStates != null) { + for (TaskStack.DockState dockState : newDockStates) { + newDockStatesSet.add(dockState); + } } - mDockRegionOverlay.setBounds( - boundsDockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight())); - updateDockRegionAlpha(dockState.dockAreaAlpha); - } - - private void updateDockRegionAlpha(int alpha) { - if (mDockRegionOverlayAnimator != null) { - mDockRegionOverlayAnimator.cancel(); + for (TaskStack.DockState dockState : mVisibleDockStates) { + TaskStack.DockState.ViewState viewState = dockState.viewState; + if (newDockStates == null || !newDockStatesSet.contains(dockState)) { + // This is no longer visible, so hide it + viewState.startAlphaAnimation(0, 150); + } else { + // This state is now visible, update the bounds and show it + int alpha = (overrideAlpha != -1 ? overrideAlpha : viewState.dockAreaAlpha); + viewState.dockAreaOverlay.setBounds( + dockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight())); + viewState.dockAreaOverlay.setCallback(this); + viewState.startAlphaAnimation(alpha, 150); + } } - mDockRegionOverlayAnimator = ObjectAnimator.ofInt(mDockRegionOverlay, "alpha", alpha); - mDockRegionOverlayAnimator.setDuration(150); - mDockRegionOverlayAnimator.start(); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java index 31ac755007f76..76399f4446aef 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java @@ -19,6 +19,7 @@ package com.android.systemui.recents.views; import android.content.res.Configuration; import android.graphics.Point; import android.view.MotionEvent; +import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.ui.dragndrop.DragDockStateChangedEvent; import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent; @@ -32,13 +33,17 @@ import com.android.systemui.recents.model.TaskStack; * Represents the dock regions for each orientation. */ class DockRegion { - public static TaskStack.DockState[] LANDSCAPE = { + public static TaskStack.DockState[] PHONE_LANDSCAPE = { TaskStack.DockState.LEFT, TaskStack.DockState.RIGHT }; - public static TaskStack.DockState[] PORTRAIT = { + public static TaskStack.DockState[] PHONE_PORTRAIT = { // We only allow docking to the top for now TaskStack.DockState.TOP }; + public static TaskStack.DockState[] TABLET_LANDSCAPE = { + TaskStack.DockState.LEFT, TaskStack.DockState.RIGHT + }; + public static TaskStack.DockState[] TABLET_PORTRAIT = PHONE_PORTRAIT; } /** @@ -60,12 +65,17 @@ class RecentsViewTouchHandler { mRv = rv; } - public TaskStack.DockState getPreferredDockStateForCurrentOrientation() { + /** + * Returns the preferred dock states for the current orientation. + */ + public TaskStack.DockState[] getDockStatesForCurrentOrientation() { boolean isLandscape = mRv.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; + RecentsConfiguration config = RecentsConfiguration.getInstance(); TaskStack.DockState[] dockStates = isLandscape ? - DockRegion.LANDSCAPE : DockRegion.PORTRAIT; - return dockStates[0]; + (config.isLargeScreen ? DockRegion.TABLET_LANDSCAPE : DockRegion.PHONE_LANDSCAPE) : + (config.isLargeScreen ? DockRegion.TABLET_PORTRAIT : DockRegion.PHONE_PORTRAIT); + return dockStates; } /** Touch preprocessing for handling below */ @@ -125,10 +135,9 @@ class RecentsViewTouchHandler { float y = evY - mDragView.getTopLeftOffset().y; // Update the dock state - TaskStack.DockState[] dockStates = isLandscape ? - DockRegion.LANDSCAPE : DockRegion.PORTRAIT; + TaskStack.DockState[] dockStates = getDockStatesForCurrentOrientation(); TaskStack.DockState foundDockState = TaskStack.DockState.NONE; - for (int i = 0; i < dockStates.length; i++) { + for (int i = dockStates.length - 1; i >= 0; i--) { TaskStack.DockState state = dockStates[i]; if (state.touchAreaContainsPoint(width, height, evX, evY)) { foundDockState = state;