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