1 /* 2 * Copyright (C) 2010 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.camera.ui; 18 19 import com.android.camera.R; 20 import com.android.camera.Util; 21 22 import android.app.Activity; 23 import android.content.ComponentName; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.content.pm.ActivityInfo; 27 import android.content.pm.PackageManager; 28 import android.content.pm.ResolveInfo; 29 import android.content.res.Resources; 30 import android.graphics.Bitmap; 31 import android.graphics.drawable.ColorDrawable; 32 import android.graphics.drawable.Drawable; 33 import android.net.Uri; 34 import android.view.LayoutInflater; 35 import android.view.MotionEvent; 36 import android.view.View; 37 import android.view.ViewGroup; 38 import android.view.ViewGroup.LayoutParams; 39 import android.view.WindowManager; 40 import android.widget.AdapterView; 41 import android.widget.GridView; 42 import android.widget.ImageView; 43 import android.widget.PopupWindow; 44 import android.widget.SimpleAdapter; 45 46 import java.util.ArrayList; 47 import java.util.HashMap; 48 import java.util.List; 49 import java.util.Map; 50 51 // A popup window that contains a big thumbnail and a list of apps to share. 52 public class SharePopup extends PopupWindow implements View.OnClickListener, 53 View.OnTouchListener, AdapterView.OnItemClickListener, Rotatable { 54 private static final String TAG = "SharePopup"; 55 private static final String ADAPTER_COLUMN_ICON = "icon"; 56 private Context mContext; 57 private Uri mUri; 58 private String mMimeType; 59 private ImageView mThumbnail; 60 private int mBitmapWidth; 61 private int mBitmapHeight; 62 private int mOrientation; 63 private int mActivityOrientation; 64 // A view that contains a list of application icons and the share view. 65 private View mRootView; 66 // The list of the application icons. 67 private GridView mShareList; 68 // A rotated view that contains the thumbnail and the play icon. 69 private RotateLayout mThumbnailRotateLayout; 70 private RotateLayout mGotoGalleryRotate; 71 private View mPreviewFrame; 72 private ArrayList<ComponentName> mComponent = new ArrayList<ComponentName>(); 73 private View mImageViewFrame; 74 75 private class MySimpleAdapter extends SimpleAdapter { MySimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)76 public MySimpleAdapter(Context context, List<? extends Map<String, ?>> data, 77 int resource, String[] from, int[] to) { 78 super(context, data, resource, from, to); 79 } 80 81 @Override getView(int position, View convertView, ViewGroup parent)82 public View getView(int position, View convertView, ViewGroup parent) { 83 View v = super.getView(position, convertView, parent); 84 RotateLayout r = (RotateLayout) v.findViewById(R.id.share_icon_rotate_layout); 85 r.setOrientation(mOrientation); 86 return v; 87 } 88 } 89 90 private final SimpleAdapter.ViewBinder mViewBinder = 91 new SimpleAdapter.ViewBinder() { 92 @Override 93 public boolean setViewValue(final View view, final Object data, 94 final String text) { 95 if (view instanceof ImageView) { 96 ((ImageView) view).setImageDrawable((Drawable) data); 97 return true; 98 } 99 return false; 100 } 101 }; 102 SharePopup(Activity activity, Uri uri, Bitmap bitmap, int orientation, View previewFrame)103 public SharePopup(Activity activity, Uri uri, Bitmap bitmap, int orientation, 104 View previewFrame) { 105 super(activity); 106 107 mActivityOrientation = activity.getRequestedOrientation(); 108 109 // Initialize variables 110 mContext = activity; 111 mUri = uri; 112 mMimeType = mContext.getContentResolver().getType(mUri); 113 mPreviewFrame = previewFrame; 114 LayoutInflater inflater = activity.getLayoutInflater(); 115 ViewGroup sharePopup = (ViewGroup) inflater.inflate(R.layout.share_popup, null, false); 116 // This is required because popup window is full screen. 117 sharePopup.setOnTouchListener(this); 118 mThumbnailRotateLayout = 119 (RotateLayout) sharePopup.findViewById(R.id.thumbnail_rotate_layout); 120 mShareList = (GridView) sharePopup.findViewById(R.id.share_list); 121 mThumbnail = (ImageView) sharePopup.findViewById(R.id.thumbnail); 122 mThumbnail.setImageBitmap(bitmap); 123 mImageViewFrame = 124 (View) sharePopup.findViewById(R.id.thumbnail_image_frame); 125 mImageViewFrame.setOnClickListener(this); 126 127 128 mGotoGalleryRotate = 129 (RotateLayout) sharePopup.findViewById(R.id.goto_gallery_button_rotate); 130 sharePopup.findViewById(R.id.goto_gallery_button).setOnClickListener(this); 131 132 mBitmapWidth = bitmap.getWidth(); 133 mBitmapHeight = bitmap.getHeight(); 134 135 // Show play button if this is a video thumbnail. 136 if (mMimeType.startsWith("video/")) { 137 sharePopup.findViewById(R.id.play).setVisibility(View.VISIBLE); 138 } 139 mBitmapWidth = bitmap.getWidth(); 140 mBitmapHeight = bitmap.getHeight(); 141 142 Resources res = mContext.getResources(); 143 144 // Initialize popup window size. 145 mRootView = sharePopup.findViewById(R.id.root); 146 LayoutParams params = mRootView.getLayoutParams(); 147 params.width = previewFrame.getWidth(); 148 params.height = previewFrame.getHeight(); 149 mRootView.setLayoutParams(params); 150 151 // Initialize popup window. 152 setWidth(WindowManager.LayoutParams.MATCH_PARENT); 153 setHeight(WindowManager.LayoutParams.MATCH_PARENT); 154 setBackgroundDrawable(new ColorDrawable()); 155 setContentView(sharePopup); 156 setOrientation(orientation); 157 setFocusable(true); 158 setAnimationStyle(R.style.AnimationPopup); 159 createShareMenu(); 160 } 161 setOrientation(int orientation)162 public void setOrientation(int orientation) { 163 if (isShowing()) return; 164 mOrientation = orientation; 165 166 int hPaddingRootView = mRootView.getPaddingLeft() + mRootView.getPaddingRight(); 167 int vPaddingRootView = mRootView.getPaddingTop() + mRootView.getPaddingBottom(); 168 169 // Calculate the width and the height of the thumbnail. Reserve the 170 // space for paddings. 171 float maxWidth = mPreviewFrame.getWidth() - hPaddingRootView; 172 float maxHeight = mPreviewFrame.getHeight() - vPaddingRootView; 173 // Swap the width and height if it is portrait mode. 174 if (orientation == 90 || orientation == 270) { 175 float temp = maxWidth; 176 maxWidth = maxHeight; 177 maxHeight = temp; 178 } 179 float actualAspect = maxWidth / maxHeight; 180 float desiredAspect = (float) mBitmapWidth / mBitmapHeight; 181 182 if (mMimeType.startsWith("video/")) { 183 desiredAspect = 4F / 3F; 184 mThumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP); 185 } else { 186 mThumbnail.setScaleType(ImageView.ScaleType.FIT_CENTER); 187 } 188 189 LayoutParams params = mThumbnail.getLayoutParams(); 190 if (actualAspect > desiredAspect) { 191 params.width = Math.round(maxHeight * desiredAspect); 192 params.height = Math.round(maxHeight); 193 } else { 194 params.width = Math.round(maxWidth); 195 params.height = Math.round(maxWidth / desiredAspect); 196 } 197 mThumbnail.setLayoutParams(params); 198 199 if (mThumbnailRotateLayout != null) mThumbnailRotateLayout.setOrientation(orientation); 200 201 int count = mShareList.getChildCount(); 202 for (int i = 0; i < count; i++) { 203 ViewGroup f = (ViewGroup) mShareList.getChildAt(i); 204 RotateLayout r = (RotateLayout) f.findViewById(R.id.share_icon_rotate_layout); 205 r.setOrientation(orientation); 206 } 207 208 mGotoGalleryRotate.setOrientation(orientation); 209 } 210 211 @Override showAtLocation(View parent, int gravity, int x, int y)212 public void showAtLocation(View parent, int gravity, int x, int y) { 213 super.showAtLocation(parent, gravity, x, y); 214 // Inform other popup to dismiss if exit 215 PopupManager.getInstance(mContext).notifyShowPopup(null); 216 } 217 218 @Override onClick(View v)219 public void onClick(View v) { 220 switch (v.getId()) { 221 case R.id.goto_gallery_button: 222 case R.id.thumbnail_image_frame: 223 Util.viewUri(mUri, mContext); 224 break; 225 } 226 } 227 228 @Override onTouch(View v, MotionEvent event)229 public boolean onTouch(View v, MotionEvent event) { 230 if (event.getAction() == MotionEvent.ACTION_DOWN) { 231 dismiss(); 232 return true; 233 } 234 return false; 235 } 236 createShareMenu()237 public void createShareMenu() { 238 PackageManager packageManager = mContext.getPackageManager(); 239 List<ResolveInfo> infos = packageManager.queryIntentActivities( 240 new Intent(Intent.ACTION_SEND).setType(mMimeType), 0); 241 242 ArrayList<HashMap<String, Object>> items = new ArrayList<HashMap<String, Object>>(); 243 for (ResolveInfo info : infos) { 244 ComponentName component = new ComponentName( 245 info.activityInfo.packageName, info.activityInfo.name); 246 HashMap<String, Object> map = new HashMap<String, Object>(); 247 map.put(ADAPTER_COLUMN_ICON, info.loadIcon(packageManager)); 248 items.add(map); 249 mComponent.add(component); 250 } 251 252 // On phone UI, we have to know how many icons in the grid view before 253 // the view is measured. 254 if (mActivityOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { 255 mShareList.setNumColumns(items.size()); 256 int width = mContext.getResources().getDimensionPixelSize(R.dimen.share_item_width); 257 mShareList.setColumnWidth(width); 258 } 259 260 SimpleAdapter listItemAdapter = new MySimpleAdapter(mContext, items, 261 R.layout.share_icon, 262 new String[] {ADAPTER_COLUMN_ICON}, 263 new int[] {R.id.icon}); 264 265 listItemAdapter.setViewBinder(mViewBinder); 266 mShareList.setAdapter(listItemAdapter); 267 mShareList.setOnItemClickListener(this); 268 } 269 getUri()270 public Uri getUri() { 271 return mUri; 272 } 273 274 @Override onItemClick(AdapterView<?> parent, View view, int index, long id)275 public void onItemClick(AdapterView<?> parent, View view, int index, long id) { 276 Intent intent = new Intent(Intent.ACTION_SEND); 277 intent.setType(mMimeType); 278 intent.putExtra(Intent.EXTRA_STREAM, mUri); 279 intent.setComponent(mComponent.get(index)); 280 mContext.startActivity(intent); 281 } 282 } 283