summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChih-Chung Chang <chihchung@google.com>2012-03-15 16:38:45 +0800
committerChih-Chung Chang <chihchung@google.com>2012-03-21 15:29:29 +0800
commit15b351a22d02e89d882fc9fe32b3f4c512080e0a (patch)
tree07a316c7f973bdb0173fc50b25837c50c65f6714 /src
parent8cab3e872dd95e55ba34fdb94269a0c5069e72ae (diff)
downloadandroid_packages_apps_Gallery2-15b351a22d02e89d882fc9fe32b3f4c512080e0a.tar.gz
android_packages_apps_Gallery2-15b351a22d02e89d882fc9fe32b3f4c512080e0a.tar.bz2
android_packages_apps_Gallery2-15b351a22d02e89d882fc9fe32b3f4c512080e0a.zip
Create a ScreenNail interface so we can add other types of screenails.
Add a new MediaItem type to contain a ScreenNail. Change-Id: Ia303949f3013dd48ded204eaf9ec69a102b8503e
Diffstat (limited to 'src')
-rw-r--r--src/com/android/gallery3d/app/CameraView.java117
-rw-r--r--src/com/android/gallery3d/app/PhotoDataAdapter.java57
-rw-r--r--src/com/android/gallery3d/app/PhotoPage.java53
-rw-r--r--src/com/android/gallery3d/app/ScreenNailBridge.java122
-rw-r--r--src/com/android/gallery3d/app/SinglePhotoDataAdapter.java10
-rw-r--r--src/com/android/gallery3d/data/DataManager.java1
-rw-r--r--src/com/android/gallery3d/data/MediaItem.java7
-rw-r--r--src/com/android/gallery3d/data/SnailAlbum.java62
-rw-r--r--src/com/android/gallery3d/data/SnailItem.java80
-rw-r--r--src/com/android/gallery3d/data/SnailSource.java74
-rw-r--r--src/com/android/gallery3d/ui/BitmapScreenNail.java84
-rw-r--r--src/com/android/gallery3d/ui/BitmapTileProvider.java12
-rw-r--r--src/com/android/gallery3d/ui/PhotoView.java120
-rw-r--r--src/com/android/gallery3d/ui/ScreenNail.java32
-rw-r--r--src/com/android/gallery3d/ui/TileImageView.java49
-rw-r--r--src/com/android/gallery3d/ui/TileImageViewAdapter.java28
16 files changed, 765 insertions, 143 deletions
diff --git a/src/com/android/gallery3d/app/CameraView.java b/src/com/android/gallery3d/app/CameraView.java
new file mode 100644
index 000000000..a6c233291
--- /dev/null
+++ b/src/com/android/gallery3d/app/CameraView.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2012 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.app;
+
+import android.content.Context;
+import android.graphics.SurfaceTexture;
+import android.hardware.Camera;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.TextureView;
+import android.view.View;
+
+import java.io.IOException;
+
+// This is a sample View which demos the usage of ScreenNailBridge. It
+// is not intended for production use.
+public class CameraView extends TextureView implements
+ TextureView.SurfaceTextureListener, ScreenNailBridge.Listener {
+ private static final String TAG = "CameraView";
+ private static final int PREVIEW_WIDTH = 960;
+ private static final int PREVIEW_HEIGHT = 720;
+ private Camera mCamera;
+ private ScreenNailBridge mScreenNailBridge;
+
+ public CameraView(Context context) {
+ super(context);
+ init();
+ }
+
+ public CameraView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ private void init() {
+ setVisibility(View.INVISIBLE);
+ setSurfaceTextureListener(this);
+ }
+
+ public void setScreenNailBridge(ScreenNailBridge s) {
+ mScreenNailBridge = s;
+ }
+
+ @Override
+ public void onMeasure(int widthSpec, int heightSpec) {
+ int width = getDefaultSize(PREVIEW_WIDTH, widthSpec);
+ int height = getDefaultSize(PREVIEW_HEIGHT, heightSpec);
+ // Keep aspect ratio
+ if (width * PREVIEW_HEIGHT > PREVIEW_WIDTH * height) {
+ width = PREVIEW_WIDTH * height / PREVIEW_HEIGHT;
+ } else {
+ height = PREVIEW_HEIGHT * width / PREVIEW_WIDTH;
+ }
+ setMeasuredDimension(width, height);
+ }
+
+ @Override
+ public void onSizeChanged(int w, int h, int oldw, int oldh) {
+ mScreenNailBridge.setSize(w, h);
+ }
+
+ @Override
+ public void updateView(boolean visible, int x, int y, int w, int h) {
+ if (!visible) {
+ setVisibility(View.INVISIBLE);
+ } else {
+ setVisibility(View.VISIBLE);
+ setTranslationX(x);
+ setTranslationY(y);
+ }
+ }
+
+ @Override
+ public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
+ try {
+ mCamera = Camera.open();
+
+ Camera.Parameters param = mCamera.getParameters();
+ param.setPreviewSize(PREVIEW_WIDTH, PREVIEW_HEIGHT);
+ mCamera.setParameters(param);
+
+ mCamera.setPreviewTexture(surface);
+ mCamera.startPreview();
+ } catch (Throwable ex) {
+ Log.e(TAG, "failed to open camera", ex);
+ }
+ }
+
+ @Override
+ public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+ mCamera.stopPreview();
+ mCamera.release();
+ return true;
+ }
+
+ @Override
+ public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
+ }
+
+ @Override
+ public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+ }
+}
diff --git a/src/com/android/gallery3d/app/PhotoDataAdapter.java b/src/com/android/gallery3d/app/PhotoDataAdapter.java
index 0b544b95a..82225d919 100644
--- a/src/com/android/gallery3d/app/PhotoDataAdapter.java
+++ b/src/com/android/gallery3d/app/PhotoDataAdapter.java
@@ -29,8 +29,9 @@ 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.BitmapScreenNail;
import com.android.gallery3d.ui.PhotoView;
-import com.android.gallery3d.ui.PhotoView.ImageData;
+import com.android.gallery3d.ui.ScreenNail;
import com.android.gallery3d.ui.SynchronizedHandler;
import com.android.gallery3d.ui.TileImageViewAdapter;
import com.android.gallery3d.util.Future;
@@ -215,20 +216,22 @@ public class PhotoDataAdapter implements PhotoPage.Model {
mDataListener = listener;
}
- private void updateScreenNail(long version, Future<Bitmap> future) {
+ private void updateScreenNail(long version, Future<ScreenNail> future) {
ImageEntry entry = mImageCache.get(version);
+ ScreenNail screenNail = future.get();
+
if (entry == null || entry.screenNailTask != future) {
- Bitmap screenNail = future.get();
if (screenNail != null) screenNail.recycle();
return;
}
entry.screenNailTask = null;
- entry.screenNail = future.get();
+ entry.screenNail = screenNail;
- if (entry.screenNail == null) {
+ if (screenNail == null) {
entry.failToLoad = true;
}
+
if (mDataListener != null) {
mDataListener.onPhotoAvailable(version, false);
}
@@ -291,24 +294,19 @@ public class PhotoDataAdapter implements PhotoPage.Model {
mTileProvider.clear();
}
- private ImageData getImage(int index) {
+ private ScreenNail getImage(int index) {
if (index < 0 || index >= mSize || !mIsActive) return null;
Utils.assertTrue(index >= mActiveStart && index < mActiveEnd);
ImageEntry entry = mImageCache.get(getVersion(index));
- Bitmap screennail = entry == null ? null : entry.screenNail;
- if (screennail != null) {
- return new ImageData(screennail, entry.rotation);
- } else {
- return new ImageData(null, 0);
- }
+ return entry == null ? null : entry.screenNail;
}
- public ImageData getPreviousImage() {
+ public ScreenNail getPrevScreenNail() {
return getImage(mCurrentIndex - 1);
}
- public ImageData getNextImage() {
+ public ScreenNail getNextScreenNail() {
return getImage(mCurrentIndex + 1);
}
@@ -343,8 +341,8 @@ public class PhotoDataAdapter implements PhotoPage.Model {
updateCurrentIndex(index);
}
- public Bitmap getBackupImage() {
- return mTileProvider.getBackupImage();
+ public ScreenNail getScreenNail() {
+ return mTileProvider.getScreenNail();
}
public int getImageHeight() {
@@ -409,17 +407,17 @@ public class PhotoDataAdapter implements PhotoPage.Model {
}
private void updateTileProvider(ImageEntry entry) {
- Bitmap screenNail = entry.screenNail;
+ ScreenNail screenNail = entry.screenNail;
BitmapRegionDecoder fullImage = entry.fullImage;
if (screenNail != null) {
if (fullImage != null) {
- mTileProvider.setBackupImage(screenNail,
+ mTileProvider.setScreenNail(screenNail,
fullImage.getWidth(), fullImage.getHeight());
mTileProvider.setRegionDecoder(fullImage);
} else {
int width = screenNail.getWidth();
int height = screenNail.getHeight();
- mTileProvider.setBackupImage(screenNail, width, height);
+ mTileProvider.setScreenNail(screenNail, width, height);
}
} else {
mTileProvider.clear();
@@ -489,7 +487,7 @@ public class PhotoDataAdapter implements PhotoPage.Model {
}
}
- private static class ScreenNailJob implements Job<Bitmap> {
+ private static class ScreenNailJob implements Job<ScreenNail> {
private MediaItem mItem;
public ScreenNailJob(MediaItem item) {
@@ -497,14 +495,19 @@ public class PhotoDataAdapter implements PhotoPage.Model {
}
@Override
- public Bitmap run(JobContext jc) {
+ public ScreenNail run(JobContext jc) {
+ // We try to get a ScreenNail first, if it fails, we fallback to get
+ // a Bitmap and then wrap it in a BitmapScreenNail instead.
+ ScreenNail s = mItem.getScreenNail();
+ if (s != null) return s;
+
Bitmap bitmap = mItem.requestImage(MediaItem.TYPE_THUMBNAIL).run(jc);
if (jc.isCancelled()) return null;
if (bitmap != null) {
bitmap = BitmapUtils.rotateBitmap(bitmap,
mItem.getRotation() - mItem.getFullImageRotation(), true);
}
- return bitmap;
+ return new BitmapScreenNail(bitmap, mItem.getFullImageRotation());
}
}
@@ -604,16 +607,16 @@ public class PhotoDataAdapter implements PhotoPage.Model {
}
private class ScreenNailListener
- implements Runnable, FutureListener<Bitmap> {
+ implements Runnable, FutureListener<ScreenNail> {
private final long mVersion;
- private Future<Bitmap> mFuture;
+ private Future<ScreenNail> mFuture;
public ScreenNailListener(long version) {
mVersion = version;
}
@Override
- public void onFutureDone(Future<Bitmap> future) {
+ public void onFutureDone(Future<ScreenNail> future) {
mFuture = future;
mMainHandler.sendMessage(
mMainHandler.obtainMessage(MSG_RUN_OBJECT, this));
@@ -629,8 +632,8 @@ public class PhotoDataAdapter implements PhotoPage.Model {
public int requestedBits = 0;
public int rotation;
public BitmapRegionDecoder fullImage;
- public Bitmap screenNail;
- public Future<Bitmap> screenNailTask;
+ public ScreenNail screenNail;
+ public Future<ScreenNail> screenNailTask;
public Future<BitmapRegionDecoder> fullImageTask;
public boolean failToLoad = false;
}
diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java
index 502530a42..df5b98ada 100644
--- a/src/com/android/gallery3d/app/PhotoPage.java
+++ b/src/com/android/gallery3d/app/PhotoPage.java
@@ -30,6 +30,7 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+import android.view.ViewGroup;
import android.view.View.MeasureSpec;
import android.view.WindowManager;
import android.widget.ShareActionProvider;
@@ -43,6 +44,7 @@ import com.android.gallery3d.data.MediaObject;
import com.android.gallery3d.data.MediaSet;
import com.android.gallery3d.data.MtpDevice;
import com.android.gallery3d.data.Path;
+import com.android.gallery3d.data.SnailSource;
import com.android.gallery3d.picasasource.PicasaSource;
import com.android.gallery3d.ui.DetailsHelper;
import com.android.gallery3d.ui.DetailsHelper.CloseListener;
@@ -106,6 +108,11 @@ public class PhotoPage extends ActivityState
private ShareActionProvider mShareActionProvider;
private String mSetPathString;
+ // This is for testing only. It should be removed once we have the real
+ // Camera view.
+ private CameraView mCameraView;
+ private ScreenNailBridge mScreenNail;
+
public static interface Model extends PhotoView.Model {
public void resume();
public void pause();
@@ -180,6 +187,14 @@ public class PhotoPage extends ActivityState
Path itemPath = Path.fromString(data.getString(KEY_MEDIA_ITEM_PATH));
if (mSetPathString != null) {
+ // Uncomment the block below to test camera screennail.
+ /*
+ Path cameraScreenNailSetPath = addCameraScreenNail();
+
+ // Combine the original MediaSet with the one for camera ScreenNail.
+ mSetPathString = "/combo/item/{" + cameraScreenNailSetPath + "," +
+ mSetPathString + "}";
+ */
mMediaSet = mActivity.getDataManager().getMediaSet(mSetPathString);
mCurrentIndex = data.getInt(KEY_INDEX_HINT, 0);
mMediaSet = (MediaSet)
@@ -259,6 +274,34 @@ public class PhotoPage extends ActivityState
mPhotoView.setOpenedItem(itemPath);
}
+ // We create a Camera View and a ScreenNail. The two work together
+ // to present the view together with other pictures. Returns the
+ // Path of the MediaItem hosting the ScreenNail.
+ private Path addCameraScreenNail() {
+ // Create a camera view and add it to the root.
+ Activity activity = (Activity) mActivity;
+ mCameraView = new CameraView(activity);
+ ViewGroup galleryRoot = (ViewGroup) activity.findViewById(R.id.gallery_root);
+ galleryRoot.addView(mCameraView);
+
+ // Create a ScreenNail and register it.
+ mScreenNail = new ScreenNailBridge(mCameraView);
+ mCameraView.setScreenNailBridge(mScreenNail);
+ return SnailSource.registerScreenNail(mScreenNail);
+ }
+
+ private void removeCameraScreenNail() {
+ if (mCameraView == null) return;
+
+ // Remove the camera view.
+ ((ViewGroup) mCameraView.getParent()).removeView(mCameraView);
+ mCameraView = null;
+
+ // Unregister the ScreenNail.
+ SnailSource.unregisterScreenNail(mScreenNail);
+ mScreenNail = null;
+ }
+
private void updateShareURI(Path path) {
if (mShareActionProvider != null) {
DataManager manager = mActivity.getDataManager();
@@ -296,7 +339,9 @@ public class PhotoPage extends ActivityState
mPhotoView.showVideoPlayIcon(
photo.getMediaType() == MediaObject.MEDIA_TYPE_VIDEO);
- updateShareURI(photo.getPath());
+ if ((photo.getSupportedOperations() & MediaItem.SUPPORT_SHARE) != 0) {
+ updateShareURI(photo.getPath());
+ }
}
private void updateMenuOperations() {
@@ -633,6 +678,12 @@ public class PhotoPage extends ActivityState
onUserInteraction();
}
+ @Override
+ protected void onDestroy() {
+ removeCameraScreenNail();
+ super.onDestroy();
+ }
+
private class MyDetailsSource implements DetailsSource {
private int mIndex;
diff --git a/src/com/android/gallery3d/app/ScreenNailBridge.java b/src/com/android/gallery3d/app/ScreenNailBridge.java
new file mode 100644
index 000000000..9da197dca
--- /dev/null
+++ b/src/com/android/gallery3d/app/ScreenNailBridge.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2012 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.app;
+
+import android.graphics.RectF;
+import android.os.Handler;
+import android.util.Log;
+
+import com.android.gallery3d.ui.GLCanvas;
+import com.android.gallery3d.ui.ScreenNail;
+
+// This is a ScreenNail whose actually display is done by an foreign component.
+// The foreign component tells the ScreenNail its size by setSize(). The
+// ScreenNail tells the foreign component the position to display by
+// updateView().
+class ScreenNailBridge implements ScreenNail {
+ private static final String TAG = "ScreenNailBridge";
+ private int mWidth, mHeight;
+ private boolean mVisible = false;
+ private int mDrawX, mDrawY, mDrawWidth, mDrawHeight;
+ private Listener mListener;
+ private Handler mMainHandler;
+
+ public interface Listener {
+ // This is called from the main thread.
+ void updateView(boolean visible, int x, int y, int width, int height);
+ };
+
+ // The constructor should be called from the main thread.
+ public ScreenNailBridge(Listener listener) {
+ mListener = listener;
+ mMainHandler = new Handler();
+ }
+
+ // This can be called from any thread. (We expect it to be called from the
+ // main thread).
+ public synchronized void setSize(int w, int h) {
+ mWidth = w;
+ mHeight = h;
+ }
+
+ // This can be called from any thread. (We expect it to be called from GL
+ // thread)
+ @Override
+ public synchronized int getWidth() {
+ return mWidth;
+ }
+
+ // This can be called from any thread. (We expect it to be called from GL
+ // thread)
+ @Override
+ public synchronized int getHeight() {
+ return mHeight;
+ }
+
+ @Override
+ public int getRotation() {
+ return 0;
+ }
+
+ // This is run in the main thread.
+ private Runnable mUpdateViewRunnable = new Runnable() {
+ public void run() {
+ boolean v;
+ int x, y, width, height;
+ synchronized (ScreenNailBridge.this) {
+ v = mVisible;
+ x = mDrawX;
+ y = mDrawY;
+ width = mDrawWidth;
+ height = mDrawHeight;
+ }
+ mListener.updateView(v, x, y, width, height);
+ }
+ };
+
+ @Override
+ public synchronized void draw(GLCanvas canvas, int x, int y, int width, int height) {
+ if (mVisible && mDrawX == x && mDrawY == y && mDrawWidth == width &&
+ mDrawHeight == height) {
+ return;
+ }
+ mVisible = true;
+ mDrawX = x;
+ mDrawY = y;
+ mDrawWidth = width;
+ mDrawHeight = height;
+ mMainHandler.post(mUpdateViewRunnable);
+ }
+
+ @Override
+ public synchronized void disableDraw() {
+ if (!mVisible) return;
+ mVisible = false;
+ mMainHandler.post(mUpdateViewRunnable);
+ }
+
+ @Override
+ public void recycle() {
+ // Make sure we will not draw anymore.
+ disableDraw();
+ }
+
+ @Override
+ public void draw(GLCanvas canvas, RectF source, RectF dest) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java b/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
index adad8fdf4..66e7c20df 100644
--- a/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
+++ b/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
@@ -28,7 +28,7 @@ import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.MediaItem;
import com.android.gallery3d.data.Path;
import com.android.gallery3d.ui.PhotoView;
-import com.android.gallery3d.ui.PhotoView.ImageData;
+import com.android.gallery3d.ui.ScreenNail;
import com.android.gallery3d.ui.SynchronizedHandler;
import com.android.gallery3d.ui.TileImageViewAdapter;
import com.android.gallery3d.util.Future;
@@ -115,7 +115,7 @@ public class SinglePhotoDataAdapter extends TileImageViewAdapter
private void onDecodeLargeComplete(ImageBundle bundle) {
try {
- setBackupImage(bundle.backupImage,
+ setScreenNail(bundle.backupImage,
bundle.decoder.getWidth(), bundle.decoder.getHeight());
setRegionDecoder(bundle.decoder);
mPhotoView.notifyImageInvalidated(0);
@@ -128,7 +128,7 @@ public class SinglePhotoDataAdapter extends TileImageViewAdapter
try {
Bitmap backup = future.get();
if (backup == null) return;
- setBackupImage(backup, backup.getWidth(), backup.getHeight());
+ setScreenNail(backup, backup.getWidth(), backup.getHeight());
mPhotoView.notifyOnNewImage();
mPhotoView.notifyImageInvalidated(0); // the current image
} catch (Throwable t) {
@@ -158,11 +158,11 @@ public class SinglePhotoDataAdapter extends TileImageViewAdapter
}
}
- public ImageData getNextImage() {
+ public ScreenNail getNextScreenNail() {
return null;
}
- public ImageData getPreviousImage() {
+ public ScreenNail getPrevScreenNail() {
return null;
}
diff --git a/src/com/android/gallery3d/data/DataManager.java b/src/com/android/gallery3d/data/DataManager.java
index e6e97e9bf..1da3b76ca 100644
--- a/src/com/android/gallery3d/data/DataManager.java
+++ b/src/com/android/gallery3d/data/DataManager.java
@@ -115,6 +115,7 @@ public class DataManager {
addSource(new ClusterSource(mApplication));
addSource(new FilterSource(mApplication));
addSource(new UriSource(mApplication));
+ addSource(new SnailSource(mApplication));
if (mActiveCount > 0) {
for (MediaSource source : mSourceMap.values()) {
diff --git a/src/com/android/gallery3d/data/MediaItem.java b/src/com/android/gallery3d/data/MediaItem.java
index b682c2d1b..b2632f1cc 100644
--- a/src/com/android/gallery3d/data/MediaItem.java
+++ b/src/com/android/gallery3d/data/MediaItem.java
@@ -20,6 +20,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapRegionDecoder;
import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.ui.ScreenNail;
// MediaItem represents an image or a video item.
public abstract class MediaItem extends MediaObject {
@@ -90,6 +91,12 @@ public abstract class MediaItem extends MediaObject {
public abstract int getWidth();
public abstract int getHeight();
+ // This is an alternative for requestImage() in PhotoPage. If this
+ // is implemented, you don't need to implement requestImage().
+ public ScreenNail getScreenNail() {
+ return null;
+ }
+
public static int getTargetSize(int type) {
switch (type) {
case TYPE_THUMBNAIL:
diff --git a/src/com/android/gallery3d/data/SnailAlbum.java b/src/com/android/gallery3d/data/SnailAlbum.java
new file mode 100644
index 000000000..39467bbaa
--- /dev/null
+++ b/src/com/android/gallery3d/data/SnailAlbum.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2012 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.data;
+
+import java.util.ArrayList;
+
+// This is a simple MediaSet which contains only one MediaItem -- a SnailItem.
+public class SnailAlbum extends MediaSet {
+
+ private MediaItem mItem;
+
+ public SnailAlbum(Path path, MediaItem item) {
+ super(path, nextVersionNumber());
+ mItem = item;
+ }
+
+ @Override
+ public int getMediaItemCount() {
+ return 1;
+ }
+
+ @Override
+ public ArrayList<MediaItem> getMediaItem(int start, int count) {
+ ArrayList<MediaItem> result = new ArrayList<MediaItem>();
+
+ // If [start, start+count) contains the index 0, return the item.
+ if (start <= 0 && start + count > 0) {
+ result.add(mItem);
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean isLeafAlbum() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return "SnailAlbum";
+ }
+
+ @Override
+ public long reload() {
+ return mDataVersion;
+ }
+}
diff --git a/src/com/android/gallery3d/data/SnailItem.java b/src/com/android/gallery3d/data/SnailItem.java
new file mode 100644
index 000000000..2836a19bb
--- /dev/null
+++ b/src/com/android/gallery3d/data/SnailItem.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2012 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.data;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapRegionDecoder;
+
+import com.android.gallery3d.ui.ScreenNail;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+// SnailItem is a MediaItem which can provide a ScreenNail. This is
+// used so we can show an foreign component (like an
+// android.view.View) instead of a Bitmap.
+public class SnailItem extends MediaItem {
+ private ScreenNail mScreenNail;
+
+ public SnailItem(Path path, ScreenNail screenNail) {
+ super(path, nextVersionNumber());
+ mScreenNail = screenNail;
+ }
+
+ @Override
+ public Job<Bitmap> requestImage(int type) {
+ // nothing to return
+ return new Job<Bitmap>() {
+ public Bitmap run(JobContext jc) {
+ return null;
+ }
+ };
+ }
+
+ @Override
+ public Job<BitmapRegionDecoder> requestLargeImage() {
+ // nothing to return
+ return new Job<BitmapRegionDecoder>() {
+ public BitmapRegionDecoder run(JobContext jc) {
+ return null;
+ }
+ };
+ }
+
+ // We do not provide requestImage or requestLargeImage, instead we
+ // provide a ScreenNail.
+ @Override
+ public ScreenNail getScreenNail() {
+ return mScreenNail;
+ }
+
+ @Override
+ public String getMimeType() {
+ return "";
+ }
+
+ // Returns width and height of the media item.
+ // Returns 0, 0 if the information is not available.
+ @Override
+ public int getWidth() {
+ return 0;
+ }
+
+ @Override
+ public int getHeight() {
+ return 0;
+ }
+}
diff --git a/src/com/android/gallery3d/data/SnailSource.java b/src/com/android/gallery3d/data/SnailSource.java
new file mode 100644
index 000000000..17b899dba
--- /dev/null
+++ b/src/com/android/gallery3d/data/SnailSource.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2012 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.data;
+
+import android.util.SparseArray;
+import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.ui.ScreenNail;
+
+public class SnailSource extends MediaSource {
+ private static final String TAG = "SnailSource";
+ private static final int SNAIL_ALBUM = 0;
+ private static final int SNAIL_ITEM = 1;
+
+ private GalleryApp mApplication;
+ private PathMatcher mMatcher;
+ private static int sNextId;
+ private static SparseArray<ScreenNail> sRegistry = new SparseArray<ScreenNail>();
+
+ public SnailSource(GalleryApp application) {
+ super("snail");
+ mApplication = application;
+ mMatcher = new PathMatcher();
+ mMatcher.add("/snail/set/*", SNAIL_ALBUM);
+ mMatcher.add("/snail/item/*", SNAIL_ITEM);
+ }
+
+ // The only path we accept is "/snail/set/id" and "/snail/item/id"
+ @Override
+ public MediaObject createMediaObject(Path path) {
+ DataManager dataManager = mApplication.getDataManager();
+ switch (mMatcher.match(path)) {
+ case SNAIL_ALBUM:
+ String itemPath = "/snail/item/" + mMatcher.getVar(0);
+ MediaItem item =
+ (MediaItem) dataManager.getMediaObject(itemPath);
+ return new SnailAlbum(path, item);
+ case SNAIL_ITEM: {
+ int id = mMatcher.getIntVar(0);
+ return new SnailItem(path, lookupScreenNail(id));
+ }
+ }
+ return null;
+ }
+
+ // Register a ScreenNail. Returns the Path of the MediaSet
+ // containing the MediaItem associated with the ScreenNail.
+ public static synchronized Path registerScreenNail(ScreenNail s) {
+ int id = sNextId++;
+ sRegistry.put(id, s);
+ return Path.fromString("/snail/set").getChild(id);
+ }
+
+ public static synchronized void unregisterScreenNail(ScreenNail s) {
+ int index = sRegistry.indexOfValue(s);
+ sRegistry.removeAt(index);
+ }
+
+ private static synchronized ScreenNail lookupScreenNail(int id) {
+ return sRegistry.get(id);
+ }
+}
diff --git a/src/com/android/gallery3d/ui/BitmapScreenNail.java b/src/com/android/gallery3d/ui/BitmapScreenNail.java
new file mode 100644
index 000000000..117a9ac30
--- /dev/null
+++ b/src/com/android/gallery3d/ui/BitmapScreenNail.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 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 android.graphics.RectF;
+import android.util.Log;
+
+// This is a ScreenNail wraps a Bitmap. It also includes the rotation
+// information. The getWidth() and getHeight() methods return the width/height
+// before rotation.
+public class BitmapScreenNail implements ScreenNail {
+ private static final String TAG = "BitmapScreenNail";
+ private final int mWidth;
+ private final int mHeight;
+ private final int mRotation;
+ private final Bitmap mBitmap;
+ private BitmapTexture mTexture;
+
+ public BitmapScreenNail(Bitmap bitmap, int rotation) {
+ mWidth = bitmap.getWidth();
+ mHeight = bitmap.getHeight();
+ mRotation = rotation;
+ mBitmap = bitmap;
+ // We create mTexture lazily, so we don't incur the cost if we don't
+ // actually need it.
+ }
+
+ @Override
+ public int getWidth() {
+ return mWidth;
+ }
+
+ @Override
+ public int getHeight() {
+ return mHeight;
+ }
+
+ @Override
+ public int getRotation() {
+ return mRotation;
+ }
+
+ @Override
+ public void recycle() {
+ if (mTexture != null) {
+ mTexture.recycle();
+ }
+ }
+
+ @Override
+ public void draw(GLCanvas canvas, int x, int y, int width, int height) {
+ if (mTexture == null) {
+ mTexture = new BitmapTexture(mBitmap);
+ }
+ mTexture.draw(canvas, x, y, width, height);
+ }
+
+ @Override
+ public void disableDraw() {
+ }
+
+ @Override
+ public void draw(GLCanvas canvas, RectF source, RectF dest) {
+ if (mTexture == null) {
+ mTexture = new BitmapTexture(mBitmap);
+ }
+ canvas.drawTexture(mTexture, source, dest);
+ }
+}
diff --git a/src/com/android/gallery3d/ui/BitmapTileProvider.java b/src/com/android/gallery3d/ui/BitmapTileProvider.java
index ec2f97fed..a031b852f 100644
--- a/src/com/android/gallery3d/ui/BitmapTileProvider.java
+++ b/src/com/android/gallery3d/ui/BitmapTileProvider.java
@@ -25,7 +25,7 @@ import com.android.gallery3d.common.BitmapUtils;
import java.util.ArrayList;
public class BitmapTileProvider implements TileImageView.Model {
- private final Bitmap mBackup;
+ private final ScreenNail mScreenNail;
private final Bitmap[] mMipmaps;
private final Config mConfig;
private final int mImageWidth;
@@ -44,13 +44,13 @@ public class BitmapTileProvider implements TileImageView.Model {
list.add(bitmap);
}
- mBackup = list.remove(list.size() - 1);
+ mScreenNail = new BitmapScreenNail(list.remove(list.size() - 1), 0);
mMipmaps = list.toArray(new Bitmap[list.size()]);
mConfig = Config.ARGB_8888;
}
- public Bitmap getBackupImage() {
- return mBackup;
+ public ScreenNail getScreenNail() {
+ return mScreenNail;
}
public int getImageHeight() {
@@ -78,7 +78,9 @@ public class BitmapTileProvider implements TileImageView.Model {
for (Bitmap bitmap : mMipmaps) {
BitmapUtils.recycleSilently(bitmap);
}
- BitmapUtils.recycleSilently(mBackup);
+ if (mScreenNail != null) {
+ mScreenNail.recycle();
+ }
}
public boolean isFailedToLoad() {
diff --git a/src/com/android/gallery3d/ui/PhotoView.java b/src/com/android/gallery3d/ui/PhotoView.java
index 31e41bff7..dee23bda0 100644
--- a/src/com/android/gallery3d/ui/PhotoView.java
+++ b/src/com/android/gallery3d/ui/PhotoView.java
@@ -176,18 +176,14 @@ public class PhotoView extends GLView {
}
}
- private void updateScreenNailEntry(int which, ImageData data) {
+ private void updateScreenNailEntry(int which, ScreenNail screenNail) {
if (mTransitionMode == TRANS_SWITCH_NEXT
|| mTransitionMode == TRANS_SWITCH_PREVIOUS) {
// ignore screen nail updating during switching
return;
}
ScreenNailEntry entry = mScreenNails[which];
- if (data == null) {
- entry.set(false, null, 0);
- } else {
- entry.set(true, data.bitmap, data.rotation);
- }
+ entry.set(screenNail);
}
// -1 previous, 0 current, 1 next
@@ -195,13 +191,13 @@ public class PhotoView extends GLView {
switch (which) {
case -1: {
updateScreenNailEntry(
- ENTRY_PREVIOUS, mModel.getPreviousImage());
+ ENTRY_PREVIOUS, mModel.getPrevScreenNail());
layoutScreenNails();
invalidate();
break;
}
case 1: {
- updateScreenNailEntry(ENTRY_NEXT, mModel.getNextImage());
+ updateScreenNailEntry(ENTRY_NEXT, mModel.getNextScreenNail());
layoutScreenNails();
invalidate();
break;
@@ -230,7 +226,7 @@ public class PhotoView extends GLView {
// TIMEOUT --> COMPLETE, FAIL, INIT
// COMPLETE --> INIT
// FAIL --> INIT
- if (mModel.getLevelCount() != 0 || mModel.getBackupImage() != null) {
+ if (mModel.getLevelCount() != 0 || mModel.getScreenNail() != null) {
mHandler.removeMessages(MSG_SHOW_LOADING);
mLoadingState = LOADING_COMPLETE;
} else if (mModel.isFailedToLoad()) {
@@ -251,8 +247,8 @@ public class PhotoView extends GLView {
updateScreenNailEntry(ENTRY_PREVIOUS, null);
updateScreenNailEntry(ENTRY_NEXT, null);
} else {
- updateScreenNailEntry(ENTRY_PREVIOUS, mModel.getPreviousImage());
- updateScreenNailEntry(ENTRY_NEXT, mModel.getNextImage());
+ updateScreenNailEntry(ENTRY_PREVIOUS, mModel.getPrevScreenNail());
+ updateScreenNailEntry(ENTRY_NEXT, mModel.getNextScreenNail());
}
layoutScreenNails();
@@ -344,8 +340,8 @@ public class PhotoView extends GLView {
ScreenNailEntry prevNail = mScreenNails[ENTRY_PREVIOUS];
ScreenNailEntry nextNail = mScreenNails[ENTRY_NEXT];
- if (prevNail.mVisible) prevNail.draw(canvas);
- if (nextNail.mVisible) nextNail.draw(canvas);
+ prevNail.draw(canvas);
+ nextNail.draw(canvas);
}
// Draw the progress spinner and the text below it
@@ -581,10 +577,10 @@ public class PhotoView extends GLView {
ScreenNailEntry prevNail = mScreenNails[ENTRY_PREVIOUS];
ScreenNailEntry nextNail = mScreenNails[ENTRY_NEXT];
mTileView.invalidateTiles();
- if (prevNail.mTexture != null) prevNail.mTexture.recycle();
- prevNail.mTexture = mTileView.mBackupImage;
- mTileView.mBackupImage = nextNail.mTexture;
- nextNail.mTexture = null;
+ if (prevNail.mScreenNail != null) prevNail.mScreenNail.recycle();
+ prevNail.set(mTileView.mScreenNail);
+ mTileView.updateScreenNail(nextNail.mScreenNail);
+ nextNail.set(null);
mModel.next();
}
@@ -593,10 +589,10 @@ public class PhotoView extends GLView {
ScreenNailEntry prevNail = mScreenNails[ENTRY_PREVIOUS];
ScreenNailEntry nextNail = mScreenNails[ENTRY_NEXT];
mTileView.invalidateTiles();
- if (nextNail.mTexture != null) nextNail.mTexture.recycle();
- nextNail.mTexture = mTileView.mBackupImage;
- mTileView.mBackupImage = prevNail.mTexture;
- nextNail.mTexture = null;
+ if (nextNail.mScreenNail != null) nextNail.mScreenNail.recycle();
+ nextNail.set(mTileView.mScreenNail);
+ mTileView.updateScreenNail(prevNail.mScreenNail);
+ nextNail.set(null);
mModel.previous();
}
@@ -627,18 +623,8 @@ public class PhotoView extends GLView {
public int getImageRotation();
// Return null if the specified image is unavailable.
- public ImageData getNextImage();
- public ImageData getPreviousImage();
- }
-
- public static class ImageData {
- public int rotation;
- public Bitmap bitmap;
-
- public ImageData(Bitmap bitmap, int rotation) {
- this.bitmap = bitmap;
- this.rotation = rotation;
- }
+ public ScreenNail getNextScreenNail();
+ public ScreenNail getPrevScreenNail();
}
private static int getRotated(int degree, int original, int theother) {
@@ -649,28 +635,20 @@ public class PhotoView extends GLView {
private boolean mVisible;
private boolean mEnabled;
- private int mRotation;
private int mDrawWidth;
private int mDrawHeight;
private int mOffsetX;
+ private int mRotation;
- private BitmapTexture mTexture;
+ private ScreenNail mScreenNail;
- public void set(boolean enabled, Bitmap bitmap, int rotation) {
- mEnabled = enabled;
- mRotation = rotation;
- if (bitmap == null) {
- if (mTexture != null) mTexture.recycle();
- mTexture = null;
- } else {
- if (mTexture != null) {
- if (mTexture.getBitmap() != bitmap) {
- mTexture.recycle();
- mTexture = new BitmapTexture(bitmap);
- }
- } else {
- mTexture = new BitmapTexture(bitmap);
- }
+ public void set(ScreenNail screenNail) {
+ mEnabled = (screenNail != null);
+ if (mScreenNail == screenNail) return;
+ if (mScreenNail != null) mScreenNail.recycle();
+ mScreenNail = screenNail;
+ if (mScreenNail != null) {
+ mRotation = mScreenNail.getRotation();
updateDrawingSize();
}
}
@@ -689,15 +667,15 @@ public class PhotoView extends GLView {
public int gapToSide() {
return ((mRotation / 90) & 1) != 0
- ? PhotoView.gapToSide(mDrawHeight, getWidth())
- : PhotoView.gapToSide(mDrawWidth, getWidth());
+ ? PhotoView.gapToSide(mDrawHeight, getWidth())
+ : PhotoView.gapToSide(mDrawWidth, getWidth());
}
public void updateDrawingSize() {
- if (mTexture == null) return;
+ if (mScreenNail == null) return;
- int width = mTexture.getWidth();
- int height = mTexture.getHeight();
+ int width = mScreenNail.getWidth();
+ int height = mScreenNail.getHeight();
// Calculate the initial scale that will used by PositionController
// (usually fit-to-screen)
@@ -714,21 +692,27 @@ public class PhotoView extends GLView {
}
public void draw(GLCanvas canvas) {
+ if (mScreenNail == null) return;
+ if (!mVisible) {
+ mScreenNail.disableDraw();
+ return;
+ }
+
int x = mOffsetX;
int y = getHeight() / 2;
- if (mTexture != null) {
- if (mRotation != 0) {
- canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
- canvas.translate(x, y);
- canvas.rotate(mRotation, 0, 0, 1); //mRotation
- canvas.translate(-x, -y);
- }
- mTexture.draw(canvas, x - mDrawWidth / 2, y - mDrawHeight / 2,
- mDrawWidth, mDrawHeight);
- if (mRotation != 0) {
- canvas.restore();
- }
+ if (mRotation != 0) {
+ canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
+ canvas.translate(x, y);
+ canvas.rotate(mRotation, 0, 0, 1);
+ canvas.translate(-x, -y);
+ }
+
+ mScreenNail.draw(canvas, x - mDrawWidth / 2, y - mDrawHeight / 2,
+ mDrawWidth, mDrawHeight);
+
+ if (mRotation != 0) {
+ canvas.restore();
}
}
}
@@ -738,7 +722,7 @@ public class PhotoView extends GLView {
mTransitionMode = TRANS_NONE;
mTileView.freeTextures();
for (ScreenNailEntry entry : mScreenNails) {
- entry.set(false, null, 0);
+ entry.set(null);
}
}
diff --git a/src/com/android/gallery3d/ui/ScreenNail.java b/src/com/android/gallery3d/ui/ScreenNail.java
new file mode 100644
index 000000000..a2377fe2a
--- /dev/null
+++ b/src/com/android/gallery3d/ui/ScreenNail.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 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.RectF;
+
+public interface ScreenNail {
+ public int getWidth();
+ public int getHeight();
+ public int getRotation();
+ public void recycle();
+ public void draw(GLCanvas canvas, int x, int y, int width, int height);
+
+ // We need this method to tell ScreenNail to stop displaying.
+ public void disableDraw();
+
+ // This is only used by TileImageView to back up the tiles not yet loaded.
+ public void draw(GLCanvas canvas, RectF source, RectF dest);
+}
diff --git a/src/com/android/gallery3d/ui/TileImageView.java b/src/com/android/gallery3d/ui/TileImageView.java
index 7ad554684..d81244d29 100644
--- a/src/com/android/gallery3d/ui/TileImageView.java
+++ b/src/com/android/gallery3d/ui/TileImageView.java
@@ -70,7 +70,7 @@ public class TileImageView extends GLView {
private static final int STATE_RECYCLED = 0x40;
private Model mModel;
- protected BitmapTexture mBackupImage;
+ protected ScreenNail mScreenNail;
protected int mLevelCount; // cache the value of mScaledBitmaps.length
// The mLevel variable indicates which level of bitmap we should use.
@@ -78,7 +78,7 @@ public class TileImageView extends GLView {
// a smaller scaled bitmap (The width and height of each scaled bitmap is
// half size of the previous one). If the value is in [0, mLevelCount), we
// use the bitmap in mScaledBitmaps[mLevel] for display, otherwise the value
- // is mLevelCount, and that means we use mBackupTexture for display.
+ // is mLevelCount, and that means we use mScreenNail for display.
private int mLevel = 0;
// The offsets of the (left, top) of the upper-left tile to the (left, top)
@@ -120,7 +120,7 @@ public class TileImageView extends GLView {
public static interface Model {
public int getLevelCount();
- public Bitmap getBackupImage();
+ public ScreenNail getScreenNail();
public int getImageWidth();
public int getImageHeight();
@@ -139,31 +139,21 @@ public class TileImageView extends GLView {
if (model != null) notifyModelInvalidated();
}
- private void updateBackupTexture(Bitmap backup) {
- if (backup == null) {
- if (mBackupImage != null) mBackupImage.recycle();
- mBackupImage = null;
- } else {
- if (mBackupImage != null) {
- if (mBackupImage.getBitmap() != backup) {
- mBackupImage.recycle();
- mBackupImage = new BitmapTexture(backup);
- }
- } else {
- mBackupImage = new BitmapTexture(backup);
- }
- }
+ public void updateScreenNail(ScreenNail s) {
+ if (mScreenNail == s) return;
+ if (mScreenNail != null) mScreenNail.recycle();
+ mScreenNail = s;
}
public void notifyModelInvalidated() {
invalidateTiles();
if (mModel == null) {
- mBackupImage = null;
+ mScreenNail = null;
mImageWidth = 0;
mImageHeight = 0;
mLevelCount = 0;
} else {
- updateBackupTexture(mModel.getBackupImage());
+ updateScreenNail(mModel.getScreenNail());
mImageWidth = mModel.getImageWidth();
mImageHeight = mModel.getImageHeight();
mLevelCount = mModel.getLevelCount();
@@ -348,7 +338,7 @@ public class TileImageView extends GLView {
tile = mRecycledQueue.pop();
}
}
- updateBackupTexture(null);
+ updateScreenNail(null);
}
public void prepareTextures() {
@@ -358,7 +348,7 @@ public class TileImageView extends GLView {
if (mIsTextureFreed) {
layoutTiles(mCenterX, mCenterY, mScale, mRotation);
mIsTextureFreed = false;
- updateBackupTexture(mModel != null ? mModel.getBackupImage() : null);
+ updateScreenNail(mModel != null ? mModel.getScreenNail() : null);
}
}
@@ -379,6 +369,10 @@ public class TileImageView extends GLView {
}
try {
if (level != mLevelCount) {
+ if (mScreenNail != null) {
+ mScreenNail.disableDraw();
+ }
+
int size = (TILE_SIZE << level);
float length = size * mScale;
Rect r = mTileRange;
@@ -390,8 +384,8 @@ public class TileImageView extends GLView {
drawTile(canvas, tx, ty, level, x, y, length);
}
}
- } else if (mBackupImage != null) {
- mBackupImage.draw(canvas, mOffsetX, mOffsetY,
+ } else if (mScreenNail != null) {
+ mScreenNail.draw(canvas, mOffsetX, mOffsetY,
Math.round(mImageWidth * mScale),
Math.round(mImageHeight * mScale));
}
@@ -542,14 +536,13 @@ public class TileImageView extends GLView {
}
if (drawTile(tile, canvas, source, target)) return;
}
- if (mBackupImage != null) {
- BasicTexture backup = mBackupImage;
+ if (mScreenNail != null) {
int size = TILE_SIZE << level;
- float scaleX = (float) backup.getWidth() / mImageWidth;
- float scaleY = (float) backup.getHeight() / mImageHeight;
+ float scaleX = (float) mScreenNail.getWidth() / mImageWidth;
+ float scaleY = (float) mScreenNail.getHeight() / mImageHeight;
source.set(tx * scaleX, ty * scaleY, (tx + size) * scaleX,
(ty + size) * scaleY);
- canvas.drawTexture(backup, source, target);
+ mScreenNail.draw(canvas, source, target);
}
}
diff --git a/src/com/android/gallery3d/ui/TileImageViewAdapter.java b/src/com/android/gallery3d/ui/TileImageViewAdapter.java
index 63bb0b2f7..475184e6c 100644
--- a/src/com/android/gallery3d/ui/TileImageViewAdapter.java
+++ b/src/com/android/gallery3d/ui/TileImageViewAdapter.java
@@ -27,10 +27,10 @@ import com.android.gallery3d.common.Utils;
public class TileImageViewAdapter implements TileImageView.Model {
private static final String TAG = "TileImageViewAdapter";
+ protected ScreenNail mScreenNail;
protected BitmapRegionDecoder mRegionDecoder;
protected int mImageWidth;
protected int mImageHeight;
- protected Bitmap mBackupImage;
protected int mLevelCount;
protected boolean mFailedToLoad;
@@ -40,8 +40,8 @@ public class TileImageViewAdapter implements TileImageView.Model {
public TileImageViewAdapter() {
}
- public TileImageViewAdapter(Bitmap backup, BitmapRegionDecoder regionDecoder) {
- mBackupImage = Utils.checkNotNull(backup);
+ public TileImageViewAdapter(Bitmap bitmap, BitmapRegionDecoder regionDecoder) {
+ mScreenNail = new BitmapScreenNail(Utils.checkNotNull(bitmap), 0);
mRegionDecoder = regionDecoder;
mImageWidth = regionDecoder.getWidth();
mImageHeight = regionDecoder.getHeight();
@@ -49,7 +49,7 @@ public class TileImageViewAdapter implements TileImageView.Model {
}
public synchronized void clear() {
- mBackupImage = null;
+ mScreenNail = null;
mImageWidth = 0;
mImageHeight = 0;
mLevelCount = 0;
@@ -57,8 +57,18 @@ public class TileImageViewAdapter implements TileImageView.Model {
mFailedToLoad = false;
}
- public synchronized void setBackupImage(Bitmap backup, int width, int height) {
- mBackupImage = Utils.checkNotNull(backup);
+ public synchronized void setScreenNail(Bitmap bitmap, int width, int height) {
+ mScreenNail = new BitmapScreenNail(Utils.checkNotNull(bitmap), 0);
+ mImageWidth = width;
+ mImageHeight = height;
+ mRegionDecoder = null;
+ mLevelCount = 0;
+ mFailedToLoad = false;
+ }
+
+ public synchronized void setScreenNail(
+ ScreenNail screenNail, int width, int height) {
+ mScreenNail = Utils.checkNotNull(screenNail);
mImageWidth = width;
mImageHeight = height;
mRegionDecoder = null;
@@ -76,7 +86,7 @@ public class TileImageViewAdapter implements TileImageView.Model {
private int calculateLevelCount() {
return Math.max(0, Utils.ceilLog2(
- (float) mImageWidth / mBackupImage.getWidth()));
+ (float) mImageWidth / mScreenNail.getWidth()));
}
@Override
@@ -122,8 +132,8 @@ public class TileImageViewAdapter implements TileImageView.Model {
}
@Override
- public Bitmap getBackupImage() {
- return mBackupImage;
+ public ScreenNail getScreenNail() {
+ return mScreenNail;
}
@Override