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