19442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann/* 29442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * Copyright (C) 2010 The Android Open Source Project 39442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * 49442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * Licensed under the Apache License, Version 2.0 (the "License"); 59442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * you may not use this file except in compliance with the License. 69442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * You may obtain a copy of the License at 79442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * 89442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * http://www.apache.org/licenses/LICENSE-2.0 99442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * 109442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * Unless required by applicable law or agreed to in writing, software 119442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * distributed under the License is distributed on an "AS IS" BASIS, 129442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * See the License for the specific language governing permissions and 149442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann * limitations under the License 159442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann */ 169442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 1718ffaa2561cc7dd2e3ef81737e6537931c0a9a11Dmitri Plotnikovpackage com.android.contacts.editor; 189442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 199442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmannimport android.content.Context; 209442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmannimport android.view.View; 219442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmannimport android.widget.AdapterView; 229442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmannimport android.widget.AdapterView.OnItemClickListener; 239442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmannimport android.widget.ArrayAdapter; 249442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmannimport android.widget.ListAdapter; 259442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmannimport android.widget.ListPopupWindow; 269442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 27e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R; 28c21751ddc1a91453a37273ace9e24907bb54cc99Yorke Leeimport com.android.contacts.util.PhoneCapabilityTester; 29619ac169e45bf547a2cbcd8a9775bb234f45c00fChiao Chengimport com.android.contacts.util.UiClosables; 30e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng 319442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmannimport java.util.ArrayList; 329442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 339442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann/** 34ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus * Shows a popup asking the user what to do for a photo. The result is passed back to the Listener 359442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann */ 369442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmannpublic class PhotoActionPopup { 379442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann public static final String TAG = "PhotoActionPopup"; 389442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 39ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus /** 40ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus * Bitmask flags to specify which actions should be presented to the user. 41ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus */ 42ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus public static final class Flags { 43ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus /** If set, show choice to remove photo. */ 44ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus public static final int REMOVE_PHOTO = 2; 45ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus /** If set, show choices to take a picture with the camera, or pick one from the gallery. */ 46ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus public static final int TAKE_OR_PICK_PHOTO = 4; 47ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus /** 48ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus * If set, modifies the wording in the choices for TAKE_OR_PICK_PHOTO 49ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus * to emphasize that the existing photo will be replaced. 50ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus */ 51ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus public static final int TAKE_OR_PICK_PHOTO_REPLACE_WORDING = 8; 52ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus } 53ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus 54ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus /** 55ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus * Convenient combinations of commonly-used flags (see {@link Flags}). 56ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus */ 57ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus public static final class Modes { 58ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus public static final int NO_PHOTO = 59ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus Flags.TAKE_OR_PICK_PHOTO; 607e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell public static final int READ_ONLY_PHOTO = 0; 617e67082d3f7c4ab56945040c0e4617b71c7e5f0bBrian Attwell public static final int WRITE_ABLE_PHOTO = 62ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus Flags.REMOVE_PHOTO | 63ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus Flags.TAKE_OR_PICK_PHOTO | 64ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus Flags.TAKE_OR_PICK_PHOTO_REPLACE_WORDING; 65b0afa207a16d22f5d220dd2b18db756a0d159e09Brian Attwell // When the popup represents multiple photos, the REMOVE_PHOTO option doesn't make sense. 66b0afa207a16d22f5d220dd2b18db756a0d159e09Brian Attwell // The REMOVE_PHOTO option would have to remove all photos. And sometimes some of the 67b0afa207a16d22f5d220dd2b18db756a0d159e09Brian Attwell // photos are readonly. 68b0afa207a16d22f5d220dd2b18db756a0d159e09Brian Attwell public static final int MULTIPLE_WRITE_ABLE_PHOTOS = 69b0afa207a16d22f5d220dd2b18db756a0d159e09Brian Attwell Flags.TAKE_OR_PICK_PHOTO | 70b0afa207a16d22f5d220dd2b18db756a0d159e09Brian Attwell Flags.TAKE_OR_PICK_PHOTO_REPLACE_WORDING; 71ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus } 729442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 730e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang public static ArrayList<ChoiceListItem> getChoices(Context context, int mode) { 749442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann // Build choices, depending on the current mode. We assume this Dialog is never called 759442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann // if there are NO choices (e.g. a read-only picture is already super-primary) 769442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann final ArrayList<ChoiceListItem> choices = new ArrayList<ChoiceListItem>(4); 779442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann // Remove 78ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus if ((mode & Flags.REMOVE_PHOTO) > 0) { 799442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann choices.add(new ChoiceListItem(ChoiceListItem.ID_REMOVE, 809442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann context.getString(R.string.removePhoto))); 819442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 82ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus // Take photo or pick one from the gallery. Wording differs if there is already a photo. 83ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus if ((mode & Flags.TAKE_OR_PICK_PHOTO) > 0) { 84ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus boolean replace = (mode & Flags.TAKE_OR_PICK_PHOTO_REPLACE_WORDING) > 0; 85ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus final int takePhotoResId = replace ? R.string.take_new_photo : R.string.take_photo; 86ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus final String takePhotoString = context.getString(takePhotoResId); 87ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus final int pickPhotoResId = replace ? R.string.pick_new_photo : R.string.pick_photo; 88ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus final String pickPhotoString = context.getString(pickPhotoResId); 89c21751ddc1a91453a37273ace9e24907bb54cc99Yorke Lee if (PhoneCapabilityTester.isCameraIntentRegistered(context)) { 90c21751ddc1a91453a37273ace9e24907bb54cc99Yorke Lee choices.add(new ChoiceListItem(ChoiceListItem.ID_TAKE_PHOTO, takePhotoString)); 91c21751ddc1a91453a37273ace9e24907bb54cc99Yorke Lee } 92ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus choices.add(new ChoiceListItem(ChoiceListItem.ID_PICK_PHOTO, pickPhotoString)); 939442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 940e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang return choices; 950e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang } 960e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang 970e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang public static ListPopupWindow createPopupMenu(Context context, View anchorView, 980e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang final Listener listener, int mode) { 990e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang final ArrayList<ChoiceListItem> choices = getChoices(context, mode); 100ced983d7a816256d93fdea1f81e63e4598c18875Josh Gargus 1019442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann final ListAdapter adapter = new ArrayAdapter<ChoiceListItem>(context, 102507d85177886bece6ac38870d0e4b6c4655abc55Katherine Kuan R.layout.select_dialog_item, choices); 1039442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 1049442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann final ListPopupWindow listPopupWindow = new ListPopupWindow(context); 1059442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann final OnItemClickListener clickListener = new OnItemClickListener() { 1069442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann @Override 1079442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 1089442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann final ChoiceListItem choice = choices.get(position); 1099442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann switch (choice.getId()) { 1109442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann case ChoiceListItem.ID_REMOVE: 1112293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan listener.onRemovePictureChosen(); 1129442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann break; 1139442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann case ChoiceListItem.ID_TAKE_PHOTO: 1149442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann listener.onTakePhotoChosen(); 1159442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann break; 1169442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann case ChoiceListItem.ID_PICK_PHOTO: 1179442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann listener.onPickFromGalleryChosen(); 1189442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann break; 1199442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 1206fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro 121619ac169e45bf547a2cbcd8a9775bb234f45c00fChiao Cheng UiClosables.closeQuietly(listPopupWindow); 1229442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 1239442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann }; 1249442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 1259442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann listPopupWindow.setAnchorView(anchorView); 1269442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann listPopupWindow.setAdapter(adapter); 1279442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann listPopupWindow.setOnItemClickListener(clickListener); 1289442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann listPopupWindow.setModal(true); 129832dc0e2d0f91a28166ea51a068ebaf339e09e0dDmitri Plotnikov listPopupWindow.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED); 1302d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu final int minWidth = context.getResources().getDimensionPixelSize( 1312d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu R.dimen.photo_action_popup_min_width); 1322d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu if (anchorView.getWidth() < minWidth) { 1332d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu listPopupWindow.setWidth(minWidth); 1342d4632c2eb7d2dc3bb94bf64c14c471aafa67b0fMaurice Chu } 1359442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann return listPopupWindow; 1369442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 1379442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 1380e72ce9d97e0133a5f7cc348eef363bef9395979Walter Jang public static final class ChoiceListItem { 1399442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann private final int mId; 1409442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann private final String mCaption; 1419442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 1429442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann public static final int ID_TAKE_PHOTO = 1; 1439442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann public static final int ID_PICK_PHOTO = 2; 1449442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann public static final int ID_REMOVE = 3; 1459442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 1469442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann public ChoiceListItem(int id, String caption) { 1479442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann mId = id; 1489442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann mCaption = caption; 1499442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 1509442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 1519442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann @Override 1529442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann public String toString() { 1539442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann return mCaption; 1549442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 1559442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 1569442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann public int getId() { 1579442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann return mId; 1589442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 1599442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 1609442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann 1619442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann public interface Listener { 1622293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan void onRemovePictureChosen(); 1639442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann void onTakePhotoChosen(); 1649442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann void onPickFromGalleryChosen(); 1659442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann } 1669442ef4d2667eab16f65535b63757a7ffe4ccf69Daniel Lehmann} 167