1 /* 2 * Copyright (C) 2020 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.test.silkfx.hdr 18 19 import android.content.Context 20 import android.graphics.Bitmap 21 import android.graphics.BlendMode 22 import android.graphics.Canvas 23 import android.graphics.LinearGradient 24 import android.graphics.Paint 25 import android.graphics.Rect 26 import android.graphics.Shader 27 import android.graphics.drawable.BitmapDrawable 28 import android.util.AttributeSet 29 import com.android.test.silkfx.common.BaseDrawingView 30 31 class BlingyNotification : BaseDrawingView { 32 33 private val image: Bitmap? 34 private val bounds = Rect() 35 private val paint = Paint() 36 37 constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { 38 val typed = context.obtainStyledAttributes(attrs, intArrayOf(android.R.attr.src)) 39 val drawable = typed.getDrawable(0) 40 image = if (drawable is BitmapDrawable) { 41 drawable.bitmap 42 } else { 43 null 44 } 45 typed.recycle() 46 } 47 48 override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 49 val image = image ?: return super.onMeasure(widthMeasureSpec, heightMeasureSpec) 50 51 val widthMode = MeasureSpec.getMode(widthMeasureSpec) 52 val heightMode = MeasureSpec.getMode(heightMeasureSpec) 53 54 // Currently only used in this mode, so that's all we'll bother to support 55 if (widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY) { 56 val width = MeasureSpec.getSize(widthMeasureSpec) 57 58 var height = image.height * width / image.width 59 if (heightMode == MeasureSpec.AT_MOST) { 60 height = minOf(MeasureSpec.getSize(heightMeasureSpec), height) 61 } 62 setMeasuredDimension(width, height) 63 } else { 64 super.onMeasure(widthMeasureSpec, heightMeasureSpec) 65 } 66 } 67 68 override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { 69 super.onSizeChanged(w, h, oldw, oldh) 70 bounds.set(0, 0, w, h) 71 paint.shader = LinearGradient(0f, 0f, w.toFloat(), 0f, 72 longArrayOf( 73 color(1f, 1f, 1f, 0f), 74 color(1f, 1f, 1f, .1f), 75 color(2f, 2f, 2f, .3f), 76 color(1f, 1f, 1f, .2f), 77 color(1f, 1f, 1f, 0f) 78 ), 79 floatArrayOf(.2f, .4f, .5f, .6f, .8f), 80 Shader.TileMode.CLAMP) 81 paint.blendMode = BlendMode.PLUS 82 } 83 84 override fun onDraw(canvas: Canvas) { 85 super.onDraw(canvas) 86 87 val image = image ?: return 88 89 canvas.drawBitmap(image, null, bounds, null) 90 91 canvas.save() 92 val frac = ((drawingTime % 2000) / 300f) - 1f 93 canvas.translate(width * frac, 0f) 94 canvas.rotate(-45f) 95 canvas.drawPaint(paint) 96 canvas.restore() 97 invalidate() 98 } 99 }