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.AbstractGalleryActivity;
20 import com.android.gallery3d.app.AlbumDataLoader;
21 import com.android.gallery3d.data.MediaObject;
22 import com.android.gallery3d.data.Path;
23 import com.android.gallery3d.glrenderer.ColorTexture;
24 import com.android.gallery3d.glrenderer.FadeInTexture;
25 import com.android.gallery3d.glrenderer.GLCanvas;
26 import com.android.gallery3d.glrenderer.Texture;
27 import com.android.gallery3d.glrenderer.TiledTexture;
28 
29 public class AlbumSlotRenderer extends AbstractSlotRenderer {
30     @SuppressWarnings("unused")
31     private static final String TAG = "AlbumView";
32 
33     public interface SlotFilter {
acceptSlot(int index)34         public boolean acceptSlot(int index);
35     }
36 
37     private final int mPlaceholderColor;
38     private static final int CACHE_SIZE = 96;
39 
40     private AlbumSlidingWindow mDataWindow;
41     private final AbstractGalleryActivity mActivity;
42     private final ColorTexture mWaitLoadingTexture;
43     private final SlotView mSlotView;
44     private final SelectionManager mSelectionManager;
45 
46     private int mPressedIndex = -1;
47     private boolean mAnimatePressedUp;
48     private Path mHighlightItemPath = null;
49     private boolean mInSelectionMode;
50 
51     private SlotFilter mSlotFilter;
52 
AlbumSlotRenderer(AbstractGalleryActivity activity, SlotView slotView, SelectionManager selectionManager, int placeholderColor)53     public AlbumSlotRenderer(AbstractGalleryActivity activity, SlotView slotView,
54             SelectionManager selectionManager, int placeholderColor) {
55         super(activity);
56         mActivity = activity;
57         mSlotView = slotView;
58         mSelectionManager = selectionManager;
59         mPlaceholderColor = placeholderColor;
60 
61         mWaitLoadingTexture = new ColorTexture(mPlaceholderColor);
62         mWaitLoadingTexture.setSize(1, 1);
63     }
64 
setPressedIndex(int index)65     public void setPressedIndex(int index) {
66         if (mPressedIndex == index) return;
67         mPressedIndex = index;
68         mSlotView.invalidate();
69     }
70 
setPressedUp()71     public void setPressedUp() {
72         if (mPressedIndex == -1) return;
73         mAnimatePressedUp = true;
74         mSlotView.invalidate();
75     }
76 
setHighlightItemPath(Path path)77     public void setHighlightItemPath(Path path) {
78         if (mHighlightItemPath == path) return;
79         mHighlightItemPath = path;
80         mSlotView.invalidate();
81     }
82 
setModel(AlbumDataLoader model)83     public void setModel(AlbumDataLoader model) {
84         if (mDataWindow != null) {
85             mDataWindow.setListener(null);
86             mSlotView.setSlotCount(0);
87             mDataWindow = null;
88         }
89         if (model != null) {
90             mDataWindow = new AlbumSlidingWindow(mActivity, model, CACHE_SIZE);
91             mDataWindow.setListener(new MyDataModelListener());
92             mSlotView.setSlotCount(model.size());
93         }
94     }
95 
checkTexture(Texture texture)96     private static Texture checkTexture(Texture texture) {
97         return (texture instanceof TiledTexture)
98                 && !((TiledTexture) texture).isReady()
99                 ? null
100                 : texture;
101     }
102 
103     @Override
renderSlot(GLCanvas canvas, int index, int pass, int width, int height)104     public int renderSlot(GLCanvas canvas, int index, int pass, int width, int height) {
105         if (mSlotFilter != null && !mSlotFilter.acceptSlot(index)) return 0;
106 
107         AlbumSlidingWindow.AlbumEntry entry = mDataWindow.get(index);
108 
109         int renderRequestFlags = 0;
110 
111         Texture content = checkTexture(entry.content);
112         if (content == null) {
113             content = mWaitLoadingTexture;
114             entry.isWaitDisplayed = true;
115         } else if (entry.isWaitDisplayed) {
116             entry.isWaitDisplayed = false;
117             content = new FadeInTexture(mPlaceholderColor, entry.bitmapTexture);
118             entry.content = content;
119         }
120         drawContent(canvas, content, width, height, entry.rotation);
121         if ((content instanceof FadeInTexture) &&
122                 ((FadeInTexture) content).isAnimating()) {
123             renderRequestFlags |= SlotView.RENDER_MORE_FRAME;
124         }
125 
126         if (entry.mediaType == MediaObject.MEDIA_TYPE_VIDEO) {
127             drawVideoOverlay(canvas, width, height);
128         }
129 
130         if (entry.isPanorama) {
131             drawPanoramaIcon(canvas, width, height);
132         }
133 
134         renderRequestFlags |= renderOverlay(canvas, index, entry, width, height);
135 
136         return renderRequestFlags;
137     }
138 
renderOverlay(GLCanvas canvas, int index, AlbumSlidingWindow.AlbumEntry entry, int width, int height)139     private int renderOverlay(GLCanvas canvas, int index,
140             AlbumSlidingWindow.AlbumEntry entry, int width, int height) {
141         int renderRequestFlags = 0;
142         if (mPressedIndex == index) {
143             if (mAnimatePressedUp) {
144                 drawPressedUpFrame(canvas, width, height);
145                 renderRequestFlags |= SlotView.RENDER_MORE_FRAME;
146                 if (isPressedUpFrameFinished()) {
147                     mAnimatePressedUp = false;
148                     mPressedIndex = -1;
149                 }
150             } else {
151                 drawPressedFrame(canvas, width, height);
152             }
153         } else if ((entry.path != null) && (mHighlightItemPath == entry.path)) {
154             drawSelectedFrame(canvas, width, height);
155         } else if (mInSelectionMode && mSelectionManager.isItemSelected(entry.path)) {
156             drawSelectedFrame(canvas, width, height);
157         }
158         return renderRequestFlags;
159     }
160 
161     private class MyDataModelListener implements AlbumSlidingWindow.Listener {
162         @Override
onContentChanged()163         public void onContentChanged() {
164             mSlotView.invalidate();
165         }
166 
167         @Override
onSizeChanged(int size)168         public void onSizeChanged(int size) {
169             mSlotView.setSlotCount(size);
170         }
171     }
172 
resume()173     public void resume() {
174         mDataWindow.resume();
175     }
176 
pause()177     public void pause() {
178         mDataWindow.pause();
179     }
180 
181     @Override
prepareDrawing()182     public void prepareDrawing() {
183         mInSelectionMode = mSelectionManager.inSelectionMode();
184     }
185 
186     @Override
onVisibleRangeChanged(int visibleStart, int visibleEnd)187     public void onVisibleRangeChanged(int visibleStart, int visibleEnd) {
188         if (mDataWindow != null) {
189             mDataWindow.setActiveWindow(visibleStart, visibleEnd);
190         }
191     }
192 
193     @Override
onSlotSizeChanged(int width, int height)194     public void onSlotSizeChanged(int width, int height) {
195         // Do nothing
196     }
197 
setSlotFilter(SlotFilter slotFilter)198     public void setSlotFilter(SlotFilter slotFilter) {
199         mSlotFilter = slotFilter;
200     }
201 }
202