summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Winson <winsonc@google.com> 2016-04-18 16:57:27 -0700
committer Winson <winsonc@google.com> 2016-04-18 18:20:43 -0700
commit99ef458ff1b79c93a8dfdc289fb6ff80fd7aacf6 (patch)
tree088fa67745580cf7bbe4e24e8203b366dc6b71fb
parent3664426dcf3a603a52d630a74f3caef9da682457 (diff)
Adding hint text for drop targets.
Bug: 28192178 Change-Id: Id7be5129488622b56082d2dfa328b751311cabd7
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/res/values/strings.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java147
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java1
5 files changed, 144 insertions, 39 deletions
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 03b9837e6175..504361008570 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -640,6 +640,9 @@
<!-- The amount of overscroll allowed when flinging to the end of the stack. -->
<dimen name="recents_fling_overscroll_distance">24dp</dimen>
+ <!-- The size of the drag hint text. -->
+ <dimen name="recents_drag_hint_text_size">14sp</dimen>
+
<!-- The min alpha to apply to a task affiliation group color. -->
<item name="recents_task_affiliation_color_min_alpha_percentage" format="float" type="dimen">0.6</item>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 37b00bbfdc27..a03aa28c47c5 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -737,6 +737,8 @@
<string name="recents_stack_action_button_label">Clear all</string>
<!-- Recents: Incompatible task message. [CHAR LIMIT=NONE] -->
<string name="recents_incompatible_app_message">App doesn\'t support split screen</string>
+ <!-- Recents: Hint text that shows on the drop targets to start multiwindow. [CHAR LIMIT=NONE] -->
+ <string name="recents_drag_hint_message">Drag here to use split screen</string>
<!-- Recents: MultiStack add stack split horizontal radio button. [CHAR LIMIT=NONE] -->
<string name="recents_multistack_add_stack_dialog_split_horizontal">Split Horizontal</string>
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 95e276f7c8cf..47995c4b73f3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -30,17 +30,21 @@ import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
-import android.animation.RectEvaluator;
+import android.annotation.IntDef;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.IntProperty;
import android.util.SparseArray;
import android.view.animation.Interpolator;
@@ -56,6 +60,8 @@ import com.android.systemui.recents.views.DropTarget;
import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -240,22 +246,30 @@ public class TaskStack {
*/
public static class DockState implements DropTarget {
+ // The rotation to apply to the hint text
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({HORIZONTAL, VERTICAL})
+ public @interface TextOrientation {}
+ private static final int HORIZONTAL = 0;
+ private static final int VERTICAL = 1;
+
private static final int DOCK_AREA_ALPHA = 192;
- public static final DockState NONE = new DockState(DOCKED_INVALID, -1, 80, null, null, null);
+ public static final DockState NONE = new DockState(DOCKED_INVALID, -1, 80, 255, HORIZONTAL,
+ null, null, null);
public static final DockState LEFT = new DockState(DOCKED_LEFT,
- DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA,
+ DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA, 0, VERTICAL,
new RectF(0, 0, 0.125f, 1), new RectF(0, 0, 0.125f, 1),
new RectF(0, 0, 0.5f, 1));
public static final DockState TOP = new DockState(DOCKED_TOP,
- DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA,
+ DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA, 0, HORIZONTAL,
new RectF(0, 0, 1, 0.125f), new RectF(0, 0, 1, 0.125f),
new RectF(0, 0, 1, 0.5f));
public static final DockState RIGHT = new DockState(DOCKED_RIGHT,
- DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA,
+ DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA, 0, VERTICAL,
new RectF(0.875f, 0, 1, 1), new RectF(0.875f, 0, 1, 1),
new RectF(0.5f, 0, 1, 1));
public static final DockState BOTTOM = new DockState(DOCKED_BOTTOM,
- DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA,
+ DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA, 0, HORIZONTAL,
new RectF(0, 0.875f, 1, 1), new RectF(0, 0.875f, 1, 1),
new RectF(0, 0.5f, 1, 1));
@@ -267,33 +281,109 @@ public class TaskStack {
}
// Represents the view state of this dock state
- public class ViewState {
+ public static class ViewState {
+ private static final IntProperty<ViewState> HINT_ALPHA =
+ new IntProperty<ViewState>("drawableAlpha") {
+ @Override
+ public void setValue(ViewState object, int alpha) {
+ object.mHintTextAlpha = alpha;
+ object.dockAreaOverlay.invalidateSelf();
+ }
+
+ @Override
+ public Integer get(ViewState object) {
+ return object.mHintTextAlpha;
+ }
+ };
+
public final int dockAreaAlpha;
public final ColorDrawable dockAreaOverlay;
- private AnimatorSet dockAreaOverlayAnimator;
-
- private ViewState(int alpha) {
- dockAreaAlpha = alpha;
+ public final int hintTextAlpha;
+ public final int hintTextOrientation;
+
+ private final int mHintTextResId;
+ private String mHintText;
+ private Paint mHintTextPaint;
+ private Point mHintTextBounds = new Point();
+ private int mHintTextAlpha = 255;
+ private AnimatorSet mDockAreaOverlayAnimator;
+ private Rect mTmpRect = new Rect();
+
+ private ViewState(int areaAlpha, int hintAlpha, @TextOrientation int hintOrientation,
+ int hintTextResId) {
+ dockAreaAlpha = areaAlpha;
dockAreaOverlay = new ColorDrawable(0xFFffffff);
dockAreaOverlay.setAlpha(0);
+ hintTextAlpha = hintAlpha;
+ hintTextOrientation = hintOrientation;
+ mHintTextResId = hintTextResId;
+ mHintTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mHintTextPaint.setColor(Color.WHITE);
+ }
+
+ /**
+ * Updates the view state with the given context.
+ */
+ public void update(Context context) {
+ Resources res = context.getResources();
+ mHintText = context.getString(mHintTextResId);
+ mHintTextPaint.setTextSize(res.getDimensionPixelSize(
+ R.dimen.recents_drag_hint_text_size));
+ mHintTextPaint.getTextBounds(mHintText, 0, mHintText.length(), mTmpRect);
+ mHintTextBounds.set((int) mHintTextPaint.measureText(mHintText), mTmpRect.height());
+ }
+
+ /**
+ * Draws the current view state.
+ */
+ public void draw(Canvas canvas) {
+ // Draw the overlay background
+ if (dockAreaOverlay.getAlpha() > 0) {
+ dockAreaOverlay.draw(canvas);
+ }
+
+ // Draw the hint text
+ if (mHintTextAlpha > 0) {
+ Rect bounds = dockAreaOverlay.getBounds();
+ int x = bounds.left + (bounds.width() - mHintTextBounds.x) / 2;
+ int y = bounds.top + (bounds.height() + mHintTextBounds.y) / 2;
+ mHintTextPaint.setAlpha(mHintTextAlpha);
+ if (hintTextOrientation == VERTICAL) {
+ canvas.save();
+ canvas.rotate(-90f, bounds.centerX(), bounds.centerY());
+ }
+ canvas.drawText(mHintText, x, y, mHintTextPaint);
+ if (hintTextOrientation == VERTICAL) {
+ canvas.restore();
+ }
+ }
}
/**
* Creates a new bounds and alpha animation.
*/
- public void startAnimation(Rect bounds, int alpha, int duration,
+ public void startAnimation(Rect bounds, int areaAlpha, int hintAlpha, int duration,
Interpolator interpolator, boolean animateAlpha, boolean animateBounds) {
- if (dockAreaOverlayAnimator != null) {
- dockAreaOverlayAnimator.cancel();
+ if (mDockAreaOverlayAnimator != null) {
+ mDockAreaOverlayAnimator.cancel();
}
ArrayList<Animator> animators = new ArrayList<>();
- if (dockAreaOverlay.getAlpha() != alpha) {
+ if (dockAreaOverlay.getAlpha() != areaAlpha) {
if (animateAlpha) {
animators.add(ObjectAnimator.ofInt(dockAreaOverlay,
- Utilities.DRAWABLE_ALPHA, dockAreaOverlay.getAlpha(), alpha));
+ Utilities.DRAWABLE_ALPHA, dockAreaOverlay.getAlpha(), areaAlpha));
} else {
- dockAreaOverlay.setAlpha(alpha);
+ dockAreaOverlay.setAlpha(areaAlpha);
+ }
+ }
+ if (mHintTextAlpha != hintAlpha) {
+ if (animateAlpha) {
+ animators.add(ObjectAnimator.ofInt(this, HINT_ALPHA, mHintTextAlpha,
+ hintAlpha));
+ } else {
+ mHintTextAlpha = hintAlpha;
+ dockAreaOverlay.invalidateSelf();
}
}
if (bounds != null && !dockAreaOverlay.getBounds().equals(bounds)) {
@@ -307,11 +397,11 @@ public class TaskStack {
}
}
if (!animators.isEmpty()) {
- dockAreaOverlayAnimator = new AnimatorSet();
- dockAreaOverlayAnimator.playTogether(animators);
- dockAreaOverlayAnimator.setDuration(duration);
- dockAreaOverlayAnimator.setInterpolator(interpolator);
- dockAreaOverlayAnimator.start();
+ mDockAreaOverlayAnimator = new AnimatorSet();
+ mDockAreaOverlayAnimator.playTogether(animators);
+ mDockAreaOverlayAnimator.setDuration(duration);
+ mDockAreaOverlayAnimator.setInterpolator(interpolator);
+ mDockAreaOverlayAnimator.start();
}
}
}
@@ -331,17 +421,26 @@ public class TaskStack {
* the initial touch area. This is also the new dock area to
* draw.
*/
- DockState(int dockSide, int createMode, int dockAreaAlpha, RectF touchArea, RectF dockArea,
+ DockState(int dockSide, int createMode, int dockAreaAlpha, int hintTextAlpha,
+ @TextOrientation int hintTextOrientation, RectF touchArea, RectF dockArea,
RectF expandedTouchDockArea) {
this.dockSide = dockSide;
this.createMode = createMode;
- this.viewState = new ViewState(dockAreaAlpha);
+ this.viewState = new ViewState(dockAreaAlpha, hintTextAlpha, hintTextOrientation,
+ R.string.recents_drag_hint_message);
this.dockArea = dockArea;
this.touchArea = touchArea;
this.expandedTouchDockArea = expandedTouchDockArea;
}
/**
+ * Updates the dock state with the given context.
+ */
+ public void update(Context context) {
+ viewState.update(context);
+ }
+
+ /**
* Returns whether {@param x} and {@param y} are contained in the area scaled to the
* given {@param width} and {@param height}.
*/
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 6604cccdb93d..a5ca302bac2f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -426,10 +426,7 @@ public class RecentsView extends FrameLayout {
ArrayList<TaskStack.DockState> visDockStates = mTouchHandler.getVisibleDockStates();
for (int i = visDockStates.size() - 1; i >= 0; i--) {
- Drawable d = visDockStates.get(i).viewState.dockAreaOverlay;
- if (d.getAlpha() > 0) {
- d.draw(canvas);
- }
+ visDockStates.get(i).viewState.draw(canvas);
}
}
@@ -465,6 +462,7 @@ public class RecentsView extends FrameLayout {
public final void onBusEvent(DragStartEvent event) {
updateVisibleDockRegions(mTouchHandler.getDockStatesForCurrentOrientation(),
true /* isDefaultDockState */, TaskStack.DockState.NONE.viewState.dockAreaAlpha,
+ TaskStack.DockState.NONE.viewState.hintTextAlpha,
true /* animateAlpha */, false /* animateBounds */);
}
@@ -472,11 +470,12 @@ public class RecentsView extends FrameLayout {
if (event.dropTarget == null || !(event.dropTarget instanceof TaskStack.DockState)) {
updateVisibleDockRegions(mTouchHandler.getDockStatesForCurrentOrientation(),
true /* isDefaultDockState */, TaskStack.DockState.NONE.viewState.dockAreaAlpha,
+ TaskStack.DockState.NONE.viewState.hintTextAlpha,
true /* animateAlpha */, true /* animateBounds */);
} else {
final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
updateVisibleDockRegions(new TaskStack.DockState[] {dockState},
- false /* isDefaultDockState */, -1, true /* animateAlpha */,
+ false /* isDefaultDockState */, -1, -1, true /* animateAlpha */,
true /* animateBounds */);
}
if (mStackActionButton != null) {
@@ -498,13 +497,9 @@ public class RecentsView extends FrameLayout {
final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
// Hide the dock region
- updateVisibleDockRegions(null, false /* isDefaultDockState */, -1,
+ updateVisibleDockRegions(null, false /* isDefaultDockState */, -1, -1,
false /* animateAlpha */, false /* animateBounds */);
- TaskStackLayoutAlgorithm stackLayout = mTaskStackView.getStackAlgorithm();
- TaskStackViewScroller stackScroller = mTaskStackView.getScroller();
- TaskViewTransform tmpTransform = new TaskViewTransform();
-
// We translated the view but we need to animate it back from the current layout-space
// rect to its final layout-space rect
int x = (int) event.taskView.getTranslationX();
@@ -548,7 +543,7 @@ public class RecentsView extends FrameLayout {
event.task.getTopComponent().flattenToShortString());
} else {
// Animate the overlay alpha back to 0
- updateVisibleDockRegions(null, true /* isDefaultDockState */, -1,
+ updateVisibleDockRegions(null, true /* isDefaultDockState */, -1, -1,
true /* animateAlpha */, false /* animateBounds */);
}
}
@@ -710,8 +705,8 @@ public class RecentsView extends FrameLayout {
* Updates the dock region to match the specified dock state.
*/
private void updateVisibleDockRegions(TaskStack.DockState[] newDockStates,
- boolean isDefaultDockState, int overrideAlpha, boolean animateAlpha,
- boolean animateBounds) {
+ boolean isDefaultDockState, int overrideAreaAlpha, int overrideHintAlpha,
+ boolean animateAlpha, boolean animateBounds) {
ArraySet<TaskStack.DockState> newDockStatesSet = Utilities.arrayToSet(newDockStates,
new ArraySet<TaskStack.DockState>());
ArrayList<TaskStack.DockState> visDockStates = mTouchHandler.getVisibleDockStates();
@@ -720,11 +715,16 @@ public class RecentsView extends FrameLayout {
TaskStack.DockState.ViewState viewState = dockState.viewState;
if (newDockStates == null || !newDockStatesSet.contains(dockState)) {
// This is no longer visible, so hide it
- viewState.startAnimation(null, 0, DOCK_AREA_OVERLAY_TRANSITION_DURATION,
+ viewState.startAnimation(null, 0, 0, DOCK_AREA_OVERLAY_TRANSITION_DURATION,
Interpolators.ALPHA_OUT, animateAlpha, animateBounds);
} else {
// This state is now visible, update the bounds and show it
- int alpha = (overrideAlpha != -1 ? overrideAlpha : viewState.dockAreaAlpha);
+ int areaAlpha = overrideAreaAlpha != -1
+ ? overrideAreaAlpha
+ : viewState.dockAreaAlpha;
+ int hintAlpha = overrideHintAlpha != -1
+ ? overrideHintAlpha
+ : viewState.hintTextAlpha;
Rect bounds = isDefaultDockState
? dockState.getPreDockedBounds(getMeasuredWidth(), getMeasuredHeight())
: dockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight(),
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 70c4dbdc9665..214ec90fe5ee 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -171,6 +171,7 @@ public class RecentsViewTouchHandler {
TaskStack.DockState[] dockStates = getDockStatesForCurrentOrientation();
for (TaskStack.DockState dockState : dockStates) {
registerDropTargetForCurrentDrag(dockState);
+ dockState.update(mRv.getContext());
mVisibleDockStates.add(dockState);
}
}