OSDN Git Service

Add WidgetsAndMore bottom sheet
[android-x86/packages-apps-Launcher3.git] / src / com / android / launcher3 / widget / WidgetCell.java
1 /*
2  * Copyright (C) 2015 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.launcher3.widget;
18
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.os.CancellationSignal;
22 import android.util.AttributeSet;
23 import android.util.Log;
24 import android.view.MotionEvent;
25 import android.view.View;
26 import android.view.View.OnLayoutChangeListener;
27 import android.view.ViewGroup;
28 import android.view.ViewPropertyAnimator;
29 import android.widget.LinearLayout;
30 import android.widget.TextView;
31
32 import com.android.launcher3.BaseActivity;
33 import com.android.launcher3.DeviceProfile;
34 import com.android.launcher3.R;
35 import com.android.launcher3.SimpleOnStylusPressListener;
36 import com.android.launcher3.StylusEventHelper;
37 import com.android.launcher3.WidgetPreviewLoader;
38 import com.android.launcher3.graphics.DrawableFactory;
39 import com.android.launcher3.model.WidgetItem;
40
41 /**
42  * Represents the individual cell of the widget inside the widget tray. The preview is drawn
43  * horizontally centered, and scaled down if needed.
44  *
45  * This view does not support padding. Since the image is scaled down to fit the view, padding will
46  * further decrease the scaling factor. Drag-n-drop uses the view bounds for showing a smooth
47  * transition from the view to drag view, so when adding padding support, DnD would need to
48  * consider the appropriate scaling factor.
49  */
50 public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
51
52     private static final String TAG = "WidgetCell";
53     private static final boolean DEBUG = false;
54
55     private static final int FADE_IN_DURATION_MS = 90;
56
57     /** Widget cell width is calculated by multiplying this factor to grid cell width. */
58     private static final float WIDTH_SCALE = 2.6f;
59
60     /** Widget preview width is calculated by multiplying this factor to the widget cell width. */
61     private static final float PREVIEW_SCALE = 0.8f;
62
63     protected int mPresetPreviewSize;
64     private int mCellSize;
65
66     private WidgetImageView mWidgetImage;
67     private TextView mWidgetName;
68     private TextView mWidgetDims;
69
70     protected WidgetItem mItem;
71
72     private WidgetPreviewLoader mWidgetPreviewLoader;
73     private StylusEventHelper mStylusEventHelper;
74
75     protected CancellationSignal mActiveRequest;
76     private boolean mAnimatePreview = true;
77
78     protected final BaseActivity mActivity;
79
80     public WidgetCell(Context context) {
81         this(context, null);
82     }
83
84     public WidgetCell(Context context, AttributeSet attrs) {
85         this(context, attrs, 0);
86     }
87
88     public WidgetCell(Context context, AttributeSet attrs, int defStyle) {
89         super(context, attrs, defStyle);
90
91         mActivity = BaseActivity.fromContext(context);
92         mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
93
94         setContainerWidth();
95         setWillNotDraw(false);
96         setClipToPadding(false);
97         setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
98     }
99
100     private void setContainerWidth() {
101         DeviceProfile profile = mActivity.getDeviceProfile();
102         mCellSize = (int) (profile.cellWidthPx * WIDTH_SCALE);
103         mPresetPreviewSize = (int) (mCellSize * PREVIEW_SCALE);
104     }
105
106     @Override
107     protected void onFinishInflate() {
108         super.onFinishInflate();
109
110         mWidgetImage = (WidgetImageView) findViewById(R.id.widget_preview);
111         mWidgetName = ((TextView) findViewById(R.id.widget_name));
112         mWidgetDims = ((TextView) findViewById(R.id.widget_dims));
113     }
114
115     /**
116      * Called to clear the view and free attached resources. (e.g., {@link Bitmap}
117      */
118     public void clear() {
119         if (DEBUG) {
120             Log.d(TAG, "reset called on:" + mWidgetName.getText());
121         }
122         mWidgetImage.animate().cancel();
123         mWidgetImage.setBitmap(null, null);
124         mWidgetName.setText(null);
125         mWidgetDims.setText(null);
126
127         if (mActiveRequest != null) {
128             mActiveRequest.cancel();
129             mActiveRequest = null;
130         }
131     }
132
133     public void applyFromCellItem(WidgetItem item, WidgetPreviewLoader loader) {
134         mItem = item;
135         mWidgetName.setText(mItem.label);
136         mWidgetDims.setText(getContext().getString(R.string.widget_dims_format,
137                 mItem.spanX, mItem.spanY));
138         mWidgetDims.setContentDescription(getContext().getString(
139                 R.string.widget_accessible_dims_format, mItem.spanX, mItem.spanY));
140         mWidgetPreviewLoader = loader;
141
142         if (item.activityInfo != null) {
143             setTag(new PendingAddShortcutInfo(item.activityInfo));
144         } else {
145             setTag(new PendingAddWidgetInfo(item.widgetInfo));
146         }
147     }
148
149     public WidgetImageView getWidgetView() {
150         return mWidgetImage;
151     }
152
153     public void setAnimatePreview(boolean shouldAnimate) {
154         mAnimatePreview = shouldAnimate;
155     }
156
157     public void applyPreview(Bitmap bitmap) {
158         if (bitmap != null) {
159             mWidgetImage.setBitmap(bitmap,
160                     DrawableFactory.get(getContext()).getBadgeForUser(mItem.user, getContext()));
161             if (mAnimatePreview) {
162                 mWidgetImage.setAlpha(0f);
163                 ViewPropertyAnimator anim = mWidgetImage.animate();
164                 anim.alpha(1.0f).setDuration(FADE_IN_DURATION_MS);
165             } else {
166                 mWidgetImage.setAlpha(1f);
167             }
168         }
169     }
170
171     public void ensurePreview() {
172         if (mActiveRequest != null) {
173             return;
174         }
175         mActiveRequest = mWidgetPreviewLoader.getPreview(
176                 mItem, mPresetPreviewSize, mPresetPreviewSize, this);
177     }
178
179     @Override
180     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
181             int oldTop, int oldRight, int oldBottom) {
182         removeOnLayoutChangeListener(this);
183         ensurePreview();
184     }
185
186     @Override
187     public boolean onTouchEvent(MotionEvent ev) {
188         boolean handled = super.onTouchEvent(ev);
189         if (mStylusEventHelper.onMotionEvent(ev)) {
190             return true;
191         }
192         return handled;
193     }
194
195     /**
196      * Helper method to get the string info of the tag.
197      */
198     private String getTagToString() {
199         if (getTag() instanceof PendingAddWidgetInfo ||
200                 getTag() instanceof PendingAddShortcutInfo) {
201             return getTag().toString();
202         }
203         return "";
204     }
205
206     @Override
207     public void setLayoutParams(ViewGroup.LayoutParams params) {
208         params.width = params.height = mCellSize;
209         super.setLayoutParams(params);
210     }
211
212     @Override
213     public CharSequence getAccessibilityClassName() {
214         return WidgetCell.class.getName();
215     }
216 }