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

Commit 3d92c138 authored by Miranda Kephart's avatar Miranda Kephart Committed by Android (Google) Code Review
Browse files

Merge "Allow path specification for rounded corners" into qt-r1-dev

parents dc20f9ae 5393915d
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -480,4 +480,10 @@
    <!-- ThemePicker package name for overlaying icons. -->
    <string name="themepicker_overlayable_package" translatable="false">com.android.wallpaper</string>

    <!-- Default rounded corner curve (a Bezier). Must match (the curved path in) rounded.xml.
         Note that while rounded.xml includes the entire path (including the horizontal and vertical
         corner edges), this pulls out just the curve.
     -->
    <string name="config_rounded_mask" translatable="false">"M8,0C3.6,0,0,3.6,0,8"</string>

</resources>
+6 −6
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.assist.ui;

import android.content.Context;
import android.graphics.Path;

/**
@@ -29,12 +30,11 @@ public final class CircularCornerPathRenderer extends CornerPathRenderer {
    private final int mWidth;
    private final Path mPath = new Path();

    public CircularCornerPathRenderer(int cornerRadiusBottom, int cornerRadiusTop,
            int width, int height) {
        mCornerRadiusBottom = cornerRadiusBottom;
        mCornerRadiusTop = cornerRadiusTop;
        mHeight = height;
        mWidth = width;
    public CircularCornerPathRenderer(Context context) {
        mCornerRadiusBottom = DisplayUtils.getCornerRadiusBottom(context);
        mCornerRadiusTop = DisplayUtils.getCornerRadiusTop(context);
        mHeight = DisplayUtils.getHeight(context);
        mWidth = DisplayUtils.getWidth(context);
    }

    @Override // CornerPathRenderer
+2 −6
Original line number Diff line number Diff line
@@ -247,13 +247,9 @@ public class InvocationLightsView extends View
     * To render corners that aren't circular, override this method in a subclass.
     */
    protected CornerPathRenderer createCornerPathRenderer(Context context) {
        int displayWidth = DisplayUtils.getWidth(context);
        int displayHeight = DisplayUtils.getHeight(context);
        int cornerRadiusBottom = DisplayUtils.getCornerRadiusBottom(context);
        int cornerRadiusTop = DisplayUtils.getCornerRadiusTop(context);
        return new CircularCornerPathRenderer(
                cornerRadiusBottom, cornerRadiusTop, displayWidth, displayHeight);
        return new CircularCornerPathRenderer(context);
    }

    /**
     * Receives an intensity from 0 (lightest) to 1 (darkest) and sets the handle color
     * appropriately. Intention is to match the home handle color.
+124 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.
 */

package com.android.systemui.assist.ui;

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.Log;
import android.util.PathParser;

import com.android.systemui.R;

/**
 * Parses a path describing rounded corners from a string.
 */
public final class PathSpecCornerPathRenderer extends CornerPathRenderer {
    private static final String TAG = "PathSpecCornerPathRenderer";

    private final int mHeight;
    private final int mWidth;
    private final float mPathScale;
    private final int mBottomCornerRadius;
    private final int mTopCornerRadius;

    private final Path mPath = new Path();
    private final Path mRoundedPath;
    private final Matrix mMatrix = new Matrix();

    public PathSpecCornerPathRenderer(Context context) {
        mWidth = DisplayUtils.getWidth(context);
        mHeight = DisplayUtils.getHeight(context);

        mBottomCornerRadius = DisplayUtils.getCornerRadiusBottom(context);
        mTopCornerRadius = DisplayUtils.getCornerRadiusTop(context);

        String pathData = context.getResources().getString(R.string.config_rounded_mask);
        Path path = PathParser.createPathFromPathData(pathData);
        if (path == null) {
            Log.e(TAG, "No rounded corner path found!");
            mRoundedPath = new Path();
        } else {
            mRoundedPath = path;

        }

        RectF bounds = new RectF();
        mRoundedPath.computeBounds(bounds, true);

        // we use this to scale the path such that the larger of its [width, height] is scaled to
        // the corner radius (to account for asymmetric paths)
        mPathScale = Math.min(
                Math.abs(bounds.right - bounds.left),
                Math.abs(bounds.top - bounds.bottom));
    }

    /**
     * Scales and rotates each corner from the path specification to its correct position.
     *
     * Note: the rounded corners are passed in as the full shape (a curved triangle), but we only
     * want the actual corner curve. Therefore we call getSegment to jump past the horizontal and
     * vertical lines.
     */
    @Override
    public Path getCornerPath(Corner corner) {
        if (mRoundedPath.isEmpty()) {
            return mRoundedPath;
        }
        int cornerRadius;
        int rotateDegrees;
        int translateX;
        int translateY;
        switch (corner) {
            case TOP_LEFT:
                cornerRadius = mTopCornerRadius;
                rotateDegrees = 0;
                translateX = 0;
                translateY = 0;
                break;
            case TOP_RIGHT:
                cornerRadius = mTopCornerRadius;
                rotateDegrees = 90;
                translateX = mWidth;
                translateY = 0;
                break;
            case BOTTOM_RIGHT:
                cornerRadius = mBottomCornerRadius;
                rotateDegrees = 180;
                translateX = mWidth;
                translateY = mHeight;
                break;
            case BOTTOM_LEFT:
            default:
                cornerRadius = mBottomCornerRadius;
                rotateDegrees = 270;
                translateX = 0;
                translateY = mHeight;
                break;
        }
        mPath.reset();
        mMatrix.reset();
        mPath.addPath(mRoundedPath);

        mMatrix.preScale(cornerRadius / mPathScale, cornerRadius / mPathScale);
        mMatrix.postRotate(rotateDegrees);
        mMatrix.postTranslate(translateX, translateY);
        mPath.transform(mMatrix);
        return mPath;
    }
}
+9 −9
Original line number Diff line number Diff line
@@ -229,14 +229,14 @@ public class PerimeterPathGuide {
                    - mDeviceWidthPx) / 2, (mDeviceWidthPx - mDeviceHeightPx) / 2);
        }

        CircularCornerPathRenderer.Corner screenBottomLeft = getRotatedCorner(
                CircularCornerPathRenderer.Corner.BOTTOM_LEFT);
        CircularCornerPathRenderer.Corner screenBottomRight = getRotatedCorner(
                CircularCornerPathRenderer.Corner.BOTTOM_RIGHT);
        CircularCornerPathRenderer.Corner screenTopLeft = getRotatedCorner(
                CircularCornerPathRenderer.Corner.TOP_LEFT);
        CircularCornerPathRenderer.Corner screenTopRight = getRotatedCorner(
                CircularCornerPathRenderer.Corner.TOP_RIGHT);
        CornerPathRenderer.Corner screenBottomLeft = getRotatedCorner(
                CornerPathRenderer.Corner.BOTTOM_LEFT);
        CornerPathRenderer.Corner screenBottomRight = getRotatedCorner(
                CornerPathRenderer.Corner.BOTTOM_RIGHT);
        CornerPathRenderer.Corner screenTopLeft = getRotatedCorner(
                CornerPathRenderer.Corner.TOP_LEFT);
        CornerPathRenderer.Corner screenTopRight = getRotatedCorner(
                CornerPathRenderer.Corner.TOP_RIGHT);

        mRegions[Region.BOTTOM_LEFT.ordinal()].path =
                mCornerPathRenderer.getInsetPath(screenBottomLeft, mEdgeInset);