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