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
17package com.android.gallery3d.ui;
18
19import com.android.gallery3d.R;
20import com.android.gallery3d.app.AbstractGalleryActivity;
21import com.android.gallery3d.app.AlbumSetDataLoader;
22import com.android.gallery3d.data.MediaObject;
23import com.android.gallery3d.data.Path;
24import com.android.gallery3d.glrenderer.ColorTexture;
25import com.android.gallery3d.glrenderer.FadeInTexture;
26import com.android.gallery3d.glrenderer.GLCanvas;
27import com.android.gallery3d.glrenderer.ResourceTexture;
28import com.android.gallery3d.glrenderer.Texture;
29import com.android.gallery3d.glrenderer.TiledTexture;
30import com.android.gallery3d.glrenderer.UploadedTexture;
31import com.android.gallery3d.ui.AlbumSetSlidingWindow.AlbumSetEntry;
32
33public 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
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
84    public void setPressedIndex(int index) {
85        if (mPressedIndex == index) return;
86        mPressedIndex = index;
87        mSlotView.invalidate();
88    }
89
90    public void setPressedUp() {
91        if (mPressedIndex == -1) return;
92        mAnimatePressedUp = true;
93        mSlotView.invalidate();
94    }
95
96    public void setHighlightItemPath(Path path) {
97        if (mHighlightItemPath == path) return;
98        mHighlightItemPath = path;
99        mSlotView.invalidate();
100    }
101
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
116    private static Texture checkLabelTexture(Texture texture) {
117        return ((texture instanceof UploadedTexture)
118                && ((UploadedTexture) texture).isUploading())
119                ? null
120                : texture;
121    }
122
123    private static Texture checkContentTexture(Texture texture) {
124        return ((texture instanceof TiledTexture)
125                && !((TiledTexture) texture).isReady())
126                ? null
127                : texture;
128    }
129
130    @Override
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
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
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
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
204    public void prepareDrawing() {
205        mInSelectionMode = mSelectionManager.inSelectionMode();
206    }
207
208    private class MyCacheListener implements AlbumSetSlidingWindow.Listener {
209
210        @Override
211        public void onSizeChanged(int size) {
212            mSlotView.setSlotCount(size);
213        }
214
215        @Override
216        public void onContentChanged() {
217            mSlotView.invalidate();
218        }
219    }
220
221    public void pause() {
222        mDataWindow.pause();
223    }
224
225    public void resume() {
226        mDataWindow.resume();
227    }
228
229    @Override
230    public void onVisibleRangeChanged(int visibleStart, int visibleEnd) {
231        if (mDataWindow != null) {
232            mDataWindow.setActiveWindow(visibleStart, visibleEnd);
233        }
234    }
235
236    @Override
237    public void onSlotSizeChanged(int width, int height) {
238        if (mDataWindow != null) {
239            mDataWindow.onSlotSizeChanged(width, height);
240        }
241    }
242}
243