blob: bde65593af2ed71d6314e186b9dd04ce26f48a87 [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 Jurka742574b2011-02-02 23:51:01 -080019import com.android.launcher.R;
20
Winson Chungcd4bc492010-12-09 18:52:32 -080021import android.animation.ObjectAnimator;
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 Chung59e1f9a2010-12-21 11:31:54 -080025import android.content.res.Resources;
Winson Chung64a3cd42010-09-17 16:47:33 -070026import android.content.res.TypedArray;
Winson Chungb3347bb2010-08-19 14:51:28 -070027import android.graphics.Bitmap;
Winson Chungb3347bb2010-08-19 14:51:28 -070028import android.graphics.Canvas;
Winson Chungb3347bb2010-08-19 14:51:28 -070029import android.graphics.Paint;
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;
Michael Jurka742574b2011-02-02 23:51:01 -080035import android.widget.TextView;
Winson Chungc84001e2010-11-09 12:20:57 -080036
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 */
Michael Jurkac0759f52011-02-03 16:47:14 -080043public class PagedViewIcon extends CachedTextView 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;
Michael Jurka0620bec2010-10-25 17:50:09 -070051 private Bitmap mIcon;
Winson Chungb3347bb2010-08-19 14:51:28 -070052
Winson Chung04998342011-01-05 13:54:43 -080053 private PagedViewIconCache.Key mIconCacheKey;
Winson Chung241c3b42010-08-25 16:53:03 -070054 private PagedViewIconCache mIconCache;
55
Winson Chung88127032010-12-13 12:11:33 -080056 private int mAlpha = 255;
Winson Chungb3347bb2010-08-19 14:51:28 -070057 private int mHolographicAlpha;
58
Winson Chung03c568e2010-08-19 17:16:59 -070059 private boolean mIsChecked;
Winson Chungcd4bc492010-12-09 18:52:32 -080060 private ObjectAnimator mCheckedAlphaAnimator;
Winson Chung59e1f9a2010-12-21 11:31:54 -080061 private float mCheckedAlpha = 1.0f;
62 private int mCheckedFadeInDuration;
63 private int mCheckedFadeOutDuration;
Winson Chung03c568e2010-08-19 17:16:59 -070064
Michael Jurkac9a96192010-11-01 11:52:08 -070065 // Highlight colors
Winson Chung64a3cd42010-09-17 16:47:33 -070066 private int mHoloBlurColor;
67 private int mHoloOutlineColor;
Winson Chung64a3cd42010-09-17 16:47:33 -070068
Michael Jurka8245a862011-02-01 17:53:59 -080069 HolographicPagedViewIcon mHolographicOutlineView;
70
Michael Jurka0620bec2010-10-25 17:50:09 -070071 private static final HandlerThread sWorkerThread = new HandlerThread("pagedviewicon-helper");
72 static {
73 sWorkerThread.start();
74 }
75
76 private static final int MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE = 1;
77
78 private static final Handler sWorker = new Handler(sWorkerThread.getLooper()) {
79 private DeferredHandler mHandler = new DeferredHandler();
80 private Paint mPaint = new Paint();
81 public void handleMessage(Message msg) {
82 final PagedViewIcon icon = (PagedViewIcon) msg.obj;
83
84 final Bitmap holographicOutline = Bitmap.createBitmap(
85 icon.mIcon.getWidth(), icon.mIcon.getHeight(), Bitmap.Config.ARGB_8888);
86 Canvas holographicOutlineCanvas = new Canvas(holographicOutline);
87 holographicOutlineCanvas.drawBitmap(icon.mIcon, 0, 0, mPaint);
88
Adam Cohen5bb50bd2010-12-03 11:39:55 -080089 sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(holographicOutline,
Michael Jurka0620bec2010-10-25 17:50:09 -070090 holographicOutlineCanvas, icon.mHoloBlurColor, icon.mHoloOutlineColor);
91
92 mHandler.post(new Runnable() {
93 public void run() {
94 icon.mHolographicOutline = holographicOutline;
95 icon.mIconCache.addOutline(icon.mIconCacheKey, holographicOutline);
Michael Jurka8245a862011-02-01 17:53:59 -080096 icon.getHolographicOutlineView().invalidate();
Michael Jurka0620bec2010-10-25 17:50:09 -070097 }
98 });
99 }
100 };
Winson Chung64a3cd42010-09-17 16:47:33 -0700101
Winson Chungb3347bb2010-08-19 14:51:28 -0700102 public PagedViewIcon(Context context) {
103 this(context, null);
104 }
105
106 public PagedViewIcon(Context context, AttributeSet attrs) {
107 this(context, attrs, 0);
108 }
109
110 public PagedViewIcon(Context context, AttributeSet attrs, int defStyle) {
111 super(context, attrs, defStyle);
Winson Chung29d6fea2010-12-01 15:47:31 -0800112
Winson Chung64a3cd42010-09-17 16:47:33 -0700113 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedViewIcon, defStyle, 0);
114 mHoloBlurColor = a.getColor(R.styleable.PagedViewIcon_blurColor, 0);
115 mHoloOutlineColor = a.getColor(R.styleable.PagedViewIcon_outlineColor, 0);
Winson Chung64a3cd42010-09-17 16:47:33 -0700116 a.recycle();
Winson Chungb3347bb2010-08-19 14:51:28 -0700117
118 if (sHolographicOutlineHelper == null) {
Winson Chung64a3cd42010-09-17 16:47:33 -0700119 sHolographicOutlineHelper = new HolographicOutlineHelper();
Winson Chungb3347bb2010-08-19 14:51:28 -0700120 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700121
Winson Chung59e1f9a2010-12-21 11:31:54 -0800122 // Set up fade in/out constants
123 final Resources r = context.getResources();
124 final int alpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha);
125 if (alpha > 0) {
126 mCheckedAlpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha) / 256.0f;
127 mCheckedFadeInDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeInTime);
128 mCheckedFadeOutDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeOutTime);
129 }
130
Winson Chungb3347bb2010-08-19 14:51:28 -0700131 setFocusable(true);
132 setBackgroundDrawable(null);
Michael Jurka8245a862011-02-01 17:53:59 -0800133 mHolographicOutlineView = new HolographicPagedViewIcon(context, this);
134 }
135
136 protected HolographicPagedViewIcon getHolographicOutlineView() {
137 return mHolographicOutlineView;
138 }
139
140 protected Bitmap getHolographicOutline() {
141 return mHolographicOutline;
Winson Chungb3347bb2010-08-19 14:51:28 -0700142 }
143
Winson Chung823c9692011-03-01 10:57:29 -0800144 private boolean queueHolographicOutlineCreation() {
Michael Jurka0620bec2010-10-25 17:50:09 -0700145 // Generate the outline in the background
146 if (mHolographicOutline == null) {
147 Message m = sWorker.obtainMessage(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE);
148 m.obj = this;
149 sWorker.sendMessage(m);
Winson Chung823c9692011-03-01 10:57:29 -0800150 return true;
Michael Jurka0620bec2010-10-25 17:50:09 -0700151 }
Winson Chung823c9692011-03-01 10:57:29 -0800152 return false;
Michael Jurka0620bec2010-10-25 17:50:09 -0700153 }
154
Winson Chungdf4b83d2010-10-20 17:49:27 -0700155 public void applyFromApplicationInfo(ApplicationInfo info, PagedViewIconCache cache,
Winson Chung04998342011-01-05 13:54:43 -0800156 boolean scaleUp, boolean createHolographicOutlines) {
Michael Jurkac9a96192010-11-01 11:52:08 -0700157 mIcon = info.iconBitmap;
Michael Jurka0620bec2010-10-25 17:50:09 -0700158 setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700159 setText(info.title);
160 setTag(info);
Michael Jurka0620bec2010-10-25 17:50:09 -0700161
Winson Chung04998342011-01-05 13:54:43 -0800162 if (createHolographicOutlines) {
163 mIconCache = cache;
164 mIconCacheKey = new PagedViewIconCache.Key(info);
165 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
Winson Chung823c9692011-03-01 10:57:29 -0800166 if (!queueHolographicOutlineCreation()) {
167 getHolographicOutlineView().invalidate();
168 }
Winson Chung04998342011-01-05 13:54:43 -0800169 }
Winson Chung241c3b42010-08-25 16:53:03 -0700170 }
171
172 public void applyFromResolveInfo(ResolveInfo info, PackageManager packageManager,
Winson Chung04998342011-01-05 13:54:43 -0800173 PagedViewIconCache cache, IconCache modelIconCache, boolean createHolographicOutlines) {
Michael Jurkac9a96192010-11-01 11:52:08 -0700174 mIcon = Utilities.createIconBitmap(
175 modelIconCache.getFullResIcon(info, packageManager), mContext);
Michael Jurka0620bec2010-10-25 17:50:09 -0700176 setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700177 setText(info.loadLabel(packageManager));
178 setTag(info);
Michael Jurka0620bec2010-10-25 17:50:09 -0700179
Winson Chung04998342011-01-05 13:54:43 -0800180 if (createHolographicOutlines) {
181 mIconCache = cache;
182 mIconCacheKey = new PagedViewIconCache.Key(info);
183 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
Winson Chung823c9692011-03-01 10:57:29 -0800184 if (!queueHolographicOutlineCreation()) {
185 getHolographicOutlineView().invalidate();
186 }
Winson Chung04998342011-01-05 13:54:43 -0800187 }
Winson Chung241c3b42010-08-25 16:53:03 -0700188 }
189
Winson Chungb3347bb2010-08-19 14:51:28 -0700190 @Override
191 public void setAlpha(float alpha) {
192 final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha);
Winson Chungb3347bb2010-08-19 14:51:28 -0700193 final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha);
Winson Chunge22a8e92010-11-12 13:40:58 -0800194 int newViewAlpha = (int) (viewAlpha * 255);
195 int newHolographicAlpha = (int) (holographicAlpha * 255);
196 if ((mAlpha != newViewAlpha) || (mHolographicAlpha != newHolographicAlpha)) {
197 mAlpha = newViewAlpha;
198 mHolographicAlpha = newHolographicAlpha;
199 super.setAlpha(viewAlpha);
200 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700201 }
202
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700203 public void invalidateCheckedImage() {
204 if (mCheckedOutline != null) {
205 mCheckedOutline.recycle();
206 mCheckedOutline = null;
207 }
208 }
209
Winson Chungb3347bb2010-08-19 14:51:28 -0700210 @Override
Michael Jurka0620bec2010-10-25 17:50:09 -0700211 protected void onDraw(Canvas canvas) {
212 if (mAlpha > 0) {
213 super.onDraw(canvas);
214 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700215
Michael Jurka0620bec2010-10-25 17:50:09 -0700216 Bitmap overlay = null;
Winson Chungb3347bb2010-08-19 14:51:28 -0700217
Michael Jurka0620bec2010-10-25 17:50:09 -0700218 // draw any blended overlays
219 if (mCheckedOutline == null) {
220 if (mHolographicOutline != null && mHolographicAlpha > 0) {
221 mPaint.setAlpha(mHolographicAlpha);
222 overlay = mHolographicOutline;
223 }
224 } else {
225 mPaint.setAlpha(255);
226 overlay = mCheckedOutline;
227 }
228
229 if (overlay != null) {
Winson Chungc84001e2010-11-09 12:20:57 -0800230 final int offset = getScrollX();
Michael Jurka0620bec2010-10-25 17:50:09 -0700231 final int compoundPaddingLeft = getCompoundPaddingLeft();
232 final int compoundPaddingRight = getCompoundPaddingRight();
233 int hspace = getWidth() - compoundPaddingRight - compoundPaddingLeft;
234 canvas.drawBitmap(overlay,
Winson Chungc84001e2010-11-09 12:20:57 -0800235 offset + compoundPaddingLeft + (hspace - overlay.getWidth()) / 2,
Michael Jurka0620bec2010-10-25 17:50:09 -0700236 mPaddingTop,
237 mPaint);
Winson Chungb3347bb2010-08-19 14:51:28 -0700238 }
239 }
240
Winson Chungb3347bb2010-08-19 14:51:28 -0700241 @Override
Michael Jurka0620bec2010-10-25 17:50:09 -0700242 public void onDetachedFromWindow() {
243 super.onDetachedFromWindow();
244 sWorker.removeMessages(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE, this);
Winson Chungb3347bb2010-08-19 14:51:28 -0700245 }
Winson Chung03c568e2010-08-19 17:16:59 -0700246
247 @Override
248 public boolean isChecked() {
249 return mIsChecked;
250 }
251
Patrick Dubroy5f445422011-02-18 14:35:21 -0800252 void setChecked(boolean checked, boolean animate) {
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700253 if (mIsChecked != checked) {
254 mIsChecked = checked;
255
Winson Chungcd4bc492010-12-09 18:52:32 -0800256 float alpha;
257 int duration;
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700258 if (mIsChecked) {
Winson Chung59e1f9a2010-12-21 11:31:54 -0800259 alpha = mCheckedAlpha;
260 duration = mCheckedFadeInDuration;
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700261 } else {
Winson Chungcd4bc492010-12-09 18:52:32 -0800262 alpha = 1.0f;
Winson Chung59e1f9a2010-12-21 11:31:54 -0800263 duration = mCheckedFadeOutDuration;
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700264 }
265
Winson Chungcd4bc492010-12-09 18:52:32 -0800266 // Initialize the animator
267 if (mCheckedAlphaAnimator != null) {
268 mCheckedAlphaAnimator.cancel();
269 }
Patrick Dubroy5f445422011-02-18 14:35:21 -0800270 if (animate) {
271 mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha);
272 mCheckedAlphaAnimator.setDuration(duration);
273 mCheckedAlphaAnimator.start();
274 } else {
275 setAlpha(alpha);
276 }
Winson Chungcd4bc492010-12-09 18:52:32 -0800277
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700278 invalidate();
279 }
Winson Chung03c568e2010-08-19 17:16:59 -0700280 }
281
282 @Override
Patrick Dubroy5f445422011-02-18 14:35:21 -0800283 public void setChecked(boolean checked) {
284 setChecked(checked, true);
285 }
286
287 @Override
Winson Chung03c568e2010-08-19 17:16:59 -0700288 public void toggle() {
289 setChecked(!mIsChecked);
290 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700291}