2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.gallery3d.ui;
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;
25 import android.graphics.Rect;
27 import java.util.Random;
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;
35 private int mVisibleStart;
36 private int mVisibleEnd;
38 private Random mRandom = new Random();
39 private long mSeed = mRandom.nextLong();
41 private AlbumSetSlidingWindow mDataWindow;
42 private final GalleryActivity mActivity;
43 private final LabelSpec mLabelSpec;
45 private SelectionDrawer mSelectionDrawer;
47 public static interface Model {
48 public MediaItem[] getCoverItems(int index);
49 public MediaSet getMediaSet(int index);
51 public void setActiveWindow(int start, int end);
52 public void setModelListener(ModelListener listener);
55 public static interface ModelListener {
56 public void onWindowContentChanged(int index);
57 public void onSizeChanged(int size);
60 public static class AlbumSetItem {
61 public DisplayItem[] covers;
62 public DisplayItem labelItem;
63 public long setDataVersion;
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;
76 public AlbumSetView(GalleryActivity activity, SelectionDrawer drawer,
77 SlotView.Spec slotViewSpec, LabelSpec labelSpec) {
78 super(activity.getAndroidContext());
80 setSelectionDrawer(drawer);
81 setSlotSpec(slotViewSpec);
82 mLabelSpec = labelSpec;
85 public void setSelectionDrawer(SelectionDrawer drawer) {
86 mSelectionDrawer = drawer;
87 if (mDataWindow != null) {
88 mDataWindow.setSelectionDrawer(drawer);
92 public void setModel(AlbumSetView.Model model) {
93 if (mDataWindow != null) {
94 mDataWindow.setListener(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());
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);
112 DisplayItem[] items = entry.covers;
113 mRandom.setSeed(slotIndex ^ mSeed);
115 int x = (rect.left + rect.right) / 2;
116 int y = (rect.top + rect.bottom) / 2;
118 Position basePosition = new Position(x, y, 0);
120 // Put the cover items in reverse order, so that the first item is on
122 Position position = new Position(x, y, 0f);
123 putDisplayItem(position, position, entry.labelItem);
125 for (int i = 0, n = items.length; i < n; ++i) {
126 DisplayItem item = items[i];
132 dz = i * PHOTO_DISTANCE;
134 position = new Position(x + dx, y + dy, dz);
135 position.theta = theta;
136 putDisplayItem(position, basePosition, item);
141 private void freeSlotContent(int index, AlbumSetItem entry) {
142 if (entry == null) return;
143 for (DisplayItem item : entry.covers) {
144 removeDisplayItem(item);
146 removeDisplayItem(entry.labelItem);
150 return mDataWindow.size();
154 public void onLayoutChanged(int width, int height) {
155 updateVisibleRange(0, 0);
156 updateVisibleRange(getVisibleStart(), getVisibleEnd());
160 public void onScrollPositionChanged(int position) {
161 super.onScrollPositionChanged(position);
162 updateVisibleRange(getVisibleStart(), getVisibleEnd());
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);
171 if (start >= mVisibleEnd || mVisibleStart >= end) {
172 for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
173 freeSlotContent(i, mDataWindow.get(i));
175 mDataWindow.setActiveWindow(start, end);
176 for (int i = start; i < end; ++i) {
177 putSlotContent(i, mDataWindow.get(i));
180 for (int i = mVisibleStart; i < start; ++i) {
181 freeSlotContent(i, mDataWindow.get(i));
183 for (int i = end, n = mVisibleEnd; i < n; ++i) {
184 freeSlotContent(i, mDataWindow.get(i));
186 mDataWindow.setActiveWindow(start, end);
187 for (int i = start, n = mVisibleStart; i < n; ++i) {
188 putSlotContent(i, mDataWindow.get(i));
190 for (int i = mVisibleEnd; i < end; ++i) {
191 putSlotContent(i, mDataWindow.get(i));
194 mVisibleStart = start;
201 protected void render(GLCanvas canvas) {
202 mSelectionDrawer.prepareDrawing();
203 super.render(canvas);
206 private class MyCacheListener implements AlbumSetSlidingWindow.Listener {
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());
215 public void onWindowContentChanged(int slot, AlbumSetItem old, AlbumSetItem update) {
216 freeSlotContent(slot, old);
217 putSlotContent(slot, update);
221 public void onContentInvalidated() {
226 public void pause() {
227 for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
228 freeSlotContent(i, mDataWindow.get(i));
233 public void resume() {
234 mDataWindow.resume();
235 for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
236 putSlotContent(i, mDataWindow.get(i));