diff options
Diffstat (limited to 'src/com/android/gallery3d/ui/AlbumSlidingWindow.java')
-rw-r--r-- | src/com/android/gallery3d/ui/AlbumSlidingWindow.java | 333 |
1 files changed, 286 insertions, 47 deletions
diff --git a/src/com/android/gallery3d/ui/AlbumSlidingWindow.java b/src/com/android/gallery3d/ui/AlbumSlidingWindow.java index fec7d1e92..f0540b175 100644 --- a/src/com/android/gallery3d/ui/AlbumSlidingWindow.java +++ b/src/com/android/gallery3d/ui/AlbumSlidingWindow.java @@ -1,4 +1,7 @@ /* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Not a Contribution + * * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,17 +19,28 @@ package com.android.gallery3d.ui; +import android.content.res.Configuration; import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.Bitmap.Config; import android.os.Message; +import android.text.TextPaint; +import android.text.TextUtils; import com.android.gallery3d.app.AbstractGalleryActivity; import com.android.gallery3d.app.AlbumDataLoader; +import com.android.gallery3d.app.AlbumPage; import com.android.gallery3d.common.Utils; import com.android.gallery3d.data.MediaItem; import com.android.gallery3d.data.MediaObject; import com.android.gallery3d.data.MediaObject.PanoramaSupportCallback; import com.android.gallery3d.data.Path; +import com.android.gallery3d.glrenderer.BitmapTexture; import com.android.gallery3d.glrenderer.Texture; +import com.android.gallery3d.glrenderer.TextureUploader; import com.android.gallery3d.glrenderer.TiledTexture; import com.android.gallery3d.util.Future; import com.android.gallery3d.util.FutureListener; @@ -38,14 +52,18 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { private static final int MSG_UPDATE_ENTRY = 0; private static final int JOB_LIMIT = 2; + private static final int MSG_UPDATE_ALBUM_ENTRY = 1; + public static final String KEY_ALBUM = "Album"; public static interface Listener { public void onSizeChanged(int size); + public void onContentChanged(); } public static class AlbumEntry { public MediaItem item; + public String name; // For title of image public Path path; public boolean isPanorama; public int rotation; @@ -55,6 +73,9 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { public Texture content; private BitmapLoader contentLoader; private PanoSupportListener mPanoSupportListener; + public BitmapTexture labelTexture; + private BitmapLoader labelLoader; + } private final AlbumDataLoader mSource; @@ -75,36 +96,64 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { private int mActiveRequestCount = 0; private boolean mIsActive = false; + private AlbumLabelMaker mLabelMaker; + private int mSlotWidth; + private BitmapTexture mLoadingLabel; + private TextureUploader mLabelUploader; + private int mCurrentView; + private AbstractGalleryActivity mActivity; + private boolean isSlotSizeChanged; + private boolean mViewType; private class PanoSupportListener implements PanoramaSupportCallback { public final AlbumEntry mEntry; - public PanoSupportListener (AlbumEntry entry) { + + public PanoSupportListener(AlbumEntry entry) { mEntry = entry; } + @Override - public void panoramaInfoAvailable(MediaObject mediaObject, boolean isPanorama, - boolean isPanorama360) { - if (mEntry != null) mEntry.isPanorama = isPanorama; + public void panoramaInfoAvailable(MediaObject mediaObject, + boolean isPanorama, boolean isPanorama360) { + if (mEntry != null) + mEntry.isPanorama = isPanorama; } } public AlbumSlidingWindow(AbstractGalleryActivity activity, - AlbumDataLoader source, int cacheSize) { + AlbumDataLoader source, int cacheSize, + AlbumSlotRenderer.LabelSpec labelSpec, boolean viewType) { source.setDataListener(this); mSource = source; + mViewType = viewType; mData = new AlbumEntry[cacheSize]; mSize = source.size(); - mHandler = new SynchronizedHandler(activity.getGLRoot()) { @Override public void handleMessage(Message message) { - Utils.assertTrue(message.what == MSG_UPDATE_ENTRY); - ((ThumbnailLoader) message.obj).updateEntry(); + switch (message.what) { + case 0: + Utils.assertTrue(message.what == MSG_UPDATE_ENTRY); + ((ThumbnailLoader) message.obj).updateEntry(); + break; + case 1: + Utils.assertTrue(message.what == MSG_UPDATE_ALBUM_ENTRY); + ((EntryUpdater) message.obj).updateEntry(); + break; + } + } }; mThreadPool = new JobLimiter(activity.getThreadPool(), JOB_LIMIT); + if (!mViewType) { + mLabelMaker = new AlbumLabelMaker(activity.getAndroidContext(), + labelSpec); + mLabelUploader = new TextureUploader(activity.getGLRoot()); + } mTileUploader = new TiledTexture.Uploader(activity.getGLRoot()); + mActivity = activity; + } public void setListener(Listener listener) { @@ -113,8 +162,8 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { public AlbumEntry get(int slotIndex) { if (!isActiveSlot(slotIndex)) { - Utils.fail("invalid slot: %s outsides (%s, %s)", - slotIndex, mActiveStart, mActiveEnd); + Utils.fail("invalid slot: %s outsides (%s, %s)", slotIndex, + mActiveStart, mActiveEnd); } return mData[slotIndex % mData.length]; } @@ -124,7 +173,8 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { } private void setContentWindow(int contentStart, int contentEnd) { - if (contentStart == mContentStart && contentEnd == mContentEnd) return; + if (contentStart == mContentStart && contentEnd == mContentEnd) + return; if (!mIsActive) { mContentStart = contentStart; @@ -170,12 +220,13 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { mActiveStart = start; mActiveEnd = end; - int contentStart = Utils.clamp((start + end) / 2 - data.length / 2, - 0, Math.max(0, mSize - data.length)); + int contentStart = Utils.clamp((start + end) / 2 - data.length / 2, 0, + Math.max(0, mSize - data.length)); int contentEnd = Math.min(contentStart + data.length, mSize); setContentWindow(contentStart, contentEnd); updateTextureUploadQueue(); - if (mIsActive) updateAllImageRequests(); + if (mIsActive) + updateAllImageRequests(); } private void uploadBgTextureInSlot(int index) { @@ -184,12 +235,21 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { if (entry.bitmapTexture != null) { mTileUploader.addTexture(entry.bitmapTexture); } + if (!mViewType) { + if (entry.labelTexture != null) { + mLabelUploader.addBgTexture(entry.labelTexture); + } + } } } private void updateTextureUploadQueue() { - if (!mIsActive) return; + if (!mIsActive) + return; mTileUploader.clear(); + if (!mViewType) { + mLabelUploader.clear(); + } // add foreground textures for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) { @@ -197,11 +257,16 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { if (entry.bitmapTexture != null) { mTileUploader.addTexture(entry.bitmapTexture); } + if (!mViewType) { + if (entry.labelTexture != null) { + mLabelUploader.addFgTexture(entry.labelTexture); + } + } } // add background textures - int range = Math.max( - (mContentEnd - mActiveEnd), (mActiveStart - mContentStart)); + int range = Math.max((mContentEnd - mActiveEnd), + (mActiveStart - mContentStart)); for (int i = 0; i < range; ++i) { uploadBgTextureInSlot(mActiveEnd + i); uploadBgTextureInSlot(mActiveStart - i - 1); @@ -209,54 +274,108 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { } // We would like to request non active slots in the following order: - // Order: 8 6 4 2 1 3 5 7 - // |---------|---------------|---------| - // |<- active ->| - // |<-------- cached range ----------->| + // Order: 8 6 4 2 1 3 5 7 + // |---------|---------------|---------| + // |<- active ->| + // |<-------- cached range ----------->| private void requestNonactiveImages() { - int range = Math.max( - (mContentEnd - mActiveEnd), (mActiveStart - mContentStart)); - for (int i = 0 ;i < range; ++i) { - requestSlotImage(mActiveEnd + i); - requestSlotImage(mActiveStart - 1 - i); + int range = Math.max((mContentEnd - mActiveEnd), + (mActiveStart - mContentStart)); + for (int i = 0; i < range; ++i) { + // requestSlotImage(mActiveEnd + i); + // requestSlotImage(mActiveStart - 1 - i); + requestImagesInSlot(mActiveEnd + i); + requestImagesInSlot(mActiveStart - 1 - i); + } + isSlotSizeChanged = false; + } + + private void requestImagesInSlot(int slotIndex) { + if (slotIndex < mContentStart || slotIndex >= mContentEnd) + return; + AlbumEntry entry = mData[slotIndex % mData.length]; + if (isSlotSizeChanged && !mViewType) { + if ((entry.content != null || entry.item == null) + && entry.labelTexture != null) { + return; + + } else { + if (entry.labelLoader != null) + entry.labelLoader.startLoad(); + } + } else { + if (entry.content != null || entry.item == null) + return; + entry.mPanoSupportListener = new PanoSupportListener(entry); + entry.item.getPanoramaSupport(entry.mPanoSupportListener); + if (entry.contentLoader != null) + entry.contentLoader.startLoad(); + if (!mViewType) { + + if (entry.labelLoader != null) + entry.labelLoader.startLoad(); + } } + } // return whether the request is in progress or not private boolean requestSlotImage(int slotIndex) { - if (slotIndex < mContentStart || slotIndex >= mContentEnd) return false; + if (slotIndex < mContentStart || slotIndex >= mContentEnd) + return false; AlbumEntry entry = mData[slotIndex % mData.length]; - if (entry.content != null || entry.item == null) return false; + if (entry.content != null || entry.item == null) + return false; // Set up the panorama callback entry.mPanoSupportListener = new PanoSupportListener(entry); entry.item.getPanoramaSupport(entry.mPanoSupportListener); - entry.contentLoader.startLoad(); return entry.contentLoader.isRequestInProgress(); } + private static boolean startLoadBitmap(BitmapLoader loader) { + if (loader == null) + return false; + loader.startLoad(); + return loader.isRequestInProgress(); + } + private void cancelNonactiveImages() { - int range = Math.max( - (mContentEnd - mActiveEnd), (mActiveStart - mContentStart)); - for (int i = 0 ;i < range; ++i) { + int range = Math.max((mContentEnd - mActiveEnd), + (mActiveStart - mContentStart)); + for (int i = 0; i < range; ++i) { cancelSlotImage(mActiveEnd + i); cancelSlotImage(mActiveStart - 1 - i); } } private void cancelSlotImage(int slotIndex) { - if (slotIndex < mContentStart || slotIndex >= mContentEnd) return; + if (slotIndex < mContentStart || slotIndex >= mContentEnd) + return; AlbumEntry item = mData[slotIndex % mData.length]; - if (item.contentLoader != null) item.contentLoader.cancelLoad(); + if (item.contentLoader != null) + item.contentLoader.cancelLoad(); + if (!mViewType) { + if (item.labelLoader != null) + item.labelLoader.cancelLoad(); + } } private void freeSlotContent(int slotIndex) { AlbumEntry data[] = mData; int index = slotIndex % data.length; AlbumEntry entry = data[index]; - if (entry.contentLoader != null) entry.contentLoader.recycle(); - if (entry.bitmapTexture != null) entry.bitmapTexture.recycle(); + if (entry.contentLoader != null) + entry.contentLoader.recycle(); + if (!mViewType) { + if (entry.labelLoader != null) + entry.labelLoader.recycle(); + if (entry.labelTexture != null) + entry.labelTexture.recycle(); + } + if (entry.bitmapTexture != null) + entry.bitmapTexture.recycle(); data[index] = null; } @@ -264,28 +383,63 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { AlbumEntry entry = new AlbumEntry(); MediaItem item = mSource.get(slotIndex); // item could be null; entry.item = item; - entry.mediaType = (item == null) - ? MediaItem.MEDIA_TYPE_UNKNOWN + entry.name = (item == null) ? null : item.getName(); + entry.mediaType = (item == null) ? MediaItem.MEDIA_TYPE_UNKNOWN : entry.item.getMediaType(); entry.path = (item == null) ? null : item.getPath(); entry.rotation = (item == null) ? 0 : item.getRotation(); entry.contentLoader = new ThumbnailLoader(slotIndex, entry.item); + if (!mViewType) { + if (entry.labelLoader != null) { + entry.labelLoader.recycle(); + entry.labelLoader = null; + entry.labelTexture = null; + } + if (entry.name != null) { + entry.labelLoader = new AlbumLabelLoader(slotIndex, entry.name); + } + } mData[slotIndex % mData.length] = entry; } private void updateAllImageRequests() { mActiveRequestCount = 0; for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) { - if (requestSlotImage(i)) ++mActiveRequestCount; + AlbumEntry entry = mData[i % mData.length]; + if (isSlotSizeChanged) { + if ((entry.content != null || entry.item == null) + && entry.labelTexture != null) { + continue; + } else { + if (startLoadBitmap(entry.labelLoader)) + ++mActiveRequestCount; + } + + } + + else { + if (entry.content != null || entry.item == null) + continue; + if (startLoadBitmap(entry.contentLoader)) + ++mActiveRequestCount; + if (!mViewType) { + if (startLoadBitmap(entry.labelLoader)) + ++mActiveRequestCount; + } + } + + // if (requestSlotImage(i)) ++mActiveRequestCount; } - if (mActiveRequestCount == 0) { + + if (isSlotSizeChanged || mActiveRequestCount == 0) { requestNonactiveImages(); } else { + cancelNonactiveImages(); } } - private class ThumbnailLoader extends BitmapLoader { + private class ThumbnailLoader extends BitmapLoader { private final int mSlotIndex; private final MediaItem mItem; @@ -307,7 +461,9 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { public void updateEntry() { Bitmap bitmap = getBitmap(); - if (bitmap == null) return; // error or recycled + + if (bitmap == null) + return; // error or recycled AlbumEntry entry = mData[mSlotIndex % mData.length]; entry.bitmapTexture = new TiledTexture(bitmap); entry.content = entry.bitmapTexture; @@ -315,8 +471,10 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { if (isActiveSlot(mSlotIndex)) { mTileUploader.addTexture(entry.bitmapTexture); --mActiveRequestCount; - if (mActiveRequestCount == 0) requestNonactiveImages(); - if (mListener != null) mListener.onContentChanged(); + if (mActiveRequestCount == 0) + requestNonactiveImages(); + if (mListener != null) + mListener.onContentChanged(); } else { mTileUploader.addTexture(entry.bitmapTexture); } @@ -327,9 +485,12 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { public void onSizeChanged(int size) { if (mSize != size) { mSize = size; - if (mListener != null) mListener.onSizeChanged(mSize); - if (mContentEnd > mSize) mContentEnd = mSize; - if (mActiveEnd > mSize) mActiveEnd = mSize; + if (mListener != null) + mListener.onSizeChanged(mSize); + if (mContentEnd > mSize) + mContentEnd = mSize; + if (mActiveEnd > mSize) + mActiveEnd = mSize; } } @@ -356,10 +517,88 @@ public class AlbumSlidingWindow implements AlbumDataLoader.DataListener { public void pause() { mIsActive = false; + if (!mViewType) + mLabelUploader.clear(); mTileUploader.clear(); TiledTexture.freeResources(); for (int i = mContentStart, n = mContentEnd; i < n; ++i) { freeSlotContent(i); } } + + private static interface EntryUpdater { + public void updateEntry(); + } + + private class AlbumLabelLoader extends BitmapLoader implements EntryUpdater { + private final int mSlotIndex; + private final String mTitle; + + public AlbumLabelLoader(int slotIndex, String title) { + mSlotIndex = slotIndex; + mTitle = title; + // mTotalCount = totalCount; + // mSourceType = sourceType; + } + + @Override + protected Future<Bitmap> submitBitmapTask(FutureListener<Bitmap> l) { + return mThreadPool.submit(mLabelMaker.requestLabel(mTitle), this); + } + + @Override + protected void onLoadComplete(Bitmap bitmap) { + mHandler.obtainMessage(MSG_UPDATE_ALBUM_ENTRY, this).sendToTarget(); + } + + @Override + public void updateEntry() { + Bitmap bitmap = getBitmap(); + if (bitmap == null) + return; // Error or recycled + + AlbumEntry entry = mData[mSlotIndex % mData.length]; + entry.labelTexture = new BitmapTexture(bitmap); + entry.labelTexture.setOpaque(false); + // entry.labelTexture = texture; + + if (isActiveSlot(mSlotIndex)) { + mLabelUploader.addFgTexture(entry.labelTexture); + --mActiveRequestCount; + if (mActiveRequestCount == 0) + requestNonactiveImages(); + if (mListener != null) + mListener.onContentChanged(); + } else { + mLabelUploader.addBgTexture(entry.labelTexture); + } + } + } + + public void onSlotSizeChanged(int width, int height) { + if (mSlotWidth == width) + return; + + isSlotSizeChanged = !mViewType ; + mSlotWidth = width; + mLoadingLabel = null; + mLabelMaker.setLabelWidth(mSlotWidth,KEY_ALBUM); + + if (!mIsActive) + return; + + for (int i = mContentStart, n = mContentEnd; i < n; ++i) { + AlbumEntry entry = mData[i % mData.length]; + if (entry.labelLoader != null) { + entry.labelLoader.recycle(); + entry.labelLoader = null; + entry.labelTexture = null; + } + if (entry.name != null) { + entry.labelLoader = new AlbumLabelLoader(i, entry.name); + } + } + updateAllImageRequests(); + updateTextureUploadQueue(); + } } |