/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.softwinner.launcher.ui; import com.softwinner.launcher.IAllAppsView; import com.softwinner.launcher.ApplicationInfo; import com.softwinner.launcher.LauncherApplication; import com.softwinner.launcher.LauncherModel; import android.app.Dialog; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.drawable.BitmapDrawable; import android.graphics.Bitmap; import android.graphics.Color; import android.net.Uri; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.view.ViewGroup; import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.view.animation.AnimationUtils; import android.widget.AdapterView; import android.widget.TextView; import android.widget.ArrayAdapter; import android.widget.GridView; import android.widget.RelativeLayout; import java.util.ArrayList; import java.util.Collections; import com.softwinner.launcher.*; public class AllApps2D extends RelativeLayout implements IAllAppsView, AdapterView.OnItemClickListener, View.OnKeyListener{ private static final String TAG = "TvdLauncher"; private static final String MODULE = "AllApp2D"; private static final Boolean LOGD = false; protected Watcher mWatcher; protected GridView mGrid; private float mZoom; protected ArrayList<ApplicationInfo> mAllAppsList = new ArrayList<ApplicationInfo>(); protected AppsAdapter mAppsAdapter; private View mAddBtn; private View mUninstallBtn; protected Dialog mMenuDialog; private View.OnClickListener mMenuEvent = new View.OnClickListener(){ @Override public void onClick(View v) { View selected = mGrid.getSelectedView(); if(selected == null){ return; } int position = mGrid.getPositionForView(selected); ApplicationInfo app = (ApplicationInfo) mGrid.getItemAtPosition(position); if(v.equals(mAddBtn)){ LauncherModel.setFavoritesApp(mContext ,app.componentName, true); }else if(v.equals(mUninstallBtn)){ Uri packageURI = Uri.parse("package:" + app.componentName.getPackageName()); Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI); LauncherApplication.getLauncher().startActivity(uninstallIntent); } mMenuDialog.dismiss(); } }; /** * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * Internal Class * Class name : AppsAdapter * Public Method: * Name : * public View getView(int position, View convertView, ViewGroup parent) * Descriptor:To create text view with icon for the application */ public class AppsAdapter extends ArrayAdapter<ApplicationInfo> { private final LayoutInflater mInflater; public AppsAdapter(Context context, ArrayList<ApplicationInfo> apps) { super(context, 0, apps); mInflater = LayoutInflater.from(context); } @Override public View getView(int position, View convertView, ViewGroup parent) { final ApplicationInfo info = getItem(position); if (convertView == null) { convertView = mInflater.inflate(R.layout.application_boxed, parent, false); } final TextView textView = (TextView) convertView; if (LOGD) { Log.d(TAG, MODULE + "icon bitmap = " + info.iconBitmap + " density = " + info.iconBitmap.getDensity()); } info.iconBitmap.setDensity(Bitmap.DENSITY_NONE); textView.setCompoundDrawablesWithIntrinsicBounds(null, new BitmapDrawable(info.iconBitmap), null, null); textView.setText(info.title); return convertView; } } /** * Internal Class * ------------------------------------------------------------------------- */ public AllApps2D(Context context, AttributeSet attrs) { super(context, attrs); setVisibility(View.GONE); setSoundEffectsEnabled(false); mAppsAdapter = new AppsAdapter(getContext(), mAllAppsList); mAppsAdapter.setNotifyOnChange(false); } public AllApps2D(Context context, AttributeSet attrs, int defStyle) { this(context, attrs); } @Override protected void onFinishInflate() { try { mGrid = (GridView)findViewWithTag("all_apps_2d_grid"); if (mGrid == null) throw new Resources.NotFoundException(); mGrid.setOnItemClickListener(this); //mGrid.setBackgroundResource(R.drawable.background); mGrid.setCacheColorHint(Color.TRANSPARENT); } catch (Resources.NotFoundException e) { Log.e(TAG, MODULE + "Can't find necessary layout elements for AllApps2D"); } } @Override protected void onFocusChanged(boolean gainFocus, int direction, android.graphics.Rect prev) { if (gainFocus) { mGrid.requestFocus(); } } @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (!isVisible()) return false; switch (keyCode) { case KeyEvent.KEYCODE_BACK: break; default: return false; } return true; } @Override protected void onAnimationEnd() { if (!isVisible()) { setVisibility(View.GONE); mGrid.setAdapter(null); mZoom = 0.0f; } else { mZoom = 1.0f; } mWatcher.zoomed(mZoom); } /** * ++++++++++++++++++++++++++++++++++++++++++++++++++++++ * AllAppsView Call back interface * * function name:public void setLauncher(Launcher launcher) * description: * * function name:public boolean isVisible() * description:return whether the app view is visible * * function name:public boolean isOpaque() * description: * * function name:public void setApps(ArrayList<ApplicationInfo> list) * description:set the app from a full copy of AllAppList. * * function name:public void addApps(ArrayList<ApplicationInfo> list) * description:set the app from a added app copy of AllAppList. * * function name:public void updateApps(ArrayList<ApplicationInfo> list * description:set the app from a updated app copy of AllAppList. * * function name:public void zoom(float zoom, boolean animate) * description:start app view */ @Override public void setWatcher(Watcher watcher) { mWatcher = watcher; } public boolean isVisible() { return mZoom > 0.001f; } @Override public boolean isOpaque() { return mZoom > 0.999f; } public void setApps(ArrayList<ApplicationInfo> list) { mAllAppsList.clear(); addApps(list); } public void addApps(ArrayList<ApplicationInfo> list) { final int N = list.size(); for (int i=0; i<N; i++) { final ApplicationInfo item = list.get(i); int index = Collections.binarySearch(mAllAppsList, item, LauncherModel.APP_NAME_COMPARATOR); if (index < 0) { index = -(index+1); } mAllAppsList.add(index, item); if(LOGD) list.get(i).toString(); } mAppsAdapter.notifyDataSetChanged(); } public void removeApps(ArrayList<ApplicationInfo> list) { final int N = list.size(); for (int i=0; i<N; i++) { final ApplicationInfo item = list.get(i); int index = findAppByComponent(mAllAppsList, item); if (index >= 0) { mAllAppsList.remove(index); //if(LOGD) item.dumpItemInfo(TAG, LOGD); } else { Log.w(TAG, MODULE + "couldn't find a match for item \"" + item + "\""); // Try to recover. This should keep us from crashing for now. } } mAppsAdapter.notifyDataSetChanged(); } public void updateApps(ArrayList<ApplicationInfo> list) { // Just remove and add, because they may need to be re-sorted. removeApps(list); addApps(list); } private static int findAppByComponent(ArrayList<ApplicationInfo> list, ApplicationInfo item) { ComponentName component = item.intent.getComponent(); final int N = list.size(); for (int i=0; i<N; i++) { ApplicationInfo x = list.get(i); if (x.intent.getComponent().equals(component)) { return i; } } return -1; } /** * Zoom to the specifed level. * * @param zoom [0..1] 0 is hidden, 1 is open */ public void zoom(float zoom, boolean animate) { cancelLongPress(); mZoom = zoom; if (isVisible()) { getParent().bringChildToFront(this); setVisibility(View.VISIBLE); mGrid.setAdapter(mAppsAdapter); if (animate) { startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.all_apps_2d_fade_in)); } else { onAnimationEnd(); } } else { if (animate) { startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.all_apps_2d_fade_out)); } else { onAnimationEnd(); } } } public void dumpState() { } public void surrender() { } /** * ------------------------------------------------------------------- */ @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { if(LOGD) Log.d(TAG,MODULE + "position=" + position + " " + "id=" + id); ApplicationInfo app = (ApplicationInfo) parent.getItemAtPosition(position); LauncherApplication.getLauncher().startActivitySafely(app.intent, TAG); } public Dialog createMenuDialog(Context context,ApplicationInfo app){ Dialog dialog = new Dialog(context,R.style.menu_dialog); Window win = dialog.getWindow(); WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.y = 99999; params.x = 0; win.setAttributes(params); dialog.setCanceledOnTouchOutside(true); LayoutInflater inflater = dialog.getLayoutInflater(); View content = inflater.inflate(R.layout.all_apps_menu, null); mAddBtn = content.findViewById(R.id.add_to_favorites); mUninstallBtn = content.findViewById(R.id.uninstall_app); if(mAddBtn != null){ mAddBtn.setOnClickListener(mMenuEvent); } if(mUninstallBtn != null){ mUninstallBtn.setOnClickListener(mMenuEvent); } dialog.setContentView(content); return dialog; } @Override public void onCreateMenu() { // TODO Auto-generated method stub View selected = mGrid.getSelectedView(); if(selected == null){ return; } int position = mGrid.getPositionForView(selected); ApplicationInfo app = (ApplicationInfo) mGrid.getItemAtPosition(position); mMenuDialog = createMenuDialog(getContext(),app); mMenuDialog.show(); Window win = mMenuDialog.getWindow(); win.setWindowAnimations(R.style.menuDialogWindowAnim); } }