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.R;
20 import com.android.gallery3d.app.AbstractGalleryActivity;
21 import com.android.gallery3d.app.AlbumSetDataLoader;
22 import com.android.gallery3d.data.MediaObject;
23 import com.android.gallery3d.data.Path;
24 import com.android.gallery3d.glrenderer.ColorTexture;
25 import com.android.gallery3d.glrenderer.FadeInTexture;
26 import com.android.gallery3d.glrenderer.GLCanvas;
27 import com.android.gallery3d.glrenderer.ResourceTexture;
28 import com.android.gallery3d.glrenderer.Texture;
29 import com.android.gallery3d.glrenderer.TiledTexture;
30 import com.android.gallery3d.glrenderer.UploadedTexture;
31 import com.android.gallery3d.ui.AlbumSetSlidingWindow.AlbumSetEntry;
32 
33 public class AlbumSetSlotRenderer extends AbstractSlotRenderer {
34     @SuppressWarnings("unused")
35     private static final String TAG = "AlbumSetView";
36     private static final int CACHE_SIZE = 96;
37     private final int mPlaceholderColor;
38 
39     private final ColorTexture mWaitLoadingTexture;
40     private final ResourceTexture mCameraOverlay;
41     private final AbstractGalleryActivity mActivity;
42     private final SelectionManager mSelectionManager;
43     protected final LabelSpec mLabelSpec;
44 
45     protected AlbumSetSlidingWindow mDataWindow;
46     private SlotView mSlotView;
47 
48     private int mPressedIndex = -1;
49     private boolean mAnimatePressedUp;
50     private Path mHighlightItemPath = null;
51     private boolean mInSelectionMode;
52 
53     public static class LabelSpec {
54         public int labelBackgroundHeight;
55         public int titleOffset;
56         public int countOffset;
57         public int titleFontSize;
58         public int countFontSize;
59         public int leftMargin;
60         public int iconSize;
61         public int titleRightMargin;
62         public int backgroundColor;
63         public int titleColor;
64         public int countColor;
65         public int borderSize;
66     }
67 
AlbumSetSlotRenderer(AbstractGalleryActivity activity, SelectionManager selectionManager, SlotView slotView, LabelSpec labelSpec, int placeholderColor)68     public AlbumSetSlotRenderer(AbstractGalleryActivity activity,
69             SelectionManager selectionManager,
70             SlotView slotView, LabelSpec labelSpec, int placeholderColor) {
71         super (activity);
72         mActivity = activity;
73         mSelectionManager = selectionManager;
74         mSlotView = slotView;
75         mLabelSpec = labelSpec;
76         mPlaceholderColor = placeholderColor;
77 
78         mWaitLoadingTexture = new ColorTexture(mPlaceholderColor);
79         mWaitLoadingTexture.setSize(1, 1);
80         mCameraOverlay = new ResourceTexture(activity,
81                 R.drawable.ic_cameraalbum_overlay);
82     }
83 
setPressedIndex(int index)84     public void setPressedIndex(int index) {
85         if (mPressedIndex == index) return;
86         mPressedIndex = index;
87         mSlotView.invalidate();
88     }
89 
setPressedUp()90     public void setPressedUp() {
91         if (mPressedIndex == -1) return;
92         mAnimatePressedUp = true;
93         mSlotView.invalidate();
94     }
95 
setHighlightItemPath(Path path)96     public void setHighlightItemPath(Path path) {
97         if (mHighlightItemPath == path) return;
98         mHighlightItemPath = path;
99         mSlotView.invalidate();
100     }
101 
setModel(AlbumSetDataLoader model)102     public void setModel(AlbumSetDataLoader model) {
103         if (mDataWindow != null) {
104             mDataWindow.setListener(null);
105             mDataWindow = null;
106             mSlotView.setSlotCount(0);
107         }
108         if (model != null) {
109             mDataWindow = new AlbumSetSlidingWindow(
110                     mActivity, model, mLabelSpec, CACHE_SIZE);
111             mDataWindow.setListener(new MyCacheListener());
112             mSlotView.setSlotCount(mDataWindow.size());
113         }
114     }
115 
checkLabelTexture(Texture texture)116     private static Texture checkLabelTexture(Texture texture) {
117         return ((texture instanceof UploadedTexture)
118                 && ((UploadedTexture) texture).isUploading())
119                 ? null
120                 : texture;
121     }
122 
checkContentTexture(Texture texture)123     private static Texture checkContentTexture(Texture texture) {
124         return ((texture instanceof TiledTexture)
125                 && !((TiledTexture) texture).isReady())
126                 ? null
127                 : texture;
128     }
129 
130     @Override
renderSlot(GLCanvas canvas, int index, int pass, int width, int height)131     public int renderSlot(GLCanvas canvas, int index, int pass, int width, int height) {
132         AlbumSetEntry entry = mDataWindow.get(index);
133         int renderRequestFlags = 0;
134         renderRequestFlags |= renderContent(canvas, entry, width, height);
135         renderRequestFlags |= renderLabel(canvas, entry, width, height);
136         renderRequestFlags |= renderOverlay(canvas, index, entry, width, height);
137         return renderRequestFlags;
138     }
139 
renderOverlay( GLCanvas canvas, int index, AlbumSetEntry entry, int width, int height)140     protected int renderOverlay(
141             GLCanvas canvas, int index, AlbumSetEntry entry, int width, int height) {
142         int renderRequestFlags = 0;
143         if (entry.album != null && entry.album.isCameraRoll()) {
144             int uncoveredHeight = height - mLabelSpec.labelBackgroundHeight;
145             int dim = uncoveredHeight / 2;
146             mCameraOverlay.draw(canvas, (width - dim) / 2,
147                     (uncoveredHeight - dim) / 2, dim, dim);
148         }
149         if (mPressedIndex == index) {
150             if (mAnimatePressedUp) {
151                 drawPressedUpFrame(canvas, width, height);
152                 renderRequestFlags |= SlotView.RENDER_MORE_FRAME;
153                 if (isPressedUpFrameFinished()) {
154                     mAnimatePressedUp = false;
155                     mPressedIndex = -1;
156                 }
157             } else {
158                 drawPressedFrame(canvas, width, height);
159             }
160         } else if ((mHighlightItemPath != null) && (mHighlightItemPath == entry.setPath)) {
161             drawSelectedFrame(canvas, width, height);
162         } else if (mInSelectionMode && mSelectionManager.isItemSelected(entry.setPath)) {
163             drawSelectedFrame(canvas, width, height);
164         }
165         return renderRequestFlags;
166     }
167 
renderContent( GLCanvas canvas, AlbumSetEntry entry, int width, int height)168     protected int renderContent(
169             GLCanvas canvas, AlbumSetEntry entry, int width, int height) {
170         int renderRequestFlags = 0;
171 
172         Texture content = checkContentTexture(entry.content);
173         if (content == null) {
174             content = mWaitLoadingTexture;
175             entry.isWaitLoadingDisplayed = true;
176         } else if (entry.isWaitLoadingDisplayed) {
177             entry.isWaitLoadingDisplayed = false;
178             content = new FadeInTexture(mPlaceholderColor, entry.bitmapTexture);
179             entry.content = content;
180         }
181         drawContent(canvas, content, width, height, entry.rotation);
182         if ((content instanceof FadeInTexture) &&
183                 ((FadeInTexture) content).isAnimating()) {
184             renderRequestFlags |= SlotView.RENDER_MORE_FRAME;
185         }
186 
187         return renderRequestFlags;
188     }
189 
renderLabel( GLCanvas canvas, AlbumSetEntry entry, int width, int height)190     protected int renderLabel(
191             GLCanvas canvas, AlbumSetEntry entry, int width, int height) {
192         Texture content = checkLabelTexture(entry.labelTexture);
193         if (content == null) {
194             content = mWaitLoadingTexture;
195         }
196         int b = AlbumLabelMaker.getBorderSize();
197         int h = mLabelSpec.labelBackgroundHeight;
198         content.draw(canvas, -b, height - h + b, width + b + b, h);
199 
200         return 0;
201     }
202 
203     @Override
prepareDrawing()204     public void prepareDrawing() {
205         mInSelectionMode = mSelectionManager.inSelectionMode();
206     }
207 
208     private class MyCacheListener implements AlbumSetSlidingWindow.Listener {
209 
210         @Override
onSizeChanged(int size)211         public void onSizeChanged(int size) {
212             mSlotView.setSlotCount(size);
213         }
214 
215         @Override
onContentChanged()216         public void onContentChanged() {
217             mSlotView.invalidate();
218         }
219     }
220 
pause()221     public void pause() {
222         mDataWindow.pause();
223     }
224 
resume()225     public void resume() {
226         mDataWindow.resume();
227     }
228 
229     @Override
onVisibleRangeChanged(int visibleStart, int visibleEnd)230     public void onVisibleRangeChanged(int visibleStart, int visibleEnd) {
231         if (mDataWindow != null) {
232             mDataWindow.setActiveWindow(visibleStart, visibleEnd);
233         }
234     }
235 
236     @Override
onSlotSizeChanged(int width, int height)237     public void onSlotSizeChanged(int width, int height) {
238         if (mDataWindow != null) {
239             mDataWindow.onSlotSizeChanged(width, height);
240         }
241     }
242 }
243