1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project
3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License.
6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at
7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software
11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and
14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License.
15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */
16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.ui;
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
19b21b8e58a604f6c701245d84b141b5b87663192bOwen Linimport com.android.gallery3d.app.AbstractGalleryActivity;
20c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Linimport com.android.gallery3d.app.AlbumDataLoader;
2131cac30e46a293f6d0901e22c6ab0d083cae7021Owen Linimport com.android.gallery3d.data.MediaObject;
2231cac30e46a293f6d0901e22c6ab0d083cae7021Owen Linimport com.android.gallery3d.data.Path;
23a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport com.android.gallery3d.glrenderer.ColorTexture;
24a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport com.android.gallery3d.glrenderer.FadeInTexture;
25a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport com.android.gallery3d.glrenderer.GLCanvas;
26a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport com.android.gallery3d.glrenderer.Texture;
27a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport com.android.gallery3d.glrenderer.TiledTexture;
28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
29c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Linpublic class AlbumSlotRenderer extends AbstractSlotRenderer {
30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @SuppressWarnings("unused")
31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "AlbumView";
32616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin
33616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin    public interface SlotFilter {
34616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin        public boolean acceptSlot(int index);
35616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin    }
36616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin
37915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu    private final int mPlaceholderColor;
38cd36bfc52cc4e7f4b667ba3c5e8eb950647ae9d1Owen Lin    private static final int CACHE_SIZE = 96;
39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private AlbumSlidingWindow mDataWindow;
41b21b8e58a604f6c701245d84b141b5b87663192bOwen Lin    private final AbstractGalleryActivity mActivity;
421a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin    private final ColorTexture mWaitLoadingTexture;
437260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin    private final SlotView mSlotView;
4431cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    private final SelectionManager mSelectionManager;
45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
4631cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    private int mPressedIndex = -1;
4790fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang    private boolean mAnimatePressedUp;
4831cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    private Path mHighlightItemPath = null;
4931cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    private boolean mInSelectionMode;
501a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin
51616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin    private SlotFilter mSlotFilter;
52616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin
53b21b8e58a604f6c701245d84b141b5b87663192bOwen Lin    public AlbumSlotRenderer(AbstractGalleryActivity activity, SlotView slotView,
54915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu            SelectionManager selectionManager, int placeholderColor) {
55b21b8e58a604f6c701245d84b141b5b87663192bOwen Lin        super(activity);
56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mActivity = activity;
5731cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mSlotView = slotView;
5831cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mSelectionManager = selectionManager;
59915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu        mPlaceholderColor = placeholderColor;
601a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin
61915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu        mWaitLoadingTexture = new ColorTexture(mPlaceholderColor);
621a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin        mWaitLoadingTexture.setSize(1, 1);
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
6531cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    public void setPressedIndex(int index) {
6631cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        if (mPressedIndex == index) return;
6731cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mPressedIndex = index;
6831cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mSlotView.invalidate();
6931cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    }
7031cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin
7190fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang    public void setPressedUp() {
7290fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang        if (mPressedIndex == -1) return;
7390fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang        mAnimatePressedUp = true;
7490fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang        mSlotView.invalidate();
7590fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang    }
7690fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang
7731cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin    public void setHighlightItemPath(Path path) {
7831cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        if (mHighlightItemPath == path) return;
7931cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mHighlightItemPath = path;
8031cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mSlotView.invalidate();
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
83c3d8ac3b9504346dafc49e006b5f732dd1db21e8Owen Lin    public void setModel(AlbumDataLoader model) {
84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (mDataWindow != null) {
85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mDataWindow.setListener(null);
867260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin            mSlotView.setSlotCount(0);
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mDataWindow = null;
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (model != null) {
901a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin            mDataWindow = new AlbumSlidingWindow(mActivity, model, CACHE_SIZE);
91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mDataWindow.setListener(new MyDataModelListener());
927260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin            mSlotView.setSlotCount(model.size());
93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
9637c605949219b8bf54c165c34d6405f5f2989f50Owen Lin    private static Texture checkTexture(Texture texture) {
97adee31f028d839e7baa8f9e052dc4e4d60b137daOwen Lin        return (texture instanceof TiledTexture)
98adee31f028d839e7baa8f9e052dc4e4d60b137daOwen Lin                && !((TiledTexture) texture).isReady()
99d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin                ? null
100d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin                : texture;
101d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin    }
102d8fb81f601830385a2343d08ad5dd171e4c7bfe0Owen Lin
103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
1047260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin    public int renderSlot(GLCanvas canvas, int index, int pass, int width, int height) {
105616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin        if (mSlotFilter != null && !mSlotFilter.acceptSlot(index)) return 0;
106616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin
1071a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin        AlbumSlidingWindow.AlbumEntry entry = mDataWindow.get(index);
1081a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin
10931cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        int renderRequestFlags = 0;
11031cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin
11137c605949219b8bf54c165c34d6405f5f2989f50Owen Lin        Texture content = checkTexture(entry.content);
1121a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin        if (content == null) {
1131a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin            content = mWaitLoadingTexture;
1141a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin            entry.isWaitDisplayed = true;
1151a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin        } else if (entry.isWaitDisplayed) {
1161a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin            entry.isWaitDisplayed = false;
117915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu            content = new FadeInTexture(mPlaceholderColor, entry.bitmapTexture);
1183535d67239b1b1e4ee038f39dece64545b78f2edOwen Lin            entry.content = content;
1191a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin        }
12031cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        drawContent(canvas, content, width, height, entry.rotation);
12131cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        if ((content instanceof FadeInTexture) &&
12231cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin                ((FadeInTexture) content).isAnimating()) {
12331cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin            renderRequestFlags |= SlotView.RENDER_MORE_FRAME;
12431cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        }
1251a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin
12631cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        if (entry.mediaType == MediaObject.MEDIA_TYPE_VIDEO) {
12731cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin            drawVideoOverlay(canvas, width, height);
1287260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin        }
12931cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin
13031cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        if (entry.isPanorama) {
1312f060cc74ab6be5e5dd39e53dc99941b368ffb60Doris Liu            drawPanoramaIcon(canvas, width, height);
13231cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        }
13331cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin
13490fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang        renderRequestFlags |= renderOverlay(canvas, index, entry, width, height);
13590fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang
13690fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang        return renderRequestFlags;
13790fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang    }
13890fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang
13990fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang    private int renderOverlay(GLCanvas canvas, int index,
14090fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang            AlbumSlidingWindow.AlbumEntry entry, int width, int height) {
14190fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang        int renderRequestFlags = 0;
14231cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        if (mPressedIndex == index) {
14390fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang            if (mAnimatePressedUp) {
14490fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang                drawPressedUpFrame(canvas, width, height);
14590fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang                renderRequestFlags |= SlotView.RENDER_MORE_FRAME;
14690fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang                if (isPressedUpFrameFinished()) {
14790fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang                    mAnimatePressedUp = false;
14890fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang                    mPressedIndex = -1;
14990fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang                }
15090fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang            } else {
15190fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang                drawPressedFrame(canvas, width, height);
15290fe70f11b0961e1e5ae353cdf563236a55f502dYuli Huang            }
15331cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        } else if ((entry.path != null) && (mHighlightItemPath == entry.path)) {
15431cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin            drawSelectedFrame(canvas, width, height);
15531cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        } else if (mInSelectionMode && mSelectionManager.isItemSelected(entry.path)) {
15631cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin            drawSelectedFrame(canvas, width, height);
15731cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        }
15831cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        return renderRequestFlags;
159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private class MyDataModelListener implements AlbumSlidingWindow.Listener {
1627260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin        @Override
1637260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin        public void onContentChanged() {
1647260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin            mSlotView.invalidate();
165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
1677260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin        @Override
168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void onSizeChanged(int size) {
1697260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin            mSlotView.setSlotCount(size);
170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void resume() {
174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mDataWindow.resume();
175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void pause() {
178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mDataWindow.pause();
179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
1807260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin
1817260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin    @Override
1827260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin    public void prepareDrawing() {
18331cac30e46a293f6d0901e22c6ab0d083cae7021Owen Lin        mInSelectionMode = mSelectionManager.inSelectionMode();
1847260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin    }
1857260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin
1867260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin    @Override
1877260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin    public void onVisibleRangeChanged(int visibleStart, int visibleEnd) {
1887260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin        if (mDataWindow != null) {
1897260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin            mDataWindow.setActiveWindow(visibleStart, visibleEnd);
1907260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin        }
1917260f6f74d465520e4497b23fe56f98abb0c15a2Owen Lin    }
1921a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin
1931a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin    @Override
1941a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin    public void onSlotSizeChanged(int width, int height) {
1951a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin        // Do nothing
1961a4bd273afe5dd11592f7625c2f19853b6f174e9Owen Lin    }
197616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin
198616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin    public void setSlotFilter(SlotFilter slotFilter) {
199616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin        mSlotFilter = slotFilter;
200616a70fdb4473d2fbd7b70772a3a82b908aeae1eOwen Lin    }
201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
202