From 199ba1cb272daa147510c3be27ad129b5beb5b4e Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Wed, 18 Jan 2017 12:38:18 -0800 Subject: [PATCH] Adjustments to PIP heuristics to snapping along edges of screen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updating to match prototype — PIP will snap to corners if within a certain distance from them - PIP can be placed freely along edges of screen otherwise Test: manual Change-Id: Ief5337c5fcfc2a19088bb947486634712ec6ca5d --- .../internal/policy/PipSnapAlgorithm.java | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/core/java/com/android/internal/policy/PipSnapAlgorithm.java index 4dd3360bcacd4..3cbc6c23754a8 100644 --- a/core/java/com/android/internal/policy/PipSnapAlgorithm.java +++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java @@ -39,14 +39,20 @@ public class PipSnapAlgorithm { private static final int SNAP_MODE_CORNERS_AND_SIDES = 1; // Allows snapping to anywhere along the edge of the screen private static final int SNAP_MODE_EDGE = 2; + // Allows snapping to four corners on a fling towards a corner or slow move near a corner + // snaps anywhere along the edge of screen otherwise + private static final int SNAP_MODE_CORNERS_AND_EDGES = 3; // The friction multiplier to control how slippery the PIP is when flung private static final float SCROLL_FRICTION_MULTIPLIER = 8f; + // Threshold to magnet to a corner + private static final float CORNER_MAGNET_THRESHOLD = 0.3f; + private final Context mContext; private final ArrayList mSnapGravities = new ArrayList<>(); - private final int mDefaultSnapMode = SNAP_MODE_CORNERS_ONLY; + private final int mDefaultSnapMode = SNAP_MODE_CORNERS_AND_EDGES; private int mSnapMode = mDefaultSnapMode; private Scroller mScroller; @@ -107,7 +113,24 @@ public class PipSnapAlgorithm { movementBounds.right + stackBounds.width(), movementBounds.bottom + stackBounds.height()); final Rect newBounds = new Rect(stackBounds); - if (mSnapMode == SNAP_MODE_EDGE) { + if (mSnapMode == SNAP_MODE_CORNERS_AND_EDGES) { + final Rect tmpBounds = new Rect(); + final Point[] snapTargets = new Point[mSnapGravities.size()]; + for (int i = 0; i < mSnapGravities.size(); i++) { + Gravity.apply(mSnapGravities.get(i), stackBounds.width(), stackBounds.height(), + pipBounds, 0, 0, tmpBounds); + snapTargets[i] = new Point(tmpBounds.left, tmpBounds.top); + } + Point snapTarget = findClosestPoint(stackBounds.left, stackBounds.top, snapTargets); + float distance = distanceToPoint(snapTarget, stackBounds.left, stackBounds.top); + final float thresh = stackBounds.width() * CORNER_MAGNET_THRESHOLD; + if (distance < thresh) { + newBounds.offsetTo(snapTarget.x, snapTarget.y); + } else { + // Otherwise we snap to the edge + snapRectToClosestEdge(stackBounds, movementBounds, newBounds); + } + } else if (mSnapMode == SNAP_MODE_EDGE) { // Find the closest edge to the given stack bounds and snap to it snapRectToClosestEdge(stackBounds, movementBounds, newBounds); } else { @@ -270,6 +293,7 @@ public class PipSnapAlgorithm { } // Fall through case SNAP_MODE_CORNERS_ONLY: + case SNAP_MODE_CORNERS_AND_EDGES: mSnapGravities.add(Gravity.TOP | Gravity.LEFT); mSnapGravities.add(Gravity.TOP | Gravity.RIGHT); mSnapGravities.add(Gravity.BOTTOM | Gravity.LEFT);