1 /* 2 * Copyright (C) 2012 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.keyguard; 18 19 import android.graphics.Bitmap; 20 import android.graphics.Canvas; 21 import android.graphics.Color; 22 import android.graphics.ColorFilter; 23 import android.graphics.Paint; 24 import android.graphics.Path; 25 import android.graphics.PixelFormat; 26 import android.graphics.PorterDuff; 27 import android.graphics.PorterDuffXfermode; 28 import android.graphics.Rect; 29 import android.graphics.RectF; 30 import android.graphics.drawable.Drawable; 31 32 class KeyguardCircleFramedDrawable extends Drawable { 33 34 private final Bitmap mBitmap; 35 private final int mSize; 36 private final Paint mPaint; 37 private final float mShadowRadius; 38 private final float mStrokeWidth; 39 private final int mFrameColor; 40 private final int mHighlightColor; 41 private final int mFrameShadowColor; 42 43 private float mScale; 44 private Path mFramePath; 45 private Rect mSrcRect; 46 private RectF mDstRect; 47 private RectF mFrameRect; 48 private boolean mPressed; 49 KeyguardCircleFramedDrawable(Bitmap bitmap, int size, int frameColor, float strokeWidth, int frameShadowColor, float shadowRadius, int highlightColor)50 public KeyguardCircleFramedDrawable(Bitmap bitmap, int size, 51 int frameColor, float strokeWidth, 52 int frameShadowColor, float shadowRadius, 53 int highlightColor) { 54 super(); 55 mSize = size; 56 mShadowRadius = shadowRadius; 57 mFrameColor = frameColor; 58 mFrameShadowColor = frameShadowColor; 59 mStrokeWidth = strokeWidth; 60 mHighlightColor = highlightColor; 61 62 mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888); 63 final Canvas canvas = new Canvas(mBitmap); 64 65 final int width = bitmap.getWidth(); 66 final int height = bitmap.getHeight(); 67 final int square = Math.min(width, height); 68 69 final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2, square, square); 70 final RectF circleRect = new RectF(0f, 0f, mSize, mSize); 71 circleRect.inset(mStrokeWidth / 2f, mStrokeWidth / 2f); 72 circleRect.inset(mShadowRadius, mShadowRadius); 73 74 final Path fillPath = new Path(); 75 fillPath.addArc(circleRect, 0f, 360f); 76 77 canvas.drawColor(0, PorterDuff.Mode.CLEAR); 78 79 // opaque circle matte 80 mPaint = new Paint(); 81 mPaint.setAntiAlias(true); 82 mPaint.setColor(Color.BLACK); 83 mPaint.setStyle(Paint.Style.FILL); 84 canvas.drawPath(fillPath, mPaint); 85 86 // mask in the icon where the bitmap is opaque 87 mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)); 88 canvas.drawBitmap(bitmap, cropRect, circleRect, mPaint); 89 90 // prepare paint for frame drawing 91 mPaint.setXfermode(null); 92 93 mScale = 1f; 94 95 mSrcRect = new Rect(0, 0, mSize, mSize); 96 mDstRect = new RectF(0, 0, mSize, mSize); 97 mFrameRect = new RectF(mDstRect); 98 mFramePath = new Path(); 99 } 100 reset()101 public void reset() { 102 mScale = 1f; 103 mPressed = false; 104 } 105 106 @Override draw(Canvas canvas)107 public void draw(Canvas canvas) { 108 // clear background 109 final float outside = Math.min(canvas.getWidth(), canvas.getHeight()); 110 final float inside = mScale * outside; 111 final float pad = (outside - inside) / 2f; 112 113 mDstRect.set(pad, pad, outside - pad, outside - pad); 114 canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null); 115 116 mFrameRect.set(mDstRect); 117 mFrameRect.inset(mStrokeWidth / 2f, mStrokeWidth / 2f); 118 mFrameRect.inset(mShadowRadius, mShadowRadius); 119 120 mFramePath.reset(); 121 mFramePath.addArc(mFrameRect, 0f, 360f); 122 123 // white frame 124 if (mPressed) { 125 mPaint.setStyle(Paint.Style.FILL); 126 mPaint.setColor(Color.argb((int) (0.33f * 255), 127 Color.red(mHighlightColor), 128 Color.green(mHighlightColor), 129 Color.blue(mHighlightColor))); 130 canvas.drawPath(mFramePath, mPaint); 131 } 132 mPaint.setStrokeWidth(mStrokeWidth); 133 mPaint.setStyle(Paint.Style.STROKE); 134 mPaint.setColor(mPressed ? mHighlightColor : mFrameColor); 135 mPaint.setShadowLayer(mShadowRadius, 0f, 0f, mFrameShadowColor); 136 canvas.drawPath(mFramePath, mPaint); 137 } 138 setScale(float scale)139 public void setScale(float scale) { 140 mScale = scale; 141 } 142 getScale()143 public float getScale() { 144 return mScale; 145 } 146 setPressed(boolean pressed)147 public void setPressed(boolean pressed) { 148 mPressed = pressed; 149 } 150 151 @Override getOpacity()152 public int getOpacity() { 153 return PixelFormat.TRANSLUCENT; 154 } 155 156 @Override setAlpha(int alpha)157 public void setAlpha(int alpha) { 158 } 159 160 @Override setColorFilter(ColorFilter cf)161 public void setColorFilter(ColorFilter cf) { 162 } 163 verifyParams(float iconSize, int frameColor, float stroke, int frameShadowColor, float shadowRadius, int highlightColor)164 public boolean verifyParams(float iconSize, int frameColor, float stroke, 165 int frameShadowColor, float shadowRadius, int highlightColor) { 166 return mSize == iconSize 167 && mFrameColor == frameColor 168 && mStrokeWidth == stroke 169 && mFrameShadowColor == frameShadowColor 170 && mShadowRadius == shadowRadius 171 && mHighlightColor == highlightColor; 172 } 173 } 174