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

Commit 927447e7 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Chaniging all-apps scrim

> Converting the scrim to View, to better avoid overdraw
> Overview and Spring loaded state have different scrim alpha
> When going from overview to all-apps, there is a color scrim drawn over the overview panel.
  The slef color is merged with this color to prevent overdraw, and the remaining screen is drawn
  with a cut-out round rect path

Bug: 79111591
Change-Id: I26801fde13dd6adb4b06110bbe8087e35cc31847
parent 729020d1
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<com.android.quickstep.views.ShelfScrimView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/scrim_view" />
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 */
public class AllAppsState extends LauncherState {

    private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY | FLAG_ALL_APPS_SCRIM;
    private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY;

    private static final PageAlphaProvider PAGE_ALPHA_PROVIDER = new PageAlphaProvider(DEACCEL_2) {
        @Override
+2 −3
Original line number Diff line number Diff line
@@ -24,9 +24,8 @@ import com.android.quickstep.views.RecentsView;
 */
public class FastOverviewState extends OverviewState {

    private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_DISABLE_RESTORE
            | FLAG_DISABLE_INTERACTION | FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON
            | FLAG_DISABLE_ACCESSIBILITY;
    private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_DISABLE_INTERACTION
            | FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON | FLAG_DISABLE_ACCESSIBILITY;

    public FastOverviewState(int id) {
        super(id, QuickScrubController.QUICK_SCRUB_START_DURATION, STATE_FLAGS);
+6 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ import com.android.quickstep.views.RecentsView;
 */
public class OverviewState extends LauncherState {

    private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
    private static final int STATE_FLAGS = FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
            | FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY;

    public OverviewState(int id) {
@@ -100,6 +100,11 @@ public class OverviewState extends LauncherState {
        }
    }

    @Override
    public float getWorkspaceScrimAlpha(Launcher launcher) {
        return 0.5f;
    }

    @Override
    public float getVerticalProgress(Launcher launcher) {
        if ((getVisibleElements(launcher) & ALL_APPS_HEADER_EXTRA) == 0) {
+196 −0
Original line number Diff line number Diff line
@@ -13,104 +13,92 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.quickstep.views;

package com.android.launcher3.uioverrides;
import static android.support.v4.graphics.ColorUtils.compositeColors;
import static android.support.v4.graphics.ColorUtils.setAlphaComponent;

import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.v4.graphics.ColorUtils;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Path.Op;
import android.util.AttributeSet;

import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.graphics.ViewScrim;
import com.android.launcher3.uioverrides.OverviewState;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ScrimView;

/**
 * Scrim used for all-apps and shelf in Overview
 * In transposed layout, it behaves as a simple color scrim.
 * In portrait layout, it draws a rounded rect such that
 *    From normal state to overview state, the shelf just fades in and does not move
 *    From overview state to all-apps state the self moves up and fades in to cover the screen
 *    From overview state to all-apps state the shelf moves up and fades in to cover the screen
 */
public class AllAppsScrim extends ViewScrim<AllAppsContainerView> {
public class ShelfScrimView extends ScrimView {

    private static final int THRESHOLD_ALPHA_DARK = 102;
    private static final int THRESHOLD_ALPHA_LIGHT = 46;

    private final Launcher mLauncher;
    private final int mEndColor;

    private int mProgressColor;

    // In transposed layout, we simply draw a flat color.
    private boolean mDrawingFlatColor;

    private final Paint mVerticalPaint;
    private float mVerticalProgress;

    // For shelf mode
    private final int mEndAlpha;
    private final int mThresholdAlpha;
    private final float mRadius;
    private final float mTopPadding;
    private final float mMaxScrimAlpha;
    private final Paint mPaint;

    // Max vertical progress after which the scrim stops moving.
    private float mMoveThreshold;
    // Minimum visible size of the scrim.
    private int mMinSize;
    private float mDrawFactor = 0;

    public AllAppsScrim(AllAppsContainerView view) {
        super(view);
        mLauncher = Launcher.getLauncher(view.getContext());
        mEndColor = Themes.getAttrColor(mLauncher, R.attr.allAppsScrimColor);
        mProgressColor = mEndColor;
    private float mScrimMoveFactor = 0;
    private int mShelfColor;
    private int mRemainingScreenColor;

    private final Path mTempPath = new Path();
    private final Path mRemainingScreenPath = new Path();
    private boolean mRemainingScreenPathValid = false;

    public ShelfScrimView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mLauncher = Launcher.getLauncher(context);
        mMaxScrimAlpha = OVERVIEW.getWorkspaceScrimAlpha(mLauncher);

        mEndAlpha = Color.alpha(mEndColor);
        mEndAlpha = Color.alpha(mEndScrim);
        mThresholdAlpha = Themes.getAttrBoolean(mLauncher, R.attr.isMainColorDark)
                ? THRESHOLD_ALPHA_DARK : THRESHOLD_ALPHA_LIGHT;
        mRadius = mLauncher.getResources().getDimension(R.dimen.shelf_surface_radius);
        mTopPadding = mLauncher.getResources().getDimension(R.dimen.shelf_surface_top_padding);

        mVerticalPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mVerticalPaint.setColor(ColorUtils.setAlphaComponent(mEndColor, 255));
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        // Just assume the easiest UI for now, until we have the proper layout information.
        mDrawingFlatColor = true;
    }

    @Override
    protected void onProgressChanged() {
        mProgressColor = ColorUtils.setAlphaComponent(mEndColor,
                Math.round(DEACCEL_2.getInterpolation(mProgress) * Color.alpha(mEndColor)));
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mRemainingScreenPathValid = false;
    }

    @Override
    public void draw(Canvas canvas, int width, int height) {
        if (mDrawingFlatColor) {
            if (mProgress > 0) {
                canvas.drawColor(mProgressColor);
            }
            return;
        }

        if (mVerticalPaint.getAlpha() == 0) {
            return;
        } else if (mDrawFactor <= 0) {
            canvas.drawPaint(mVerticalPaint);
        } else {
            float top = (height - mMinSize) * mDrawFactor - mTopPadding;
            canvas.drawRoundRect(0, top - mRadius, width, height + mRadius,
                    mRadius, mRadius, mVerticalPaint);
        }
    }

    public void reInitUi() {
        DeviceProfile dp = mLauncher.getDeviceProfile();
        mDrawingFlatColor = dp.isVerticalBarLayout();
@@ -119,36 +107,90 @@ public class AllAppsScrim extends ViewScrim<AllAppsContainerView> {
            float swipeLength = OverviewState.getDefaultSwipeHeight(mLauncher);
            mMoveThreshold = 1 - swipeLength / mLauncher.getAllAppsController().getShiftRange();
            mMinSize = dp.hotseatBarSizePx + dp.getInsets().bottom;
            onVerticalProgress(mVerticalProgress);
            mRemainingScreenPathValid = false;
            updateColors();
        }
        invalidate();
    }

    public void onVerticalProgress(float progress) {
        mVerticalProgress = progress;

    @Override
    public void updateColors() {
        super.updateColors();
        if (mDrawingFlatColor) {
            return;
        }

        float drawFactor;
        int alpha;
        if (mVerticalProgress >= mMoveThreshold) {
            drawFactor = 1;
            alpha = mVerticalProgress >= 1 ? 0 : Math.round(mThresholdAlpha
                    * ACCEL_2.getInterpolation((1 - mVerticalProgress) / (1 - mMoveThreshold)));
        } else if (mVerticalProgress <= 0) {
            drawFactor = 0;
            alpha = mEndAlpha;
        if (mProgress >= mMoveThreshold) {
            mScrimMoveFactor = 1;

            if (mProgress >= 1) {
                mShelfColor = 0;
            } else {
            drawFactor = mVerticalProgress / mMoveThreshold;
            alpha = mEndAlpha - Math.round((mEndAlpha - mThresholdAlpha) * drawFactor);
                int alpha = Math.round(mThresholdAlpha * ACCEL_2.getInterpolation(
                        (1 - mProgress) / (1 - mMoveThreshold)));
                mShelfColor = setAlphaComponent(mEndScrim, alpha);
            }
        alpha = Utilities.boundToRange(alpha, 0, 255);
        if (alpha != mVerticalPaint.getAlpha() || drawFactor != mDrawFactor) {
            mVerticalPaint.setAlpha(alpha);
            mDrawFactor = drawFactor;
            invalidate();
            mRemainingScreenColor = 0;
        } else if (mProgress <= 0) {
            mScrimMoveFactor = 0;
            mShelfColor = mCurrentFlatColor;
            mRemainingScreenColor = 0;

        } else {
            mScrimMoveFactor = mProgress / mMoveThreshold;
            mRemainingScreenColor = setAlphaComponent(mScrimColor,
                    Math.round((1 - mScrimMoveFactor) * mMaxScrimAlpha * 255));

            // Merge the remainingScreenColor and shelfColor in one to avoid overdraw.
            int alpha = mEndAlpha - Math.round((mEndAlpha - mThresholdAlpha) * mScrimMoveFactor);
            mShelfColor = compositeColors(setAlphaComponent(mEndScrim, alpha),
                    mRemainingScreenColor);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mDrawingFlatColor) {
            if (mCurrentFlatColor != 0) {
                canvas.drawColor(mCurrentFlatColor);
            }
            return;
        }

        if (mShelfColor == 0) {
            return;
        } else if (mScrimMoveFactor <= 0) {
            canvas.drawColor(mShelfColor);
            return;
        }

        float minTop = getHeight() - mMinSize;
        float top = minTop * mScrimMoveFactor - mTopPadding - mRadius;

        // Draw the scrim over the remaining screen if needed.
        if (mRemainingScreenColor != 0) {
            if (!mRemainingScreenPathValid) {
                mTempPath.reset();
                // Using a arbitrary '+10' in the bottom to avoid any left-overs at the
                // corners due to rounding issues.
                mTempPath.addRoundRect(0, minTop, getWidth(), getHeight() + mRadius + 10,
                        mRadius, mRadius, Direction.CW);

                mRemainingScreenPath.reset();
                mRemainingScreenPath.addRect(0, 0, getWidth(), getHeight(), Direction.CW);
                mRemainingScreenPath.op(mTempPath, Op.DIFFERENCE);
            }

            float offset = minTop - top;
            canvas.translate(0, -offset);
            mPaint.setColor(mRemainingScreenColor);
            canvas.drawPath(mRemainingScreenPath, mPaint);
            canvas.translate(0, offset);
        }

        mPaint.setColor(mShelfColor);
        canvas.drawRoundRect(0, top, getWidth(), getHeight() + mRadius,
                mRadius, mRadius, mPaint);
    }
}
Loading