blob: 010c573f1b10e59d131be3dfa40a181760d54056 [file] [log] [blame]
Winson Chungb3347bb2010-08-19 14:51:28 -07001/*
2 * Copyright (C) 2010 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
17package com.android.launcher2;
18
19import android.content.Context;
Winson Chung241c3b42010-08-25 16:53:03 -070020import android.content.pm.PackageManager;
21import android.content.pm.ResolveInfo;
Winson Chung64a3cd42010-09-17 16:47:33 -070022import android.content.res.TypedArray;
Winson Chungb3347bb2010-08-19 14:51:28 -070023import android.graphics.Bitmap;
Winson Chungb3347bb2010-08-19 14:51:28 -070024import android.graphics.Canvas;
Winson Chungb3347bb2010-08-19 14:51:28 -070025import android.graphics.Paint;
26import android.graphics.PointF;
Winson Chungb3347bb2010-08-19 14:51:28 -070027import android.graphics.Rect;
28import android.graphics.Region.Op;
Winson Chung03c568e2010-08-19 17:16:59 -070029import android.graphics.drawable.Drawable;
Winson Chungb3347bb2010-08-19 14:51:28 -070030import android.util.AttributeSet;
Winson Chung03c568e2010-08-19 17:16:59 -070031import android.widget.Checkable;
Winson Chungb3347bb2010-08-19 14:51:28 -070032import android.widget.TextView;
33
Winson Chung64a3cd42010-09-17 16:47:33 -070034import com.android.launcher.R;
35import com.android.launcher2.PagedView.PagedViewIconCache;
36
Winson Chung241c3b42010-08-25 16:53:03 -070037
Winson Chungb3347bb2010-08-19 14:51:28 -070038
39/**
40 * An icon on a PagedView, specifically for items in the launcher's paged view (with compound
41 * drawables on the top).
42 */
Winson Chung03c568e2010-08-19 17:16:59 -070043public class PagedViewIcon extends TextView implements Checkable {
Winson Chungb3347bb2010-08-19 14:51:28 -070044 private static final String TAG = "PagedViewIcon";
45
46 // holographic outline
47 private final Paint mPaint = new Paint();
48 private static HolographicOutlineHelper sHolographicOutlineHelper;
Winson Chung5f2aa4e2010-08-20 14:49:25 -070049 private Bitmap mCheckedOutline;
Winson Chungb3347bb2010-08-19 14:51:28 -070050 private Bitmap mHolographicOutline;
51 private Canvas mHolographicOutlineCanvas;
52 private boolean mIsHolographicUpdatePass;
53 private Rect mDrawableClipRect;
54
Winson Chung241c3b42010-08-25 16:53:03 -070055 private Object mIconCacheKey;
56 private PagedViewIconCache mIconCache;
Winson Chungdf4b83d2010-10-20 17:49:27 -070057 private int mScaledIconSize;
Winson Chung241c3b42010-08-25 16:53:03 -070058
Winson Chungb3347bb2010-08-19 14:51:28 -070059 private int mAlpha;
60 private int mHolographicAlpha;
61
Winson Chung03c568e2010-08-19 17:16:59 -070062 private boolean mIsChecked;
63
Winson Chung64a3cd42010-09-17 16:47:33 -070064 // Highlight colours
65 private int mHoloBlurColor;
66 private int mHoloOutlineColor;
67 private int mCheckedBlurColor;
68 private int mCheckedOutlineColor;
69
70
Winson Chungb3347bb2010-08-19 14:51:28 -070071 public PagedViewIcon(Context context) {
72 this(context, null);
73 }
74
75 public PagedViewIcon(Context context, AttributeSet attrs) {
76 this(context, attrs, 0);
77 }
78
79 public PagedViewIcon(Context context, AttributeSet attrs, int defStyle) {
80 super(context, attrs, defStyle);
Winson Chung64a3cd42010-09-17 16:47:33 -070081 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedViewIcon, defStyle, 0);
82 mHoloBlurColor = a.getColor(R.styleable.PagedViewIcon_blurColor, 0);
83 mHoloOutlineColor = a.getColor(R.styleable.PagedViewIcon_outlineColor, 0);
84 mCheckedBlurColor = a.getColor(R.styleable.PagedViewIcon_checkedBlurColor, 0);
85 mCheckedOutlineColor = a.getColor(R.styleable.PagedViewIcon_checkedOutlineColor, 0);
Winson Chungdf4b83d2010-10-20 17:49:27 -070086 mScaledIconSize = a.getDimensionPixelSize(R.styleable.PagedViewIcon_scaledIconSize, 64);
Winson Chung64a3cd42010-09-17 16:47:33 -070087 a.recycle();
Winson Chungb3347bb2010-08-19 14:51:28 -070088
89 if (sHolographicOutlineHelper == null) {
Winson Chung64a3cd42010-09-17 16:47:33 -070090 sHolographicOutlineHelper = new HolographicOutlineHelper();
Winson Chungb3347bb2010-08-19 14:51:28 -070091 }
92 mDrawableClipRect = new Rect();
93
94 setFocusable(true);
95 setBackgroundDrawable(null);
96 }
97
Winson Chungdf4b83d2010-10-20 17:49:27 -070098 public void applyFromApplicationInfo(ApplicationInfo info, PagedViewIconCache cache,
99 boolean scaleUp) {
Winson Chung241c3b42010-08-25 16:53:03 -0700100 mIconCache = cache;
101 mIconCacheKey = info;
102 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
103
Winson Chungdf4b83d2010-10-20 17:49:27 -0700104 Bitmap icon;
105 if (scaleUp) {
106 icon = Bitmap.createScaledBitmap(info.iconBitmap, mScaledIconSize,
107 mScaledIconSize, true);
108 } else {
109 icon = info.iconBitmap;
110 }
Winson Chung241c3b42010-08-25 16:53:03 -0700111 setCompoundDrawablesWithIntrinsicBounds(null,
Winson Chungdf4b83d2010-10-20 17:49:27 -0700112 new FastBitmapDrawable(icon), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700113 setText(info.title);
114 setTag(info);
115 }
116
117 public void applyFromResolveInfo(ResolveInfo info, PackageManager packageManager,
118 PagedViewIconCache cache) {
119 mIconCache = cache;
120 mIconCacheKey = info;
121 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
122
Winson Chungc1f48b92010-09-30 12:07:45 -0700123 Bitmap image = Utilities.createIconBitmap(info.loadIcon(packageManager), mContext);
124 setCompoundDrawablesWithIntrinsicBounds(null,
125 new FastBitmapDrawable(image), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700126 setText(info.loadLabel(packageManager));
127 setTag(info);
128 }
129
Winson Chungb3347bb2010-08-19 14:51:28 -0700130 @Override
131 public void setAlpha(float alpha) {
132 final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha);
Winson Chungb3347bb2010-08-19 14:51:28 -0700133 final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha);
Winson Chungaffd7b42010-08-20 15:11:56 -0700134 mAlpha = (int) (viewAlpha * 255);
Winson Chungb3347bb2010-08-19 14:51:28 -0700135 mHolographicAlpha = (int) (holographicAlpha * 255);
Winson Chungb3347bb2010-08-19 14:51:28 -0700136 super.setAlpha(viewAlpha);
137 }
138
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700139 public void invalidateCheckedImage() {
140 if (mCheckedOutline != null) {
141 mCheckedOutline.recycle();
142 mCheckedOutline = null;
143 }
144 }
145
Winson Chungb3347bb2010-08-19 14:51:28 -0700146 @Override
147 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
148 super.onLayout(changed, left, top, right, bottom);
149
Winson Chung96785572010-10-14 13:37:13 -0700150 if (mIconCache != null && mHolographicOutline == null) {
Winson Chungb3347bb2010-08-19 14:51:28 -0700151 // update the clipping rect to be used in the holographic pass below
152 getDrawingRect(mDrawableClipRect);
153 mDrawableClipRect.bottom = getPaddingTop() + getCompoundPaddingTop();
154
155 // set a flag to indicate that we are going to draw the view at full alpha with the text
156 // clipped for the generation of the holographic icon
157 mIsHolographicUpdatePass = true;
158 mHolographicOutline = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
159 Bitmap.Config.ARGB_8888);
160 mHolographicOutlineCanvas = new Canvas(mHolographicOutline);
161 mHolographicOutlineCanvas.concat(getMatrix());
162 draw(mHolographicOutlineCanvas);
Winson Chung64a3cd42010-09-17 16:47:33 -0700163 sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(mHolographicOutline,
164 mHolographicOutlineCanvas, mHoloBlurColor, mHoloOutlineColor);
Winson Chungb3347bb2010-08-19 14:51:28 -0700165 mIsHolographicUpdatePass = false;
Winson Chung241c3b42010-08-25 16:53:03 -0700166 mIconCache.addOutline(mIconCacheKey, mHolographicOutline);
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700167 mHolographicOutlineCanvas = null;
Winson Chungb3347bb2010-08-19 14:51:28 -0700168 }
169 }
170
Winson Chungb3347bb2010-08-19 14:51:28 -0700171 @Override
172 protected void onDraw(Canvas canvas) {
Winson Chungaffd7b42010-08-20 15:11:56 -0700173 // draw the view itself
Winson Chungb3347bb2010-08-19 14:51:28 -0700174 if (mIsHolographicUpdatePass) {
175 // only clip to the text view (restore its alpha so that we get a proper outline)
176 canvas.save();
177 canvas.clipRect(mDrawableClipRect, Op.REPLACE);
Winson Chungaffd7b42010-08-20 15:11:56 -0700178 final float alpha = getAlpha();
179 super.setAlpha(1.0f);
Winson Chungb3347bb2010-08-19 14:51:28 -0700180 super.onDraw(canvas);
Winson Chungaffd7b42010-08-20 15:11:56 -0700181 super.setAlpha(alpha);
Winson Chungb3347bb2010-08-19 14:51:28 -0700182 canvas.restore();
183 } else {
184 if (mAlpha > 0) {
185 super.onDraw(canvas);
186 }
187 }
188
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700189 // draw any blended overlays
190 if (!mIsHolographicUpdatePass) {
191 if (mCheckedOutline == null) {
192 if (mHolographicOutline != null && mHolographicAlpha > 0) {
193 mPaint.setAlpha(mHolographicAlpha);
194 canvas.drawBitmap(mHolographicOutline, 0, 0, mPaint);
195 }
196 } else {
197 mPaint.setAlpha(255);
198 canvas.drawBitmap(mCheckedOutline, 0, 0, mPaint);
199 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700200 }
201 }
Winson Chung03c568e2010-08-19 17:16:59 -0700202
203 @Override
204 public boolean isChecked() {
205 return mIsChecked;
206 }
207
208 @Override
209 public void setChecked(boolean checked) {
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700210 if (mIsChecked != checked) {
211 mIsChecked = checked;
212
213 if (mIsChecked) {
Winson Chung64a3cd42010-09-17 16:47:33 -0700214 // update the clipping rect to be used in the holographic pass below
215 getDrawingRect(mDrawableClipRect);
216 mDrawableClipRect.bottom = getPaddingTop() + getCompoundPaddingTop();
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700217
218 // set a flag to indicate that we are going to draw the view at full alpha with the text
219 // clipped for the generation of the holographic icon
220 mIsHolographicUpdatePass = true;
221 mCheckedOutline = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
222 Bitmap.Config.ARGB_8888);
223 mHolographicOutlineCanvas = new Canvas(mCheckedOutline);
224 mHolographicOutlineCanvas.concat(getMatrix());
225 draw(mHolographicOutlineCanvas);
Winson Chung64a3cd42010-09-17 16:47:33 -0700226 sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(mCheckedOutline,
227 mHolographicOutlineCanvas, mCheckedBlurColor, mCheckedOutlineColor);
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700228 mIsHolographicUpdatePass = false;
229 mHolographicOutlineCanvas = null;
230 } else {
231 invalidateCheckedImage();
232 }
233
234 invalidate();
235 }
Winson Chung03c568e2010-08-19 17:16:59 -0700236 }
237
238 @Override
239 public void toggle() {
240 setChecked(!mIsChecked);
241 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700242}