Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 882072ba authored by Winson's avatar Winson
Browse files

Allowing multiple preferred drag regions for tablets.

Change-Id: I514e501d185f4139ce21798fc92bc931626c8239
parent 09d8a184
Loading
Loading
Loading
Loading
+33 −4
Original line number Diff line number Diff line
@@ -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));

        public final int createMode;
        // Represents the view state of this dock state
        public class ViewState {
            public final int dockAreaAlpha;
        private final RectF touchArea;
            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 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;
        }

+48 −34
Original line number Diff line number Diff line
@@ -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();
        }
        mDockRegionOverlay.setBounds(
                boundsDockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight()));
        updateDockRegionAlpha(dockState.dockAreaAlpha);
    private void updateVisibleDockRegions(TaskStack.DockState[] newDockStates, int overrideAlpha) {
        ArraySet<TaskStack.DockState> newDockStatesSet = new ArraySet<>();
        if (newDockStates != null) {
            for (TaskStack.DockState dockState : newDockStates) {
                newDockStatesSet.add(dockState);
            }
        }
        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);
            }

    private void updateDockRegionAlpha(int alpha) {
        if (mDockRegionOverlayAnimator != null) {
            mDockRegionOverlayAnimator.cancel();
        }
        mDockRegionOverlayAnimator = ObjectAnimator.ofInt(mDockRegionOverlay, "alpha", alpha);
        mDockRegionOverlayAnimator.setDuration(150);
        mDockRegionOverlayAnimator.start();
    }
}
+17 −8
Original line number Diff line number Diff line
@@ -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;