Menu handler for details, delete and rotate (cw/ccw)
Change-Id: I714f9a4535b7861cf97f4f6275368e8d13acb67e
diff --git a/new3d/src/com/android/gallery3d/app/AlbumPage.java b/new3d/src/com/android/gallery3d/app/AlbumPage.java
index 6a77b72..7285cdc 100644
--- a/new3d/src/com/android/gallery3d/app/AlbumPage.java
+++ b/new3d/src/com/android/gallery3d/app/AlbumPage.java
@@ -42,6 +42,7 @@
private AdaptiveBackground mBackground;
private AlbumView mAlbumView;
+ private HudMenu mHudMenu;
private HeadUpDisplay mHud;
private SynchronizedHandler mHandler;
private Bitmap mBgImages[];
@@ -116,6 +117,7 @@
@Override
public void onPause() {
mHandler.removeMessages(CHANGE_BACKGROUND);
+ mHudMenu.onPause();
}
private void initializeViews() {
@@ -126,7 +128,8 @@
mAlbumView = new AlbumView(mContext, mSelectionManager);
mRootPane.addComponent(mAlbumView);
mHud = new HeadUpDisplay(mContext.getAndroidContext());
- mHud.setMenu(new HudMenu(mContext, mSelectionManager));
+ mHudMenu = new HudMenu(mContext, mSelectionManager);
+ mHud.setMenu(mHudMenu);
mRootPane.addComponent(mHud);
mAlbumView.setSlotTapListener(this);
diff --git a/new3d/src/com/android/gallery3d/app/AlbumSetPage.java b/new3d/src/com/android/gallery3d/app/AlbumSetPage.java
index 0563400..a1ce4ef 100644
--- a/new3d/src/com/android/gallery3d/app/AlbumSetPage.java
+++ b/new3d/src/com/android/gallery3d/app/AlbumSetPage.java
@@ -41,6 +41,7 @@
private AdaptiveBackground mBackground;
private AlbumSetView mAlbumSetView;
+ private HudMenu mHudMenu;
private HeadUpDisplay mHud;
private SynchronizedHandler mHandler;
@@ -117,6 +118,7 @@
@Override
public void onPause() {
mHandler.removeMessages(CHANGE_BACKGROUND);
+ mHudMenu.onPause();
}
@Override
@@ -142,7 +144,8 @@
mRootPane.addComponent(mAlbumSetView);
mHud = new HeadUpDisplay(mContext.getAndroidContext());
- mHud.setMenu(new HudMenu(mContext, mSelectionManager));
+ mHudMenu = new HudMenu(mContext, mSelectionManager);
+ mHud.setMenu(mHudMenu);
mRootPane.addComponent(mHud);
loadBackgroundBitmap(R.drawable.square,
R.drawable.potrait, R.drawable.landscape);
diff --git a/new3d/src/com/android/gallery3d/data/DataManager.java b/new3d/src/com/android/gallery3d/data/DataManager.java
index fdea01a..95f01e7 100644
--- a/new3d/src/com/android/gallery3d/data/DataManager.java
+++ b/new3d/src/com/android/gallery3d/data/DataManager.java
@@ -28,6 +28,7 @@
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
+import java.util.Map;
// DataManager manages all media sets and media items in the system.
//
@@ -212,4 +213,9 @@
MediaSet parent = getMediaSet(parentId);
return parent.getMediaType(uniqueId);
}
+
+ public Map<Integer, String> getDetails(long uniqueId) {
+ // TODO: implement get details
+ return null;
+ }
}
diff --git a/new3d/src/com/android/gallery3d/ui/HeadUpDisplay.java b/new3d/src/com/android/gallery3d/ui/HeadUpDisplay.java
index efe708b..fdbc3ab 100644
--- a/new3d/src/com/android/gallery3d/ui/HeadUpDisplay.java
+++ b/new3d/src/com/android/gallery3d/ui/HeadUpDisplay.java
@@ -17,11 +17,7 @@
package com.android.gallery3d.ui;
import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.View.MeasureSpec;
diff --git a/new3d/src/com/android/gallery3d/ui/HudMenu.java b/new3d/src/com/android/gallery3d/ui/HudMenu.java
index 78e4ea8..013000d 100644
--- a/new3d/src/com/android/gallery3d/ui/HudMenu.java
+++ b/new3d/src/com/android/gallery3d/ui/HudMenu.java
@@ -16,6 +16,7 @@
package com.android.gallery3d.ui;
+import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -24,11 +25,14 @@
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Handler;
import com.android.gallery3d.R;
import com.android.gallery3d.app.GalleryContext;
import com.android.gallery3d.data.DataManager;
import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.ui.MenuExecutor.MediaOperation;
+import com.android.gallery3d.ui.MenuExecutor.OnProgressUpdateListener;
import java.util.ArrayList;
import java.util.List;
@@ -48,9 +52,63 @@
NinePatchTexture mHighlight;
SelectionManager mSelectionManager;
MenuModel[] mMenuModels;
+ MenuExecutor mMenuExecutor;
MenuItem mShare;
MenuItem mDelete;
MenuItem mMore;
+ ProgressUpdateDialog mDialog;
+
+ private class ProgressUpdateDialog extends ProgressDialog implements OnProgressUpdateListener {
+ Handler mUiHandler;
+ MediaOperation mOperation;
+ boolean mIsDead;
+
+ public ProgressUpdateDialog(int title, int total) {
+ super(mContext.getAndroidContext());
+ setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ mUiHandler = new Handler();
+ setTitle(title);
+ setMax(total);
+ show();
+ }
+
+ /**
+ * The following two methods are callbacks from data thread.
+ */
+ public void onProgressUpdate(final int index, Object result) {
+ mUiHandler.post(new Runnable() {
+ public void run() {
+ if (!mIsDead) setProgress(index);
+ }
+ });
+ }
+
+ public void onProgressComplete() {
+ // SourceMediaSet remains unchanged since SelectionManager is created so race condition
+ // between UI and data threads is not a concern here.
+ // reload has to be called from data thread.
+ mSelectionManager.getSourceMediaSet().reload();
+ // dismiss() can be called from any thread.
+ dismiss();
+ }
+
+ // This will be called when back is pressed or dismiss() is called.
+ protected void onStop() {
+ stop();
+ mSelectionManager.leaveSelectionMode();
+ }
+
+ public void stop() {
+ if (!mIsDead) {
+ mIsDead = true;
+ mOperation.cancel();
+ }
+ }
+
+ public void setOperation(MediaOperation operation) {
+ mOperation = operation;
+ }
+ }
public HudMenu(GalleryContext context, SelectionManager manager) {
mContext = context;
@@ -58,6 +116,14 @@
mHighlight = new NinePatchTexture(context.getAndroidContext(), R.drawable.menu_highlight);
manager.setSelectionListener(this);
mMenuModels = new MenuModel[TOTAL_MODEL_COUNT];
+ mMenuExecutor = new MenuExecutor(context.getDataManager());
+ }
+
+ public void onPause() {
+ if (mDialog != null) {
+ mDialog.stop();
+ mDialog = null;
+ }
}
public MenuBar getTopMenuBar() {
@@ -130,6 +196,31 @@
* Handle the menu operation here.
*/
public void onItemSelected(int position) {
+ MenuItem item = (MenuItem) getView(position);
+ int title;
+ int action = item.getItemId();
+ switch (action) {
+ case MenuExecutor.ACTION_DELETE:
+ title = R.string.delete;
+ break;
+ case MenuExecutor.ACTION_ROTATE_CW:
+ title = R.string.rotate_right;
+ break;
+ case MenuExecutor.ACTION_ROTATE_CCW:
+ title = R.string.rotate_left;
+ break;
+ case MenuExecutor.ACTION_DETAILS:
+ title = R.string.details;
+ break;
+ default:
+ return;
+ }
+
+ ArrayList<Long> ids = mSelectionManager.getSelected(false);
+ if (mDialog != null) mDialog.stop();
+ mDialog = new ProgressUpdateDialog(title, ids.size());
+ MediaOperation operation = mMenuExecutor.startMediaOperation(action, ids, mDialog);
+ mDialog.setOperation(operation);
}
}
@@ -182,7 +273,9 @@
ArrayList<Uri> uris = new ArrayList<Uri>(items.size());
DataManager manager = mContext.getDataManager();
for (Long id : items) {
- uris.add(manager.getMediaItemUri(id));
+ if ((manager.getSupportedOperations(id) & MediaSet.SUPPORT_SHARE) != 0) {
+ uris.add(manager.getMediaItemUri(id));
+ }
}
if (uris.isEmpty()) {
@@ -216,7 +309,7 @@
, mHighlight);
mMenuModels[DELETE_MODEL] = new MenuModel(new MenuItem[] {
new MenuItem(context, R.drawable.icon_delete, R.string.confirm_delete,
- mHighlight),
+ mHighlight, MenuExecutor.ACTION_DELETE),
new MenuItem(context, R.drawable.icon_cancel, R.string.cancel,
mHighlight)
});
@@ -226,11 +319,11 @@
mMore = new MenuItem(context, R.drawable.icon_more, R.string.more, mHighlight);
mMenuModels[MORE_MODEL] = new MenuModel(new MenuItem[] {
new MenuItem(context, R.drawable.icon_details, R.string.details,
- mHighlight),
+ mHighlight, MenuExecutor.ACTION_DETAILS),
new MenuItem(context, R.drawable.icon_details, R.string.rotate_right,
- mHighlight),
+ mHighlight, MenuExecutor.ACTION_ROTATE_CW),
new MenuItem(context, R.drawable.icon_details, R.string.rotate_left,
- mHighlight),
+ mHighlight, MenuExecutor.ACTION_ROTATE_CCW),
});
mBottomBar.addComponent(mMore);
}
diff --git a/new3d/src/com/android/gallery3d/ui/MenuExecutor.java b/new3d/src/com/android/gallery3d/ui/MenuExecutor.java
new file mode 100644
index 0000000..eb2fe0e
--- /dev/null
+++ b/new3d/src/com/android/gallery3d/ui/MenuExecutor.java
@@ -0,0 +1,123 @@
+/*
+ * 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.gallery3d.ui;
+
+import android.os.Handler;
+
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.FutureTask;
+
+import java.util.ArrayList;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+
+public class MenuExecutor {
+ private static final String TAG = "MenuExecutor";
+
+ public static final int ACTION_DELETE = 1;
+ public static final int ACTION_DETAILS = 2;
+ public static final int ACTION_ROTATE_CW = 3;
+ public static final int ACTION_ROTATE_CCW = 4;
+
+ private Handler mHandler;
+ private DataManager mDataManager;
+
+ public MenuExecutor(DataManager manager) {
+ mDataManager = manager;
+ mHandler = new Handler(manager.getDataLooper());
+ }
+
+ public static interface OnProgressUpdateListener {
+ public void onProgressUpdate(int index, Object result);
+ public void onProgressComplete();
+ }
+
+ public class MediaOperation implements Callable<Void>, FutureListener<Void> {
+ ArrayList<Long> mItems;
+ int mOperation;
+ int mIndex;
+ FutureTask<Void> mTask;
+ OnProgressUpdateListener mProgressUpdater;
+
+ public MediaOperation(int operation, ArrayList<Long> items,
+ OnProgressUpdateListener progressUpdater) {
+ mItems = items;
+ mIndex = 0;
+ mOperation = operation;
+ mProgressUpdater = progressUpdater;
+ }
+
+ public Void call() throws Exception {
+ for (long id : mItems) {
+ if (mTask.isCancelled()) return null;
+
+ Object result = null;
+ switch (mOperation) {
+ case ACTION_DELETE:
+ mDataManager.delete(id);
+ break;
+ case ACTION_ROTATE_CW:
+ mDataManager.rotate(id, -90);
+ break;
+ case ACTION_ROTATE_CCW:
+ mDataManager.rotate(id, 90);
+ break;
+ case ACTION_DETAILS:
+ result = mDataManager.getDetails(id);
+ break;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ mProgressUpdater.onProgressUpdate(mIndex++, result);
+ }
+ return null;
+ }
+
+ public void setTask(FutureTask<Void> task) {
+ mTask = task;
+ }
+
+ public void onFutureDone(Future<? extends Void> future) {
+ mProgressUpdater.onProgressComplete();
+ }
+
+ public void cancel() {
+ mTask.requestCancel();
+ try {
+ mTask.get();
+ } catch (CancellationException ce) {
+ // ignore it.
+ } catch (ExecutionException ee) {
+ // ignore it.
+ } catch (InterruptedException ie) {
+ // ignore it.
+ }
+ }
+ }
+
+ public MediaOperation startMediaOperation(int opcode, ArrayList<Long> items,
+ final OnProgressUpdateListener listener) {
+ MediaOperation operation = new MediaOperation(opcode, items, listener);
+ FutureTask<Void> task = new FutureTask<Void>(operation, operation);
+ operation.setTask(task);
+ mHandler.post(task);
+ return operation;
+ }
+}
diff --git a/new3d/src/com/android/gallery3d/ui/MenuItem.java b/new3d/src/com/android/gallery3d/ui/MenuItem.java
index 4e135aa..8356c23 100644
--- a/new3d/src/com/android/gallery3d/ui/MenuItem.java
+++ b/new3d/src/com/android/gallery3d/ui/MenuItem.java
@@ -20,18 +20,29 @@
import android.graphics.Rect;
public class MenuItem extends IconLabel {
+ private static final int ACTION_NONE = 0;
private boolean mSelected;
private Texture mHighlight;
+ private int mItemId;
public MenuItem(Context context, int icon, int label, Texture highlight) {
+ this(context, icon, label, highlight, ACTION_NONE);
+ }
+
+ public MenuItem(Context context, int icon, int label, Texture highlight, int itemId) {
super(context, icon, label);
mHighlight = highlight;
+ mItemId = itemId;
}
public MenuItem(Context context, BasicTexture texture, String label) {
super(context, texture, label);
}
+ public int getItemId() {
+ return mItemId;
+ }
+
public void setHighlight(Texture texture) {
mHighlight = texture;
}