1package com.android.launcher3.dragndrop;
2
3import android.content.Context;
4import android.graphics.Bitmap;
5import android.graphics.Canvas;
6import android.util.AttributeSet;
7import android.view.View;
8import android.widget.FrameLayout;
9import android.widget.RemoteViews;
10
11import com.android.launcher3.BaseActivity;
12import com.android.launcher3.DeviceProfile;
13import com.android.launcher3.LauncherAppWidgetProviderInfo;
14import com.android.launcher3.widget.WidgetCell;
15
16/**
17 * Extension of {@link WidgetCell} which supports generating previews from {@link RemoteViews}
18 */
19public class LivePreviewWidgetCell extends WidgetCell {
20
21    private RemoteViews mPreview;
22
23    public LivePreviewWidgetCell(Context context) {
24        this(context, null);
25    }
26
27    public LivePreviewWidgetCell(Context context, AttributeSet attrs) {
28        this(context, attrs, 0);
29    }
30
31    public LivePreviewWidgetCell(Context context, AttributeSet attrs, int defStyle) {
32        super(context, attrs, defStyle);
33    }
34
35    public void setPreview(RemoteViews view) {
36        mPreview = view;
37    }
38
39    @Override
40    public void ensurePreview() {
41        if (mPreview != null && mActiveRequest == null) {
42            Bitmap preview = generateFromRemoteViews(
43                    mActivity, mPreview, mItem.widgetInfo, mPresetPreviewSize, new int[1]);
44            if (preview != null) {
45                applyPreview(preview);
46                return;
47            }
48        }
49        super.ensurePreview();
50    }
51
52    /**
53     * Generates a bitmap by inflating {@param views}.
54     * @see com.android.launcher3.WidgetPreviewLoader#generateWidgetPreview
55     *
56     * TODO: Consider moving this to the background thread.
57     */
58    public static Bitmap generateFromRemoteViews(BaseActivity activity, RemoteViews views,
59            LauncherAppWidgetProviderInfo info, int previewSize, int[] preScaledWidthOut) {
60
61        DeviceProfile dp = activity.getDeviceProfile();
62        int viewWidth = dp.cellWidthPx * info.spanX;
63        int viewHeight = dp.cellHeightPx * info.spanY;
64
65        final View v;
66        try {
67            v = views.apply(activity, new FrameLayout(activity));
68            v.measure(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.EXACTLY),
69                    MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY));
70
71            viewWidth = v.getMeasuredWidth();
72            viewHeight = v.getMeasuredHeight();
73            v.layout(0, 0, viewWidth, viewHeight);
74        } catch (Exception e) {
75            return null;
76        }
77
78        preScaledWidthOut[0] = viewWidth;
79        final int bitmapWidth, bitmapHeight;
80        final float scale;
81        if (viewWidth > previewSize) {
82            scale = ((float) previewSize) / viewWidth;
83            bitmapWidth = previewSize;
84            bitmapHeight = (int) (viewHeight * scale);
85        } else {
86            scale = 1;
87            bitmapWidth = viewWidth;
88            bitmapHeight = viewHeight;
89        }
90
91        Bitmap preview = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
92        Canvas c = new Canvas(preview);
93        c.scale(scale, scale);
94        v.draw(c);
95        c.setBitmap(null);
96        return preview;
97    }
98}
99