Interpolate scrim radius using display shape
So the scrim still looks right on display with more square corners. Bug: 185683835 Test: manual Change-Id: Id02a098815b71a98bc517e765e39e75ed11a6727
This commit is contained in:
@@ -47,9 +47,9 @@ public class ScrimDrawable extends Drawable {
|
||||
private ValueAnimator mColorAnimation;
|
||||
private int mMainColorTo;
|
||||
private float mCornerRadius;
|
||||
private Rect mBounds;
|
||||
private ConcaveInfo mConcaveInfo;
|
||||
private int mBottomEdgePosition;
|
||||
private boolean mCornerRadiusEnabled;
|
||||
|
||||
public ScrimDrawable() {
|
||||
mPaint = new Paint();
|
||||
@@ -134,29 +134,50 @@ public class ScrimDrawable extends Drawable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable drawable shape to have rounded corners with provided radius
|
||||
* Corner radius used by either concave or convex corners.
|
||||
*/
|
||||
public void setRoundedCorners(float radius) {
|
||||
if (radius == mCornerRadius) {
|
||||
return;
|
||||
}
|
||||
mCornerRadius = radius;
|
||||
if (mConcaveInfo != null) {
|
||||
mConcaveInfo.setCornerRadius(radius);
|
||||
updatePath();
|
||||
}
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make bottom edge concave with provided corner radius
|
||||
* If we should draw a rounded rect instead of a rect.
|
||||
*/
|
||||
public void setBottomEdgeConcave(float radius) {
|
||||
if (radius == 0) {
|
||||
// Disable clipping completely when there's no radius.
|
||||
mConcaveInfo = null;
|
||||
public void setRoundedCornersEnabled(boolean enabled) {
|
||||
if (mCornerRadiusEnabled == enabled) {
|
||||
return;
|
||||
}
|
||||
// only rounding top corners for clip out path
|
||||
float[] cornerRadii = new float[]{radius, radius, radius, radius, 0, 0, 0, 0};
|
||||
mConcaveInfo = new ConcaveInfo(radius, cornerRadii);
|
||||
mCornerRadiusEnabled = enabled;
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
/**
|
||||
* If we should draw a concave rounded rect instead of a rect.
|
||||
*/
|
||||
public void setBottomEdgeConcave(boolean enabled) {
|
||||
if (enabled && mConcaveInfo != null) {
|
||||
return;
|
||||
}
|
||||
if (!enabled) {
|
||||
mConcaveInfo = null;
|
||||
} else {
|
||||
mConcaveInfo = new ConcaveInfo();
|
||||
mConcaveInfo.setCornerRadius(mCornerRadius);
|
||||
}
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
/**
|
||||
* Location of concave edge.
|
||||
* @see #setBottomEdgeConcave(float)
|
||||
* @see #setBottomEdgeConcave(boolean)
|
||||
*/
|
||||
public void setBottomEdgePosition(int y) {
|
||||
if (mBottomEdgePosition == y) {
|
||||
@@ -176,34 +197,35 @@ public class ScrimDrawable extends Drawable {
|
||||
mPaint.setAlpha(mAlpha);
|
||||
if (mConcaveInfo != null) {
|
||||
drawConcave(canvas);
|
||||
} else {
|
||||
} else if (mCornerRadiusEnabled && mCornerRadius > 0) {
|
||||
canvas.drawRoundRect(getBounds().left, getBounds().top, getBounds().right,
|
||||
getBounds().bottom + mCornerRadius,
|
||||
/* x radius*/ mCornerRadius, /* y radius*/ mCornerRadius, mPaint);
|
||||
} else {
|
||||
canvas.drawRect(getBounds().left, getBounds().top, getBounds().right,
|
||||
getBounds().bottom, mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBoundsChange(Rect bounds) {
|
||||
updatePath();
|
||||
}
|
||||
|
||||
private void drawConcave(Canvas canvas) {
|
||||
// checking if width of clip out path needs to change
|
||||
if (mBounds == null
|
||||
|| getBounds().right != mBounds.right
|
||||
|| getBounds().left != mBounds.left) {
|
||||
mBounds = getBounds();
|
||||
updatePath();
|
||||
}
|
||||
canvas.clipOutPath(mConcaveInfo.mPath);
|
||||
canvas.drawRect(getBounds().left, getBounds().top, getBounds().right,
|
||||
mBottomEdgePosition + mConcaveInfo.mPathOverlap, mPaint);
|
||||
}
|
||||
|
||||
private void updatePath() {
|
||||
mConcaveInfo.mPath.reset();
|
||||
if (mBounds == null) {
|
||||
mBounds = getBounds();
|
||||
if (mConcaveInfo == null) {
|
||||
return;
|
||||
}
|
||||
mConcaveInfo.mPath.reset();
|
||||
float top = mBottomEdgePosition;
|
||||
float bottom = mBottomEdgePosition + mConcaveInfo.mPathOverlap;
|
||||
mConcaveInfo.mPath.addRoundRect(mBounds.left, top, mBounds.right, bottom,
|
||||
mConcaveInfo.mPath.addRoundRect(getBounds().left, top, getBounds().right, bottom,
|
||||
mConcaveInfo.mCornerRadii, Path.Direction.CW);
|
||||
}
|
||||
|
||||
@@ -213,13 +235,20 @@ public class ScrimDrawable extends Drawable {
|
||||
}
|
||||
|
||||
private static class ConcaveInfo {
|
||||
private final float mPathOverlap;
|
||||
private float mPathOverlap;
|
||||
private final float[] mCornerRadii;
|
||||
private final Path mPath = new Path();
|
||||
|
||||
ConcaveInfo(float pathOverlap, float[] cornerRadii) {
|
||||
mPathOverlap = pathOverlap;
|
||||
mCornerRadii = cornerRadii;
|
||||
ConcaveInfo() {
|
||||
mCornerRadii = new float[] {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
}
|
||||
|
||||
public void setCornerRadius(float radius) {
|
||||
mPathOverlap = radius;
|
||||
mCornerRadii[0] = radius;
|
||||
mCornerRadii[1] = radius;
|
||||
mCornerRadii[2] = radius;
|
||||
mCornerRadii[3] = radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,14 +31,12 @@ import android.os.Looper;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.DimenRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.colorextraction.ColorExtractor;
|
||||
import com.android.systemui.R;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@@ -50,9 +48,6 @@ import java.util.concurrent.Executor;
|
||||
*/
|
||||
public class ScrimView extends View {
|
||||
|
||||
@DimenRes
|
||||
private static final int CORNER_RADIUS = R.dimen.notification_scrim_corner_radius;
|
||||
|
||||
private final Object mColorLock = new Object();
|
||||
|
||||
@GuardedBy("mColorLock")
|
||||
@@ -301,13 +296,10 @@ public class ScrimView extends View {
|
||||
* Make bottom edge concave so overlap between layers is not visible for alphas between 0 and 1
|
||||
* @return height of concavity
|
||||
*/
|
||||
public float enableBottomEdgeConcave(boolean clipScrim) {
|
||||
public void enableBottomEdgeConcave(boolean clipScrim) {
|
||||
if (mDrawable instanceof ScrimDrawable) {
|
||||
float radius = clipScrim ? getResources().getDimensionPixelSize(CORNER_RADIUS) : 0;
|
||||
((ScrimDrawable) mDrawable).setBottomEdgeConcave(radius);
|
||||
return radius;
|
||||
((ScrimDrawable) mDrawable).setBottomEdgeConcave(clipScrim);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -321,12 +313,11 @@ public class ScrimView extends View {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable view to have rounded corners with radius of {@link #CORNER_RADIUS}
|
||||
* Enable view to have rounded corners.
|
||||
*/
|
||||
public void enableRoundedCorners() {
|
||||
public void enableRoundedCorners(boolean enabled) {
|
||||
if (mDrawable instanceof ScrimDrawable) {
|
||||
int radius = getResources().getDimensionPixelSize(CORNER_RADIUS);
|
||||
((ScrimDrawable) mDrawable).setRoundedCorners(radius);
|
||||
((ScrimDrawable) mDrawable).setRoundedCornersEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,4 +331,15 @@ public class ScrimView extends View {
|
||||
mDrawableBounds.set((int) left, (int) top, (int) right, (int) bottom);
|
||||
mDrawable.setBounds(mDrawableBounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Corner radius of both concave or convex corners.
|
||||
* @see #enableRoundedCorners(boolean)
|
||||
* @see #enableBottomEdgeConcave(boolean)
|
||||
*/
|
||||
public void setCornerRadius(int radius) {
|
||||
if (mDrawable instanceof ScrimDrawable) {
|
||||
((ScrimDrawable) mDrawable).setRoundedCorners(radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,12 +523,13 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
private final Rect mKeyguardStatusAreaClipBounds = new Rect();
|
||||
private int mOldLayoutDirection;
|
||||
private NotificationShelfController mNotificationShelfController;
|
||||
private int mScrimCornerRadius;
|
||||
private int mScreenCornerRadius;
|
||||
|
||||
private final QuickAccessWalletClient mQuickAccessWalletClient;
|
||||
private final Executor mUiExecutor;
|
||||
|
||||
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
|
||||
private int mScrimCornerRadius;
|
||||
private KeyguardMediaController mKeyguardMediaController;
|
||||
|
||||
private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
|
||||
@@ -807,6 +808,10 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
com.android.internal.R.dimen.status_bar_height);
|
||||
mHeadsUpInset = statusbarHeight + mResources.getDimensionPixelSize(
|
||||
R.dimen.heads_up_status_bar_padding);
|
||||
mScrimCornerRadius = mResources.getDimensionPixelSize(
|
||||
R.dimen.notification_scrim_corner_radius);
|
||||
mScreenCornerRadius = mResources.getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.rounded_corner_radius);
|
||||
}
|
||||
|
||||
private void updateViewControllers(KeyguardStatusView keyguardStatusView,
|
||||
@@ -871,8 +876,6 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
public void updateResources() {
|
||||
mSplitShadeNotificationsTopPadding =
|
||||
mResources.getDimensionPixelSize(R.dimen.notifications_top_padding_split_shade);
|
||||
mScrimCornerRadius =
|
||||
mResources.getDimensionPixelSize(R.dimen.notification_scrim_corner_radius);
|
||||
int qsWidth = mResources.getDimensionPixelSize(R.dimen.qs_panel_width);
|
||||
int panelWidth = mResources.getDimensionPixelSize(R.dimen.notification_panel_width);
|
||||
mShouldUseSplitNotificationShade =
|
||||
@@ -2058,6 +2061,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
boolean visible = qsFraction > 0 || qsPanelBottomY > 0;
|
||||
int radius = mScrimCornerRadius;
|
||||
if (visible || !mShouldUseSplitNotificationShade) {
|
||||
if (!mShouldUseSplitNotificationShade) {
|
||||
float notificationTop = mAmbientState.getStackY() - mQsNotificationTopPadding;
|
||||
@@ -2065,6 +2069,8 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
bottom = getView().getBottom();
|
||||
left = getView().getLeft();
|
||||
right = getView().getRight();
|
||||
radius = (int) MathUtils.lerp(mScreenCornerRadius, mScrimCornerRadius,
|
||||
Math.min(top / (float) mScrimCornerRadius, 1f));
|
||||
} else {
|
||||
top = Math.min(qsPanelBottomY, mSplitShadeNotificationsTopPadding);
|
||||
bottom = mNotificationStackScrollLayoutController.getHeight();
|
||||
@@ -2076,7 +2082,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
if (!mShouldUseSplitNotificationShade) {
|
||||
// Fancy clipping for quick settings
|
||||
if (mQs != null) {
|
||||
mQs.setFancyClipping(top, bottom, mScrimCornerRadius, visible);
|
||||
mQs.setFancyClipping(top, bottom, radius, visible);
|
||||
}
|
||||
// The padding on this area is large enough that we can use a cheaper clipping strategy
|
||||
mKeyguardStatusAreaClipBounds.set(left, top, right, bottom);
|
||||
@@ -2084,6 +2090,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
? mKeyguardStatusAreaClipBounds : null);
|
||||
}
|
||||
mScrimController.setNotificationsBounds(left, top, right, bottom);
|
||||
mScrimController.setScrimCornerRadius(radius);
|
||||
}
|
||||
|
||||
private int calculateQsBottomPosition(float qsExpansionFraction) {
|
||||
|
||||
@@ -269,7 +269,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
||||
updateThemeColors();
|
||||
|
||||
behindScrim.enableBottomEdgeConcave(mClipsQsScrim);
|
||||
mNotificationsScrim.enableRoundedCorners();
|
||||
mNotificationsScrim.enableRoundedCorners(true);
|
||||
|
||||
if (mScrimBehindChangeRunnable != null) {
|
||||
mScrimBehind.setChangeRunnable(mScrimBehindChangeRunnable, mMainExecutor);
|
||||
@@ -294,6 +294,17 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
||||
mKeyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets corner radius of scrims.
|
||||
*/
|
||||
public void setScrimCornerRadius(int radius) {
|
||||
if (mScrimBehind == null || mNotificationsScrim == null) {
|
||||
return;
|
||||
}
|
||||
mScrimBehind.setCornerRadius(radius);
|
||||
mNotificationsScrim.setCornerRadius(radius);
|
||||
}
|
||||
|
||||
void setScrimVisibleListener(Consumer<Integer> listener) {
|
||||
mScrimVisibleListener = listener;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user