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

Commit 400c2537 authored by Matt Casey's avatar Matt Casey Committed by android-build-merger
Browse files

Merge "Rendering fixes for assist handles." into qt-dev am: 075baa2e am: 05e8a22a

am: cc229b18

Change-Id: I4e62ac4a26528312257e3af844121b5bb5d1b2bf
parents fd799860 cc229b18
Loading
Loading
Loading
Loading
+70 −57
Original line number Original line Diff line number Diff line
@@ -20,8 +20,8 @@ import android.animation.ArgbEvaluator;
import android.content.Context;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.RectF;
import android.os.SystemProperties;
import android.util.AttributeSet;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.DisplayMetrics;
import android.view.ContextThemeWrapper;
import android.view.ContextThemeWrapper;
@@ -34,17 +34,19 @@ import com.android.settingslib.Utils;
 * corners.
 * corners.
 */
 */
public class CornerHandleView extends View {
public class CornerHandleView extends View {
    private static final boolean ALLOW_TUNING = false;
    private static final float STROKE_DP_LARGE = 2f;
    private static final int ANGLE_DEGREES = 50;
    private static final float STROKE_DP_SMALL = 1.95f;
    private static final float STROKE_DP = 2.5f;
    // Radius to use if none is available.
    // Radius to use if none is available.
    private static final int FALLBACK_RADIUS_DP = 15;
    private static final int FALLBACK_RADIUS_DP = 15;
    private static final float MARGIN_DP = 8;
    private static final int MAX_ARC_DEGREES = 90;
    // Arc length along the phone's perimeter used to measure the desired angle.
    private static final float ARC_LENGTH_DP = 31f;


    private Paint mPaint;
    private Paint mPaint;
    private int mLightColor;
    private int mLightColor;
    private int mDarkColor;
    private int mDarkColor;
    private RectF mOval;
    private Path mPath;



    public CornerHandleView(Context context, AttributeSet attrs) {
    public CornerHandleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        super(context, attrs);
@@ -55,18 +57,46 @@ public class CornerHandleView extends View {
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(getStrokePx());
        mPaint.setStrokeWidth(getStrokePx());


        final int dualToneDarkTheme = Utils.getThemeAttr(mContext,
        final int dualToneDarkTheme = Utils.getThemeAttr(mContext, R.attr.darkIconTheme);
                R.attr.darkIconTheme);
        final int dualToneLightTheme = Utils.getThemeAttr(mContext, R.attr.lightIconTheme);
        final int dualToneLightTheme = Utils.getThemeAttr(mContext,
                R.attr.lightIconTheme);
        Context lightContext = new ContextThemeWrapper(mContext, dualToneLightTheme);
        Context lightContext = new ContextThemeWrapper(mContext, dualToneLightTheme);
        Context darkContext = new ContextThemeWrapper(mContext, dualToneDarkTheme);
        Context darkContext = new ContextThemeWrapper(mContext, dualToneDarkTheme);
        mLightColor = Utils.getColorAttrDefaultColor(lightContext,
        mLightColor = Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor);
                R.attr.singleToneColor);
        mDarkColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor);
        mDarkColor = Utils.getColorAttrDefaultColor(darkContext,

                R.attr.singleToneColor);
        updatePath();

    }
        updateOval();

    private void updatePath() {
        mPath = new Path();

        float marginPx = getMarginPx();
        float radiusPx = getInnerRadiusPx();
        float halfStrokePx = getStrokePx() / 2f;
        float angle = getAngle();
        float startAngle = 180 + ((90 - angle) / 2);
        RectF circle = new RectF(marginPx + halfStrokePx,
                marginPx + halfStrokePx,
                marginPx + 2 * radiusPx - halfStrokePx,
                marginPx + 2 * radiusPx - halfStrokePx);

        if (angle >= 90f) {
            float innerCircumferenceDp = convertPixelToDp(radiusPx * 2 * (float) Math.PI,
                    mContext);
            float arcDp = innerCircumferenceDp * getAngle() / 360f;
            // Add additional "arms" to the two ends of the arc. The length computation is
            // hand-tuned.
            float lineLengthPx = convertDpToPixel((ARC_LENGTH_DP - arcDp - MARGIN_DP) / 2,
                    mContext);

            mPath.moveTo(marginPx + halfStrokePx, marginPx + radiusPx + lineLengthPx);
            mPath.lineTo(marginPx + halfStrokePx, marginPx + radiusPx);
            mPath.arcTo(circle, startAngle, angle);
            mPath.moveTo(marginPx + radiusPx, marginPx + halfStrokePx);
            mPath.lineTo(marginPx + radiusPx + lineLengthPx, marginPx + halfStrokePx);
        } else {
            mPath.arcTo(circle, startAngle, angle);
        }
    }
    }


    /**
    /**
@@ -83,50 +113,40 @@ public class CornerHandleView extends View {
    @Override
    @Override
    public void onDraw(Canvas canvas) {
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        super.onDraw(canvas);

        canvas.drawPath(mPath, mPaint);
        if (ALLOW_TUNING) {
            mPaint.setStrokeWidth(getStrokePx());
            updateOval();
        }

        canvas.drawArc(mOval, 180 + ((90 - getAngle()) / 2), getAngle(), false,
                mPaint);
    }
    }


    // TODO(b/133834204): Remove tweaking of corner handles
    private static float convertDpToPixel(float dp, Context context) {
    private static float convertDpToPixel(float dp, Context context) {
        return dp * ((float) context.getResources().getDisplayMetrics().densityDpi
        return dp * ((float) context.getResources().getDisplayMetrics().densityDpi
                / DisplayMetrics.DENSITY_DEFAULT);
                / DisplayMetrics.DENSITY_DEFAULT);
    }
    }


    private void updateOval() {
    private static float convertPixelToDp(float px, Context context) {
        mOval = new RectF(getMarginPx() - (getStrokePx() / 2.f),
        return px * DisplayMetrics.DENSITY_DEFAULT
                getMarginPx() - (getStrokePx() / 2.f),
                / ((float) context.getResources().getDisplayMetrics().densityDpi);
                getMarginPx() + (2 * (getRadiusPx()) + (getStrokePx() / 2.f)),
                getMarginPx() + 2 * getRadiusPx() + (getStrokePx() / 2.f));
    }
    }


    private int getAngle() {
    private float getAngle() {
        if (ALLOW_TUNING) {
        // Measure a length of ARC_LENGTH_DP along the *screen's* perimeter, get the angle and cap
            return SystemProperties.getInt("CORNER_HANDLE_ANGLE_DEGREES", ANGLE_DEGREES);
        // it at 90.
        } else {
        float circumferenceDp = convertPixelToDp((
            return ANGLE_DEGREES;
                getOuterRadiusPx()) * 2 * (float) Math.PI, mContext);
        float angleDeg = (ARC_LENGTH_DP / circumferenceDp) * 360;
        if (angleDeg > MAX_ARC_DEGREES) {
            angleDeg = MAX_ARC_DEGREES;
        }
        }
        return angleDeg;
    }
    }


    private int getMarginPx() {
    private float getMarginPx() {
        // Hand-derived function to map radiusPx to the margin amount.
        return convertDpToPixel(MARGIN_DP, mContext);
        // https://www.wolframalpha.com/input/?i=0.001402+*+x+%5E2%E2%88%920.08661+*+x%2B17.20+from+40+to+180
        int radius = getRadiusPx();
        int marginPx = (int) (0.001402f * radius * radius - 0.08661f * radius + 17.2f);
        if (ALLOW_TUNING) {
            return SystemProperties.getInt("CORNER_HANDLE_MARGIN_PX", marginPx);
        } else {
            return marginPx;
    }
    }

    private float getInnerRadiusPx() {
        return getOuterRadiusPx() - getMarginPx();
    }
    }


    private int getRadiusPx() {
    private float getOuterRadiusPx() {
        // Attempt to get the bottom corner radius, otherwise fall back on the generic or top
        // Attempt to get the bottom corner radius, otherwise fall back on the generic or top
        // values. If none are available, use the FALLBACK_RADIUS_DP.
        // values. If none are available, use the FALLBACK_RADIUS_DP.
        int radius = getResources().getDimensionPixelSize(
        int radius = getResources().getDimensionPixelSize(
@@ -142,19 +162,12 @@ public class CornerHandleView extends View {
        if (radius == 0) {
        if (radius == 0) {
            radius = (int) convertDpToPixel(FALLBACK_RADIUS_DP, mContext);
            radius = (int) convertDpToPixel(FALLBACK_RADIUS_DP, mContext);
        }
        }
        if (ALLOW_TUNING) {
            return SystemProperties.getInt("CORNER_HANDLE_RADIUS_PX", radius);
        } else {
        return radius;
        return radius;
    }
    }
    }


    private int getStrokePx() {
    private float getStrokePx() {
        if (ALLOW_TUNING) {
        // Use a slightly smaller stroke if we need to cover the full corner angle.
            return SystemProperties.getInt("CORNER_HANDLE_STROKE_PX",
        return convertDpToPixel((getAngle() < 90) ? STROKE_DP_LARGE : STROKE_DP_SMALL,
                    (int) convertDpToPixel(STROKE_DP, getContext()));
                getContext());
        } else {
            return (int) convertDpToPixel(STROKE_DP, getContext());
        }
    }
    }
}
}