AlbumSetSlidingWindow.java revision dbf4ba12afba115888493caa34937643257e2bb1
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 19dbf4ba12afba115888493caa34937643257e2bb1Ray Chenimport android.graphics.Bitmap; 20dbf4ba12afba115888493caa34937643257e2bb1Ray Chenimport android.graphics.Color; 21dbf4ba12afba115888493caa34937643257e2bb1Ray Chenimport android.os.Message; 22dbf4ba12afba115888493caa34937643257e2bb1Ray Chen 23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.R; 24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.app.GalleryActivity; 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.common.Utils; 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.MediaItem; 27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.MediaSet; 28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.data.Path; 29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.ui.AlbumSetView.AlbumSetItem; 30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.Future; 31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.FutureListener; 32bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Changimport com.android.gallery3d.util.GalleryUtils; 33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.MediaSetUtils; 34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport com.android.gallery3d.util.ThreadPool; 35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class AlbumSetSlidingWindow implements AlbumSetView.ModelListener { 37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "GallerySlidingWindow"; 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int MSG_LOAD_BITMAP_DONE = 0; 39da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang private static final int PLACEHOLDER_COLOR = 0xFF222222; 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static interface Listener { 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onSizeChanged(int size); 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onContentInvalidated(); 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onWindowContentChanged( 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int slot, AlbumSetItem old, AlbumSetItem update); 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final AlbumSetView.Model mSource; 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mSize; 50dbf4ba12afba115888493caa34937643257e2bb1Ray Chen private final AlbumSetView.LabelSpec mLabelSpec; 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mContentStart = 0; 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mContentEnd = 0; 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mActiveStart = 0; 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mActiveEnd = 0; 57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private Listener mListener; 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final MyAlbumSetItem mData[]; 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private SelectionDrawer mSelectionDrawer; 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final ColorTexture mWaitLoadingTexture; 63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 64dbf4ba12afba115888493caa34937643257e2bb1Ray Chen private final SynchronizedHandler mHandler; 65dbf4ba12afba115888493caa34937643257e2bb1Ray Chen private final ThreadPool mThreadPool; 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mActiveRequestCount = 0; 68dbf4ba12afba115888493caa34937643257e2bb1Ray Chen private final String mLoadingLabel; 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mIsActive = false; 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static class MyAlbumSetItem extends AlbumSetItem { 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Path setPath; 73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int sourceType; 74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int cacheFlag; 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int cacheStatus; 76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 789201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang public AlbumSetSlidingWindow(GalleryActivity activity, 799201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang AlbumSetView.LabelSpec labelSpec, SelectionDrawer drawer, 80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin AlbumSetView.Model source, int cacheSize) { 81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin source.setModelListener(this); 829201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang mLabelSpec = labelSpec; 83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mLoadingLabel = activity.getAndroidContext().getString(R.string.loading); 84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource = source; 85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSelectionDrawer = drawer; 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mData = new MyAlbumSetItem[cacheSize]; 87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSize = source.size(); 88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 89da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang mWaitLoadingTexture = new ColorTexture(PLACEHOLDER_COLOR); 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mWaitLoadingTexture.setSize(1, 1); 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mHandler = new SynchronizedHandler(activity.getGLRoot()) { 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void handleMessage(Message message) { 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Utils.assertTrue(message.what == MSG_LOAD_BITMAP_DONE); 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ((GalleryDisplayItem) message.obj).onLoadBitmapDone(); 97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin }; 99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mThreadPool = activity.getThreadPool(); 101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setSelectionDrawer(SelectionDrawer drawer) { 104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSelectionDrawer = drawer; 105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setListener(Listener listener) { 108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mListener = listener; 109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public AlbumSetItem get(int slotIndex) { 112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Utils.assertTrue(isActiveSlot(slotIndex), 113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin "invalid slot: %s outsides (%s, %s)", 114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin slotIndex, mActiveStart, mActiveEnd); 115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mData[slotIndex % mData.length]; 116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int size() { 119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mSize; 120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean isActiveSlot(int slotIndex) { 123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return slotIndex >= mActiveStart && slotIndex < mActiveEnd; 124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void setContentWindow(int contentStart, int contentEnd) { 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (contentStart == mContentStart && contentEnd == mContentEnd) return; 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (contentStart >= mContentEnd || mContentStart >= contentEnd) { 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mContentStart, n = mContentEnd; i < n; ++i) { 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin freeSlotContent(i); 132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource.setActiveWindow(contentStart, contentEnd); 134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = contentStart; i < contentEnd; ++i) { 135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin prepareSlotContent(i); 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mContentStart; i < contentStart; ++i) { 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin freeSlotContent(i); 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = contentEnd, n = mContentEnd; i < n; ++i) { 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin freeSlotContent(i); 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource.setActiveWindow(contentStart, contentEnd); 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = contentStart, n = mContentStart; i < n; ++i) { 146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin prepareSlotContent(i); 147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mContentEnd; i < contentEnd; ++i) { 149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin prepareSlotContent(i); 150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentStart = contentStart; 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentEnd = contentEnd; 155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setActiveWindow(int start, int end) { 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Utils.assertTrue( 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin start <= end && end - start <= mData.length && end <= mSize, 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin "start = %s, end = %s, length = %s, size = %s", 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin start, end, mData.length, mSize); 162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin AlbumSetItem data[] = mData; 164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mActiveStart = start; 166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mActiveEnd = end; 167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // If no data is visible, keep the cache content 169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (start == end) return; 170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int contentStart = Utils.clamp((start + end) / 2 - data.length / 2, 172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 0, Math.max(0, mSize - data.length)); 173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int contentEnd = Math.min(contentStart + data.length, mSize); 174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setContentWindow(contentStart, contentEnd); 175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mIsActive) updateAllImageRequests(); 176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // We would like to request non active slots in the following order: 179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Order: 8 6 4 2 1 3 5 7 180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // |---------|---------------|---------| 181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // |<- active ->| 182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // |<-------- cached range ----------->| 183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void requestNonactiveImages() { 184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int range = Math.max( 185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentEnd - mActiveEnd, mActiveStart - mContentStart); 186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0 ;i < range; ++i) { 187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestImagesInSlot(mActiveEnd + i); 188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestImagesInSlot(mActiveStart - 1 - i); 189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void cancelNonactiveImages() { 193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int range = Math.max( 194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContentEnd - mActiveEnd, mActiveStart - mContentStart); 195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0 ;i < range; ++i) { 196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cancelImagesInSlot(mActiveEnd + i); 197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cancelImagesInSlot(mActiveStart - 1 - i); 198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void requestImagesInSlot(int slotIndex) { 202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (slotIndex < mContentStart || slotIndex >= mContentEnd) return; 203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin AlbumSetItem items = mData[slotIndex % mData.length]; 204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (DisplayItem item : items.covers) { 205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ((GalleryDisplayItem) item).requestImage(); 206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void cancelImagesInSlot(int slotIndex) { 210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (slotIndex < mContentStart || slotIndex >= mContentEnd) return; 211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin AlbumSetItem items = mData[slotIndex % mData.length]; 212f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (DisplayItem item : items.covers) { 213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ((GalleryDisplayItem) item).cancelImageRequest(); 214f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 215f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 216f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 217f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void freeSlotContent(int slotIndex) { 218f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin AlbumSetItem data[] = mData; 219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int index = slotIndex % data.length; 220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin AlbumSetItem original = data[index]; 221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (original != null) { 222f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin data[index] = null; 223f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (DisplayItem item : original.covers) { 224f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ((GalleryDisplayItem) item).recycle(); 225f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 226f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private long getMediaSetDataVersion(MediaSet set) { 230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return set == null 231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ? MediaSet.INVALID_DATA_VERSION 232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin : set.getDataVersion(); 233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 235f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void prepareSlotContent(int slotIndex) { 236f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaSet set = mSource.getMediaSet(slotIndex); 237f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 238f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MyAlbumSetItem item = new MyAlbumSetItem(); 239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaItem[] coverItems = mSource.getCoverItems(slotIndex); 240f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin item.covers = new GalleryDisplayItem[coverItems.length]; 241f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin item.sourceType = identifySourceType(set); 242f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin item.cacheFlag = identifyCacheFlag(set); 243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin item.cacheStatus = identifyCacheStatus(set); 244f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin item.setPath = set == null ? null : set.getPath(); 245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0; i < coverItems.length; ++i) { 247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin item.covers[i] = new GalleryDisplayItem(slotIndex, i, coverItems[i]); 248f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin item.labelItem = new LabelDisplayItem(slotIndex); 250f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin item.setDataVersion = getMediaSetDataVersion(set); 251f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mData[slotIndex % mData.length] = item; 252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 254f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean isCoverItemsChanged(int slotIndex) { 255f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin AlbumSetItem original = mData[slotIndex % mData.length]; 256f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (original == null) return true; 257f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaItem[] coverItems = mSource.getCoverItems(slotIndex); 258f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 259f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (original.covers.length != coverItems.length) return true; 260f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = 0, n = coverItems.length; i < n; ++i) { 261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GalleryDisplayItem g = (GalleryDisplayItem) original.covers[i]; 262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (g.mDataVersion != coverItems[i].getDataVersion()) return true; 263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return false; 265f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 266f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 267f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void updateSlotContent(final int slotIndex) { 268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MyAlbumSetItem data[] = mData; 270f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int pos = slotIndex % data.length; 271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MyAlbumSetItem original = data[pos]; 272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!isCoverItemsChanged(slotIndex)) { 274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaSet set = mSource.getMediaSet(slotIndex); 275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin original.sourceType = identifySourceType(set); 276f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin original.cacheFlag = identifyCacheFlag(set); 277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin original.cacheStatus = identifyCacheStatus(set); 278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin original.setPath = set == null ? null : set.getPath(); 279f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ((LabelDisplayItem) original.labelItem).updateContent(); 280f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mListener != null) mListener.onContentInvalidated(); 281f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return; 282f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 283f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 284f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin prepareSlotContent(slotIndex); 285f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin AlbumSetItem update = data[pos]; 286f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 287f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mListener != null && isActiveSlot(slotIndex)) { 288f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mListener.onWindowContentChanged(slotIndex, original, update); 289f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 290f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (original != null) { 291f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (DisplayItem item : original.covers) { 292f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ((GalleryDisplayItem) item).recycle(); 293f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 294f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 295f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 296f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 297f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void notifySlotChanged(int slotIndex) { 298f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // If the updated content is not cached, ignore it 299f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (slotIndex < mContentStart || slotIndex >= mContentEnd) { 300f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.w(TAG, String.format( 301f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin "invalid update: %s is outside (%s, %s)", 302f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin slotIndex, mContentStart, mContentEnd) ); 303f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return; 304f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 305f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin updateSlotContent(slotIndex); 306f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean isActiveSlot = isActiveSlot(slotIndex); 307f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mActiveRequestCount == 0 || isActiveSlot) { 308f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (DisplayItem item : mData[slotIndex % mData.length].covers) { 309f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GalleryDisplayItem galleryItem = (GalleryDisplayItem) item; 310f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin galleryItem.requestImage(); 311f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (isActiveSlot && galleryItem.isRequestInProgress()) { 312f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ++mActiveRequestCount; 313f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 314f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 315f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 316f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 317f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 318f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void updateAllImageRequests() { 319f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mActiveRequestCount = 0; 320f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) { 321f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (DisplayItem item : mData[i % mData.length].covers) { 322f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GalleryDisplayItem coverItem = (GalleryDisplayItem) item; 323f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin coverItem.requestImage(); 324f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (coverItem.isRequestInProgress()) ++mActiveRequestCount; 325f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 326f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 327f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mActiveRequestCount == 0) { 328f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin requestNonactiveImages(); 329f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 330f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cancelNonactiveImages(); 331f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 332f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 333f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 334f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private class GalleryDisplayItem extends AbstractDisplayItem 335f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin implements FutureListener<Bitmap> { 336f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private Future<Bitmap> mFuture; 337f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mSlotIndex; 338f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mCoverIndex; 339f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mMediaType; 340f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private Texture mContent; 341f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final long mDataVersion; 342dbf4ba12afba115888493caa34937643257e2bb1Ray Chen private final boolean mIsPanorama; 3436c1f01e21406a05dc7d3258001aa901bd8628a79Chih-Chung Chang private boolean mWaitLoadingDisplayed; 344f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 345f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public GalleryDisplayItem(int slotIndex, int coverIndex, MediaItem item) { 346f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super(item); 347f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSlotIndex = slotIndex; 348f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCoverIndex = coverIndex; 349f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mMediaType = item.getMediaType(); 350f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mDataVersion = item.getDataVersion(); 351bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang mIsPanorama = GalleryUtils.isPanorama(item); 352f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin updateContent(mWaitLoadingTexture); 353f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 354f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 355f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 356f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin protected void onBitmapAvailable(Bitmap bitmap) { 357f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (isActiveSlot(mSlotIndex)) { 358f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin --mActiveRequestCount; 359f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mActiveRequestCount == 0) requestNonactiveImages(); 360f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 361f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (bitmap != null) { 3621a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang BitmapTexture texture = new BitmapTexture(bitmap, true); 363f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin texture.setThrottled(true); 3646c1f01e21406a05dc7d3258001aa901bd8628a79Chih-Chung Chang if (mWaitLoadingDisplayed) { 3656c1f01e21406a05dc7d3258001aa901bd8628a79Chih-Chung Chang updateContent(new FadeInTexture(PLACEHOLDER_COLOR, texture)); 3666c1f01e21406a05dc7d3258001aa901bd8628a79Chih-Chung Chang } else { 3676c1f01e21406a05dc7d3258001aa901bd8628a79Chih-Chung Chang updateContent(texture); 3686c1f01e21406a05dc7d3258001aa901bd8628a79Chih-Chung Chang } 369f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mListener != null) mListener.onContentInvalidated(); 370f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 371f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 372f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 373f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void updateContent(Texture content) { 374f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mContent = content; 3759201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang } 376f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3779201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang @Override 378da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang public int render(GLCanvas canvas, int pass) { 3799201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang // Fit the content into the box 3809201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang int width = mContent.getWidth(); 3819201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang int height = mContent.getHeight(); 382f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3839201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang float scalex = mBoxWidth / (float) width; 3849201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang float scaley = mBoxHeight / (float) height; 3859201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang float scale = Math.min(scalex, scaley); 386f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 387f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin width = (int) Math.floor(width * scale); 388f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin height = (int) Math.floor(height * scale); 389f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3909201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang // Now draw it 391f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int sourceType = SelectionDrawer.DATASOURCE_TYPE_NOT_CATEGORIZED; 392f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int cacheFlag = MediaSet.CACHE_FLAG_NO; 393f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int cacheStatus = MediaSet.CACHE_STATUS_NOT_CACHED; 394f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MyAlbumSetItem set = mData[mSlotIndex % mData.length]; 395f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Path path = set.setPath; 396f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mCoverIndex == 0) { 397f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin sourceType = set.sourceType; 398f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cacheFlag = set.cacheFlag; 399f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cacheStatus = set.cacheStatus; 400f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 401f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 4029201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang mSelectionDrawer.draw(canvas, mContent, width, height, 403da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang getRotation(), path, sourceType, mMediaType, 404bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang mIsPanorama, mLabelSpec.labelBackgroundHeight, 405f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cacheFlag == MediaSet.CACHE_FLAG_FULL, 406f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin (cacheFlag == MediaSet.CACHE_FLAG_FULL) 407f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin && (cacheStatus != MediaSet.CACHE_STATUS_CACHED_FULL)); 408da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang 4096c1f01e21406a05dc7d3258001aa901bd8628a79Chih-Chung Chang if (mContent == mWaitLoadingTexture) { 4106c1f01e21406a05dc7d3258001aa901bd8628a79Chih-Chung Chang mWaitLoadingDisplayed = true; 4116c1f01e21406a05dc7d3258001aa901bd8628a79Chih-Chung Chang } 4126c1f01e21406a05dc7d3258001aa901bd8628a79Chih-Chung Chang 4136c1f01e21406a05dc7d3258001aa901bd8628a79Chih-Chung Chang if ((mContent instanceof FadeInTexture) && 414da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang ((FadeInTexture) mContent).isAnimating()) { 415da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang return RENDER_MORE_FRAME; 416da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang } else { 417da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang return 0; 418da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang } 419f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 420f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 421f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 422f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void startLoadBitmap() { 423f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFuture = mThreadPool.submit(mMediaItem.requestImage( 424f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaItem.TYPE_MICROTHUMBNAIL), this); 425f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 426f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 427f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 428f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void cancelLoadBitmap() { 429f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFuture.cancel(); 430f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 431f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 432f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 433f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onFutureDone(Future<Bitmap> future) { 434f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mHandler.sendMessage(mHandler.obtainMessage(MSG_LOAD_BITMAP_DONE, this)); 435f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 436f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 437f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void onLoadBitmapDone() { 438f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Future<Bitmap> future = mFuture; 439f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mFuture = null; 440f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin updateImage(future.get(), future.isCancelled()); 441f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 442f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 443f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 444f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public String toString() { 445f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return String.format("GalleryDisplayItem(%s, %s)", mSlotIndex, mCoverIndex); 446f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 447f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 448f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 449f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static int identifySourceType(MediaSet set) { 450f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (set == null) { 451f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return SelectionDrawer.DATASOURCE_TYPE_NOT_CATEGORIZED; 452f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 453f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 454f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Path path = set.getPath(); 455f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (MediaSetUtils.isCameraSource(path)) { 456f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return SelectionDrawer.DATASOURCE_TYPE_CAMERA; 457f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 458f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 459f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int type = SelectionDrawer.DATASOURCE_TYPE_NOT_CATEGORIZED; 460f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin String prefix = path.getPrefix(); 461f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 462f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (prefix.equals("picasa")) { 463f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin type = SelectionDrawer.DATASOURCE_TYPE_PICASA; 464f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (prefix.equals("local") || prefix.equals("merge")) { 465f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin type = SelectionDrawer.DATASOURCE_TYPE_LOCAL; 466f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else if (prefix.equals("mtp")) { 467f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin type = SelectionDrawer.DATASOURCE_TYPE_MTP; 468f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 469f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 470f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return type; 471f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 472f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 473f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static int identifyCacheFlag(MediaSet set) { 474f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (set == null || (set.getSupportedOperations() 475f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin & MediaSet.SUPPORT_CACHE) == 0) { 476f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return MediaSet.CACHE_FLAG_NO; 477f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 478f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 479f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return set.getCacheFlag(); 480f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 481f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 482f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static int identifyCacheStatus(MediaSet set) { 483f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (set == null || (set.getSupportedOperations() 484f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin & MediaSet.SUPPORT_CACHE) == 0) { 485f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return MediaSet.CACHE_STATUS_NOT_CACHED; 486f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 487f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 488f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return set.getCacheStatus(); 489f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 490f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 491f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private class LabelDisplayItem extends DisplayItem { 4929201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang private static final int FONT_COLOR_TITLE = Color.WHITE; 493bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang private static final int FONT_COLOR_COUNT = 0x80FFFFFF; // 50% white 4949201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang 4959201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang private StringTexture mTextureTitle; 496bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang private StringTexture mTextureCount; 4979201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang private String mTitle; 498bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang private String mCount; 4999201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang private int mLastWidth; 500f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mSlotIndex; 501bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang private boolean mHasIcon; 502f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 503f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public LabelDisplayItem(int slotIndex) { 504f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSlotIndex = slotIndex; 505f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 506f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 507f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean updateContent() { 5089201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang String title = mLoadingLabel; 509bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang String count = ""; 510f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaSet set = mSource.getMediaSet(mSlotIndex); 511f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (set != null) { 5129201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang title = Utils.ensureNotNull(set.getName()); 513bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang count = "" + set.getTotalMediaItemCount(); 5149201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang } 5159201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang if (Utils.equals(title, mTitle) 516bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang && Utils.equals(count, mCount) 5179201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang && Utils.equals(mBoxWidth, mLastWidth)) { 5189201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang return false; 519f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 5209201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang mTitle = title; 521bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang mCount = count; 5229201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang mLastWidth = mBoxWidth; 523bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang mHasIcon = (identifySourceType(set) != 524bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang SelectionDrawer.DATASOURCE_TYPE_NOT_CATEGORIZED); 5259201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang 5269201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang AlbumSetView.LabelSpec s = mLabelSpec; 5279201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang mTextureTitle = StringTexture.newInstance( 5289201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang title, s.titleFontSize, FONT_COLOR_TITLE, 5299201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang mBoxWidth - s.leftMargin, false); 530bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang mTextureCount = StringTexture.newInstance( 531bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang count, s.countFontSize, FONT_COLOR_COUNT, 5329201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang mBoxWidth - s.leftMargin, true); 5339201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang 534f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return true; 535f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 536f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 537f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 538da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang public int render(GLCanvas canvas, int pass) { 5399201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang if (mBoxWidth != mLastWidth) { 5409201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang updateContent(); 5419201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang } 5429201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang 5439201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang AlbumSetView.LabelSpec s = mLabelSpec; 5449201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang int x = -mBoxWidth / 2; 545bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang int y = (mBoxHeight + 1) / 2 - s.labelBackgroundHeight; 5469201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang y += s.titleOffset; 5479201679ed1c485767f2e334aa618bd733024af03Chih-Chung Chang mTextureTitle.draw(canvas, x + s.leftMargin, y); 548bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang y += s.titleFontSize + s.countOffset; 549bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang x += mHasIcon ? s.iconSize : s.leftMargin; 550bc2154199aee16762e3758ad0cfed685323d9a9fChih-Chung Chang mTextureCount.draw(canvas, x, y); 551da071d27a1435cce080b5c609d0d833555e5a175Chih-Chung Chang return 0; 552f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 553f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 554f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 555f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public long getIdentity() { 556f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return System.identityHashCode(this); 557f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 558f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 559f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 560f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onSizeChanged(int size) { 561dbf4ba12afba115888493caa34937643257e2bb1Ray Chen if (mIsActive && mSize != size) { 562f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSize = size; 563dbf4ba12afba115888493caa34937643257e2bb1Ray Chen if (mListener != null) mListener.onSizeChanged(mSize); 564f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 565f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 566f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 567f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onWindowContentChanged(int index) { 568f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!mIsActive) { 569f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // paused, ignore slot changed event 570f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return; 571f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 572f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin notifySlotChanged(index); 573f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 574f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 575f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void pause() { 576f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIsActive = false; 577f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mContentStart, n = mContentEnd; i < n; ++i) { 578f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin freeSlotContent(i); 579f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 580f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 581f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 582f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void resume() { 583f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIsActive = true; 584f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin for (int i = mContentStart, n = mContentEnd; i < n; ++i) { 585f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin prepareSlotContent(i); 586f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 587f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin updateAllImageRequests(); 588f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 589f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 590