1 package com.cooliris.media;
3 import java.util.ArrayList;
6 import javax.microedition.khronos.opengles.GL11;
8 import android.app.AlertDialog;
9 import android.content.ComponentName;
10 import android.content.Context;
11 import android.content.Intent;
12 import android.content.pm.ActivityInfo;
13 import android.content.pm.PackageManager;
14 import android.content.pm.ResolveInfo;
15 import android.content.res.Resources;
16 import android.net.Uri;
17 import android.util.FloatMath;
18 import android.view.MotionEvent;
20 import com.cooliris.media.MenuBar.Menu;
21 import com.cooliris.media.PopupMenu.Option;
23 public final class HudLayer extends Layer {
24 public static final int MODE_NORMAL = 0;
25 public static final int MODE_SELECT = 1;
27 private Context mContext;
28 private GridLayer mGridLayer;
29 private final ImageButton mTopRightButton = new ImageButton();
30 private final ImageButton mZoomInButton = new ImageButton();
31 private final ImageButton mZoomOutButton = new ImageButton();
32 private static PathBarLayer sPathBar;
33 private static TimeBar sTimeBar;
34 private MenuBar.Menu[] mNormalBottomMenu = null;
35 private MenuBar.Menu[] mSingleViewIntentBottomMenu = null;
36 private final MenuBar mSelectionMenuBottom;
37 private final MenuBar mSelectionMenuTop;
38 private final MenuBar mFullscreenMenu;
39 private final LoadingLayer mLoadingLayer = new LoadingLayer();
40 private RenderView mView = null;
42 private int mMode = MODE_NORMAL;
44 // Camera button - launches the camera intent when pressed.
45 private static final int CAMERA_BUTTON_ICON = R.drawable.btn_camera;
46 private static final int CAMERA_BUTTON_ICON_PRESSED = R.drawable.btn_camera_pressed;
47 private static final int ZOOM_IN_ICON = R.drawable.btn_hud_zoom_in_normal;
48 private static final int ZOOM_IN_ICON_PRESSED = R.drawable.btn_hud_zoom_in_pressed;
49 private static final int ZOOM_OUT_ICON = R.drawable.btn_hud_zoom_out_normal;
50 private static final int ZOOM_OUT_ICON_PRESSED = R.drawable.btn_hud_zoom_out_pressed;
52 private final Runnable mCameraButtonAction = new Runnable() {
54 // Launch the camera intent.
55 Intent intent = new Intent();
56 intent.setClassName("com.android.camera", "com.android.camera.Camera");
57 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
58 mContext.startActivity(intent);
62 // Grid mode button - switches the media browser to grid mode.
63 private static final int GRID_MODE_ICON = R.drawable.mode_stack;
64 private static final int GRID_MODE_PRESSED_ICON = R.drawable.mode_stack;
66 private final Runnable mZoomInButtonAction = new Runnable() {
68 mGridLayer.zoomInToSelectedItem();
69 mGridLayer.markDirty(1);
73 private final Runnable mZoomOutButtonAction = new Runnable() {
75 mGridLayer.zoomOutFromSelectedItem();
76 mGridLayer.markDirty(1);
80 private final Runnable mGridModeButtonAction = new Runnable() {
82 mGridLayer.setState(GridLayer.STATE_GRID_VIEW);
87 * Stack mode button - switches the media browser to grid mode.
89 private static final int STACK_MODE_ICON = R.drawable.mode_grid;
90 private static final int STACK_MODE_PRESSED_ICON = R.drawable.mode_grid;
91 private final Runnable mStackModeButtonAction = new Runnable() {
93 mGridLayer.setState(GridLayer.STATE_TIMELINE);
97 private float mAnimAlpha;
98 private boolean mAutoHide;
99 private float mTimeElapsedSinceFullOpacity;
100 private String mCachedCaption;
101 private String mCachedPosition;
102 private String mCachedCurrentLabel;
104 HudLayer(Context context) {
106 if (sTimeBar == null) {
107 sTimeBar = new TimeBar(context);
108 sPathBar = new PathBarLayer();
110 mTopRightButton.setSize((int) (100 * Gallery.PIXEL_DENSITY), (int) (94 * Gallery.PIXEL_DENSITY));
112 mZoomInButton.setSize(43 * Gallery.PIXEL_DENSITY, 43 * Gallery.PIXEL_DENSITY);
113 mZoomOutButton.setSize(43 * Gallery.PIXEL_DENSITY, 43 * Gallery.PIXEL_DENSITY);
114 mZoomInButton.setImages(ZOOM_IN_ICON, ZOOM_IN_ICON_PRESSED);
115 mZoomInButton.setAction(mZoomInButtonAction);
116 mZoomOutButton.setImages(ZOOM_OUT_ICON, ZOOM_OUT_ICON_PRESSED);
117 mZoomOutButton.setAction(mZoomOutButtonAction);
119 // The Share submenu is populated dynamically when opened.
120 Resources resources = context.getResources();
121 PopupMenu.Option[] deleteOptions = {
122 new PopupMenu.Option(context.getResources().getString(R.string.confirm_delete), resources
123 .getDrawable(R.drawable.icon_delete), new Runnable() {
128 new PopupMenu.Option(context.getResources().getString(R.string.cancel), resources
129 .getDrawable(R.drawable.icon_cancel), new Runnable() {
134 mSelectionMenuBottom = new MenuBar(context);
136 MenuBar.Menu shareMenu = new MenuBar.Menu.Builder(context.getResources().getString(R.string.share)).icon(
137 R.drawable.icon_share).onSelect(new Runnable() {
143 MenuBar.Menu deleteMenu = new MenuBar.Menu.Builder(context.getResources().getString(R.string.delete)).icon(
144 R.drawable.icon_delete).options(deleteOptions).build();
146 MenuBar.Menu moreMenu = new MenuBar.Menu.Builder(context.getResources().getString(R.string.more)).icon(
147 R.drawable.icon_more).onSelect(new Runnable() {
153 mNormalBottomMenu = new MenuBar.Menu[] { shareMenu, deleteMenu, moreMenu };
154 mSingleViewIntentBottomMenu = new MenuBar.Menu[] { shareMenu, moreMenu };
156 mSelectionMenuBottom.setMenus(mNormalBottomMenu);
157 mSelectionMenuTop = new MenuBar(context);
158 mSelectionMenuTop.setMenus(new MenuBar.Menu[] {
159 new MenuBar.Menu.Builder(context.getResources().getString(R.string.select_all)).onSelect(new Runnable() {
161 mGridLayer.selectAll();
163 }).build(), new MenuBar.Menu.Builder("").build(),
164 new MenuBar.Menu.Builder(context.getResources().getString(R.string.deselect_all)).onSelect(new Runnable() {
166 mGridLayer.deselectOrCancelSelectMode();
169 mFullscreenMenu = new MenuBar(context);
170 mFullscreenMenu.setMenus(new MenuBar.Menu[] {
171 new MenuBar.Menu.Builder(context.getResources().getString(R.string.slideshow)).icon(R.drawable.icon_play)
172 .onSingleTapUp(new Runnable() {
174 if (getAlpha() == 1.0f)
175 mGridLayer.startSlideshow();
179 }).build(), /* new MenuBar.Menu.Builder("").build(), */
180 new MenuBar.Menu.Builder(context.getResources().getString(R.string.menu)).icon(R.drawable.icon_more)
181 .onSingleTapUp(new Runnable() {
183 if (getAlpha() == 1.0f)
184 mGridLayer.enterSelectionMode();
191 public void setContext(Context context) {
192 if (mContext != context) {
194 sTimeBar.regenerateStringsForContext(context);
198 private void buildMoreOptions() {
199 ArrayList<MediaBucket> buckets = mGridLayer.getSelectedBuckets();
201 int numBuckets = buckets.size();
202 boolean albumMode = false;
203 boolean singleItem = false;
204 boolean isPicasa = false;
205 int mediaType = MediaItem.MEDIA_TYPE_IMAGE;
206 if (numBuckets > 1) {
209 if (numBuckets == 1) {
210 MediaBucket bucket = buckets.get(0);
211 MediaSet mediaSet = bucket.mediaSet;
212 if (mediaSet == null) {
215 isPicasa = mediaSet.mPicasaAlbumId != Shared.INVALID;
216 if (bucket.mediaItems == null || bucket.mediaItems.size() == 0) {
219 ArrayList<MediaItem> items = bucket.mediaItems;
220 int numItems = items.size();
221 mediaType = items.get(0).getMediaType();
225 for (int i = 1; i < numItems; ++i) {
226 if (items.get(0).getMediaType() != mediaType) {
235 Option[] optionAll = new Option[] { new PopupMenu.Option(mContext.getResources().getString(R.string.details), mContext
236 .getResources().getDrawable(R.drawable.ic_menu_view_details), new Runnable() {
238 ArrayList<MediaBucket> buckets = mGridLayer.getSelectedBuckets();
239 final AlertDialog.Builder builder = new AlertDialog.Builder((Gallery) mContext);
240 builder.setTitle(mContext.getResources().getString(R.string.details));
241 boolean foundDataToDisplay = true;
243 if (buckets == null) {
244 foundDataToDisplay = false;
246 CharSequence[] strings = DetailMode.populateDetailModeStrings(mContext, buckets);
247 if (strings == null) {
248 foundDataToDisplay = false;
250 builder.setItems(strings, null);
254 mGridLayer.deselectAll();
255 if (foundDataToDisplay) {
256 builder.setNeutralButton(R.string.details_ok, null);
257 ((Gallery) mContext).getHandler().post(new Runnable() {
266 Option[] optionSingle = new Option[] { new PopupMenu.Option(mContext.getResources().getString(R.string.show_on_map),
267 mContext.getResources().getDrawable(R.drawable.ic_menu_mapmode), new Runnable() {
269 ArrayList<MediaBucket> buckets = mGridLayer.getSelectedBuckets();
270 MediaItem item = MediaBucketList.getFirstItemSelection(buckets);
274 mGridLayer.deselectAll();
275 Util.openMaps(mContext, item.mLatitude, item.mLongitude);
279 Option[] optionImageMultiple = new Option[] {
280 new PopupMenu.Option(mContext.getResources().getString(R.string.rotate_left), mContext.getResources().getDrawable(
281 R.drawable.ic_menu_rotate_left), new Runnable() {
283 mGridLayer.rotateSelectedItems(-90.0f);
286 new PopupMenu.Option(mContext.getResources().getString(R.string.rotate_right), mContext.getResources().getDrawable(
287 R.drawable.ic_menu_rotate_right), new Runnable() {
289 mGridLayer.rotateSelectedItems(90.0f);
294 optionImageMultiple = new Option[] {};
296 Option[] optionImageSingle;
298 optionImageSingle = new Option[] { new PopupMenu.Option(mContext.getResources().getString(R.string.set_as_wallpaper),
299 mContext.getResources().getDrawable(R.drawable.ic_menu_set_as), new Runnable() {
301 ArrayList<MediaBucket> buckets = mGridLayer.getSelectedBuckets();
302 MediaItem item = MediaBucketList.getFirstItemSelection(buckets);
306 mGridLayer.deselectAll();
307 if (item.mParentMediaSet.mPicasaAlbumId != Shared.INVALID) {
308 final Intent intent = new Intent("android.intent.action.ATTACH_DATA");
309 intent.setClassName("com.cooliris.media", "com.cooliris.media.Photographs");
310 intent.setData(Uri.parse(item.mContentUri));
311 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
312 ((Gallery) mContext).startActivityForResult(intent, 0);
317 optionImageSingle = new Option[] {
318 new PopupMenu.Option((isPicasa) ? mContext.getResources().getString(R.string.set_as_wallpaper) : mContext
319 .getResources().getString(R.string.set_as), mContext.getResources().getDrawable(
320 R.drawable.ic_menu_set_as), new Runnable() {
322 ArrayList<MediaBucket> buckets = mGridLayer.getSelectedBuckets();
323 MediaItem item = MediaBucketList.getFirstItemSelection(buckets);
327 mGridLayer.deselectAll();
328 if (item.mParentMediaSet.mPicasaAlbumId != Shared.INVALID) {
329 final Intent intent = new Intent("android.intent.action.ATTACH_DATA");
330 intent.setClassName("com.cooliris.media", "com.cooliris.media.Photographs");
331 intent.setData(Uri.parse(item.mContentUri));
332 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
333 ((Gallery) mContext).startActivityForResult(intent, 0);
335 Intent intent = Util.createSetAsIntent(Uri.parse(item.mContentUri), item.mMimeType);
336 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
337 ((Gallery) mContext).startActivity(Intent.createChooser(intent, ((Gallery) mContext)
338 .getText(R.string.set_image)));
342 new PopupMenu.Option(mContext.getResources().getString(R.string.crop), mContext.getResources().getDrawable(
343 R.drawable.ic_menu_crop), new Runnable() {
345 ArrayList<MediaBucket> buckets = mGridLayer.getSelectedBuckets();
346 MediaItem item = MediaBucketList.getFirstItemSelection(buckets);
350 mGridLayer.deselectAll();
351 final Intent intent = new Intent("com.android.camera.action.CROP");
352 intent.setClassName("com.cooliris.media", "com.cooliris.media.CropImage");
353 intent.setData(Uri.parse(item.mContentUri));
354 ((Gallery) mContext).startActivityForResult(intent, Gallery.CROP_MSG_INTERNAL);
358 Option[] options = optionAll;
361 if (mediaType == MediaItem.MEDIA_TYPE_IMAGE)
362 options = concat(options, optionImageMultiple);
364 MediaItem item = MediaBucketList.getFirstItemSelection(buckets);
365 if (item.mLatitude != 0.0f && item.mLongitude != 0.0f) {
366 options = concat(options, optionSingle);
368 if (mediaType == MediaItem.MEDIA_TYPE_IMAGE) {
369 options = concat(options, optionImageSingle);
370 options = concat(options, optionImageMultiple);
375 // We are assuming that the more menu is the last item in the menu array.
376 int lastIndex = mSelectionMenuBottom.getMenus().length - 1;
377 mSelectionMenuBottom.getMenus()[lastIndex].options = options;
380 private static final Option[] concat(Option[] A, Option[] B) {
381 Option[] C = (Option[]) new Option[A.length + B.length];
382 System.arraycopy(A, 0, C, 0, A.length);
383 System.arraycopy(B, 0, C, A.length, B.length);
387 public void updateNumItemsSelected(int numItems) {
388 String items = " " + ((numItems == 1) ? mContext.getString(R.string.item) : mContext.getString(R.string.items));
389 Menu menu = new MenuBar.Menu.Builder(numItems + items).config(MenuBar.MENU_TITLE_STYLE_TEXT).build();
390 mSelectionMenuTop.updateMenu(menu, 1);
393 protected void deleteSelection() {
394 mGridLayer.deleteSelection();
397 void setGridLayer(GridLayer layer) {
406 void setMode(int mode) {
414 protected void onSizeChanged() {
415 final float width = mWidth;
416 final float height = mHeight;
417 closeSelectionMenu();
419 sTimeBar.setPosition(0f, height - TimeBar.HEIGHT * Gallery.PIXEL_DENSITY);
420 sTimeBar.setSize(width, TimeBar.HEIGHT * Gallery.PIXEL_DENSITY);
421 mSelectionMenuTop.setPosition(0f, 0);
422 mSelectionMenuTop.setSize(width, MenuBar.HEIGHT * Gallery.PIXEL_DENSITY);
423 mSelectionMenuBottom.setPosition(0f, height - MenuBar.HEIGHT * Gallery.PIXEL_DENSITY);
424 mSelectionMenuBottom.setSize(width, MenuBar.HEIGHT * Gallery.PIXEL_DENSITY);
426 mFullscreenMenu.setPosition(0f, height - MenuBar.HEIGHT * Gallery.PIXEL_DENSITY);
427 mFullscreenMenu.setSize(width, MenuBar.HEIGHT * Gallery.PIXEL_DENSITY);
429 sPathBar.setPosition(0f, -4f * Gallery.PIXEL_DENSITY);
430 computeSizeForPathbar();
432 mTopRightButton.setPosition(width - mTopRightButton.getWidth(), 0f);
433 mZoomInButton.setPosition(width - mZoomInButton.getWidth(), 0f);
434 mZoomOutButton.setPosition(width - mZoomInButton.getWidth(), mZoomInButton.getHeight());
437 private void computeSizeForPathbar() {
438 float pathBarWidth = mWidth
439 - ((mGridLayer.getState() == GridLayer.STATE_FULL_SCREEN) ? 32 * Gallery.PIXEL_DENSITY
440 : 120 * Gallery.PIXEL_DENSITY);
441 sPathBar.setSize(pathBarWidth, FloatMath.ceil(39 * Gallery.PIXEL_DENSITY));
442 sPathBar.recomputeComponents();
445 public void setFeed(MediaFeed feed, int state, boolean needsLayout) {
446 sTimeBar.setFeed(feed, state, needsLayout);
449 public void onGridStateChanged() {
453 private void updateViews() {
454 if (mGridLayer == null)
456 final int state = mGridLayer.getState();
457 // Show the selection menu in selection mode.
458 final boolean selectionMode = mMode == MODE_SELECT;
459 final boolean fullscreenMode = state == GridLayer.STATE_FULL_SCREEN;
460 final boolean stackMode = state == GridLayer.STATE_MEDIA_SETS || state == GridLayer.STATE_TIMELINE;
461 mSelectionMenuTop.setHidden(!selectionMode || fullscreenMode);
462 mSelectionMenuBottom.setHidden(!selectionMode);
463 mFullscreenMenu.setHidden(!fullscreenMode || selectionMode);
464 mZoomInButton.setHidden(mFullscreenMenu.isHidden());
465 mZoomOutButton.setHidden(mFullscreenMenu.isHidden());
467 // Show the time bar in stack and grid states, except in selection mode.
468 sTimeBar.setHidden(fullscreenMode || selectionMode || stackMode);
469 // mTimeBar.setHidden(selectionMode || (state != GridLayer.STATE_TIMELINE && state != GridLayer.STATE_GRID_VIEW));
471 // Hide the path bar and top-right button in selection mode.
472 sPathBar.setHidden(selectionMode);
473 mTopRightButton.setHidden(selectionMode || fullscreenMode);
474 computeSizeForPathbar();
476 // Configure the top-right button.
478 int pressedImage = 0;
479 Runnable action = null;
480 final ImageButton topRightButton = mTopRightButton;
481 int height = (int) (94 * Gallery.PIXEL_DENSITY);
483 case GridLayer.STATE_MEDIA_SETS:
484 image = CAMERA_BUTTON_ICON;
485 pressedImage = CAMERA_BUTTON_ICON_PRESSED;
486 action = mCameraButtonAction;
488 case GridLayer.STATE_GRID_VIEW:
490 image = STACK_MODE_ICON;
491 pressedImage = STACK_MODE_PRESSED_ICON;
492 action = mStackModeButtonAction;
494 case GridLayer.STATE_TIMELINE:
495 image = GRID_MODE_ICON;
496 pressedImage = GRID_MODE_PRESSED_ICON;
497 action = mGridModeButtonAction;
502 topRightButton.setSize((int) (100 * Gallery.PIXEL_DENSITY), height);
503 topRightButton.setImages(image, pressedImage);
504 topRightButton.setAction(action);
507 public TimeBar getTimeBar() {
511 public PathBarLayer getPathBar() {
515 public GridLayer getGridLayer() {
520 public boolean update(RenderView view, float frameInterval) {
522 if (mAlpha == 1.0f) {
523 // Speed up the animation when it becomes visible.
526 mAnimAlpha = FloatUtils.animate(mAnimAlpha, mAlpha, frameInterval * factor);
527 boolean timeElapsedSinceFullOpacity_Reset = mTimeElapsedSinceFullOpacity == 0.0f;
530 if (mAlpha == 1.0f && mMode != MODE_SELECT) {
531 mTimeElapsedSinceFullOpacity += frameInterval;
532 if (mTimeElapsedSinceFullOpacity > 5.0f)
536 if (mAnimAlpha != mAlpha || (mTimeElapsedSinceFullOpacity < 5.0f && !timeElapsedSinceFullOpacity_Reset))
542 public void renderOpaque(RenderView view, GL11 gl) {
546 public void renderBlended(RenderView view, GL11 gl) {
547 view.setAlpha(mAnimAlpha);
550 public void setAlpha(float alpha) {
551 float oldAlpha = mAlpha;
553 if (oldAlpha != alpha) {
555 mView.requestRender();
558 mTimeElapsedSinceFullOpacity = 0.0f;
562 public float getAlpha() {
566 public void setTimeBarTime(long time) {
567 // mTimeBar.setTime(time);
571 public void generate(RenderView view, RenderView.Lists lists) {
572 lists.opaqueList.add(this);
573 lists.blendedList.add(this);
574 lists.hitTestList.add(this);
575 lists.updateList.add(this);
576 mTopRightButton.generate(view, lists);
577 mZoomInButton.generate(view, lists);
578 mZoomOutButton.generate(view, lists);
579 sTimeBar.generate(view, lists);
580 mSelectionMenuTop.generate(view, lists);
581 mSelectionMenuBottom.generate(view, lists);
582 mFullscreenMenu.generate(view, lists);
583 sPathBar.generate(view, lists);
584 // mLoadingLayer.generate(view, lists);
589 public boolean containsPoint(float x, float y) {
593 public void cancelSelection() {
594 mSelectionMenuBottom.close();
595 closeSelectionMenu();
596 setMode(MODE_NORMAL);
599 public void closeSelectionMenu() {
600 mSelectionMenuBottom.close();
604 public boolean onTouchEvent(MotionEvent event) {
605 if (mMode == MODE_SELECT) {
607 * setMode(MODE_NORMAL); ArrayList<MediaBucket> displayBuckets = mGridLayer.getSelectedBuckets(); // use this list, and
608 * then clear the items return true;
616 public boolean isLoaded() {
617 return mLoadingLayer.isLoaded();
621 mLoadingLayer.reset();
622 sTimeBar.regenerateStringsForContext(mContext);
625 public void fullscreenSelectionChanged(MediaItem item, int index, int count) {
626 // request = new ReverseGeocoder.Request();
627 // request.firstLatitude = request.secondLatitude = item.latitude;
628 // request.firstLongitude = request.secondLongitude = item.longitude;
629 // mGeo.enqueue(request);
632 String location = index + "/" + count;
633 mCachedCaption = item.mCaption;
634 mCachedPosition = location;
635 mCachedCurrentLabel = location;
636 sPathBar.changeLabel(location);
639 private void updateShareMenu() {
640 // Get the first selected item. Wire this up to multiple-item intents when we move
642 ArrayList<MediaBucket> selection = mGridLayer.getSelectedBuckets();
643 ArrayList<Uri> uris = new ArrayList<Uri>();
644 String mimeType = null;
645 if (!selection.isEmpty()) {
646 int mediaType = Shared.INVALID;
647 int numBuckets = selection.size();
648 for (int j = 0; j < numBuckets; ++j) {
649 MediaBucket bucket = selection.get(j);
650 ArrayList<MediaItem> items = null;
652 if (bucket.mediaItems != null && !bucket.mediaItems.isEmpty()) {
653 items = bucket.mediaItems;
654 numItems = items.size();
655 } else if (bucket.mediaSet != null) {
656 // We need to delete the entire bucket.
657 items = bucket.mediaSet.getItems();
658 numItems = bucket.mediaSet.getNumItems();
660 for (int i = 0; i < numItems; ++i) {
661 MediaItem item = items.get(i);
662 if (mimeType == null) {
663 mimeType = item.mMimeType;
664 mediaType = item.getMediaType();
665 MediaSet parentMediaSet = item.mParentMediaSet;
666 if (parentMediaSet != null && parentMediaSet.mPicasaAlbumId != Shared.INVALID) {
667 // This will go away once http uri's are supported for all media types.
668 // This ensures that just the link is shared as a text
669 mimeType = "text/plain";
672 if (mediaType == item.getMediaType()) {
674 if (item.mContentUri != null) {
675 Uri uri = Uri.parse(item.mContentUri);
682 PopupMenu.Option[] options = null;
683 if (uris.size() != 0) {
684 final Intent intent = new Intent();
685 if (mimeType == null)
686 mimeType = "image/jpeg";
687 if (mimeType.contains("text")) {
688 // We need to share this as a text string.
689 intent.setAction(Intent.ACTION_SEND);
690 intent.setType(mimeType);
692 // Create a newline-separated list of URLs.
693 StringBuilder builder = new StringBuilder();
694 for (int i = 0, size = uris.size(); i < size; ++i) {
695 builder.append(uris.get(i));
697 builder.append('\n');
700 intent.putExtra(Intent.EXTRA_TEXT, builder.toString());
702 if (uris.size() == 1) {
703 intent.setAction(Intent.ACTION_SEND);
704 intent.putExtra(Intent.EXTRA_STREAM, uris.get(0));
706 intent.setAction(Intent.ACTION_SEND_MULTIPLE);
707 intent.putExtra(Intent.EXTRA_STREAM, uris);
709 intent.setType(mimeType);
711 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
713 // Query the system for matching activities.
714 PackageManager packageManager = mContext.getPackageManager();
715 List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
716 int numActivities = activities.size();
717 options = new PopupMenu.Option[numActivities];
718 for (int i = 0; i != numActivities; ++i) {
719 final ResolveInfo info = activities.get(i);
720 String label = info.loadLabel(packageManager).toString();
721 options[i] = new PopupMenu.Option(label, info.loadIcon(packageManager), new Runnable() {
723 startResolvedActivity(intent, info);
728 mSelectionMenuBottom.getMenus()[0].options = options;
731 private void startResolvedActivity(Intent intent, ResolveInfo info) {
732 final Intent resolvedIntent = new Intent(intent);
733 ActivityInfo ai = info.activityInfo;
734 resolvedIntent.setComponent(new ComponentName(ai.applicationInfo.packageName, ai.name));
735 ((Gallery) mContext).getHandler().post(new Runnable() {
737 mContext.startActivity(resolvedIntent);
742 public void autoHide(boolean hide) {
746 public void swapFullscreenLabel() {
747 mCachedCurrentLabel = (mCachedCurrentLabel == mCachedCaption || mCachedCaption == null) ? mCachedPosition : mCachedCaption;
748 sPathBar.changeLabel(mCachedCurrentLabel);
751 public void clear() {
755 public void enterSelectionMode() {
757 setMode(HudLayer.MODE_SELECT);
758 // if we are in single view mode, show the bottom menu without the delete button.
759 if (mGridLayer.noDeleteMode()) {
760 mSelectionMenuBottom.setMenus(mSingleViewIntentBottomMenu);
762 mSelectionMenuBottom.setMenus(mNormalBottomMenu);
766 public void computeBottomMenu() {
767 // we need to the same for picasa albums
768 ArrayList<MediaBucket> selection = mGridLayer.getSelectedBuckets();
769 Menu[] menus = mSelectionMenuBottom.getMenus();
770 if (menus == mSingleViewIntentBottomMenu)
772 int numBuckets = selection.size();
773 for (int i = 0; i < numBuckets; ++i) {
774 MediaBucket bucket = selection.get(i);
775 if (bucket.mediaSet.mPicasaAlbumId != Shared.INVALID) {
776 mSelectionMenuBottom.setMenus(mSingleViewIntentBottomMenu);
782 public Layer getMenuBar() {
783 return mFullscreenMenu;