summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
authorOwen Lin <owenlin@google.com>2012-05-07 16:35:53 +0800
committerOwen Lin <owenlin@google.com>2012-05-17 12:59:21 -0700
commit3aad1aba14d3abe8324e0a0e129627d51a466bc4 (patch)
tree48652c461e62e8b7f74b7755427791ae8012f511 /src/com/android
parent93300e13d5ae3b4e4c532a90fc7f763ec62cbb8c (diff)
downloadandroid_packages_apps_Snap-3aad1aba14d3abe8324e0a0e129627d51a466bc4.tar.gz
android_packages_apps_Snap-3aad1aba14d3abe8324e0a0e129627d51a466bc4.tar.bz2
android_packages_apps_Snap-3aad1aba14d3abe8324e0a0e129627d51a466bc4.zip
Add transition animation for tapping from PhotoPage.
bug:6383694 Change-Id: Ib457d6b636dafd3f8ef7340bfa85725f14d90bd0
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/gallery3d/app/AbstractGalleryActivity.java6
-rw-r--r--src/com/android/gallery3d/app/ActivityState.java8
-rw-r--r--src/com/android/gallery3d/app/AlbumPage.java48
-rw-r--r--src/com/android/gallery3d/app/GalleryActivity.java1
-rw-r--r--src/com/android/gallery3d/app/PhotoDataAdapter.java10
-rw-r--r--src/com/android/gallery3d/app/PhotoPage.java53
-rw-r--r--src/com/android/gallery3d/app/SinglePhotoDataAdapter.java4
-rw-r--r--src/com/android/gallery3d/app/StateManager.java1
-rw-r--r--src/com/android/gallery3d/app/TransitionStore.java36
-rw-r--r--src/com/android/gallery3d/ui/AlbumSlotRenderer.java16
-rw-r--r--src/com/android/gallery3d/ui/PhotoFallbackEffect.java177
-rw-r--r--src/com/android/gallery3d/ui/PhotoView.java35
-rw-r--r--src/com/android/gallery3d/ui/SlotView.java22
13 files changed, 379 insertions, 38 deletions
diff --git a/src/com/android/gallery3d/app/AbstractGalleryActivity.java b/src/com/android/gallery3d/app/AbstractGalleryActivity.java
index 4ee740360..f674c0bee 100644
--- a/src/com/android/gallery3d/app/AbstractGalleryActivity.java
+++ b/src/com/android/gallery3d/app/AbstractGalleryActivity.java
@@ -45,6 +45,7 @@ public class AbstractGalleryActivity extends Activity implements GalleryActivity
private StateManager mStateManager;
private GalleryActionBar mActionBar;
private OrientationManager mOrientationManager;
+ private TransitionStore mTransitionStore = new TransitionStore();
private boolean mDisableToggleStatusBar;
private AlertDialog mAlertDialog = null;
@@ -260,4 +261,9 @@ public class AbstractGalleryActivity extends Activity implements GalleryActivity
win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
+
+ @Override
+ public TransitionStore getTransitionStore() {
+ return mTransitionStore;
+ }
}
diff --git a/src/com/android/gallery3d/app/ActivityState.java b/src/com/android/gallery3d/app/ActivityState.java
index 443e2bd29..233b3986d 100644
--- a/src/com/android/gallery3d/app/ActivityState.java
+++ b/src/com/android/gallery3d/app/ActivityState.java
@@ -59,6 +59,7 @@ abstract public class ActivityState {
private boolean mDestroyed = false;
private boolean mPlugged = false;
+ boolean mIsFinishing = false;
protected ActivityState() {
}
@@ -173,6 +174,9 @@ abstract public class ActivityState {
activity.registerReceiver(mPowerIntentReceiver, filter);
}
onResume();
+
+ // the transition store should be cleared after resume;
+ mActivity.getTransitionStore().clear();
}
// a subclass of ActivityState should override the method to resume itself
@@ -196,4 +200,8 @@ abstract public class ActivityState {
boolean isDestroyed() {
return mDestroyed;
}
+
+ public boolean isFinishing() {
+ return mIsFinishing;
+ }
}
diff --git a/src/com/android/gallery3d/app/AlbumPage.java b/src/com/android/gallery3d/app/AlbumPage.java
index df0124c52..3033b937c 100644
--- a/src/com/android/gallery3d/app/AlbumPage.java
+++ b/src/com/android/gallery3d/app/AlbumPage.java
@@ -50,6 +50,7 @@ import com.android.gallery3d.ui.FadeTexture;
import com.android.gallery3d.ui.GLCanvas;
import com.android.gallery3d.ui.GLRoot;
import com.android.gallery3d.ui.GLView;
+import com.android.gallery3d.ui.PhotoFallbackEffect;
import com.android.gallery3d.ui.RelativePosition;
import com.android.gallery3d.ui.SelectionManager;
import com.android.gallery3d.ui.SlotView;
@@ -70,6 +71,7 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
public static final String KEY_SET_CENTER = "set-center";
public static final String KEY_AUTO_SELECT_ALL = "auto-select-all";
public static final String KEY_SHOW_CLUSTER_MENU = "cluster-menu";
+ public static final String KEY_RESUME_ANIMATION = "resume_animation";
private static final int REQUEST_SLIDESHOW = 1;
private static final int REQUEST_PHOTO = 2;
@@ -110,6 +112,30 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
private boolean mInitialSynced = false;
private RelativePosition mOpenCenter = new RelativePosition();
+ private PhotoFallbackEffect mResumeEffect;
+ private PhotoFallbackEffect.PositionProvider mPositionProvider =
+ new PhotoFallbackEffect.PositionProvider() {
+ @Override
+ public Rect getPosition(int index) {
+ Rect rect = mSlotView.getSlotRect(index);
+ Rect bounds = mSlotView.bounds();
+ rect.offset(bounds.left - mSlotView.getScrollX(),
+ bounds.top - mSlotView.getScrollY());
+ return rect;
+ }
+
+ @Override
+ public int getItemIndex(Path path) {
+ int start = mSlotView.getVisibleStart();
+ int end = mSlotView.getVisibleEnd();
+ for (int i = start; i < end; ++i) {
+ MediaItem item = mAlbumDataAdapter.get(i);
+ if (item != null && item.getPath() == path) return i;
+ }
+ return -1;
+ }
+ };
+
private final GLView mRootPane = new GLView() {
private final float mMatrix[] = new float[16];
@@ -144,6 +170,16 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
canvas.save(GLCanvas.SAVE_FLAG_MATRIX);
canvas.multiplyMatrix(mMatrix, 0);
super.render(canvas);
+
+ if (mResumeEffect != null) {
+ boolean more = mResumeEffect.draw(canvas);
+ if (!more) {
+ mResumeEffect = null;
+ mAlbumView.setSlotFilter(null);
+ } else {
+ invalidate();
+ }
+ }
canvas.restore();
}
};
@@ -336,6 +372,14 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
protected void onResume() {
super.onResume();
mIsActive = true;
+
+ mResumeEffect = mActivity.getTransitionStore().get(KEY_RESUME_ANIMATION);
+ if (mResumeEffect != null) {
+ mAlbumView.setSlotFilter(mResumeEffect);
+ mResumeEffect.setPositionProvider(mPositionProvider);
+ mResumeEffect.start();
+ }
+
setContentPane(mRootPane);
Path path = mMediaSet.getPath();
@@ -359,6 +403,9 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
protected void onPause() {
super.onPause();
mIsActive = false;
+
+ mAlbumView.setSlotFilter(null);
+
mAlbumDataAdapter.pause();
mAlbumView.pause();
DetailsHelper.pause();
@@ -549,7 +596,6 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
if (data == null) return;
mFocusIndex = data.getIntExtra(PhotoPage.KEY_RETURN_INDEX_HINT, 0);
mSlotView.makeSlotVisible(mFocusIndex);
- mSlotView.startRestoringAnimation(mFocusIndex);
break;
}
case REQUEST_DO_ANIMATION: {
diff --git a/src/com/android/gallery3d/app/GalleryActivity.java b/src/com/android/gallery3d/app/GalleryActivity.java
index 0c6375fd7..33c77fb4c 100644
--- a/src/com/android/gallery3d/app/GalleryActivity.java
+++ b/src/com/android/gallery3d/app/GalleryActivity.java
@@ -23,4 +23,5 @@ public interface GalleryActivity extends GalleryContext {
public GLRoot getGLRoot();
public GalleryActionBar getGalleryActionBar();
public OrientationManager getOrientationManager();
+ public TransitionStore getTransitionStore();
}
diff --git a/src/com/android/gallery3d/app/PhotoDataAdapter.java b/src/com/android/gallery3d/app/PhotoDataAdapter.java
index d88b72ca8..a0c4cdf6a 100644
--- a/src/com/android/gallery3d/app/PhotoDataAdapter.java
+++ b/src/com/android/gallery3d/app/PhotoDataAdapter.java
@@ -469,8 +469,12 @@ public class PhotoDataAdapter implements PhotoPage.Model {
return mCurrentIndex;
}
- public MediaItem getCurrentMediaItem() {
- return mData[mCurrentIndex % DATA_CACHE_SIZE];
+ public MediaItem getMediaItem(int offset) {
+ int index = mCurrentIndex + offset;
+ if (index >= mContentStart && index < mContentEnd) {
+ return mData[index % DATA_CACHE_SIZE];
+ }
+ return null;
}
public void setCurrentPhoto(Path path, int indexHint) {
@@ -482,7 +486,7 @@ public class PhotoDataAdapter implements PhotoPage.Model {
fireDataChange();
// We need to reload content if the path doesn't match.
- MediaItem item = getCurrentMediaItem();
+ MediaItem item = getMediaItem(0);
if (item != null && item.getPath() != path) {
if (mReloadTask != null) mReloadTask.notifyDirty();
}
diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java
index 493e4aaf4..d344558ce 100644
--- a/src/com/android/gallery3d/app/PhotoPage.java
+++ b/src/com/android/gallery3d/app/PhotoPage.java
@@ -37,6 +37,7 @@ import android.widget.ShareActionProvider;
import android.widget.Toast;
import com.android.gallery3d.R;
+import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.DataManager;
import com.android.gallery3d.data.MediaDetails;
import com.android.gallery3d.data.MediaItem;
@@ -52,9 +53,12 @@ import com.android.gallery3d.ui.DetailsHelper;
import com.android.gallery3d.ui.DetailsHelper.CloseListener;
import com.android.gallery3d.ui.DetailsHelper.DetailsSource;
import com.android.gallery3d.ui.GLCanvas;
+import com.android.gallery3d.ui.GLRoot;
+import com.android.gallery3d.ui.GLRoot.OnGLIdleListener;
import com.android.gallery3d.ui.GLView;
import com.android.gallery3d.ui.ImportCompleteListener;
import com.android.gallery3d.ui.MenuExecutor;
+import com.android.gallery3d.ui.PhotoFallbackEffect;
import com.android.gallery3d.ui.PhotoView;
import com.android.gallery3d.ui.SelectionManager;
import com.android.gallery3d.ui.SynchronizedHandler;
@@ -129,7 +133,6 @@ public class PhotoPage extends ActivityState implements
public void resume();
public void pause();
public boolean isEmpty();
- public MediaItem getCurrentMediaItem();
public void setCurrentPhoto(Path path, int indexHint);
}
@@ -223,7 +226,7 @@ public class PhotoPage extends ActivityState implements
public void onPhotoChanged(int index, Path item) {
mCurrentIndex = index;
if (item != null) {
- MediaItem photo = mModel.getCurrentMediaItem();
+ MediaItem photo = mModel.getMediaItem(0);
if (photo != null) updateCurrentPhoto(photo);
}
updateBars();
@@ -232,7 +235,7 @@ public class PhotoPage extends ActivityState implements
@Override
public void onLoadingFinished() {
if (!mModel.isEmpty()) {
- MediaItem photo = mModel.getCurrentMediaItem();
+ MediaItem photo = mModel.getMediaItem(0);
if (photo != null) updateCurrentPhoto(photo);
} else if (mIsActive) {
mActivity.getStateManager().finishState(PhotoPage.this);
@@ -519,7 +522,7 @@ public class PhotoPage extends ActivityState implements
@Override
protected boolean onItemSelected(MenuItem item) {
- MediaItem current = mModel.getCurrentMediaItem();
+ MediaItem current = mModel.getMediaItem(0);
if (current == null) {
// item is not ready, ignore
@@ -624,7 +627,7 @@ public class PhotoPage extends ActivityState implements
if (mAppBridge.onSingleTapUp(x, y)) return;
}
- MediaItem item = mModel.getCurrentMediaItem();
+ MediaItem item = mModel.getMediaItem(0);
if (item == null || item == mScreenNailItem) {
// item is not ready or it is camera preview, ignore
return;
@@ -724,11 +727,49 @@ public class PhotoPage extends ActivityState implements
}
}
+ private class PreparePhotoFallback implements OnGLIdleListener {
+ private PhotoFallbackEffect mPhotoFallback = new PhotoFallbackEffect();
+ private boolean mResultReady = false;
+
+ public synchronized PhotoFallbackEffect get() {
+ while (!mResultReady) {
+ Utils.waitWithoutInterrupt(this);
+ }
+ return mPhotoFallback;
+ }
+
+ @Override
+ public boolean onGLIdle(GLCanvas canvas, boolean renderRequested) {
+ mPhotoFallback = mPhotoView.buildFallbackEffect(mRootPane, canvas);
+ synchronized (this) {
+ mResultReady = true;
+ notifyAll();
+ }
+ return false;
+ }
+ }
+
+ private void preparePhotoFallbackView() {
+ GLRoot root = mActivity.getGLRoot();
+ PreparePhotoFallback task = new PreparePhotoFallback();
+ root.unlockRenderThread();
+ PhotoFallbackEffect anim;
+ try {
+ root.addOnGLIdleListener(task);
+ anim = task.get();
+ } finally {
+ root.lockRenderThread();
+ }
+ mActivity.getTransitionStore().put(
+ AlbumPage.KEY_RESUME_ANIMATION, anim);
+ }
+
@Override
public void onPause() {
mActivity.getGLRoot().unfreeze();
mHandler.removeMessages(MSG_UNFREEZE_GLROOT);
super.onPause();
+ if (isFinishing()) preparePhotoFallbackView();
mIsActive = false;
DetailsHelper.pause();
@@ -789,7 +830,7 @@ public class PhotoPage extends ActivityState implements
@Override
public MediaDetails getDetails() {
- return mModel.getCurrentMediaItem().getDetails();
+ return mModel.getMediaItem(0).getDetails();
}
@Override
diff --git a/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java b/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
index 4ee6a0144..179c93043 100644
--- a/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
+++ b/src/com/android/gallery3d/app/SinglePhotoDataAdapter.java
@@ -194,8 +194,8 @@ public class SinglePhotoDataAdapter extends TileImageViewAdapter
return mItem.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO;
}
- public MediaItem getCurrentMediaItem() {
- return mItem;
+ public MediaItem getMediaItem(int offset) {
+ return offset == 0 ? mItem : null;
}
public int getCurrentIndex() {
diff --git a/src/com/android/gallery3d/app/StateManager.java b/src/com/android/gallery3d/app/StateManager.java
index 096602a78..02e99762c 100644
--- a/src/com/android/gallery3d/app/StateManager.java
+++ b/src/com/android/gallery3d/app/StateManager.java
@@ -175,6 +175,7 @@ public class StateManager {
// Remove the top state.
mStack.pop();
+ state.mIsFinishing = true;
if (mIsResumed) state.onPause();
mContext.getGLRoot().setContentPane(null);
state.onDestroy();
diff --git a/src/com/android/gallery3d/app/TransitionStore.java b/src/com/android/gallery3d/app/TransitionStore.java
new file mode 100644
index 000000000..9c09e7ba5
--- /dev/null
+++ b/src/com/android/gallery3d/app/TransitionStore.java
@@ -0,0 +1,36 @@
+/*
+ * 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 java.util.HashMap;
+
+public class TransitionStore {
+ private HashMap<Object, Object> mStorage = new HashMap<Object, Object>();
+
+ public void put(Object key, Object value) {
+ mStorage.put(key, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T get(Object key) {
+ return (T) mStorage.get(key);
+ }
+
+ public void clear() {
+ mStorage.clear();
+ }
+}
diff --git a/src/com/android/gallery3d/ui/AlbumSlotRenderer.java b/src/com/android/gallery3d/ui/AlbumSlotRenderer.java
index 922e2c358..5f1e3a132 100644
--- a/src/com/android/gallery3d/ui/AlbumSlotRenderer.java
+++ b/src/com/android/gallery3d/ui/AlbumSlotRenderer.java
@@ -24,10 +24,14 @@ import com.android.gallery3d.data.MediaObject;
import com.android.gallery3d.data.Path;
public class AlbumSlotRenderer extends AbstractSlotRenderer {
- private static final int PLACEHOLDER_COLOR = 0xFF222222;
-
@SuppressWarnings("unused")
private static final String TAG = "AlbumView";
+
+ public interface SlotFilter {
+ public boolean acceptSlot(int index);
+ }
+
+ private static final int PLACEHOLDER_COLOR = 0xFF222222;
private static final int CACHE_SIZE = 96;
private AlbumSlidingWindow mDataWindow;
@@ -41,6 +45,8 @@ public class AlbumSlotRenderer extends AbstractSlotRenderer {
private Path mHighlightItemPath = null;
private boolean mInSelectionMode;
+ private SlotFilter mSlotFilter;
+
public AlbumSlotRenderer(GalleryActivity activity, SlotView slotView,
SelectionManager selectionManager) {
super((Context) activity);
@@ -92,6 +98,8 @@ public class AlbumSlotRenderer extends AbstractSlotRenderer {
@Override
public int renderSlot(GLCanvas canvas, int index, int pass, int width, int height) {
+ if (mSlotFilter != null && !mSlotFilter.acceptSlot(index)) return 0;
+
AlbumSlidingWindow.AlbumEntry entry = mDataWindow.get(index);
int renderRequestFlags = 0;
@@ -183,4 +191,8 @@ public class AlbumSlotRenderer extends AbstractSlotRenderer {
public void onSlotSizeChanged(int width, int height) {
// Do nothing
}
+
+ public void setSlotFilter(SlotFilter slotFilter) {
+ mSlotFilter = slotFilter;
+ }
}
diff --git a/src/com/android/gallery3d/ui/PhotoFallbackEffect.java b/src/com/android/gallery3d/ui/PhotoFallbackEffect.java
new file mode 100644
index 000000000..cd930bdd3
--- /dev/null
+++ b/src/com/android/gallery3d/ui/PhotoFallbackEffect.java
@@ -0,0 +1,177 @@
+/*
+ * 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.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(canvas)) 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;
+ }
+}
diff --git a/src/com/android/gallery3d/ui/PhotoView.java b/src/com/android/gallery3d/ui/PhotoView.java
index 7f3bee0a3..1610a1274 100644
--- a/src/com/android/gallery3d/ui/PhotoView.java
+++ b/src/com/android/gallery3d/ui/PhotoView.java
@@ -28,11 +28,10 @@ import android.view.animation.AccelerateInterpolator;
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.util.RangeArray;
-import java.util.Arrays;
-
public class PhotoView extends GLView {
@SuppressWarnings("unused")
private static final String TAG = "PhotoView";
@@ -55,6 +54,9 @@ public class PhotoView extends GLView {
// not avaiable, width = height = 0.
public void getImageSize(int offset, Size size);
+ // Returns the media item for the specified picture.
+ public MediaItem getMediaItem(int offset);
+
// Returns the rotation for the specified picture.
public int getImageRotation(int offset);
@@ -1337,4 +1339,33 @@ public class PhotoView extends GLView {
public void setListener(Listener listener) {
mListener = listener;
}
+
+ public Rect getPhotoRect(int index) {
+ return mPositionController.getPosition(index);
+ }
+
+
+ public PhotoFallbackEffect buildFallbackEffect(GLView root, GLCanvas canvas) {
+ Rect location = new Rect();
+ Utils.assertTrue(root.getBoundsOf(this, location));
+
+ Rect fullRect = bounds();
+ PhotoFallbackEffect effect = new PhotoFallbackEffect();
+ for (int i = -SCREEN_NAIL_MAX; i <= SCREEN_NAIL_MAX; ++i) {
+ MediaItem item = mModel.getMediaItem(i);
+ if (item == null) continue;
+ ScreenNail sc = mModel.getScreenNail(i);
+ if (sc == null) continue;
+ Rect rect = new Rect(getPhotoRect(i));
+ if (!Rect.intersects(fullRect, rect)) continue;
+ rect.offset(location.left, location.top);
+
+ RawTexture texture = new RawTexture(sc.getWidth(), sc.getHeight(), true);
+ canvas.beginRenderTarget(texture);
+ sc.draw(canvas, 0, 0, sc.getWidth(), sc.getHeight());
+ canvas.endRenderTarget();
+ effect.addEntry(item.getPath(), rect, texture);
+ }
+ return effect;
+ }
}
diff --git a/src/com/android/gallery3d/ui/SlotView.java b/src/com/android/gallery3d/ui/SlotView.java
index 0334c555b..88a2e0d3c 100644
--- a/src/com/android/gallery3d/ui/SlotView.java
+++ b/src/com/android/gallery3d/ui/SlotView.java
@@ -179,12 +179,6 @@ public class SlotView extends GLView {
if (mLayout.mSlotCount != 0) invalidate();
}
- public void startRestoringAnimation(int targetIndex) {
- mAnimation = new RestoringAnimation(targetIndex);
- mAnimation.start();
- if (mLayout.mSlotCount != 0) invalidate();
- }
-
private void updateScrollPosition(int position, boolean force) {
if (!force && (WIDE ? position == mScrollX : position == mScrollY)) return;
if (WIDE) {
@@ -378,22 +372,6 @@ public class SlotView extends GLView {
}
}
- public static class RestoringAnimation extends SlotAnimation {
- private static final int DISTANCE = 1000;
- private int mTargetIndex;
-
- public RestoringAnimation(int targetIndex) {
- mTargetIndex = targetIndex;
- }
-
- @Override
- public void apply(GLCanvas canvas, int slotIndex, Rect target) {
- if (slotIndex == mTargetIndex) {
- canvas.translate(0, 0, -DISTANCE * (1 - mProgress));
- }
- }
- }
-
// This Spec class is used to specify the size of each slot in the SlotView.
// There are two ways to do it:
//