blob: 6c6c4dcd480756eba8740ce7c7a1ed20c226bfad [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
Michael Jurka0620bec2010-10-25 17:50:09 -070019import com.android.launcher.R;
20import com.android.launcher2.PagedView.PagedViewIconCache;
21
Winson Chungb3347bb2010-08-19 14:51:28 -070022import android.content.Context;
Winson Chung241c3b42010-08-25 16:53:03 -070023import android.content.pm.PackageManager;
24import android.content.pm.ResolveInfo;
Winson Chung64a3cd42010-09-17 16:47:33 -070025import android.content.res.TypedArray;
Winson Chungb3347bb2010-08-19 14:51:28 -070026import android.graphics.Bitmap;
Winson Chungb3347bb2010-08-19 14:51:28 -070027import android.graphics.Canvas;
Winson Chungb3347bb2010-08-19 14:51:28 -070028import android.graphics.Paint;
Winson Chungb3347bb2010-08-19 14:51:28 -070029import android.graphics.Rect;
Michael Jurka0620bec2010-10-25 17:50:09 -070030import android.os.Handler;
31import android.os.HandlerThread;
32import android.os.Message;
Winson Chungb3347bb2010-08-19 14:51:28 -070033import android.util.AttributeSet;
Winson Chung03c568e2010-08-19 17:16:59 -070034import android.widget.Checkable;
Winson Chungb3347bb2010-08-19 14:51:28 -070035import android.widget.TextView;
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;
Winson Chungb3347bb2010-08-19 14:51:28 -070052 private Rect mDrawableClipRect;
Michael Jurka0620bec2010-10-25 17:50:09 -070053 private Bitmap mIcon;
Winson Chungb3347bb2010-08-19 14:51:28 -070054
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
Michael Jurka0620bec2010-10-25 17:50:09 -070070 private static final HandlerThread sWorkerThread = new HandlerThread("pagedviewicon-helper");
71 static {
72 sWorkerThread.start();
73 }
74
75 private static final int MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE = 1;
76
77 private static final Handler sWorker = new Handler(sWorkerThread.getLooper()) {
78 private DeferredHandler mHandler = new DeferredHandler();
79 private Paint mPaint = new Paint();
80 public void handleMessage(Message msg) {
81 final PagedViewIcon icon = (PagedViewIcon) msg.obj;
82
83 final Bitmap holographicOutline = Bitmap.createBitmap(
84 icon.mIcon.getWidth(), icon.mIcon.getHeight(), Bitmap.Config.ARGB_8888);
85 Canvas holographicOutlineCanvas = new Canvas(holographicOutline);
86 holographicOutlineCanvas.drawBitmap(icon.mIcon, 0, 0, mPaint);
87
88 sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(holographicOutline,
89 holographicOutlineCanvas, icon.mHoloBlurColor, icon.mHoloOutlineColor);
90
91 mHandler.post(new Runnable() {
92 public void run() {
93 icon.mHolographicOutline = holographicOutline;
94 icon.mIconCache.addOutline(icon.mIconCacheKey, holographicOutline);
95 icon.invalidate();
96 }
97 });
98 }
99 };
Winson Chung64a3cd42010-09-17 16:47:33 -0700100
Winson Chungb3347bb2010-08-19 14:51:28 -0700101 public PagedViewIcon(Context context) {
102 this(context, null);
103 }
104
105 public PagedViewIcon(Context context, AttributeSet attrs) {
106 this(context, attrs, 0);
107 }
108
109 public PagedViewIcon(Context context, AttributeSet attrs, int defStyle) {
110 super(context, attrs, defStyle);
Winson Chung64a3cd42010-09-17 16:47:33 -0700111 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedViewIcon, defStyle, 0);
112 mHoloBlurColor = a.getColor(R.styleable.PagedViewIcon_blurColor, 0);
113 mHoloOutlineColor = a.getColor(R.styleable.PagedViewIcon_outlineColor, 0);
114 mCheckedBlurColor = a.getColor(R.styleable.PagedViewIcon_checkedBlurColor, 0);
115 mCheckedOutlineColor = a.getColor(R.styleable.PagedViewIcon_checkedOutlineColor, 0);
Winson Chung0e41ae62010-10-27 18:10:32 -0700116 mScaledIconSize =
117 context.getResources().getDimensionPixelSize(R.dimen.temp_scaled_icon_size);
118
Winson Chung64a3cd42010-09-17 16:47:33 -0700119 a.recycle();
Winson Chungb3347bb2010-08-19 14:51:28 -0700120
121 if (sHolographicOutlineHelper == null) {
Winson Chung64a3cd42010-09-17 16:47:33 -0700122 sHolographicOutlineHelper = new HolographicOutlineHelper();
Winson Chungb3347bb2010-08-19 14:51:28 -0700123 }
124 mDrawableClipRect = new Rect();
125
126 setFocusable(true);
127 setBackgroundDrawable(null);
128 }
129
Michael Jurka0620bec2010-10-25 17:50:09 -0700130 private void queueHolographicOutlineCreation() {
131 // Generate the outline in the background
132 if (mHolographicOutline == null) {
133 Message m = sWorker.obtainMessage(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE);
134 m.obj = this;
135 sWorker.sendMessage(m);
136 }
137 }
138
Winson Chungdf4b83d2010-10-20 17:49:27 -0700139 public void applyFromApplicationInfo(ApplicationInfo info, PagedViewIconCache cache,
140 boolean scaleUp) {
Winson Chung241c3b42010-08-25 16:53:03 -0700141 mIconCache = cache;
142 mIconCacheKey = info;
143 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
144
Winson Chungdf4b83d2010-10-20 17:49:27 -0700145 if (scaleUp) {
Michael Jurka0620bec2010-10-25 17:50:09 -0700146 mIcon = Bitmap.createScaledBitmap(info.iconBitmap, mScaledIconSize,
Winson Chungdf4b83d2010-10-20 17:49:27 -0700147 mScaledIconSize, true);
148 } else {
Michael Jurka0620bec2010-10-25 17:50:09 -0700149 mIcon = info.iconBitmap;
Winson Chungdf4b83d2010-10-20 17:49:27 -0700150 }
Michael Jurka0620bec2010-10-25 17:50:09 -0700151 setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700152 setText(info.title);
153 setTag(info);
Michael Jurka0620bec2010-10-25 17:50:09 -0700154
155 queueHolographicOutlineCreation();
Winson Chung241c3b42010-08-25 16:53:03 -0700156 }
157
158 public void applyFromResolveInfo(ResolveInfo info, PackageManager packageManager,
Winson Chung7da10252010-10-28 16:07:04 -0700159 PagedViewIconCache cache, boolean scaleUp) {
Winson Chung241c3b42010-08-25 16:53:03 -0700160 mIconCache = cache;
161 mIconCacheKey = info;
162 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
163
Michael Jurka0620bec2010-10-25 17:50:09 -0700164 mIcon = Utilities.createIconBitmap(info.loadIcon(packageManager), mContext);
Winson Chung7da10252010-10-28 16:07:04 -0700165 if (scaleUp) {
166 mIcon = Bitmap.createScaledBitmap(mIcon, mScaledIconSize,
167 mScaledIconSize, true);
168 }
Michael Jurka0620bec2010-10-25 17:50:09 -0700169 setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700170 setText(info.loadLabel(packageManager));
171 setTag(info);
Michael Jurka0620bec2010-10-25 17:50:09 -0700172
173 queueHolographicOutlineCreation();
Winson Chung241c3b42010-08-25 16:53:03 -0700174 }
175
Winson Chungb3347bb2010-08-19 14:51:28 -0700176 @Override
177 public void setAlpha(float alpha) {
178 final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha);
Winson Chungb3347bb2010-08-19 14:51:28 -0700179 final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha);
Winson Chungaffd7b42010-08-20 15:11:56 -0700180 mAlpha = (int) (viewAlpha * 255);
Winson Chungb3347bb2010-08-19 14:51:28 -0700181 mHolographicAlpha = (int) (holographicAlpha * 255);
Winson Chungb3347bb2010-08-19 14:51:28 -0700182 super.setAlpha(viewAlpha);
183 }
184
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700185 public void invalidateCheckedImage() {
186 if (mCheckedOutline != null) {
187 mCheckedOutline.recycle();
188 mCheckedOutline = null;
189 }
190 }
191
Winson Chungb3347bb2010-08-19 14:51:28 -0700192 @Override
Michael Jurka0620bec2010-10-25 17:50:09 -0700193 protected void onDraw(Canvas canvas) {
194 if (mAlpha > 0) {
195 super.onDraw(canvas);
196 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700197
Michael Jurka0620bec2010-10-25 17:50:09 -0700198 Bitmap overlay = null;
Winson Chungb3347bb2010-08-19 14:51:28 -0700199
Michael Jurka0620bec2010-10-25 17:50:09 -0700200 // draw any blended overlays
201 if (mCheckedOutline == null) {
202 if (mHolographicOutline != null && mHolographicAlpha > 0) {
203 mPaint.setAlpha(mHolographicAlpha);
204 overlay = mHolographicOutline;
205 }
206 } else {
207 mPaint.setAlpha(255);
208 overlay = mCheckedOutline;
209 }
210
211 if (overlay != null) {
212 final int compoundPaddingLeft = getCompoundPaddingLeft();
213 final int compoundPaddingRight = getCompoundPaddingRight();
214 int hspace = getWidth() - compoundPaddingRight - compoundPaddingLeft;
215 canvas.drawBitmap(overlay,
216 compoundPaddingLeft + (hspace - overlay.getWidth()) / 2,
217 mPaddingTop,
218 mPaint);
Winson Chungb3347bb2010-08-19 14:51:28 -0700219 }
220 }
221
Winson Chungb3347bb2010-08-19 14:51:28 -0700222 @Override
Michael Jurka0620bec2010-10-25 17:50:09 -0700223 public void onDetachedFromWindow() {
224 super.onDetachedFromWindow();
225 sWorker.removeMessages(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE, this);
Winson Chungb3347bb2010-08-19 14:51:28 -0700226 }
Winson Chung03c568e2010-08-19 17:16:59 -0700227
228 @Override
229 public boolean isChecked() {
230 return mIsChecked;
231 }
232
233 @Override
234 public void setChecked(boolean checked) {
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700235 if (mIsChecked != checked) {
236 mIsChecked = checked;
237
238 if (mIsChecked) {
Michael Jurka0620bec2010-10-25 17:50:09 -0700239 mCheckedOutline = Bitmap.createBitmap(mIcon.getWidth(), mIcon.getHeight(),
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700240 Bitmap.Config.ARGB_8888);
Michael Jurka0620bec2010-10-25 17:50:09 -0700241 Canvas checkedOutlineCanvas = new Canvas(mCheckedOutline);
242 mPaint.setAlpha(255);
243 checkedOutlineCanvas.drawBitmap(mIcon, 0, 0, mPaint);
244
Winson Chung64a3cd42010-09-17 16:47:33 -0700245 sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(mCheckedOutline,
Michael Jurka0620bec2010-10-25 17:50:09 -0700246 checkedOutlineCanvas, mCheckedBlurColor, mCheckedOutlineColor);
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700247 } else {
248 invalidateCheckedImage();
249 }
250
251 invalidate();
252 }
Winson Chung03c568e2010-08-19 17:16:59 -0700253 }
254
255 @Override
256 public void toggle() {
257 setChecked(!mIsChecked);
258 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700259}