summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
authorSteve Kondik <steve@cyngn.com>2016-11-14 13:42:04 -0800
committerSteve Kondik <steve@cyngn.com>2016-11-17 23:54:30 -0800
commit80b47c20e4f35545fce802b6acfd4496810e16dd (patch)
treed39d9424302ba3aa831ba4f4ee504619db50d8d5 /src/com/android
parent605a3aaabb1120673a254a78cfc027772c79ca3e (diff)
downloadandroid_packages_apps_Snap-80b47c20e4f35545fce802b6acfd4496810e16dd.tar.gz
android_packages_apps_Snap-80b47c20e4f35545fce802b6acfd4496810e16dd.tar.bz2
android_packages_apps_Snap-80b47c20e4f35545fce802b6acfd4496810e16dd.zip
snap: Improve transitions
* Synchronize animation to filmstrip with input * More code cleanups, introduce BaseModule * Animations are hard Change-Id: Ie664bb2059a28b3a9f3957fb491ec28fede521e5
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/camera/BaseModule.java47
-rw-r--r--src/com/android/camera/BaseUI.java124
-rw-r--r--src/com/android/camera/CameraActivity.java54
-rw-r--r--src/com/android/camera/CameraModule.java4
-rw-r--r--src/com/android/camera/CaptureModule.java24
-rw-r--r--src/com/android/camera/CaptureUI.java7
-rw-r--r--src/com/android/camera/PhotoController.java3
-rw-r--r--[-rwxr-xr-x]src/com/android/camera/PhotoModule.java28
-rw-r--r--src/com/android/camera/PhotoUI.java10
-rw-r--r--src/com/android/camera/VideoModule.java19
-rw-r--r--src/com/android/camera/VideoUI.java7
-rw-r--r--src/com/android/camera/WideAnglePanoramaModule.java27
-rw-r--r--src/com/android/camera/ui/CameraControls.java453
-rw-r--r--src/com/android/camera/ui/FilmStripView.java6
14 files changed, 496 insertions, 317 deletions
diff --git a/src/com/android/camera/BaseModule.java b/src/com/android/camera/BaseModule.java
new file mode 100644
index 000000000..07b7cf043
--- /dev/null
+++ b/src/com/android/camera/BaseModule.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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;
+
+public abstract class BaseModule<T extends BaseUI> implements CameraModule {
+
+ // subclass initializes in init() for now
+ protected T mUI;
+
+ @Override
+ public void showPreviewCover() {
+ mUI.showPreviewCover();
+ }
+
+ @Override
+ public void hidePreviewCover() {
+ mUI.hidePreviewCover();
+ }
+
+ @Override
+ public void animateControls(float alpha) {
+ mUI.animateControls(alpha);
+ }
+
+ @Override
+ public boolean arePreviewControlsVisible() {
+ return mUI.arePreviewControlsVisible();
+ }
+
+ @Override
+ public void onPreviewFocusChanged(boolean previewFocused) {
+ mUI.onPreviewFocusChanged(previewFocused);
+ }
+}
diff --git a/src/com/android/camera/BaseUI.java b/src/com/android/camera/BaseUI.java
index 384c166e8..83ea01550 100644
--- a/src/com/android/camera/BaseUI.java
+++ b/src/com/android/camera/BaseUI.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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;
import android.graphics.Bitmap;
@@ -7,7 +22,6 @@ import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewStub;
import com.android.camera.ui.CameraControls;
import com.android.camera.ui.CaptureAnimationOverlay;
@@ -20,10 +34,14 @@ import org.codeaurora.snapcam.R;
import java.util.ArrayList;
import java.util.List;
-/** we can start accumulating common code between UI classes here
- * toward an eventual unification - WF */
+/**
+ * we can start accumulating common code between UI classes here
+ * toward an eventual unification - WF
+ */
public abstract class BaseUI {
+ private static final String TAG = "CAM_" + BaseUI.class.getSimpleName();
+
protected final CaptureAnimationOverlay mCaptureOverlay;
protected final View mPreviewCover;
@@ -39,6 +57,8 @@ public abstract class BaseUI {
protected int mOrientation = 0;
private boolean mOverlaysDisabled;
+ private float mPreviewCoverAlpha;
+
private final List<View> mDisabledViews = new ArrayList<>();
public BaseUI(CameraActivity activity, ViewGroup rootView, int layout) {
@@ -61,36 +81,56 @@ public abstract class BaseUI {
mBottomMargin = margins.second;
}
- private void calculateMargins(Point size) {
- int l = size.x > size.y ? size.x : size.y;
- int tm = mActivity.getResources().getDimensionPixelSize(R.dimen.preview_top_margin);
- int bm = mActivity.getResources().getDimensionPixelSize(R.dimen.preview_bottom_margin);
- mTopMargin = l / 4 * tm / (tm + bm);
- mBottomMargin = l / 4 - mTopMargin;
+ public void onPreviewFocusChanged(boolean previewFocused) {
+ if (previewFocused) {
+ showUI();
+ } else {
+ hideUI(true);
+ }
}
public void showPreviewCover() {
- if (mPreviewCover != null && mPreviewCover.getVisibility() != View.VISIBLE) {
- mPreviewCover.setVisibility(View.VISIBLE);
- disableOverlays();
+ if (mPreviewCover != null) {
+ synchronized (mPreviewCover) {
+ if (mPreviewCover.getVisibility() != View.VISIBLE) {
+ mPreviewCover.setAlpha(0.0f);
+ mPreviewCover.setVisibility(View.VISIBLE);
+ disableOverlays();
+ }
+ }
}
}
public void hidePreviewCover() {
- if (mPreviewCover != null && mPreviewCover.getVisibility() != View.GONE) {
- mPreviewCover.setVisibility(View.GONE);
- enableOverlays();
+ if (mPreviewCover != null) {
+ synchronized (mPreviewCover) {
+ if (mPreviewCover.getVisibility() != View.GONE) {
+ mPreviewCover.setAlpha(1.0f);
+ mPreviewCover.setVisibility(View.GONE);
+ enableOverlays();
+ }
+ }
}
}
- public void setPreviewCoverAlpha(float alpha) {
+ public void animateControls(float offset) {
if (mPreviewCover != null) {
- mPreviewCover.setAlpha(alpha);
+ synchronized (mPreviewCover) {
+ setPreviewCoverAlpha(offset, false);
+ if (mCameraControls != null) {
+ mCameraControls.setUIOffset(offset, true);
+ }
+ }
}
}
public boolean isPreviewCoverVisible() {
- return mPreviewCover != null && mPreviewCover.getVisibility() == View.VISIBLE;
+ if (mPreviewCover == null) {
+ return false;
+ }
+ synchronized (mPreviewCover) {
+ return mPreviewCover.getVisibility() == View.VISIBLE;
+ }
}
public void hideUI() {
@@ -98,14 +138,28 @@ public abstract class BaseUI {
}
protected void hideUI(boolean toBlack) {
- if (mCameraControls != null) {
- mCameraControls.hideUI(toBlack);
+ if (mPreviewCover != null) {
+ synchronized (mPreviewCover) {
+ if (toBlack) {
+ setPreviewCoverAlpha(1.0f, true);
+ } else {
+ setPreviewCoverAlpha(0.4f, true);
+ }
+ if (mCameraControls != null) {
+ mCameraControls.hideUI(toBlack);
+ }
+ }
}
}
protected void showUI() {
- if (mCameraControls != null) {
- mCameraControls.showUI();
+ if (mPreviewCover != null) {
+ synchronized (mPreviewCover) {
+ setPreviewCoverAlpha(0.0f, true);
+ if (mCameraControls != null) {
+ mCameraControls.showUI();
+ }
+ }
}
}
@@ -240,4 +294,30 @@ public abstract class BaseUI {
mRecordingTime.showTimeLapse(enable);
}
}
+
+ private void setPreviewCoverAlpha(float alpha, boolean animate) {
+ if (mPreviewCover == null) {
+ return;
+ }
+ synchronized (mPreviewCover) {
+ if (alpha == mPreviewCoverAlpha || alpha < 0.0f || alpha > 1.0f) {
+ return;
+ }
+
+ if (alpha == 0.0f) {
+ hidePreviewCover();
+ } else {
+ showPreviewCover();
+ }
+
+ if (animate) {
+ mPreviewCover.animate().cancel();
+ mPreviewCover.animate().alpha(alpha).start();
+ } else {
+ mPreviewCover.setAlpha(alpha);
+ }
+
+ mPreviewCoverAlpha = alpha;
+ }
+ }
}
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 570fad1c4..b0aad3640 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -216,7 +216,6 @@ public class CameraActivity extends Activity
private final Object mStorageSpaceLock = new Object();
private long mStorageSpaceBytes = Storage.LOW_STORAGE_THRESHOLD_BYTES;
private boolean mSecureCamera;
- private boolean mInCameraApp = true;
// Keep track of powershutter state
public static boolean mPowerShutter = false;
// Keep track of max brightness state
@@ -267,6 +266,8 @@ public class CameraActivity extends Activity
private static final int REFOCUS_ACTIVITY_CODE = 1;
private int mDisplayWidth;
+ private boolean mShowingFilmstrip = false;
+
private class MyOrientationEventListener
extends OrientationEventListener {
public MyOrientationEventListener(Context context) {
@@ -473,8 +474,7 @@ public class CameraActivity extends Activity
return;
}
- if(!arePreviewControlsVisible()) {
- setPreviewControlsVisibility(true);
+ if (!arePreviewControlsVisible()) {
CameraActivity.this.setSystemBarsVisibility(false);
}
}
@@ -485,10 +485,6 @@ public class CameraActivity extends Activity
// For now, We ignore all items that are not the camera preview.
return;
}
-
- if (arePreviewControlsVisible()) {
- setPreviewControlsVisibility(false);
- }
}
@Override
@@ -525,7 +521,7 @@ public class CameraActivity extends Activity
LocalData.LOCAL_CAMERA_PREVIEW;
if (!focused) {
if (isCameraID) {
- mCurrentModule.onPreviewFocusChanged(false);
+ //mCurrentModule.onPreviewFocusChanged(false);
CameraActivity.this.setSystemBarsVisibility(true);
}
hidePanoStitchingProgress();
@@ -580,25 +576,18 @@ public class CameraActivity extends Activity
CameraActivity.this.setSystemBarsVisibility(visible);
}
- private float previewCoverAlpha = 1.0f;
-
- private void setPreviewCoverAlpha(float alpha) {
- if (alpha == previewCoverAlpha || alpha < 0.0f || alpha > 1.0f) {
- return;
- }
- mCurrentModule.setPreviewCoverAlpha(alpha);
- if (alpha == 0.0f) {
- mCurrentModule.hidePreviewCover();
- } else if (previewCoverAlpha == 0.0f) {
- mCurrentModule.showPreviewCover();
- }
- previewCoverAlpha = alpha;
- }
-
@Override
public void onFilmStripScroll(int offset) {
float rangePx = mDisplayWidth / 2f;
- setPreviewCoverAlpha((float)Math.min(1.0, offset/rangePx));
+ if (offset >= rangePx && !mShowingFilmstrip) {
+ mShowingFilmstrip = true;
+ setPreviewControlsVisibility(false);
+ } else if (offset == 0 && mShowingFilmstrip) {
+ mShowingFilmstrip = false;
+ setPreviewControlsVisibility(true);
+ } else {
+ mCurrentModule.animateControls((float) Math.min(1.0, offset / rangePx));
+ }
}
};
@@ -1771,6 +1760,7 @@ public class CameraActivity extends Activity
super.onResume();
mPaused = false;
mCurrentModule.onResumeAfterSuper();
+ mCurrentModule.animateControls(0);
setSwipingEnabled(true);
@@ -1963,7 +1953,7 @@ public class CameraActivity extends Activity
if (!CameraUtil.hasCameraKey()) {
mPowerShutter = val.equals(CameraSettings.VALUE_ON);
}
- if (mPowerShutter && mInCameraApp) {
+ if (mPowerShutter && arePreviewControlsVisible()) {
getWindow().addPrivateFlags(
WindowManager.LayoutParams.PRIVATE_FLAG_PREVENT_POWER_KEY);
} else {
@@ -1981,7 +1971,7 @@ public class CameraActivity extends Activity
mMaxBrightness = val.equals(CameraSettings.VALUE_ON);
- if (mMaxBrightness && mInCameraApp) {
+ if (mMaxBrightness && arePreviewControlsVisible()) {
params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL;
} else {
params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
@@ -2049,7 +2039,7 @@ public class CameraActivity extends Activity
}
public boolean isInCameraApp() {
- return mInCameraApp;
+ return arePreviewControlsVisible();
}
@Override
@@ -2382,14 +2372,10 @@ public class CameraActivity extends Activity
* Show or hide the {@link CameraControls} using the current module's
* implementation of {@link #onPreviewFocusChanged}.
*
- * @param showControls whether to show camera controls.
+ * @param visible whether to show camera controls.
*/
- private void setPreviewControlsVisibility(boolean showControls) {
- mCurrentModule.onPreviewFocusChanged(showControls);
-
- // controls are only shown when the camera app is active
- // so we can assume to fetch this information from here
- mInCameraApp = showControls;
+ private void setPreviewControlsVisibility(boolean visible) {
+ mCurrentModule.onPreviewFocusChanged(visible);
}
// Accessor methods for getting latency times used in performance testing
diff --git a/src/com/android/camera/CameraModule.java b/src/com/android/camera/CameraModule.java
index 7b591e1f9..a3a88fe41 100644
--- a/src/com/android/camera/CameraModule.java
+++ b/src/com/android/camera/CameraModule.java
@@ -21,7 +21,7 @@ import android.content.res.Configuration;
import android.view.KeyEvent;
import android.view.View;
-public interface CameraModule {
+public interface CameraModule<T extends BaseUI> {
public void init(CameraActivity activity, View frame);
@@ -79,5 +79,5 @@ public interface CameraModule {
public void hidePreviewCover();
- public void setPreviewCoverAlpha(float alpha);
+ public void animateControls(float offset);
}
diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java
index 8aea9cd35..9ccfc6e59 100644
--- a/src/com/android/camera/CaptureModule.java
+++ b/src/com/android/camera/CaptureModule.java
@@ -104,11 +104,12 @@ import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
-public class CaptureModule implements CameraModule, PhotoController,
+public class CaptureModule extends BaseModule<CaptureUI> implements PhotoController,
MediaSaveService.Listener, ClearSightImageProcessor.Callback,
SettingsManager.Listener, LocationManager.Listener,
CountDownView.OnCountDownFinishedListener,
PauseButton.OnPauseButtonListener {
+
public static final int DUAL_MODE = 0;
public static final int BAYER_MODE = 1;
public static final int MONO_MODE = 2;
@@ -200,7 +201,6 @@ public class CaptureModule implements CameraModule, PhotoController,
private boolean[] mCameraOpened = new boolean[MAX_NUM_CAM];
private CameraDevice[] mCameraDevice = new CameraDevice[MAX_NUM_CAM];
private String[] mCameraId = new String[MAX_NUM_CAM];
- private CaptureUI mUI;
private CameraActivity mActivity;
private List<Integer> mCameraIdList;
private float mZoomValue = 1f;
@@ -1694,11 +1694,6 @@ public class CaptureModule implements CameraModule, PhotoController,
}
@Override
- public void onPreviewFocusChanged(boolean previewFocused) {
- mUI.onPreviewFocusChanged(previewFocused);
- }
-
- @Override
public void onPauseBeforeSuper() {
mPaused = true;
mUI.onPause();
@@ -3516,19 +3511,4 @@ 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 e1f6dea3f..3a4d24c8e 100644
--- a/src/com/android/camera/CaptureUI.java
+++ b/src/com/android/camera/CaptureUI.java
@@ -1424,11 +1424,8 @@ public class CaptureUI extends BaseUI implements PreviewGestures.SingleTapListen
}
public void onPreviewFocusChanged(boolean previewFocused) {
- if (previewFocused) {
- showUI();
- } else {
- hideUI(true);
- }
+ super.onPreviewFocusChanged(previewFocused);
+
if (mFaceView != null) {
mFaceView.setBlockDraw(!previewFocused);
}
diff --git a/src/com/android/camera/PhotoController.java b/src/com/android/camera/PhotoController.java
index 887f0d375..415eb6e7f 100644
--- a/src/com/android/camera/PhotoController.java
+++ b/src/com/android/camera/PhotoController.java
@@ -22,7 +22,8 @@ import android.view.View;
import com.android.camera.ShutterButton.OnShutterButtonListener;
-public interface PhotoController extends OnShutterButtonListener {
+public interface PhotoController extends CameraModule, ShutterButton.OnShutterButtonListener {
+
public static final int INIT = -1;
public static final int PREVIEW_STOPPED = 0;
public static final int IDLE = 1; // preview is active
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 69976fdc3..14e358b88 100755..100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -110,8 +110,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.os.SystemProperties;
-public class PhotoModule
- implements CameraModule,
+public class PhotoModule extends BaseModule<PhotoUI> implements
PhotoController,
FocusOverlayManager.Listener,
CameraPreference.OnPreferenceChangedListener,
@@ -171,8 +170,6 @@ public class PhotoModule
private boolean mPaused;
private View mRootView;
- private PhotoUI mUI;
-
// The activity is going to switch to the specified camera id. This is
// needed because texture copy is done in GL thread. -1 means camera is not
// switching.
@@ -4970,23 +4967,11 @@ public class PhotoModule
mHeading += 360;
}
}
- @Override
- public void onPreviewFocusChanged(boolean previewFocused) {
- mUI.onPreviewFocusChanged(previewFocused);
- }
+
// TODO: Delete this function after old camera code is removed
@Override
public void onRestorePreferencesClicked() {}
-/*
- * Provide a mapping for Jpeg encoding quality levels
- * from String representation to numeric representation.
- */
- @Override
- public boolean arePreviewControlsVisible() {
- return mUI.arePreviewControlsVisible();
- }
-
// For debugging only.
public void setDebugUri(Uri uri) {
mDebugUri = uri;
@@ -5025,24 +5010,19 @@ public class PhotoModule
@Override
public void showPreviewCover() {
+ super.showPreviewCover();
disableAutoFocusMoveCallback();
stopFaceDetection();
mUI.getFocusRing().stopFocusAnimations();
- mUI.showPreviewCover();
}
@Override
public void hidePreviewCover() {
- mUI.hidePreviewCover();
+ super.showPreviewCover();
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 f71eb31cc..96dda6f8a 100644
--- a/src/com/android/camera/PhotoUI.java
+++ b/src/com/android/camera/PhotoUI.java
@@ -26,7 +26,6 @@ import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.hardware.Camera;
-import android.hardware.Camera.Face;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;
@@ -703,11 +702,8 @@ public class PhotoUI extends BaseUI implements PieListener,
}
public void onPreviewFocusChanged(boolean previewFocused) {
- if (previewFocused) {
- showUI();
- } else {
- hideUI(true);
- }
+ super.onPreviewFocusChanged(previewFocused);
+
if (mFaceView != null) {
mFaceView.setBlockDraw(!previewFocused);
}
@@ -1165,7 +1161,7 @@ public class PhotoUI extends BaseUI implements PieListener,
}
@Override
- public void onFaceDetection(Face[] faces, CameraManager.CameraProxy camera) {
+ public void onFaceDetection(Camera.Face[] faces, CameraManager.CameraProxy camera) {
mFaceView.setFaces(faces);
}
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 049ce0a46..b528a7625 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -84,7 +84,7 @@ import java.util.List;
import java.util.HashMap;
import java.lang.reflect.Method;
-public class VideoModule implements CameraModule,
+public class VideoModule extends BaseModule<VideoUI> implements
VideoController,
FocusOverlayManager.Listener,
CameraPreference.OnPreferenceChangedListener,
@@ -208,7 +208,6 @@ public class VideoModule implements CameraModule,
private LocationManager mLocationManager;
private int mPendingSwitchCameraId;
private final Handler mHandler = new MainHandler();
- private VideoUI mUI;
private CameraProxy mCameraDevice;
private static final String KEY_PREVIEW_FORMAT = "preview-format";
private static final String FORMAT_NV12_VENUS = "nv12-venus";
@@ -3154,16 +3153,11 @@ public class VideoModule implements CameraModule,
@Override
public void onPreviewFocusChanged(boolean previewFocused) {
- mUI.onPreviewFocusChanged(previewFocused);
+ super.onPreviewFocusChanged(previewFocused);
mHandler.sendEmptyMessageDelayed(HANDLE_FLASH_TORCH_DELAY, 800);
mPreviewFocused = previewFocused;
}
- @Override
- public boolean arePreviewControlsVisible() {
- return mUI.arePreviewControlsVisible();
- }
-
private final class JpegPictureCallback implements CameraPictureCallback {
Location mLocation;
@@ -3344,20 +3338,15 @@ public class VideoModule implements CameraModule,
@Override
public void showPreviewCover() {
+ super.showPreviewCover();
stopFaceDetection();
mUI.getFocusRing().stopFocusAnimations();
- mUI.showPreviewCover();
}
@Override
public void hidePreviewCover() {
- mUI.hidePreviewCover();
+ super.hidePreviewCover();
startFaceDetection();
}
-
- @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 467990882..f2b725e85 100644
--- a/src/com/android/camera/VideoUI.java
+++ b/src/com/android/camera/VideoUI.java
@@ -885,11 +885,8 @@ public class VideoUI extends BaseUI implements PieRenderer.PieListener,
}
public void onPreviewFocusChanged(boolean previewFocused) {
- if (previewFocused) {
- showUI();
- } else {
- hideUI(true);
- }
+ super.onPreviewFocusChanged(previewFocused);
+
if (mGestures != null) {
mGestures.setEnabled(previewFocused);
}
diff --git a/src/com/android/camera/WideAnglePanoramaModule.java b/src/com/android/camera/WideAnglePanoramaModule.java
index 9b712c6bf..9687be8af 100644
--- a/src/com/android/camera/WideAnglePanoramaModule.java
+++ b/src/com/android/camera/WideAnglePanoramaModule.java
@@ -65,8 +65,8 @@ import java.util.TimeZone;
/**
* Activity to handle panorama capturing.
*/
-public class WideAnglePanoramaModule
- implements CameraModule, WideAnglePanoramaController,
+public class WideAnglePanoramaModule extends BaseModule<WideAnglePanoramaUI> implements
+ WideAnglePanoramaController,
SurfaceTexture.OnFrameAvailableListener {
public static final int DEFAULT_SWEEP_ANGLE = 160;
@@ -93,7 +93,6 @@ public class WideAnglePanoramaModule
private static final boolean DEBUG = false;
private ContentResolver mContentResolver;
- private WideAnglePanoramaUI mUI;
private MosaicPreviewRenderer mMosaicPreviewRenderer;
private Object mRendererLock = new Object();
@@ -358,13 +357,8 @@ public class WideAnglePanoramaModule
@Override
public void onPreviewFocusChanged(boolean previewFocused) {
+ super.onPreviewFocusChanged(previewFocused);
mPreviewFocused = previewFocused;
- mUI.onPreviewFocusChanged(previewFocused);
- }
-
- @Override
- public boolean arePreviewControlsVisible() {
- return mUI.arePreviewControlsVisible();
}
/**
@@ -1304,19 +1298,4 @@ 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/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java
index 740a07ea1..9102db3c3 100644
--- a/src/com/android/camera/ui/CameraControls.java
+++ b/src/com/android/camera/ui/CameraControls.java
@@ -21,6 +21,7 @@ import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
@@ -31,6 +32,7 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.MathUtils;
import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
@@ -49,15 +51,14 @@ import com.android.camera.util.CameraUtil;
import org.codeaurora.snapcam.R;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
public class CameraControls extends RotatableLayout {
private static final String TAG = "CAM_Controls";
- private LinearLayout mTopBar;
- private LinearLayout mBottomBar;
-
private ShutterButton mShutter;
private View mVideoShutter;
private ModuleSwitcher mSwitcher;
@@ -69,6 +70,9 @@ public class CameraControls extends RotatableLayout {
private View mFrontBackSwitcher;
private View mMenu;
+ private ViewGroup mTopBar;
+ private ViewGroup mBottomBar;
+
private View mReviewDoneButton;
private View mReviewCancelButton;
private View mReviewRetakeButton;
@@ -77,11 +81,6 @@ public class CameraControls extends RotatableLayout {
private static final int WIDTH_GRID = 5;
private static final int HEIGHT_GRID = 7;
- private boolean mHidden = false;
- private AnimatorSet mAnimator = null;
- private boolean mFullyHidden = false;
-
- private static final int ANIME_DURATION = 300;
private boolean mHideRemainingPhoto = false;
private LinearLayout mRemainingPhotos;
@@ -98,45 +97,7 @@ public class CameraControls extends RotatableLayout {
private int mModuleIndex = -1;
- AnimatorListener outlistener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- enableTouch(false);
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- setChildrenVisibility(mBottomBar, false);
- if (mFullyHidden) {
- setChildrenVisibility(mTopBar, false);
- setVisibility(View.INVISIBLE);
- }
- }
- };
-
- AnimatorListener inlistener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- setChildrenVisibility(mBottomBar, true);
- if (mFullyHidden) {
- setChildrenVisibility(mTopBar, true);
- setVisibility(View.VISIBLE);
- mFullyHidden = false;
- }
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- enableTouch(true);
- }
- };
-
- private void setChildrenVisibility(ViewGroup parent, boolean visible) {
- for (int i = 0; i < parent.getChildCount(); i++) {
- View v = parent.getChildAt(i);
- if (v.getVisibility() != View.GONE) {
- v.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
- }
- }
- }
+ private final AnimationHelper mAnimationHelper;
public CameraControls(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -146,9 +107,11 @@ public class CameraControls extends RotatableLayout {
setMeasureAllChildren(true);
- Pair<Integer, Integer> margins = CameraUtil.calculateMargins((Activity)context);
+ Pair<Integer, Integer> margins = CameraUtil.calculateMargins((Activity) context);
mTopMargin = margins.first;
mBottomMargin = margins.second;
+
+ mAnimationHelper = new AnimationHelper();
}
public CameraControls(Context context) {
@@ -156,12 +119,21 @@ public class CameraControls extends RotatableLayout {
}
public boolean isAnimating() {
- return mAnimator != null && mAnimator.isRunning();
+ return mAnimationHelper.isAnimating();
}
- public void enableTouch(boolean enable) {
- Log.d(TAG, "ENABLE TOUCH " + enable + " mViews.size=" + mViews.size());
+ public void reset() { mAnimationHelper.reset(); }
+ private void setChildrenVisibility(ViewGroup parent, boolean visible) {
+ for (int i = 0; i < parent.getChildCount(); i++) {
+ View v = parent.getChildAt(i);
+ if (v.getVisibility() != View.GONE) {
+ v.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+ }
+ }
+ }
+
+ public void enableTouch(boolean enable) {
synchronized (mViews) {
for (View v : mViews) {
if (v.getVisibility() != View.GONE) {
@@ -227,7 +199,7 @@ public class CameraControls extends RotatableLayout {
mShutter.addOnShutterButtonListener(mShutterListener);
- mSwitcher.setSwitchListener((CameraActivity)getContext());
+ mSwitcher.setSwitchListener((CameraActivity) getContext());
mSwitcher.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@@ -357,19 +329,6 @@ public class CameraControls extends RotatableLayout {
});
}
- @Override
- public void onAttachedToWindow() {
- super.onAttachedToWindow();
- mTopBar.setTranslationX(0);
- mTopBar.setTranslationY(0);
- mBottomBar.setTranslationX(0);
- mBottomBar.setTranslationY(0);
- mHidden = false;
- mFullyHidden = false;
- setChildrenVisibility(mTopBar, true);
- setChildrenVisibility(mBottomBar, true);
- }
-
private void setLocation(int w, int h) {
int rotation = getUnifiedRotation();
layoutToast(mRefocusToast, w, h, rotation);
@@ -422,103 +381,21 @@ public class CameraControls extends RotatableLayout {
mAutoHdrNotice.setVisibility(enabled ? View.VISIBLE : View.GONE);
}
- private ObjectAnimator getViewAnimation(View v, float distance, boolean vertical) {
- final ObjectAnimator anim = ObjectAnimator.ofFloat(v,
- (vertical ? "translationY" : "translationX"), distance);
- anim.setDuration(ANIME_DURATION);
- return anim;
- }
-
- private void animateViews(boolean enabled, boolean full, AnimatorListener listener) {
- int rotation = getUnifiedRotation();
- int topSize = enabled ? 0 : -mTopMargin;
- int bottomSize = enabled ? 0 : mBottomMargin;
- boolean vertical = true;
- switch (rotation) {
- case 0:
- break;
- case 90:
- vertical = false;
- break;
- case 180:
- topSize = -topSize;
- bottomSize = -bottomSize;
- break;
- case 270:
- topSize = -topSize;
- bottomSize = -bottomSize;
- vertical = false;
- break;
- }
-
- mAnimator = new AnimatorSet();
- mAnimator.addListener(listener);
- mAnimator.setDuration(ANIME_DURATION);
- mAnimator.setInterpolator(enabled ?
- new DecelerateInterpolator() :
- new AccelerateInterpolator());
-
- if (full) {
- mAnimator.playTogether(getViewAnimation(mTopBar, topSize, vertical),
- getViewAnimation(mBottomBar, bottomSize, vertical));
- } else {
- final ArrayList<ObjectAnimator> anims = new ArrayList<>();
- for (int i = 0; i < mBottomBar.getChildCount(); i++) {
- View v = mBottomBar.getChildAt(i);
- if (v.getVisibility() != View.GONE) {
- anims.add(getViewAnimation(v, bottomSize, vertical));
- }
- }
- if (anims.size() > 0) {
- mAnimator.playTogether(anims.toArray(new ObjectAnimator[anims.size()]));
- }
- }
- mAnimator.start();
- }
-
public void setMenuAndSwitcherEnabled(boolean enable) {
mMenu.setEnabled(enable);
mFrontBackSwitcher.setEnabled(enable);
}
- public void hideUI(boolean toBlack) {
- if (mHidden) {
- return;
- }
-
- mHidden = true;
- mFullyHidden = toBlack;
-
- if (isAnimating()) {
- mAnimator.cancel();
- }
-
- collapse();
-
- animateViews(false, toBlack, outlistener);
+ public void setUIOffset(float offset, boolean toBlack) {
+ mAnimationHelper.slideTo(offset, toBlack);
+ }
- mRemainingPhotos.setVisibility(View.INVISIBLE);
- mRefocusToast.setVisibility(View.GONE);
+ public void hideUI(boolean toBlack) {
+ mAnimationHelper.slideOut(toBlack);
}
public void showUI() {
- if (!mHidden) {
- return;
- }
-
- mHidden = false;
-
- if (isAnimating()) {
- mAnimator.cancel();
- }
-
- animateViews(true, mFullyHidden, inlistener);
-
- if ((mRemainingPhotos.getVisibility() == View.INVISIBLE) &&
- !mHideRemainingPhoto) {
- mRemainingPhotos.setVisibility(View.VISIBLE);
- }
- mRefocusToast.setVisibility(View.GONE);
+ mAnimationHelper.slideIn();
}
private void layoutRemaingPhotos() {
@@ -563,7 +440,7 @@ public class CameraControls extends RotatableLayout {
}
public boolean arePreviewControlsVisible() {
- return !mHidden;
+ return mAnimationHelper.areControlsVisible();
}
public void setPreviewRect(RectF rectL) {
@@ -574,6 +451,7 @@ public class CameraControls extends RotatableLayout {
} else {
mBottomBar.setBackgroundResource(R.drawable.camera_controls_bg_translucent);
}
+ mAnimationHelper.reset();
}
public void showRefocusToast(boolean show) {
@@ -631,7 +509,272 @@ public class CameraControls extends RotatableLayout {
mRemainingPhotosText.setVisibility(View.GONE);
}
- private class ArrowTextView extends TextView {
+
+ private class AnimationHelper {
+
+ private float mCurrentOffset = 0.0f;
+ private float mTargetOffset = 0.0f;
+
+ private boolean mEntering = false;
+ private boolean mFullyHidden = false;
+
+ private AnimatorSet mAnimator = null;
+
+ private static final boolean DEBUG = false;
+
+ public void slideOut(boolean hideFully) {
+ mTargetOffset = 1.0f;
+ mEntering = false;
+ mFullyHidden = hideFully;
+ dump("slideOut");
+ animate();
+ }
+
+ public void slideIn() {
+ mTargetOffset = 0.0f;
+ mEntering = true;
+ dump("slideIn");
+ animate();
+ }
+
+ public void slideTo(float offset, boolean hideFully) {
+ if (offset > 1.0f || offset < 0.0f || offset == mCurrentOffset) {
+ return;
+ }
+
+ if (mAnimator != null && mAnimator.isRunning()) {
+ return;
+ }
+
+ mTargetOffset = offset;
+ mEntering = mTargetOffset < mCurrentOffset;
+
+ if (mEntering) {
+ preEnter();
+ } else {
+ mFullyHidden = hideFully;
+ preExit();
+ }
+
+ dump("slideTo");
+
+ if (mFullyHidden) {
+
+ mTopBar.setAlpha(1.0f - offset);
+ mBottomBar.setAlpha(1.0f - offset);
+
+ if (isVertical()) {
+ mTopBar.setTranslationY(getTopTranslation());
+ mBottomBar.setTranslationY(getBottomTranslation());
+ } else {
+ mTopBar.setTranslationX(getTopTranslation());
+ mBottomBar.setTranslationX(getBottomTranslation());
+ }
+ } else {
+ for (int i = 0; i < mBottomBar.getChildCount(); i++) {
+ View v = mBottomBar.getChildAt(i);
+ if (v.getVisibility() != View.GONE) {
+ if (isVertical()) {
+ v.setTranslationY(getBottomTranslation());
+ } else {
+ v.setTranslationX(getBottomTranslation());
+ }
+ }
+ }
+ }
+
+ if (mEntering) {
+ postEnter();
+ } else {
+ postExit();
+ }
+ }
+
+ private void reset(View v) {
+ v.setVisibility(View.VISIBLE);
+ v.setTranslationX(0.0f);
+ v.setTranslationY(0.0f);
+ v.setAlpha(1.0f);
+ }
+
+ public void reset() {
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ }
+ for (int i = 0; i < mBottomBar.getChildCount(); i++) {
+ View v = mBottomBar.getChildAt(i);
+ if (v.getVisibility() != View.GONE) {
+ reset(v);
+ }
+ }
+ reset(mTopBar);
+ reset(mBottomBar);
+
+ mCurrentOffset = 0.0f;
+ mTargetOffset = 0.0f;
+ mFullyHidden = false;
+ }
+
+ private void animate() {
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ }
+
+ mAnimator = new AnimatorSet();
+
+ if (mFullyHidden) {
+ mAnimator.playTogether(
+ getViewAnimation(mTopBar, getTopTranslation()),
+ getViewAnimation(mBottomBar, getBottomTranslation()));
+ } else {
+ final ArrayList<ObjectAnimator> anims = new ArrayList<>();
+ for (int i = 0; i < mBottomBar.getChildCount(); i++) {
+ View v = mBottomBar.getChildAt(i);
+ if (v.getVisibility() != View.GONE) {
+ anims.add(getViewAnimation(v, getBottomTranslation()));
+ }
+ }
+ if (anims.size() > 0) {
+ mAnimator.playTogether(anims.toArray(new ObjectAnimator[anims.size()]));
+ }
+ }
+
+ mAnimator.start();
+ }
+
+ public boolean isAnimating() {
+ return (mAnimator != null && mAnimator.isRunning()) || !areControlsVisible();
+ }
+
+ public boolean areControlsVisible() {
+ dump("hasOffset");
+ return mCurrentOffset == 0.0f;
+ }
+
+ private float getBottomTranslation() {
+ return MathUtils.lerp(0.0f, mBottomMargin, mTargetOffset);
+ }
+
+ private float getTopTranslation() {
+ return MathUtils.lerp(0.0f, -mTopMargin, mTargetOffset);
+ }
+
+ private boolean isVertical() {
+ return true;
+ //(getUnifiedRotation() / 90) < 2;
+ }
+
+ private int getDuration() {
+ return (mCurrentOffset == 0.0f && mTargetOffset == 1.0f) ? 200 : 20;
+ }
+
+ private AnimatorListener getListener() {
+ return mEntering ? mEnterListener : mExitListener;
+ }
+
+ private ObjectAnimator getViewAnimation(View v, float target) {
+ final ObjectAnimator anim = ObjectAnimator.ofFloat(v,
+ (isVertical() ? "translationY" : "translationX"), target);
+ anim.setDuration(getDuration());
+ anim.addListener(getListener());
+ return anim;
+ }
+
+ private void preEnter() {
+ if (mCurrentOffset == 1.0f) {
+ if (mFullyHidden) {
+ mTopBar.setVisibility(View.VISIBLE);
+ mBottomBar.setVisibility(View.VISIBLE);
+ } else {
+ setChildrenVisibility(mBottomBar, true);
+ }
+ }
+ dump("preEnter");
+ }
+
+ private void postEnter() {
+ if (mTargetOffset == 0.0f) {
+ enableTouch(true);
+ if ((mRemainingPhotos.getVisibility() == View.INVISIBLE) &&
+ !mHideRemainingPhoto) {
+ mRemainingPhotos.setVisibility(View.VISIBLE);
+ }
+ mRefocusToast.setVisibility(View.GONE);
+ }
+ mCurrentOffset = mTargetOffset;
+ dump("postEnter");
+ }
+
+ private void preExit() {
+ if (mCurrentOffset == 0.0f) {
+ collapse();
+ enableTouch(false);
+ }
+ dump("preExit");
+ }
+
+ private void postExit() {
+ if (mTargetOffset == 1.0f) {
+ if (mFullyHidden) {
+ mTopBar.setVisibility(View.INVISIBLE);
+ mBottomBar.setVisibility(View.INVISIBLE);
+ } else {
+ setChildrenVisibility(mBottomBar, false);
+ }
+ mRemainingPhotos.setVisibility(View.INVISIBLE);
+ mRefocusToast.setVisibility(View.GONE);
+ }
+ mCurrentOffset = mTargetOffset;
+ dump("postExit");
+ }
+
+ private void dump(String info) {
+ if (!DEBUG) {
+ return;
+ }
+ float[] tx = new float[mBottomBar.getChildCount()];
+ float[] ty = new float[mBottomBar.getChildCount()];
+ for (int i = 0; i < mBottomBar.getChildCount(); i++) {
+ tx[i] = mBottomBar.getChildAt(i).getTranslationX();
+ ty[i] = mBottomBar.getChildAt(i).getTranslationY();
+ }
+ Log.d(TAG, String.format(
+ "animate: (%s) currentOffset=%f targetOffset=%f top=%f bottom=%f vertical=%b " +
+ " topX=%f topY=%f bottomX=%f bottomY=%f " +
+ " viewsX=%s viewsY=%s fullyHidden=%b entering=%b",
+ info, mCurrentOffset, mTargetOffset,
+ getTopTranslation(), getBottomTranslation(), isVertical(),
+ mTopBar.getTranslationX(), mTopBar.getTranslationY(),
+ mBottomBar.getTranslationX(), mBottomBar.getTranslationY(),
+ Arrays.toString(tx), Arrays.toString(ty), mFullyHidden, mEntering));
+ }
+
+ private final AnimatorListener mEnterListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ preEnter();
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ postEnter();
+ }
+ };
+
+ private final AnimatorListener mExitListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ preExit();
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ postExit();
+ }
+ };
+ }
+
+ private static class ArrowTextView extends TextView {
private static final int TEXT_SIZE = 14;
private static final int PADDING_SIZE = 18;
private static final int BACKGROUND = 0x80000000;
diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java
index 47f480e57..53cff67da 100644
--- a/src/com/android/camera/ui/FilmStripView.java
+++ b/src/com/android/camera/ui/FilmStripView.java
@@ -100,6 +100,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener {
private int mDataIdOnUserScrolling;
private ValueAnimator.AnimatorUpdateListener mViewItemUpdateListener;
private float mOverScaleFactor = 1f;
+ private int mCurrentOffset = 0;
private int mLastTotalNumber = 0;
private RenderOverlay mRenderOverlay;
@@ -1473,7 +1474,10 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener {
// 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);
+ if (offset != mCurrentOffset) {
+ mCurrentOffset = offset;
+ mListener.onFilmStripScroll(offset);
+ }
}
}