OSDN Git Service

Use icon to indicate the orientation of the taken photos.
authorOwen Lin <owenlin@google.com>
Fri, 4 Dec 2009 03:48:21 +0000 (11:48 +0800)
committerOwen Lin <owenlin@google.com>
Fri, 4 Dec 2009 10:58:06 +0000 (18:58 +0800)
Change-Id: I144e2dd590e98942763fc6e243da3e17cb25d88d

res/drawable-hdpi/btn_ic_mode_switch_camera.png
res/drawable-hdpi/btn_ic_mode_switch_video.png
res/drawable-mdpi/btn_ic_mode_switch_camera.png [changed mode: 0755->0644]
res/drawable-mdpi/btn_ic_mode_switch_video.png [changed mode: 0755->0644]
res/layout/camera_control.xml
src/com/android/camera/Camera.java
src/com/android/camera/ImageManager.java
src/com/android/camera/RotateImageView.java [new file with mode: 0644]

index 3f3e534..ca53bb7 100644 (file)
Binary files a/res/drawable-hdpi/btn_ic_mode_switch_camera.png and b/res/drawable-hdpi/btn_ic_mode_switch_camera.png differ
index 0fc8302..09a2036 100644 (file)
Binary files a/res/drawable-hdpi/btn_ic_mode_switch_video.png and b/res/drawable-hdpi/btn_ic_mode_switch_video.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 9dbe57b..b8b0df7
Binary files a/res/drawable-mdpi/btn_ic_mode_switch_camera.png and b/res/drawable-mdpi/btn_ic_mode_switch_camera.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 397e9ad..f31e9ff
Binary files a/res/drawable-mdpi/btn_ic_mode_switch_video.png and b/res/drawable-mdpi/btn_ic_mode_switch_video.png differ
index 8f7f6c8..6b84ad2 100644 (file)
@@ -23,7 +23,8 @@
         android:layout_marginBottom="10dp"
         android:layout_alignParentRight="true">
 
-    <ImageView android:id="@+id/review_thumbnail"
+    <com.android.camera.RotateImageView
+            android:id="@+id/review_thumbnail"
             android:layout_alignParentTop="true"
             android:layout_centerHorizontal="true"
             android:layout_height="52dp"
 
     <LinearLayout android:id="@+id/camera_switch_set"
             android:orientation="vertical"
+            android:gravity="center"
             android:layout_centerInParent="true"
             android:layout_height="wrap_content"
             android:layout_width="wrap_content">
-        <ImageView android:layout_height="wrap_content"
+        <com.android.camera.RotateImageView android:id="@+id/video_switch_icon"
+                android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
                 android:src="@drawable/btn_ic_mode_switch_video"/>
         <com.android.camera.Switcher android:id="@+id/camera_switch"
@@ -45,7 +48,9 @@
                 android:layout_height="70dp"
                 android:src="@drawable/btn_mode_switch_knob"
                 android:background="@drawable/btn_mode_switch_bg" />
-        <ImageView android:layout_height="wrap_content"
+        <com.android.camera.RotateImageView
+                android:id="@+id/camera_switch_icon"
+                android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
                 android:layout_marginBottom="3dp"
                 android:src="@drawable/btn_ic_mode_switch_camera"/>
index a82a83e..6fea12a 100644 (file)
@@ -262,15 +262,18 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
 
         // Create orientation listenter. This should be done first because it
         // takes some time to get first orientation.
-        mOrientationListener =
-                new OrientationEventListener(Camera.this) {
+        mOrientationListener = new OrientationEventListener(Camera.this) {
             @Override
             public void onOrientationChanged(int orientation) {
                 // We keep the last known orientation. So if the user
                 // first orient the camera then point the camera to
-                // floor/sky, we still have the correct orientation.
                 if (orientation != ORIENTATION_UNKNOWN) {
+                    orientation += 90;
+                }
+                orientation = ImageManager.roundOrientation(orientation);
+                if (orientation != mLastOrientation) {
                     mLastOrientation = orientation;
+                    setOrientationIndicator(mLastOrientation);
                 }
             }
         };
@@ -806,14 +809,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
             mCaptureOnlyData = null;
 
             // Set rotation.
-            int orientation = mLastOrientation;
-            if (orientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
-                orientation += 90;
-            }
-            orientation = ImageManager.roundOrientation(orientation);
-            Log.v(TAG, "mLastOrientation = " + mLastOrientation
-                    + ", orientation = " + orientation);
-            mParameters.setRotation(orientation);
+            mParameters.setRotation(mLastOrientation);
 
             // Clear previous GPS location from the parameters.
             mParameters.removeGpsData();
@@ -992,6 +988,15 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
         removeUnsupportedIndicators();
     }
 
+    private void setOrientationIndicator(int degree) {
+        ((RotateImageView) findViewById(
+                R.id.review_thumbnail)).setDegree(degree);
+        ((RotateImageView) findViewById(
+                R.id.camera_switch_icon)).setDegree(degree);
+        ((RotateImageView) findViewById(
+                R.id.video_switch_icon)).setDegree(degree);
+    }
+
     private void removeUnsupportedIndicators() {
         if (mParameters.getSupportedFocusModes() == null) {
             mFocusIndicator.setVisibility(View.GONE);
index 0a6fd2f..50884ba 100644 (file)
@@ -41,6 +41,7 @@ import android.provider.DrmStore;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Images;
 import android.util.Log;
+import android.view.OrientationEventListener;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -168,7 +169,8 @@ public class ImageManager {
 
     public static int roundOrientation(int orientationInput) {
         int orientation = orientationInput;
-        if (orientation == -1) {
+
+        if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {
             orientation = 0;
         }
 
diff --git a/src/com/android/camera/RotateImageView.java b/src/com/android/camera/RotateImageView.java
new file mode 100644 (file)
index 0000000..74152d4
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2009 The Android Open Source 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.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.animation.AnimationUtils;
+import android.widget.ImageView;
+
+/**
+ * A @{code ImageView} which can rotate it's content.
+ */
+public class RotateImageView extends ImageView {
+
+    @SuppressWarnings("unused")
+    private static final String TAG = "RotateImageView";
+
+    private static final int ANIMATION_SPEED = 180; // 180 deg/sec
+
+    private int mCurrentDegree = 0; // [0, 359]
+    private int mStartDegree = 0;
+    private int mTargetDegree = 0;
+
+    private boolean mClockwise = false;
+
+    private long mAnimationStartTime = 0;
+    private long mAnimationEndTime = 0;
+
+    public RotateImageView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void setDegree(int degree) {
+        // make sure in the range of [0, 359]
+        degree = degree >= 0 ? degree % 360 : degree % 360 + 360;
+        if (degree == mTargetDegree) return;
+
+        mTargetDegree = degree;
+        mStartDegree = mCurrentDegree;
+        mAnimationStartTime = AnimationUtils.currentAnimationTimeMillis();
+
+        int diff = mTargetDegree - mCurrentDegree;
+        diff = diff >= 0 ? diff : 360 + diff; // make it in range [0, 359]
+
+        // Make it in range [-179, 180]. That's the shorted distance between the
+        // two angles
+        diff = diff > 180 ? diff - 360 : diff;
+
+        mClockwise = diff >= 0;
+        mAnimationEndTime = mAnimationStartTime
+                + Math.abs(diff) * 1000 / ANIMATION_SPEED;
+
+        invalidate();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+
+        Drawable drawable = getDrawable();
+        if (drawable == null) return;
+
+        Rect bounds = drawable.getBounds();
+        int w = bounds.right - bounds.left;
+        int h = bounds.bottom - bounds.top;
+
+        if (w == 0 || h == 0) return; // nothing to draw
+
+        if (mCurrentDegree != mTargetDegree) {
+            long time = AnimationUtils.currentAnimationTimeMillis();
+            if (time < mAnimationEndTime) {
+                int deltaTime = (int)(time - mAnimationStartTime);
+                int degree = mStartDegree + ANIMATION_SPEED
+                        * (mClockwise ? deltaTime : -deltaTime) / 1000;
+                degree = degree >= 0 ? degree % 360 : degree % 360 + 360;
+                mCurrentDegree = degree;
+                invalidate();
+            } else {
+                mCurrentDegree = mTargetDegree;
+            }
+        }
+
+        int saveCount = canvas.getSaveCount();
+        canvas.rotate(-mCurrentDegree, w / 2, h / 2);
+        drawable.draw(canvas);
+        canvas.restoreToCount(saveCount);
+    }
+}