diff options
-rw-r--r-- | src/com/android/camera/BaseUI.java | 27 | ||||
-rw-r--r--[-rwxr-xr-x] | src/com/android/camera/CameraActivity.java | 73 | ||||
-rw-r--r-- | src/com/android/camera/CameraModule.java | 6 | ||||
-rwxr-xr-x | src/com/android/camera/CaptureModule.java | 15 | ||||
-rw-r--r-- | src/com/android/camera/CaptureUI.java | 14 | ||||
-rwxr-xr-x | src/com/android/camera/PhotoModule.java | 30 | ||||
-rw-r--r-- | src/com/android/camera/PhotoUI.java | 18 | ||||
-rw-r--r-- | src/com/android/camera/VideoModule.java | 14 | ||||
-rw-r--r-- | src/com/android/camera/VideoUI.java | 16 | ||||
-rw-r--r-- | src/com/android/camera/WideAnglePanoramaModule.java | 15 | ||||
-rw-r--r-- | src/com/android/camera/WideAnglePanoramaUI.java | 16 | ||||
-rw-r--r-- | src/com/android/camera/data/FixedFirstDataAdapter.java | 1 | ||||
-rw-r--r-- | src/com/android/camera/data/FixedLastDataAdapter.java | 1 | ||||
-rw-r--r-- | src/com/android/camera/data/LocalMediaData.java | 10 | ||||
-rw-r--r-- | src/com/android/camera/ui/FilmStripView.java | 167 |
15 files changed, 274 insertions, 149 deletions
diff --git a/src/com/android/camera/BaseUI.java b/src/com/android/camera/BaseUI.java new file mode 100644 index 000000000..7587c0511 --- /dev/null +++ b/src/com/android/camera/BaseUI.java @@ -0,0 +1,27 @@ +package com.android.camera; + +import android.view.View; + +/** we can start accumulating common code between UI classes here + * toward an eventual unification - WF */ +public abstract class BaseUI { + protected View mPreviewCover; + + public void showPreviewCover() { + if (mPreviewCover != null && mPreviewCover.getVisibility() != View.VISIBLE) { + mPreviewCover.setVisibility(View.VISIBLE); + } + } + + public void hidePreviewCover() { + if (mPreviewCover != null && mPreviewCover.getVisibility() != View.GONE) { + mPreviewCover.setVisibility(View.GONE); + } + } + + public void setPreviewCoverAlpha(float alpha) { + if (mPreviewCover != null) { + mPreviewCover.setAlpha(alpha); + } + } +} diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java index f7aa35a43..6b1d8d13f 100755..100644 --- a/src/com/android/camera/CameraActivity.java +++ b/src/com/android/camera/CameraActivity.java @@ -53,6 +53,7 @@ import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.graphics.Point; import android.net.Uri; import android.media.ThumbnailUtils; import android.nfc.NfcAdapter; @@ -228,8 +229,6 @@ public class CameraActivity extends Activity private ViewGroup mUndoDeletionBar; private boolean mIsUndoingDeletion = false; private boolean mIsEditActivityInProgress = false; - private View mPreviewCover; - private FrameLayout mPreviewContentLayout; private boolean mPaused = true; private boolean mHasCriticalPermissions; private boolean mForceReleaseCamera = false; @@ -263,6 +262,7 @@ public class CameraActivity extends Activity private WakeLock mWakeLock; private static final int REFOCUS_ACTIVITY_CODE = 1; + private int mDisplayWidth; private class MyOrientationEventListener extends OrientationEventListener { @@ -473,7 +473,6 @@ public class CameraActivity extends Activity if(!arePreviewControlsVisible()) { setPreviewControlsVisibility(true); CameraActivity.this.setSystemBarsVisibility(false); - mFilmStripView.getController().goToFullScreen(); } } @@ -577,6 +576,25 @@ public class CameraActivity extends Activity public void setSystemDecorsVisibility(boolean visible) { CameraActivity.this.setSystemBarsVisibility(visible); } + + private boolean stripHasScrolled = false; + + @Override + public void onFilmStripScroll(int offset) { + if (offset == 0) { + if (stripHasScrolled) { + mCurrentModule.hidePreviewCover(); + mCurrentModule.setPreviewCoverAlpha(1.0f); + } + } else { + // preview cover becomes fully opaque when the film strip has + // scrolled half the width of the screen + float rangePx = mDisplayWidth / 2f; + mCurrentModule.setPreviewCoverAlpha((float)Math.min(1.0, offset/rangePx)); + mCurrentModule.showPreviewCover(); + stripHasScrolled = true; + } + } }; public void gotoGallery() { @@ -604,45 +622,7 @@ public class CameraActivity extends Activity return; } } - try { - Intent intent = IntentHelper.getGalleryIntent(this); - intent.setAction(Intent.ACTION_VIEW); - intent.setData(uri); - intent.putExtra(KEY_FROM_SNAPCAM, true); - intent.putExtra(KEY_TOTAL_NUMBER, (adapter.getTotalNumber() -1)); - startActivity(intent); - } catch (ActivityNotFoundException ex) { - gotoReviewPhoto(uri); - } catch (IllegalArgumentException ex) { - gotoReviewPhoto(uri); - } - } - - private void gotoReviewPhoto(Uri uri) { - try { - Log.w(TAG, "Gallery not found"); - Intent intent = new Intent(CameraUtil.REVIEW_ACTION, uri); - startActivity(intent); - intent.putExtra(KEY_FROM_SNAPCAM, true); - intent.putExtra(KEY_TOTAL_NUMBER, getDataAdapter().getTotalNumber() - 1); - } catch (ActivityNotFoundException e) { - gotoViewPhoto(uri); - } catch (IllegalArgumentException e) { - gotoViewPhoto(uri); - } - } - - private void gotoViewPhoto(Uri uri) { - try { - Log.w(TAG, "Gallery not found"); - Intent intent = new Intent(Intent.ACTION_VIEW, uri); - startActivity(intent); - intent.putExtra(KEY_FROM_SNAPCAM, true); - } catch (ActivityNotFoundException e) { - Log.w(TAG, "No Activity could be found to open image or video"); - } catch (IllegalArgumentException e) { - Log.w(TAG, "No Activity could be found to open image or video"); - } + mFilmStripView.getController().goToNextItem(); } /** @@ -1496,6 +1476,8 @@ public class CameraActivity extends Activity mCameraPanoModuleRootView = rootLayout.findViewById(R.id.camera_pano_root); mCameraCaptureModuleRootView = rootLayout.findViewById(R.id.camera_capture_root); + calculateDisplayWidth(); + int moduleIndex = -1; if (MediaStore.INTENT_ACTION_VIDEO_CAMERA.equals(getIntent().getAction()) || MediaStore.ACTION_VIDEO_CAPTURE.equals(getIntent().getAction())) { @@ -1844,6 +1826,7 @@ public class CameraActivity extends Activity public void onConfigurationChanged(Configuration config) { super.onConfigurationChanged(config); mCurrentModule.onConfigurationChanged(config); + calculateDisplayWidth(); } @Override @@ -2083,6 +2066,12 @@ public class CameraActivity extends Activity prefs.edit().putInt(CameraSettings.KEY_STARTUP_MODULE_INDEX, moduleIndex).apply(); } + private void calculateDisplayWidth() { + Point size = new Point(); + getWindowManager().getDefaultDisplay().getSize(size); + mDisplayWidth = size.x; + } + /** * Sets the mCurrentModuleIndex, creates a new module instance for the given * index an sets it as mCurrentModule. diff --git a/src/com/android/camera/CameraModule.java b/src/com/android/camera/CameraModule.java index 9de16746d..7b591e1f9 100644 --- a/src/com/android/camera/CameraModule.java +++ b/src/com/android/camera/CameraModule.java @@ -74,4 +74,10 @@ public interface CameraModule { public void waitingLocationPermissionResult(boolean waiting); public void enableRecordingLocation(boolean enable); + + public void showPreviewCover(); + + public void hidePreviewCover(); + + public void setPreviewCoverAlpha(float alpha); } diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java index ee9a89133..7c6ccf8a1 100755 --- a/src/com/android/camera/CaptureModule.java +++ b/src/com/android/camera/CaptureModule.java @@ -3595,4 +3595,19 @@ public class CaptureModule implements CameraModule, PhotoController, buffer.get(bytes); return bytes; } + + @Override + public void showPreviewCover() { + mUI.showPreviewCover(); + } + + @Override + public void hidePreviewCover() { + mUI.hidePreviewCover(); + } + + @Override + public void setPreviewCoverAlpha(float alpha) { + mUI.setPreviewCoverAlpha(alpha); + } } diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java index 652861fdb..0fb0bdccb 100644 --- a/src/com/android/camera/CaptureUI.java +++ b/src/com/android/camera/CaptureUI.java @@ -80,7 +80,7 @@ import java.util.List; import java.util.Locale; import java.util.Set; -public class CaptureUI implements PreviewGestures.SingleTapListener, +public class CaptureUI extends BaseUI implements PreviewGestures.SingleTapListener, CameraManager.CameraFaceDetectionCallback, SettingsManager.Listener, ListMenu.Listener, @@ -138,7 +138,6 @@ public class CaptureUI implements PreviewGestures.SingleTapListener, private final FocusRing mFocusRing; private CameraActivity mActivity; private View mRootView; - private View mPreviewCover; private CaptureModule mModule; private AutoFitSurfaceView mSurfaceView; private AutoFitSurfaceView mSurfaceViewMono; @@ -1375,17 +1374,6 @@ public class CaptureUI implements PreviewGestures.SingleTapListener, return mMonoDummyAllocation.getSurface(); } - public void showPreviewCover() { - mPreviewCover.setVisibility(View.VISIBLE); - } - - public void hidePreviewCover() { - // Hide the preview cover if need. - if (mPreviewCover.getVisibility() != View.GONE) { - mPreviewCover.setVisibility(View.GONE); - } - } - private void initializeCountDown() { mActivity.getLayoutInflater().inflate(R.layout.count_down_to_capture, (ViewGroup) mRootView, true); diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java index f07d132c7..5eff069ab 100755 --- a/src/com/android/camera/PhotoModule.java +++ b/src/com/android/camera/PhotoModule.java @@ -4152,6 +4152,9 @@ public class PhotoModule @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void updateAutoFocusMoveCallback() { + if (mCameraDevice == null) { + return; + } if (mParameters.getFocusMode().equals(CameraUtil.FOCUS_MODE_CONTINUOUS_PICTURE) || mParameters.getFocusMode().equals(CameraUtil.FOCUS_MODE_MW_CONTINUOUS_PICTURE)) { mCameraDevice.setAutoFocusMoveCallback(mHandler, @@ -4161,6 +4164,13 @@ public class PhotoModule } } + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + private void disableAutoFocusMoveCallback() { + if (mCameraDevice != null) { + mCameraDevice.setAutoFocusMoveCallback(null, null); + } + } + // We separate the parameters into several subsets, so we can update only // the subsets actually need updating. The PREFERENCE set needs extra // locking because the preference can be changed from GLThread as well. @@ -5008,6 +5018,26 @@ public class PhotoModule } } + @Override + public void showPreviewCover() { + disableAutoFocusMoveCallback(); + stopFaceDetection(); + mUI.getFocusRing().stopFocusAnimations(); + mUI.showPreviewCover(); + } + + @Override + public void hidePreviewCover() { + mUI.hidePreviewCover(); + startFaceDetection(); + updateAutoFocusMoveCallback(); + } + + @Override + public void setPreviewCoverAlpha(float alpha) { + mUI.setPreviewCoverAlpha(alpha); + } + public void onMakeupLevelSync(String key, String value) { Log.d(TAG, "PhotoModule.onMakeupLevel(): key is " + key + ", value is " + value); diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java index 75e810d8b..3683c7a31 100644 --- a/src/com/android/camera/PhotoUI.java +++ b/src/com/android/camera/PhotoUI.java @@ -79,7 +79,7 @@ import com.android.camera.ui.ZoomRenderer; import com.android.camera.ui.focus.FocusRing; import com.android.camera.util.CameraUtil; -public class PhotoUI implements PieListener, +public class PhotoUI extends BaseUI implements PieListener, PreviewGestures.SingleTapListener, SurfaceHolder.Callback, CameraRootView.MyDisplayListener, @@ -143,7 +143,6 @@ public class PhotoUI implements PieListener, private boolean mOrientationResize; private boolean mPrevOrientationResize; - private View mPreviewCover; private RotateLayout mMenuLayout; private RotateLayout mSubMenuLayout; private LinearLayout mPreviewMenuLayout; @@ -479,6 +478,8 @@ public class PhotoUI implements PieListener, RectF r = new RectF(mSurfaceView.getLeft(), mSurfaceView.getTop(), mSurfaceView.getRight(), mSurfaceView.getBottom()); mController.onPreviewRectChanged(CameraUtil.rectFToRect(r)); + // Make sure preview cover is hidden if preview data is available. + hidePreviewCover(); } @Override @@ -816,7 +817,7 @@ public class PhotoUI implements PieListener, if (mPieRenderer != null) { mPieRenderer.setBlockFocus(!previewFocused); } - setShowMenu(previewFocused); + //setShowMenu(previewFocused); if (!previewFocused && mCountDownView != null) mCountDownView.cancelCountDown(); } @@ -1216,17 +1217,6 @@ public class PhotoUI implements PieListener, mNotSelectableToast.show(); } - public void showPreviewCover() { - mPreviewCover.setVisibility(View.VISIBLE); - } - - public void hidePreviewCover() { - // Hide the preview cover if need. - if (mPreviewCover.getVisibility() != View.GONE) { - mPreviewCover.setVisibility(View.GONE); - } - } - public boolean isPreviewCoverVisible() { if ((mPreviewCover != null) && (mPreviewCover.getVisibility() == View.VISIBLE)) { diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java index 55f2fbef7..401e4d7cd 100644 --- a/src/com/android/camera/VideoModule.java +++ b/src/com/android/camera/VideoModule.java @@ -3343,5 +3343,19 @@ public class VideoModule implements CameraModule, enableRecordingLocation(false); } + @Override + public void showPreviewCover() { + mUI.showPreviewCover(); + } + + @Override + public void hidePreviewCover() { + mUI.hidePreviewCover(); + } + + @Override + public void setPreviewCoverAlpha(float alpha) { + mUI.setPreviewCoverAlpha(alpha); + } } diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java index ecccb5a84..5dd51b585 100644 --- a/src/com/android/camera/VideoUI.java +++ b/src/com/android/camera/VideoUI.java @@ -64,7 +64,7 @@ import com.android.camera.ui.ZoomRenderer; import com.android.camera.ui.focus.FocusRing; import com.android.camera.util.CameraUtil; -public class VideoUI implements PieRenderer.PieListener, +public class VideoUI extends BaseUI implements PieRenderer.PieListener, PreviewGestures.SingleTapListener, CameraRootView.MyDisplayListener, SurfaceHolder.Callback, @@ -111,7 +111,6 @@ public class VideoUI implements PieRenderer.PieListener, private RotateLayout mSubMenuLayout; private LinearLayout mPreviewMenuLayout; - private View mPreviewCover; private SurfaceView mSurfaceView = null; private int mMaxPreviewWidth = 0; private int mMaxPreviewHeight = 0; @@ -138,16 +137,6 @@ public class VideoUI implements PieRenderer.PieListener, SURFACE_VIEW; } - public void showPreviewCover() { - mPreviewCover.setVisibility(View.VISIBLE); - } - - public void hidePreviewCover() { - if (mPreviewCover != null && mPreviewCover.getVisibility() != View.GONE) { - mPreviewCover.setVisibility(View.GONE); - } - } - public boolean isPreviewCoverVisible() { if ((mPreviewCover != null) && (mPreviewCover.getVisibility() == View.VISIBLE)) { @@ -1158,6 +1147,9 @@ public class VideoUI implements PieRenderer.PieListener, @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.v(TAG, "surfaceChanged: width = " + width + ", height = " + height); + + // Make sure preview cover is hidden if preview data is available. + hidePreviewCover(); } @Override diff --git a/src/com/android/camera/WideAnglePanoramaModule.java b/src/com/android/camera/WideAnglePanoramaModule.java index e8e9483a0..de2667034 100644 --- a/src/com/android/camera/WideAnglePanoramaModule.java +++ b/src/com/android/camera/WideAnglePanoramaModule.java @@ -1306,4 +1306,19 @@ public class WideAnglePanoramaModule public void onMediaSaveServiceConnected(MediaSaveService s) { // do nothing. } + + @Override + public void showPreviewCover() { + mUI.showPreviewCover(); + } + + @Override + public void hidePreviewCover() { + mUI.hidePreviewCover(); + } + + @Override + public void setPreviewCoverAlpha(float alpha) { + mUI.setPreviewCoverAlpha(alpha); + } } diff --git a/src/com/android/camera/WideAnglePanoramaUI.java b/src/com/android/camera/WideAnglePanoramaUI.java index 75defffa5..183c2aaed 100644 --- a/src/com/android/camera/WideAnglePanoramaUI.java +++ b/src/com/android/camera/WideAnglePanoramaUI.java @@ -59,7 +59,7 @@ import org.codeaurora.snapcam.R; /** * The UI of {@link WideAnglePanoramaModule}. */ -public class WideAnglePanoramaUI implements +public class WideAnglePanoramaUI extends BaseUI implements TextureView.SurfaceTextureListener, ShutterButton.OnShutterButtonListener, CameraRootView.MyDisplayListener, @@ -101,7 +101,6 @@ public class WideAnglePanoramaUI implements private int mIndicatorColorFast; private int mReviewBackground; private SurfaceTexture mSurfaceTexture; - private View mPreviewCover; private int mOrientation; private int mPreviewYOffset; @@ -271,11 +270,11 @@ public class WideAnglePanoramaUI implements mSurfaceTexture = surfaceTexture; mController.onPreviewUIReady(); mActivity.updateThumbnail(mThumbnail); + hidePreviewCover(); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) { - } @Override @@ -287,12 +286,7 @@ public class WideAnglePanoramaUI implements } @Override - public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { - // Make sure preview cover is hidden if preview data is available. - if (mPreviewCover.getVisibility() != View.GONE) { - mPreviewCover.setVisibility(View.GONE); - } - } + public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {} private void hideDirectionIndicators() { mLeftIndicator.setVisibility(View.INVISIBLE); @@ -554,10 +548,6 @@ public class WideAnglePanoramaUI implements ((CameraRootView) mRootView).removeDisplayChangeListener(); } - public void showPreviewCover() { - mPreviewCover.setVisibility(View.VISIBLE); - } - private class DialogHelper { DialogHelper() { diff --git a/src/com/android/camera/data/FixedFirstDataAdapter.java b/src/com/android/camera/data/FixedFirstDataAdapter.java index 03402da43..aa2025234 100644 --- a/src/com/android/camera/data/FixedFirstDataAdapter.java +++ b/src/com/android/camera/data/FixedFirstDataAdapter.java @@ -23,6 +23,7 @@ import android.view.View; import com.android.camera.ui.FilmStripView.DataAdapter; import com.android.camera.ui.FilmStripView.ImageData; +import org.codeaurora.snapcam.R; /** * A {@link LocalDataAdapter} which puts a {@link LocalData} fixed at the first diff --git a/src/com/android/camera/data/FixedLastDataAdapter.java b/src/com/android/camera/data/FixedLastDataAdapter.java index b7e2c45d3..4df0652e1 100644 --- a/src/com/android/camera/data/FixedLastDataAdapter.java +++ b/src/com/android/camera/data/FixedLastDataAdapter.java @@ -22,6 +22,7 @@ import android.net.Uri; import android.view.View; import com.android.camera.ui.FilmStripView; +import org.codeaurora.snapcam.R; /** * A {@link LocalDataAdapter} which puts a {@link LocalData} fixed at the last diff --git a/src/com/android/camera/data/LocalMediaData.java b/src/com/android/camera/data/LocalMediaData.java index bc3f09f18..e77578b16 100644 --- a/src/com/android/camera/data/LocalMediaData.java +++ b/src/com/android/camera/data/LocalMediaData.java @@ -206,12 +206,10 @@ public abstract class LocalMediaData implements LocalData { LocalDataAdapter adapter) { v.setScaleType(ImageView.ScaleType.FIT_XY); v.setImageDrawable(placeHolder); -/* - * Remove loading bitmaps for this adapter as we no longer use it. - */ -// BitmapLoadTask task = getBitmapLoadTask(v, decodeWidth, decodeHeight, -// ctx.getContentResolver(), adapter); -// task.execute(); + + BitmapLoadTask task = getBitmapLoadTask(v, decodeWidth, decodeHeight, + ctx.getContentResolver(), adapter); + task.execute(); return v; } diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java index e6e00ad56..3ac0bf6d9 100644 --- a/src/com/android/camera/ui/FilmStripView.java +++ b/src/com/android/camera/ui/FilmStripView.java @@ -87,6 +87,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { private MotionEvent mDown; private boolean mCheckToIntercept = true; private View mCameraView; + private ViewItem mCameraViewItem; private int mSlop; private TimeInterpolator mViewAnimInterpolator; @@ -106,8 +107,6 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { private boolean mSendToPreviewMenu; private boolean mSendToMenu; private boolean mReset; - private boolean mIsLoaded = false; - private boolean initialClampX = false; /** * Common interface for all images in the filmstrip. @@ -393,6 +392,12 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { * @param visible The visibility of the system decors */ public void setSystemDecorsVisibility(boolean visible); + + /** + * Called when film strip is scrolled + * @param offset positive distance scrolled from initial offset in pixels + */ + public void onFilmStripScroll(int offset); } /** @@ -435,6 +440,8 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { private ValueAnimator mTranslationXAnimator; + private boolean mIsPreview; + /** * Constructor. * @@ -442,7 +449,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { * @param v The {@code View} representing the data. */ public ViewItem( - int id, View v, ValueAnimator.AnimatorUpdateListener listener) { + int id, View v, ValueAnimator.AnimatorUpdateListener listener, boolean isPreview) { v.setPivotX(0f); v.setPivotY(0f); mDataId = id; @@ -451,6 +458,12 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { mViewArea = new RectF(); mTranslationXAnimator = new ValueAnimator(); mTranslationXAnimator.addUpdateListener(listener); + mIsPreview = isPreview; + + // Ordering of the children in the filmstrip can get shuffled around so we + // set the Z order explicity to make sure the film strip images are drawn on + // top of the camera + mView.setZ(mIsPreview ? 0 : 100); } /** Returns the data id from {@link DataAdapter}. */ @@ -508,11 +521,13 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { /** Sets the translation of Y regarding the view scale. */ public void setTranslationY(float transY, float scale) { + if(mIsPreview) return; // keep preview pinned in place mView.setTranslationY(transY * scale); } /** Sets the translation of X regarding the view scale. */ public void setTranslationX(float transX, float scale) { + if(mIsPreview) return; // keep preview pinned in place mView.setTranslationX(transX * scale); } @@ -583,20 +598,28 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { * @param scale The current scale of the filmstrip. */ public void layoutIn(Rect drawArea, int refCenter, float scale) { - final float translationX = (mTranslationXAnimator.isRunning() ? - (Float) mTranslationXAnimator.getAnimatedValue() : 0f); - int left = (int) (drawArea.centerX() + (mLeftPosition - refCenter + translationX) * scale); - int top = (int) (drawArea.centerY() - (mView.getMeasuredHeight() / 2) * scale); + final float adjustedScale = mIsPreview ? 1.0f : scale; + int left = 0; + int top = 0; + + if (!mIsPreview) { + final float translationX = (mTranslationXAnimator.isRunning() ? + (Float) mTranslationXAnimator.getAnimatedValue() : 0f); + left = (int) (drawArea.centerX() + (mLeftPosition - refCenter + translationX) + * adjustedScale); + top = (int) (drawArea.centerY() - (mView.getMeasuredHeight() / 2) * scale); + } + layoutAt(left, top); - mView.setScaleX(scale); - mView.setScaleY(scale); + mView.setScaleX(adjustedScale); + mView.setScaleY(adjustedScale); // update mViewArea for touch detection. int l = mView.getLeft(); int t = mView.getTop(); mViewArea.set(l, t, - l + mView.getMeasuredWidth() * scale, - t + mView.getMeasuredHeight() * scale); + l + mView.getMeasuredWidth() * adjustedScale, + t + mView.getMeasuredHeight() * adjustedScale); } /** Returns true if the point is in the view. */ @@ -904,10 +927,23 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { if (v == null) { return null; } - ViewItem item = new ViewItem(dataID, v, mViewItemUpdateListener); + + boolean isCameraView = false; + if (data instanceof LocalData) { + isCameraView = ((LocalData)data).getLocalDataType() + == LocalData.LOCAL_CAMERA_PREVIEW; + } + ViewItem item = new ViewItem(dataID, v, mViewItemUpdateListener, isCameraView); + if (isCameraView) { + mCameraViewItem = item; + } + v = item.getView(); if (v != mCameraView) { addView(item.getView()); + if (data.getViewType() == ImageData.VIEW_TYPE_STICKY) { + mCameraView = v; + } } else { v.setVisibility(View.VISIBLE); v.setAlpha(1f); @@ -999,7 +1035,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { } boolean stopScroll = false; - if (curr.getId() == 0 && (mCenterX < curr.getCenterX() || initialClampX) + if (curr.getId() == 0 && mCenterX < curr.getCenterX() && mDataIdOnUserScrolling <= 1) { // Stop at the first ViewItem. stopScroll = true; @@ -1048,6 +1084,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { } // ZoomView is a special case to always be in the front. bringChildToFront(mZoomView); + mZoomView.setElevation(Float.MAX_VALUE); } /** @@ -1277,8 +1314,12 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { return; } - mViewItem[mCurrentItem].setLeftPosition( - mCenterX - mViewItem[mCurrentItem].getView().getMeasuredWidth() / 2); + // If the layout changed, we need to adjust the current position so + // that if an item is centered before the change, it's still centered. + if (layoutChanged) { + mViewItem[mCurrentItem].setLeftPosition( + mCenterX - mViewItem[mCurrentItem].getView().getMeasuredWidth() / 2); + } if (mController.isZoomStarted()) { return; @@ -1424,6 +1465,15 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { stepIfNeeded(); updateBottomControls(false /* no forced update */); mLastItemId = getCurrentId(); + + if (mCameraViewItem != null && mListener != null) { + // mCenterX and the left position of each item are defined relative to each other. + // In order to figure out how much the user has scrolled, we need to subtract the + // two values and compare that to a fixed reference point. Since we know that + // the camera preview always starts at (0,0) we can use it as a reference point. + int offset = -1 * (mDrawArea.centerX() + mCameraViewItem.getLeftPosition() - mCenterX); + mListener.onFilmStripScroll(offset); + } } @Override @@ -1485,8 +1535,11 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { removeView(v); data.recycle(); } else { - v.setVisibility(View.INVISIBLE); if (mCameraView != null && mCameraView != v) { + // Not sure if this code is complete... logging a warning in case + // we encounter strange behavior related to this - EM + Log.w(TAG, "Encountered new camera view, removing old one"); + v.setVisibility(View.INVISIBLE); removeView(mCameraView); } mCameraView = v; @@ -1737,9 +1790,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { @Override public void onDataLoaded() { mActivity.updateThumbnail(false); - if (!mIsLoaded) - reload(); - mIsLoaded = true; + reload(); } @Override @@ -1755,12 +1806,17 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { return; } updateInsertion(dataID); - mActivity.updateThumbnail(true); + if (dataID == 1) { + mActivity.updateThumbnail(true); + } } @Override public void onDataRemoved(int dataID, ImageData data) { animateItemRemoval(dataID, data); + if (dataID == 1) { + mActivity.updateThumbnail(false); + } } }); } @@ -1787,7 +1843,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { if (!inFullScreen() || mController.isScrolling()) { return true; } - initialClampX = false; + if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { mCheckToIntercept = true; mDown = MotionEvent.obtain(ev); @@ -1814,7 +1870,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { && deltaX < mSlop * (-1)) { // intercept left swipe if (Math.abs(deltaX) >= Math.abs(deltaY) * 2) { - return false; + return true; } } } @@ -1823,6 +1879,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { @Override public boolean onTouchEvent(MotionEvent ev) { + mGestureRecognizer.onTouchEvent(ev); return true; } @@ -2040,18 +2097,17 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { } // Remove all views from the mViewItem buffer, except the camera view. - for (final ViewItem item : mViewItem) { - if (item != null) { - ImageData imageData = mDataAdapter.getImageData(item.getId()); - if (imageData != null) { - imageData.recycle(); - View v = item.getView(); - if (imageData.getViewType() != ImageData.VIEW_TYPE_STICKY) { - removeView(v); - } else { - mCameraView = v; - } - } + for (int i = 0; i < mViewItem.length; i++) { + if (mViewItem[i] == null) { + continue; + } + View v = mViewItem[i].getView(); + if (v != mCameraView) { + removeView(v); + } + ImageData imageData = mDataAdapter.getImageData(mViewItem[i].getId()); + if (imageData != null) { + imageData.recycle(); } } @@ -2078,7 +2134,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { // center of the display upon a reload. mCenterX = -1; mScale = FULL_SCREEN_SCALE; - initialClampX = true; + adjustChildZOrder(); invalidate(); @@ -2490,7 +2546,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { // TODO: Need to find a better way to toggle the visibility of views around // the current view. for (int i = 0; i < mCurrentItem; i++) { - if (i == mCurrentItem || mViewItem[i] == null) { + if (i == mCurrentItem || mViewItem[i] == null || mViewItem[i].mIsPreview) { continue; } mViewItem[i].getView().setVisibility(visible ? VISIBLE : INVISIBLE); @@ -2698,6 +2754,9 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { // Indicating the current trend of scaling is up (>1) or down (<1). private float mScaleTrend; private float mMaxScale; + private boolean mVerticalSwipe; + private boolean mHorizontalSwipe; + private int mVerticalViewId = -1; @Override public boolean onSingleTapUp(float x, float y) { @@ -2750,6 +2809,9 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { @Override public boolean onUp(float x, float y) { + mHorizontalSwipe = false; + mVerticalSwipe = false; + mVerticalViewId = -1; final ViewItem currItem = mViewItem[mCurrentItem]; if (currItem == null) { return false; @@ -2834,6 +2896,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { if (!mDataAdapter.canSwipeInFullScreen(currItem.getId())) { return false; } + hideZoomView(); // When image is zoomed in to be bigger than the screen if (mController.isZoomStarted()) { @@ -2852,25 +2915,31 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { mDataIdOnUserScrolling = mViewItem[mCurrentItem].getId(); } if (inFilmStrip()) { - if (Math.abs(dx) > Math.abs(dy)) { + if (Math.abs(dx) > Math.abs(dy) && !mVerticalSwipe) { mController.scroll(deltaX); - } else { + mHorizontalSwipe = true; + } else if (!mHorizontalSwipe) { + mVerticalSwipe = true; // Vertical part. Promote or demote. int hit = 0; - Rect hitRect = new Rect(); - for (; hit < BUFFER_SIZE; hit++) { - if (mViewItem[hit] == null) { - continue; + if (mVerticalViewId == -1) { + Rect hitRect = new Rect(); + for (; hit < BUFFER_SIZE; hit++) { + if (mViewItem[hit] == null || mViewItem[hit].mIsPreview) { + continue; + } + mViewItem[hit].getView().getHitRect(hitRect); + if (hitRect.contains((int) x, (int) y)) { + break; + } } - mViewItem[hit].getView().getHitRect(hitRect); - if (hitRect.contains((int) x, (int) y)) { - break; + if (hit == BUFFER_SIZE) { + return false; } + mVerticalViewId = hit; + } else { + hit = mVerticalViewId; } - if (hit == BUFFER_SIZE) { - return false; - } - ImageData data = mDataAdapter.getImageData(mViewItem[hit].getId()); float transY = mViewItem[hit].getScaledTranslationY(mScale) - dy / mScale; if (!data.isUIActionSupported(ImageData.ACTION_DEMOTE) && transY > 0f) { |