Home | History | Annotate | Download | only in launcher2
      1 /*
      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 
     17 package com.android.launcher2;
     18 
     19 import android.content.ComponentName;
     20 import android.content.Context;
     21 import android.content.res.Resources;
     22 import android.graphics.drawable.BitmapDrawable;
     23 import android.graphics.Bitmap;
     24 import android.graphics.Color;
     25 import android.util.AttributeSet;
     26 import android.util.Log;
     27 import android.view.KeyEvent;
     28 import android.view.ViewGroup;
     29 import android.view.LayoutInflater;
     30 import android.view.View;
     31 import android.view.animation.AnimationUtils;
     32 import android.view.ViewConfiguration;
     33 import android.widget.AdapterView;
     34 import android.widget.ImageButton;
     35 import android.widget.TextView;
     36 import android.widget.ArrayAdapter;
     37 import android.widget.GridView;
     38 import android.widget.RelativeLayout;
     39 
     40 import java.util.ArrayList;
     41 import java.util.Collections;
     42 
     43 import com.android.launcher.R;
     44 
     45 public 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";
     54     private static final boolean DEBUG = false;
     55 
     56     private Launcher mLauncher;
     57     private DragController mDragController;
     58 
     59     private GridView mGrid;
     60 
     61     private ArrayList<ApplicationInfo> mAllAppsList = new ArrayList<ApplicationInfo>();
     62 
     63     // preserve compatibility with 3D all apps:
     64     //    0.0 -> hidden
     65     //    1.0 -> shown and opaque
     66     //    intermediate values -> partially shown & partially opaque
     67     private float mZoom;
     68 
     69     private AppsAdapter mAppsAdapter;
     70 
     71     // ------------------------------------------------------------
     72 
     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     }
     83 
     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;
    106             if (DEBUG) {
    107                 Log.d(TAG, "icon bitmap = " + info.iconBitmap
    108                     + " density = " + info.iconBitmap.getDensity());
    109             }
    110             info.iconBitmap.setDensity(Bitmap.DENSITY_NONE);
    111             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() {
    129         setBackgroundColor(Color.BLACK);
    130 
    131         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);
    136             mGrid.setBackgroundColor(Color.BLACK);
    137             mGrid.setCacheColorHint(Color.BLACK);
    138 
    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         }
    150 
    151         setOnKeyListener(this);
    152     }
    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);
    178         mLauncher.startActivitySafely(app.intent, app);
    179     }
    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 
    195     protected void onFocusChanged(boolean gainFocus, int direction, android.graphics.Rect prev) {
    196         if (gainFocus) {
    197             mGrid.requestFocus();
    198         }
    199     }
    200 
    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         }
    245 
    246         mLauncher.zoomed(mZoom);
    247     }
    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 
    295     public void updateApps(ArrayList<ApplicationInfo> list) {
    296         // 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     }
    316 
    317     public void surrender() {
    318     }
    319 }
    320 
    321 
    322