• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.launcher2;
18 
19 import android.animation.ObjectAnimator;
20 import android.appwidget.AppWidgetProviderInfo;
21 import android.content.Context;
22 import android.content.pm.PackageManager;
23 import android.content.pm.ResolveInfo;
24 import android.content.res.Resources;
25 import android.graphics.Bitmap;
26 import android.graphics.Canvas;
27 import android.graphics.Paint;
28 import android.graphics.RectF;
29 import android.util.AttributeSet;
30 import android.view.KeyEvent;
31 import android.view.MotionEvent;
32 import android.widget.Checkable;
33 import android.widget.ImageView;
34 import android.widget.LinearLayout;
35 import android.widget.TextView;
36 
37 import com.android.launcher.R;
38 
39 /**
40  * The linear layout used strictly for the widget/wallpaper tab of the customization tray
41  */
42 public class PagedViewWidget extends LinearLayout implements Checkable {
43     static final String TAG = "PagedViewWidgetLayout";
44 
45     private static final int sPreviewFadeInDuration = 80;
46     private static final int sPreviewFadeInStaggerDuration = 20;
47 
48     private final Paint mPaint = new Paint();
49     private Bitmap mHolographicOutline;
50     private HolographicOutlineHelper mHolographicOutlineHelper;
51     private ImageView mPreviewImageView;
52     private final RectF mTmpScaleRect = new RectF();
53 
54     private String mDimensionsFormatString;
55 
56     private int mAlpha = 255;
57     private int mHolographicAlpha;
58 
59     private boolean mIsChecked;
60     private ObjectAnimator mCheckedAlphaAnimator;
61     private float mCheckedAlpha = 1.0f;
62     private int mCheckedFadeInDuration;
63     private int mCheckedFadeOutDuration;
64 
PagedViewWidget(Context context)65     public PagedViewWidget(Context context) {
66         this(context, null);
67     }
68 
PagedViewWidget(Context context, AttributeSet attrs)69     public PagedViewWidget(Context context, AttributeSet attrs) {
70         this(context, attrs, 0);
71     }
72 
PagedViewWidget(Context context, AttributeSet attrs, int defStyle)73     public PagedViewWidget(Context context, AttributeSet attrs, int defStyle) {
74         super(context, attrs, defStyle);
75 
76         // Set up fade in/out constants
77         final Resources r = context.getResources();
78         final int alpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha);
79         if (alpha > 0) {
80             mCheckedAlpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha) / 256.0f;
81             mCheckedFadeInDuration =
82                 r.getInteger(R.integer.config_dragAppsCustomizeIconFadeInDuration);
83             mCheckedFadeOutDuration =
84                 r.getInteger(R.integer.config_dragAppsCustomizeIconFadeOutDuration);
85         }
86         mDimensionsFormatString = r.getString(R.string.widget_dims_format);
87 
88         setWillNotDraw(false);
89         setClipToPadding(false);
90     }
91 
92     @Override
onDetachedFromWindow()93     protected void onDetachedFromWindow() {
94         super.onDetachedFromWindow();
95 
96         final ImageView image = (ImageView) findViewById(R.id.widget_preview);
97         if (image != null) {
98             FastBitmapDrawable preview = (FastBitmapDrawable) image.getDrawable();
99             if (preview != null && preview.getBitmap() != null) {
100                 preview.getBitmap().recycle();
101             }
102             image.setImageDrawable(null);
103         }
104     }
105 
applyFromAppWidgetProviderInfo(AppWidgetProviderInfo info, int maxWidth, int[] cellSpan, HolographicOutlineHelper holoOutlineHelper)106     public void applyFromAppWidgetProviderInfo(AppWidgetProviderInfo info,
107             int maxWidth, int[] cellSpan, HolographicOutlineHelper holoOutlineHelper) {
108         mHolographicOutlineHelper = holoOutlineHelper;
109         final ImageView image = (ImageView) findViewById(R.id.widget_preview);
110         if (maxWidth > -1) {
111             image.setMaxWidth(maxWidth);
112         }
113         image.setContentDescription(info.label);
114         mPreviewImageView = image;
115         final TextView name = (TextView) findViewById(R.id.widget_name);
116         name.setText(info.label);
117         final TextView dims = (TextView) findViewById(R.id.widget_dims);
118         if (dims != null) {
119             dims.setText(String.format(mDimensionsFormatString, cellSpan[0], cellSpan[1]));
120         }
121     }
122 
applyFromResolveInfo(PackageManager pm, ResolveInfo info, HolographicOutlineHelper holoOutlineHelper)123     public void applyFromResolveInfo(PackageManager pm, ResolveInfo info,
124             HolographicOutlineHelper holoOutlineHelper) {
125         mHolographicOutlineHelper = holoOutlineHelper;
126         CharSequence label = info.loadLabel(pm);
127         final ImageView image = (ImageView) findViewById(R.id.widget_preview);
128         image.setContentDescription(label);
129         mPreviewImageView = image;
130         final TextView name = (TextView) findViewById(R.id.widget_name);
131         name.setText(label);
132         final TextView dims = (TextView) findViewById(R.id.widget_dims);
133         if (dims != null) {
134             dims.setText(String.format(mDimensionsFormatString, 1, 1));
135         }
136     }
137 
applyPreview(FastBitmapDrawable preview, int index, boolean scale)138     void applyPreview(FastBitmapDrawable preview, int index, boolean scale) {
139         final ImageView image = (ImageView) findViewById(R.id.widget_preview);
140         if (preview != null) {
141             image.setImageDrawable(preview);
142             image.setScaleType(scale ? ImageView.ScaleType.FIT_START : ImageView.ScaleType.MATRIX);
143             image.setAlpha(0f);
144             image.animate()
145                  .alpha(1f)
146                  .setDuration(sPreviewFadeInDuration + (index * sPreviewFadeInStaggerDuration))
147                  .start();
148         }
149     }
150 
setHolographicOutline(Bitmap holoOutline)151     public void setHolographicOutline(Bitmap holoOutline) {
152         mHolographicOutline = holoOutline;
153         invalidate();
154     }
155 
156     @Override
onTouchEvent(MotionEvent event)157     public boolean onTouchEvent(MotionEvent event) {
158         // We eat up the touch events here, since the PagedView (which uses the same swiping
159         // touch code as Workspace previously) uses onInterceptTouchEvent() to determine when
160         // the user is scrolling between pages.  This means that if the pages themselves don't
161         // handle touch events, it gets forwarded up to PagedView itself, and it's own
162         // onTouchEvent() handling will prevent further intercept touch events from being called
163         // (it's the same view in that case).  This is not ideal, but to prevent more changes,
164         // we just always mark the touch event as handled.
165         return super.onTouchEvent(event) || true;
166     }
167 
168     @Override
onKeyDown(int keyCode, KeyEvent event)169     public boolean onKeyDown(int keyCode, KeyEvent event) {
170         return FocusHelper.handleAppsCustomizeKeyEvent(this, keyCode, event)
171                 || super.onKeyDown(keyCode, event);
172     }
173 
174     @Override
onKeyUp(int keyCode, KeyEvent event)175     public boolean onKeyUp(int keyCode, KeyEvent event) {
176         return FocusHelper.handleAppsCustomizeKeyEvent(this, keyCode, event)
177                 || super.onKeyUp(keyCode, event);
178     }
179 
180     @Override
onDraw(Canvas canvas)181     protected void onDraw(Canvas canvas) {
182         if (mAlpha > 0) {
183             super.onDraw(canvas);
184         }
185 
186         // draw any blended overlays
187         if (mHolographicOutline != null && mHolographicAlpha > 0) {
188             // Calculate how much to scale the holographic preview
189             mTmpScaleRect.set(0,0,1,1);
190             mPreviewImageView.getImageMatrix().mapRect(mTmpScaleRect);
191 
192             mPaint.setAlpha(mHolographicAlpha);
193             canvas.save();
194             canvas.scale(mTmpScaleRect.right, mTmpScaleRect.bottom);
195             canvas.drawBitmap(mHolographicOutline, mPreviewImageView.getLeft(),
196                     mPreviewImageView.getTop(), mPaint);
197             canvas.restore();
198         }
199     }
200 
201     @Override
onSetAlpha(int alpha)202     protected boolean onSetAlpha(int alpha) {
203         return true;
204     }
205 
setChildrenAlpha(float alpha)206     private void setChildrenAlpha(float alpha) {
207         final int childCount = getChildCount();
208         for (int i = 0; i < childCount; i++) {
209             getChildAt(i).setAlpha(alpha);
210         }
211     }
212     @Override
setAlpha(float alpha)213     public void setAlpha(float alpha) {
214         final float viewAlpha = mHolographicOutlineHelper.viewAlphaInterpolator(alpha);
215         final float holographicAlpha = mHolographicOutlineHelper.highlightAlphaInterpolator(alpha);
216         int newViewAlpha = (int) (viewAlpha * 255);
217         int newHolographicAlpha = (int) (holographicAlpha * 255);
218         if ((mAlpha != newViewAlpha) || (mHolographicAlpha != newHolographicAlpha)) {
219             mAlpha = newViewAlpha;
220             mHolographicAlpha = newHolographicAlpha;
221             setChildrenAlpha(viewAlpha);
222             super.setAlpha(viewAlpha);
223         }
224     }
225 
setChecked(boolean checked, boolean animate)226     void setChecked(boolean checked, boolean animate) {
227         if (mIsChecked != checked) {
228             mIsChecked = checked;
229 
230             float alpha;
231             int duration;
232             if (mIsChecked) {
233                 alpha = mCheckedAlpha;
234                 duration = mCheckedFadeInDuration;
235             } else {
236                 alpha = 1.0f;
237                 duration = mCheckedFadeOutDuration;
238             }
239 
240             // Initialize the animator
241             if (mCheckedAlphaAnimator != null) {
242                 mCheckedAlphaAnimator.cancel();
243             }
244             if (animate) {
245                 mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha);
246                 mCheckedAlphaAnimator.setDuration(duration);
247                 mCheckedAlphaAnimator.start();
248             } else {
249                 setAlpha(alpha);
250             }
251 
252             invalidate();
253         }
254     }
255 
256     @Override
setChecked(boolean checked)257     public void setChecked(boolean checked) {
258         setChecked(checked, true);
259     }
260 
261     @Override
isChecked()262     public boolean isChecked() {
263         return mIsChecked;
264     }
265 
266     @Override
toggle()267     public void toggle() {
268         setChecked(!mIsChecked);
269     }
270 }
271