OSDN Git Service

Adjust capture indicator position while open/close mode options.
[android-x86/packages-apps-Camera2.git] / src / com / android / camera / ui / StickyBottomCaptureLayout.java
index 2c0dec0..14c7e73 100644 (file)
@@ -17,6 +17,9 @@
 package com.android.camera.ui;
 
 import android.content.Context;
+import android.content.res.Configuration;
+import android.view.animation.Interpolator;
+import android.graphics.PointF;
 import android.graphics.RectF;
 import android.util.AttributeSet;
 import android.view.View;
@@ -24,6 +27,9 @@ import android.widget.FrameLayout;
 
 import com.android.camera.CaptureLayoutHelper;
 import com.android.camera.debug.Log;
+import com.android.camera.ui.motion.InterpolatorHelper;
+import com.android.camera.widget.ModeOptions;
+import com.android.camera.widget.ModeOptionsOverlay;
 import com.android.camera.widget.RoundedThumbnailView;
 import com.android.camera2.R;
 
@@ -37,10 +43,40 @@ public class StickyBottomCaptureLayout extends FrameLayout {
 
     private final static Log.Tag TAG = new Log.Tag("StickyBotCapLayout");
     private RoundedThumbnailView mRoundedThumbnailView;
-    private View mModeOptionsOverlay;
+    private ModeOptionsOverlay mModeOptionsOverlay;
     private View mBottomBar;
     private CaptureLayoutHelper mCaptureLayoutHelper = null;
 
+    private ModeOptions.Listener mModeOptionsListener = new ModeOptions.Listener() {
+        @Override
+        public void onBeginToShowModeOptions() {
+            final PointF thumbnailViewPosition = getRoundedThumbnailPosition(
+                    mCaptureLayoutHelper.getUncoveredPreviewRect(),
+                    false,
+                    mModeOptionsOverlay.getModeOptionsToggleWidth());
+            final int orientation = getResources().getConfiguration().orientation;
+            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+                animateCaptureIndicatorToY(thumbnailViewPosition.y);
+            } else {
+                animateCaptureIndicatorToX(thumbnailViewPosition.x);
+            }
+        }
+
+        @Override
+        public void onBeginToHideModeOptions() {
+            final PointF thumbnailViewPosition = getRoundedThumbnailPosition(
+                    mCaptureLayoutHelper.getUncoveredPreviewRect(),
+                    true,
+                    mModeOptionsOverlay.getModeOptionsToggleWidth());
+            final int orientation = getResources().getConfiguration().orientation;
+            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+                animateCaptureIndicatorToY(thumbnailViewPosition.y);
+            } else {
+                animateCaptureIndicatorToX(thumbnailViewPosition.x);
+            }
+        }
+    };
+
     public StickyBottomCaptureLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -48,7 +84,8 @@ public class StickyBottomCaptureLayout extends FrameLayout {
     @Override
     public void onFinishInflate() {
         mRoundedThumbnailView = (RoundedThumbnailView) findViewById(R.id.rounded_thumbnail_view);
-        mModeOptionsOverlay = findViewById(R.id.mode_options_overlay);
+        mModeOptionsOverlay = (ModeOptionsOverlay) findViewById(R.id.mode_options_overlay);
+        mModeOptionsOverlay.setModeOptionsListener(mModeOptionsListener);
         mBottomBar = findViewById(R.id.bottom_bar);
     }
 
@@ -65,19 +102,114 @@ public class StickyBottomCaptureLayout extends FrameLayout {
             Log.e(TAG, "Capture layout helper needs to be set first.");
             return;
         }
-        RectF drawRect = new RectF(left, top, right, bottom);
+        // Layout mode options overlay.
         RectF uncoveredPreviewRect = mCaptureLayoutHelper.getUncoveredPreviewRect();
-        RectF bottomBarRect = mCaptureLayoutHelper.getBottomBarRect();
-        RectF roundedThumbnailViewRect =
-                mRoundedThumbnailView.getDesiredLayout(drawRect, uncoveredPreviewRect);
-        mRoundedThumbnailView.layout(
-                (int) roundedThumbnailViewRect.left,
-                (int) roundedThumbnailViewRect.top,
-                (int) roundedThumbnailViewRect.right,
-                (int) roundedThumbnailViewRect.bottom);
         mModeOptionsOverlay.layout((int) uncoveredPreviewRect.left, (int) uncoveredPreviewRect.top,
                 (int) uncoveredPreviewRect.right, (int) uncoveredPreviewRect.bottom);
+
+        // Layout capture indicator.
+        PointF roundedThumbnailViewPosition = getRoundedThumbnailPosition(
+                uncoveredPreviewRect,
+                mModeOptionsOverlay.isModeOptionsHidden(),
+                mModeOptionsOverlay.getModeOptionsToggleWidth());
+        mRoundedThumbnailView.layout(
+                (int) roundedThumbnailViewPosition.x,
+                (int) roundedThumbnailViewPosition.y,
+                (int) roundedThumbnailViewPosition.x + mRoundedThumbnailView.getMeasuredWidth(),
+                (int) roundedThumbnailViewPosition.y + mRoundedThumbnailView.getMeasuredHeight());
+
+        // Layout bottom bar.
+        RectF bottomBarRect = mCaptureLayoutHelper.getBottomBarRect();
         mBottomBar.layout((int) bottomBarRect.left, (int) bottomBarRect.top,
                 (int) bottomBarRect.right, (int) bottomBarRect.bottom);
     }
-}
\ No newline at end of file
+
+    /**
+     * Calculates the desired layout of capture indicator.
+     *
+     * @param uncoveredPreviewRect The uncovered preview bound which contains mode option
+     *                             overlay and capture indicator.
+     * @param isModeOptionsHidden Whether the mode options button are hidden.
+     * @param modeOptionsToggleWidth The width of mode options toggle (three dots button).
+     * @return the desired view bound for capture indicator.
+     */
+    private PointF getRoundedThumbnailPosition(
+            RectF uncoveredPreviewRect, boolean isModeOptionsHidden, float modeOptionsToggleWidth) {
+        final float threeDotsButtonDiameter =
+                getResources().getDimension(R.dimen.option_button_circle_size);
+        final float threeDotsButtonPadding =
+                getResources().getDimension(R.dimen.mode_options_toggle_padding);
+        final float modeOptionsHeight = getResources().getDimension(R.dimen.mode_options_height);
+
+        final float roundedThumbnailViewSize = mRoundedThumbnailView.getMeasuredWidth();
+        final float roundedThumbnailFinalSize = mRoundedThumbnailView.getThumbnailFinalDiameter();
+        final float roundedThumbnailViewPadding = mRoundedThumbnailView.getThumbnailPadding();
+
+        // The view bound is based on the maximal ripple ring diameter. This is the diff of maximal
+        // ripple ring radius and the final thumbnail radius.
+        final float radiusDiffBetweenViewAndThumbnail =
+                (roundedThumbnailViewSize - roundedThumbnailFinalSize) / 2.0f;
+        final float distanceFromModeOptions = roundedThumbnailViewPadding +
+                roundedThumbnailFinalSize + radiusDiffBetweenViewAndThumbnail;
+
+        final int orientation = getResources().getConfiguration().orientation;
+
+        float x = 0;
+        float y = 0;
+        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
+            // The view finder of 16:9 aspect ratio might have a black padding.
+            x = uncoveredPreviewRect.right - distanceFromModeOptions;
+
+            y = uncoveredPreviewRect.bottom;
+            if (isModeOptionsHidden) {
+                y -= threeDotsButtonPadding + threeDotsButtonDiameter;
+            } else {
+                y -= modeOptionsHeight;
+            }
+            y -= distanceFromModeOptions;
+        }
+        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            if (isModeOptionsHidden) {
+                x = uncoveredPreviewRect.right - threeDotsButtonPadding - modeOptionsToggleWidth;
+            } else {
+                x = uncoveredPreviewRect.right - modeOptionsHeight;
+            }
+            x -= distanceFromModeOptions;
+            y = uncoveredPreviewRect.top + roundedThumbnailViewPadding -
+                    radiusDiffBetweenViewAndThumbnail;
+        }
+        return new PointF(x, y);
+    }
+
+    private void animateCaptureIndicatorToX(float x) {
+        final Interpolator interpolator =
+                InterpolatorHelper.getLinearOutSlowInInterpolator(getContext());
+        mRoundedThumbnailView.animate()
+                .setDuration(ModeOptions.PADDING_ANIMATION_TIME)
+                .setInterpolator(interpolator)
+                .x(x)
+                .withEndAction(new Runnable() {
+                    @Override
+                    public void run() {
+                        mRoundedThumbnailView.setTranslationX(0.0f);
+                        requestLayout();
+                    }
+                });
+    }
+
+    private void animateCaptureIndicatorToY(float y) {
+        final Interpolator interpolator =
+                InterpolatorHelper.getLinearOutSlowInInterpolator(getContext());
+        mRoundedThumbnailView.animate()
+                .setDuration(ModeOptions.PADDING_ANIMATION_TIME)
+                .setInterpolator(interpolator)
+                .y(y)
+                .withEndAction(new Runnable() {
+                    @Override
+                    public void run() {
+                        mRoundedThumbnailView.setTranslationY(0.0f);
+                        requestLayout();
+                    }
+                });
+    }
+}