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
17package com.android.camera.ui;
18
19import com.android.camera.R;
20import com.android.camera.Util;
21
22import android.app.Activity;
23import android.content.ComponentName;
24import android.content.Context;
25import android.content.Intent;
26import android.content.pm.ActivityInfo;
27import android.content.pm.PackageManager;
28import android.content.pm.ResolveInfo;
29import android.content.res.Resources;
30import android.graphics.Bitmap;
31import android.graphics.drawable.ColorDrawable;
32import android.graphics.drawable.Drawable;
33import android.net.Uri;
34import android.view.LayoutInflater;
35import android.view.MotionEvent;
36import android.view.View;
37import android.view.ViewGroup;
38import android.view.ViewGroup.LayoutParams;
39import android.view.WindowManager;
40import android.widget.AdapterView;
41import android.widget.GridView;
42import android.widget.ImageView;
43import android.widget.PopupWindow;
44import android.widget.SimpleAdapter;
45
46import java.util.ArrayList;
47import java.util.HashMap;
48import java.util.List;
49import java.util.Map;
50
51// A popup window that contains a big thumbnail and a list of apps to share.
52public 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 {
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
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
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
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
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
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
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
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
270    public Uri getUri() {
271        return mUri;
272    }
273
274    @Override
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