summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/ui/FilmStripView.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/camera/ui/FilmStripView.java')
-rw-r--r--src/com/android/camera/ui/FilmStripView.java830
1 files changed, 0 insertions, 830 deletions
diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java
deleted file mode 100644
index 9aeb96ffd..000000000
--- a/src/com/android/camera/ui/FilmStripView.java
+++ /dev/null
@@ -1,830 +0,0 @@
-/*
- * Copyright (C) 2013 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.camera.ui;
-
-import android.animation.Animator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.Scroller;
-
-public class FilmStripView extends ViewGroup {
- private static final String TAG = FilmStripView.class.getSimpleName();
- private static final int BUFFER_SIZE = 5;
- // Horizontal padding of children.
- private static final int H_PADDING = 50;
- // Duration to go back to the first.
- private static final int DURATION_BACK_ANIM = 500;
- private static final int DURATION_SCROLL_TO_FILMSTRIP = 350;
- private static final int DURATION_GEOMETRY_ADJUST = 200;
- private static final float FILM_STRIP_SCALE = 0.6f;
- private static final float MAX_SCALE = 1f;
-
- private Context mContext;
- private FilmStripGestureRecognizer mGestureRecognizer;
- private DataAdapter mDataAdapter;
- private final Rect mDrawArea = new Rect();
-
- private int mCurrentInfo;
- private float mScale;
- private GeometryAnimator mGeometryAnimator;
- private int mCenterPosition = -1;
- private ViewInfo[] mViewInfo = new ViewInfo[BUFFER_SIZE];
-
- // This is used to resolve the misalignment problem when the device
- // orientation is changed. If the current item is in fullscreen, it might
- // be shifted because mCenterPosition is not adjusted with the orientation.
- // Set this to true when onSizeChanged is called to make sure we adjust
- // mCenterPosition accordingly.
- private boolean mAnchorPending;
-
- public interface ImageData {
- public static final int TYPE_NONE = 0;
- public static final int TYPE_CAMERA_PREVIEW = 1;
- public static final int TYPE_PHOTO = 2;
- public static final int TYPE_VIDEO = 3;
- public static final int TYPE_PHOTOSPHERE = 4;
-
- // The actions are defined bit-wise so we can use bit operations like
- // | and &.
- public static final int ACTION_NONE = 0;
- public static final int ACTION_PROMOTE = 1;
- public static final int ACTION_DEMOTE = 2;
-
- // SIZE_FULL means disgard the width or height when deciding the view size
- // of this ImageData, just use full screen size.
- public static final int SIZE_FULL = -2;
-
- // The values returned by getWidth() and getHeight() will be used for layout.
- public int getWidth();
- public int getHeight();
- public int getType();
- public boolean isActionSupported(int action);
- }
-
- public interface DataAdapter {
- public interface UpdateReporter {
- public boolean isDataRemoved(int id);
- public boolean isDataUpdated(int id);
- }
-
- public interface Listener {
- // Called when the whole data loading is done. No any assumption
- // on previous data.
- public void onDataLoaded();
- // Only some of the data is changed. The listener should check
- // if any thing needs to be updated.
- public void onDataUpdated(UpdateReporter reporter);
- public void onDataInserted(int dataID);
- public void onDataRemoved(int dataID);
- }
-
- public int getTotalNumber();
- public View getView(Context context, int id);
- public ImageData getImageData(int id);
- public void suggestSize(int w, int h);
-
- public void setListener(Listener listener);
- }
-
- // A helper class to tract and calculate the view coordination.
- private static class ViewInfo {
- private int mDataID;
- // the position of the left of the view in the whole filmstrip.
- private int mLeftPosition;
- private View mView;
- private float mOffsetY;
-
- public ViewInfo(int id, View v) {
- v.setPivotX(0f);
- v.setPivotY(0f);
- mDataID = id;
- mView = v;
- mLeftPosition = -1;
- mOffsetY = 0;
- }
-
- public int getID() {
- return mDataID;
- }
-
- public void setLeftPosition(int pos) {
- mLeftPosition = pos;
- }
-
- public int getLeftPosition() {
- return mLeftPosition;
- }
-
- public float getOffsetY() {
- return mOffsetY;
- }
-
- public void setOffsetY(float offset) {
- mOffsetY = offset;
- }
-
- public int getCenterX() {
- return mLeftPosition + mView.getWidth() / 2;
- }
-
- public View getView() {
- return mView;
- }
-
- private void layoutAt(int left, int top) {
- mView.layout(left, top, left + mView.getMeasuredWidth(),
- top + mView.getMeasuredHeight());
- }
-
- public void layoutIn(Rect drawArea, int refCenter, float scale) {
- // drawArea is where to layout in.
- // refCenter is the absolute horizontal position of the center of drawArea.
- int left = (int) (drawArea.centerX() + (mLeftPosition - refCenter) * scale);
- int top = (int) (drawArea.centerY() - (mView.getMeasuredHeight() / 2) * scale
- + mOffsetY);
- layoutAt(left, top);
- mView.setScaleX(scale);
- mView.setScaleY(scale);
- }
- }
-
- public FilmStripView(Context context) {
- super(context);
- init(context);
- }
-
- public FilmStripView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- public FilmStripView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init(context);
- }
-
- private void init(Context context) {
- mCurrentInfo = (BUFFER_SIZE - 1) / 2;
- // This is for positioning camera controller at the same place in
- // different orientations.
- setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
-
- setWillNotDraw(false);
- mContext = context;
- mScale = 1.0f;
- mGeometryAnimator = new GeometryAnimator(context);
- mGestureRecognizer =
- new FilmStripGestureRecognizer(context, new MyGestureReceiver());
- }
-
- public float getScale() {
- return mScale;
- }
-
- public boolean isAnchoredTo(int id) {
- if (mViewInfo[mCurrentInfo].getID() == id
- && mViewInfo[mCurrentInfo].getCenterX() == mCenterPosition) {
- return true;
- }
- return false;
- }
-
- public int getCurrentType() {
- if (mDataAdapter == null) return ImageData.TYPE_NONE;
- ViewInfo curr = mViewInfo[mCurrentInfo];
- if (curr == null) return ImageData.TYPE_NONE;
- return mDataAdapter.getImageData(curr.getID()).getType();
- }
-
- @Override
- public void onDraw(Canvas c) {
- if (mGeometryAnimator.hasNewGeometry()) {
- layoutChildren();
- }
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
- int boundWidth = MeasureSpec.getSize(widthMeasureSpec);
- int boundHeight = MeasureSpec.getSize(heightMeasureSpec);
- if (mDataAdapter != null) {
- mDataAdapter.suggestSize(boundWidth / 2, boundHeight / 2);
- }
-
- int wMode = View.MeasureSpec.EXACTLY;
- int hMode = View.MeasureSpec.EXACTLY;
-
- for (int i = 0; i < mViewInfo.length; i++) {
- ViewInfo info = mViewInfo[i];
- if (mViewInfo[i] == null) continue;
-
- int imageWidth = mDataAdapter.getImageData(info.getID()).getWidth();
- int imageHeight = mDataAdapter.getImageData(info.getID()).getHeight();
- if (imageWidth == ImageData.SIZE_FULL) imageWidth = boundWidth;
- if (imageHeight == ImageData.SIZE_FULL) imageHeight = boundHeight;
-
- int scaledWidth = boundWidth;
- int scaledHeight = boundHeight;
-
- if (imageWidth * scaledHeight > scaledWidth * imageHeight) {
- scaledHeight = imageHeight * scaledWidth / imageWidth;
- } else {
- scaledWidth = imageWidth * scaledHeight / imageHeight;
- }
- scaledWidth += H_PADDING * 2;
- mViewInfo[i].getView().measure(
- View.MeasureSpec.makeMeasureSpec(scaledWidth, wMode)
- , View.MeasureSpec.makeMeasureSpec(scaledHeight, hMode));
- }
- setMeasuredDimension(boundWidth, boundHeight);
- }
-
- private int findTheNearestView(int pointX) {
-
- int nearest = 0;
- // find the first non-null ViewInfo.
- for (; nearest < BUFFER_SIZE
- && (mViewInfo[nearest] == null || mViewInfo[nearest].getLeftPosition() == -1);
- nearest++);
- // no existing available ViewInfo
- if (nearest == BUFFER_SIZE) return -1;
- int min = Math.abs(pointX - mViewInfo[nearest].getCenterX());
-
- for (int infoID = nearest + 1;
- infoID < BUFFER_SIZE && mViewInfo[infoID] != null; infoID++) {
- // not measured yet.
- if (mViewInfo[infoID].getLeftPosition() == -1) continue;
-
- int c = mViewInfo[infoID].getCenterX();
- int dist = Math.abs(pointX - c);
- if (dist < min) {
- min = dist;
- nearest = infoID;
- }
- }
- return nearest;
- }
-
- private ViewInfo buildInfoFromData(int dataID) {
- View v = mDataAdapter.getView(mContext, dataID);
- if (v == null) return null;
- v.setPadding(H_PADDING, 0, H_PADDING, 0);
- ViewInfo info = new ViewInfo(dataID, v);
- addView(info.getView());
- return info;
- }
-
- // We try to keep the one closest to the center of the screen at position mCurrentInfo.
- private void stepIfNeeded() {
- int nearest = findTheNearestView(mCenterPosition);
- // no change made.
- if (nearest == -1 || nearest == mCurrentInfo) return;
-
- int adjust = nearest - mCurrentInfo;
- if (adjust > 0) {
- for (int k = 0; k < adjust; k++) {
- if (mViewInfo[k] != null) {
- removeView(mViewInfo[k].getView());
- }
- }
- for (int k = 0; k + adjust < BUFFER_SIZE; k++) {
- mViewInfo[k] = mViewInfo[k + adjust];
- }
- for (int k = BUFFER_SIZE - adjust; k < BUFFER_SIZE; k++) {
- mViewInfo[k] = null;
- if (mViewInfo[k - 1] != null)
- mViewInfo[k] = buildInfoFromData(mViewInfo[k - 1].getID() + 1);
- }
- } else {
- for (int k = BUFFER_SIZE - 1; k >= BUFFER_SIZE + adjust; k--) {
- if (mViewInfo[k] != null) {
- removeView(mViewInfo[k].getView());
- }
- }
- for (int k = BUFFER_SIZE - 1; k + adjust >= 0; k--) {
- mViewInfo[k] = mViewInfo[k + adjust];
- }
- for (int k = -1 - adjust; k >= 0; k--) {
- mViewInfo[k] = null;
- if (mViewInfo[k + 1] != null)
- mViewInfo[k] = buildInfoFromData(mViewInfo[k + 1].getID() - 1);
- }
- }
- }
-
- // Don't go out of bound.
- private void adjustCenterPosition() {
- ViewInfo curr = mViewInfo[mCurrentInfo];
- if (curr == null) return;
-
- if (curr.getID() == 0 && mCenterPosition < curr.getCenterX()) {
- mCenterPosition = curr.getCenterX();
- mGeometryAnimator.stopScroll();
- }
- if (curr.getID() == mDataAdapter.getTotalNumber() - 1
- && mCenterPosition > curr.getCenterX()) {
- mCenterPosition = curr.getCenterX();
- mGeometryAnimator.stopScroll();
- }
- }
-
- private void layoutChildren() {
- if (mAnchorPending) {
- mCenterPosition = mViewInfo[mCurrentInfo].getCenterX();
- mAnchorPending = false;
- }
-
- if (mGeometryAnimator.hasNewGeometry()) {
- mCenterPosition = mGeometryAnimator.getNewPosition();
- mScale = mGeometryAnimator.getNewScale();
- }
-
- adjustCenterPosition();
-
- mViewInfo[mCurrentInfo].layoutIn(mDrawArea, mCenterPosition, mScale);
-
- // images on the left
- for (int infoID = mCurrentInfo - 1; infoID >= 0; infoID--) {
- ViewInfo curr = mViewInfo[infoID];
- if (curr != null) {
- ViewInfo next = mViewInfo[infoID + 1];
- curr.setLeftPosition(
- next.getLeftPosition() - curr.getView().getMeasuredWidth());
- curr.layoutIn(mDrawArea, mCenterPosition, mScale);
- }
- }
-
- // images on the right
- for (int infoID = mCurrentInfo + 1; infoID < BUFFER_SIZE; infoID++) {
- ViewInfo curr = mViewInfo[infoID];
- if (curr != null) {
- ViewInfo prev = mViewInfo[infoID - 1];
- curr.setLeftPosition(
- prev.getLeftPosition() + prev.getView().getMeasuredWidth());
- curr.layoutIn(mDrawArea, mCenterPosition, mScale);
- }
- }
-
- stepIfNeeded();
- invalidate();
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- if (mViewInfo[mCurrentInfo] == null) return;
-
- mDrawArea.left = l;
- mDrawArea.top = t;
- mDrawArea.right = r;
- mDrawArea.bottom = b;
-
- layoutChildren();
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- if (w == oldw && h == oldh) return;
- if (mViewInfo[mCurrentInfo] != null && mScale == 1f
- && isAnchoredTo(mViewInfo[mCurrentInfo].getID())) {
- mAnchorPending = true;
- }
- }
-
- public void setDataAdapter(DataAdapter adapter) {
- mDataAdapter = adapter;
- mDataAdapter.suggestSize(getMeasuredWidth(), getMeasuredHeight());
- mDataAdapter.setListener(new DataAdapter.Listener() {
- @Override
- public void onDataLoaded() {
- reload();
- }
-
- @Override
- public void onDataUpdated(DataAdapter.UpdateReporter reporter) {
- update(reporter);
- }
-
- @Override
- public void onDataInserted(int dataID) {
- }
-
- @Override
- public void onDataRemoved(int dataID) {
- }
- });
- }
-
- public boolean isInCameraFullscreen() {
- return (isAnchoredTo(0) && mScale == 1f
- && getCurrentType() == ImageData.TYPE_CAMERA_PREVIEW);
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (isInCameraFullscreen()) return false;
- return true;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- mGestureRecognizer.onTouchEvent(ev);
- return true;
- }
-
- private void updateViewInfo(int infoID) {
- ViewInfo info = mViewInfo[infoID];
- removeView(info.getView());
- mViewInfo[infoID] = buildInfoFromData(info.getID());
- }
-
- // Some of the data is changed.
- private void update(DataAdapter.UpdateReporter reporter) {
- // No data yet.
- if (mViewInfo[mCurrentInfo] == null) {
- reload();
- return;
- }
-
- // Check the current one.
- ViewInfo curr = mViewInfo[mCurrentInfo];
- int dataID = curr.getID();
- if (reporter.isDataRemoved(dataID)) {
- mCenterPosition = -1;
- reload();
- return;
- }
- if (reporter.isDataUpdated(dataID)) {
- updateViewInfo(mCurrentInfo);
- }
-
- // Check left
- for (int i = mCurrentInfo - 1; i >= 0; i--) {
- curr = mViewInfo[i];
- if (curr != null) {
- dataID = curr.getID();
- if (reporter.isDataRemoved(dataID) || reporter.isDataUpdated(dataID)) {
- updateViewInfo(i);
- }
- } else {
- ViewInfo next = mViewInfo[i + 1];
- if (next != null) mViewInfo[i] = buildInfoFromData(next.getID() - 1);
- }
- }
-
- // Check right
- for (int i = mCurrentInfo + 1; i < BUFFER_SIZE; i++) {
- curr = mViewInfo[i];
- if (curr != null) {
- dataID = curr.getID();
- if (reporter.isDataRemoved(dataID) || reporter.isDataUpdated(dataID)) {
- updateViewInfo(i);
- }
- } else {
- ViewInfo prev = mViewInfo[i - 1];
- if (prev != null) mViewInfo[i] = buildInfoFromData(prev.getID() + 1);
- }
- }
- }
-
- // The whole data might be totally different. Flush all and load from the start.
- private void reload() {
- removeAllViews();
- int dataNumber = mDataAdapter.getTotalNumber();
- if (dataNumber == 0) return;
-
- int currentData = 0;
- int currentLeft = 0;
- mViewInfo[mCurrentInfo] = buildInfoFromData(currentData);
- mViewInfo[mCurrentInfo].setLeftPosition(currentLeft);
- if (getCurrentType() == ImageData.TYPE_CAMERA_PREVIEW
- && currentLeft == 0) {
- // we are in camera mode by default.
- mGeometryAnimator.lockPosition(currentLeft);
- }
- for (int i = 1; mCurrentInfo + i < BUFFER_SIZE || mCurrentInfo - i >= 0; i++) {
- int infoID = mCurrentInfo + i;
- if (infoID < BUFFER_SIZE && mViewInfo[infoID - 1] != null) {
- mViewInfo[infoID] = buildInfoFromData(mViewInfo[infoID - 1].getID() + 1);
- }
- infoID = mCurrentInfo - i;
- if (infoID >= 0 && mViewInfo[infoID + 1] != null) {
- mViewInfo[infoID] = buildInfoFromData(mViewInfo[infoID + 1].getID() - 1);
- }
- }
- layoutChildren();
- }
-
- // GeometryAnimator controls all the geometry animations. It passively
- // tells the geometry information on demand.
- private class GeometryAnimator implements
- ValueAnimator.AnimatorUpdateListener,
- Animator.AnimatorListener {
-
- private ValueAnimator mScaleAnimator;
- private boolean mHasNewScale;
- private float mNewScale;
-
- private Scroller mScroller;
- private boolean mHasNewPosition;
- private DecelerateInterpolator mDecelerateInterpolator;
-
- private boolean mCanStopScroll;
- private boolean mCanStopScale;
-
- private boolean mIsPositionLocked;
- private int mLockedPosition;
-
- private Runnable mPostAction;
-
- GeometryAnimator(Context context) {
- mScroller = new Scroller(context);
- mHasNewPosition = false;
- mScaleAnimator = new ValueAnimator();
- mScaleAnimator.addUpdateListener(GeometryAnimator.this);
- mScaleAnimator.addListener(GeometryAnimator.this);
- mDecelerateInterpolator = new DecelerateInterpolator();
- mCanStopScroll = true;
- mCanStopScale = true;
- mHasNewScale = false;
- }
-
- boolean hasNewGeometry() {
- mHasNewPosition = mScroller.computeScrollOffset();
- if (!mHasNewPosition) {
- mCanStopScroll = true;
- }
- // If the position is locked, then we always return true to force
- // the position value to use the locked value.
- return (mHasNewPosition || mHasNewScale || mIsPositionLocked);
- }
-
- // Always call hasNewGeometry() before getting the new scale value.
- float getNewScale() {
- if (!mHasNewScale) return mScale;
- mHasNewScale = false;
- return mNewScale;
- }
-
- // Always call hasNewGeometry() before getting the new position value.
- int getNewPosition() {
- if (mIsPositionLocked) return mLockedPosition;
- if (!mHasNewPosition) return mCenterPosition;
- return mScroller.getCurrX();
- }
-
- void lockPosition(int pos) {
- mIsPositionLocked = true;
- mLockedPosition = pos;
- }
-
- void unlockPosition() {
- if (mIsPositionLocked) {
- // only when the position is previously locked we set the current
- // position to make it consistent.
- mCenterPosition = mLockedPosition;
- mIsPositionLocked = false;
- }
- }
-
- void fling(int velocityX, int minX, int maxX) {
- if (!stopScroll() || mIsPositionLocked) return;
- mScroller.fling(mCenterPosition, 0, velocityX, 0, minX, maxX, 0, 0);
- }
-
- boolean stopScroll() {
- if (!mCanStopScroll) return false;
- mScroller.forceFinished(true);
- mHasNewPosition = false;
- return true;
- }
-
- boolean stopScale() {
- if (!mCanStopScale) return false;
- mScaleAnimator.cancel();
- mHasNewScale = false;
- return true;
- }
-
- void stop() {
- stopScroll();
- stopScale();
- }
-
- void scrollTo(int position, int duration, boolean interruptible) {
- if (!stopScroll() || mIsPositionLocked) return;
- mCanStopScroll = interruptible;
- stopScroll();
- mScroller.startScroll(mCenterPosition, 0, position - mCenterPosition,
- 0, duration);
- }
-
- void scrollTo(int position, int duration) {
- scrollTo(position, duration, true);
- }
-
- void scaleTo(float scale, int duration, boolean interruptible) {
- if (!stopScale()) return;
- mCanStopScale = interruptible;
- mScaleAnimator.setDuration(duration);
- mScaleAnimator.setFloatValues(mScale, scale);
- mScaleAnimator.setInterpolator(mDecelerateInterpolator);
- mScaleAnimator.start();
- mHasNewScale = true;
- }
-
- void scaleTo(float scale, int duration) {
- scaleTo(scale, duration, true);
- }
-
- void setPostAction(Runnable act) {
- mPostAction = act;
- }
-
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mHasNewScale = true;
- mNewScale = (Float) animation.getAnimatedValue();
- layoutChildren();
- }
-
- @Override
- public void onAnimationStart(Animator anim) {
- }
-
- @Override
- public void onAnimationEnd(Animator anim) {
- if (mPostAction != null) {
- mPostAction.run();
- mPostAction = null;
- }
- mCanStopScale = true;
- }
-
- @Override
- public void onAnimationCancel(Animator anim) {
- mPostAction = null;
- }
-
- @Override
- public void onAnimationRepeat(Animator anim) {
- }
- }
-
- private class MyGestureReceiver implements FilmStripGestureRecognizer.Listener {
- // Indicating the current trend of scaling is up (>1) or down (<1).
- private float mScaleTrend;
-
- @Override
- public boolean onSingleTapUp(float x, float y) {
- return false;
- }
-
- @Override
- public boolean onDoubleTap(float x, float y) {
- return false;
- }
-
- @Override
- public boolean onDown(float x, float y) {
- mGeometryAnimator.stop();
- return true;
- }
-
- @Override
- public boolean onScroll(float x, float y, float dx, float dy) {
- int deltaX = (int) (dx / mScale);
- if (deltaX > 0 && isInCameraFullscreen()) {
- mGeometryAnimator.unlockPosition();
- mGeometryAnimator.scaleTo(FILM_STRIP_SCALE, DURATION_GEOMETRY_ADJUST, false);
- }
-
- mCenterPosition += deltaX;
-
- // Vertical part. Promote or demote.
- int scaledDeltaY = (int) (dy / mScale);
-
- for (int i = 0; i < BUFFER_SIZE; i++) {
- if (mViewInfo[i] == null) continue;
- Rect hitRect = new Rect();
- View v = mViewInfo[i].getView();
- v.getHitRect(hitRect);
- if (hitRect.contains((int) x, (int) y)) {
- ImageData data = mDataAdapter.getImageData(mViewInfo[i].getID());
- if ((data.isActionSupported(ImageData.ACTION_DEMOTE) && dy > 0)
- || (data.isActionSupported(ImageData.ACTION_PROMOTE) && dy < 0)) {
- mViewInfo[i].setOffsetY(mViewInfo[i].getOffsetY() - dy);
- }
- break;
- }
- }
-
- layoutChildren();
- return true;
- }
-
- @Override
- public boolean onFling(float velocityX, float velocityY) {
- float scaledVelocityX = velocityX / mScale;
- if (isInCameraFullscreen() && scaledVelocityX < 0) {
- mGeometryAnimator.unlockPosition();
- mGeometryAnimator.scaleTo(FILM_STRIP_SCALE, DURATION_GEOMETRY_ADJUST, false);
- }
- ViewInfo info = mViewInfo[mCurrentInfo];
- int w = getWidth();
- if (info == null) return true;
- mGeometryAnimator.fling((int) -scaledVelocityX,
- // estimation of possible length on the left
- info.getLeftPosition() - info.getID() * w * 2,
- // estimation of possible length on the right
- info.getLeftPosition()
- + (mDataAdapter.getTotalNumber() - info.getID()) * w * 2);
- layoutChildren();
- return true;
- }
-
- @Override
- public boolean onScaleBegin(float focusX, float focusY) {
- if (isInCameraFullscreen()) return false;
- mScaleTrend = 1f;
- return true;
- }
-
- @Override
- public boolean onScale(float focusX, float focusY, float scale) {
- if (isInCameraFullscreen()) return false;
-
- mScaleTrend = mScaleTrend * 0.5f + scale * 0.5f;
- mScale *= scale;
- if (mScale <= FILM_STRIP_SCALE) mScale = FILM_STRIP_SCALE;
- if (mScale >= MAX_SCALE) mScale = MAX_SCALE;
- layoutChildren();
- return true;
- }
-
- @Override
- public void onScaleEnd() {
- if (mScaleTrend >= 1f) {
- if (mScale != 1f) {
- mGeometryAnimator.scaleTo(1f, DURATION_GEOMETRY_ADJUST, false);
- }
-
- if (getCurrentType() == ImageData.TYPE_CAMERA_PREVIEW) {
- if (isAnchoredTo(0)) {
- mGeometryAnimator.lockPosition(mViewInfo[mCurrentInfo].getCenterX());
- } else {
- mGeometryAnimator.scrollTo(
- mViewInfo[mCurrentInfo].getCenterX(),
- DURATION_GEOMETRY_ADJUST, false);
- mGeometryAnimator.setPostAction(mLockPositionRunnable);
- }
- }
- } else {
- // Scale down to film strip mode.
- if (mScale == FILM_STRIP_SCALE) {
- mGeometryAnimator.unlockPosition();
- return;
- }
- mGeometryAnimator.scaleTo(FILM_STRIP_SCALE, DURATION_GEOMETRY_ADJUST, false);
- mGeometryAnimator.setPostAction(mUnlockPositionRunnable);
- }
- }
-
- private Runnable mLockPositionRunnable = new Runnable() {
- @Override
- public void run() {
- mGeometryAnimator.lockPosition(mViewInfo[mCurrentInfo].getCenterX());
- }
- };
-
- private Runnable mUnlockPositionRunnable = new Runnable() {
- @Override
- public void run() {
- mGeometryAnimator.unlockPosition();
- }
- };
- }
-}