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.app.AbstractGalleryActivity;
20import com.android.gallery3d.app.AlbumDataLoader;
21import com.android.gallery3d.data.MediaObject;
22import com.android.gallery3d.data.Path;
23import com.android.gallery3d.glrenderer.ColorTexture;
24import com.android.gallery3d.glrenderer.FadeInTexture;
25import com.android.gallery3d.glrenderer.GLCanvas;
26import com.android.gallery3d.glrenderer.Texture;
27import com.android.gallery3d.glrenderer.TiledTexture;
28
29public class AlbumSlotRenderer extends AbstractSlotRenderer {
30    @SuppressWarnings("unused")
31    private static final String TAG = "AlbumView";
32
33    public interface SlotFilter {
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
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
65    public void setPressedIndex(int index) {
66        if (mPressedIndex == index) return;
67        mPressedIndex = index;
68        mSlotView.invalidate();
69    }
70
71    public void setPressedUp() {
72        if (mPressedIndex == -1) return;
73        mAnimatePressedUp = true;
74        mSlotView.invalidate();
75    }
76
77    public void setHighlightItemPath(Path path) {
78        if (mHighlightItemPath == path) return;
79        mHighlightItemPath = path;
80        mSlotView.invalidate();
81    }
82
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
96    private static Texture checkTexture(Texture texture) {
97        return (texture instanceof TiledTexture)
98                && !((TiledTexture) texture).isReady()
99                ? null
100                : texture;
101    }
102
103    @Override
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
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
163        public void onContentChanged() {
164            mSlotView.invalidate();
165        }
166
167        @Override
168        public void onSizeChanged(int size) {
169            mSlotView.setSlotCount(size);
170        }
171    }
172
173    public void resume() {
174        mDataWindow.resume();
175    }
176
177    public void pause() {
178        mDataWindow.pause();
179    }
180
181    @Override
182    public void prepareDrawing() {
183        mInSelectionMode = mSelectionManager.inSelectionMode();
184    }
185
186    @Override
187    public void onVisibleRangeChanged(int visibleStart, int visibleEnd) {
188        if (mDataWindow != null) {
189            mDataWindow.setActiveWindow(visibleStart, visibleEnd);
190        }
191    }
192
193    @Override
194    public void onSlotSizeChanged(int width, int height) {
195        // Do nothing
196    }
197
198    public void setSlotFilter(SlotFilter slotFilter) {
199        mSlotFilter = slotFilter;
200    }
201}
202