AlbumSlotRenderer.java revision 915c2c5b2c367df71599370613af0924bd7c4887
1e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*
2e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 2010 The Android Open Source Project
3e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
4e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Licensed under the Apache License, Version 2.0 (the "License");
5e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * you may not use this file except in compliance with the License.
6e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * You may obtain a copy of the License at
7e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
88f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo *      http://www.apache.org/licenses/LICENSE-2.0
9e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *
10e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Unless required by applicable law or agreed to in writing, software
11e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * distributed under the License is distributed on an "AS IS" BASIS,
128f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * See the License for the specific language governing permissions and
14e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * limitations under the License.
15e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */
16e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
17e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETpackage com.android.gallery3d.ui;
18e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
19e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETimport android.content.Context;
20e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
21e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETimport com.android.gallery3d.app.AlbumDataLoader;
228f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymoimport com.android.gallery3d.app.GalleryActivity;
238f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymoimport com.android.gallery3d.data.MediaObject;
248f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymoimport com.android.gallery3d.data.Path;
258f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo
268f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymopublic class AlbumSlotRenderer extends AbstractSlotRenderer {
27e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    @SuppressWarnings("unused")
28e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private static final String TAG = "AlbumView";
29e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
30e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    public interface SlotFilter {
31e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        public boolean acceptSlot(int index);
32e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
33e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
34e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private final int mPlaceholderColor;
35e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private static final int CACHE_SIZE = 96;
36e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
37e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private AlbumSlidingWindow mDataWindow;
38e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private final GalleryActivity mActivity;
39e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private final ColorTexture mWaitLoadingTexture;
40e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private final SlotView mSlotView;
41e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private final SelectionManager mSelectionManager;
42e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
43e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private int mPressedIndex = -1;
44e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private boolean mAnimatePressedUp;
45e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private Path mHighlightItemPath = null;
46e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private boolean mInSelectionMode;
47e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
48e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private SlotFilter mSlotFilter;
49e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
50e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    public AlbumSlotRenderer(GalleryActivity activity, SlotView slotView,
51e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            SelectionManager selectionManager, int placeholderColor) {
52e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        super((Context) activity);
53e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        mActivity = activity;
548f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo        mSlotView = slotView;
558f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo        mSelectionManager = selectionManager;
56e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        mPlaceholderColor = placeholderColor;
57e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
58e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        mWaitLoadingTexture = new ColorTexture(mPlaceholderColor);
59e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        mWaitLoadingTexture.setSize(1, 1);
60e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
61e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
62e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    public void setPressedIndex(int index) {
63e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if (mPressedIndex == index) return;
64e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        mPressedIndex = index;
65e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        mSlotView.invalidate();
66e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
67e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
68e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    public void setPressedUp() {
69e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if (mPressedIndex == -1) return;
70e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        mAnimatePressedUp = true;
71e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        mSlotView.invalidate();
72e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
73e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
74e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    public void setHighlightItemPath(Path path) {
75e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if (mHighlightItemPath == path) return;
76e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        mHighlightItemPath = path;
77e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        mSlotView.invalidate();
78e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
79e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
80e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    public void setModel(AlbumDataLoader model) {
81e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if (mDataWindow != null) {
82e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            mDataWindow.setListener(null);
83e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            mSlotView.setSlotCount(0);
84e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            mDataWindow = null;
85e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
86e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if (model != null) {
87e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            mDataWindow = new AlbumSlidingWindow(mActivity, model, CACHE_SIZE);
88e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            mDataWindow.setListener(new MyDataModelListener());
89e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            mSlotView.setSlotCount(model.size());
90e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
91e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
92e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
938f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo    private static Texture checkTexture(Texture texture) {
948f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo        return (texture instanceof UploadedTexture)
95e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                && ((UploadedTexture) texture).isUploading()
96e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                ? null
97e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                : texture;
98e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
99e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
100e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    @Override
1018f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo    public int renderSlot(GLCanvas canvas, int index, int pass, int width, int height) {
102e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if (mSlotFilter != null && !mSlotFilter.acceptSlot(index)) return 0;
1038f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo
1048f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo        AlbumSlidingWindow.AlbumEntry entry = mDataWindow.get(index);
105e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
106e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        int renderRequestFlags = 0;
107e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
108e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        Texture content = checkTexture(entry.content);
109e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if (content == null) {
110e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            content = mWaitLoadingTexture;
111e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            entry.isWaitDisplayed = true;
112e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        } else if (entry.isWaitDisplayed) {
113e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            entry.isWaitDisplayed = false;
114e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            content = new FadeInTexture(mPlaceholderColor, entry.bitmapTexture);
115e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            entry.content = content;
116e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
117e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        drawContent(canvas, content, width, height, entry.rotation);
118e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if ((content instanceof FadeInTexture) &&
119e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                ((FadeInTexture) content).isAnimating()) {
120e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            renderRequestFlags |= SlotView.RENDER_MORE_FRAME;
121e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
122e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
123e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if (entry.mediaType == MediaObject.MEDIA_TYPE_VIDEO) {
124e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            drawVideoOverlay(canvas, width, height);
125e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
126e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
127e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if (entry.isPanorama) {
128e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            drawPanoramaBorder(canvas, width, height);
129e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
130e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
131e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        renderRequestFlags |= renderOverlay(canvas, index, entry, width, height);
1328f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo
1338f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo        return renderRequestFlags;
134e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
135e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
136e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private int renderOverlay(GLCanvas canvas, int index,
137e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            AlbumSlidingWindow.AlbumEntry entry, int width, int height) {
138e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        int renderRequestFlags = 0;
139e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        if (mPressedIndex == index) {
140e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            if (mAnimatePressedUp) {
141e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                drawPressedUpFrame(canvas, width, height);
142e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                renderRequestFlags |= SlotView.RENDER_MORE_FRAME;
143e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                if (isPressedUpFrameFinished()) {
144e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                    mAnimatePressedUp = false;
1458f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo                    mPressedIndex = -1;
146e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                }
1478f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo            } else {
148e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET                drawPressedFrame(canvas, width, height);
149e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            }
150e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        } else if ((entry.path != null) && (mHighlightItemPath == entry.path)) {
151e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            drawSelectedFrame(canvas, width, height);
152e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        } else if (mInSelectionMode && mSelectionManager.isItemSelected(entry.path)) {
153e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            drawSelectedFrame(canvas, width, height);
154e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
155e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        return renderRequestFlags;
156e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    }
157e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
158e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET    private class MyDataModelListener implements AlbumSlidingWindow.Listener {
159e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        @Override
160e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        public void onContentChanged() {
161e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET            mSlotView.invalidate();
162e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        }
163e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET
164e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        @Override
165e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET        public void onSizeChanged(int size) {
166            mSlotView.setSlotCount(size);
167        }
168    }
169
170    public void resume() {
171        mDataWindow.resume();
172    }
173
174    public void pause() {
175        mDataWindow.pause();
176    }
177
178    @Override
179    public void prepareDrawing() {
180        mInSelectionMode = mSelectionManager.inSelectionMode();
181    }
182
183    @Override
184    public void onVisibleRangeChanged(int visibleStart, int visibleEnd) {
185        if (mDataWindow != null) {
186            mDataWindow.setActiveWindow(visibleStart, visibleEnd);
187        }
188    }
189
190    @Override
191    public void onSlotSizeChanged(int width, int height) {
192        // Do nothing
193    }
194
195    public void setSlotFilter(SlotFilter slotFilter) {
196        mSlotFilter = slotFilter;
197    }
198}
199