diff options
author | Steve Kondik <steve@cyngn.com> | 2016-11-07 16:50:48 -0800 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2016-11-09 00:32:48 -0800 |
commit | f549631a977d44b3cf378cf51de108ab022c7315 (patch) | |
tree | 56f691c6df6825e8302824e07ef8c9f8ec398e87 /src/com | |
parent | 594d0fc312f957f0e9a1d64f658520f699e09b50 (diff) | |
download | android_packages_apps_Snap-f549631a977d44b3cf378cf51de108ab022c7315.tar.gz android_packages_apps_Snap-f549631a977d44b3cf378cf51de108ab022c7315.tar.bz2 android_packages_apps_Snap-f549631a977d44b3cf378cf51de108ab022c7315.zip |
Reenable left swipe for Filmstrip
* These commits are from the CameraNext application in COS.
* Credits: Ed Carrigan, Ed Mancebo, Wilhelm Fitzpatrick
Revert "SnapdragonCamera: Fix preview broken when coming back from gallery"
This reverts commit 5b8948f83a65e8f9bd1b419bd11511e48dc34887.
Revert "SnapdragonCamera: fix crash after photo deletion"
This reverts commit 171d2b253a752ca104ccf4a58f4e9d6d82bd7b28.
CameraNext: Fix camera crash on device unlock
This patch from the plugin branch also fixes CYNGNOS-1878
Due to the bug below, when the camera is fore-grounded when device
is unlocked, the SurfaceView is getting recreated, which caused it
to be in a weird state when we were trying to reattach the preview
to it.
-----
Fixed Black Screen On Back.
The issue was that mCameraView was not being populated when it
should have been (after it had been added to the view hierarchy).
The problem was the SurfaceView was being removed from the hierarchy
when it shouldn't have been.
Issue-Id: CP-129
(cherry picked from commit 4010462fe0b4cf1c15624cfca7d6a3d4d380613a)
CameraNext: avoid scaling camera preview in filmstrip
(cherry picked from commit 823ed983c4dccac3959635f1a14fcfe47cd7b120)
CameraNext: fade camera preview to black during film strip transition
Instead of scaling and translating the camera preview to make room for film strip
images, we leave the preview in place and cover it gradually with the black preview
cover.
CameraNext : Add offset calculation for left navbar
Also prevent preview from translating while hidden - was
causing occasional glimpses of it in filmstrip.
CameraNext : Ensure vertical/horizontal swipes don't conflict
Ensure that the user can't swipe horizontally while trying
to delete the image. Avoids all sorts of synching issues between
mViewItem and the data adapter since the buffer is trying to constantly
keep its center to be the current visible item
CYNGNOS-1069
CameraNext: fix crash on entering filmstrip via thumbnail tap
mVerticalViewId was getting initialized in onUp, but if filmstrip
was entered without a swipe, no onUp occurred. Fixed by directly
initializing the field on object creation.
CameraNext: Fix ZoomView in the filmstrip
The ZoomView was getting covered in the Z axis while scrolling.
issue-id: SAMBAR-862
Revert "SnapdragonCamera: fix camera preview broken when resume from gallery"
This reverts commit 0acc1f027637c4f0126883be68f97817d7306032.
Change-Id: If4dd591c5c752a7fa33c669c15875c0077446a37
Diffstat (limited to 'src/com')
-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 | ||||
-rw-r--r-- | 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 735c30abd..09ee0b595 100644 --- 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 281e814e2..fac8c5b1e 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) { |