PagedViewIcon.java revision 3b823cd9e22c805653121b43288ac12e6c06b64c
1/*
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;
20import android.content.pm.PackageManager;
21import android.content.pm.ResolveInfo;
22import android.content.res.TypedArray;
23import android.graphics.Bitmap;
24import android.graphics.Canvas;
25import android.graphics.Paint;
26import android.os.Handler;
27import android.os.HandlerThread;
28import android.os.Message;
29import android.util.AttributeSet;
30import android.widget.Checkable;
31import android.widget.TextView;
32
33import com.android.launcher.R;
34import com.android.launcher2.PagedView.PagedViewIconCache;
35
36
37
38/**
39 * An icon on a PagedView, specifically for items in the launcher's paged view (with compound
40 * drawables on the top).
41 */
42public class PagedViewIcon extends CacheableTextView implements Checkable {
43    private static final String TAG = "PagedViewIcon";
44
45    // holographic outline
46    private final Paint mPaint = new Paint();
47    private static HolographicOutlineHelper sHolographicOutlineHelper;
48    private Bitmap mCheckedOutline;
49    private Bitmap mHolographicOutline;
50    private Bitmap mIcon;
51
52    private Object mIconCacheKey;
53    private PagedViewIconCache mIconCache;
54
55    private int mAlpha;
56    private int mHolographicAlpha;
57
58    private boolean mIsChecked;
59
60    // Highlight colors
61    private int mHoloBlurColor;
62    private int mHoloOutlineColor;
63    private int mCheckedBlurColor;
64    private int mCheckedOutlineColor;
65
66    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.applyThickExpensiveOutlineWithBlur(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    };
96
97    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);
107
108        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedViewIcon, defStyle, 0);
109	mAlpha = 255;
110        mHoloBlurColor = a.getColor(R.styleable.PagedViewIcon_blurColor, 0);
111        mHoloOutlineColor = a.getColor(R.styleable.PagedViewIcon_outlineColor, 0);
112        mCheckedBlurColor = a.getColor(R.styleable.PagedViewIcon_checkedBlurColor, 0);
113        mCheckedOutlineColor = a.getColor(R.styleable.PagedViewIcon_checkedOutlineColor, 0);
114        a.recycle();
115
116        if (sHolographicOutlineHelper == null) {
117            sHolographicOutlineHelper = new HolographicOutlineHelper();
118        }
119
120        setFocusable(true);
121        setBackgroundDrawable(null);
122    }
123
124    private void queueHolographicOutlineCreation() {
125        /* Temporarily disabling holographic outline creation.
126        // Generate the outline in the background
127        if (mHolographicOutline == null) {
128            Message m = sWorker.obtainMessage(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE);
129            m.obj = this;
130            sWorker.sendMessage(m);
131        }
132        */
133    }
134
135    public void applyFromApplicationInfo(ApplicationInfo info, PagedViewIconCache cache,
136            boolean scaleUp) {
137        mIconCache = cache;
138        mIconCacheKey = info;
139        mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
140
141        mIcon = info.iconBitmap;
142        setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
143        setText(info.title);
144        buildAndEnableCache();
145        setTag(info);
146
147        queueHolographicOutlineCreation();
148    }
149
150    public void applyFromResolveInfo(ResolveInfo info, PackageManager packageManager,
151            PagedViewIconCache cache, IconCache modelIconCache) {
152        mIconCache = cache;
153        mIconCacheKey = info;
154        mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
155
156        mIcon = Utilities.createIconBitmap(
157                modelIconCache.getFullResIcon(info, packageManager), mContext);
158        setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
159        setText(info.loadLabel(packageManager));
160        buildAndEnableCache();
161        setTag(info);
162
163        queueHolographicOutlineCreation();
164    }
165
166    @Override
167    public void setAlpha(float alpha) {
168        final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha);
169        final float holographicAlpha = sHolographicOutlineHelper.highlightAlphaInterpolator(alpha);
170        int newViewAlpha = (int) (viewAlpha * 255);
171        int newHolographicAlpha = (int) (holographicAlpha * 255);
172        if ((mAlpha != newViewAlpha) || (mHolographicAlpha != newHolographicAlpha)) {
173            mAlpha = newViewAlpha;
174            mHolographicAlpha = newHolographicAlpha;
175            super.setAlpha(viewAlpha);
176        }
177    }
178
179    public void invalidateCheckedImage() {
180        if (mCheckedOutline != null) {
181            mCheckedOutline.recycle();
182            mCheckedOutline = null;
183        }
184    }
185
186    @Override
187    protected void onDraw(Canvas canvas) {
188        if (mAlpha > 0) {
189            super.onDraw(canvas);
190        }
191
192        Bitmap overlay = null;
193
194        // draw any blended overlays
195        if (mCheckedOutline == null) {
196            if (mHolographicOutline != null && mHolographicAlpha > 0) {
197                mPaint.setAlpha(mHolographicAlpha);
198                overlay = mHolographicOutline;
199            }
200        } else {
201            mPaint.setAlpha(255);
202            overlay = mCheckedOutline;
203        }
204
205        if (overlay != null) {
206            final int offset = getScrollX();
207            final int compoundPaddingLeft = getCompoundPaddingLeft();
208            final int compoundPaddingRight = getCompoundPaddingRight();
209            int hspace = getWidth() - compoundPaddingRight - compoundPaddingLeft;
210            canvas.drawBitmap(overlay,
211                    offset + compoundPaddingLeft + (hspace - overlay.getWidth()) / 2,
212                    mPaddingTop,
213                    mPaint);
214        }
215    }
216
217    @Override
218    public void onDetachedFromWindow() {
219        super.onDetachedFromWindow();
220        sWorker.removeMessages(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE, this);
221    }
222
223    @Override
224    public boolean isChecked() {
225        return mIsChecked;
226    }
227
228    @Override
229    public void setChecked(boolean checked) {
230        if (mIsChecked != checked) {
231            mIsChecked = checked;
232
233            if (mIsChecked) {
234                mCheckedOutline = Bitmap.createBitmap(mIcon.getWidth(), mIcon.getHeight(),
235                        Bitmap.Config.ARGB_8888);
236                Canvas checkedOutlineCanvas = new Canvas(mCheckedOutline);
237                mPaint.setAlpha(255);
238                checkedOutlineCanvas.drawBitmap(mIcon, 0, 0, mPaint);
239
240                sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(mCheckedOutline,
241                        checkedOutlineCanvas, mCheckedBlurColor, mCheckedOutlineColor);
242            } else {
243                invalidateCheckedImage();
244            }
245
246            invalidate();
247        }
248    }
249
250    @Override
251    public void toggle() {
252        setChecked(!mIsChecked);
253    }
254}
255