blob: 50ba8d45970c528e1dd8527b16dbc1aa2fe9ac83 [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;
Michael Jurka0620bec2010-10-25 17:50:09 -070026import android.os.Handler;
27import android.os.HandlerThread;
28import android.os.Message;
Winson Chungb3347bb2010-08-19 14:51:28 -070029import android.util.AttributeSet;
Winson Chung03c568e2010-08-19 17:16:59 -070030import android.widget.Checkable;
Winson Chungb3347bb2010-08-19 14:51:28 -070031import android.widget.TextView;
32
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 */
Winson Chung03c568e2010-08-19 17:16:59 -070042public class PagedViewIcon extends TextView 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 Chungb3347bb2010-08-19 14:51:28 -070055 private int mAlpha;
56 private int mHolographicAlpha;
57
Winson Chung03c568e2010-08-19 17:16:59 -070058 private boolean mIsChecked;
59
Michael Jurkac9a96192010-11-01 11:52:08 -070060 // Highlight colors
Winson Chung64a3cd42010-09-17 16:47:33 -070061 private int mHoloBlurColor;
62 private int mHoloOutlineColor;
63 private int mCheckedBlurColor;
64 private int mCheckedOutlineColor;
65
Michael Jurka0620bec2010-10-25 17:50:09 -070066 private static final HandlerThread sWorkerThread = new HandlerThread("pagedviewicon-helper");
67 static {
68 sWorkerThread.start();
69 }
70
71 private static final int MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE = 1;
72
73 private static final Handler sWorker = new Handler(sWorkerThread.getLooper()) {
74 private DeferredHandler mHandler = new DeferredHandler();
75 private Paint mPaint = new Paint();
76 public void handleMessage(Message msg) {
77 final PagedViewIcon icon = (PagedViewIcon) msg.obj;
78
79 final Bitmap holographicOutline = Bitmap.createBitmap(
80 icon.mIcon.getWidth(), icon.mIcon.getHeight(), Bitmap.Config.ARGB_8888);
81 Canvas holographicOutlineCanvas = new Canvas(holographicOutline);
82 holographicOutlineCanvas.drawBitmap(icon.mIcon, 0, 0, mPaint);
83
84 sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(holographicOutline,
85 holographicOutlineCanvas, icon.mHoloBlurColor, icon.mHoloOutlineColor);
86
87 mHandler.post(new Runnable() {
88 public void run() {
89 icon.mHolographicOutline = holographicOutline;
90 icon.mIconCache.addOutline(icon.mIconCacheKey, holographicOutline);
91 icon.invalidate();
92 }
93 });
94 }
95 };
Winson Chung64a3cd42010-09-17 16:47:33 -070096
Winson Chungb3347bb2010-08-19 14:51:28 -070097 public PagedViewIcon(Context context) {
98 this(context, null);
99 }
100
101 public PagedViewIcon(Context context, AttributeSet attrs) {
102 this(context, attrs, 0);
103 }
104
105 public PagedViewIcon(Context context, AttributeSet attrs, int defStyle) {
106 super(context, attrs, defStyle);
Winson Chung64a3cd42010-09-17 16:47:33 -0700107 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedViewIcon, defStyle, 0);
108 mHoloBlurColor = a.getColor(R.styleable.PagedViewIcon_blurColor, 0);
109 mHoloOutlineColor = a.getColor(R.styleable.PagedViewIcon_outlineColor, 0);
110 mCheckedBlurColor = a.getColor(R.styleable.PagedViewIcon_checkedBlurColor, 0);
111 mCheckedOutlineColor = a.getColor(R.styleable.PagedViewIcon_checkedOutlineColor, 0);
Winson Chung0e41ae62010-10-27 18:10:32 -0700112
Winson Chung64a3cd42010-09-17 16:47:33 -0700113 a.recycle();
Winson Chungb3347bb2010-08-19 14:51:28 -0700114
115 if (sHolographicOutlineHelper == null) {
Winson Chung64a3cd42010-09-17 16:47:33 -0700116 sHolographicOutlineHelper = new HolographicOutlineHelper();
Winson Chungb3347bb2010-08-19 14:51:28 -0700117 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700118
119 setFocusable(true);
120 setBackgroundDrawable(null);
121 }
122
Michael Jurka0620bec2010-10-25 17:50:09 -0700123 private void queueHolographicOutlineCreation() {
124 // Generate the outline in the background
125 if (mHolographicOutline == null) {
126 Message m = sWorker.obtainMessage(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE);
127 m.obj = this;
128 sWorker.sendMessage(m);
129 }
130 }
131
Winson Chungdf4b83d2010-10-20 17:49:27 -0700132 public void applyFromApplicationInfo(ApplicationInfo info, PagedViewIconCache cache,
133 boolean scaleUp) {
Winson Chung241c3b42010-08-25 16:53:03 -0700134 mIconCache = cache;
135 mIconCacheKey = info;
136 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
137
Michael Jurkac9a96192010-11-01 11:52:08 -0700138 mIcon = info.iconBitmap;
Michael Jurka0620bec2010-10-25 17:50:09 -0700139 setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700140 setText(info.title);
141 setTag(info);
Michael Jurka0620bec2010-10-25 17:50:09 -0700142
143 queueHolographicOutlineCreation();
Winson Chung241c3b42010-08-25 16:53:03 -0700144 }
145
146 public void applyFromResolveInfo(ResolveInfo info, PackageManager packageManager,
Michael Jurkac9a96192010-11-01 11:52:08 -0700147 PagedViewIconCache cache, IconCache modelIconCache) {
Winson Chung241c3b42010-08-25 16:53:03 -0700148 mIconCache = cache;
149 mIconCacheKey = info;
150 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
151
Michael Jurkac9a96192010-11-01 11:52:08 -0700152 mIcon = Utilities.createIconBitmap(
153 modelIconCache.getFullResIcon(info, packageManager), mContext);
Michael Jurka0620bec2010-10-25 17:50:09 -0700154 setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
Winson Chung241c3b42010-08-25 16:53:03 -0700155 setText(info.loadLabel(packageManager));
156 setTag(info);
Michael Jurka0620bec2010-10-25 17:50:09 -0700157
158 queueHolographicOutlineCreation();
Winson Chung241c3b42010-08-25 16:53:03 -0700159 }
160
Winson Chungb3347bb2010-08-19 14:51:28 -0700161 @Override
162 public void setAlpha(float alpha) {
163 final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha);
Winson Chungb3347bb2010-08-19 14:51:28 -0700164 final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha);
Winson Chungaffd7b42010-08-20 15:11:56 -0700165 mAlpha = (int) (viewAlpha * 255);
Winson Chungb3347bb2010-08-19 14:51:28 -0700166 mHolographicAlpha = (int) (holographicAlpha * 255);
Winson Chungb3347bb2010-08-19 14:51:28 -0700167 super.setAlpha(viewAlpha);
168 }
169
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700170 public void invalidateCheckedImage() {
171 if (mCheckedOutline != null) {
172 mCheckedOutline.recycle();
173 mCheckedOutline = null;
174 }
175 }
176
Winson Chungb3347bb2010-08-19 14:51:28 -0700177 @Override
Michael Jurka0620bec2010-10-25 17:50:09 -0700178 protected void onDraw(Canvas canvas) {
179 if (mAlpha > 0) {
180 super.onDraw(canvas);
181 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700182
Michael Jurka0620bec2010-10-25 17:50:09 -0700183 Bitmap overlay = null;
Winson Chungb3347bb2010-08-19 14:51:28 -0700184
Michael Jurka0620bec2010-10-25 17:50:09 -0700185 // draw any blended overlays
186 if (mCheckedOutline == null) {
187 if (mHolographicOutline != null && mHolographicAlpha > 0) {
188 mPaint.setAlpha(mHolographicAlpha);
189 overlay = mHolographicOutline;
190 }
191 } else {
192 mPaint.setAlpha(255);
193 overlay = mCheckedOutline;
194 }
195
196 if (overlay != null) {
Winson Chungc84001e2010-11-09 12:20:57 -0800197 final int offset = getScrollX();
Michael Jurka0620bec2010-10-25 17:50:09 -0700198 final int compoundPaddingLeft = getCompoundPaddingLeft();
199 final int compoundPaddingRight = getCompoundPaddingRight();
200 int hspace = getWidth() - compoundPaddingRight - compoundPaddingLeft;
201 canvas.drawBitmap(overlay,
Winson Chungc84001e2010-11-09 12:20:57 -0800202 offset + compoundPaddingLeft + (hspace - overlay.getWidth()) / 2,
Michael Jurka0620bec2010-10-25 17:50:09 -0700203 mPaddingTop,
204 mPaint);
Winson Chungb3347bb2010-08-19 14:51:28 -0700205 }
206 }
207
Winson Chungb3347bb2010-08-19 14:51:28 -0700208 @Override
Michael Jurka0620bec2010-10-25 17:50:09 -0700209 public void onDetachedFromWindow() {
210 super.onDetachedFromWindow();
211 sWorker.removeMessages(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE, this);
Winson Chungb3347bb2010-08-19 14:51:28 -0700212 }
Winson Chung03c568e2010-08-19 17:16:59 -0700213
214 @Override
215 public boolean isChecked() {
216 return mIsChecked;
217 }
218
219 @Override
220 public void setChecked(boolean checked) {
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700221 if (mIsChecked != checked) {
222 mIsChecked = checked;
223
224 if (mIsChecked) {
Michael Jurka0620bec2010-10-25 17:50:09 -0700225 mCheckedOutline = Bitmap.createBitmap(mIcon.getWidth(), mIcon.getHeight(),
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700226 Bitmap.Config.ARGB_8888);
Michael Jurka0620bec2010-10-25 17:50:09 -0700227 Canvas checkedOutlineCanvas = new Canvas(mCheckedOutline);
228 mPaint.setAlpha(255);
229 checkedOutlineCanvas.drawBitmap(mIcon, 0, 0, mPaint);
230
Winson Chung64a3cd42010-09-17 16:47:33 -0700231 sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(mCheckedOutline,
Michael Jurka0620bec2010-10-25 17:50:09 -0700232 checkedOutlineCanvas, mCheckedBlurColor, mCheckedOutlineColor);
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700233 } else {
234 invalidateCheckedImage();
235 }
236
237 invalidate();
238 }
Winson Chung03c568e2010-08-19 17:16:59 -0700239 }
240
241 @Override
242 public void toggle() {
243 setChecked(!mIsChecked);
244 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700245}