From acfe99e268f157bfd524c825f388e6d37261e135 Mon Sep 17 00:00:00 2001 From: Doris Liu Date: Fri, 3 May 2013 10:26:01 -0700 Subject: Anchor camera controls when flipping device Also adjusted margins for camera root view to avoid covering undo bar Bug: 8758513 Bug: 8714114 Change-Id: If27f55a40f95402923d59d162db0c7cc29eabba4 --- .../com/android/gallery3d/common/ApiHelper.java | 3 + src/com/android/camera/ui/CameraControls.java | 88 +++++++++++++---- src/com/android/camera/ui/CameraRootView.java | 104 +++++++++++---------- 3 files changed, 127 insertions(+), 68 deletions(-) diff --git a/gallerycommon/src/com/android/gallery3d/common/ApiHelper.java b/gallerycommon/src/com/android/gallery3d/common/ApiHelper.java index f6439f1ad..dde4c567a 100644 --- a/gallerycommon/src/com/android/gallery3d/common/ApiHelper.java +++ b/gallerycommon/src/com/android/gallery3d/common/ApiHelper.java @@ -195,6 +195,9 @@ public class ApiHelper { public static final boolean HAS_MEDIA_MUXER = Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2; + public static final boolean HAS_DISPLAY_LISTENER = + Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1; + public static int getIntFieldIfExists(Class klass, String fieldName, Class obj, int defaultVal) { try { diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java index f7af52c28..5d2f12360 100644 --- a/src/com/android/camera/ui/CameraControls.java +++ b/src/com/android/camera/ui/CameraControls.java @@ -20,13 +20,15 @@ import android.app.Activity; import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; +import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManager.DisplayListener; import android.util.AttributeSet; -import android.view.Gravity; import android.view.View; import android.widget.FrameLayout; import com.android.camera.Util; import com.android.gallery3d.R; +import com.android.gallery3d.common.ApiHelper; public class CameraControls extends RotatableLayout { @@ -38,19 +40,40 @@ public class CameraControls extends RotatableLayout { private View mMenu; private View mIndicators; private View mPreview; + private Object mDisplayListener = null; + private int mLastRotation = 0; public CameraControls(Context context, AttributeSet attrs) { super(context, attrs); + initDisplayListener(); } public CameraControls(Context context) { super(context); + initDisplayListener(); } - @Override - public void onConfigurationChanged(Configuration config) { - super.onConfigurationChanged(config); - adjustBackground(); + public void initDisplayListener() { + if (ApiHelper.HAS_DISPLAY_LISTENER) { + mDisplayListener = new DisplayListener() { + + @Override + public void onDisplayAdded(int arg0) {} + + @Override + public void onDisplayChanged(int arg0) { + int currentRotation = Util.getDisplayRotation((Activity) getContext()); + if ((currentRotation - mLastRotation) % 180 == 0) { + flipChildren(); + getParent().requestLayout(); + } + mLastRotation = currentRotation; + } + + @Override + public void onDisplayRemoved(int arg0) {} + }; + } } @Override @@ -64,13 +87,39 @@ public class CameraControls extends RotatableLayout { mPreview = findViewById(R.id.preview_thumb); } + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + adjustControlsToRightPosition(); + mLastRotation = Util.getDisplayRotation((Activity) getContext()); + if (ApiHelper.HAS_DISPLAY_LISTENER) { + ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE)) + .registerDisplayListener((DisplayListener) mDisplayListener, null); + } + } + + @Override + public void onDetachedFromWindow () { + super.onDetachedFromWindow(); + if (ApiHelper.HAS_DISPLAY_LISTENER) { + ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE)) + .unregisterDisplayListener((DisplayListener) mDisplayListener); + } + } + @Override public void onLayout(boolean changed, int l, int t, int r, int b) { int orientation = getResources().getConfiguration().orientation; - int rotation = Util.getDisplayRotation((Activity) getContext()); int size = getResources().getDimensionPixelSize(R.dimen.camera_controls_size); - rotation = correctRotation(rotation, orientation); + int rotation = getUnifiedRotation(); + adjustBackground(); super.onLayout(changed, l, t, r, b); + // As l,t,r,b are positions relative to parents, we need to convert them + // to child's coordinates + r = r - l; + b = b - t; + l = 0; + t = 0; Rect shutter = new Rect(); topRight(mPreview, l, t, r, b, orientation, rotation); if (size > 0) { @@ -104,9 +153,11 @@ public class CameraControls extends RotatableLayout { } } - private int correctRotation(int rotation, int orientation) { + private int getUnifiedRotation() { // all the layout code assumes camera device orientation to be portrait // adjust rotation for landscape + int orientation = getResources().getConfiguration().orientation; + int rotation = Util.getDisplayRotation((Activity) getContext()); int camOrientation = (rotation % 180 == 0) ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; if (camOrientation != orientation) { @@ -241,27 +292,28 @@ public class CameraControls extends RotatableLayout { public void adjustControlsToRightPosition() { Configuration config = getResources().getConfiguration(); int orientation = Util.getDisplayRotation((Activity) getContext()); - if (orientation == 270 && config.orientation == Configuration.ORIENTATION_LANDSCAPE) { + if (orientation >= 180) { flipChildren(); } - if (orientation == 180 && config.orientation == Configuration.ORIENTATION_PORTRAIT) { - flipChildren(); - } - adjustBackground(); } private void adjustBackground() { + int rotation = getUnifiedRotation(); // remove current drawable and reset rotation mBackgroundView.setBackgroundDrawable(null); mBackgroundView.setRotationX(0); mBackgroundView.setRotationY(0); // if the switcher background is top aligned we need to flip the background // drawable vertically; if left aligned, flip horizontally - int gravity = ((LayoutParams) mBackgroundView.getLayoutParams()).gravity; - if ((gravity & Gravity.TOP) == Gravity.TOP) { - mBackgroundView.setRotationX(180); - } else if ((gravity & Gravity.LEFT) == Gravity.LEFT) { - mBackgroundView.setRotationY(180); + switch (rotation) { + case 180: + mBackgroundView.setRotationX(180); + break; + case 270: + mBackgroundView.setRotationY(180); + break; + default: + break; } mBackgroundView.setBackgroundResource(R.drawable.switcher_bg); } diff --git a/src/com/android/camera/ui/CameraRootView.java b/src/com/android/camera/ui/CameraRootView.java index 9e3469f6f..0cff14480 100644 --- a/src/com/android/camera/ui/CameraRootView.java +++ b/src/com/android/camera/ui/CameraRootView.java @@ -29,14 +29,14 @@ import android.widget.RelativeLayout; import com.android.camera.Util; import com.android.gallery3d.R; -public class CameraRootView extends RelativeLayout - implements RotatableLayout.RotationListener { +public class CameraRootView extends RelativeLayout { private int mTopMargin = 0; private int mBottomMargin = 0; private int mLeftMargin = 0; private int mRightMargin = 0; private int mOffset = 0; + private Rect mCurrentInsets; public CameraRootView(Context context, AttributeSet attrs) { super(context, attrs); // Layout the window as if we did not need navigation bar @@ -47,64 +47,68 @@ public class CameraRootView extends RelativeLayout @Override protected boolean fitSystemWindows(Rect insets) { super.fitSystemWindows(insets); + mCurrentInsets = insets; // insets include status bar, navigation bar, etc // In this case, we are only concerned with the size of nav bar - if (mOffset > 0) { - // Add margin if necessary to the view to ensure nothing is covered - // by navigation bar - FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); - int right, bottom; - if (insets.right > 0) { - // navigation bar on the right - right = mRightMargin > 0 ? 0 : insets.right; - bottom = 0; - } else { - // navigation bar on the bottom - bottom = mBottomMargin > 0 ? 0 : insets.bottom; - right = 0; - } - lp.setMargins(mLeftMargin, mTopMargin, mRightMargin + right, mBottomMargin + bottom); - return true; - } - FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); + if (mOffset > 0) return true; + if (insets.bottom > 0) { mOffset = insets.bottom; } else if (insets.right > 0) { mOffset = insets.right; } - Configuration config = getResources().getConfiguration(); - if (config.orientation == Configuration.ORIENTATION_PORTRAIT) { - mBottomMargin = mOffset; - } else if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) { - mRightMargin = mOffset; - } - lp.setMargins( mLeftMargin, mTopMargin, mRightMargin, mBottomMargin); - CameraControls controls = (CameraControls) findViewById(R.id.camera_controls); - if (controls != null) { - controls.setRotationListener(this); - controls.adjustControlsToRightPosition(); - } return true; } - @Override - public void onRotation(int rotation) { - FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); - int b = mBottomMargin; - int t = mTopMargin; - int l = mLeftMargin; - int r = mRightMargin; - rotation = (rotation + 360) % 360; - if (rotation == 90) { - lp.setMargins(b, l, t, r); - } else if (rotation == 270) { - lp.setMargins(t, r, b, l); - } else if (rotation == 180) { - lp.setMargins(r, b, l, t); + public void onLayout(boolean changed, int l, int t, int r, int b) { + int rotation = Util.getDisplayRotation((Activity) getContext()); + // all the layout code assumes camera device orientation to be portrait + // adjust rotation for landscape + int orientation = getResources().getConfiguration().orientation; + int camOrientation = (rotation % 180 == 0) ? Configuration.ORIENTATION_PORTRAIT + : Configuration.ORIENTATION_LANDSCAPE; + if (camOrientation != orientation) { + rotation = (rotation + 90) % 360; + } + // calculate margins + int left = 0; + int right = 0; + int bottom = 0; + int top = 0; + switch (rotation) { + case 0: + bottom += mOffset; + break; + case 90: + right += mOffset; + break; + case 180: + top += mOffset; + break; + case 270: + left += mOffset; + break; + } + if (mCurrentInsets.right > 0) { + // navigation bar on the right + right = right > 0 ? right : mCurrentInsets.right; + } else { + // navigation bar on the bottom + bottom = bottom > 0 ? bottom : mCurrentInsets.bottom; + } + for (int i = 0; i < getChildCount(); i++) { + View v = getChildAt(i); + if (v instanceof CameraControls) { + // Lay out camera controls to fill the short side of the screen + // so that they stay in place during rotation + if (rotation % 180 == 0) { + v.layout(l, t + top, r, b - bottom); + } else { + v.layout(l + left, t, r - right, b); + } + } else { + v.layout(l + left, t + top, r - right, b - bottom); + } } - mLeftMargin = lp.leftMargin; - mTopMargin = lp.topMargin; - mRightMargin = lp.rightMargin; - mBottomMargin = lp.bottomMargin; } } -- cgit v1.2.3