summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/ui/TiledScreenNail.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/ui/TiledScreenNail.java')
-rw-r--r--src/com/android/gallery3d/ui/TiledScreenNail.java218
1 files changed, 218 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/ui/TiledScreenNail.java b/src/com/android/gallery3d/ui/TiledScreenNail.java
new file mode 100644
index 000000000..860e230bb
--- /dev/null
+++ b/src/com/android/gallery3d/ui/TiledScreenNail.java
@@ -0,0 +1,218 @@
+/*
+ * 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 com.android.gallery3d.common.Utils;
+import com.android.photos.data.GalleryBitmapPool;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.TiledTexture;
+
+// This is a ScreenNail wraps a Bitmap. There are some extra functions:
+//
+// - If we need to draw before the bitmap is available, we draw a rectange of
+// placeholder color (gray).
+//
+// - When the the bitmap is available, and we have drawn the placeholder color
+// before, we will do a fade-in animation.
+public class TiledScreenNail implements ScreenNail {
+ @SuppressWarnings("unused")
+ private static final String TAG = "TiledScreenNail";
+
+ // The duration of the fading animation in milliseconds
+ private static final int DURATION = 180;
+
+ private static int sMaxSide = 640;
+
+ // These are special values for mAnimationStartTime
+ private static final long ANIMATION_NOT_NEEDED = -1;
+ private static final long ANIMATION_NEEDED = -2;
+ private static final long ANIMATION_DONE = -3;
+
+ private int mWidth;
+ private int mHeight;
+ private long mAnimationStartTime = ANIMATION_NOT_NEEDED;
+
+ private Bitmap mBitmap;
+ private TiledTexture mTexture;
+
+ public TiledScreenNail(Bitmap bitmap) {
+ mWidth = bitmap.getWidth();
+ mHeight = bitmap.getHeight();
+ mBitmap = bitmap;
+ mTexture = new TiledTexture(bitmap);
+ }
+
+ public TiledScreenNail(int width, int height) {
+ setSize(width, height);
+ }
+
+ // This gets overridden by bitmap_screennail_placeholder
+ // in GalleryUtils.initialize
+ private static int mPlaceholderColor = 0xFF222222;
+ private static boolean mDrawPlaceholder = true;
+
+ public static void setPlaceholderColor(int color) {
+ mPlaceholderColor = color;
+ }
+
+ private void setSize(int width, int height) {
+ if (width == 0 || height == 0) {
+ width = sMaxSide;
+ height = sMaxSide * 3 / 4;
+ }
+ float scale = Math.min(1, (float) sMaxSide / Math.max(width, height));
+ mWidth = Math.round(scale * width);
+ mHeight = Math.round(scale * height);
+ }
+
+ // Combines the two ScreenNails.
+ // Returns the used one and recycle the unused one.
+ public ScreenNail combine(ScreenNail other) {
+ if (other == null) {
+ return this;
+ }
+
+ if (!(other instanceof TiledScreenNail)) {
+ recycle();
+ return other;
+ }
+
+ // Now both are TiledScreenNail. Move over the information about width,
+ // height, and Bitmap, then recycle the other.
+ TiledScreenNail newer = (TiledScreenNail) other;
+ mWidth = newer.mWidth;
+ mHeight = newer.mHeight;
+ if (newer.mTexture != null) {
+ if (mBitmap != null) GalleryBitmapPool.getInstance().put(mBitmap);
+ if (mTexture != null) mTexture.recycle();
+ mBitmap = newer.mBitmap;
+ mTexture = newer.mTexture;
+ newer.mBitmap = null;
+ newer.mTexture = null;
+ }
+ newer.recycle();
+ return this;
+ }
+
+ public void updatePlaceholderSize(int width, int height) {
+ if (mBitmap != null) return;
+ if (width == 0 || height == 0) return;
+ setSize(width, height);
+ }
+
+ @Override
+ public int getWidth() {
+ return mWidth;
+ }
+
+ @Override
+ public int getHeight() {
+ return mHeight;
+ }
+
+ @Override
+ public void noDraw() {
+ }
+
+ @Override
+ public void recycle() {
+ if (mTexture != null) {
+ mTexture.recycle();
+ mTexture = null;
+ }
+ if (mBitmap != null) {
+ GalleryBitmapPool.getInstance().put(mBitmap);
+ mBitmap = null;
+ }
+ }
+
+ public static void disableDrawPlaceholder() {
+ mDrawPlaceholder = false;
+ }
+
+ public static void enableDrawPlaceholder() {
+ mDrawPlaceholder = true;
+ }
+
+ @Override
+ public void draw(GLCanvas canvas, int x, int y, int width, int height) {
+ if (mTexture == null || !mTexture.isReady()) {
+ if (mAnimationStartTime == ANIMATION_NOT_NEEDED) {
+ mAnimationStartTime = ANIMATION_NEEDED;
+ }
+ if(mDrawPlaceholder) {
+ canvas.fillRect(x, y, width, height, mPlaceholderColor);
+ }
+ return;
+ }
+
+ if (mAnimationStartTime == ANIMATION_NEEDED) {
+ mAnimationStartTime = AnimationTime.get();
+ }
+
+ if (isAnimating()) {
+ mTexture.drawMixed(canvas, mPlaceholderColor, getRatio(), x, y,
+ width, height);
+ } else {
+ mTexture.draw(canvas, x, y, width, height);
+ }
+ }
+
+ @Override
+ public void draw(GLCanvas canvas, RectF source, RectF dest) {
+ if (mTexture == null || !mTexture.isReady()) {
+ canvas.fillRect(dest.left, dest.top, dest.width(), dest.height(),
+ mPlaceholderColor);
+ return;
+ }
+
+ mTexture.draw(canvas, source, dest);
+ }
+
+ public boolean isAnimating() {
+ // The TiledTexture may not be uploaded completely yet.
+ // In that case, we count it as animating state and we will draw
+ // the placeholder in TileImageView.
+ if (mTexture == null || !mTexture.isReady()) return true;
+ if (mAnimationStartTime < 0) return false;
+ if (AnimationTime.get() - mAnimationStartTime >= DURATION) {
+ mAnimationStartTime = ANIMATION_DONE;
+ return false;
+ }
+ return true;
+ }
+
+ private float getRatio() {
+ float r = (float) (AnimationTime.get() - mAnimationStartTime) / DURATION;
+ return Utils.clamp(1.0f - r, 0.0f, 1.0f);
+ }
+
+ public boolean isShowingPlaceholder() {
+ return (mBitmap == null) || isAnimating();
+ }
+
+ public TiledTexture getTexture() {
+ return mTexture;
+ }
+
+ public static void setMaxSide(int size) {
+ sMaxSide = size;
+ }
+}