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 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 101 public void reset() { 102 mScale = 1f; 103 mPressed = false; 104 } 105 106 @Override 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 139 public void setScale(float scale) { 140 mScale = scale; 141 } 142 143 public float getScale() { 144 return mScale; 145 } 146 147 public void setPressed(boolean pressed) { 148 mPressed = pressed; 149 } 150 151 @Override 152 public int getOpacity() { 153 return PixelFormat.TRANSLUCENT; 154 } 155 156 @Override 157 public void setAlpha(int alpha) { 158 } 159 160 @Override 161 public void setColorFilter(ColorFilter cf) { 162 } 163 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