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.PackageManager; 27 import android.content.pm.ResolveInfo; 28 import android.content.res.Resources; 29 import android.graphics.Bitmap; 30 import android.graphics.drawable.ColorDrawable; 31 import android.graphics.drawable.Drawable; 32 import android.net.Uri; 33 import android.view.LayoutInflater; 34 import android.view.MotionEvent; 35 import android.view.View; 36 import android.view.ViewGroup; 37 import android.view.ViewGroup.LayoutParams; 38 import android.view.WindowManager; 39 import android.widget.AdapterView; 40 import android.widget.ImageView; 41 import android.widget.ListView; 42 import android.widget.PopupWindow; 43 import android.widget.RelativeLayout; 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 { 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 // A view that contains a thumbnail and an arrow icon. 64 private ViewGroup mShareView; 65 // A view that contains a list of application icons and the share view. 66 private View mRootView; 67 // The list of the application icons. 68 private ListView mShareList; 69 // A rotated view that contains the thumbnail. 70 private RotateLayout mThumbnailRotateLayout; 71 private RotateLayout mGotoGalleryRotate; 72 private View mPreviewFrame; 73 private ArrayList<ComponentName> mComponent = new ArrayList<ComponentName>(); 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 // Initialize variables 108 mContext = activity; 109 mUri = uri; 110 mMimeType = mContext.getContentResolver().getType(mUri); 111 mPreviewFrame = previewFrame; 112 LayoutInflater inflater = activity.getLayoutInflater(); 113 ViewGroup sharePopup = (ViewGroup) inflater.inflate(R.layout.share_popup, null, false); 114 // This is required because popup window is full screen. 115 sharePopup.setOnTouchListener(this); 116 mThumbnailRotateLayout = (RotateLayout) sharePopup.findViewById(R.id.thumbnail_rotate_layout); 117 mShareList = (ListView) sharePopup.findViewById(R.id.share_list); 118 mShareList.setDivider(null); 119 mThumbnail = (ImageView) sharePopup.findViewById(R.id.thumbnail); 120 mThumbnail.setImageBitmap(bitmap); 121 mShareView = (ViewGroup) sharePopup.findViewById(R.id.share_view); 122 mShareView.setOnClickListener(this); 123 124 mGotoGalleryRotate =(RotateLayout) sharePopup.findViewById(R.id.goto_gallery_button_rotate); 125 sharePopup.findViewById(R.id.goto_gallery_button).setOnClickListener(this); 126 127 mBitmapWidth = bitmap.getWidth(); 128 mBitmapHeight = bitmap.getHeight(); 129 130 // Show play button if this is a video thumbnail. 131 if (mMimeType.startsWith("video/")) { 132 sharePopup.findViewById(R.id.play).setVisibility(View.VISIBLE); 133 } 134 mBitmapWidth = bitmap.getWidth(); 135 mBitmapHeight = bitmap.getHeight(); 136 137 Resources res = mContext.getResources(); 138 139 // Initialize popup window size. 140 mRootView = sharePopup.findViewById(R.id.root); 141 LayoutParams params = mRootView.getLayoutParams(); 142 params.width = previewFrame.getWidth(); 143 params.height = previewFrame.getHeight(); 144 mRootView.setLayoutParams(params); 145 146 // Initialize popup window. 147 setWidth(WindowManager.LayoutParams.MATCH_PARENT); 148 setHeight(WindowManager.LayoutParams.MATCH_PARENT); 149 setBackgroundDrawable(new ColorDrawable()); 150 setContentView(sharePopup); 151 setOrientation(orientation); 152 setFocusable(true); 153 setAnimationStyle(R.style.AnimationPopup); 154 createShareMenu(); 155 156 adjustThumbnailPosition(); 157 } 158 adjustThumbnailPosition()159 private void adjustThumbnailPosition() { 160 RelativeLayout.LayoutParams lpOld = 161 (RelativeLayout.LayoutParams) mThumbnailRotateLayout.getLayoutParams(); 162 RelativeLayout.LayoutParams lpNew = 163 new RelativeLayout.LayoutParams(lpOld.width, lpOld.height); 164 165 mRootView.setBackgroundDrawable(null); 166 if (mBitmapWidth > mBitmapHeight * 2 || mBitmapHeight > mBitmapWidth * 2) { 167 // panorama image 168 lpNew.addRule(RelativeLayout.CENTER_HORIZONTAL); 169 lpNew.addRule(RelativeLayout.CENTER_VERTICAL); 170 171 // panorama images block the preview from showing in the background 172 // use a special color here for that. 173 mRootView.setBackgroundColor( 174 mContext.getResources().getColor(R.color.share_popup_blackout)); 175 } else if (mBitmapWidth > mBitmapHeight) { 176 // landscape image 177 lpNew.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 178 lpNew.addRule(RelativeLayout.ALIGN_PARENT_TOP); 179 lpNew.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 180 } else { 181 // portrait image 182 lpNew.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 183 lpNew.addRule(RelativeLayout.ALIGN_PARENT_TOP); 184 lpNew.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 185 } 186 187 mThumbnailRotateLayout.setLayoutParams(lpNew); 188 } 189 setOrientation(int orientation)190 public void setOrientation(int orientation) { 191 mOrientation = orientation; 192 193 int hPaddingRootView = mRootView.getPaddingLeft() + mRootView.getPaddingRight(); 194 int vPaddingRootView = mRootView.getPaddingTop() + mRootView.getPaddingBottom(); 195 int hPadding = mShareView.getPaddingLeft() + mShareView.getPaddingRight(); 196 int vPadding = mShareView.getPaddingTop() + mShareView.getPaddingBottom(); 197 198 // Calculate the width and the height of the thumbnail. Reserve the 199 // space for paddings. 200 float maxWidth = mPreviewFrame.getWidth() - hPadding - hPaddingRootView; 201 float maxHeight = mPreviewFrame.getHeight() - vPadding - vPaddingRootView; 202 // Swap the width and height if it is portrait mode. 203 if (orientation == 90 || orientation == 270) { 204 float temp = maxWidth; 205 maxWidth = maxHeight; 206 maxHeight = temp; 207 } 208 float actualAspect = maxWidth / maxHeight; 209 float desiredAspect = (float) mBitmapWidth / mBitmapHeight; 210 211 if (mMimeType.startsWith("video/")) { 212 desiredAspect = 4F/3F; 213 mThumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP); 214 } else { 215 mThumbnail.setScaleType(ImageView.ScaleType.CENTER_INSIDE); 216 } 217 218 LayoutParams params = mThumbnail.getLayoutParams(); 219 if (actualAspect > desiredAspect) { 220 params.width = Math.round(maxHeight * desiredAspect); 221 params.height = Math.round(maxHeight); 222 } else { 223 params.width = Math.round(maxWidth); 224 params.height = Math.round(maxWidth / desiredAspect); 225 } 226 mThumbnail.setLayoutParams(params); 227 228 if (mThumbnailRotateLayout != null) mThumbnailRotateLayout.setOrientation(orientation); 229 230 int count = mShareList.getChildCount(); 231 for (int i = 0; i < count; i++) { 232 ViewGroup f = (ViewGroup) mShareList.getChildAt(i); 233 RotateLayout r = (RotateLayout) f.findViewById(R.id.share_icon_rotate_layout); 234 r.setOrientation(orientation); 235 } 236 237 mGotoGalleryRotate.setOrientation(orientation); 238 239 adjustThumbnailPosition(); 240 } 241 242 @Override showAtLocation(View parent, int gravity, int x, int y)243 public void showAtLocation(View parent, int gravity, int x, int y) { 244 super.showAtLocation(parent, gravity, x, y); 245 // Inform other popup to dismiss if exit 246 PopupManager.getInstance(mContext).notifyShowPopup(null); 247 } 248 249 @Override onClick(View v)250 public void onClick(View v) { 251 switch (v.getId()) { 252 case R.id.goto_gallery_button: 253 case R.id.share_view: 254 Util.viewUri(mUri, mContext); 255 break; 256 } 257 } 258 259 @Override onTouch(View v, MotionEvent event)260 public boolean onTouch(View v, MotionEvent event) { 261 if (event.getAction() == MotionEvent.ACTION_DOWN) { 262 dismiss(); 263 return true; 264 } 265 return false; 266 } 267 createShareMenu()268 public void createShareMenu() { 269 PackageManager packageManager = mContext.getPackageManager(); 270 List<ResolveInfo> infos = packageManager.queryIntentActivities( 271 new Intent(Intent.ACTION_SEND).setType(mMimeType), 0); 272 273 ArrayList<HashMap<String, Object>> items = new ArrayList<HashMap<String, Object>>(); 274 for (ResolveInfo info: infos) { 275 ComponentName component = new ComponentName( 276 info.activityInfo.packageName, info.activityInfo.name); 277 HashMap<String, Object> map = new HashMap<String, Object>(); 278 map.put(ADAPTER_COLUMN_ICON, info.loadIcon(packageManager)); 279 items.add(map); 280 mComponent.add(component); 281 } 282 SimpleAdapter listItemAdapter = new MySimpleAdapter(mContext, items, 283 R.layout.share_icon, 284 new String[] {ADAPTER_COLUMN_ICON}, 285 new int[] {R.id.icon}); 286 listItemAdapter.setViewBinder(mViewBinder); 287 mShareList.setAdapter(listItemAdapter); 288 mShareList.setOnItemClickListener(this); 289 } 290 getUri()291 public Uri getUri() { 292 return mUri; 293 } 294 295 @Override onItemClick(AdapterView<?> parent, View view, int index, long id)296 public void onItemClick(AdapterView<?> parent, View view, int index, long id) { 297 Intent intent = new Intent(Intent.ACTION_SEND); 298 intent.setType(mMimeType); 299 intent.putExtra(Intent.EXTRA_STREAM, mUri); 300 intent.setComponent(mComponent.get(index)); 301 mContext.startActivity(intent); 302 } 303 } 304