blob: 7ad5e4915c3ad1e824401ab60d003ad8754c157d [file] [log] [blame]
Daniel Sandler388f6792010-03-02 14:08:08 -05001/*
2 * Copyright (C) 2008 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.ComponentName;
20import android.content.Context;
21import android.content.res.Resources;
Daniel Sandler388f6792010-03-02 14:08:08 -050022import android.graphics.drawable.BitmapDrawable;
Daniel Sandler86b40542010-06-01 14:48:12 -070023import android.graphics.Bitmap;
24import android.graphics.Color;
Daniel Sandler388f6792010-03-02 14:08:08 -050025import android.util.AttributeSet;
26import android.util.Log;
27import android.view.KeyEvent;
28import android.view.ViewGroup;
Daniel Sandler388f6792010-03-02 14:08:08 -050029import android.view.LayoutInflater;
Daniel Sandler388f6792010-03-02 14:08:08 -050030import android.view.View;
Daniel Sandler388f6792010-03-02 14:08:08 -050031import android.view.animation.AnimationUtils;
32import android.view.ViewConfiguration;
Daniel Sandler388f6792010-03-02 14:08:08 -050033import android.widget.AdapterView;
34import android.widget.ImageButton;
35import android.widget.TextView;
36import android.widget.ArrayAdapter;
37import android.widget.GridView;
38import android.widget.RelativeLayout;
39
40import java.util.ArrayList;
Daniel Sandler388f6792010-03-02 14:08:08 -050041import java.util.Collections;
Daniel Sandler388f6792010-03-02 14:08:08 -050042
Romain Guyedcce092010-03-04 13:03:17 -080043import com.android.launcher.R;
Daniel Sandler388f6792010-03-02 14:08:08 -050044
45public class AllApps2D
46 extends RelativeLayout
47 implements AllAppsView,
48 AdapterView.OnItemClickListener,
49 AdapterView.OnItemLongClickListener,
50 View.OnKeyListener,
51 DragSource {
52
53 private static final String TAG = "Launcher.AllApps2D";
Daniel Sandler86b40542010-06-01 14:48:12 -070054 private static final boolean DEBUG = false;
Daniel Sandler388f6792010-03-02 14:08:08 -050055
56 private Launcher mLauncher;
57 private DragController mDragController;
58
59 private GridView mGrid;
60
61 private ArrayList<ApplicationInfo> mAllAppsList = new ArrayList<ApplicationInfo>();
62
Daniel Sandler73a05542010-03-09 14:45:57 -050063 // preserve compatibility with 3D all apps:
64 // 0.0 -> hidden
65 // 1.0 -> shown and opaque
66 // intermediate values -> partially shown & partially opaque
Daniel Sandler388f6792010-03-02 14:08:08 -050067 private float mZoom;
68
69 private AppsAdapter mAppsAdapter;
70
71 // ------------------------------------------------------------
Daniel Sandler73a05542010-03-09 14:45:57 -050072
73 public static class HomeButton extends ImageButton {
74 public HomeButton(Context context, AttributeSet attrs) {
75 super(context, attrs);
76 }
77 @Override
78 public View focusSearch(int direction) {
79 if (direction == FOCUS_UP) return super.focusSearch(direction);
80 return null;
81 }
82 }
Daniel Sandler388f6792010-03-02 14:08:08 -050083
84 public class AppsAdapter extends ArrayAdapter<ApplicationInfo> {
85 private final LayoutInflater mInflater;
86
87 public AppsAdapter(Context context, ArrayList<ApplicationInfo> apps) {
88 super(context, 0, apps);
89 mInflater = LayoutInflater.from(context);
90 }
91
92 @Override
93 public View getView(int position, View convertView, ViewGroup parent) {
94 final ApplicationInfo info = getItem(position);
95
96 if (convertView == null) {
97 convertView = mInflater.inflate(R.layout.application_boxed, parent, false);
98 }
99
100// if (!info.filtered) {
101// info.icon = Utilities.createIconThumbnail(info.icon, getContext());
102// info.filtered = true;
103// }
104
105 final TextView textView = (TextView) convertView;
Daniel Sandler86b40542010-06-01 14:48:12 -0700106 if (DEBUG) {
107 Log.d(TAG, "icon bitmap = " + info.iconBitmap
108 + " density = " + info.iconBitmap.getDensity());
109 }
110 info.iconBitmap.setDensity(Bitmap.DENSITY_NONE);
Daniel Sandler388f6792010-03-02 14:08:08 -0500111 textView.setCompoundDrawablesWithIntrinsicBounds(null, new BitmapDrawable(info.iconBitmap), null, null);
112 textView.setText(info.title);
113
114 return convertView;
115 }
116 }
117
118 public AllApps2D(Context context, AttributeSet attrs) {
119 super(context, attrs);
120 setVisibility(View.GONE);
121 setSoundEffectsEnabled(false);
122
123 mAppsAdapter = new AppsAdapter(getContext(), mAllAppsList);
124 mAppsAdapter.setNotifyOnChange(false);
125 }
126
127 @Override
128 protected void onFinishInflate() {
Daniel Sandler86b40542010-06-01 14:48:12 -0700129 setBackgroundColor(Color.BLACK);
Daniel Sandler388f6792010-03-02 14:08:08 -0500130
Daniel Sandlerc351eb82010-03-03 15:05:19 -0500131 try {
132 mGrid = (GridView)findViewWithTag("all_apps_2d_grid");
133 if (mGrid == null) throw new Resources.NotFoundException();
134 mGrid.setOnItemClickListener(this);
135 mGrid.setOnItemLongClickListener(this);
Daniel Sandler86b40542010-06-01 14:48:12 -0700136 mGrid.setBackgroundColor(Color.BLACK);
137 mGrid.setCacheColorHint(Color.BLACK);
Daniel Sandlerc351eb82010-03-03 15:05:19 -0500138
139 ImageButton homeButton = (ImageButton) findViewWithTag("all_apps_2d_home");
140 if (homeButton == null) throw new Resources.NotFoundException();
141 homeButton.setOnClickListener(
142 new View.OnClickListener() {
143 public void onClick(View v) {
144 mLauncher.closeAllApps(true);
145 }
146 });
147 } catch (Resources.NotFoundException e) {
148 Log.e(TAG, "Can't find necessary layout elements for AllApps2D");
149 }
Daniel Sandler388f6792010-03-02 14:08:08 -0500150
Daniel Sandlerc351eb82010-03-03 15:05:19 -0500151 setOnKeyListener(this);
Daniel Sandler388f6792010-03-02 14:08:08 -0500152 }
153
154 public AllApps2D(Context context, AttributeSet attrs, int defStyle) {
155 this(context, attrs);
156 }
157
158 public void setLauncher(Launcher launcher) {
159 mLauncher = launcher;
160 }
161
162 public boolean onKey(View v, int keyCode, KeyEvent event) {
163 if (!isVisible()) return false;
164
165 switch (keyCode) {
166 case KeyEvent.KEYCODE_BACK:
167 mLauncher.closeAllApps(true);
168 break;
169 default:
170 return false;
171 }
172
173 return true;
174 }
175
176 public void onItemClick(AdapterView parent, View v, int position, long id) {
177 ApplicationInfo app = (ApplicationInfo) parent.getItemAtPosition(position);
Joe Onoratof984e852010-03-25 09:47:45 -0700178 mLauncher.startActivitySafely(app.intent, app);
Daniel Sandler388f6792010-03-02 14:08:08 -0500179 }
180
181 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
182 if (!view.isInTouchMode()) {
183 return false;
184 }
185
186 ApplicationInfo app = (ApplicationInfo) parent.getItemAtPosition(position);
187 app = new ApplicationInfo(app);
188
189 mDragController.startDrag(view, this, app, DragController.DRAG_ACTION_COPY);
190 mLauncher.closeAllApps(true);
191
192 return true;
193 }
194
Daniel Sandler73a05542010-03-09 14:45:57 -0500195 protected void onFocusChanged(boolean gainFocus, int direction, android.graphics.Rect prev) {
196 if (gainFocus) {
197 mGrid.requestFocus();
198 }
199 }
Daniel Sandler388f6792010-03-02 14:08:08 -0500200
201 public void setDragController(DragController dragger) {
202 mDragController = dragger;
203 }
204
205 public void onDropCompleted(View target, boolean success) {
206 }
207
208 /**
209 * Zoom to the specifed level.
210 *
211 * @param zoom [0..1] 0 is hidden, 1 is open
212 */
213 public void zoom(float zoom, boolean animate) {
214// Log.d(TAG, "zooming " + ((zoom == 1.0) ? "open" : "closed"));
215 cancelLongPress();
216
217 mZoom = zoom;
218
219 if (isVisible()) {
220 getParent().bringChildToFront(this);
221 setVisibility(View.VISIBLE);
222 mGrid.setAdapter(mAppsAdapter);
223 if (animate) {
224 startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.all_apps_2d_fade_in));
225 } else {
226 onAnimationEnd();
227 }
228 } else {
229 if (animate) {
230 startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.all_apps_2d_fade_out));
231 } else {
232 onAnimationEnd();
233 }
234 }
235 }
236
237 protected void onAnimationEnd() {
238 if (!isVisible()) {
239 setVisibility(View.GONE);
240 mGrid.setAdapter(null);
241 mZoom = 0.0f;
242 } else {
243 mZoom = 1.0f;
244 }
Daniel Sandlerc351eb82010-03-03 15:05:19 -0500245
246 mLauncher.zoomed(mZoom);
Daniel Sandler388f6792010-03-02 14:08:08 -0500247 }
248
249 public boolean isVisible() {
250 return mZoom > 0.001f;
251 }
252
253 @Override
254 public boolean isOpaque() {
255 return mZoom > 0.999f;
256 }
257
258 public void setApps(ArrayList<ApplicationInfo> list) {
259 mAllAppsList.clear();
260 addApps(list);
261 }
262
263 public void addApps(ArrayList<ApplicationInfo> list) {
264// Log.d(TAG, "addApps: " + list.size() + " apps: " + list.toString());
265
266 final int N = list.size();
267
268 for (int i=0; i<N; i++) {
269 final ApplicationInfo item = list.get(i);
270 int index = Collections.binarySearch(mAllAppsList, item,
271 LauncherModel.APP_NAME_COMPARATOR);
272 if (index < 0) {
273 index = -(index+1);
274 }
275 mAllAppsList.add(index, item);
276 }
277 mAppsAdapter.notifyDataSetChanged();
278 }
279
280 public void removeApps(ArrayList<ApplicationInfo> list) {
281 final int N = list.size();
282 for (int i=0; i<N; i++) {
283 final ApplicationInfo item = list.get(i);
284 int index = findAppByComponent(mAllAppsList, item);
285 if (index >= 0) {
286 mAllAppsList.remove(index);
287 } else {
288 Log.w(TAG, "couldn't find a match for item \"" + item + "\"");
289 // Try to recover. This should keep us from crashing for now.
290 }
291 }
292 mAppsAdapter.notifyDataSetChanged();
293 }
294
Joe Onorato64e6be72010-03-05 15:05:52 -0500295 public void updateApps(ArrayList<ApplicationInfo> list) {
Daniel Sandler388f6792010-03-02 14:08:08 -0500296 // Just remove and add, because they may need to be re-sorted.
297 removeApps(list);
298 addApps(list);
299 }
300
301 private static int findAppByComponent(ArrayList<ApplicationInfo> list, ApplicationInfo item) {
302 ComponentName component = item.intent.getComponent();
303 final int N = list.size();
304 for (int i=0; i<N; i++) {
305 ApplicationInfo x = list.get(i);
306 if (x.intent.getComponent().equals(component)) {
307 return i;
308 }
309 }
310 return -1;
311 }
312
313 public void dumpState() {
314 ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList", mAllAppsList);
315 }
Romain Guy13c2e7b2010-03-10 19:45:00 -0800316
317 public void surrender() {
318 }
Daniel Sandler388f6792010-03-02 14:08:08 -0500319}
320
321