Change dialog to popup
Bug:3140059
Change-Id: If09c7082cff59808c9c60962bece8c58cc2c1ff4
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 01cd535..02c378a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -469,7 +469,7 @@
<!-- Attaches a photo to a contact. Started from external applications -->
<activity android:name="AttachImage"
- android:label="@string/contact_photo_dialog_title"
+ android:label="@string/attach_photo_dialog_title"
android:taskAffinity="">
<intent-filter>
<action android:name="android.intent.action.ATTACH_DATA" />
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 6cbfca8..fc0056c 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -30,10 +30,12 @@
<dimen name="aggregation_suggestion_icon_size">40dip</dimen>
<dimen name="account_selector_popup_width">400dip</dimen>
-
+
+ <dimen name="photo_action_popup_width">400dip</dimen>
+
<dimen name="aizy_preview_width">80dip</dimen>
<dimen name="aizy_preview_height">80dip</dimen>
-
+
<!-- Padding of the rounded plus/minus buttons in the editor (the minus button is created
in code) -->
<dimen name="editor_round_button_padding_left">5dip</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index aa93b79..07ea96c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -243,8 +243,8 @@
<!-- Description in the dialog that appears if there are no pictures from which to create an icon for a contact -->
<string name="photoPickerNotFoundText" product="default">No pictures are available on the phone.</string>
- <!-- Description of the dialog used to set a photo for a contact [CHAR LIMIT=50] -->
- <string name="contact_photo_dialog_title">Contact photo</string>
+ <!-- Description used in the attach photo Intent from third party apps [CHAR LIMIT=50] -->
+ <string name="attach_photo_dialog_title">Contact photo</string>
<!-- Title of the dialog used to set a custom label for a contact detail, like a phone number or email address.
For example, this may be used to set a phone number's label to "Vaction house" -->
diff --git a/src/com/android/contacts/views/editor/ContactEditorFragment.java b/src/com/android/contacts/views/editor/ContactEditorFragment.java
index 4456b89..c4bf6c3 100644
--- a/src/com/android/contacts/views/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/views/editor/ContactEditorFragment.java
@@ -75,7 +75,6 @@
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.DisplayNameSources;
import android.provider.ContactsContract.Intents;
import android.provider.ContactsContract.RawContacts;
import android.provider.MediaStore;
@@ -103,9 +102,8 @@
import java.util.List;
public class ContactEditorFragment extends Fragment implements
- SplitContactConfirmationDialogFragment.Listener, PhotoDialogFragment.Listener,
- SelectAccountDialogFragment.Listener, AggregationSuggestionEngine.Listener,
- AggregationSuggestionView.Listener {
+ SplitContactConfirmationDialogFragment.Listener, SelectAccountDialogFragment.Listener,
+ AggregationSuggestionEngine.Listener, AggregationSuggestionView.Listener {
private static final String TAG = "ContactEditorFragment";
@@ -483,51 +481,13 @@
editor = (BaseRawContactEditorView) inflater.inflate(
R.layout.read_only_raw_contact_editor_view, mContent, false);
}
- final PhotoEditorView photoEditor = editor.getPhotoEditor();
- final boolean sourceReadOnly = source.readOnly;
- photoEditor.setEditorListener(new EditorListener() {
- @Override
- public void onRequest(int request) {
- if (!hasValidState()) return;
-
- if (request == EditorListener.REQUEST_PICK_PHOTO) {
- // Determine mode
- final int mode;
- if (sourceReadOnly) {
- if (editor.hasSetPhoto() && hasMoreThanOnePhoto()) {
- mode = PhotoDialogFragment.MODE_READ_ONLY_ALLOW_PRIMARY;
- } else {
- // Read-only and either no photo or the only photo ==> no options
- return;
- }
- } else {
- if (editor.hasSetPhoto()) {
- if (hasMoreThanOnePhoto()) {
- mode = PhotoDialogFragment.MODE_PHOTO_ALLOW_PRIMARY;
- } else {
- mode = PhotoDialogFragment.MODE_PHOTO_DISALLOW_PRIMARY;
- }
- } else {
- mode = PhotoDialogFragment.MODE_NO_PHOTO;
- }
- }
-
- final PhotoDialogFragment fragment = new PhotoDialogFragment();
- fragment.setArguments(mode, rawContactId);
- fragment.setTargetFragment(ContactEditorFragment.this, 0);
- fragment.show(getFragmentManager(), PhotoDialogFragment.TAG);
- }
- }
-
- @Override
- public void onDeleted(Editor removedEditor) {
- }
- });
mContent.addView(editor);
editor.setState(entity, source, mViewIdGenerator);
+ editor.getPhotoEditor().setEditorListener(
+ new PhotoEditorListener(editor, source.readOnly));
if (editor instanceof RawContactEditorView) {
final RawContactEditorView rawContactEditor = (RawContactEditorView) editor;
final TextFieldsEditorView nameEditor = rawContactEditor.getNameEditor();
@@ -1739,76 +1699,6 @@
}
/**
- * User has chosen to set the selected photo as the (super) primary photo
- */
- @Override
- public void onUseAsPrimaryChosen(long rawContactId) {
- // Set the IsSuperPrimary for each editor
- int count = mContent.getChildCount();
- for (int i = 0; i < count; i++) {
- final View childView = mContent.getChildAt(i);
- if (childView instanceof BaseRawContactEditorView) {
- final BaseRawContactEditorView editor = (BaseRawContactEditorView) childView;
- final PhotoEditorView photoEditor = editor.getPhotoEditor();
- photoEditor.setSuperPrimary(editor.getRawContactId() == rawContactId);
- }
- }
- }
-
- /**
- * User has chosen to remove a picture
- */
- @Override
- public void onRemovePictureChose(long rawContactId) {
- // find the correct editor and remove it's photo
- final int editorCount = mContent.getChildCount();
- for (int i = 0; i < editorCount; i++) {
- final View child = mContent.getChildAt(i);
- if (child instanceof BaseRawContactEditorView) {
- final BaseRawContactEditorView editor =
- (BaseRawContactEditorView) child;
- if (editor.getRawContactId() == rawContactId) {
- editor.setPhotoBitmap(null);
- break;
- }
- }
- }
- }
-
- /**
- * Launches Camera to take a picture and store it in a file.
- */
- @Override
- public void onTakePhotoChosen(long rawContactId) {
- mRawContactIdRequestingPhoto = rawContactId;
- try {
- // Launch camera to take photo for selected contact
- PHOTO_DIR.mkdirs();
- mCurrentPhotoFile = new File(PHOTO_DIR, getPhotoFileName());
- final Intent intent = getTakePickIntent(mCurrentPhotoFile);
-
- startActivityForResult(intent, REQUEST_CODE_CAMERA_WITH_DATA);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(mContext, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
- }
- }
-
- /**
- * Launches Gallery to pick a photo.
- */
- @Override
- public void onPickFromGalleryChosen(long rawContactId) {
- mRawContactIdRequestingPhoto = rawContactId;
- try {
- // Launch picker to choose photo for selected contact
- final Intent intent = getPhotoPickIntent();
- startActivityForResult(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA);
- } catch (ActivityNotFoundException e) {
- Toast.makeText(mContext, R.string.photoPickerNotFoundText, Toast.LENGTH_LONG).show();
- }
- }
-
- /**
* Account was chosen in the selector. Create a RawContact for this account now
*/
@Override
@@ -1825,4 +1715,109 @@
mListener.onAccountSelectorAborted();
}
}
+
+ private final class PhotoEditorListener
+ implements EditorListener, PhotoActionPopup.Listener {
+ private final BaseRawContactEditorView mEditor;
+ private final boolean mSourceReadOnly;
+
+ private PhotoEditorListener(BaseRawContactEditorView editor, boolean sourceReadOnly) {
+ mEditor = editor;
+ mSourceReadOnly = sourceReadOnly;
+ }
+
+ @Override
+ public void onRequest(int request) {
+ if (!hasValidState()) return;
+
+ if (request == EditorListener.REQUEST_PICK_PHOTO) {
+ // Determine mode
+ final int mode;
+ if (mSourceReadOnly) {
+ if (mEditor.hasSetPhoto() && hasMoreThanOnePhoto()) {
+ mode = PhotoActionPopup.MODE_READ_ONLY_ALLOW_PRIMARY;
+ } else {
+ // Read-only and either no photo or the only photo ==> no options
+ return;
+ }
+ } else {
+ if (mEditor.hasSetPhoto()) {
+ if (hasMoreThanOnePhoto()) {
+ mode = PhotoActionPopup.MODE_PHOTO_ALLOW_PRIMARY;
+ } else {
+ mode = PhotoActionPopup.MODE_PHOTO_DISALLOW_PRIMARY;
+ }
+ } else {
+ mode = PhotoActionPopup.MODE_NO_PHOTO;
+ }
+ }
+ PhotoActionPopup.createPopupMenu(mContext, mEditor.getPhotoEditor(), this, mode)
+ .show();
+ }
+ }
+
+ @Override
+ public void onDeleted(Editor removedEditor) {
+ }
+
+ /**
+ * User has chosen to set the selected photo as the (super) primary photo
+ */
+ @Override
+ public void onUseAsPrimaryChosen() {
+ // Set the IsSuperPrimary for each editor
+ int count = mContent.getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View childView = mContent.getChildAt(i);
+ if (childView instanceof BaseRawContactEditorView) {
+ final BaseRawContactEditorView editor = (BaseRawContactEditorView) childView;
+ final PhotoEditorView photoEditor = editor.getPhotoEditor();
+ photoEditor.setSuperPrimary(editor == mEditor);
+ }
+ }
+ }
+
+ /**
+ * User has chosen to remove a picture
+ */
+ @Override
+ public void onRemovePictureChose() {
+ mEditor.setPhotoBitmap(null);
+ }
+
+ /**
+ * Launches Camera to take a picture and store it in a file.
+ */
+ @Override
+ public void onTakePhotoChosen() {
+ mRawContactIdRequestingPhoto = mEditor.getRawContactId();
+ try {
+ // Launch camera to take photo for selected contact
+ PHOTO_DIR.mkdirs();
+ mCurrentPhotoFile = new File(PHOTO_DIR, getPhotoFileName());
+ final Intent intent = getTakePickIntent(mCurrentPhotoFile);
+
+ startActivityForResult(intent, REQUEST_CODE_CAMERA_WITH_DATA);
+ } catch (ActivityNotFoundException e) {
+ Toast.makeText(mContext, R.string.photoPickerNotFoundText,
+ Toast.LENGTH_LONG).show();
+ }
+ }
+
+ /**
+ * Launches Gallery to pick a photo.
+ */
+ @Override
+ public void onPickFromGalleryChosen() {
+ mRawContactIdRequestingPhoto = mEditor.getRawContactId();
+ try {
+ // Launch picker to choose photo for selected contact
+ final Intent intent = getPhotoPickIntent();
+ startActivityForResult(intent, REQUEST_CODE_PHOTO_PICKED_WITH_DATA);
+ } catch (ActivityNotFoundException e) {
+ Toast.makeText(mContext, R.string.photoPickerNotFoundText,
+ Toast.LENGTH_LONG).show();
+ }
+ }
+ }
}
diff --git a/src/com/android/contacts/views/editor/PhotoActionPopup.java b/src/com/android/contacts/views/editor/PhotoActionPopup.java
new file mode 100644
index 0000000..2dba00c
--- /dev/null
+++ b/src/com/android/contacts/views/editor/PhotoActionPopup.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.contacts.views.editor;
+
+import com.android.contacts.R;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
+import android.widget.ListPopupWindow;
+
+import java.util.ArrayList;
+
+/**
+ * Shows a popup asking the user what to do for a photo. The result is pased back to the Listener
+ */
+public class PhotoActionPopup {
+ public static final String TAG = "PhotoActionPopup";
+
+ public static final int MODE_NO_PHOTO = 0;
+ public static final int MODE_READ_ONLY_ALLOW_PRIMARY = 1;
+ public static final int MODE_PHOTO_DISALLOW_PRIMARY = 2;
+ public static final int MODE_PHOTO_ALLOW_PRIMARY = 3;
+
+ public static ListPopupWindow createPopupMenu(Context context, View anchorView,
+ final Listener listener, int mode) {
+ // Build choices, depending on the current mode. We assume this Dialog is never called
+ // if there are NO choices (e.g. a read-only picture is already super-primary)
+ final ArrayList<ChoiceListItem> choices = new ArrayList<ChoiceListItem>(4);
+ // Use as Primary
+ if (mode == MODE_PHOTO_ALLOW_PRIMARY || mode == MODE_READ_ONLY_ALLOW_PRIMARY) {
+ choices.add(new ChoiceListItem(ChoiceListItem.ID_USE_AS_PRIMARY,
+ context.getString(R.string.use_photo_as_primary)));
+ }
+ // Remove
+ if (mode == MODE_PHOTO_DISALLOW_PRIMARY || mode == MODE_PHOTO_ALLOW_PRIMARY) {
+ choices.add(new ChoiceListItem(ChoiceListItem.ID_REMOVE,
+ context.getString(R.string.removePhoto)));
+ }
+ // Take photo (if there is already a photo, it says "Take new photo")
+ if (mode == MODE_NO_PHOTO || mode == MODE_PHOTO_ALLOW_PRIMARY
+ || mode == MODE_PHOTO_DISALLOW_PRIMARY) {
+ final int resId = mode == MODE_NO_PHOTO ? R.string.take_photo :R.string.take_new_photo;
+ choices.add(new ChoiceListItem(ChoiceListItem.ID_TAKE_PHOTO,
+ context.getString(resId)));
+ }
+ // Select from Gallery (or "Select new from Gallery")
+ if (mode == MODE_NO_PHOTO || mode == MODE_PHOTO_ALLOW_PRIMARY
+ || mode == MODE_PHOTO_DISALLOW_PRIMARY) {
+ final int resId = mode == MODE_NO_PHOTO ? R.string.pick_photo :R.string.pick_new_photo;
+ choices.add(new ChoiceListItem(ChoiceListItem.ID_PICK_PHOTO,
+ context.getString(resId)));
+ }
+ final ListAdapter adapter = new ArrayAdapter<ChoiceListItem>(context,
+ android.R.layout.select_dialog_item, choices);
+
+ final ListPopupWindow listPopupWindow = new ListPopupWindow(context);
+ final OnItemClickListener clickListener = new OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ final ChoiceListItem choice = choices.get(position);
+ listPopupWindow.dismiss();
+
+ switch (choice.getId()) {
+ case ChoiceListItem.ID_USE_AS_PRIMARY:
+ listener.onUseAsPrimaryChosen();
+ break;
+ case ChoiceListItem.ID_REMOVE:
+ listener.onRemovePictureChose();
+ break;
+ case ChoiceListItem.ID_TAKE_PHOTO:
+ listener.onTakePhotoChosen();
+ break;
+ case ChoiceListItem.ID_PICK_PHOTO:
+ listener.onPickFromGalleryChosen();
+ break;
+ }
+ }
+ };
+
+ listPopupWindow.setAnchorView(anchorView);
+ listPopupWindow.setAdapter(adapter);
+ listPopupWindow.setOnItemClickListener(clickListener);
+ listPopupWindow.setWidth(context.getResources().getDimensionPixelSize(
+ R.dimen.photo_action_popup_width));
+ listPopupWindow.setModal(true);
+ return listPopupWindow;
+ }
+
+ private static final class ChoiceListItem {
+ private final int mId;
+ private final String mCaption;
+
+ public static final int ID_USE_AS_PRIMARY = 0;
+ public static final int ID_TAKE_PHOTO = 1;
+ public static final int ID_PICK_PHOTO = 2;
+ public static final int ID_REMOVE = 3;
+
+ public ChoiceListItem(int id, String caption) {
+ mId = id;
+ mCaption = caption;
+ }
+
+ @Override
+ public String toString() {
+ return mCaption;
+ }
+
+ public int getId() {
+ return mId;
+ }
+ }
+
+ public interface Listener {
+ void onUseAsPrimaryChosen();
+ void onRemovePictureChose();
+ void onTakePhotoChosen();
+ void onPickFromGalleryChosen();
+ }
+}
diff --git a/src/com/android/contacts/views/editor/PhotoDialogFragment.java b/src/com/android/contacts/views/editor/PhotoDialogFragment.java
deleted file mode 100644
index 634733b..0000000
--- a/src/com/android/contacts/views/editor/PhotoDialogFragment.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.contacts.views.editor;
-
-import com.android.contacts.R;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.Fragment;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.widget.ArrayAdapter;
-import android.widget.ListAdapter;
-
-import java.util.ArrayList;
-
-/**
- * Shows a dialog asking the user what to do for a photo. The dialog has to be
- * configured by {@link #setArguments(int, long)}.
- * The result is passed back to the Fragment that is configured by
- * {@link Fragment#setTargetFragment(Fragment, int)}, which
- * has to implement {@link PhotoDialogFragment.Listener}.
- * Does not perform any action by itself.
- */
-public class PhotoDialogFragment extends DialogFragment {
- public static final String TAG = "PhotoDialogFragment";
- private static final String BUNDLE_MODE = "MODE";
- private static final String BUNDLE_RAW_CONTACT_ID = "RAW_CONTACT_ID";
-
- public static final int MODE_NO_PHOTO = 0;
- public static final int MODE_READ_ONLY_ALLOW_PRIMARY = 1;
- public static final int MODE_PHOTO_DISALLOW_PRIMARY = 2;
- public static final int MODE_PHOTO_ALLOW_PRIMARY = 3;
-
- public PhotoDialogFragment() {
- }
-
- public void setArguments(int mode, long rawContactId) {
- final Bundle bundle = new Bundle();
- bundle.putInt(BUNDLE_MODE, mode);
- bundle.putLong(BUNDLE_RAW_CONTACT_ID, rawContactId);
- setArguments(bundle);
- }
-
- private int getMode() {
- return getArguments().getInt(BUNDLE_MODE);
- }
-
- private long getRawContactId() {
- return getArguments().getLong(BUNDLE_RAW_CONTACT_ID);
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- // Wrap our context to inflate list items using correct theme
- final Activity context = getActivity();
-
- int mode = getMode();
- // Build choices, depending on the current mode. We assume this Dialog is never called
- // if there are NO choices (e.g. a read-only picture is already super-primary)
- final ArrayList<ChoiceListItem> choices =
- new ArrayList<PhotoDialogFragment.ChoiceListItem>(4);
- // Use as Primary
- if (mode == MODE_PHOTO_ALLOW_PRIMARY || mode == MODE_READ_ONLY_ALLOW_PRIMARY) {
- choices.add(new ChoiceListItem(ChoiceListItem.ID_USE_AS_PRIMARY,
- context.getString(R.string.use_photo_as_primary)));
- }
- // Remove
- if (mode == MODE_PHOTO_DISALLOW_PRIMARY || mode == MODE_PHOTO_ALLOW_PRIMARY) {
- choices.add(new ChoiceListItem(ChoiceListItem.ID_REMOVE,
- context.getString(R.string.removePhoto)));
- }
- // Take photo (if there is already a photo, it says "Take new photo")
- if (mode == MODE_NO_PHOTO || mode == MODE_PHOTO_ALLOW_PRIMARY
- || mode == MODE_PHOTO_DISALLOW_PRIMARY) {
- final int resId = mode == MODE_NO_PHOTO ? R.string.take_photo :R.string.take_new_photo;
- choices.add(new ChoiceListItem(ChoiceListItem.ID_TAKE_PHOTO, context.getString(resId)));
- }
- // Select from Gallery (or "Select new from Gallery")
- if (mode == MODE_NO_PHOTO || mode == MODE_PHOTO_ALLOW_PRIMARY
- || mode == MODE_PHOTO_DISALLOW_PRIMARY) {
- final int resId = mode == MODE_NO_PHOTO ? R.string.pick_photo :R.string.pick_new_photo;
- choices.add(new ChoiceListItem(ChoiceListItem.ID_PICK_PHOTO, context.getString(resId)));
- }
- final ListAdapter adapter = new ArrayAdapter<ChoiceListItem>(context,
- android.R.layout.select_dialog_item, choices);
-
- final DialogInterface.OnClickListener clickListener =
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- final ChoiceListItem choice = choices.get(which);
-
- final Listener target = (Listener) getTargetFragment();
- switch (choice.getId()) {
- case ChoiceListItem.ID_USE_AS_PRIMARY:
- target.onUseAsPrimaryChosen(getRawContactId());
- break;
- case ChoiceListItem.ID_REMOVE:
- target.onRemovePictureChose(getRawContactId());
- break;
- case ChoiceListItem.ID_TAKE_PHOTO:
- target.onTakePhotoChosen(getRawContactId());
- break;
- case ChoiceListItem.ID_PICK_PHOTO:
- target.onPickFromGalleryChosen(getRawContactId());
- break;
- }
- }
- };
-
- final AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(R.string.contact_photo_dialog_title);
- builder.setSingleChoiceItems(adapter, -1, clickListener);
- return builder.create();
- }
-
- private static final class ChoiceListItem {
- private final int mId;
- private final String mCaption;
-
- public static final int ID_USE_AS_PRIMARY = 0;
- public static final int ID_TAKE_PHOTO = 1;
- public static final int ID_PICK_PHOTO = 2;
- public static final int ID_REMOVE = 3;
-
- public ChoiceListItem(int id, String caption) {
- mId = id;
- mCaption = caption;
- }
-
- @Override
- public String toString() {
- return mCaption;
- }
-
- public int getId() {
- return mId;
- }
- }
-
- public interface Listener {
- void onUseAsPrimaryChosen(long rawContactId);
- void onRemovePictureChose(long rawContactId);
- void onTakePhotoChosen(long rawContactId);
- void onPickFromGalleryChosen(long rawContactId);
- }
-}