AlbumSetPage.java revision 1f4e6d14bba7290ea0268fbde28ffc664d4f7004
1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project
3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License.
6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at
7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software
11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and
14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License.
15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */
16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.app;
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
191f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.app.Activity;
201f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.content.Context;
211f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.content.Intent;
221f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.graphics.Rect;
231f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.os.Bundle;
241f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.os.Vibrator;
251f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.provider.MediaStore;
261f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.view.ActionMode;
271f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.view.Menu;
281f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.view.MenuInflater;
291f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.view.MenuItem;
301f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chenimport android.widget.Toast;
311f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chen
32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.R;
33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.common.Utils;
34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.DataManager;
35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.MediaDetails;
36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.MediaObject;
37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.MediaSet;
38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.Path;
39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.picasasource.PicasaSource;
40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.settings.GallerySettings;
41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.ActionModeHandler;
42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.ActionModeHandler.ActionModeListener;
43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.AlbumSetView;
444105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chenimport com.android.gallery3d.ui.DetailsHelper;
454105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chenimport com.android.gallery3d.ui.DetailsHelper.CloseListener;
46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.GLCanvas;
47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.GLView;
48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.GridDrawer;
49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.HighlightDrawer;
50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.PositionProvider;
51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.PositionRepository;
52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.PositionRepository.Position;
53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.SelectionManager;
54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.SlotView;
55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.StaticBackground;
56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.GalleryUtils;
57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class AlbumSetPage extends ActivityState implements
59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        SelectionManager.SelectionListener, GalleryActionBar.ClusterRunner,
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        EyePosition.EyePositionListener {
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @SuppressWarnings("unused")
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "AlbumSetPage";
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static final String KEY_MEDIA_PATH = "media-path";
65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static final String KEY_SET_TITLE = "set-title";
66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public static final String KEY_SET_SUBTITLE = "set-subtitle";
67b5f8d908c5dd287052cd49eddaf1f82d858cca03Ray Chen    public static final String KEY_SELECTED_CLUSTER_TYPE = "selected-cluster";
686cf807453fb58ccd4cc513ff187b306c7090e67cOwen Lin
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int DATA_CACHE_SIZE = 256;
70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int REQUEST_DO_ANIMATION = 1;
71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final int MSG_GOTO_MANAGE_CACHE_PAGE = 1;
72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private boolean mIsActive = false;
74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private StaticBackground mStaticBackground;
75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private AlbumSetView mAlbumSetView;
76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private MediaSet mMediaSet;
78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private String mTitle;
79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private String mSubtitle;
80b5f8d908c5dd287052cd49eddaf1f82d858cca03Ray Chen    private boolean mShowClusterMenu;
81b5f8d908c5dd287052cd49eddaf1f82d858cca03Ray Chen    private int mSelectedAction;
821f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chen    private Vibrator mVibrator;
83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected SelectionManager mSelectionManager;
85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private AlbumSetDataAdapter mAlbumSetDataAdapter;
86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private GridDrawer mGridDrawer;
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private HighlightDrawer mHighlightDrawer;
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private boolean mGetContent;
90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private boolean mGetAlbum;
91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private ActionMode mActionMode;
92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private ActionModeHandler mActionModeHandler;
934105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen    private DetailsHelper mDetailsHelper;
944105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen    private MyDetailsSource mDetailsSource;
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private boolean mShowDetails;
96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private EyePosition mEyePosition;
97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // The eyes' position of the user, the origin is at the center of the
99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    // device and the unit is in pixels.
100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private float mX;
101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private float mY;
102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private float mZ;
103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private GLView mRootPane = new GLView() {
105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        private float mMatrix[] = new float[16];
106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        protected void onLayout(
109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                boolean changed, int left, int top, int right, int bottom) {
110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mStaticBackground.layout(0, 0, right - left, bottom - top);
111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mEyePosition.resetPosition();
112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int slotViewTop = GalleryActionBar.getHeight((Activity) mActivity);
114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int slotViewBottom = bottom - top;
115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int slotViewRight = right - left;
116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (mShowDetails) {
1184105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen                mDetailsHelper.layout(left, slotViewTop, right, bottom);
119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else {
120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mAlbumSetView.setSelectionDrawer(mGridDrawer);
121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlbumSetView.layout(0, slotViewTop, slotViewRight, slotViewBottom);
124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            PositionRepository.getInstance(mActivity).setOffset(
125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    0, slotViewTop);
126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        protected void render(GLCanvas canvas) {
130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            GalleryUtils.setViewPointMatrix(mMatrix,
132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    getWidth() / 2 + mX, getHeight() / 2 + mY, mZ);
133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            canvas.multiplyMatrix(mMatrix, 0);
134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            super.render(canvas);
135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            canvas.restore();
136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    };
138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onEyePositionChanged(float x, float y, float z) {
141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mRootPane.lockRendering();
142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mX = x;
143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mY = y;
144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mZ = z;
145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mRootPane.unlockRendering();
146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mRootPane.invalidate();
147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onBackPressed() {
151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mShowDetails) {
152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            hideDetails();
153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else if (mSelectionManager.inSelectionMode()) {
154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mSelectionManager.leaveSelectionMode();
155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else {
156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlbumSetView.savePositions(
157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    PositionRepository.getInstance(mActivity));
158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            super.onBackPressed();
159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void savePositions(int slotIndex, int center[]) {
163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Rect offset = new Rect();
164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mRootPane.getBoundsOf(mAlbumSetView, offset);
165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetView.savePositions(PositionRepository.getInstance(mActivity));
166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Rect r = mAlbumSetView.getSlotRect(slotIndex);
167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int scrollX = mAlbumSetView.getScrollX();
168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int scrollY = mAlbumSetView.getScrollY();
169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        center[0] = offset.left + (r.left + r.right) / 2 - scrollX;
170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        center[1] = offset.top + (r.top + r.bottom) / 2 - scrollY;
171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onSingleTapUp(int slotIndex) {
174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (targetSet == null) return; // Content is dirty, we shall reload soon
176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mShowDetails) {
178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Path path = targetSet.getPath();
179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mHighlightDrawer.setHighlightItem(path);
1804105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen            mDetailsHelper.reloadDetails(slotIndex);
181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else if (!mSelectionManager.inSelectionMode()) {
182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Bundle data = new Bundle(getData());
183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            String mediaPath = targetSet.getPath().toString();
184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int[] center = new int[2];
185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            savePositions(slotIndex, center);
186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            data.putIntArray(AlbumPage.KEY_SET_CENTER, center);
187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (mGetAlbum && targetSet.isLeafAlbum()) {
188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                Activity activity = (Activity) mActivity;
189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                Intent result = new Intent()
190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        .putExtra(AlbumPicker.KEY_ALBUM_PATH, targetSet.getPath().toString());
191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                activity.setResult(Activity.RESULT_OK, result);
192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                activity.finish();
193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else if (targetSet.getSubMediaSetCount() > 0) {
194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mActivity.getStateManager().startStateForResult(
196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        AlbumSetPage.class, REQUEST_DO_ANIMATION, data);
197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else {
198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (!mGetContent && (targetSet.getSupportedOperations()
199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        & MediaObject.SUPPORT_IMPORT) != 0) {
200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    data.putBoolean(AlbumPage.KEY_AUTO_SELECT_ALL, true);
201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                data.putString(AlbumPage.KEY_MEDIA_PATH, mediaPath);
203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                boolean inAlbum = mActivity.getStateManager().hasStateClass(AlbumPage.class);
204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                // We only show cluster menu in the first AlbumPage in stack
205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                data.putBoolean(AlbumPage.KEY_SHOW_CLUSTER_MENU, !inAlbum);
206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mActivity.getStateManager().startStateForResult(
207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        AlbumPage.class, REQUEST_DO_ANIMATION, data);
208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else {
210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mSelectionManager.toggle(targetSet.getPath());
211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlbumSetView.invalidate();
212f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
214f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
215bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    private void onDown(int index) {
216bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang        MediaSet set = mAlbumSetDataAdapter.getMediaSet(index);
217bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang        Path path = (set == null) ? null : set.getPath();
218bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang        mSelectionManager.setPressedPath(path);
219bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang        mAlbumSetView.invalidate();
220bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    }
221bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
222bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    private void onUp() {
223bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang        mSelectionManager.setPressedPath(null);
224bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang        mAlbumSetView.invalidate();
225bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang    }
226bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onLongTap(int slotIndex) {
228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mGetContent || mGetAlbum) return;
229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mShowDetails) {
230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            onSingleTapUp(slotIndex);
231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else {
232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaSet set = mAlbumSetDataAdapter.getMediaSet(slotIndex);
233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (set == null) return;
234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mSelectionManager.setAutoLeaveSelectionMode(true);
235f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mSelectionManager.toggle(set.getPath());
2364105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen            mDetailsSource.findIndex(slotIndex);
237f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlbumSetView.invalidate();
238f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
240f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
241f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void doCluster(int clusterType) {
242e9ae772f3400d53d24ce3d2834bd5866de599406Ray Chen        Log.v(TAG, "doCluster: " + clusterType);
243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String basePath = mMediaSet.getPath().toString();
244f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String newPath = FilterUtils.switchClusterPath(basePath, clusterType);
245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Bundle data = new Bundle(getData());
246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
247b5f8d908c5dd287052cd49eddaf1f82d858cca03Ray Chen        data.putInt(KEY_SELECTED_CLUSTER_TYPE, clusterType);
248f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetView.savePositions(PositionRepository.getInstance(mActivity));
249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mActivity.getStateManager().switchState(this, AlbumSetPage.class, data);
250f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
251f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void doFilter(int filterType) {
253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String basePath = mMediaSet.getPath().toString();
254f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String newPath = FilterUtils.switchFilterPath(basePath, filterType);
255f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Bundle data = new Bundle(getData());
256f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        data.putString(AlbumSetPage.KEY_MEDIA_PATH, newPath);
257f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetView.savePositions(PositionRepository.getInstance(mActivity));
258f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mActivity.getStateManager().switchState(this, AlbumSetPage.class, data);
259f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
260f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onOperationComplete() {
262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetView.invalidate();
263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // TODO: enable animation
264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
265f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
266f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
267f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onCreate(Bundle data, Bundle restoreState) {
268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        initializeViews();
269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        initializeData(data);
2701f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chen        Context context = mActivity.getAndroidContext();
271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mGetContent = data.getBoolean(Gallery.KEY_GET_CONTENT, false);
272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mGetAlbum = data.getBoolean(Gallery.KEY_GET_ALBUM, false);
273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mTitle = data.getString(AlbumSetPage.KEY_SET_TITLE);
274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mSubtitle = data.getString(AlbumSetPage.KEY_SET_SUBTITLE);
2751f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chen        mEyePosition = new EyePosition(context, this);
2764105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen        mDetailsSource = new MyDetailsSource();
2771f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chen        mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
278a79bbef0ffe0b99cb8d0e5dcedd3082abc61559cWei Huang        GalleryActionBar actionBar = mActivity.getGalleryActionBar();
279a79bbef0ffe0b99cb8d0e5dcedd3082abc61559cWei Huang        if (actionBar != null) {
280b5f8d908c5dd287052cd49eddaf1f82d858cca03Ray Chen            mSelectedAction = data.getInt(
281b5f8d908c5dd287052cd49eddaf1f82d858cca03Ray Chen                    AlbumSetPage.KEY_SELECTED_CLUSTER_TYPE, FilterUtils.CLUSTER_BY_ALBUM);
282a79bbef0ffe0b99cb8d0e5dcedd3082abc61559cWei Huang        }
283f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        startTransition();
284f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
285f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
286f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
287f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onPause() {
288f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super.onPause();
289e9ae772f3400d53d24ce3d2834bd5866de599406Ray Chen        Log.v(TAG, "onPause");
290f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mIsActive = false;
291f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mActionModeHandler.pause();
292f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetDataAdapter.pause();
293f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetView.pause();
294f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mEyePosition.pause();
2954105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen        DetailsHelper.pause();
296f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        GalleryActionBar actionBar = mActivity.getGalleryActionBar();
297b5f8d908c5dd287052cd49eddaf1f82d858cca03Ray Chen        if (actionBar != null) actionBar.hideClusterMenu();
298f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
299f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
300f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
301f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onResume() {
302f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        super.onResume();
303e9ae772f3400d53d24ce3d2834bd5866de599406Ray Chen        Log.v(TAG, "onResume");
304f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mIsActive = true;
305f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        setContentPane(mRootPane);
306f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetDataAdapter.resume();
307f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetView.resume();
308f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mEyePosition.resume();
309f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mActionModeHandler.resume();
310f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        GalleryActionBar actionBar = mActivity.getGalleryActionBar();
311b5f8d908c5dd287052cd49eddaf1f82d858cca03Ray Chen        if (mShowClusterMenu && actionBar != null) actionBar.showClusterMenu(mSelectedAction, this);
312f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
313f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
314f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void initializeData(Bundle data) {
315f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String mediaPath = data.getString(AlbumSetPage.KEY_MEDIA_PATH);
316f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMediaSet = mActivity.getDataManager().getMediaSet(mediaPath);
317f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mSelectionManager.setSourceMediaSet(mMediaSet);
318f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetDataAdapter = new AlbumSetDataAdapter(
319f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mActivity, mMediaSet, DATA_CACHE_SIZE);
320f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetDataAdapter.setLoadingListener(new MyLoadingListener());
321f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetView.setModel(mAlbumSetDataAdapter);
322f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
323f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
324f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void initializeViews() {
325f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mSelectionManager = new SelectionManager(mActivity, true);
326f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mSelectionManager.setSelectionListener(this);
327f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mStaticBackground = new StaticBackground(mActivity.getAndroidContext());
328f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mRootPane.addComponent(mStaticBackground);
329f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
330f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mGridDrawer = new GridDrawer((Context) mActivity, mSelectionManager);
331f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Config.AlbumSetPage config = Config.AlbumSetPage.get((Context) mActivity);
332f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetView = new AlbumSetView(mActivity, mGridDrawer,
3339201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang                config.slotViewSpec, config.labelSpec);
334f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetView.setListener(new SlotView.SimpleListener() {
335f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            @Override
336bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            public void onDown(int index) {
337bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang                AlbumSetPage.this.onDown(index);
338bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            }
339bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
340bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            @Override
341bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            public void onUp() {
342bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang                AlbumSetPage.this.onUp();
343bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            }
344bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
345bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            @Override
346f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            public void onSingleTapUp(int slotIndex) {
347f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                AlbumSetPage.this.onSingleTapUp(slotIndex);
348f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
349bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang
350f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            @Override
351f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            public void onLongTap(int slotIndex) {
352f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                AlbumSetPage.this.onLongTap(slotIndex);
353f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
354f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        });
355f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
356f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mActionModeHandler = new ActionModeHandler(mActivity, mSelectionManager);
357f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mActionModeHandler.setActionModeListener(new ActionModeListener() {
358f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            public boolean onActionItemClicked(MenuItem item) {
359f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return onItemSelected(item);
360f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
361f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        });
362f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mRootPane.addComponent(mAlbumSetView);
363f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
364f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mStaticBackground.setImage(R.drawable.background,
365f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                R.drawable.background_portrait);
366f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
367f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
368f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
369f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected boolean onCreateActionBar(Menu menu) {
370f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Activity activity = (Activity) mActivity;
371f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        GalleryActionBar actionBar = mActivity.getGalleryActionBar();
372f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        MenuInflater inflater = activity.getMenuInflater();
373f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
374f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        final boolean inAlbum = mActivity.getStateManager().hasStateClass(
375f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                AlbumPage.class);
376f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
377f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mGetContent) {
378f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            inflater.inflate(R.menu.pickup, menu);
379f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int typeBits = mData.getInt(
380f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    Gallery.KEY_TYPE_BITS, DataManager.INCLUDE_IMAGE);
381f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int id = R.string.select_image;
382f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if ((typeBits & DataManager.INCLUDE_VIDEO) != 0) {
383f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                id = (typeBits & DataManager.INCLUDE_IMAGE) == 0
384f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        ? R.string.select_video
385f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        : R.string.select_item;
386f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
387f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            actionBar.setTitle(id);
388f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else  if (mGetAlbum) {
389f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            inflater.inflate(R.menu.pickup, menu);
390f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            actionBar.setTitle(R.string.select_album);
391f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else {
392b5f8d908c5dd287052cd49eddaf1f82d858cca03Ray Chen            mShowClusterMenu = !inAlbum;
393f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            inflater.inflate(R.menu.albumset, menu);
394f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (mTitle != null) {
395f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                actionBar.setTitle(mTitle);
396f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else {
397f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                actionBar.setTitle(activity.getApplicationInfo().labelRes);
398f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
399f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MenuItem selectItem = menu.findItem(R.id.action_select);
400f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
401f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (selectItem != null) {
402f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                boolean selectAlbums = !inAlbum &&
403f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        actionBar.getClusterTypeAction() == FilterUtils.CLUSTER_BY_ALBUM;
404f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (selectAlbums) {
405f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    selectItem.setTitle(R.string.select_album);
406f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                } else {
407f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    selectItem.setTitle(R.string.select_group);
408f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
409f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
410f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
411f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MenuItem switchCamera = menu.findItem(R.id.action_camera);
412f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (switchCamera != null) {
413f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                switchCamera.setVisible(GalleryUtils.isCameraAvailable(activity));
414f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
415f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
416f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            actionBar.setSubtitle(mSubtitle);
417f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
418f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return true;
419f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
420f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
421f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
422f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected boolean onItemSelected(MenuItem item) {
423f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Activity activity = (Activity) mActivity;
424f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        switch (item.getItemId()) {
425bd8e025f1bb39b2be236b183ea8e78f93b308ad1Ray Chen            case R.id.action_cancel:
426bd8e025f1bb39b2be236b183ea8e78f93b308ad1Ray Chen                activity.setResult(Activity.RESULT_CANCELED);
427bd8e025f1bb39b2be236b183ea8e78f93b308ad1Ray Chen                activity.finish();
428bd8e025f1bb39b2be236b183ea8e78f93b308ad1Ray Chen                return true;
429f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case R.id.action_select:
430f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mSelectionManager.setAutoLeaveSelectionMode(false);
431f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mSelectionManager.enterSelectionMode();
432f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return true;
433f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case R.id.action_details:
434f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (mAlbumSetDataAdapter.size() != 0) {
435f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    if (mShowDetails) {
436f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        hideDetails();
437f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    } else {
438f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        showDetails();
439f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    }
440f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                } else {
441f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    Toast.makeText(activity,
442f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                            activity.getText(R.string.no_albums_alert),
443f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                            Toast.LENGTH_SHORT).show();
444f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
445f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return true;
446f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case R.id.action_camera: {
447f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA)
448f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
449f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        | Intent.FLAG_ACTIVITY_NEW_TASK);
450f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                activity.startActivity(intent);
451f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return true;
452f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
453f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case R.id.action_manage_offline: {
4546cf807453fb58ccd4cc513ff187b306c7090e67cOwen Lin                Bundle data = new Bundle();
4556cf807453fb58ccd4cc513ff187b306c7090e67cOwen Lin                String mediaPath = mActivity.getDataManager().getTopSetPath(
4566cf807453fb58ccd4cc513ff187b306c7090e67cOwen Lin                    DataManager.INCLUDE_ALL);
4576cf807453fb58ccd4cc513ff187b306c7090e67cOwen Lin                data.putString(AlbumSetPage.KEY_MEDIA_PATH, mediaPath);
4586cf807453fb58ccd4cc513ff187b306c7090e67cOwen Lin                mActivity.getStateManager().startState(ManageCachePage.class, data);
459f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return true;
460f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
461f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case R.id.action_sync_picasa_albums: {
462f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                PicasaSource.requestSync(activity);
463f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return true;
464f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
465f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case R.id.action_settings: {
466f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                activity.startActivity(new Intent(activity, GallerySettings.class));
467f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return true;
468f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
469f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            default:
470f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return false;
471f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
472f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
473f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
474f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
475f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    protected void onStateResult(int requestCode, int resultCode, Intent data) {
476f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        switch (requestCode) {
477f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case REQUEST_DO_ANIMATION: {
478f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                startTransition();
479f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
480f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
481f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
482f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
483f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void startTransition() {
484f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        final PositionRepository repository =
485f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                PositionRepository.getInstance(mActivity);
486f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetView.startTransition(new PositionProvider() {
487f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            private Position mTempPosition = new Position();
488f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            public Position getPosition(long identity, Position target) {
489f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                Position p = repository.get(identity);
490f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (p == null) {
491f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    p = mTempPosition;
492f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    p.set(target.x, target.y, 128, target.theta, 1);
493f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
494f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return p;
495f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
496f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        });
497f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
498f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
499f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private String getSelectedString() {
500f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        GalleryActionBar actionBar = mActivity.getGalleryActionBar();
501f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int count = mSelectionManager.getSelectedCount();
502f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int action = actionBar.getClusterTypeAction();
503f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int string = action == FilterUtils.CLUSTER_BY_ALBUM
504f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                ? R.plurals.number_of_albums_selected
505f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                : R.plurals.number_of_groups_selected;
506f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String format = mActivity.getResources().getQuantityString(string, count);
507f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return String.format(format, count);
508f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
509f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
510f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onSelectionModeChange(int mode) {
511f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
512f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        switch (mode) {
513f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case SelectionManager.ENTER_SELECTION_MODE: {
514b5f8d908c5dd287052cd49eddaf1f82d858cca03Ray Chen                mActivity.getGalleryActionBar().hideClusterMenu();
515f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mActionMode = mActionModeHandler.startActionMode();
5161f4e6d14bba7290ea0268fbde28ffc664d4f7004Ray Chen                mVibrator.vibrate(100);
517f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                break;
518f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
519f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case SelectionManager.LEAVE_SELECTION_MODE: {
520f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mActionMode.finish();
521b5f8d908c5dd287052cd49eddaf1f82d858cca03Ray Chen                mActivity.getGalleryActionBar().showClusterMenu(mSelectedAction, this);
522f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mRootPane.invalidate();
523f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                break;
524f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
525f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            case SelectionManager.SELECT_ALL_MODE: {
526f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mActionModeHandler.setTitle(getSelectedString());
527f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mRootPane.invalidate();
528f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                break;
529f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
530f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
531f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
532f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
533f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void onSelectionChange(Path path, boolean selected) {
534f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Utils.assertTrue(mActionMode != null);
535f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mActionModeHandler.setTitle(getSelectedString());
536f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mActionModeHandler.updateSupportedOperation(path, selected);
537f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
538f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
539f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void hideDetails() {
540f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mShowDetails = false;
5414105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen        mDetailsHelper.hide();
542a4f0526dc8d993fb914d0e6505e22a1f30ad0e14Ray Chen        mAlbumSetView.setSelectionDrawer(mGridDrawer);
543a4f0526dc8d993fb914d0e6505e22a1f30ad0e14Ray Chen        mAlbumSetView.invalidate();
544f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
545f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
546f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private void showDetails() {
547f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mShowDetails = true;
5484105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen        if (mDetailsHelper == null) {
549bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang            mHighlightDrawer = new HighlightDrawer(mActivity.getAndroidContext(),
550bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang                    mSelectionManager);
5514105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen            mDetailsHelper = new DetailsHelper(mActivity, mRootPane, mDetailsSource);
5524105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen            mDetailsHelper.setCloseListener(new CloseListener() {
553f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                public void onClose() {
554f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    hideDetails();
555f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
556f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            });
557f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
558f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mAlbumSetView.setSelectionDrawer(mHighlightDrawer);
5594105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen        mDetailsHelper.show();
560f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
561f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
562f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private class MyLoadingListener implements LoadingListener {
563f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void onLoadingStarted() {
564f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            GalleryUtils.setSpinnerVisibility((Activity) mActivity, true);
565f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
566f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
567f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void onLoadingFinished() {
568f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (!mIsActive) return;
569f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            GalleryUtils.setSpinnerVisibility((Activity) mActivity, false);
570f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (mAlbumSetDataAdapter.size() == 0) {
571f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                Toast.makeText((Context) mActivity,
572f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        R.string.empty_album, Toast.LENGTH_LONG).show();
573f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (mActivity.getStateManager().getStateCount() > 1) {
574f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    mActivity.getStateManager().finishState(AlbumSetPage.this);
575f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
576f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
577f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
578f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
579f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
5804105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen    private class MyDetailsSource implements DetailsHelper.DetailsSource {
581f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        private int mIndex;
582f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public int size() {
583f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return mAlbumSetDataAdapter.size();
584f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
585f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
5864105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen        public int getIndex() {
5874105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen            return mIndex;
5884105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen        }
5894105e22d72d7a44e67cba4a58ad88018ed664d10Ray Chen
590f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // If requested index is out of active window, suggest a valid index.
591f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // If there is no valid index available, return -1.
592f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public int findIndex(int indexHint) {
593f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (mAlbumSetDataAdapter.isActive(indexHint)) {
594f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mIndex = indexHint;
595f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else {
596f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mIndex = mAlbumSetDataAdapter.getActiveStart();
597f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (!mAlbumSetDataAdapter.isActive(mIndex)) {
598f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    return -1;
599f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
600f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
601f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return mIndex;
602f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
603f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
604f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public MediaDetails getDetails() {
605f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaObject item = mAlbumSetDataAdapter.getMediaSet(mIndex);
606f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (item != null) {
607f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mHighlightDrawer.setHighlightItem(item.getPath());
608f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return item.getDetails();
609f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else {
610f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                return null;
611f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
612f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
613f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
614f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
615