Merge "Added new app launch crop / positioning."
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index 8e6a5b6..99c4dba 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -56,6 +56,7 @@
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
+import android.os.SystemProperties;
import android.util.Pair;
import android.view.View;
@@ -99,6 +100,9 @@
private static final String TAG = "QuickstepTransition";
+ private static final boolean ENABLE_SHELL_STARTING_SURFACE =
+ SystemProperties.getBoolean("persist.debug.shell_starting_surface", false);
+
/** Duration of status bar animations. */
public static final int STATUS_BAR_TRANSITION_DURATION = 120;
@@ -442,9 +446,9 @@
RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets,
Rect windowTargetBounds, boolean toggleVisibility) {
- RectF bounds = new RectF();
+ RectF launcherIconBounds = new RectF();
FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v,
- toggleVisibility, bounds, true /* isOpening */);
+ toggleVisibility, launcherIconBounds, true /* isOpening */);
Rect crop = new Rect();
Matrix matrix = new Matrix();
@@ -458,11 +462,17 @@
mDragLayer.getLocationOnScreen(dragLayerBounds);
AnimOpenProperties prop = new AnimOpenProperties(mLauncher.getResources(), mDeviceProfile,
- windowTargetBounds, bounds, v, dragLayerBounds);
+ windowTargetBounds, launcherIconBounds, v, dragLayerBounds[0], dragLayerBounds[1]);
+ int left = (int) (prop.cropCenterXStart - prop.cropWidthStart / 2);
+ int top = (int) (prop.cropCenterYStart - prop.cropHeightStart / 2);
+ int right = (int) (left + prop.cropWidthStart);
+ int bottom = (int) (top + prop.cropHeightStart);
+ // Set the crop here so we can calculate the corner radius below.
+ crop.set(left, top, right, bottom);
RectF targetBounds = new RectF(windowTargetBounds);
- RectF iconBounds = new RectF();
- RectF temp = new RectF();
+ RectF floatingIconBounds = new RectF();
+ RectF tmpRectF = new RectF();
Point tmpPos = new Point();
AnimatorSet animatorSet = new AnimatorSet();
@@ -481,68 +491,79 @@
});
final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources())
- ? prop.startCrop / 2f : 0f;
+ ? Math.max(crop.width(), crop.height()) / 2f
+ : 0f;
final float finalWindowRadius = mDeviceProfile.isMultiWindowMode
? 0 : getWindowCornerRadius(mLauncher.getResources());
appAnimator.addUpdateListener(new MultiValueUpdateListener() {
FloatProp mDx = new FloatProp(0, prop.dX, 0, prop.xDuration, AGGRESSIVE_EASE);
FloatProp mDy = new FloatProp(0, prop.dY, 0, prop.yDuration, AGGRESSIVE_EASE);
- FloatProp mScale = new FloatProp(prop.initialAppIconScale,
+
+ FloatProp mIconScaleToFitScreen = new FloatProp(prop.initialAppIconScale,
prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE);
FloatProp mIconAlpha = new FloatProp(prop.iconAlphaStart, 0f,
APP_LAUNCH_ALPHA_START_DELAY, prop.alphaDuration, LINEAR);
- FloatProp mCroppedSize = new FloatProp(prop.startCrop, prop.endCrop, 0, CROP_DURATION,
- EXAGGERATED_EASE);
+
FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius, 0,
RADIUS_DURATION, EXAGGERATED_EASE);
FloatProp mShadowRadius = new FloatProp(0, mMaxShadowRadius, 0,
APP_LAUNCH_DURATION, EXAGGERATED_EASE);
+ FloatProp mCropRectCenterX = new FloatProp(prop.cropCenterXStart, prop.cropCenterXEnd,
+ 0, CROP_DURATION, EXAGGERATED_EASE);
+ FloatProp mCropRectCenterY = new FloatProp(prop.cropCenterYStart, prop.cropCenterYEnd,
+ 0, CROP_DURATION, EXAGGERATED_EASE);
+ FloatProp mCropRectWidth = new FloatProp(prop.cropWidthStart, prop.cropWidthEnd, 0,
+ CROP_DURATION, EXAGGERATED_EASE);
+ FloatProp mCropRectHeight = new FloatProp(prop.cropHeightStart, prop.cropHeightEnd, 0,
+ CROP_DURATION, EXAGGERATED_EASE);
+
@Override
public void onUpdate(float percent) {
// Calculate the size of the scaled icon.
- float width = bounds.width() * mScale.value;
- float height = bounds.height() * mScale.value;
+ float iconWidth = launcherIconBounds.width() * mIconScaleToFitScreen.value;
+ float iconHeight = launcherIconBounds.height() * mIconScaleToFitScreen.value;
- // Animate the crop so that it starts off as a square.
- final int cropWidth;
- final int cropHeight;
- if (mDeviceProfile.isVerticalBarLayout()) {
- cropWidth = (int) mCroppedSize.value;
- cropHeight = windowTargetBounds.height();
- } else {
- cropWidth = windowTargetBounds.width();
- cropHeight = (int) mCroppedSize.value;
- }
- crop.set(0, 0, cropWidth, cropHeight);
+ int left = (int) (mCropRectCenterX.value - mCropRectWidth.value / 2);
+ int top = (int) (mCropRectCenterY.value - mCropRectHeight.value / 2);
+ int right = (int) (left + mCropRectWidth.value);
+ int bottom = (int) (top + mCropRectHeight.value);
+ crop.set(left, top, right, bottom);
+
+ final int windowCropWidth = crop.width();
+ final int windowCropHeight = crop.height();
// Scale the size of the icon to match the size of the window crop.
- float scaleX = width / cropWidth;
- float scaleY = height / cropHeight;
+ float scaleX = iconWidth / windowCropWidth;
+ float scaleY = iconHeight / windowCropHeight;
float scale = Math.min(1f, Math.max(scaleX, scaleY));
- float scaledCropWidth = cropWidth * scale;
- float scaledCropHeight = cropHeight * scale;
- float offsetX = (scaledCropWidth - width) / 2;
- float offsetY = (scaledCropHeight - height) / 2;
+ float scaledCropWidth = windowCropWidth * scale;
+ float scaledCropHeight = windowCropHeight * scale;
+ float offsetX = (scaledCropWidth - iconWidth) / 2;
+ float offsetY = (scaledCropHeight - iconHeight) / 2;
// Calculate the window position to match the icon position.
- temp.set(bounds);
- temp.offset(dragLayerBounds[0], dragLayerBounds[1]);
- temp.offset(mDx.value, mDy.value);
- Utilities.scaleRectFAboutCenter(temp, mScale.value);
- float windowTransX0 = temp.left - offsetX;
- float windowTransY0 = temp.top - offsetY;
+ tmpRectF.set(launcherIconBounds);
+ tmpRectF.offset(dragLayerBounds[0], dragLayerBounds[1]);
+ tmpRectF.offset(mDx.value, mDy.value);
+ Utilities.scaleRectFAboutCenter(tmpRectF, mIconScaleToFitScreen.value);
+ float windowTransX0 = tmpRectF.left - offsetX;
+ float windowTransY0 = tmpRectF.top - offsetY;
+ if (ENABLE_SHELL_STARTING_SURFACE) {
+ windowTransX0 -= crop.left * scale;
+ windowTransY0 -= crop.top * scale;
+ }
// Calculate the icon position.
- iconBounds.set(bounds);
- iconBounds.offset(mDx.value, mDy.value);
- Utilities.scaleRectFAboutCenter(iconBounds, mScale.value);
- iconBounds.left -= offsetX;
- iconBounds.top -= offsetY;
- iconBounds.right += offsetX;
- iconBounds.bottom += offsetY;
+ floatingIconBounds.set(launcherIconBounds);
+ floatingIconBounds.offset(mDx.value, mDy.value);
+ Utilities.scaleRectFAboutCenter(floatingIconBounds, mIconScaleToFitScreen.value);
+ floatingIconBounds.left -= offsetX;
+ floatingIconBounds.top -= offsetY;
+ floatingIconBounds.right += offsetX;
+ floatingIconBounds.bottom += offsetY;
SurfaceParams[] params = new SurfaceParams[appTargets.length];
for (int i = appTargets.length - 1; i >= 0; i--) {
@@ -553,7 +574,7 @@
matrix.setScale(scale, scale);
matrix.postTranslate(windowTransX0, windowTransY0);
- floatingView.update(iconBounds, mIconAlpha.value, percent, 0f,
+ floatingView.update(floatingIconBounds, mIconAlpha.value, percent, 0f,
mWindowRadius.value * scale, true /* isOpening */);
builder.withMatrix(matrix)
.withWindowCrop(crop)
@@ -932,8 +953,15 @@
*/
static class AnimOpenProperties {
- public final float startCrop;
- public final float endCrop;
+ public final int cropCenterXStart;
+ public final int cropCenterYStart;
+ public final int cropWidthStart;
+ public final int cropHeightStart;
+
+ public final int cropCenterXEnd;
+ public final int cropCenterYEnd;
+ public final int cropWidthEnd;
+ public final int cropHeightEnd;
public final float dX;
public final float dY;
@@ -948,7 +976,7 @@
public final float iconAlphaStart;
AnimOpenProperties(Resources r, DeviceProfile dp, Rect windowTargetBounds,
- RectF launcherIconBounds, View view, int[] dragLayerBounds) {
+ RectF launcherIconBounds, View view, int dragLayerLeft, int dragLayerTop) {
// Scale the app icon to take up the entire screen. This simplifies the math when
// animating the app window position / scale.
float smallestSize = Math.min(windowTargetBounds.height(), windowTargetBounds.width());
@@ -966,8 +994,8 @@
finalAppIconScale = Math.max(maxScaleX, maxScaleY);
// Animate the app icon to the center of the window bounds in screen coordinates.
- float centerX = windowTargetBounds.centerX() - dragLayerBounds[0];
- float centerY = windowTargetBounds.centerY() - dragLayerBounds[1];
+ float centerX = windowTargetBounds.centerX() - dragLayerLeft;
+ float centerY = windowTargetBounds.centerY() - dragLayerTop;
dX = centerX - launcherIconBounds.centerX();
dY = centerY - launcherIconBounds.centerY();
@@ -981,15 +1009,31 @@
alphaDuration = useUpwardAnimation ? APP_LAUNCH_ALPHA_DURATION
: APP_LAUNCH_ALPHA_DOWN_DURATION;
- if (dp.isVerticalBarLayout()) {
- startCrop = windowTargetBounds.height();
- endCrop = windowTargetBounds.width();
+ if (ENABLE_SHELL_STARTING_SURFACE) {
+ iconAlphaStart = 0;
+
+ // TOOD: Share value from shell when available.
+ final float windowIconSize = Utilities.pxFromSp(108, r.getDisplayMetrics());
+
+ cropCenterXStart = windowTargetBounds.centerX();
+ cropCenterYStart = windowTargetBounds.centerY();
+
+ cropWidthStart = (int) windowIconSize;
+ cropHeightStart = (int) windowIconSize;
} else {
- startCrop = windowTargetBounds.width();
- endCrop = windowTargetBounds.height();
+ iconAlphaStart = 1;
+
+ cropWidthStart = cropHeightStart =
+ Math.min(windowTargetBounds.width(), windowTargetBounds.height());
+ cropCenterXStart = cropCenterYStart =
+ Math.min(windowTargetBounds.centerX(), windowTargetBounds.centerY());
}
- iconAlphaStart = 1f;
+ cropWidthEnd = windowTargetBounds.width();
+ cropHeightEnd = windowTargetBounds.height();
+
+ cropCenterXEnd = windowTargetBounds.centerX();
+ cropCenterYEnd = windowTargetBounds.centerY();
}
}
}