blob: 884884e3121751000e6dc803dfe5adc8999e36fa [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
Winson Chungcd4bc492010-12-09 18:52:32 -080019import android.animation.ObjectAnimator;
Winson Chungb3347bb2010-08-19 14:51:28 -070020import android.content.Context;
Winson Chung241c3b42010-08-25 16:53:03 -070021import android.content.pm.PackageManager;
22import android.content.pm.ResolveInfo;
Winson Chung64a3cd42010-09-17 16:47:33 -070023import android.content.res.TypedArray;
Winson Chungb3347bb2010-08-19 14:51:28 -070024import android.graphics.Bitmap;
Winson Chungb3347bb2010-08-19 14:51:28 -070025import android.graphics.Canvas;
Winson Chungb3347bb2010-08-19 14:51:28 -070026import android.graphics.Paint;
Michael Jurka0620bec2010-10-25 17:50:09 -070027import android.os.Handler;
28import android.os.HandlerThread;
29import android.os.Message;
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 -070032
Winson Chungc84001e2010-11-09 12:20:57 -080033import com.android.launcher.R;
34import com.android.launcher2.PagedView.PagedViewIconCache;
35
Winson Chung241c3b42010-08-25 16:53:03 -070036
Winson Chungb3347bb2010-08-19 14:51:28 -070037
38/**
39 * An icon on a PagedView, specifically for items in the launcher's paged view (with compound
40 * drawables on the top).
41 */
Michael Jurka67b2f6c2010-11-17 12:33:46 -080042public class PagedViewIcon extends CacheableTextView implements Checkable {
Winson Chungb3347bb2010-08-19 14:51:28 -070043 private static final String TAG = "PagedViewIcon";
44
45 // holographic outline
46 private final Paint mPaint = new Paint();
47 private static HolographicOutlineHelper sHolographicOutlineHelper;
Winson Chung5f2aa4e2010-08-20 14:49:25 -070048 private Bitmap mCheckedOutline;
Winson Chungb3347bb2010-08-19 14:51:28 -070049 private Bitmap mHolographicOutline;
Michael Jurka0620bec2010-10-25 17:50:09 -070050 private Bitmap mIcon;
Winson Chungb3347bb2010-08-19 14:51:28 -070051
Winson Chung241c3b42010-08-25 16:53:03 -070052 private Object mIconCacheKey;
53 private PagedViewIconCache mIconCache;
54
Winson Chung29d6fea2010-12-01 15:47:31 -080055 private int mAlpha;
Winson Chungb3347bb2010-08-19 14:51:28 -070056 private int mHolographicAlpha;
57
Winson Chung03c568e2010-08-19 17:16:59 -070058 private boolean mIsChecked;
Winson Chungcd4bc492010-12-09 18:52:32 -080059 private ObjectAnimator mCheckedAlphaAnimator;
60 private final static float sCheckedAlpha = 0.4f;
61 private final static int sCheckedFadeInDuration = 150;
62 private final static int sCheckedFadeOutDuration = 200;
Winson Chung03c568e2010-08-19 17:16:59 -070063
Michael Jurkac9a96192010-11-01 11:52:08 -070064 // Highlight colors
Winson Chung64a3cd42010-09-17 16:47:33 -070065 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
Adam Cohen5bb50bd2010-12-03 11:39:55 -080088 sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(holographicOutline,
Michael Jurka0620bec2010-10-25 17:50:09 -070089 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 Chung29d6fea2010-12-01 15:47:31 -0800111
Winson Chung64a3cd42010-09-17 16:47:33 -0700112 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedViewIcon, defStyle, 0);
Winson Chung29d6fea2010-12-01 15:47:31 -0800113 mAlpha = 255;
Winson Chung64a3cd42010-09-17 16:47:33 -0700114 mHoloBlurColor = a.getColor(R.styleable.PagedViewIcon_blurColor, 0);
115 mHoloOutlineColor = a.getColor(R.styleable.PagedViewIcon_outlineColor, 0);
116 mCheckedBlurColor = a.getColor(R.styleable.PagedViewIcon_checkedBlurColor, 0);
117 mCheckedOutlineColor = a.getColor(R.styleable.PagedViewIcon_checkedOutlineColor, 0);
118 a.recycle();
Winson Chungb3347bb2010-08-19 14:51:28 -0700119
120 if (sHolographicOutlineHelper == null) {
Winson Chung64a3cd42010-09-17 16:47:33 -0700121 sHolographicOutlineHelper = new HolographicOutlineHelper();
Winson Chungb3347bb2010-08-19 14:51:28 -0700122 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700123
124 setFocusable(true);
125 setBackgroundDrawable(null);
126 }
127
Michael Jurka0620bec2010-10-25 17:50:09 -0700128 private void queueHolographicOutlineCreation() {
Winson Chung3b823cd2010-12-06 15:25:00 -0800129 /* Temporarily disabling holographic outline creation.
Michael Jurka0620bec2010-10-25 17:50:09 -0700130 // Generate the outline in the background
131 if (mHolographicOutline == null) {
132 Message m = sWorker.obtainMessage(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE);
133 m.obj = this;
134 sWorker.sendMessage(m);
135 }
Winson Chung3b823cd2010-12-06 15:25:00 -0800136 */
Michael Jurka0620bec2010-10-25 17:50:09 -0700137 }
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
Michael Jurkac9a96192010-11-01 11:52:08 -0700145 mIcon = info.iconBitmap;
Michael Jurka0620bec2010-10-25 17:50:09 -0700146 setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700147 setText(info.title);
Michael Jurka67b2f6c2010-11-17 12:33:46 -0800148 buildAndEnableCache();
Winson Chung241c3b42010-08-25 16:53:03 -0700149 setTag(info);
Michael Jurka0620bec2010-10-25 17:50:09 -0700150
151 queueHolographicOutlineCreation();
Winson Chung241c3b42010-08-25 16:53:03 -0700152 }
153
154 public void applyFromResolveInfo(ResolveInfo info, PackageManager packageManager,
Michael Jurkac9a96192010-11-01 11:52:08 -0700155 PagedViewIconCache cache, IconCache modelIconCache) {
Winson Chung241c3b42010-08-25 16:53:03 -0700156 mIconCache = cache;
157 mIconCacheKey = info;
158 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
159
Michael Jurkac9a96192010-11-01 11:52:08 -0700160 mIcon = Utilities.createIconBitmap(
161 modelIconCache.getFullResIcon(info, packageManager), mContext);
Michael Jurka0620bec2010-10-25 17:50:09 -0700162 setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700163 setText(info.loadLabel(packageManager));
Michael Jurka67b2f6c2010-11-17 12:33:46 -0800164 buildAndEnableCache();
Winson Chung241c3b42010-08-25 16:53:03 -0700165 setTag(info);
Michael Jurka0620bec2010-10-25 17:50:09 -0700166
167 queueHolographicOutlineCreation();
Winson Chung241c3b42010-08-25 16:53:03 -0700168 }
169
Winson Chungb3347bb2010-08-19 14:51:28 -0700170 @Override
171 public void setAlpha(float alpha) {
172 final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha);
Winson Chungb3347bb2010-08-19 14:51:28 -0700173 final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha);
Winson Chunge22a8e92010-11-12 13:40:58 -0800174 int newViewAlpha = (int) (viewAlpha * 255);
175 int newHolographicAlpha = (int) (holographicAlpha * 255);
176 if ((mAlpha != newViewAlpha) || (mHolographicAlpha != newHolographicAlpha)) {
177 mAlpha = newViewAlpha;
178 mHolographicAlpha = newHolographicAlpha;
179 super.setAlpha(viewAlpha);
180 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700181 }
182
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700183 public void invalidateCheckedImage() {
184 if (mCheckedOutline != null) {
185 mCheckedOutline.recycle();
186 mCheckedOutline = null;
187 }
188 }
189
Winson Chungb3347bb2010-08-19 14:51:28 -0700190 @Override
Michael Jurka0620bec2010-10-25 17:50:09 -0700191 protected void onDraw(Canvas canvas) {
192 if (mAlpha > 0) {
193 super.onDraw(canvas);
194 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700195
Michael Jurka0620bec2010-10-25 17:50:09 -0700196 Bitmap overlay = null;
Winson Chungb3347bb2010-08-19 14:51:28 -0700197
Michael Jurka0620bec2010-10-25 17:50:09 -0700198 // draw any blended overlays
199 if (mCheckedOutline == null) {
200 if (mHolographicOutline != null && mHolographicAlpha > 0) {
201 mPaint.setAlpha(mHolographicAlpha);
202 overlay = mHolographicOutline;
203 }
204 } else {
205 mPaint.setAlpha(255);
206 overlay = mCheckedOutline;
207 }
208
209 if (overlay != null) {
Winson Chungc84001e2010-11-09 12:20:57 -0800210 final int offset = getScrollX();
Michael Jurka0620bec2010-10-25 17:50:09 -0700211 final int compoundPaddingLeft = getCompoundPaddingLeft();
212 final int compoundPaddingRight = getCompoundPaddingRight();
213 int hspace = getWidth() - compoundPaddingRight - compoundPaddingLeft;
214 canvas.drawBitmap(overlay,
Winson Chungc84001e2010-11-09 12:20:57 -0800215 offset + compoundPaddingLeft + (hspace - overlay.getWidth()) / 2,
Michael Jurka0620bec2010-10-25 17:50:09 -0700216 mPaddingTop,
217 mPaint);
Winson Chungb3347bb2010-08-19 14:51:28 -0700218 }
219 }
220
Winson Chungb3347bb2010-08-19 14:51:28 -0700221 @Override
Michael Jurka0620bec2010-10-25 17:50:09 -0700222 public void onDetachedFromWindow() {
223 super.onDetachedFromWindow();
224 sWorker.removeMessages(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE, this);
Winson Chungb3347bb2010-08-19 14:51:28 -0700225 }
Winson Chung03c568e2010-08-19 17:16:59 -0700226
227 @Override
228 public boolean isChecked() {
229 return mIsChecked;
230 }
231
232 @Override
233 public void setChecked(boolean checked) {
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700234 if (mIsChecked != checked) {
235 mIsChecked = checked;
236
Winson Chungcd4bc492010-12-09 18:52:32 -0800237 float alpha;
238 int duration;
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700239 if (mIsChecked) {
Winson Chungcd4bc492010-12-09 18:52:32 -0800240 alpha = sCheckedAlpha;
241 duration = sCheckedFadeInDuration;
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700242 } else {
Winson Chungcd4bc492010-12-09 18:52:32 -0800243 alpha = 1.0f;
244 duration = sCheckedFadeOutDuration;
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700245 }
246
Winson Chungcd4bc492010-12-09 18:52:32 -0800247 // Initialize the animator
248 if (mCheckedAlphaAnimator != null) {
249 mCheckedAlphaAnimator.cancel();
250 }
251 mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", alpha);
252 mCheckedAlphaAnimator.setDuration(duration);
253 mCheckedAlphaAnimator.start();
254
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700255 invalidate();
256 }
Winson Chung03c568e2010-08-19 17:16:59 -0700257 }
258
259 @Override
260 public void toggle() {
261 setChecked(!mIsChecked);
262 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700263}