diff options
| author | Owen Lin <owenlin@google.com> | 2012-03-26 18:28:48 +0800 |
|---|---|---|
| committer | Owen Lin <owenlin@google.com> | 2012-04-05 14:46:06 +0800 |
| commit | 1a4bd273afe5dd11592f7625c2f19853b6f174e9 (patch) | |
| tree | 20c2c3a4ca0a0699f7978adc365df4f11055cf1f /src | |
| parent | 33ef03776b7734717b16f6fc861b831fb1b1dfac (diff) | |
| download | android_packages_apps_Gallery2-1a4bd273afe5dd11592f7625c2f19853b6f174e9.tar.gz android_packages_apps_Gallery2-1a4bd273afe5dd11592f7625c2f19853b6f174e9.tar.bz2 android_packages_apps_Gallery2-1a4bd273afe5dd11592f7625c2f19853b6f174e9.zip | |
Make all drawing happens in background.
Also move more rendering code to SlotRenderers (AlbumSetView and AlbumView).
Change-Id: I1d678711bfd3655a48bb4b99d8ca175e088bdffb
Diffstat (limited to 'src')
| -rw-r--r-- | src/com/android/gallery3d/app/AlbumSetDataAdapter.java | 32 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/AbstractDisplayItem.java | 118 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/AlbumLabelMaker.java | 169 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java | 502 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/AlbumSetView.java | 109 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/AlbumSlidingWindow.java | 257 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/AlbumView.java | 73 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/BitmapLoader.java | 108 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/DisplayItem.java | 39 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/GridDrawer.java | 3 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/HighlightDrawer.java | 2 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/IconDrawer.java | 57 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/ManageCacheDrawer.java | 2 | ||||
| -rw-r--r-- | src/com/android/gallery3d/ui/SlotView.java | 6 |
14 files changed, 724 insertions, 753 deletions
diff --git a/src/com/android/gallery3d/app/AlbumSetDataAdapter.java b/src/com/android/gallery3d/app/AlbumSetDataAdapter.java index 1d642f931..e739a96fb 100644 --- a/src/com/android/gallery3d/app/AlbumSetDataAdapter.java +++ b/src/com/android/gallery3d/app/AlbumSetDataAdapter.java @@ -41,16 +41,13 @@ public class AlbumSetDataAdapter implements AlbumSetView.Model { private static final int INDEX_NONE = -1; private static final int MIN_LOAD_COUNT = 4; - private static final int MAX_COVER_COUNT = 1; private static final int MSG_LOAD_START = 1; private static final int MSG_LOAD_FINISH = 2; private static final int MSG_RUN_OBJECT = 3; - private static final MediaItem[] EMPTY_MEDIA_ITEMS = new MediaItem[0]; - private final MediaSet[] mData; - private final MediaItem[][] mCoverData; + private final MediaItem[] mCoverItem; private final long[] mItemVersion; private final long[] mSetVersion; @@ -74,7 +71,7 @@ public class AlbumSetDataAdapter implements AlbumSetView.Model { public AlbumSetDataAdapter(GalleryActivity activity, MediaSet albumSet, int cacheSize) { mSource = Utils.checkNotNull(albumSet); - mCoverData = new MediaItem[cacheSize][]; + mCoverItem = new MediaItem[cacheSize]; mData = new MediaSet[cacheSize]; mItemVersion = new long[cacheSize]; mSetVersion = new long[cacheSize]; @@ -119,15 +116,12 @@ public class AlbumSetDataAdapter implements AlbumSetView.Model { return mData[index % mData.length]; } - public MediaItem[] getCoverItems(int index) { + public MediaItem getCoverItem(int index) { if (index < mActiveStart && index >= mActiveEnd) { throw new IllegalArgumentException(String.format( "%s not in (%s, %s)", index, mActiveStart, mActiveEnd)); } - MediaItem[] result = mCoverData[index % mCoverData.length]; - - // If the result is not ready yet, return an empty array - return result == null ? EMPTY_MEDIA_ITEMS : result; + return mCoverItem[index % mCoverItem.length]; } public int getActiveStart() { @@ -144,15 +138,14 @@ public class AlbumSetDataAdapter implements AlbumSetView.Model { private void clearSlot(int slotIndex) { mData[slotIndex] = null; - mCoverData[slotIndex] = null; + mCoverItem[slotIndex] = null; mItemVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION; mSetVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION; } private void setContentWindow(int contentStart, int contentEnd) { if (contentStart == mContentStart && contentEnd == mContentEnd) return; - MediaItem[][] data = mCoverData; - int length = data.length; + int length = mCoverItem.length; int start = this.mContentStart; int end = this.mContentEnd; @@ -179,12 +172,12 @@ public class AlbumSetDataAdapter implements AlbumSetView.Model { if (start == mActiveStart && end == mActiveEnd) return; Utils.assertTrue(start <= end - && end - start <= mCoverData.length && end <= mSize); + && end - start <= mCoverItem.length && end <= mSize); mActiveStart = start; mActiveEnd = end; - int length = mCoverData.length; + int length = mCoverItem.length; // If no data is visible, keep the cache content if (start == end) return; @@ -217,7 +210,7 @@ public class AlbumSetDataAdapter implements AlbumSetView.Model { public int size; public MediaSet item; - public MediaItem covers[]; + public MediaItem cover; } private class GetUpdateInfo implements Callable<UpdateInfo> { @@ -271,13 +264,13 @@ public class AlbumSetDataAdapter implements AlbumSetView.Model { } // Note: info.index could be INDEX_NONE, i.e., -1 if (info.index >= mContentStart && info.index < mContentEnd) { - int pos = info.index % mCoverData.length; + int pos = info.index % mCoverItem.length; mSetVersion[pos] = info.version; long itemVersion = info.item.getDataVersion(); if (mItemVersion[pos] == itemVersion) return null; mItemVersion[pos] = itemVersion; mData[pos] = info.item; - mCoverData[pos] = info.covers; + mCoverItem[pos] = info.cover; if (mModelListener != null && info.index >= mActiveStart && info.index < mActiveEnd) { mModelListener.onWindowContentChanged(info.index); @@ -355,8 +348,7 @@ public class AlbumSetDataAdapter implements AlbumSetView.Model { if (info.index != INDEX_NONE) { info.item = mSource.getSubMediaSet(info.index); if (info.item == null) continue; - MediaItem cover = info.item.getCoverMediaItem(); - info.covers = cover == null ? new MediaItem[0] : new MediaItem[] {cover}; + info.cover = info.item.getCoverMediaItem(); } } executeAndWait(new UpdateContent(info)); diff --git a/src/com/android/gallery3d/ui/AbstractDisplayItem.java b/src/com/android/gallery3d/ui/AbstractDisplayItem.java deleted file mode 100644 index 2547ebf31..000000000 --- a/src/com/android/gallery3d/ui/AbstractDisplayItem.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.ui; - -import android.graphics.Bitmap; - -import com.android.gallery3d.data.MediaItem; - -public abstract class AbstractDisplayItem extends DisplayItem { - - private static final String TAG = "AbstractDisplayItem"; - - private static final int STATE_INVALID = 0x01; - private static final int STATE_VALID = 0x02; - private static final int STATE_UPDATING = 0x04; - private static final int STATE_CANCELING = 0x08; - private static final int STATE_ERROR = 0x10; - - private int mState = STATE_INVALID; - private boolean mImageRequested = false; - private boolean mRecycling = false; - private Bitmap mBitmap; - - protected final MediaItem mMediaItem; - - public AbstractDisplayItem(MediaItem item) { - mMediaItem = item; - if (item == null) mState = STATE_ERROR; - } - - protected void updateImage(Bitmap bitmap, boolean isCancelled) { - if (mRecycling) { - recycleBitmap(bitmap); - return; - } - - if (isCancelled && bitmap == null) { - mState = STATE_INVALID; - if (mImageRequested) { - // request image again. - requestImage(); - } - return; - } - - mBitmap = bitmap; - mState = bitmap == null ? STATE_ERROR : STATE_VALID ; - onBitmapAvailable(mBitmap); - } - - @Override - public int getRotation() { - if (mMediaItem != null) return mMediaItem.getRotation(); - return 0; - } - - @Override - public int getIdentity() { - return mMediaItem != null - ? System.identityHashCode(mMediaItem.getPath()) - : System.identityHashCode(this); - } - - public void requestImage() { - mImageRequested = true; - if (mState == STATE_INVALID) { - mState = STATE_UPDATING; - startLoadBitmap(); - } - } - - public void cancelImageRequest() { - mImageRequested = false; - if (mState == STATE_UPDATING) { - mState = STATE_CANCELING; - cancelLoadBitmap(); - } - } - - private boolean inState(int states) { - return (mState & states) != 0; - } - - public void recycle() { - if (!inState(STATE_UPDATING | STATE_CANCELING)) { - if (mBitmap != null) { - recycleBitmap(mBitmap); - mBitmap = null; - } - } else { - mRecycling = true; - cancelImageRequest(); - } - } - - public boolean isRequestInProgress() { - return mImageRequested && inState(STATE_UPDATING | STATE_CANCELING); - } - - abstract protected void startLoadBitmap(); - abstract protected void cancelLoadBitmap(); - abstract protected void onBitmapAvailable(Bitmap bitmap); - abstract protected void recycleBitmap(Bitmap bitmap); -} diff --git a/src/com/android/gallery3d/ui/AlbumLabelMaker.java b/src/com/android/gallery3d/ui/AlbumLabelMaker.java new file mode 100644 index 000000000..22fe16d5f --- /dev/null +++ b/src/com/android/gallery3d/ui/AlbumLabelMaker.java @@ -0,0 +1,169 @@ +// Copyright 2012 Google Inc. All Rights Reserved. + +package com.android.gallery3d.ui; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Typeface; +import android.text.TextPaint; +import android.text.TextUtils; + +import com.android.gallery3d.R; +import com.android.gallery3d.common.Utils; +import com.android.gallery3d.data.MediaSet; +import com.android.gallery3d.util.ThreadPool; +import com.android.gallery3d.util.ThreadPool.JobContext; + +public class AlbumLabelMaker { + private static final int FONT_COLOR_TITLE = Color.WHITE; + private static final int FONT_COLOR_COUNT = 0x80FFFFFF; // 50% white + + private final AlbumSetView.LabelSpec mSpec; + private final TextPaint mTitlePaint; + private final TextPaint mCountPaint; + private final Context mContext; + + private final LazyLoadedBitmap mLocalSetIcon; + private final LazyLoadedBitmap mPicasaIcon; + private final LazyLoadedBitmap mCameraIcon; + private final LazyLoadedBitmap mMtpIcon; + + public AlbumLabelMaker(Context context, AlbumSetView.LabelSpec spec) { + mContext = context; + mSpec = spec; + mTitlePaint = getTextPaint(spec.titleFontSize, FONT_COLOR_TITLE, false); + mCountPaint = getTextPaint(spec.countFontSize, FONT_COLOR_COUNT, true); + + mLocalSetIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_folder); + mPicasaIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_picasa); + mCameraIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_camera); + mMtpIcon = new LazyLoadedBitmap(R.drawable.frame_overlay_gallery_ptp); + } + + private Bitmap getOverlayAlbumIcon(int sourceType) { + switch (sourceType) { + case SelectionDrawer.DATASOURCE_TYPE_CAMERA: + return mCameraIcon.get(); + case SelectionDrawer.DATASOURCE_TYPE_LOCAL: + return mLocalSetIcon.get(); + case SelectionDrawer.DATASOURCE_TYPE_MTP: + return mMtpIcon.get(); + case SelectionDrawer.DATASOURCE_TYPE_PICASA: + return mPicasaIcon.get(); + } + return null; + } + + private static TextPaint getTextPaint(int textSize, int color, boolean isBold) { + TextPaint paint = new TextPaint(); + paint.setTextSize(textSize); + paint.setAntiAlias(true); + paint.setColor(color); + paint.setShadowLayer(2f, 0f, 0f, Color.BLACK); + if (isBold) { + paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD)); + } + return paint; + } + + private class LazyLoadedBitmap { + private Bitmap mBitmap; + private int mResId; + + public LazyLoadedBitmap(int resId) { + mResId = resId; + } + + public synchronized Bitmap get() { + if (mBitmap == null) { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inPreferredConfig = Bitmap.Config.ARGB_8888; + mBitmap = BitmapFactory.decodeResource( + mContext.getResources(), mResId, options); + } + return mBitmap; + } + } + + public ThreadPool.Job<Bitmap> requestLabel( + String title, String count, int sourceType, int slotWidth) { + return new AlbumLabelJob(null, title, count, sourceType, slotWidth); + } + + public ThreadPool.Job<Bitmap> requestLabel( + MediaSet album, int sourceType, int slotWidth) { + return new AlbumLabelJob(album, null, null, sourceType, slotWidth); + } + + private static void drawText(Canvas canvas, + int x, int y, String text, int lengthLimit, TextPaint p) { + // The TextPaint cannot be used concurrently + synchronized (p) { + text = TextUtils.ellipsize( + text, p, lengthLimit, TextUtils.TruncateAt.END).toString(); + canvas.drawText(text, x, y - p.getFontMetricsInt().ascent, p); + } + } + + private class AlbumLabelJob implements ThreadPool.Job<Bitmap> { + private final MediaSet mAlbum; + private final String mTitle; + private final String mCount; + private final int mSourceType; + private final int mSlotWidth; + + public AlbumLabelJob(MediaSet album, + String title, String count, int sourceType, int slotWidth) { + mAlbum = album; + mTitle = title; + mCount = count; + mSourceType = sourceType; + mSlotWidth = slotWidth; + } + + @Override + public Bitmap run(JobContext jc) { + MediaSet album = mAlbum; + AlbumSetView.LabelSpec s = mSpec; + + String title = Utils.ensureNotNull( + (album == null) ? mTitle : album.getName()); + String count = album == null + ? Utils.ensureNotNull(mCount) + : String.valueOf(album.getTotalMediaItemCount()); + Bitmap icon = getOverlayAlbumIcon(mSourceType); + Bitmap bitmap = Bitmap.createBitmap(mSlotWidth, + s.labelBackgroundHeight, Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + + // draw title + if (jc.isCancelled()) return null; + int x = s.leftMargin; + int y = s.titleOffset; + drawText(canvas, x, y, title, mSlotWidth - s.leftMargin, mTitlePaint); + + // draw the count + if (jc.isCancelled()) return null; + if (icon != null) x = s.iconSize; + y += s.titleFontSize + s.countOffset; + drawText(canvas, x, y, count, + mSlotWidth - s.leftMargin - s.iconSize, mCountPaint); + + // draw the icon + if (icon != null) { + if (jc.isCancelled()) return null; + float scale = (float) s.iconSize / icon.getWidth(); + canvas.translate(0, bitmap.getHeight() + - Math.round(scale * icon.getHeight())); + canvas.scale(scale, scale); + canvas.drawBitmap(icon, 0, 0, null); + } + + return bitmap; + } + } +} diff --git a/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java b/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java index 1d94c69a1..6eb391198 100644 --- a/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java +++ b/src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java @@ -17,17 +17,15 @@ package com.android.gallery3d.ui; import android.graphics.Bitmap; -import android.graphics.Color; import android.os.Message; -import android.util.FloatMath; import com.android.gallery3d.R; import com.android.gallery3d.app.GalleryActivity; import com.android.gallery3d.common.Utils; import com.android.gallery3d.data.MediaItem; +import com.android.gallery3d.data.MediaObject; import com.android.gallery3d.data.MediaSet; import com.android.gallery3d.data.Path; -import com.android.gallery3d.ui.AlbumSetView.AlbumSetItem; import com.android.gallery3d.util.Future; import com.android.gallery3d.util.FutureListener; import com.android.gallery3d.util.GalleryUtils; @@ -35,9 +33,8 @@ import com.android.gallery3d.util.MediaSetUtils; import com.android.gallery3d.util.ThreadPool; public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener { - private static final String TAG = "GallerySlidingWindow"; - private static final int MSG_LOAD_BITMAP_DONE = 0; - private static final int PLACEHOLDER_COLOR = 0xFF222222; + private static final String TAG = "AlbumSetSlidingWindow"; + private static final int MSG_UPDATE_ALBUM_ENTRY = 1; public static interface Listener { public void onSizeChanged(int size); @@ -46,7 +43,6 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener { private final AlbumSetView.Model mSource; private int mSize; - private final AlbumSetView.LabelSpec mLabelSpec; private int mContentStart = 0; private int mContentEnd = 0; @@ -56,58 +52,63 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener { private Listener mListener; - private final MyAlbumSetItem mData[]; - private SelectionDrawer mSelectionDrawer; - private final ColorTexture mWaitLoadingTexture; - + private final AlbumSetEntry mData[]; private final SynchronizedHandler mHandler; private final ThreadPool mThreadPool; + private final AlbumLabelMaker mLabelMaker; + private final String mLoadingText; private int mActiveRequestCount = 0; - private final String mLoadingLabel; private boolean mIsActive = false; + private BitmapTexture mLoadingLabel; + + private int mSlotWidth; - private static class MyAlbumSetItem extends AlbumSetItem { + public static class AlbumSetEntry { + public MediaSet album; + public MediaItem coverItem; + public Texture content; + public Texture label; public Path setPath; public int sourceType; public int cacheFlag; public int cacheStatus; + public int rotation; + public int mediaType; + public boolean isPanorama; + public boolean isWaitLoadingDisplayed; + public long setDataVersion; + public long coverDataVersion; + private BitmapLoader labelLoader; + private BitmapLoader coverLoader; } public AlbumSetSlidingWindow(GalleryActivity activity, AlbumSetView.LabelSpec labelSpec, SelectionDrawer drawer, AlbumSetView.Model source, int cacheSize) { source.setModelListener(this); - mLabelSpec = labelSpec; - mLoadingLabel = activity.getAndroidContext().getString(R.string.loading); mSource = source; - mSelectionDrawer = drawer; - mData = new MyAlbumSetItem[cacheSize]; + mData = new AlbumSetEntry[cacheSize]; mSize = source.size(); + mThreadPool = activity.getThreadPool(); - mWaitLoadingTexture = new ColorTexture(PLACEHOLDER_COLOR); - mWaitLoadingTexture.setSize(1, 1); + mLabelMaker = new AlbumLabelMaker(activity.getAndroidContext(), labelSpec); + mLoadingText = activity.getAndroidContext().getString(R.string.loading); mHandler = new SynchronizedHandler(activity.getGLRoot()) { @Override public void handleMessage(Message message) { - Utils.assertTrue(message.what == MSG_LOAD_BITMAP_DONE); - ((GalleryDisplayItem) message.obj).onLoadBitmapDone(); + Utils.assertTrue(message.what == MSG_UPDATE_ALBUM_ENTRY); + ((EntryUpdater) message.obj).updateEntry(); } }; - - mThreadPool = activity.getThreadPool(); - } - - public void setSelectionDrawer(SelectionDrawer drawer) { - mSelectionDrawer = drawer; } public void setListener(Listener listener) { mListener = listener; } - public AlbumSetItem get(int slotIndex) { + public AlbumSetEntry get(int slotIndex) { if (!isActiveSlot(slotIndex)) { Utils.fail("invalid slot: %s outsides (%s, %s)", slotIndex, mActiveStart, mActiveEnd); @@ -160,11 +161,9 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener { start, end, mData.length, mSize); } - AlbumSetItem data[] = mData; - + AlbumSetEntry data[] = mData; mActiveStart = start; mActiveEnd = end; - 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); @@ -197,98 +196,79 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener { private void requestImagesInSlot(int slotIndex) { if (slotIndex < mContentStart || slotIndex >= mContentEnd) return; - AlbumSetItem items = mData[slotIndex % mData.length]; - for (DisplayItem item : items.covers) { - ((GalleryDisplayItem) item).requestImage(); - } + AlbumSetEntry entry = mData[slotIndex % mData.length]; + if (entry.coverLoader != null) entry.coverLoader.startLoad(); + if (entry.labelLoader != null) entry.labelLoader.startLoad(); } private void cancelImagesInSlot(int slotIndex) { if (slotIndex < mContentStart || slotIndex >= mContentEnd) return; - AlbumSetItem items = mData[slotIndex % mData.length]; - for (DisplayItem item : items.covers) { - ((GalleryDisplayItem) item).cancelImageRequest(); - } + AlbumSetEntry entry = mData[slotIndex % mData.length]; + if (entry.coverLoader != null) entry.coverLoader.cancelLoad(); + if (entry.labelLoader != null) entry.labelLoader.cancelLoad(); + } + + private static long getDataVersion(MediaObject object) { + return object == null + ? MediaSet.INVALID_DATA_VERSION + : object.getDataVersion(); } private void freeSlotContent(int slotIndex) { - AlbumSetItem data[] = mData; - int index = slotIndex % data.length; - AlbumSetItem original = data[index]; - if (original != null) { - data[index] = null; - for (DisplayItem item : original.covers) { - ((GalleryDisplayItem) item).recycle(); - } - } + AlbumSetEntry entry = mData[slotIndex % mData.length]; + if (entry.coverLoader != null) entry.coverLoader.recycle(); + if (entry.labelLoader != null) entry.labelLoader.recycle(); + mData[slotIndex % mData.length] = null; } - private long getMediaSetDataVersion(MediaSet set) { - return set == null - ? MediaSet.INVALID_DATA_VERSION - : set.getDataVersion(); + private void updateAlbumSetEntry(AlbumSetEntry entry, + int slotIndex, MediaSet album, MediaItem cover) { + entry.album = album; + entry.setDataVersion = getDataVersion(album); + entry.sourceType = identifySourceType(album); + entry.cacheFlag = identifyCacheFlag(album); + entry.cacheStatus = identifyCacheStatus(album); + entry.setPath = (album == null) ? null : album.getPath(); + + if (entry.labelLoader != null) { + entry.labelLoader.recycle(); + entry.labelLoader = null; + entry.label = null; + } + if (album != null) { + entry.labelLoader = new AlbumLabelLoader( + slotIndex, album, entry.sourceType, mSlotWidth); + } + + entry.coverItem = cover; + if (getDataVersion(cover) != entry.coverDataVersion) { + entry.coverDataVersion = getDataVersion(cover); + entry.isPanorama = GalleryUtils.isPanorama(cover); + entry.rotation = (cover == null) ? 0 : cover.getRotation(); + entry.mediaType = (cover == null) ? 0 : cover.getMediaType(); + if (entry.coverLoader != null) { + entry.coverLoader.recycle(); + entry.coverLoader = null; + entry.content = null; + } + if (cover != null) { + entry.coverLoader = new AlbumCoverLoader(slotIndex, cover); + } + } } private void prepareSlotContent(int slotIndex) { MediaSet set = mSource.getMediaSet(slotIndex); - - MyAlbumSetItem item = new MyAlbumSetItem(); - MediaItem[] coverItems = mSource.getCoverItems(slotIndex); - item.covers = new GalleryDisplayItem[coverItems.length]; - item.sourceType = identifySourceType(set); - item.cacheFlag = identifyCacheFlag(set); - item.cacheStatus = identifyCacheStatus(set); - item.setPath = set == null ? null : set.getPath(); - - for (int i = 0; i < coverItems.length; ++i) { - item.covers[i] = new GalleryDisplayItem(slotIndex, i, coverItems[i]); - } - item.labelItem = new LabelDisplayItem(slotIndex); - item.setDataVersion = getMediaSetDataVersion(set); - mData[slotIndex % mData.length] = item; + MediaItem coverItem = mSource.getCoverItem(slotIndex); + AlbumSetEntry entry = new AlbumSetEntry(); + updateAlbumSetEntry(entry, slotIndex, set, coverItem); + mData[slotIndex % mData.length] = entry; } - private boolean isCoverItemsChanged(int slotIndex) { - AlbumSetItem original = mData[slotIndex % mData.length]; - if (original == null) return true; - MediaItem[] coverItems = mSource.getCoverItems(slotIndex); - - if (original.covers.length != coverItems.length) return true; - for (int i = 0, n = coverItems.length; i < n; ++i) { - GalleryDisplayItem g = (GalleryDisplayItem) original.covers[i]; - if (g.mDataVersion != coverItems[i].getDataVersion()) return true; - } - return false; - } - - private void updateSlotContent(final int slotIndex) { - - MyAlbumSetItem data[] = mData; - int pos = slotIndex % data.length; - MyAlbumSetItem original = data[pos]; - - if (!isCoverItemsChanged(slotIndex)) { - MediaSet set = mSource.getMediaSet(slotIndex); - original.sourceType = identifySourceType(set); - original.cacheFlag = identifyCacheFlag(set); - original.cacheStatus = identifyCacheStatus(set); - original.setPath = set == null ? null : set.getPath(); - ((LabelDisplayItem) original.labelItem).updateContent(); - if (mListener != null) mListener.onContentChanged(); - return; - } - - prepareSlotContent(slotIndex); - AlbumSetItem update = data[pos]; - - if (mListener != null && isActiveSlot(slotIndex)) { - mListener.onContentChanged(); - } - if (original != null) { - for (DisplayItem item : original.covers) { - ((GalleryDisplayItem) item).recycle(); - } - } + private static boolean startLoadBitmap(BitmapLoader loader) { + if (loader == null) return false; + loader.startLoad(); + return loader.isRequestInProgress(); } private void notifySlotChanged(int slotIndex) { @@ -299,27 +279,23 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener { slotIndex, mContentStart, mContentEnd) ); return; } - updateSlotContent(slotIndex); - boolean isActiveSlot = isActiveSlot(slotIndex); - if (mActiveRequestCount == 0 || isActiveSlot) { - for (DisplayItem item : mData[slotIndex % mData.length].covers) { - GalleryDisplayItem galleryItem = (GalleryDisplayItem) item; - galleryItem.requestImage(); - if (isActiveSlot && galleryItem.isRequestInProgress()) { - ++mActiveRequestCount; - } - } + + AlbumSetEntry entry = mData[slotIndex % mData.length]; + MediaSet set = mSource.getMediaSet(slotIndex); + MediaItem coverItem = mSource.getCoverItem(slotIndex); + updateAlbumSetEntry(entry, slotIndex, set, coverItem); + updateAllImageRequests(); + if (mListener != null && isActiveSlot(slotIndex)) { + mListener.onContentChanged(); } } private void updateAllImageRequests() { mActiveRequestCount = 0; for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) { - for (DisplayItem item : mData[i % mData.length].covers) { - GalleryDisplayItem coverItem = (GalleryDisplayItem) item; - coverItem.requestImage(); - if (coverItem.isRequestInProgress()) ++mActiveRequestCount; - } + AlbumSetEntry entry = mData[i % mData.length]; + if (startLoadBitmap(entry.coverLoader)) ++mActiveRequestCount; + if (startLoadBitmap(entry.labelLoader)) ++mActiveRequestCount; } if (mActiveRequestCount == 0) { requestNonactiveImages(); @@ -328,123 +304,92 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener { } } - private class GalleryDisplayItem extends AbstractDisplayItem - implements FutureListener<Bitmap> { - private Future<Bitmap> mFuture; - private final int mSlotIndex; - private final int mCoverIndex; - private final int mMediaType; - private Texture mContent; - private final long mDataVersion; - private final boolean mIsPanorama; - private boolean mWaitLoadingDisplayed; - - public GalleryDisplayItem(int slotIndex, int coverIndex, MediaItem item) { - super(item); - mSlotIndex = slotIndex; - mCoverIndex = coverIndex; - mMediaType = item.getMediaType(); - mDataVersion = item.getDataVersion(); - mIsPanorama = GalleryUtils.isPanorama(item); - updateContent(mWaitLoadingTexture); + @Override + public void onSizeChanged(int size) { + if (mIsActive && mSize != size) { + mSize = size; + if (mListener != null) mListener.onSizeChanged(mSize); } + } - @Override - protected void recycleBitmap(Bitmap bitmap) { - BitmapPool.recycle(BitmapPool.TYPE_MICRO_THUMB, bitmap); + @Override + public void onWindowContentChanged(int index) { + if (!mIsActive) { + // paused, ignore slot changed event + return; } + notifySlotChanged(index); + } - @Override - protected void onBitmapAvailable(Bitmap bitmap) { - if (isActiveSlot(mSlotIndex)) { - --mActiveRequestCount; - if (mActiveRequestCount == 0) requestNonactiveImages(); - } - if (bitmap != null) { - BitmapTexture texture = new BitmapTexture(bitmap, true); - texture.setThrottled(true); - if (mWaitLoadingDisplayed) { - updateContent(new FadeInTexture(PLACEHOLDER_COLOR, texture)); - } else { - updateContent(texture); - } - if (mListener != null) mListener.onContentChanged(); - } + public BitmapTexture getLoadingTexture() { + if (mLoadingLabel == null) { + Bitmap bitmap = mLabelMaker.requestLabel(mLoadingText, null, + SelectionDrawer.DATASOURCE_TYPE_NOT_CATEGORIZED, mSlotWidth) + .run(ThreadPool.JOB_CONTEXT_STUB); + mLoadingLabel = new BitmapTexture(bitmap); + mLoadingLabel.setOpaque(false); } + return mLoadingLabel; + } - private void updateContent(Texture content) { - mContent = content; + public void pause() { + mIsActive = false; + for (int i = mContentStart, n = mContentEnd; i < n; ++i) { + freeSlotContent(i); } + } - @Override - public int render(GLCanvas canvas, int pass) { - // Fit the content into the box - int width = mContent.getWidth(); - int height = mContent.getHeight(); - - float scalex = mBoxWidth / (float) width; - float scaley = mBoxHeight / (float) height; - float scale = Math.min(scalex, scaley); - - width = (int) FloatMath.floor(width * scale); - height = (int) FloatMath.floor(height * scale); - - // Now draw it - int sourceType = SelectionDrawer.DATASOURCE_TYPE_NOT_CATEGORIZED; - int cacheFlag = MediaSet.CACHE_FLAG_NO; - int cacheStatus = MediaSet.CACHE_STATUS_NOT_CACHED; - MyAlbumSetItem set = mData[mSlotIndex % mData.length]; - Path path = set.setPath; - if (mCoverIndex == 0) { - sourceType = set.sourceType; - cacheFlag = set.cacheFlag; - cacheStatus = set.cacheStatus; - } + public void resume() { + mIsActive = true; + for (int i = mContentStart, n = mContentEnd; i < n; ++i) { + prepareSlotContent(i); + } + updateAllImageRequests(); + } - mSelectionDrawer.draw(canvas, mContent, width, height, - getRotation(), path, sourceType, mMediaType, - mIsPanorama, mLabelSpec.labelBackgroundHeight, - cacheFlag == MediaSet.CACHE_FLAG_FULL, - (cacheFlag == MediaSet.CACHE_FLAG_FULL) - && (cacheStatus != MediaSet.CACHE_STATUS_CACHED_FULL)); + private static interface EntryUpdater { + public void updateEntry(); + } - if (mContent == mWaitLoadingTexture) { - mWaitLoadingDisplayed = true; - } + private class AlbumCoverLoader extends BitmapLoader implements EntryUpdater { + private MediaItem mMediaItem; + private final int mSlotIndex; - if ((mContent instanceof FadeInTexture) && - ((FadeInTexture) mContent).isAnimating()) { - return SlotView.RENDER_MORE_FRAME; - } else { - return 0; - } + public AlbumCoverLoader(int slotIndex, MediaItem item) { + mSlotIndex = slotIndex; + mMediaItem = item; } @Override - public void startLoadBitmap() { - mFuture = mThreadPool.submit(mMediaItem.requestImage( - MediaItem.TYPE_MICROTHUMBNAIL), this); + protected void recycleBitmap(Bitmap bitmap) { + BitmapPool.recycle(BitmapPool.TYPE_MICRO_THUMB, bitmap); } @Override - public void cancelLoadBitmap() { - mFuture.cancel(); + protected Future<Bitmap> submitBitmapTask(FutureListener<Bitmap> l) { + return mThreadPool.submit(mMediaItem.requestImage( + MediaItem.TYPE_MICROTHUMBNAIL), l); } @Override - public void onFutureDone(Future<Bitmap> future) { - mHandler.sendMessage(mHandler.obtainMessage(MSG_LOAD_BITMAP_DONE, this)); - } - - private void onLoadBitmapDone() { - Future<Bitmap> future = mFuture; - mFuture = null; - updateImage(future.get(), future.isCancelled()); + protected void onLoadComplete(Bitmap bitmap) { + mHandler.obtainMessage(MSG_UPDATE_ALBUM_ENTRY, this).sendToTarget(); } @Override - public String toString() { - return String.format("GalleryDisplayItem(%s, %s)", mSlotIndex, mCoverIndex); + public void updateEntry() { + Bitmap bitmap = getBitmap(); + if (bitmap == null) return; + + AlbumSetEntry entry = mData[mSlotIndex % mData.length]; + BitmapTexture content = new BitmapTexture(bitmap); + entry.content = content; + + if (isActiveSlot(mSlotIndex)) { + --mActiveRequestCount; + if (mActiveRequestCount == 0) requestNonactiveImages(); + if (mListener != null) mListener.onContentChanged(); + } } } @@ -490,103 +435,70 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener { return set.getCacheStatus(); } - private class LabelDisplayItem extends DisplayItem { - private static final int FONT_COLOR_TITLE = Color.WHITE; - private static final int FONT_COLOR_COUNT = 0x80FFFFFF; // 50% white - - private StringTexture mTextureTitle; - private StringTexture mTextureCount; - private String mTitle; - private String mCount; - private int mLastWidth; + private class AlbumLabelLoader extends BitmapLoader implements EntryUpdater { + private final MediaSet mMediaSet; private final int mSlotIndex; - private boolean mHasIcon; + private final int mSourceType; + private final int mLabelWidth; - public LabelDisplayItem(int slotIndex) { + public AlbumLabelLoader(int slotIndex, + MediaSet mediaSet, int sourceType, int labelWidth) { mSlotIndex = slotIndex; + mMediaSet = mediaSet; + mSourceType = sourceType; + mLabelWidth = labelWidth; } - public boolean updateContent() { - String title = mLoadingLabel; - String count = ""; - MediaSet set = mSource.getMediaSet(mSlotIndex); - if (set != null) { - title = Utils.ensureNotNull(set.getName()); - count = "" + set.getTotalMediaItemCount(); - } - if (Utils.equals(title, mTitle) - && Utils.equals(count, mCount) - && Utils.equals(mBoxWidth, mLastWidth)) { - return false; - } - mTitle = title; - mCount = count; - mLastWidth = mBoxWidth; - mHasIcon = (identifySourceType(set) != - SelectionDrawer.DATASOURCE_TYPE_NOT_CATEGORIZED); - - AlbumSetView.LabelSpec s = mLabelSpec; - mTextureTitle = StringTexture.newInstance( - title, s.titleFontSize, FONT_COLOR_TITLE, - mBoxWidth - s.leftMargin, false); - mTextureCount = StringTexture.newInstance( - count, s.countFontSize, FONT_COLOR_COUNT, - mBoxWidth - s.leftMargin, true); - - return true; + @Override + protected Future<Bitmap> submitBitmapTask(FutureListener<Bitmap> l) { + return mThreadPool.submit(mLabelMaker.requestLabel( + mMediaSet, mSourceType, mLabelWidth), l); } @Override - public int render(GLCanvas canvas, int pass) { - if (mBoxWidth != mLastWidth) { - updateContent(); - } - - AlbumSetView.LabelSpec s = mLabelSpec; - int x = -mBoxWidth / 2; - int y = (mBoxHeight + 1) / 2 - s.labelBackgroundHeight; - y += s.titleOffset; - mTextureTitle.draw(canvas, x + s.leftMargin, y); - y += s.titleFontSize + s.countOffset; - x += mHasIcon ? s.iconSize : s.leftMargin; - mTextureCount.draw(canvas, x, y); - return 0; + protected void recycleBitmap(Bitmap bitmap) { } @Override - public int getIdentity() { - return System.identityHashCode(this); + protected void onLoadComplete(Bitmap bitmap) { + mHandler.obtainMessage(MSG_UPDATE_ALBUM_ENTRY, this).sendToTarget(); } - } - @Override - public void onSizeChanged(int size) { - if (mIsActive && mSize != size) { - mSize = size; - if (mListener != null) mListener.onSizeChanged(mSize); - } - } + @Override + public void updateEntry() { + if (isRecycled()) return; - @Override - public void onWindowContentChanged(int index) { - if (!mIsActive) { - // paused, ignore slot changed event - return; - } - notifySlotChanged(index); - } + Bitmap bitmap = getBitmap(); + if (bitmap == null) return; - public void pause() { - mIsActive = false; - for (int i = mContentStart, n = mContentEnd; i < n; ++i) { - freeSlotContent(i); + AlbumSetEntry entry = mData[mSlotIndex % mData.length]; + BitmapTexture content = new BitmapTexture(bitmap); + content.setOpaque(false); + entry.label = content; + + if (isActiveSlot(mSlotIndex)) { + --mActiveRequestCount; + if (mActiveRequestCount == 0) requestNonactiveImages(); + if (mListener != null) mListener.onContentChanged(); + } } } - public void resume() { - mIsActive = true; + public void onSlotSizeChanged(int width, int height) { + if (mSlotWidth == width) return; + mSlotWidth = width; + mLoadingLabel = null; + for (int i = mContentStart, n = mContentEnd; i < n; ++i) { - prepareSlotContent(i); + AlbumSetEntry entry = mData[i % mData.length]; + if (entry.labelLoader != null) { + entry.labelLoader.recycle(); + entry.labelLoader = null; + entry.label = null; + } + entry.labelLoader = (entry.album == null) + ? null + : new AlbumLabelLoader(i, entry.album, entry.sourceType, width); } updateAllImageRequests(); } diff --git a/src/com/android/gallery3d/ui/AlbumSetView.java b/src/com/android/gallery3d/ui/AlbumSetView.java index 7a4b651a6..70ecbb49b 100644 --- a/src/com/android/gallery3d/ui/AlbumSetView.java +++ b/src/com/android/gallery3d/ui/AlbumSetView.java @@ -16,24 +16,33 @@ package com.android.gallery3d.ui; +import android.content.Context; +import android.util.FloatMath; + +import com.android.gallery3d.R; import com.android.gallery3d.app.GalleryActivity; import com.android.gallery3d.data.MediaItem; import com.android.gallery3d.data.MediaSet; +import com.android.gallery3d.ui.AlbumSetSlidingWindow.AlbumSetEntry; +// TODO: rename to AlbumSetRenderer public class AlbumSetView implements SlotView.SlotRenderer { @SuppressWarnings("unused") private static final String TAG = "AlbumSetView"; - private static final int CACHE_SIZE = 32; + private static final int CACHE_SIZE = 64; + private static final int PLACEHOLDER_COLOR = 0xFF222222; + private final ColorTexture mWaitLoadingTexture; private AlbumSetSlidingWindow mDataWindow; private final GalleryActivity mActivity; private final LabelSpec mLabelSpec; private SelectionDrawer mSelectionDrawer; private SlotView mSlotView; + private NinePatchTexture mDarkStrip; public static interface Model { - public MediaItem[] getCoverItems(int index); + public MediaItem getCoverItem(int index); public MediaSet getMediaSet(int index); public int size(); public void setActiveWindow(int start, int end); @@ -45,12 +54,6 @@ public class AlbumSetView implements SlotView.SlotRenderer { public void onSizeChanged(int size); } - public static class AlbumSetItem { - public DisplayItem[] covers; - public DisplayItem labelItem; - public long setDataVersion; - } - public static class LabelSpec { public int labelBackgroundHeight; public int titleOffset; @@ -64,16 +67,21 @@ public class AlbumSetView implements SlotView.SlotRenderer { public AlbumSetView(GalleryActivity activity, SelectionDrawer drawer, SlotView slotView, LabelSpec labelSpec) { mActivity = activity; - setSelectionDrawer(drawer); mLabelSpec = labelSpec; mSlotView = slotView; + + mWaitLoadingTexture = new ColorTexture(PLACEHOLDER_COLOR); + mWaitLoadingTexture.setSize(1, 1); + + Context context = activity.getAndroidContext(); + mDarkStrip = new NinePatchTexture(context, R.drawable.dark_strip); + + setSelectionDrawer(drawer); } public void setSelectionDrawer(SelectionDrawer drawer) { mSelectionDrawer = drawer; - if (mDataWindow != null) { - mDataWindow.setSelectionDrawer(drawer); - } + mSlotView.invalidate(); } public void setModel(AlbumSetView.Model model) { @@ -92,24 +100,66 @@ public class AlbumSetView implements SlotView.SlotRenderer { @Override public int renderSlot(GLCanvas canvas, int index, int pass, int width, int height) { - AlbumSetItem entry = mDataWindow.get(index); - DisplayItem cover = entry.covers.length > 0 ? entry.covers[0] : null; - DisplayItem label = entry.labelItem; + AlbumSetEntry entry = mDataWindow.get(index); + return renderContent(canvas, pass, entry, width, height) + | renderLabel(canvas, pass, entry, width, height); + } + + private int renderContent(GLCanvas canvas, + int pass, AlbumSetEntry entry, int width, int height) { + // Fit the content into the box + Texture content = entry.content; + + if (content == null) { + content = mWaitLoadingTexture; + entry.isWaitLoadingDisplayed = true; + } else if (entry.isWaitLoadingDisplayed) { + entry.isWaitLoadingDisplayed = false; + entry.content = new FadeInTexture( + PLACEHOLDER_COLOR, (BitmapTexture) content); + content = entry.content; + } + + int w = content.getWidth(); + int h = content.getHeight(); + + float scale = Math.min(width / (float) w, height / (float) h); + + w = (int) FloatMath.floor(w * scale); + h = (int) FloatMath.floor(h * scale); - // Put the cover items in reverse order, so that the first item is on - // top of the rest. canvas.translate(width / 2, height / 2); - int r = 0; - if (cover != null) { - cover.setBox(width, height); - r |= cover.render(canvas, pass); + // Now draw it + mSelectionDrawer.draw(canvas, content, width, height, + entry.rotation, entry.setPath, entry.sourceType, entry.mediaType, + entry.isPanorama, mLabelSpec.labelBackgroundHeight, + entry.cacheFlag == MediaSet.CACHE_FLAG_FULL, + (entry.cacheFlag == MediaSet.CACHE_FLAG_FULL) + && (entry.cacheStatus != MediaSet.CACHE_STATUS_CACHED_FULL)); + canvas.translate(-width / 2, -height / 2); + + if ((content instanceof FadeInTexture) && + ((FadeInTexture) content).isAnimating()) { + return SlotView.RENDER_MORE_FRAME; + } + return 0; + } + + private int renderLabel(GLCanvas canvas, + int pass, AlbumSetEntry entry, int width, int height) { + + // We show the loading message only when the album is still loading + // (Not when we are still preparing the label) + Texture content = entry.label; + if (entry.album == null) { + content = mDataWindow.getLoadingTexture(); } - if (label != null) { - label.setBox(width, height); - r |= entry.labelItem.render(canvas, pass); + if (content != null) { + int h = mLabelSpec.labelBackgroundHeight; + SelectionDrawer.drawFrame(canvas, mDarkStrip, 0, height - h, width, h); + content.draw(canvas, 0, height - h, width, h); } - canvas.translate(-width / 2, -height / 2); - return r; + return 0; } @Override @@ -144,4 +194,11 @@ public class AlbumSetView implements SlotView.SlotRenderer { mDataWindow.setActiveWindow(visibleStart, visibleEnd); } } + + @Override + public void onSlotSizeChanged(int width, int height) { + if (mDataWindow != null) { + mDataWindow.onSlotSizeChanged(width, height); + } + } } diff --git a/src/com/android/gallery3d/ui/AlbumSlidingWindow.java b/src/com/android/gallery3d/ui/AlbumSlidingWindow.java index b196e7e4d..c88ca7d97 100644 --- a/src/com/android/gallery3d/ui/AlbumSlidingWindow.java +++ b/src/com/android/gallery3d/ui/AlbumSlidingWindow.java @@ -18,7 +18,6 @@ package com.android.gallery3d.ui; import android.graphics.Bitmap; import android.os.Message; -import android.util.FloatMath; import com.android.gallery3d.app.GalleryActivity; import com.android.gallery3d.common.BitmapUtils; @@ -29,23 +28,30 @@ import com.android.gallery3d.util.Future; import com.android.gallery3d.util.FutureListener; import com.android.gallery3d.util.GalleryUtils; import com.android.gallery3d.util.JobLimiter; -import com.android.gallery3d.util.ThreadPool.Job; -import com.android.gallery3d.util.ThreadPool.JobContext; public class AlbumSlidingWindow implements AlbumView.ModelListener { @SuppressWarnings("unused") private static final String TAG = "AlbumSlidingWindow"; - private static final int MSG_LOAD_BITMAP_DONE = 0; - private static final int MSG_UPDATE_SLOT = 1; + private static final int MSG_UPDATE_ENTRY = 0; private static final int JOB_LIMIT = 2; - private static final int PLACEHOLDER_COLOR = 0xFF222222; public static interface Listener { public void onSizeChanged(int size); public void onContentChanged(); } + public static class AlbumEntry { + public MediaItem item; + public Path path; + public boolean isPanorama; + public int rotation; + public int mediaType; + public boolean isWaitDisplayed; + public Texture content; + private BitmapLoader contentLoader; + } + private final AlbumView.Model mSource; private int mSize; @@ -56,11 +62,8 @@ public class AlbumSlidingWindow implements AlbumView.ModelListener { private int mActiveEnd = 0; private Listener mListener; - private int mFocusIndex = -1; - private final AlbumDisplayItem mData[]; - private final ColorTexture mWaitLoadingTexture; - private SelectionDrawer mSelectionDrawer; + private final AlbumEntry mData[]; private SynchronizedHandler mHandler; private JobLimiter mThreadPool; @@ -72,44 +75,25 @@ public class AlbumSlidingWindow implements AlbumView.ModelListener { AlbumView.Model source, int cacheSize) { source.setModelListener(this); mSource = source; - mData = new AlbumDisplayItem[cacheSize]; + mData = new AlbumEntry[cacheSize]; mSize = source.size(); - mWaitLoadingTexture = new ColorTexture(PLACEHOLDER_COLOR); - mWaitLoadingTexture.setSize(1, 1); - mHandler = new SynchronizedHandler(activity.getGLRoot()) { @Override public void handleMessage(Message message) { - switch (message.what) { - case MSG_LOAD_BITMAP_DONE: { - ((AlbumDisplayItem) message.obj).onLoadBitmapDone(); - break; - } - case MSG_UPDATE_SLOT: { - updateSlotContent(message.arg1); - break; - } - } + Utils.assertTrue(message.what == MSG_UPDATE_ENTRY); + ((ThumbnailLoader) message.obj).updateEntry(); } }; mThreadPool = new JobLimiter(activity.getThreadPool(), JOB_LIMIT); } - public void setSelectionDrawer(SelectionDrawer drawer) { - mSelectionDrawer = drawer; - } - public void setListener(Listener listener) { mListener = listener; } - public void setFocusIndex(int slotIndex) { - mFocusIndex = slotIndex; - } - - public DisplayItem get(int slotIndex) { + public AlbumEntry get(int slotIndex) { if (!isActiveSlot(slotIndex)) { Utils.fail("invalid slot: %s outsides (%s, %s)", slotIndex, mActiveStart, mActiveEnd); @@ -163,7 +147,7 @@ public class AlbumSlidingWindow implements AlbumView.ModelListener { if (!(start <= end && end - start <= mData.length && end <= mSize)) { Utils.fail("%s, %s, %s, %s", start, end, mData.length, mSize); } - DisplayItem data[] = mData; + AlbumEntry data[] = mData; mActiveStart = start; mActiveEnd = end; @@ -184,80 +168,73 @@ public class AlbumSlidingWindow implements AlbumView.ModelListener { int range = Math.max( (mContentEnd - mActiveEnd), (mActiveStart - mContentStart)); for (int i = 0 ;i < range; ++i) { - requestSlotImage(mActiveEnd + i, false); - requestSlotImage(mActiveStart - 1 - i, false); + requestSlotImage(mActiveEnd + i); + requestSlotImage(mActiveStart - 1 - i); } } - private void requestSlotImage(int slotIndex, boolean isActive) { - if (slotIndex < mContentStart || slotIndex >= mContentEnd) return; - AlbumDisplayItem item = mData[slotIndex % mData.length]; - item.requestImage(); + // return whether the request is in progress or not + private boolean requestSlotImage(int slotIndex) { + if (slotIndex < mContentStart || slotIndex >= mContentEnd) return false; + AlbumEntry entry = mData[slotIndex % mData.length]; + if (entry.content != null || entry.item == null) return false; + + entry.contentLoader.startLoad(); + return entry.contentLoader.isRequestInProgress(); } private void cancelNonactiveImages() { int range = Math.max( (mContentEnd - mActiveEnd), (mActiveStart - mContentStart)); for (int i = 0 ;i < range; ++i) { - cancelSlotImage(mActiveEnd + i, false); - cancelSlotImage(mActiveStart - 1 - i, false); + cancelSlotImage(mActiveEnd + i); + cancelSlotImage(mActiveStart - 1 - i); } } - private void cancelSlotImage(int slotIndex, boolean isActive) { + private void cancelSlotImage(int slotIndex) { if (slotIndex < mContentStart || slotIndex >= mContentEnd) return; - AlbumDisplayItem item = mData[slotIndex % mData.length]; - item.cancelImageRequest(); + AlbumEntry item = mData[slotIndex % mData.length]; + if (item.contentLoader != null) item.contentLoader.cancelLoad(); } private void freeSlotContent(int slotIndex) { - AlbumDisplayItem data[] = mData; + AlbumEntry data[] = mData; int index = slotIndex % data.length; - AlbumDisplayItem original = data[index]; - if (original != null) { - original.recycle(); - data[index] = null; + AlbumEntry entry = data[index]; + if (entry.contentLoader != null) { + entry.contentLoader.recycle(); } + data[index] = null; } - private void prepareSlotContent(final int slotIndex) { - mData[slotIndex % mData.length] = new AlbumDisplayItem( - slotIndex, mSource.get(slotIndex)); + private void prepareSlotContent(int slotIndex) { + AlbumEntry entry = new AlbumEntry(); + MediaItem item = mSource.get(slotIndex); // item could be null; + entry.item = item; + entry.isPanorama = GalleryUtils.isPanorama(entry.item); + 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); + mData[slotIndex % mData.length] = entry; } - private void updateSlotContent(final int slotIndex) { - MediaItem item = mSource.get(slotIndex); - AlbumDisplayItem data[] = mData; - int index = slotIndex % data.length; - AlbumDisplayItem original = data[index]; - AlbumDisplayItem update = new AlbumDisplayItem(slotIndex, item); - data[index] = update; - boolean isActive = isActiveSlot(slotIndex); - if (mListener != null && isActive) { + private void updateSlotContent(int slotIndex) { + freeSlotContent(slotIndex); + prepareSlotContent(slotIndex); + updateAllImageRequests(); + if (mListener != null && isActiveSlot(slotIndex)) { mListener.onContentChanged(); } - if (original != null) { - if (isActive && original.isRequestInProgress()) { - --mActiveRequestCount; - } - original.recycle(); - } - if (isActive) { - if (mActiveRequestCount == 0) cancelNonactiveImages(); - ++mActiveRequestCount; - update.requestImage(); - } else { - if (mActiveRequestCount == 0) update.requestImage(); - } } private void updateAllImageRequests() { mActiveRequestCount = 0; - AlbumDisplayItem data[] = mData; for (int i = mActiveStart, n = mActiveEnd; i < n; ++i) { - AlbumDisplayItem item = data[i % data.length]; - item.requestImage(); - if (item.isRequestInProgress()) ++mActiveRequestCount; + if (requestSlotImage(i)) ++mActiveRequestCount; } if (mActiveRequestCount == 0) { requestNonactiveImages(); @@ -266,23 +243,13 @@ public class AlbumSlidingWindow implements AlbumView.ModelListener { } } - private class AlbumDisplayItem extends AbstractDisplayItem - implements FutureListener<Bitmap> { - private Future<Bitmap> mFuture; - private final int mSlotIndex; - private final int mMediaType; - private Texture mContent; - private boolean mIsPanorama; - private boolean mWaitLoadingDisplayed; - - public AlbumDisplayItem(int slotIndex, MediaItem item) { - super(item); - mMediaType = (item == null) - ? MediaItem.MEDIA_TYPE_UNKNOWN - : item.getMediaType(); + private class ThumbnailLoader extends BitmapLoader { + final int mSlotIndex; + final MediaItem mItem; + + public ThumbnailLoader(int slotIndex, MediaItem item) { mSlotIndex = slotIndex; - mIsPanorama = GalleryUtils.isPanorama(item); - updateContent(mWaitLoadingTexture); + mItem = item; } @Override @@ -291,99 +258,32 @@ public class AlbumSlidingWindow implements AlbumView.ModelListener { } @Override - protected void onBitmapAvailable(Bitmap bitmap) { - boolean isActiveSlot = isActiveSlot(mSlotIndex); - if (isActiveSlot) { - --mActiveRequestCount; - if (mActiveRequestCount == 0) requestNonactiveImages(); - } - if (bitmap != null) { - BitmapTexture texture = new BitmapTexture(bitmap, true); - texture.setThrottled(true); - if (mWaitLoadingDisplayed) { - updateContent(new FadeInTexture(PLACEHOLDER_COLOR, texture)); - } else { - updateContent(texture); - } - if (mListener != null && isActiveSlot) { - mListener.onContentChanged(); - } - } - } - - private void updateContent(Texture content) { - mContent = content; - } - - @Override - public int render(GLCanvas canvas, int pass) { - // Fit the content into the box - int width = mContent.getWidth(); - int height = mContent.getHeight(); - - float scalex = mBoxWidth / (float) width; - float scaley = mBoxHeight / (float) height; - float scale = Math.min(scalex, scaley); - - width = (int) FloatMath.floor(width * scale); - height = (int) FloatMath.floor(height * scale); - - // Now draw it - if (pass == 0) { - Path path = null; - if (mMediaItem != null) path = mMediaItem.getPath(); - mSelectionDrawer.draw(canvas, mContent, width, height, - getRotation(), path, mMediaType, mIsPanorama); - if (mContent == mWaitLoadingTexture) { - mWaitLoadingDisplayed = true; - } - int result = 0; - if (mFocusIndex == mSlotIndex) { - result |= SlotView.RENDER_MORE_PASS; - } - if ((mContent instanceof FadeInTexture) && - ((FadeInTexture) mContent).isAnimating()) { - result |= SlotView.RENDER_MORE_FRAME; - } - return result; - } else if (pass == 1) { - mSelectionDrawer.drawFocus(canvas, width, height); - } - return 0; + protected Future<Bitmap> submitBitmapTask(FutureListener<Bitmap> l) { + return mThreadPool.submit( + mItem.requestImage(MediaItem.TYPE_MICROTHUMBNAIL), this); } @Override - public void startLoadBitmap() { - mFuture = mThreadPool.submit(mMediaItem.requestImage( - MediaItem.TYPE_MICROTHUMBNAIL), this); + protected void onLoadComplete(Bitmap bitmap) { + mHandler.obtainMessage(MSG_UPDATE_ENTRY, this).sendToTarget(); } - @Override - public void cancelLoadBitmap() { - if (mFuture != null) { - mFuture.cancel(); - } - } + public void updateEntry() { + if (isRecycled()) return; - @Override - public void onFutureDone(Future<Bitmap> bitmap) { - mHandler.sendMessage(mHandler.obtainMessage(MSG_LOAD_BITMAP_DONE, this)); - } - - private void onLoadBitmapDone() { - Future<Bitmap> future = mFuture; - mFuture = null; - Bitmap bitmap = future.get(); - boolean isCancelled = future.isCancelled(); - updateImage(bitmap, isCancelled); - } + AlbumEntry entry = mData[mSlotIndex % mData.length]; + Bitmap bitmap = entry.contentLoader.getBitmap(); + if (bitmap != null) entry.content = new BitmapTexture(bitmap); - @Override - public String toString() { - return String.format("AlbumDisplayItem[%s]", mSlotIndex); + if (isActiveSlot(mSlotIndex)) { + --mActiveRequestCount; + if (mActiveRequestCount == 0) requestNonactiveImages(); + if (mListener != null) mListener.onContentChanged(); + } } } + @Override public void onSizeChanged(int size) { if (mSize != size) { mSize = size; @@ -391,6 +291,7 @@ public class AlbumSlidingWindow implements AlbumView.ModelListener { } } + @Override public void onWindowContentChanged(int index) { if (index >= mContentStart && index < mContentEnd && mIsActive) { updateSlotContent(index); diff --git a/src/com/android/gallery3d/ui/AlbumView.java b/src/com/android/gallery3d/ui/AlbumView.java index 1e7b247c6..827d57dec 100644 --- a/src/com/android/gallery3d/ui/AlbumView.java +++ b/src/com/android/gallery3d/ui/AlbumView.java @@ -16,20 +16,26 @@ package com.android.gallery3d.ui; +import android.util.FloatMath; + import com.android.gallery3d.app.GalleryActivity; import com.android.gallery3d.data.MediaItem; public class AlbumView implements SlotView.SlotRenderer { + private static final int PLACEHOLDER_COLOR = 0xFF222222; + @SuppressWarnings("unused") private static final String TAG = "AlbumView"; private static final int CACHE_SIZE = 64; private AlbumSlidingWindow mDataWindow; private final GalleryActivity mActivity; - private SelectionDrawer mSelectionDrawer; - + private final ColorTexture mWaitLoadingTexture; private final SlotView mSlotView; + private SelectionDrawer mSelectionDrawer; + private int mFocusIndex = -1; + public static interface Model { public int size(); public MediaItem get(int index); @@ -45,11 +51,13 @@ public class AlbumView implements SlotView.SlotRenderer { public AlbumView(GalleryActivity activity, SlotView slotView) { mSlotView = slotView; mActivity = activity; + + mWaitLoadingTexture = new ColorTexture(PLACEHOLDER_COLOR); + mWaitLoadingTexture.setSize(1, 1); } public void setSelectionDrawer(SelectionDrawer drawer) { mSelectionDrawer = drawer; - if (mDataWindow != null) mDataWindow.setSelectionDrawer(drawer); } public void setModel(Model model) { @@ -59,29 +67,61 @@ public class AlbumView implements SlotView.SlotRenderer { mDataWindow = null; } if (model != null) { - mDataWindow = new AlbumSlidingWindow( - mActivity, model, CACHE_SIZE); - mDataWindow.setSelectionDrawer(mSelectionDrawer); + mDataWindow = new AlbumSlidingWindow(mActivity, model, CACHE_SIZE); mDataWindow.setListener(new MyDataModelListener()); mSlotView.setSlotCount(model.size()); } } public void setFocusIndex(int slotIndex) { - if (mDataWindow != null) { - mDataWindow.setFocusIndex(slotIndex); - } + if (mFocusIndex == slotIndex) return; + mFocusIndex = slotIndex; + mSlotView.invalidate(); } @Override public int renderSlot(GLCanvas canvas, int index, int pass, int width, int height) { - DisplayItem item = mDataWindow.get(index); - if (item != null) { + AlbumSlidingWindow.AlbumEntry entry = mDataWindow.get(index); + Texture content = entry.content; + + if (content == null) { + content = mWaitLoadingTexture; + entry.isWaitDisplayed = true; + } else if (entry.isWaitDisplayed) { + entry.isWaitDisplayed = false; + entry.content = new FadeInTexture( + PLACEHOLDER_COLOR, (BitmapTexture) entry.content); + content = entry.content; + } + + // Fit the content into the box + int w = content.getWidth(); + int h = content.getHeight(); + + float scale = Math.min((float) width / w, (float) height / h); + + w = (int) FloatMath.floor(w * scale); + h = (int) FloatMath.floor(h * scale); + + // Now draw it + if (pass == 0) { canvas.translate(width / 2, height / 2); - item.setBox(width, height); - int r = item.render(canvas, pass); + mSelectionDrawer.draw(canvas, content, w, h, + entry.rotation, entry.path, entry.mediaType, entry.isPanorama); + canvas.translate(-width / 2, -height / 2); + int result = 0; + if (mFocusIndex == index) { + result |= SlotView.RENDER_MORE_PASS; + } + if ((content instanceof FadeInTexture) && + ((FadeInTexture) content).isAnimating()) { + result |= SlotView.RENDER_MORE_FRAME; + } + return result; + } else if (pass == 1) { + canvas.translate(width / 2, height / 2); + mSelectionDrawer.drawFocus(canvas, width, height); canvas.translate(-width / 2, -height / 2); - return r; } return 0; } @@ -117,4 +157,9 @@ public class AlbumView implements SlotView.SlotRenderer { mDataWindow.setActiveWindow(visibleStart, visibleEnd); } } + + @Override + public void onSlotSizeChanged(int width, int height) { + // Do nothing + } } diff --git a/src/com/android/gallery3d/ui/BitmapLoader.java b/src/com/android/gallery3d/ui/BitmapLoader.java new file mode 100644 index 000000000..4f07cc047 --- /dev/null +++ b/src/com/android/gallery3d/ui/BitmapLoader.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import android.graphics.Bitmap; + +import com.android.gallery3d.util.Future; +import com.android.gallery3d.util.FutureListener; + +// We use this class to +// 1.) load bitmaps in background. +// 2.) as a place holder for the loaded bitmap +public abstract class BitmapLoader implements FutureListener<Bitmap> { + @SuppressWarnings("unused") + private static final String TAG = "BitmapLoader"; + + /* Transition Map: + * INIT -> REQUESTED, RECYCLED + * REQUESTED -> INIT (cancel), LOADED, ERROR, RECYCLED + * LOADED, ERROR -> RECYCLED + */ + private static final int STATE_INIT = 0; + private static final int STATE_REQUESTED = 1; + private static final int STATE_LOADED = 2; + private static final int STATE_ERROR = 3; + private static final int STATE_RECYCLED = 4; + + private int mState = STATE_INIT; + // mTask is not null only when a task is on the way + private Future<Bitmap> mTask; + private Bitmap mBitmap; + + @Override + public void onFutureDone(Future<Bitmap> future) { + synchronized (this) { + mTask = null; + mBitmap = future.get(); + if (mState == STATE_RECYCLED) { + if (mBitmap != null) { + recycleBitmap(mBitmap); + mBitmap = null; + } + return; // don't call callback + } + if (future.isCancelled() && mBitmap == null) { + if (mState == STATE_REQUESTED) mTask = submitBitmapTask(this); + return; // don't call callback + } else { + mState = mBitmap == null ? STATE_ERROR : STATE_LOADED; + } + } + onLoadComplete(mBitmap); + } + + public synchronized void startLoad() { + if (mState == STATE_INIT) { + mState = STATE_REQUESTED; + if (mTask == null) mTask = submitBitmapTask(this); + } + } + + public synchronized void cancelLoad() { + if (mState == STATE_REQUESTED) { + mState = STATE_INIT; + if (mTask != null) mTask.cancel(); + } + } + + // Recycle the loader and the bitmap + public synchronized void recycle() { + mState = STATE_RECYCLED; + if (mBitmap != null) { + recycleBitmap(mBitmap); + mBitmap = null; + } + if (mTask != null) mTask.cancel(); + } + + public synchronized boolean isRequestInProgress() { + return mState == STATE_REQUESTED; + } + + public synchronized boolean isRecycled() { + return mState == STATE_RECYCLED; + } + + public synchronized Bitmap getBitmap() { + return mBitmap; + } + + abstract protected Future<Bitmap> submitBitmapTask(FutureListener<Bitmap> l); + abstract protected void recycleBitmap(Bitmap bitmap); + abstract protected void onLoadComplete(Bitmap bitmap); +} diff --git a/src/com/android/gallery3d/ui/DisplayItem.java b/src/com/android/gallery3d/ui/DisplayItem.java deleted file mode 100644 index b389daebc..000000000 --- a/src/com/android/gallery3d/ui/DisplayItem.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.ui; - -public abstract class DisplayItem { - - protected int mBoxWidth; - protected int mBoxHeight; - - // setBox() specifies the box that the DisplayItem should render into. It - // should be called before first render(). It may be called again between - // render() calls to change the size of the box. - public void setBox(int width, int height) { - mBoxWidth = width; - mBoxHeight = height; - } - - public abstract int render(GLCanvas canvas, int pass); - - public abstract int getIdentity(); - - public int getRotation() { - return 0; - } -} diff --git a/src/com/android/gallery3d/ui/GridDrawer.java b/src/com/android/gallery3d/ui/GridDrawer.java index bf15eff00..c5e921e8c 100644 --- a/src/com/android/gallery3d/ui/GridDrawer.java +++ b/src/com/android/gallery3d/ui/GridDrawer.java @@ -64,8 +64,7 @@ public class GridDrawer extends IconDrawer { } drawMediaTypeOverlay(canvas, mediaType, isPanorama, x, y, width, height); - drawLabelBackground(canvas, width, height, labelBackgroundHeight); - drawIcon(canvas, width, height, dataSourceType); + if (dataSourceType == DATASOURCE_TYPE_MTP) { drawImportLabel(canvas, width, height); } diff --git a/src/com/android/gallery3d/ui/HighlightDrawer.java b/src/com/android/gallery3d/ui/HighlightDrawer.java index 6e73b0fda..65afd1814 100644 --- a/src/com/android/gallery3d/ui/HighlightDrawer.java +++ b/src/com/android/gallery3d/ui/HighlightDrawer.java @@ -51,8 +51,6 @@ public class HighlightDrawer extends IconDrawer { } drawMediaTypeOverlay(canvas, mediaType, isPanorama, x, y, width, height); - drawLabelBackground(canvas, width, height, labelBackgroundHeight); - drawIcon(canvas, width, height, dataSourceType); if (mSelectionManager.isPressedPath(path)) { drawPressedFrame(canvas, x, y, width, height); diff --git a/src/com/android/gallery3d/ui/IconDrawer.java b/src/com/android/gallery3d/ui/IconDrawer.java index 95a11731a..dffcbfdd1 100644 --- a/src/com/android/gallery3d/ui/IconDrawer.java +++ b/src/com/android/gallery3d/ui/IconDrawer.java @@ -22,19 +22,13 @@ import com.android.gallery3d.data.MediaObject; public abstract class IconDrawer extends SelectionDrawer { private static final String TAG = "IconDrawer"; - private static final int LABEL_BACKGROUND_COLOR = 0x99000000; // 60% black - private final ResourceTexture mLocalSetIcon; - private final ResourceTexture mCameraIcon; - private final ResourceTexture mPicasaIcon; - private final ResourceTexture mMtpIcon; private final NinePatchTexture mFramePressed; private final NinePatchTexture mFrameSelected; private final NinePatchTexture mDarkStrip; private final NinePatchTexture mPanoramaBorder; private final Texture mVideoOverlay; private final Texture mVideoPlayIcon; - private final int mIconSize; public static class IconDimension { int x; @@ -44,69 +38,18 @@ public abstract class IconDrawer extends SelectionDrawer { } public IconDrawer(Context context) { - mLocalSetIcon = new ResourceTexture(context, R.drawable.frame_overlay_gallery_folder); - mCameraIcon = new ResourceTexture(context, R.drawable.frame_overlay_gallery_camera); - mPicasaIcon = new ResourceTexture(context, R.drawable.frame_overlay_gallery_picasa); - mMtpIcon = new ResourceTexture(context, R.drawable.frame_overlay_gallery_ptp); mVideoOverlay = new ResourceTexture(context, R.drawable.ic_video_thumb); mVideoPlayIcon = new ResourceTexture(context, R.drawable.ic_gallery_play); mPanoramaBorder = new NinePatchTexture(context, R.drawable.ic_pan_thumb); mFramePressed = new NinePatchTexture(context, R.drawable.grid_pressed); mFrameSelected = new NinePatchTexture(context, R.drawable.grid_selected); mDarkStrip = new NinePatchTexture(context, R.drawable.dark_strip); - mIconSize = context.getResources().getDimensionPixelSize( - R.dimen.albumset_icon_size); } @Override public void prepareDrawing() { } - protected IconDimension drawIcon(GLCanvas canvas, int width, int height, - int dataSourceType) { - ResourceTexture icon = getIcon(dataSourceType); - - if (icon != null) { - IconDimension id = getIconDimension(icon, width, height); - icon.draw(canvas, id.x, id.y, id.width, id.height); - return id; - } - return null; - } - - protected ResourceTexture getIcon(int dataSourceType) { - ResourceTexture icon = null; - switch (dataSourceType) { - case DATASOURCE_TYPE_LOCAL: - icon = mLocalSetIcon; - break; - case DATASOURCE_TYPE_PICASA: - icon = mPicasaIcon; - break; - case DATASOURCE_TYPE_CAMERA: - icon = mCameraIcon; - break; - case DATASOURCE_TYPE_MTP: - icon = mMtpIcon; - break; - default: - break; - } - - return icon; - } - - protected IconDimension getIconDimension(ResourceTexture icon, int width, - int height) { - IconDimension id = new IconDimension(); - float scale = (float) mIconSize / icon.getWidth(); - id.width = Math.round(scale * icon.getWidth()); - id.height = Math.round(scale * icon.getHeight()); - id.x = -width / 2; - id.y = (height + 1) / 2 - id.height; - return id; - } - protected void drawMediaTypeOverlay(GLCanvas canvas, int mediaType, boolean isPanorama, int x, int y, int width, int height) { if (mediaType == MediaObject.MEDIA_TYPE_VIDEO) { diff --git a/src/com/android/gallery3d/ui/ManageCacheDrawer.java b/src/com/android/gallery3d/ui/ManageCacheDrawer.java index 7734fb331..208c527da 100644 --- a/src/com/android/gallery3d/ui/ManageCacheDrawer.java +++ b/src/com/android/gallery3d/ui/ManageCacheDrawer.java @@ -86,8 +86,6 @@ public class ManageCacheDrawer extends IconDrawer { } drawMediaTypeOverlay(canvas, mediaType, isPanorama, x, y, width, height); - drawLabelBackground(canvas, width, height, labelBackgroundHeight); - drawIcon(canvas, width, height, dataSourceType); drawCachingPin(canvas, path, dataSourceType, isCaching, chooseToCache, width, height); diff --git a/src/com/android/gallery3d/ui/SlotView.java b/src/com/android/gallery3d/ui/SlotView.java index e12bb080e..aef97a436 100644 --- a/src/com/android/gallery3d/ui/SlotView.java +++ b/src/com/android/gallery3d/ui/SlotView.java @@ -55,6 +55,7 @@ public class SlotView extends GLView { public static interface SlotRenderer { public void prepareDrawing(); public void onVisibleRangeChanged(int visibleStart, int visibleEnd); + public void onSlotSizeChanged(int width, int height); public int renderSlot(GLCanvas canvas, int index, int pass, int width, int height); } @@ -94,6 +95,7 @@ public class SlotView extends GLView { public void setSlotRenderer(SlotRenderer slotDrawer) { mRenderer = slotDrawer; if (mRenderer != null) { + mRenderer.onSlotSizeChanged(mLayout.mSlotWidth, mLayout.mSlotHeight); mRenderer.onVisibleRangeChanged(getVisibleStart(), getVisibleEnd()); } } @@ -512,6 +514,10 @@ public class SlotView extends GLView { mSlotWidth = mSlotHeight; } + if (mRenderer != null) { + mRenderer.onSlotSizeChanged(mSlotWidth, mSlotHeight); + } + int[] padding = new int[2]; if (WIDE) { initLayoutParameters(mWidth, mHeight, mSlotWidth, mSlotHeight, padding); |
