1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.layoutlib.bridge.impl; 18 19 import android.content.Context; 20 import android.graphics.Canvas; 21 import android.graphics.Color; 22 import android.graphics.Paint; 23 import android.graphics.Path; 24 import android.util.DisplayMetrics; 25 import android.util.TypedValue; 26 import android.view.View; 27 28 class SysUiOverlay extends View { 29 private final Path mCornerPath; 30 private final Path mNotchPath; 31 private final Paint mCornerPaint; 32 private final Paint mNotchPaint; 33 private final int mNotchTopWidth; 34 35 createCornerPath(float width, float height, float r)36 private static Path createCornerPath(float width, float height, float r) { 37 Path corner = new Path(); 38 corner.moveTo(0, 0); 39 corner.lineTo(width, 0); 40 corner.cubicTo(width, 0, width /2 - r, height /2 - r, 0, height); 41 corner.close(); 42 43 return corner; 44 } 45 createNotchPath(float topWidth, float bottomWidth, float height, float r)46 private static Path createNotchPath(float topWidth, float bottomWidth, float height, float r) { 47 Path corner = new Path(); 48 corner.moveTo(0, 0); 49 float widthDiff = topWidth - bottomWidth; 50 corner.lineTo(topWidth, 0); 51 corner.lineTo(topWidth - widthDiff/2, height); 52 corner.lineTo(widthDiff/2, height); 53 corner.close(); 54 55 return corner; 56 } 57 58 dpToPx(DisplayMetrics metrics, float value)59 private static float dpToPx(DisplayMetrics metrics, float value) { 60 return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, value, metrics); 61 } 62 63 SysUiOverlay(Context context, int cornerSizeDp, int radiusDp, int topNotchWidthDp, int bottomNotchWidthDp, int notchHeightDp)64 public SysUiOverlay(Context context, int cornerSizeDp, int radiusDp, int topNotchWidthDp, int bottomNotchWidthDp, int notchHeightDp) { 65 super(context); 66 67 DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 68 69 float cornerSizePx = dpToPx(metrics, cornerSizeDp); 70 float radiusPx = dpToPx(metrics, radiusDp); 71 72 float topNotchWidthPx = dpToPx(metrics, topNotchWidthDp); 73 float bottomNotchWidthPx = dpToPx(metrics, bottomNotchWidthDp); 74 float notchHeightPx = dpToPx(metrics, notchHeightDp); 75 76 mCornerPath = createCornerPath(cornerSizePx, cornerSizePx, radiusPx); 77 mNotchPath = createNotchPath(topNotchWidthPx, bottomNotchWidthPx, notchHeightPx, 0); 78 mNotchTopWidth = topNotchWidthDp; 79 80 mCornerPaint = new Paint(); 81 mCornerPaint.setColor(Color.BLACK); 82 mCornerPaint.setStrokeWidth(0); 83 mCornerPaint.setAntiAlias(true); 84 85 mNotchPaint = new Paint(); 86 mNotchPaint.setColor(Color.BLACK); 87 mNotchPaint.setStrokeWidth(0); 88 mNotchPaint.setAntiAlias(true); 89 } 90 setCornerColor(int color)91 public void setCornerColor(int color) { 92 mCornerPaint.setColor(color); 93 } 94 setNotchColor(int color)95 public void setNotchColor(int color) { 96 mNotchPaint.setColor(color); 97 } 98 paintRoundedBorders(Canvas canvas)99 private void paintRoundedBorders(Canvas canvas) { 100 // Top left 101 canvas.drawPath(mCornerPath, mCornerPaint); 102 // Top right 103 canvas.save(); 104 canvas.translate(getWidth(), 0); 105 canvas.rotate(90); 106 canvas.drawPath(mCornerPath, mCornerPaint); 107 canvas.restore(); 108 // Bottom right 109 canvas.save(); 110 canvas.translate( getWidth(), getHeight()); 111 canvas.rotate(180); 112 canvas.drawPath(mCornerPath, mCornerPaint); 113 canvas.restore(); 114 // Bottom left 115 canvas.save(); 116 canvas.translate( 0, getHeight()); 117 canvas.rotate(270); 118 canvas.drawPath(mCornerPath, mCornerPaint); 119 canvas.restore(); 120 } 121 paintNotch(Canvas canvas)122 private void paintNotch(Canvas canvas) { 123 canvas.translate(getWidth() / 2 - mNotchTopWidth / 2, 0); 124 canvas.drawPath(mNotchPath, mNotchPaint); 125 } 126 127 @Override onDraw(Canvas canvas)128 protected void onDraw(Canvas canvas) { 129 paintRoundedBorders(canvas); 130 paintNotch(canvas); 131 132 } 133 }