summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/ui/PhotoFallbackEffect.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/ui/PhotoFallbackEffect.java')
-rw-r--r--src/com/android/gallery3d/ui/PhotoFallbackEffect.java179
1 files changed, 179 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/ui/PhotoFallbackEffect.java b/src/com/android/gallery3d/ui/PhotoFallbackEffect.java
new file mode 100644
index 000000000..4603285a4
--- /dev/null
+++ b/src/com/android/gallery3d/ui/PhotoFallbackEffect.java
@@ -0,0 +1,179 @@
+/*
+ * 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.Rect;
+import android.graphics.RectF;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+import com.android.gallery3d.anim.Animation;
+import com.android.gallery3d.data.Path;
+import com.android.gallery3d.glrenderer.GLCanvas;
+import com.android.gallery3d.glrenderer.RawTexture;
+import com.android.gallery3d.ui.AlbumSlotRenderer.SlotFilter;
+
+import java.util.ArrayList;
+
+public class PhotoFallbackEffect extends Animation implements SlotFilter {
+
+ private static final int ANIM_DURATION = 300;
+ private static final Interpolator ANIM_INTERPOLATE = new DecelerateInterpolator(1.5f);
+
+ public static class Entry {
+ public int index;
+ public Path path;
+ public Rect source;
+ public Rect dest;
+ public RawTexture texture;
+
+ public Entry(Path path, Rect source, RawTexture texture) {
+ this.path = path;
+ this.source = source;
+ this.texture = texture;
+ }
+ }
+
+ public interface PositionProvider {
+ public Rect getPosition(int index);
+ public int getItemIndex(Path path);
+ }
+
+ private RectF mSource = new RectF();
+ private RectF mTarget = new RectF();
+ private float mProgress;
+ private PositionProvider mPositionProvider;
+
+ private ArrayList<Entry> mList = new ArrayList<Entry>();
+
+ public PhotoFallbackEffect() {
+ setDuration(ANIM_DURATION);
+ setInterpolator(ANIM_INTERPOLATE);
+ }
+
+ public void addEntry(Path path, Rect rect, RawTexture texture) {
+ mList.add(new Entry(path, rect, texture));
+ }
+
+ public Entry getEntry(Path path) {
+ for (int i = 0, n = mList.size(); i < n; ++i) {
+ Entry entry = mList.get(i);
+ if (entry.path == path) return entry;
+ }
+ return null;
+ }
+
+ public boolean draw(GLCanvas canvas) {
+ boolean more = calculate(AnimationTime.get());
+ for (int i = 0, n = mList.size(); i < n; ++i) {
+ Entry entry = mList.get(i);
+ if (entry.index < 0) continue;
+ entry.dest = mPositionProvider.getPosition(entry.index);
+ drawEntry(canvas, entry);
+ }
+ return more;
+ }
+
+ private void drawEntry(GLCanvas canvas, Entry entry) {
+ if (!entry.texture.isLoaded()) return;
+
+ int w = entry.texture.getWidth();
+ int h = entry.texture.getHeight();
+
+ Rect s = entry.source;
+ Rect d = entry.dest;
+
+ // the following calculation is based on d.width() == d.height()
+
+ float p = mProgress;
+
+ float fullScale = (float) d.height() / Math.min(s.width(), s.height());
+ float scale = fullScale * p + 1 * (1 - p);
+
+ float cx = d.centerX() * p + s.centerX() * (1 - p);
+ float cy = d.centerY() * p + s.centerY() * (1 - p);
+
+ float ch = s.height() * scale;
+ float cw = s.width() * scale;
+
+ if (w > h) {
+ // draw the center part
+ mTarget.set(cx - ch / 2, cy - ch / 2, cx + ch / 2, cy + ch / 2);
+ mSource.set((w - h) / 2, 0, (w + h) / 2, h);
+ canvas.drawTexture(entry.texture, mSource, mTarget);
+
+ canvas.save(GLCanvas.SAVE_FLAG_ALPHA);
+ canvas.multiplyAlpha(1 - p);
+
+ // draw the left part
+ mTarget.set(cx - cw / 2, cy - ch / 2, cx - ch / 2, cy + ch / 2);
+ mSource.set(0, 0, (w - h) / 2, h);
+ canvas.drawTexture(entry.texture, mSource, mTarget);
+
+ // draw the right part
+ mTarget.set(cx + ch / 2, cy - ch / 2, cx + cw / 2, cy + ch / 2);
+ mSource.set((w + h) / 2, 0, w, h);
+ canvas.drawTexture(entry.texture, mSource, mTarget);
+
+ canvas.restore();
+ } else {
+ // draw the center part
+ mTarget.set(cx - cw / 2, cy - cw / 2, cx + cw / 2, cy + cw / 2);
+ mSource.set(0, (h - w) / 2, w, (h + w) / 2);
+ canvas.drawTexture(entry.texture, mSource, mTarget);
+
+ canvas.save(GLCanvas.SAVE_FLAG_ALPHA);
+ canvas.multiplyAlpha(1 - p);
+
+ // draw the upper part
+ mTarget.set(cx - cw / 2, cy - ch / 2, cx + cw / 2, cy - cw / 2);
+ mSource.set(0, 0, w, (h - w) / 2);
+ canvas.drawTexture(entry.texture, mSource, mTarget);
+
+ // draw the bottom part
+ mTarget.set(cx - cw / 2, cy + cw / 2, cx + cw / 2, cy + ch / 2);
+ mSource.set(0, (w + h) / 2, w, h);
+ canvas.drawTexture(entry.texture, mSource, mTarget);
+
+ canvas.restore();
+ }
+ }
+
+ @Override
+ protected void onCalculate(float progress) {
+ mProgress = progress;
+ }
+
+ public void setPositionProvider(PositionProvider provider) {
+ mPositionProvider = provider;
+ if (mPositionProvider != null) {
+ for (int i = 0, n = mList.size(); i < n; ++i) {
+ Entry entry = mList.get(i);
+ entry.index = mPositionProvider.getItemIndex(entry.path);
+ }
+ }
+ }
+
+ @Override
+ public boolean acceptSlot(int index) {
+ for (int i = 0, n = mList.size(); i < n; ++i) {
+ Entry entry = mList.get(i);
+ if (entry.index == index) return false;
+ }
+ return true;
+ }
+}