blob: 4fa83dfa7e601fe4289b35d4da8d4f4a7ff76a92 [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 Jurka5f1c5092010-09-03 14:15:02 -070019import com.android.launcher2.PagedView.PagedViewIconCache;
20
Winson Chungb3347bb2010-08-19 14:51:28 -070021import android.content.Context;
Winson Chung241c3b42010-08-25 16:53:03 -070022import android.content.pm.PackageManager;
23import android.content.pm.ResolveInfo;
Winson Chungb3347bb2010-08-19 14:51:28 -070024import android.content.res.Resources;
25import 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;
28import android.graphics.PointF;
Winson Chungb3347bb2010-08-19 14:51:28 -070029import android.graphics.Rect;
30import android.graphics.Region.Op;
Winson Chung03c568e2010-08-19 17:16:59 -070031import android.graphics.drawable.Drawable;
Winson Chungb3347bb2010-08-19 14:51:28 -070032import android.util.AttributeSet;
33import android.util.DisplayMetrics;
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;
52 private boolean mIsHolographicUpdatePass;
53 private Rect mDrawableClipRect;
54
Winson Chung241c3b42010-08-25 16:53:03 -070055 private Object mIconCacheKey;
56 private PagedViewIconCache mIconCache;
57
Winson Chungb3347bb2010-08-19 14:51:28 -070058 private int mAlpha;
59 private int mHolographicAlpha;
60
Winson Chung03c568e2010-08-19 17:16:59 -070061 private boolean mIsChecked;
62
Winson Chungb3347bb2010-08-19 14:51:28 -070063 public PagedViewIcon(Context context) {
64 this(context, null);
65 }
66
67 public PagedViewIcon(Context context, AttributeSet attrs) {
68 this(context, attrs, 0);
69 }
70
71 public PagedViewIcon(Context context, AttributeSet attrs, int defStyle) {
72 super(context, attrs, defStyle);
73
74 if (sHolographicOutlineHelper == null) {
75 final Resources resources = context.getResources();
76 final DisplayMetrics metrics = resources.getDisplayMetrics();
77 final float density = metrics.density;
78 sHolographicOutlineHelper = new HolographicOutlineHelper(density);
79 }
80 mDrawableClipRect = new Rect();
81
82 setFocusable(true);
83 setBackgroundDrawable(null);
84 }
85
Winson Chung241c3b42010-08-25 16:53:03 -070086 public void applyFromApplicationInfo(ApplicationInfo info, PagedViewIconCache cache) {
87 mIconCache = cache;
88 mIconCacheKey = info;
89 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
90
91 setCompoundDrawablesWithIntrinsicBounds(null,
92 new FastBitmapDrawable(info.iconBitmap), null, null);
93 setText(info.title);
94 setTag(info);
95 }
96
97 public void applyFromResolveInfo(ResolveInfo info, PackageManager packageManager,
98 PagedViewIconCache cache) {
99 mIconCache = cache;
100 mIconCacheKey = info;
101 mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
102
103 Drawable image = info.loadIcon(packageManager);
104 image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
105 setCompoundDrawablesWithIntrinsicBounds(null, image, null, null);
106 setText(info.loadLabel(packageManager));
107 setTag(info);
108 }
109
Winson Chungb3347bb2010-08-19 14:51:28 -0700110 @Override
111 public void setAlpha(float alpha) {
112 final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha);
Winson Chungb3347bb2010-08-19 14:51:28 -0700113 final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha);
Winson Chungaffd7b42010-08-20 15:11:56 -0700114 mAlpha = (int) (viewAlpha * 255);
Winson Chungb3347bb2010-08-19 14:51:28 -0700115 mHolographicAlpha = (int) (holographicAlpha * 255);
Winson Chungb3347bb2010-08-19 14:51:28 -0700116 super.setAlpha(viewAlpha);
117 }
118
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700119 public void invalidateCheckedImage() {
120 if (mCheckedOutline != null) {
121 mCheckedOutline.recycle();
122 mCheckedOutline = null;
123 }
124 }
125
Winson Chungb3347bb2010-08-19 14:51:28 -0700126 @Override
127 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
128 super.onLayout(changed, left, top, right, bottom);
129
130 if (mHolographicOutline == null) {
131 final PointF offset = new PointF(0,
132 -(getCompoundPaddingBottom() + getCompoundPaddingTop())/2.0f);
133
134 // update the clipping rect to be used in the holographic pass below
135 getDrawingRect(mDrawableClipRect);
136 mDrawableClipRect.bottom = getPaddingTop() + getCompoundPaddingTop();
137
138 // set a flag to indicate that we are going to draw the view at full alpha with the text
139 // clipped for the generation of the holographic icon
140 mIsHolographicUpdatePass = true;
141 mHolographicOutline = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
142 Bitmap.Config.ARGB_8888);
143 mHolographicOutlineCanvas = new Canvas(mHolographicOutline);
144 mHolographicOutlineCanvas.concat(getMatrix());
145 draw(mHolographicOutlineCanvas);
Winson Chung03c568e2010-08-19 17:16:59 -0700146 sHolographicOutlineHelper.setColor(HolographicOutlineHelper.HOLOGRAPHIC_BLUE);
147 sHolographicOutlineHelper.applyOutline(mHolographicOutline, mHolographicOutlineCanvas,
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700148 HolographicOutlineHelper.DEFAULT_STROKE_WIDTH, offset);
Winson Chungb3347bb2010-08-19 14:51:28 -0700149 sHolographicOutlineHelper.applyBlur(mHolographicOutline, mHolographicOutlineCanvas);
150 mIsHolographicUpdatePass = false;
Winson Chung241c3b42010-08-25 16:53:03 -0700151 mIconCache.addOutline(mIconCacheKey, mHolographicOutline);
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700152 mHolographicOutlineCanvas = null;
Winson Chungb3347bb2010-08-19 14:51:28 -0700153 }
154 }
155
Winson Chungb3347bb2010-08-19 14:51:28 -0700156 @Override
157 protected void onDraw(Canvas canvas) {
Winson Chungaffd7b42010-08-20 15:11:56 -0700158 // draw the view itself
Winson Chungb3347bb2010-08-19 14:51:28 -0700159 if (mIsHolographicUpdatePass) {
160 // only clip to the text view (restore its alpha so that we get a proper outline)
161 canvas.save();
162 canvas.clipRect(mDrawableClipRect, Op.REPLACE);
Winson Chungaffd7b42010-08-20 15:11:56 -0700163 final float alpha = getAlpha();
164 super.setAlpha(1.0f);
Winson Chungb3347bb2010-08-19 14:51:28 -0700165 super.onDraw(canvas);
Winson Chungaffd7b42010-08-20 15:11:56 -0700166 super.setAlpha(alpha);
Winson Chungb3347bb2010-08-19 14:51:28 -0700167 canvas.restore();
168 } else {
169 if (mAlpha > 0) {
170 super.onDraw(canvas);
171 }
172 }
173
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700174 // draw any blended overlays
175 if (!mIsHolographicUpdatePass) {
176 if (mCheckedOutline == null) {
177 if (mHolographicOutline != null && mHolographicAlpha > 0) {
178 mPaint.setAlpha(mHolographicAlpha);
179 canvas.drawBitmap(mHolographicOutline, 0, 0, mPaint);
180 }
181 } else {
182 mPaint.setAlpha(255);
183 canvas.drawBitmap(mCheckedOutline, 0, 0, mPaint);
184 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700185 }
186 }
Winson Chung03c568e2010-08-19 17:16:59 -0700187
188 @Override
189 public boolean isChecked() {
190 return mIsChecked;
191 }
192
193 @Override
194 public void setChecked(boolean checked) {
Winson Chung5f2aa4e2010-08-20 14:49:25 -0700195 if (mIsChecked != checked) {
196 mIsChecked = checked;
197
198 if (mIsChecked) {
199 final PointF offset = new PointF(0,
200 -(getCompoundPaddingBottom() + getCompoundPaddingTop())/2.0f);
201
202 // set a flag to indicate that we are going to draw the view at full alpha with the text
203 // clipped for the generation of the holographic icon
204 mIsHolographicUpdatePass = true;
205 mCheckedOutline = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(),
206 Bitmap.Config.ARGB_8888);
207 mHolographicOutlineCanvas = new Canvas(mCheckedOutline);
208 mHolographicOutlineCanvas.concat(getMatrix());
209 draw(mHolographicOutlineCanvas);
210 sHolographicOutlineHelper.setColor(HolographicOutlineHelper.HOLOGRAPHIC_GREEN);
211 sHolographicOutlineHelper.applyOutline(mCheckedOutline, mHolographicOutlineCanvas,
212 HolographicOutlineHelper.DEFAULT_STROKE_WIDTH + 1.0f, offset);
213 mIsHolographicUpdatePass = false;
214 mHolographicOutlineCanvas = null;
215 } else {
216 invalidateCheckedImage();
217 }
218
219 invalidate();
220 }
Winson Chung03c568e2010-08-19 17:16:59 -0700221 }
222
223 @Override
224 public void toggle() {
225 setChecked(!mIsChecked);
226 }
Winson Chungb3347bb2010-08-19 14:51:28 -0700227}