summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/app/AlbumSetPage.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/app/AlbumSetPage.java')
-rw-r--r--src/com/android/gallery3d/app/AlbumSetPage.java586
1 files changed, 586 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/app/AlbumSetPage.java b/src/com/android/gallery3d/app/AlbumSetPage.java
new file mode 100644
index 000000000..688ff81f2
--- /dev/null
+++ b/src/com/android/gallery3d/app/AlbumSetPage.java
@@ -0,0 +1,586 @@
+/*
+ * 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.app;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.data.DataManager;
+import com.android.gallery3d.data.MediaDetails;
+import com.android.gallery3d.data.MediaObject;
+import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.picasasource.PicasaSource;
+import com.android.gallery3d.settings.GallerySettings;
+import com.android.gallery3d.ui.ActionModeHandler;
+import com.android.gallery3d.ui.ActionModeHandler.ActionModeListener;
+import com.android.gallery3d.ui.AlbumSetView;
+import com.android.gallery3d.ui.DetailsWindow;
+import com.android.gallery3d.ui.DetailsWindow.CloseListener;
+import com.android.gallery3d.ui.GLCanvas;
+import com.android.gallery3d.ui.GLView;
+import com.android.gallery3d.ui.GridDrawer;
+import com.android.gallery3d.ui.HighlightDrawer;
+import com.android.gallery3d.ui.PositionProvider;
+import com.android.gallery3d.ui.PositionRepository;
+import com.android.gallery3d.ui.PositionRepository.Position;
+import com.android.gallery3d.ui.SelectionManager;
+import com.android.gallery3d.ui.SlotView;
+import com.android.gallery3d.ui.StaticBackground;
+import com.android.gallery3d.ui.SynchronizedHandler;
+import com.android.gallery3d.util.GalleryUtils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Message;
+import android.provider.MediaStore;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View.MeasureSpec;
+import android.widget.Toast;
+
+public class AlbumSetPage extends ActivityState implements
+ SelectionManager.SelectionListener, GalleryActionBar.ClusterRunner,
+ EyePosition.EyePositionListener {
+ @SuppressWarnings("unused")
+ private static final String TAG = "AlbumSetPage";
+
+ public static final String KEY_MEDIA_PATH = "media-path";
+ public static final String KEY_SET_TITLE = "set-title";
+ public static final String KEY_SET_SUBTITLE = "set-subtitle";
+ private static final int DATA_CACHE_SIZE = 256;
+ private static final int REQUEST_DO_ANIMATION = 1;
+ private static final int MSG_GOTO_MANAGE_CACHE_PAGE = 1;
+
+ private boolean mIsActive = false;
+ private StaticBackground mStaticBackground;
+ private AlbumSetView mAlbumSetView;
+
+ private MediaSet mMediaSet;
+ private String mTitle;
+ private String mSubtitle;
+ private boolean mShowClusterTabs;
+
+ protected SelectionManager mSelectionManager;
+ private AlbumSetDataAdapter mAlbumSetDataAdapter;
+ private GridDrawer mGridDrawer;
+ private HighlightDrawer mHighlightDrawer;
+
+ private boolean mGetContent;
+ private boolean mGetAlbum;
+ private ActionMode mActionMode;
+ private ActionModeHandler mActionModeHandler;
+ private DetailsWindow mDetailsWindow;
+ private boolean mShowDetails;
+ private EyePosition mEyePosition;
+
+ // The eyes' position of the user, the origin is at the center of the
+ // device and the unit is in pixels.
+ private float mX;
+ private float mY;
+ private float mZ;
+
+ private SynchronizedHandler mHandler;
+
+ private GLView mRootPane = new GLView() {
+ private float mMatrix[] = new float[16];
+
+ @Override
+ protected void onLayout(
+ boolean changed, int left, int top, int right, int bottom) {
+ mStaticBackground.layout(0, 0, right - left, bottom - top);
+ mEyePosition.resetPosition();
+
+ int slotViewTop = GalleryActionBar.getHeight((Activity) mActivity);
+ int slotViewBottom = bottom - top;
+ int slotViewRight = right - left;
+
+ if (mShowDetails) {
+ mDetailsWindow.measure(
+ MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ int width = mDetailsWindow.getMeasuredWidth();
+ int detailLeft = right - left - width;
+ slotViewRight = detailLeft;
+ mDetailsWindow.layout(detailLeft, slotViewTop, detailLeft + width,
+ bottom - top);
+ } else {
+ mAlbumSetView.setSelectionDrawer(mGridDrawer);
+ }
+
+ mAlbumSetView.layout(0, slotViewTop, slotViewRight, slotViewBottom);
+ PositionRepository.getInstance(mActivity).setOffset(
+ 0, slotViewTop);
+ }
+
+ @Override
+ protected void render(GLCanvas canvas) {
+ canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
+ GalleryUtils.setViewPointMatrix(mMatrix,
+ getWidth() / 2 + mX, getHeight() / 2 + mY, mZ);
+ canvas.multiplyMatrix(mMatrix, 0);
+ super.render(canvas);
+ canvas.restore();
+ }
+ };
+
+ @Override
+ public void onEyePositionChanged(float x, float y, float z) {
+ mRootPane.lockRendering();
+ mX = x;
+ mY = y;
+ mZ = z;
+ mRootPane.unlockRendering();
+ mRootPane.invalidate();
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (mShowDetails) {
+ hideDetails();
+ } else if (mSelectionManager.inSelectionMode()) {
+ mSelectionManager.leaveSelectionMode();
+ } else {
+ mAlbumSetView.savePositions(
+ PositionRepository.getInstance(mActivity));
+ super.onBackPressed();
+ }
+ }
+
+ private void savePositions(int slotIndex, int center[]) {
+ Rect offset = new Rect();
+ mRootPane.getBoundsOf(mAlbumSetView, offset);
+ mAlbumSetView.savePositions(PositionRepository.getInstance(mActivity));
+ Rect r = mAlbumSetView.getSlotRect(slotIndex);
+ int scrollX = mAlbumSetView.getScrollX();
+ int scrollY = mAlbumSetView.getScrollY();
+ center[0] = offset.left + (r.left + r.right) / 2 - scrollX;
+ center[1] = offset.top + (r.top + r.bottom) / 2 - scrollY;
+ }
+
+ public void onSingleTapUp(int slotIndex) {
+ MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
+ if (targetSet == null) return; // Content is dirty, we shall reload soon
+
+ if (mShowDetails) {
+ Path path = targetSet.getPath();
+ mHighlightDrawer.setHighlightItem(path);
+ mDetailsWindow.reloadDetails(slotIndex);
+ } else if (!mSelectionManager.inSelectionMode()) {
+ Bundle data = new Bundle(getData());
+ String mediaPath = targetSet.getPath().toString();
+ int[] center = new int[2];
+ savePositions(slotIndex, center);
+ data.putIntArray(AlbumPage.KEY_SET_CENTER, center);
+ if (mGetAlbum && targetSet.isLeafAlbum()) {
+ Activity activity = (Activity) mActivity;
+ Intent result = new Intent()
+ .putExtra(AlbumPicker.KEY_ALBUM_PATH, targetSet.getPath().toString());
+ activity.setResult(Activity.RESULT_OK, result);
+ activity.finish();
+ } else if (targetSet.getSubMediaSetCount() > 0) {
+ data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
+ mActivity.getStateManager().startStateForResult(
+ AlbumSetPage.class, REQUEST_DO_ANIMATION, data);
+ } else {
+ if (!mGetContent && (targetSet.getSupportedOperations()
+ & MediaObject.SUPPORT_IMPORT) != 0) {
+ data.putBoolean(AlbumPage.KEY_AUTO_SELECT_ALL, true);
+ }
+ data.putString(AlbumPage.KEY_MEDIA_PATH, mediaPath);
+ boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class);
+ // We only show cluster menu in the first AlbumPage in stack
+ data.putBoolean(AlbumPage.KEY_SHOW_CLUSTER_MENU, !inAlbum);
+ mActivity.getStateManager().startStateForResult(
+ AlbumPage.class, REQUEST_DO_ANIMATION, data);
+ }
+ } else {
+ mSelectionManager.toggle(targetSet.getPath());
+ mAlbumSetView.invalidate();
+ }
+ }
+
+ public void onLongTap(int slotIndex) {
+ if (mGetContent || mGetAlbum) return;
+ if (mShowDetails) {
+ onSingleTapUp(slotIndex);
+ } else {
+ MediaSet set = mAlbumSetDataAdapter.getMediaSet(slotIndex);
+ if (set == null) return;
+ mSelectionManager.setAutoLeaveSelectionMode(true);
+ mSelectionManager.toggle(set.getPath());
+ mAlbumSetView.invalidate();
+ }
+ }
+
+ public void doCluster(int clusterType) {
+ String basePath = mMediaSet.getPath().toString();
+ String newPath = FilterUtils.switchClusterPath(basePath, clusterType);
+ Bundle data = new Bundle(getData());
+ data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
+ mAlbumSetView.savePositions(PositionRepository.getInstance(mActivity));
+ mActivity.getStateManager().switchState(this, AlbumSetPage.class, data);
+ }
+
+ public void doFilter(int filterType) {
+ String basePath = mMediaSet.getPath().toString();
+ String newPath = FilterUtils.switchFilterPath(basePath, filterType);
+ Bundle data = new Bundle(getData());
+ data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
+ mAlbumSetView.savePositions(PositionRepository.getInstance(mActivity));
+ mActivity.getStateManager().switchState(this, AlbumSetPage.class, data);
+ }
+
+ public void onOperationComplete() {
+ mAlbumSetView.invalidate();
+ // TODO: enable animation
+ }
+
+ @Override
+ public void onCreate(Bundle data, Bundle restoreState) {
+ mHandler = new SynchronizedHandler(mActivity.getGLRoot()) {
+ @Override
+ public void handleMessage(Message message) {
+ Utils.assertTrue(message.what == MSG_GOTO_MANAGE_CACHE_PAGE);
+ Bundle data = new Bundle();
+ String mediaPath = mActivity.getDataManager().getTopSetPath(
+ DataManager.INCLUDE_ALL);
+ data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
+ mActivity.getStateManager().startState(ManageCachePage.class, data);
+ }
+ };
+
+ initializeViews();
+ initializeData(data);
+ mGetContent = data.getBoolean(Gallery.KEY_GET_CONTENT, false);
+ mGetAlbum = data.getBoolean(Gallery.KEY_GET_ALBUM, false);
+ mTitle = data.getString(AlbumSetPage.KEY_SET_TITLE);
+ mSubtitle = data.getString(AlbumSetPage.KEY_SET_SUBTITLE);
+ mEyePosition = new EyePosition(mActivity.getAndroidContext(), this);
+
+ startTransition();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mIsActive = false;
+ mActionModeHandler.pause();
+ mAlbumSetDataAdapter.pause();
+ mAlbumSetView.pause();
+ mEyePosition.pause();
+ if (mDetailsWindow != null) {
+ mDetailsWindow.pause();
+ }
+ GalleryActionBar actionBar = mActivity.getGalleryActionBar();
+ if (actionBar != null) actionBar.hideClusterTabs();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mIsActive = true;
+ setContentPane(mRootPane);
+ mAlbumSetDataAdapter.resume();
+ mAlbumSetView.resume();
+ mEyePosition.resume();
+ mActionModeHandler.resume();
+ GalleryActionBar actionBar = mActivity.getGalleryActionBar();
+ if (mShowClusterTabs && actionBar != null) actionBar.showClusterTabs(this);
+ }
+
+ private void initializeData(Bundle data) {
+ String mediaPath = data.getString(AlbumSetPage.KEY_MEDIA_PATH);
+ mMediaSet = mActivity.getDataManager().getMediaSet(mediaPath);
+ mSelectionManager.setSourceMediaSet(mMediaSet);
+ mAlbumSetDataAdapter = new AlbumSetDataAdapter(
+ mActivity, mMediaSet, DATA_CACHE_SIZE);
+ mAlbumSetDataAdapter.setLoadingListener(new MyLoadingListener());
+ mAlbumSetView.setModel(mAlbumSetDataAdapter);
+ }
+
+ private void initializeViews() {
+ mSelectionManager = new SelectionManager(mActivity, true);
+ mSelectionManager.setSelectionListener(this);
+ mStaticBackground = new StaticBackground(mActivity.getAndroidContext());
+ mRootPane.addComponent(mStaticBackground);
+
+ mGridDrawer = new GridDrawer((Context) mActivity, mSelectionManager);
+ Config.AlbumSetPage config = Config.AlbumSetPage.get((Context) mActivity);
+ mAlbumSetView = new AlbumSetView(mActivity, mGridDrawer,
+ config.slotWidth, config.slotHeight,
+ config.displayItemSize, config.labelFontSize,
+ config.labelOffsetY, config.labelMargin);
+ mAlbumSetView.setListener(new SlotView.SimpleListener() {
+ @Override
+ public void onSingleTapUp(int slotIndex) {
+ AlbumSetPage.this.onSingleTapUp(slotIndex);
+ }
+ @Override
+ public void onLongTap(int slotIndex) {
+ AlbumSetPage.this.onLongTap(slotIndex);
+ }
+ });
+
+ mActionModeHandler = new ActionModeHandler(mActivity, mSelectionManager);
+ mActionModeHandler.setActionModeListener(new ActionModeListener() {
+ public boolean onActionItemClicked(MenuItem item) {
+ return onItemSelected(item);
+ }
+ });
+ mRootPane.addComponent(mAlbumSetView);
+
+ mStaticBackground.setImage(R.drawable.background,
+ R.drawable.background_portrait);
+ }
+
+ @Override
+ protected boolean onCreateActionBar(Menu menu) {
+ Activity activity = (Activity) mActivity;
+ GalleryActionBar actionBar = mActivity.getGalleryActionBar();
+ MenuInflater inflater = activity.getMenuInflater();
+
+ final boolean inAlbum = mActivity.getStateManager().hasStateClass(
+ AlbumPage.class);
+
+ if (mGetContent) {
+ inflater.inflate(R.menu.pickup, menu);
+ int typeBits = mData.getInt(
+ Gallery.KEY_TYPE_BITS, DataManager.INCLUDE_IMAGE);
+ int id = R.string.select_image;
+ if ((typeBits & DataManager.INCLUDE_VIDEO) != 0) {
+ id = (typeBits & DataManager.INCLUDE_IMAGE) == 0
+ ? R.string.select_video
+ : R.string.select_item;
+ }
+ actionBar.setTitle(id);
+ } else if (mGetAlbum) {
+ inflater.inflate(R.menu.pickup, menu);
+ actionBar.setTitle(R.string.select_album);
+ } else {
+ mShowClusterTabs = !inAlbum;
+ inflater.inflate(R.menu.albumset, menu);
+ if (mTitle != null) {
+ actionBar.setTitle(mTitle);
+ } else {
+ actionBar.setTitle(activity.getApplicationInfo().labelRes);
+ }
+ MenuItem selectItem = menu.findItem(R.id.action_select);
+
+ if (selectItem != null) {
+ boolean selectAlbums = !inAlbum &&
+ actionBar.getClusterTypeAction() == FilterUtils.CLUSTER_BY_ALBUM;
+ if (selectAlbums) {
+ selectItem.setTitle(R.string.select_album);
+ } else {
+ selectItem.setTitle(R.string.select_group);
+ }
+ }
+
+ MenuItem switchCamera = menu.findItem(R.id.action_camera);
+ if (switchCamera != null) {
+ switchCamera.setVisible(GalleryUtils.isCameraAvailable(activity));
+ }
+
+ actionBar.setSubtitle(mSubtitle);
+ }
+ return true;
+ }
+
+ @Override
+ protected boolean onItemSelected(MenuItem item) {
+ Activity activity = (Activity) mActivity;
+ switch (item.getItemId()) {
+ case R.id.action_select:
+ mSelectionManager.setAutoLeaveSelectionMode(false);
+ mSelectionManager.enterSelectionMode();
+ return true;
+ case R.id.action_details:
+ if (mAlbumSetDataAdapter.size() != 0) {
+ if (mShowDetails) {
+ hideDetails();
+ } else {
+ showDetails();
+ }
+ } else {
+ Toast.makeText(activity,
+ activity.getText(R.string.no_albums_alert),
+ Toast.LENGTH_SHORT).show();
+ }
+ return true;
+ case R.id.action_camera: {
+ Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA)
+ .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
+ | Intent.FLAG_ACTIVITY_NEW_TASK);
+ activity.startActivity(intent);
+ return true;
+ }
+ case R.id.action_manage_offline: {
+ mHandler.sendEmptyMessage(MSG_GOTO_MANAGE_CACHE_PAGE);
+ return true;
+ }
+ case R.id.action_sync_picasa_albums: {
+ PicasaSource.requestSync(activity);
+ return true;
+ }
+ case R.id.action_settings: {
+ activity.startActivity(new Intent(activity, GallerySettings.class));
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ protected void onStateResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case REQUEST_DO_ANIMATION: {
+ startTransition();
+ }
+ }
+ }
+
+ private void startTransition() {
+ final PositionRepository repository =
+ PositionRepository.getInstance(mActivity);
+ mAlbumSetView.startTransition(new PositionProvider() {
+ private Position mTempPosition = new Position();
+ public Position getPosition(long identity, Position target) {
+ Position p = repository.get(identity);
+ if (p == null) {
+ p = mTempPosition;
+ p.set(target.x, target.y, 128, target.theta, 1);
+ }
+ return p;
+ }
+ });
+ }
+
+ private String getSelectedString() {
+ GalleryActionBar actionBar = mActivity.getGalleryActionBar();
+ int count = mSelectionManager.getSelectedCount();
+ int action = actionBar.getClusterTypeAction();
+ int string = action == FilterUtils.CLUSTER_BY_ALBUM
+ ? R.plurals.number_of_albums_selected
+ : R.plurals.number_of_groups_selected;
+ String format = mActivity.getResources().getQuantityString(string, count);
+ return String.format(format, count);
+ }
+
+ public void onSelectionModeChange(int mode) {
+
+ switch (mode) {
+ case SelectionManager.ENTER_SELECTION_MODE: {
+ mActivity.getGalleryActionBar().hideClusterTabs();
+ mActionMode = mActionModeHandler.startActionMode();
+ break;
+ }
+ case SelectionManager.LEAVE_SELECTION_MODE: {
+ mActionMode.finish();
+ mActivity.getGalleryActionBar().showClusterTabs(this);
+ mRootPane.invalidate();
+ break;
+ }
+ case SelectionManager.SELECT_ALL_MODE: {
+ mActionModeHandler.setTitle(getSelectedString());
+ mRootPane.invalidate();
+ break;
+ }
+ }
+ }
+
+ public void onSelectionChange(Path path, boolean selected) {
+ Utils.assertTrue(mActionMode != null);
+ mActionModeHandler.setTitle(getSelectedString());
+ mActionModeHandler.updateSupportedOperation(path, selected);
+ }
+
+ private void hideDetails() {
+ mShowDetails = false;
+ mAlbumSetView.setSelectionDrawer(mGridDrawer);
+ mDetailsWindow.hide();
+ }
+
+ private void showDetails() {
+ mShowDetails = true;
+ if (mDetailsWindow == null) {
+ mHighlightDrawer = new HighlightDrawer(mActivity.getAndroidContext());
+ mDetailsWindow = new DetailsWindow(mActivity, new MyDetailsSource());
+ mDetailsWindow.setCloseListener(new CloseListener() {
+ public void onClose() {
+ hideDetails();
+ }
+ });
+ mRootPane.addComponent(mDetailsWindow);
+ }
+ mAlbumSetView.setSelectionDrawer(mHighlightDrawer);
+ mDetailsWindow.show();
+ }
+
+ private class MyLoadingListener implements LoadingListener {
+ public void onLoadingStarted() {
+ GalleryUtils.setSpinnerVisibility((Activity) mActivity, true);
+ }
+
+ public void onLoadingFinished() {
+ if (!mIsActive) return;
+ GalleryUtils.setSpinnerVisibility((Activity) mActivity, false);
+ if (mAlbumSetDataAdapter.size() == 0) {
+ Toast.makeText((Context) mActivity,
+ R.string.empty_album, Toast.LENGTH_LONG).show();
+ if (mActivity.getStateManager().getStateCount() > 1) {
+ mActivity.getStateManager().finishState(AlbumSetPage.this);
+ }
+ }
+ }
+ }
+
+ private class MyDetailsSource implements DetailsWindow.DetailsSource {
+ private int mIndex;
+ public int size() {
+ return mAlbumSetDataAdapter.size();
+ }
+
+ // If requested index is out of active window, suggest a valid index.
+ // If there is no valid index available, return -1.
+ public int findIndex(int indexHint) {
+ if (mAlbumSetDataAdapter.isActive(indexHint)) {
+ mIndex = indexHint;
+ } else {
+ mIndex = mAlbumSetDataAdapter.getActiveStart();
+ if (!mAlbumSetDataAdapter.isActive(mIndex)) {
+ return -1;
+ }
+ }
+ return mIndex;
+ }
+
+ public MediaDetails getDetails() {
+ MediaObject item = mAlbumSetDataAdapter.getMediaSet(mIndex);
+ if (item != null) {
+ mHighlightDrawer.setHighlightItem(item.getPath());
+ return item.getDetails();
+ } else {
+ return null;
+ }
+ }
+ }
+}