OSDN Git Service

c122fe77788f4f83b946d6cd3b3af6bc6fdf6dea
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / ui / AlbumSetView.java
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.gallery3d.ui;
18
19 import com.android.gallery3d.app.GalleryActivity;
20 import com.android.gallery3d.common.Utils;
21 import com.android.gallery3d.data.MediaItem;
22 import com.android.gallery3d.data.MediaSet;
23 import com.android.gallery3d.ui.PositionRepository.Position;
24
25 import android.graphics.Rect;
26
27 import java.util.Random;
28
29 public class AlbumSetView extends SlotView {
30     @SuppressWarnings("unused")
31     private static final String TAG = "AlbumSetView";
32     private static final int CACHE_SIZE = 32;
33     private static final float PHOTO_DISTANCE = 35f;
34
35     private int mVisibleStart;
36     private int mVisibleEnd;
37
38     private Random mRandom = new Random();
39     private long mSeed = mRandom.nextLong();
40
41     private AlbumSetSlidingWindow mDataWindow;
42     private final GalleryActivity mActivity;
43     private final LabelSpec mLabelSpec;
44
45     private SelectionDrawer mSelectionDrawer;
46
47     public static interface Model {
48         public MediaItem[] getCoverItems(int index);
49         public MediaSet getMediaSet(int index);
50         public int size();
51         public void setActiveWindow(int start, int end);
52         public void setModelListener(ModelListener listener);
53     }
54
55     public static interface ModelListener {
56         public void onWindowContentChanged(int index);
57         public void onSizeChanged(int size);
58     }
59
60     public static class AlbumSetItem {
61         public DisplayItem[] covers;
62         public DisplayItem labelItem;
63         public long setDataVersion;
64     }
65
66     public static class LabelSpec {
67         public int darkStripHeight;
68         public int titleOffset;
69         public int numberOffset;
70         public int titleFontSize;
71         public int numberFontSize;
72         public int leftMargin;
73         public int iconSize;
74     }
75
76     public AlbumSetView(GalleryActivity activity, SelectionDrawer drawer,
77             SlotView.Spec slotViewSpec, LabelSpec labelSpec) {
78         super(activity.getAndroidContext());
79         mActivity = activity;
80         setSelectionDrawer(drawer);
81         setSlotSpec(slotViewSpec);
82         mLabelSpec = labelSpec;
83     }
84
85     public void setSelectionDrawer(SelectionDrawer drawer) {
86         mSelectionDrawer = drawer;
87         if (mDataWindow != null) {
88             mDataWindow.setSelectionDrawer(drawer);
89         }
90     }
91
92     public void setModel(AlbumSetView.Model model) {
93         if (mDataWindow != null) {
94             mDataWindow.setListener(null);
95             setSlotCount(0);
96             mDataWindow = null;
97         }
98         if (model != null) {
99             mDataWindow = new AlbumSetSlidingWindow(mActivity, mLabelSpec,
100                     mSelectionDrawer, model, CACHE_SIZE);
101             mDataWindow.setListener(new MyCacheListener());
102             setSlotCount(mDataWindow.size());
103             updateVisibleRange(getVisibleStart(), getVisibleEnd());
104         }
105     }
106
107     private void putSlotContent(int slotIndex, AlbumSetItem entry) {
108         // Get displayItems from mItemsetMap or create them from MediaSet.
109         Utils.assertTrue(entry != null);
110         Rect rect = getSlotRect(slotIndex);
111
112         DisplayItem[] items = entry.covers;
113         mRandom.setSeed(slotIndex ^ mSeed);
114
115         int x = (rect.left + rect.right) / 2;
116         int y = (rect.top + rect.bottom) / 2;
117
118         Position basePosition = new Position(x, y, 0);
119
120         // Put the cover items in reverse order, so that the first item is on
121         // top of the rest.
122         Position position = new Position(x, y, 0f);
123         putDisplayItem(position, position, entry.labelItem);
124
125         for (int i = 0, n = items.length; i < n; ++i) {
126             DisplayItem item = items[i];
127             float dx = 0;
128             float dy = 0;
129             float dz = 0f;
130             float theta = 0;
131             if (i != 0) {
132                 dz = i * PHOTO_DISTANCE;
133             }
134             position = new Position(x + dx, y + dy, dz);
135             position.theta = theta;
136             putDisplayItem(position, basePosition, item);
137         }
138
139     }
140
141     private void freeSlotContent(int index, AlbumSetItem entry) {
142         if (entry == null) return;
143         for (DisplayItem item : entry.covers) {
144             removeDisplayItem(item);
145         }
146         removeDisplayItem(entry.labelItem);
147     }
148
149     public int size() {
150         return mDataWindow.size();
151     }
152
153     @Override
154     public void onLayoutChanged(int width, int height) {
155         updateVisibleRange(0, 0);
156         updateVisibleRange(getVisibleStart(), getVisibleEnd());
157     }
158
159     @Override
160     public void onScrollPositionChanged(int position) {
161         super.onScrollPositionChanged(position);
162         updateVisibleRange(getVisibleStart(), getVisibleEnd());
163     }
164
165     private void updateVisibleRange(int start, int end) {
166         if (start == mVisibleStart && end == mVisibleEnd) {
167             // we need to set the mDataWindow active range in any case.
168             mDataWindow.setActiveWindow(start, end);
169             return;
170         }
171         if (start >= mVisibleEnd || mVisibleStart >= end) {
172             for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
173                 freeSlotContent(i, mDataWindow.get(i));
174             }
175             mDataWindow.setActiveWindow(start, end);
176             for (int i = start; i < end; ++i) {
177                 putSlotContent(i, mDataWindow.get(i));
178             }
179         } else {
180             for (int i = mVisibleStart; i < start; ++i) {
181                 freeSlotContent(i, mDataWindow.get(i));
182             }
183             for (int i = end, n = mVisibleEnd; i < n; ++i) {
184                 freeSlotContent(i, mDataWindow.get(i));
185             }
186             mDataWindow.setActiveWindow(start, end);
187             for (int i = start, n = mVisibleStart; i < n; ++i) {
188                 putSlotContent(i, mDataWindow.get(i));
189             }
190             for (int i = mVisibleEnd; i < end; ++i) {
191                 putSlotContent(i, mDataWindow.get(i));
192             }
193         }
194         mVisibleStart = start;
195         mVisibleEnd = end;
196
197         invalidate();
198     }
199
200     @Override
201     protected void render(GLCanvas canvas) {
202         mSelectionDrawer.prepareDrawing();
203         super.render(canvas);
204     }
205
206     private class MyCacheListener implements AlbumSetSlidingWindow.Listener {
207
208         public void onSizeChanged(int size) {
209             // If the layout parameters are changed, we need reput all items.
210             if (setSlotCount(size)) updateVisibleRange(0, 0);
211             updateVisibleRange(getVisibleStart(), getVisibleEnd());
212             invalidate();
213         }
214
215         public void onWindowContentChanged(int slot, AlbumSetItem old, AlbumSetItem update) {
216             freeSlotContent(slot, old);
217             putSlotContent(slot, update);
218             invalidate();
219         }
220
221         public void onContentInvalidated() {
222             invalidate();
223         }
224     }
225
226     public void pause() {
227         for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
228             freeSlotContent(i, mDataWindow.get(i));
229         }
230         mDataWindow.pause();
231     }
232
233     public void resume() {
234         mDataWindow.resume();
235         for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
236             putSlotContent(i, mDataWindow.get(i));
237         }
238     }
239 }