blob: e4049eb19c1adfa9d37840cddab72c42363c3967 [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 Chung59e1f9a2010-12-21 11:31:54 -080023import android.content.res.Resources;
Winson Chung64a3cd42010-09-17 16:47:33 -070024import android.content.res.TypedArray;
Winson Chungb3347bb2010-08-19 14:51:28 -070025import android.graphics.Bitmap;
Winson Chungb3347bb2010-08-19 14:51:28 -070026import android.graphics.Canvas;
Winson Chungb3347bb2010-08-19 14:51:28 -070027import android.graphics.Paint;
Michael Jurka0620bec2010-10-25 17:50:09 -070028import android.os.Handler;
29import android.os.HandlerThread;
30import android.os.Message;
Winson Chungb3347bb2010-08-19 14:51:28 -070031import android.util.AttributeSet;
Winson Chung03c568e2010-08-19 17:16:59 -070032import android.widget.Checkable;
Winson Chungb3347bb2010-08-19 14:51:28 -070033
Winson Chungc84001e2010-11-09 12:20:57 -080034import 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 */
Michael Jurka67b2f6c2010-11-17 12:33:46 -080043public class PagedViewIcon extends CacheableTextView 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 Chung241c3b42010-08-25 16:53:03 -070053 private Object mIconCacheKey;
54 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 Jurka0620bec2010-10-25 17:50:09 -070069 private static final HandlerThread sWorkerThread = new HandlerThread("pagedviewicon-helper");
70 static {
71 sWorkerThread.start();
72 }
73
74 private static final int MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE = 1;
75
76 private static final Handler sWorker = new Handler(sWorkerThread.getLooper()) {
77 private DeferredHandler mHandler = new DeferredHandler();
78 private Paint mPaint = new Paint();
79 public void handleMessage(Message msg) {
80 final PagedViewIcon icon = (PagedViewIcon) msg.obj;
81
82 final Bitmap holographicOutline = Bitmap.createBitmap(
83 icon.mIcon.getWidth(), icon.mIcon.getHeight(), Bitmap.Config.ARGB_8888);
84 Canvas holographicOutlineCanvas = new Canvas(holographicOutline);
85 holographicOutlineCanvas.drawBitmap(icon.mIcon, 0, 0, mPaint);
86
Adam Cohen5bb50bd2010-12-03 11:39:55 -080087 sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(holographicOutline,
Michael Jurka0620bec2010-10-25 17:50:09 -070088 holographicOutlineCanvas, icon.mHoloBlurColor, icon.mHoloOutlineColor);
89
90 mHandler.post(new Runnable() {
91 public void run() {
92 icon.mHolographicOutline = holographicOutline;
93 icon.mIconCache.addOutline(icon.mIconCacheKey, holographicOutline);
94 icon.invalidate();
95 }
96 });
97 }
98 };
Winson Chung64a3cd42010-09-17 16:47:33 -070099
Winson Chungb3347bb2010-08-19 14:51:28 -0700100 public PagedViewIcon(Context context) {
101 this(context, null);
102 }
103
104 public PagedViewIcon(Context context, AttributeSet attrs) {
105 this(context, attrs, 0);
106 }
107
108 public PagedViewIcon(Context context, AttributeSet attrs, int defStyle) {
109 super(context, attrs, defStyle);
Winson Chung29d6fea2010-12-01 15:47:31 -0800110
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);
Winson Chung64a3cd42010-09-17 16:47:33 -0700114 a.recycle();
Winson Chungb3347bb2010-08-19 14:51:28 -0700115
116 if (sHolographicOutlineHelper == null) {
Winson Chung64a3cd42010-09-17 16:47:33 -0700117 sHolographicOutlineHelper = new HolographicOutlineHelper();
Winson Chungb3347bb2010-08-19 14:51:28 -0700118 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700119
Winson Chung59e1f9a2010-12-21 11:31:54 -0800120 // Set up fade in/out constants
121 final Resources r = context.getResources();
122 final int alpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha);
123 if (alpha > 0) {
124 mCheckedAlpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha) / 256.0f;
125 mCheckedFadeInDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeInTime);
126 mCheckedFadeOutDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeOutTime);
127 }
128
Winson Chungb3347bb2010-08-19 14:51:28 -0700129 setFocusable(true);
130 setBackgroundDrawable(null);
131 }
132
Michael Jurka0620bec2010-10-25 17:50:09 -0700133 private void queueHolographicOutlineCreation() {
134 // Generate the outline in the background
135 if (mHolographicOutline == null) {
136 Message m = sWorker.obtainMessage(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE);
137 m.obj = this;
138 sWorker.sendMessage(m);
139 }
140 }
141
Winson Chungdf4b83d2010-10-20 17:49:27 -0700142 public void applyFromApplicationInfo(ApplicationInfo info, PagedViewIconCache cache,
143 boolean scaleUp) {
Winson Chung241c3b42010-08-25 16:53:03 -0700144 mIconCache = cache;
145 mIconCacheKey = info;
146 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
147
Michael Jurkac9a96192010-11-01 11:52:08 -0700148 mIcon = info.iconBitmap;
Michael Jurka0620bec2010-10-25 17:50:09 -0700149 setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700150 setText(info.title);
Michael Jurka67b2f6c2010-11-17 12:33:46 -0800151 buildAndEnableCache();
Winson Chung241c3b42010-08-25 16:53:03 -0700152 setTag(info);
Michael Jurka0620bec2010-10-25 17:50:09 -0700153
154 queueHolographicOutlineCreation();
Winson Chung241c3b42010-08-25 16:53:03 -0700155 }
156
157 public void applyFromResolveInfo(ResolveInfo info, PackageManager packageManager,
Michael Jurkac9a96192010-11-01 11:52:08 -0700158 PagedViewIconCache cache, IconCache modelIconCache) {
Winson Chung241c3b42010-08-25 16:53:03 -0700159 mIconCache = cache;
160 mIconCacheKey = info;
161 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
162
Michael Jurkac9a96192010-11-01 11:52:08 -0700163 mIcon = Utilities.createIconBitmap(
164 modelIconCache.getFullResIcon(info, packageManager), mContext);
Michael Jurka0620bec2010-10-25 17:50:09 -0700165 setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700166 setText(info.loadLabel(packageManager));
Michael Jurka67b2f6c2010-11-17 12:33:46 -0800167 buildAndEnableCache();
Winson Chung241c3b42010-08-25 16:53:03 -0700168 setTag(info);
Michael Jurka0620bec2010-10-25 17:50:09 -0700169
170 queueHolographicOutlineCreation();
Winson Chung241c3b42010-08-25 16:53:03 -0700171 }
172
Winson Chungb3347bb2010-08-19 14:51:28 -0700173 @Override
174 public void setAlpha(float alpha) {
175 final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha);
Winson Chungb3347bb2010-08-19 14:51:28 -0700176 final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha);
Winson Chunge22a8e92010-11-12 13:40:58 -0800177 int newViewAlpha = (int) (viewAlpha * 255);
178 int newHolographicAlpha = (int) (holographicAlpha * 255);
179 if ((mAlpha != newViewAlpha) || (mHolographicAlpha != newHolographicAlpha)) {
180 mAlpha = newViewAlpha;
181 mHolographicAlpha = newHolographicAlpha;
182 super.setAlpha(viewAlpha);
183 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700184 }
185
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700186 public void invalidateCheckedImage() {
187 if (mCheckedOutline != null) {
188 mCheckedOutline.recycle();
189 mCheckedOutline = null;
190 }
191 }
192
Winson Chungb3347bb2010-08-19 14:51:28 -0700193 @Override
Michael Jurka0620bec2010-10-25 17:50:09 -0700194 protected void onDraw(Canvas canvas) {
195 if (mAlpha > 0) {
196 super.onDraw(canvas);
197 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700198
Michael Jurka0620bec2010-10-25 17:50:09 -0700199 Bitmap overlay = null;
Winson Chungb3347bb2010-08-19 14:51:28 -0700200
Michael Jurka0620bec2010-10-25 17:50:09 -0700201 // draw any blended overlays
202 if (mCheckedOutline == null) {
203 if (mHolographicOutline != null && mHolographicAlpha > 0) {
204 mPaint.setAlpha(mHolographicAlpha);
205 overlay = mHolographicOutline;
206 }
207 } else {
208 mPaint.setAlpha(255);
209 overlay = mCheckedOutline;
210 }
211
212 if (overlay != null) {
Winson Chungc84001e2010-11-09 12:20:57 -0800213 final int offset = getScrollX();
Michael Jurka0620bec2010-10-25 17:50:09 -0700214 final int compoundPaddingLeft = getCompoundPaddingLeft();
215 final int compoundPaddingRight = getCompoundPaddingRight();
216 int hspace = getWidth() - compoundPaddingRight - compoundPaddingLeft;
217 canvas.drawBitmap(overlay,
Winson Chungc84001e2010-11-09 12:20:57 -0800218 offset + compoundPaddingLeft + (hspace - overlay.getWidth()) / 2,
Michael Jurka0620bec2010-10-25 17:50:09 -0700219 mPaddingTop,
220 mPaint);
Winson Chungb3347bb2010-08-19 14:51:28 -0700221 }
222 }
223
Winson Chungb3347bb2010-08-19 14:51:28 -0700224 @Override
Michael Jurka0620bec2010-10-25 17:50:09 -0700225 public void onDetachedFromWindow() {
226 super.onDetachedFromWindow();
227 sWorker.removeMessages(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE, this);
Winson Chungb3347bb2010-08-19 14:51:28 -0700228 }
Winson Chung03c568e2010-08-19 17:16:59 -0700229
230 @Override
231 public boolean isChecked() {
232 return mIsChecked;
233 }
234
235 @Override
236 public void setChecked(boolean checked) {
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700237 if (mIsChecked != checked) {
238 mIsChecked = checked;
239
Winson Chungcd4bc492010-12-09 18:52:32 -0800240 float alpha;
241 int duration;
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700242 if (mIsChecked) {
Winson Chung59e1f9a2010-12-21 11:31:54 -0800243 alpha = mCheckedAlpha;
244 duration = mCheckedFadeInDuration;
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700245 } else {
Winson Chungcd4bc492010-12-09 18:52:32 -0800246 alpha = 1.0f;
Winson Chung59e1f9a2010-12-21 11:31:54 -0800247 duration = mCheckedFadeOutDuration;
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700248 }
249
Winson Chungcd4bc492010-12-09 18:52:32 -0800250 // Initialize the animator
251 if (mCheckedAlphaAnimator != null) {
252 mCheckedAlphaAnimator.cancel();
253 }
Winson Chung88127032010-12-13 12:11:33 -0800254 mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha);
Winson Chungcd4bc492010-12-09 18:52:32 -0800255 mCheckedAlphaAnimator.setDuration(duration);
256 mCheckedAlphaAnimator.start();
257
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700258 invalidate();
259 }
Winson Chung03c568e2010-08-19 17:16:59 -0700260 }
261
262 @Override
263 public void toggle() {
264 setChecked(!mIsChecked);
265 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700266}