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