summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOwen Lin <owenlin@google.com>2012-03-26 18:28:48 +0800
committerOwen Lin <owenlin@google.com>2012-04-05 14:46:06 +0800
commit1a4bd273afe5dd11592f7625c2f19853b6f174e9 (patch)
tree20c2c3a4ca0a0699f7978adc365df4f11055cf1f /src
parent33ef03776b7734717b16f6fc861b831fb1b1dfac (diff)
downloadandroid_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.java32
-rw-r--r--src/com/android/gallery3d/ui/AbstractDisplayItem.java118
-rw-r--r--src/com/android/gallery3d/ui/AlbumLabelMaker.java169
-rw-r--r--src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java502
-rw-r--r--src/com/android/gallery3d/ui/AlbumSetView.java109
-rw-r--r--src/com/android/gallery3d/ui/AlbumSlidingWindow.java257
-rw-r--r--src/com/android/gallery3d/ui/AlbumView.java73
-rw-r--r--src/com/android/gallery3d/ui/BitmapLoader.java108
-rw-r--r--src/com/android/gallery3d/ui/DisplayItem.java39
-rw-r--r--src/com/android/gallery3d/ui/GridDrawer.java3
-rw-r--r--src/com/android/gallery3d/ui/HighlightDrawer.java2
-rw-r--r--src/com/android/gallery3d/ui/IconDrawer.java57
-rw-r--r--src/com/android/gallery3d/ui/ManageCacheDrawer.java2
-rw-r--r--src/com/android/gallery3d/ui/SlotView.java6
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);