1 /* 2 * Copyright (C) 2023 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 package com.android.customization.picker.color.ui.view 17 18 import android.annotation.ColorInt 19 import android.content.Context 20 import android.graphics.Canvas 21 import android.graphics.Color 22 import android.graphics.Paint 23 import android.graphics.RectF 24 import android.util.AttributeSet 25 import android.view.View 26 27 /** 28 * Draw a color option icon, which is a quadrant circle that can show at most 4 different colors. 29 */ 30 class ColorOptionIconView( 31 context: Context, 32 attrs: AttributeSet, 33 ) : View(context, attrs) { 34 <lambda>null35 private val paint = Paint().apply { style = Paint.Style.FILL } 36 37 private val oval = RectF() 38 39 private var color0 = DEFAULT_PLACEHOLDER_COLOR 40 private var color1 = DEFAULT_PLACEHOLDER_COLOR 41 private var color2 = DEFAULT_PLACEHOLDER_COLOR 42 private var color3 = DEFAULT_PLACEHOLDER_COLOR 43 44 private var w = 0 45 private var h = 0 46 47 /** 48 * @param color0 the color in the top left quadrant 49 * @param color1 the color in the top right quadrant 50 * @param color2 the color in the bottom left quadrant 51 * @param color3 the color in the bottom right quadrant 52 */ bindColornull53 fun bindColor( 54 @ColorInt color0: Int, 55 @ColorInt color1: Int, 56 @ColorInt color2: Int, 57 @ColorInt color3: Int, 58 ) { 59 this.color0 = color0 60 this.color1 = color1 61 this.color2 = color2 62 this.color3 = color3 63 invalidate() 64 } 65 onSizeChangednull66 override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { 67 this.w = w 68 this.h = h 69 super.onSizeChanged(w, h, oldw, oldh) 70 } 71 onDrawnull72 override fun onDraw(canvas: Canvas) { 73 super.onDraw(canvas) 74 // The w and h need to be an even number to avoid tiny pixel-level gaps between the pies 75 w = w.roundDownToEven() 76 h = h.roundDownToEven() 77 78 val width = w.toFloat() 79 val height = h.toFloat() 80 81 oval.set(0f, 0f, width, height) 82 canvas.apply { 83 paint.color = color3 84 drawArc( 85 oval, 86 0f, 87 90f, 88 true, 89 paint, 90 ) 91 paint.color = color2 92 drawArc( 93 oval, 94 90f, 95 90f, 96 true, 97 paint, 98 ) 99 paint.color = color0 100 drawArc( 101 oval, 102 180f, 103 90f, 104 true, 105 paint, 106 ) 107 paint.color = color1 108 drawArc( 109 oval, 110 270f, 111 90f, 112 true, 113 paint, 114 ) 115 } 116 } 117 118 companion object { 119 const val DEFAULT_PLACEHOLDER_COLOR = Color.BLACK 120 roundDownToEvennull121 fun Int.roundDownToEven(): Int { 122 return if (this % 2 == 0) this else this - 1 123 } 124 } 125 } 126