Merge "Overview - add the ability to color scrim task views." into sc-dev
This commit is contained in:
@@ -30,6 +30,7 @@ import android.content.Intent;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.LauncherApps.AppUsageLimit;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Paint;
|
||||
import android.icu.text.MeasureFormat;
|
||||
import android.icu.text.MeasureFormat.FormatWidth;
|
||||
import android.icu.util.Measure;
|
||||
@@ -48,6 +49,7 @@ import androidx.annotation.StringRes;
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
|
||||
import java.time.Duration;
|
||||
@@ -297,4 +299,17 @@ public final class DigitalWellBeingToast {
|
||||
mBanner.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
void setBannerColorTint(int color, float amount) {
|
||||
if (mBanner == null) {
|
||||
return;
|
||||
}
|
||||
if (mBannerAlpha == 0 || amount == 0) {
|
||||
mBanner.setLayerType(View.LAYER_TYPE_NONE, null);
|
||||
}
|
||||
Paint layerPaint = new Paint();
|
||||
layerPaint.setColorFilter(Utilities.makeColorTintingColorFilter(color, amount));
|
||||
mBanner.setLayerType(View.LAYER_TYPE_HARDWARE, layerPaint);
|
||||
mBanner.setLayerPaint(layerPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
|
||||
/**
|
||||
* A view which draws a drawable stretched to fit its size. Unlike ImageView, it avoids relayout
|
||||
* when the drawable changes.
|
||||
@@ -102,4 +104,16 @@ public class IconView extends View {
|
||||
setVisibility(INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tint color of the icon, useful for scrimming or dimming.
|
||||
*
|
||||
* @param color to blend in.
|
||||
* @param amount [0,1] 0 no tint, 1 full tint
|
||||
*/
|
||||
public void setIconColorTint(int color, float amount) {
|
||||
if (mDrawable != null) {
|
||||
mDrawable.setColorFilter(Utilities.makeColorTintingColorFilter(color, amount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3309,6 +3309,16 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
return mSizeStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all the task views to color tint scrim mode, dimming or tinting them all. Allows the
|
||||
* tasks to be dimmed while other elements in the recents view are left alone.
|
||||
*/
|
||||
public void showForegroundScrim(boolean show) {
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
getTaskViewAt(i).showColorTint(show);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean showAsGrid() {
|
||||
return mOverviewGridEnabled || (mCurrentGestureEndTarget != null
|
||||
&& mSizeStrategy.stateFromGestureEndTarget(
|
||||
|
||||
@@ -249,9 +249,11 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
final Animator revealAnimator = createOpenCloseOutlineProvider()
|
||||
.createRevealAnimator(this, closing);
|
||||
revealAnimator.setInterpolator(Interpolators.DEACCEL);
|
||||
mOpenCloseAnimator.play(revealAnimator);
|
||||
mOpenCloseAnimator.play(ObjectAnimator.ofFloat(mTaskView.getThumbnail(), DIM_ALPHA,
|
||||
closing ? 0 : TaskView.MAX_PAGE_SCRIM_ALPHA));
|
||||
mOpenCloseAnimator.playTogether(revealAnimator,
|
||||
ObjectAnimator.ofFloat(
|
||||
mTaskView.getThumbnail(), DIM_ALPHA,
|
||||
closing ? 0 : TaskView.MAX_PAGE_SCRIM_ALPHA),
|
||||
ObjectAnimator.ofFloat(this, ALPHA, closing ? 0 : 1));
|
||||
mOpenCloseAnimator.addListener(new AnimationSuccessListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
@@ -265,7 +267,6 @@ public class TaskMenuView extends AbstractFloatingView {
|
||||
}
|
||||
}
|
||||
});
|
||||
mOpenCloseAnimator.play(ObjectAnimator.ofFloat(this, ALPHA, closing ? 0 : 1));
|
||||
mOpenCloseAnimator.setDuration(closing ? REVEAL_CLOSE_DURATION: REVEAL_OPEN_DURATION);
|
||||
mOpenCloseAnimator.start();
|
||||
}
|
||||
|
||||
@@ -28,8 +28,6 @@ import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.ColorMatrix;
|
||||
import android.graphics.ColorMatrixColorFilter;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
@@ -46,10 +44,10 @@ import android.view.Surface;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
||||
@@ -67,10 +65,6 @@ import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
* A task in the Recents view.
|
||||
*/
|
||||
public class TaskThumbnailView extends View implements PluginListener<OverviewScreenshotActions> {
|
||||
|
||||
private static final ColorMatrix COLOR_MATRIX = new ColorMatrix();
|
||||
private static final ColorMatrix SATURATION_COLOR_MATRIX = new ColorMatrix();
|
||||
|
||||
private static final MainThreadInitializedObject<FullscreenDrawParams> TEMP_PARAMS =
|
||||
new MainThreadInitializedObject<>(FullscreenDrawParams::new);
|
||||
|
||||
@@ -89,11 +83,11 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
|
||||
private final BaseActivity mActivity;
|
||||
private TaskOverlay mOverlay;
|
||||
private final boolean mIsDarkTextTheme;
|
||||
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint mClearPaint = new Paint();
|
||||
private final Paint mDimmingPaintAfterClearing = new Paint();
|
||||
private final int mDimColor;
|
||||
|
||||
// Contains the portion of the thumbnail that is clipped when fullscreen progress = 0.
|
||||
private final Rect mPreviewRect = new Rect();
|
||||
@@ -104,9 +98,8 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
private ThumbnailData mThumbnailData;
|
||||
protected BitmapShader mBitmapShader;
|
||||
|
||||
private float mDimAlpha = 1f;
|
||||
private float mDimAlphaMultiplier = 1f;
|
||||
private float mSaturation = 1f;
|
||||
/** How much this thumbnail is dimmed, 0 not dimmed at all, 1 totally dimmed. */
|
||||
private float mDimAlpha = 0f;
|
||||
|
||||
private boolean mOverlayEnabled;
|
||||
private OverviewScreenshotActions mOverviewScreenshotActionsPlugin;
|
||||
@@ -124,11 +117,12 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
mPaint.setFilterBitmap(true);
|
||||
mBackgroundPaint.setColor(Color.WHITE);
|
||||
mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
|
||||
mDimmingPaintAfterClearing.setColor(Color.BLACK);
|
||||
mActivity = BaseActivity.fromContext(context);
|
||||
mIsDarkTextTheme = Themes.getAttrBoolean(mActivity, R.attr.isWorkspaceDarkText);
|
||||
// Initialize with placeholder value. It is overridden later by TaskView
|
||||
mFullscreenParams = TEMP_PARAMS.get(context);
|
||||
|
||||
mDimColor = Themes.getColorBackgroundFloating(context);
|
||||
mDimmingPaintAfterClearing.setColor(mDimColor);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,15 +180,12 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
updateThumbnailPaintFilter();
|
||||
}
|
||||
|
||||
public void setDimAlphaMultipler(float dimAlphaMultipler) {
|
||||
mDimAlphaMultiplier = dimAlphaMultipler;
|
||||
setDimAlpha(mDimAlpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the alpha of the dim layer on top of this view.
|
||||
* <p>
|
||||
* If dimAlpha is 0, no dimming is applied; if dimAlpha is 1, the thumbnail will be black.
|
||||
* If dimAlpha is 0, no dimming is applied; if dimAlpha is 1, the thumbnail will be the
|
||||
* extracted background color.
|
||||
*
|
||||
*/
|
||||
public void setDimAlpha(float dimAlpha) {
|
||||
mDimAlpha = dimAlpha;
|
||||
@@ -359,15 +350,15 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
}
|
||||
|
||||
private void updateThumbnailPaintFilter() {
|
||||
int mul = (int) ((1 - mDimAlpha * mDimAlphaMultiplier) * 255);
|
||||
ColorFilter filter = getColorFilter(mul, mIsDarkTextTheme, mSaturation);
|
||||
ColorFilter filter = getColorFilter(mDimAlpha);
|
||||
mBackgroundPaint.setColorFilter(filter);
|
||||
mDimmingPaintAfterClearing.setAlpha(255 - mul);
|
||||
int alpha = (int) (mDimAlpha * 255);
|
||||
mDimmingPaintAfterClearing.setAlpha(alpha);
|
||||
if (mBitmapShader != null) {
|
||||
mPaint.setColorFilter(filter);
|
||||
} else {
|
||||
mPaint.setColorFilter(null);
|
||||
mPaint.setColor(Color.argb(255, mul, mul, mul));
|
||||
mPaint.setColor(ColorUtils.blendARGB(Color.BLACK, mDimColor, alpha));
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
@@ -401,35 +392,8 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
|
||||
updateThumbnailMatrix();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param intensity multiplier for color values. 0 - make black (white if shouldLighten), 255 -
|
||||
* leave unchanged.
|
||||
*/
|
||||
private static ColorFilter getColorFilter(int intensity, boolean shouldLighten,
|
||||
float saturation) {
|
||||
intensity = Utilities.boundToRange(intensity, 0, 255);
|
||||
|
||||
if (intensity == 255 && saturation == 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final float intensityScale = intensity / 255f;
|
||||
COLOR_MATRIX.setScale(intensityScale, intensityScale, intensityScale, 1);
|
||||
|
||||
if (saturation != 1) {
|
||||
SATURATION_COLOR_MATRIX.setSaturation(saturation);
|
||||
COLOR_MATRIX.postConcat(SATURATION_COLOR_MATRIX);
|
||||
}
|
||||
|
||||
if (shouldLighten) {
|
||||
final float[] colorArray = COLOR_MATRIX.getArray();
|
||||
final int colorAdd = 255 - intensity;
|
||||
colorArray[4] = colorAdd;
|
||||
colorArray[9] = colorAdd;
|
||||
colorArray[14] = colorAdd;
|
||||
}
|
||||
|
||||
return new ColorMatrixColorFilter(COLOR_MATRIX);
|
||||
private ColorFilter getColorFilter(float dimAmount) {
|
||||
return Utilities.makeColorTintingColorFilter(mDimColor, dimAmount);
|
||||
}
|
||||
|
||||
public Bitmap getThumbnail() {
|
||||
|
||||
@@ -89,6 +89,7 @@ import com.android.launcher3.util.ActivityOptionsWrapper;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.RunnableList;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.util.TransformingTouchDelegate;
|
||||
import com.android.launcher3.util.ViewPool.Reusable;
|
||||
import com.android.quickstep.RecentsModel;
|
||||
@@ -134,10 +135,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
@IntDef({FLAG_UPDATE_ALL, FLAG_UPDATE_ICON, FLAG_UPDATE_THUMBNAIL})
|
||||
public @interface TaskDataChanges {}
|
||||
|
||||
/**
|
||||
* The alpha of a black scrim on a page in the carousel as it leaves the screen.
|
||||
* In the resting position of the carousel, the adjacent pages have about half this scrim.
|
||||
*/
|
||||
/** The maximum amount that a task view can be scrimmed, dimmed or tinted. */
|
||||
public static final float MAX_PAGE_SCRIM_ALPHA = 0.4f;
|
||||
|
||||
/**
|
||||
@@ -254,6 +252,19 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
}
|
||||
};
|
||||
|
||||
private static final FloatProperty<TaskView> COLOR_TINT =
|
||||
new FloatProperty<TaskView>("colorTint") {
|
||||
@Override
|
||||
public void setValue(TaskView taskView, float v) {
|
||||
taskView.setColorTint(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(TaskView taskView) {
|
||||
return taskView.getColorTint();
|
||||
}
|
||||
};
|
||||
|
||||
private final OnAttachStateChangeListener mTaskMenuStateListener =
|
||||
new OnAttachStateChangeListener() {
|
||||
@Override
|
||||
@@ -314,6 +325,11 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
private final float[] mIconCenterCoords = new float[2];
|
||||
private final float[] mChipCenterCoords = new float[2];
|
||||
|
||||
// Colored tint for the task view and all its supplementary views (like the task icon and well
|
||||
// being banner.
|
||||
private final int mTintingColor;
|
||||
private float mTintAmount;
|
||||
|
||||
private boolean mIsClickableAsLiveTile = true;
|
||||
|
||||
public TaskView(Context context) {
|
||||
@@ -375,6 +391,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
mOutlineProvider = new TaskOutlineProvider(getContext(), mCurrentFullscreenParams,
|
||||
mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx);
|
||||
setOutlineProvider(mOutlineProvider);
|
||||
|
||||
mTintingColor = Themes.getColorBackgroundFloating(context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -722,7 +740,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
progress = 1 - progress;
|
||||
}
|
||||
mFocusTransitionProgress = progress;
|
||||
mSnapshotView.setDimAlphaMultipler(0);
|
||||
float iconScalePercentage = (float) SCALE_ICON_DURATION / DIM_ANIM_DURATION;
|
||||
float lowerClamp = invert ? 1f - iconScalePercentage : 0;
|
||||
float upperClamp = invert ? 1 : iconScalePercentage;
|
||||
@@ -781,6 +798,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
setTranslationZ(0);
|
||||
setAlpha(mStableAlpha);
|
||||
setIconScaleAndDim(1);
|
||||
setColorTint(0);
|
||||
}
|
||||
|
||||
public void setStableAlpha(float parentAlpha) {
|
||||
@@ -1324,6 +1342,26 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||
rv.initiateSplitSelect(this, splitPositionOption);
|
||||
}
|
||||
|
||||
private void setColorTint(float amount) {
|
||||
mSnapshotView.setDimAlpha(amount);
|
||||
mIconView.setIconColorTint(mTintingColor, amount);
|
||||
mDigitalWellBeingToast.setBannerColorTint(mTintingColor, amount);
|
||||
}
|
||||
|
||||
private float getColorTint() {
|
||||
return mTintAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the task view with a color tint (animates value).
|
||||
*/
|
||||
public void showColorTint(boolean enable) {
|
||||
ObjectAnimator tintAnimator = ObjectAnimator.ofFloat(
|
||||
this, COLOR_TINT, enable ? MAX_PAGE_SCRIM_ALPHA : 0);
|
||||
tintAnimator.setAutoCancel(true);
|
||||
tintAnimator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* We update and subsequently draw these in {@link #setFullscreenProgress(float)}.
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,8 @@ import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.LightingColorFilter;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Point;
|
||||
@@ -64,6 +66,7 @@ import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.core.os.BuildCompat;
|
||||
|
||||
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
|
||||
@@ -732,6 +735,23 @@ public final class Utilities {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a color filter that blends a color into the destination based on a scalable amout.
|
||||
*
|
||||
* @param color to blend in.
|
||||
* @param tintAmount [0-1] 0 no tinting, 1 full color.
|
||||
* @return ColorFilter for tinting, or {@code null} if no filter is needed.
|
||||
*/
|
||||
public static ColorFilter makeColorTintingColorFilter(int color, float tintAmount) {
|
||||
if (tintAmount == 0f) {
|
||||
return null;
|
||||
}
|
||||
return new LightingColorFilter(
|
||||
// This isn't blending in white, its making a multiplication mask for the base color
|
||||
ColorUtils.blendARGB(Color.WHITE, 0, tintAmount),
|
||||
ColorUtils.blendARGB(0, color, tintAmount));
|
||||
}
|
||||
|
||||
private static class FixedSizeEmptyDrawable extends ColorDrawable {
|
||||
|
||||
private final int mSize;
|
||||
|
||||
Reference in New Issue
Block a user