summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/anim/grow_fade_in_from_top_right.xml30
-rw-r--r--res/anim/shrink_fade_out_from_top_right.xml30
-rw-r--r--res/drawable-hdpi/divider_strong_holo.9.pngbin0 -> 122 bytes
-rw-r--r--res/drawable-mdpi/divider_strong_holo.9.pngbin0 -> 122 bytes
-rw-r--r--res/layout-w1024dp/review_thumbnail.xml21
-rw-r--r--res/layout/review_thumbnail.xml25
-rw-r--r--res/layout/share_item.xml36
-rw-r--r--res/layout/share_popup.xml78
-rw-r--r--res/values-w1024dp/dimens.xml1
-rw-r--r--res/values/colors.xml1
-rw-r--r--res/values/dimens.xml1
-rw-r--r--res/values/ids.xml19
-rw-r--r--res/values/styles.xml4
-rw-r--r--src/com/android/camera/Camera.java84
-rw-r--r--src/com/android/camera/VideoCamera.java95
-rw-r--r--src/com/android/camera/ui/RotateLayout.java51
-rw-r--r--src/com/android/camera/ui/SharePopup.java159
17 files changed, 395 insertions, 240 deletions
diff --git a/res/anim/grow_fade_in_from_top_right.xml b/res/anim/grow_fade_in_from_top_right.xml
new file mode 100644
index 0000000..1bfede0
--- /dev/null
+++ b/res/anim/grow_fade_in_from_top_right.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/fade_in.xml
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false">
+ <scale android:interpolator="@android:interpolator/decelerate_quint"
+ android:fromXScale="0.9" android:toXScale="1.0"
+ android:fromYScale="0.9" android:toYScale="1.0"
+ android:pivotX="100%" android:pivotY="0%"
+ android:duration="300" />
+ <alpha android:interpolator="@android:interpolator/decelerate_cubic"
+ android:fromAlpha="0.5" android:toAlpha="1.0"
+ android:duration="300" />
+</set>
diff --git a/res/anim/shrink_fade_out_from_top_right.xml b/res/anim/shrink_fade_out_from_top_right.xml
new file mode 100644
index 0000000..9727386
--- /dev/null
+++ b/res/anim/shrink_fade_out_from_top_right.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/anim/fade_out.xml
+**
+** Copyright 2007, 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false">
+ <scale android:interpolator="@android:interpolator/decelerate_quint"
+ android:fromXScale="1.0" android:toXScale="0.9"
+ android:fromYScale="1.0" android:toYScale="0.9"
+ android:pivotX="100%" android:pivotY="0%"
+ android:duration="300" />
+ <alpha android:interpolator="@android:interpolator/decelerate_cubic"
+ android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:duration="300" />
+</set>
diff --git a/res/drawable-hdpi/divider_strong_holo.9.png b/res/drawable-hdpi/divider_strong_holo.9.png
new file mode 100644
index 0000000..0758593
--- /dev/null
+++ b/res/drawable-hdpi/divider_strong_holo.9.png
Binary files differ
diff --git a/res/drawable-mdpi/divider_strong_holo.9.png b/res/drawable-mdpi/divider_strong_holo.9.png
new file mode 100644
index 0000000..0758593
--- /dev/null
+++ b/res/drawable-mdpi/divider_strong_holo.9.png
Binary files differ
diff --git a/res/layout-w1024dp/review_thumbnail.xml b/res/layout-w1024dp/review_thumbnail.xml
index 0290d50..0f8c4d1 100644
--- a/res/layout-w1024dp/review_thumbnail.xml
+++ b/res/layout-w1024dp/review_thumbnail.xml
@@ -14,15 +14,24 @@
limitations under the License.
-->
-<com.android.camera.ui.RotateImageView xmlns:android="http://schemas.android.com/apk/res/android"
- android:visibility="invisible"
- android:id="@+id/review_thumbnail"
- android:layout_width="86dp"
- android:layout_height="86dp"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/share_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_marginTop="@dimen/thumbnail_margin_top"
android:layout_marginRight="@dimen/thumbnail_margin_right"
+ android:orientation="horizontal"
android:clickable="true"
android:focusable="false"
- android:background="@drawable/border_last_picture"/>
+ android:background="@drawable/border_last_picture">
+ <com.android.camera.ui.RotateImageView android:id="@+id/share_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_viewfinder_share"
+ android:background="@android:color/black" />
+ <com.android.camera.ui.RotateImageView android:id="@+id/thumbnail"
+ android:layout_width="86dp"
+ android:layout_height="86dp"/>
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/review_thumbnail.xml b/res/layout/review_thumbnail.xml
index 1f8b344..f94a186 100644
--- a/res/layout/review_thumbnail.xml
+++ b/res/layout/review_thumbnail.xml
@@ -14,29 +14,22 @@
limitations under the License.
-->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/share_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
- android:orientation="vertical">
- <com.android.camera.ui.RotateImageView
- android:id="@+id/review_thumbnail"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:focusable="false"
+ android:background="@drawable/border_last_picture">
+ <com.android.camera.ui.RotateImageView android:id="@+id/thumbnail"
android:layout_width="52dp"
- android:layout_height="52dp"
- android:clickable="true"
- android:focusable="false"
- android:background="@drawable/border_last_picture" />
- <com.android.camera.ui.RotateImageView
- android:id="@+id/btn_share"
+ android:layout_height="52dp"/>
+ <com.android.camera.ui.RotateImageView android:id="@+id/share_icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:paddingTop="2dp"
- android:paddingBottom="2dp"
- android:clickable="true"
- android:focusable="false"
android:src="@drawable/ic_viewfinder_share"
android:background="@android:color/black" />
</LinearLayout> \ No newline at end of file
diff --git a/res/layout/share_item.xml b/res/layout/share_item.xml
new file mode 100644
index 0000000..e5b0b9e
--- /dev/null
+++ b/res/layout/share_item.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2011 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.
+*/
+-->
+<!-- A row that contains an icon and the name of the app to share in a listview -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="48dp"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:paddingLeft="4dp"
+ android:paddingRight="4dp">
+ <TextView android:id="@+id/text"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="left|center_vertical"
+ android:textAppearance="?android:textAppearanceMedium"
+ android:singleLine="true"
+ android:paddingLeft="4dp"
+ android:textColor="@android:color/white" />
+</LinearLayout>
diff --git a/res/layout/share_popup.xml b/res/layout/share_popup.xml
index 93ffd4b..06b0e2a 100644
--- a/res/layout/share_popup.xml
+++ b/res/layout/share_popup.xml
@@ -14,23 +14,77 @@
limitations under the License.
-->
-<RelativeLayout
+<!-- Use a full-screen popup window because UI has some intermediate problems
+ when its size is changed. -->
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:camera="http://schemas.android.com/apk/res/com.android.camera"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <com.android.camera.ui.RotateLayout
- android:id="@+id/rotate_layout"
+ <!-- Need a relative layout here because collapse button does not rotate and
+ it is not in the thumbnail. -->
+ <RelativeLayout android:id="@+id/root"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_alignParentRight="true">
- <!-- The size of the thumbnail is calculated in SharePopup.java -->
- <ImageView
- android:id="@+id/expanded_thumbnail"
+ android:layout_gravity="top|bottom">
+ <com.android.camera.ui.RotateLayout
+ android:id="@+id/share_view_rotate_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:adjustViewBounds="true"
- android:scaleType="fitCenter" />
- </com.android.camera.ui.RotateLayout>
-</RelativeLayout>
+ android:layout_toLeftOf="@+id/thumbnail_rotate_layout">
+ <!-- The width of the share list is calculated in SharePopup.java. -->
+ <LinearLayout android:id="@+id/share_view"
+ android:layout_width="@dimen/share_list_width_landscape"
+ android:layout_height="@dimen/share_image_max_height_landscape"
+ android:orientation="vertical"
+ android:background="@color/dark_gray"
+ android:paddingLeft="7dp"
+ android:paddingRight="7dp"
+ android:clickable="true">
+ <TextView android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="44dp"
+ android:gravity="left|center_vertical"
+ android:textAppearance="?android:textAppearanceMedium"
+ android:text="@string/share_picture_via"
+ android:textColor="@android:color/white"
+ android:paddingLeft="4dp" />
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:scaleType="fitXY"
+ android:gravity="fill_horizontal"
+ android:src="@drawable/divider_strong_holo" />
+ <ListView android:id="@+id/share_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_gravity="center"
+ android:choiceMode="singleChoice"
+ style="@android:style/Widget.ListView" />
+ </LinearLayout>
+ </com.android.camera.ui.RotateLayout>
+ <com.android.camera.ui.RotateLayout
+ android:id="@+id/thumbnail_rotate_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true">
+ <!-- The size of the thumbnail is calculated in SharePopup.java -->
+ <ImageView android:id="@+id/thumbnail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:adjustViewBounds="true"
+ android:scaleType="fitCenter"
+ android:background="@drawable/border_last_picture" />
+ </com.android.camera.ui.RotateLayout>
+ <ImageView android:id="@+id/collapse_button"
+ android:layout_width="56dp"
+ android:layout_height="56dp"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:src="@drawable/btn_ic_review_play"
+ android:scaleType="center" />
+ </RelativeLayout>
+</FrameLayout>
diff --git a/res/values-w1024dp/dimens.xml b/res/values-w1024dp/dimens.xml
index c9f8b1d..ad93943 100644
--- a/res/values-w1024dp/dimens.xml
+++ b/res/values-w1024dp/dimens.xml
@@ -30,4 +30,5 @@
<dimen name="share_image_max_height_landscape">360dp</dimen>
<dimen name="share_image_max_width_portrait">480dp</dimen>
<dimen name="share_image_max_height_portrait">480dp</dimen>
+ <dimen name="share_list_width_landscape">200dp</dimen>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 8a1652a..96d269f 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -24,4 +24,5 @@
<color name="review_control_pressed_color">#FF6899FF</color>
<color name="icon_disabled_color">#DD777777</color>
<color name="time_lapse_arc">#FFC5C5C5</color>
+ <color name="dark_gray">#151515</color>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index cd42854..7978d9c 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -23,4 +23,5 @@
<dimen name="share_image_max_height_landscape">240dp</dimen>
<dimen name="share_image_max_width_portrait">240dp</dimen>
<dimen name="share_image_max_height_portrait">240dp</dimen>
+ <dimen name="share_list_width_landscape">180dp</dimen>
</resources>
diff --git a/res/values/ids.xml b/res/values/ids.xml
deleted file mode 100644
index 81d920f..0000000
--- a/res/values/ids.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<resources>
- <item type="id" name="btn_gallery" />
-</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 05c28a0..520ae31 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -117,4 +117,8 @@
<item name="android:textSize">16dp</item>
<item name="android:background">@drawable/bg_text_on_preview</item>
</style>
+ <style name="AnimationPopup" parent="android:Animation">
+ <item name="android:windowEnterAnimation">@anim/grow_fade_in_from_top_right</item>
+ <item name="android:windowExitAnimation">@anim/shrink_fade_out_from_top_right</item>
+ </style>
</resources>
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 02e9eab..1183de0 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -168,16 +168,16 @@ public class Camera extends ActivityBase implements View.OnClickListener,
private GLRootView mGLRootView;
- // A button showing the last captured picture thumbnail. Clicking on it will
- // show the share popup window.
- private RotateImageView mThumbnailButton;
// A popup window that contains a bigger thumbnail and a list of apps to share.
private SharePopup mSharePopup;
// The bitmap of the last captured picture thumbnail and the URI of the
// original picture.
private Thumbnail mThumbnail;
- // A button sharing the last picture.
- private RotateImageView mShareButton;
+ // A button that contains the thumbnail and the share icon.
+ private View mShareButton;
+ // An imageview showing showing the last captured picture thumbnail.
+ private RotateImageView mThumbnailView;
+ private RotateImageView mShareIcon;
private RotateImageView mCameraSwitchIcon;
private RotateImageView mVideoSwitchIcon;
@@ -386,7 +386,6 @@ public class Camera extends ActivityBase implements View.OnClickListener,
if (!mIsImageCaptureIntent) { // no thumbnail in image capture intent
findViewById(R.id.camera_switch).setOnClickListener(this);
initThumbnailButton();
- if (mShareButton != null) mShareButton.setOnClickListener(this);
}
// Initialize shutter button.
@@ -430,7 +429,7 @@ public class Camera extends ActivityBase implements View.OnClickListener,
}
private void initThumbnailButton() {
- mThumbnailButton.setOnClickListener(this);
+ mShareButton.setOnClickListener(this);
// Load the thumbnail from the disk.
mThumbnail = Thumbnail.loadFrom(new File(getFilesDir(), LAST_THUMB_FILENAME));
updateThumbnailButton();
@@ -443,9 +442,9 @@ public class Camera extends ActivityBase implements View.OnClickListener,
mThumbnail = Thumbnail.getLastImageThumbnail(mContentResolver);
}
if (mThumbnail != null) {
- mThumbnailButton.setBitmap(mThumbnail.getBitmap());
+ mThumbnailView.setBitmap(mThumbnail.getBitmap());
} else {
- mThumbnailButton.setBitmap(null);
+ mThumbnailView.setBitmap(null);
}
}
@@ -867,7 +866,7 @@ public class Camera extends ActivityBase implements View.OnClickListener,
int inSampleSize = Util.nextPowerOf2(ratio);
mThumbnail = Thumbnail.createThumbnail(data, orientation, inSampleSize, uri);
if (mThumbnail != null) {
- mThumbnailButton.setBitmap(mThumbnail.getBitmap());
+ mThumbnailView.setBitmap(mThumbnail.getBitmap());
}
sendBroadcast(new Intent("com.android.camera.NEW_PICTURE", uri));
}
@@ -981,8 +980,9 @@ public class Camera extends ActivityBase implements View.OnClickListener,
setContentView(R.layout.camera);
}
mFocusRectangle = (FocusRectangle) findViewById(R.id.focus_rectangle);
- mThumbnailButton = (RotateImageView) findViewById(R.id.review_thumbnail);
- mShareButton = (RotateImageView) findViewById(R.id.btn_share);
+ mShareButton = findViewById(R.id.share_button);
+ mThumbnailView = (RotateImageView) findViewById(R.id.thumbnail);
+ mShareIcon = (RotateImageView) findViewById(R.id.share_icon);
mCameraSwitchIcon = (RotateImageView) findViewById(R.id.camera_switch_icon);
mVideoSwitchIcon = (RotateImageView) findViewById(R.id.video_switch_icon);
@@ -1231,8 +1231,8 @@ public class Camera extends ActivityBase implements View.OnClickListener,
private void setOrientationIndicator(int degree) {
if (mHeadUpDisplay != null) mHeadUpDisplay.setOrientation(mOrientationCompensation);
- if (mThumbnailButton != null) mThumbnailButton.setDegree(degree);
- if (mShareButton != null) mShareButton.setDegree(degree);
+ if (mThumbnailView != null) mThumbnailView.setDegree(degree);
+ if (mShareIcon != null) mShareIcon.setDegree(degree);
if (mCameraSwitchIcon != null) mCameraSwitchIcon.setDegree(degree);
if (mVideoSwitchIcon != null) mVideoSwitchIcon.setDegree(degree);
if (mSharePopup != null) mSharePopup.setOrientation(degree);
@@ -1255,31 +1255,24 @@ public class Camera extends ActivityBase implements View.OnClickListener,
updateStorageHint();
}
+ @Override
public void onClick(View v) {
switch (v.getId()) {
+ case R.id.share_button:
+ if (isCameraIdle() && mThumbnail != null) {
+ showSharePopup();
+ }
+ break;
case R.id.btn_retake:
hidePostCaptureAlert();
startPreview();
break;
- case R.id.review_thumbnail:
- if (isCameraIdle() && mThumbnail != null) {
- Util.viewUri(mThumbnail.getUri(), this);
- }
- break;
case R.id.btn_done:
doAttach();
break;
case R.id.btn_cancel:
doCancel();
break;
- case R.id.btn_gallery:
- gotoGallery();
- break;
- case R.id.btn_share:
- if (isCameraIdle() && mThumbnail != null) {
- createSharePopup();
- }
- break;
}
}
@@ -1519,7 +1512,7 @@ public class Camera extends ActivityBase implements View.OnClickListener,
hidePostCaptureAlert();
}
- dismissSharePopup();
+ if (mSharePopup != null) mSharePopup.dismiss();
if (mDidRegister) {
unregisterReceiver(mReceiver);
@@ -2447,36 +2440,13 @@ public class Camera extends ActivityBase implements View.OnClickListener,
mNotSelectableToast.show();
}
- private void createSharePopup() {
- if (mSharePopup != null) mSharePopup.dismiss();
- mSharePopup = new SharePopup(this, mThumbnail.getUri(),
- mThumbnail.getBitmap(), mOrientationCompensation, mThumbnailButton);
- mSharePopup.showAtLocation(mThumbnailButton, Gravity.NO_GRAVITY, 0, 0);
- }
-
- private void dismissSharePopup() {
- if (mSharePopup != null) {
- mSharePopup.dismiss();
- mSharePopup = null;
- }
- }
-
- private void onShareButtonClicked() {
- if (mPausing) return;
-
- // Share the last captured picture.
- if (mThumbnail != null) {
- Intent intent = new Intent(Intent.ACTION_SEND);
- intent.setType("image/jpeg");
- intent.putExtra(Intent.EXTRA_STREAM, mThumbnail.getUri());
- startActivity(Intent.createChooser(intent, getString(R.string.share_picture_via)));
- } else { // No last picture
- if (mNoShareToast == null) {
- mNoShareToast = Toast.makeText(this,
- getResources().getString(R.string.no_picture_to_share), Toast.LENGTH_SHORT);
- }
- mNoShareToast.show();
+ private void showSharePopup() {
+ Uri uri = mThumbnail.getUri();
+ if (mSharePopup == null || !uri.equals(mSharePopup.getUri())) {
+ mSharePopup = new SharePopup(this, uri, mThumbnail.getBitmap(), "image/jpeg",
+ mOrientationCompensation, mShareButton);
}
+ mSharePopup.showAtLocation(mThumbnailView, Gravity.NO_GRAVITY, 0, 0);
}
private class MyIndicatorWheelListener implements IndicatorWheel.Listener {
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index 31444c4..300d31f 100644
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -150,19 +150,19 @@ public class VideoCamera extends ActivityBase
private View mReviewControl;
private Toast mNoShareToast;
- // A button showing the last captured video thumbnail. Clicking on it will
- // show the share popup window.
- private RotateImageView mThumbnailButton;
+ // An review image having same size as preview. It is displayed when
+ // recording is stopped in capture intent.
+ private ImageView mReviewImage;
// A popup window that contains a bigger thumbnail and a list of apps to share.
private SharePopup mSharePopup;
// The bitmap of the last captured video thumbnail and the URI of the
// original video.
private Thumbnail mThumbnail;
- // An review image having same size as preview. It is displayed when
- // recording is stopped in capture intent.
- private ImageView mReviewImage;
- // A button sharing the last picture.
- private RotateImageView mShareButton;
+ // A button that contains the thumbnail and the share icon.
+ private View mShareButton;
+ // An imageview showing showing the last captured picture thumbnail.
+ private RotateImageView mThumbnailView;
+ private RotateImageView mShareIcon;
private RotateImageView mCameraSwitchIcon;
private RotateImageView mVideoSwitchIcon;
private ShutterButton mShutterButton;
@@ -406,8 +406,7 @@ public class VideoCamera extends ActivityBase
setContentView(R.layout.video_camera);
initThumbnailButton();
- mShareButton = (RotateImageView) findViewById(R.id.btn_share);
- if (mShareButton != null) mShareButton.setOnClickListener(this);
+ mShareIcon = (RotateImageView) findViewById(R.id.share_icon);
mSwitcher = (SwitcherSet) findViewById(R.id.camera_switch);
mSwitcher.setVisibility(View.VISIBLE);
mSwitcher.setOnSwitchListener(this);
@@ -418,6 +417,8 @@ public class VideoCamera extends ActivityBase
mPreviewFrameLayout.setOnSizeChangedListener(this);
mReviewImage = (ImageView) findViewById(R.id.review_image);
+ mShareButton = findViewById(R.id.share_button);
+ mShareIcon = (RotateImageView) findViewById(R.id.share_icon);
mCameraSwitchIcon = (RotateImageView) findViewById(R.id.camera_switch_icon);
mVideoSwitchIcon = (RotateImageView) findViewById(R.id.video_switch_icon);
@@ -607,8 +608,8 @@ public class VideoCamera extends ActivityBase
private void setOrientationIndicator(int degree) {
if (mHeadUpDisplay != null) mHeadUpDisplay.setOrientation(mOrientationCompensation);
- if (mThumbnailButton != null) mThumbnailButton.setDegree(degree);
- if (mShareButton != null) mShareButton.setDegree(degree);
+ if (mThumbnailView != null) mThumbnailView.setDegree(degree);
+ if (mShareIcon != null) mShareIcon.setDegree(degree);
if (mCameraSwitchIcon != null) mCameraSwitchIcon.setDegree(degree);
if (mVideoSwitchIcon != null) mVideoSwitchIcon.setDegree(degree);
if (mSharePopup != null) mSharePopup.setOrientation(degree);
@@ -623,8 +624,14 @@ public class VideoCamera extends ActivityBase
}
}
+ @Override
public void onClick(View v) {
switch (v.getId()) {
+ case R.id.share_button:
+ if (!mMediaRecorderRecording && mThumbnail != null) {
+ showSharePopup();
+ }
+ break;
case R.id.btn_retake:
deleteCurrentVideo();
hideAlert();
@@ -639,19 +646,6 @@ public class VideoCamera extends ActivityBase
stopVideoRecording();
doReturnToCaller(false);
break;
- case R.id.review_thumbnail:
- if (!mMediaRecorderRecording && mThumbnail != null) {
- Util.viewUri(mThumbnail.getUri(), this);
- }
- break;
- case R.id.btn_gallery:
- gotoGallery();
- break;
- case R.id.btn_share:
- if (!mMediaRecorderRecording && mThumbnail != null) {
- createSharePopup();
- }
- break;
}
}
@@ -981,7 +975,7 @@ public class VideoCamera extends ActivityBase
finishRecorderAndCloseCamera();
- dismissSharePopup();
+ if (mSharePopup != null) mSharePopup.dismiss();
if (mReceiver != null) {
unregisterReceiver(mReceiver);
@@ -1496,7 +1490,7 @@ public class VideoCamera extends ActivityBase
mCurrentVideoFilename, Video.Thumbnails.MINI_KIND);
if (videoFrame != null) {
mThumbnail = new Thumbnail(mCurrentVideoUri, videoFrame, 0);
- mThumbnailButton.setBitmap(mThumbnail.getBitmap());
+ mThumbnailView.setBitmap(mThumbnail.getBitmap());
}
}
}
@@ -1619,8 +1613,8 @@ public class VideoCamera extends ActivityBase
}
private void initThumbnailButton() {
- mThumbnailButton = (RotateImageView) findViewById(R.id.review_thumbnail);
- mThumbnailButton.setOnClickListener(this);
+ mThumbnailView = (RotateImageView) findViewById(R.id.thumbnail);
+ findViewById(R.id.share_button).setOnClickListener(this);
// Load the thumbnail from the disk.
mThumbnail = Thumbnail.loadFrom(new File(getFilesDir(), LAST_THUMB_FILENAME));
}
@@ -1630,9 +1624,9 @@ public class VideoCamera extends ActivityBase
mThumbnail = Thumbnail.getLastVideoThumbnail(mContentResolver);
}
if (mThumbnail != null) {
- mThumbnailButton.setBitmap(mThumbnail.getBitmap());
+ mThumbnailView.setBitmap(mThumbnail.getBitmap());
} else {
- mThumbnailButton.setBitmap(null);
+ mThumbnailView.setBitmap(null);
}
}
@@ -1921,36 +1915,13 @@ public class VideoCamera extends ActivityBase
}
- private void createSharePopup() {
- if (mSharePopup != null) mSharePopup.dismiss();
- mSharePopup = new SharePopup(this, mThumbnail.getUri(),
- mThumbnail.getBitmap(), mOrientationCompensation, mThumbnailButton);
- mSharePopup.showAtLocation(mThumbnailButton, Gravity.NO_GRAVITY, 0, 0);
- }
-
- private void dismissSharePopup() {
- if (mSharePopup != null) {
- mSharePopup.dismiss();
- mSharePopup = null;
- }
- }
-
- private void onShareButtonClicked() {
- if (mPausing) return;
-
- // Share the last captured video.
- if (mThumbnail != null) {
- Intent intent = new Intent(Intent.ACTION_SEND);
- intent.setType("video/*");
- intent.putExtra(Intent.EXTRA_STREAM, mThumbnail.getUri());
- startActivity(Intent.createChooser(intent, getString(R.string.share_video_via)));
- } else { // No last picture
- if (mNoShareToast == null) {
- mNoShareToast = Toast.makeText(this,
- getResources().getString(R.string.no_video_to_share), Toast.LENGTH_SHORT);
- }
- mNoShareToast.show();
+ private void showSharePopup() {
+ Uri uri = mThumbnail.getUri();
+ if (mSharePopup == null || !uri.equals(mSharePopup.getUri())) {
+ mSharePopup = new SharePopup(this, uri, mThumbnail.getBitmap(),
+ "video/*", mOrientationCompensation, mShareButton);
}
+ mSharePopup.showAtLocation(mThumbnailView, Gravity.NO_GRAVITY, 0, 0);
}
private class MyIndicatorWheelListener implements IndicatorWheel.Listener {
@@ -1964,10 +1935,6 @@ public class VideoCamera extends ActivityBase
public void onOverriddenPreferencesClicked() {
}
-
- public void onShareButtonClicked() {
- VideoCamera.this.onShareButtonClicked();
- }
}
private class MyCameraPickerListener implements CameraPicker.Listener {
diff --git a/src/com/android/camera/ui/RotateLayout.java b/src/com/android/camera/ui/RotateLayout.java
index 6e1aa92..c900557 100644
--- a/src/com/android/camera/ui/RotateLayout.java
+++ b/src/com/android/camera/ui/RotateLayout.java
@@ -17,15 +17,14 @@
package com.android.camera.ui;
import android.content.Context;
-import android.graphics.Canvas;
import android.util.AttributeSet;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
// A RotateLayout is designed to display a single item and provides the
// capabilities to rotate the item.
class RotateLayout extends ViewGroup {
+ private static final String TAG = "RotateLayout";
private int mOrientation;
private View mChild;
@@ -36,6 +35,8 @@ class RotateLayout extends ViewGroup {
@Override
protected void onFinishInflate() {
mChild = getChildAt(0);
+ mChild.setPivotX(0);
+ mChild.setPivotY(0);
}
@Override
@@ -57,54 +58,42 @@ class RotateLayout extends ViewGroup {
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
+ int w = 0, h = 0;
switch(mOrientation) {
case 0:
case 180:
measureChild(mChild, widthSpec, heightSpec);
- setMeasuredDimension(mChild.getMeasuredWidth(), mChild.getMeasuredHeight());
+ w = mChild.getMeasuredWidth();
+ h = mChild.getMeasuredHeight();
break;
case 90:
case 270:
measureChild(mChild, heightSpec, widthSpec);
- setMeasuredDimension(mChild.getMeasuredHeight(), mChild.getMeasuredWidth());
+ w = mChild.getMeasuredHeight();
+ h = mChild.getMeasuredWidth();
break;
}
- }
+ setMeasuredDimension(w, h);
- @Override
- public void dispatchDraw(Canvas canvas) {
- int w = getWidth();
- int h = getHeight();
switch (mOrientation) {
+ case 0:
+ mChild.setTranslationX(0);
+ mChild.setTranslationY(0);
+ break;
case 90:
- canvas.translate(0, h);
- canvas.rotate(-mOrientation);
+ mChild.setTranslationX(0);
+ mChild.setTranslationY(h);
break;
case 180:
- canvas.rotate(-mOrientation, w / 2, h / 2);
+ mChild.setTranslationX(w);
+ mChild.setTranslationY(h);
break;
case 270:
- canvas.translate(w, 0);
- canvas.rotate(-mOrientation);
+ mChild.setTranslationX(w);
+ mChild.setTranslationY(0);
break;
}
- super.dispatchDraw(canvas);
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- float x = event.getX();
- float y = event.getY();
- float width = getWidth();
- float height = getHeight();
- switch (mOrientation) {
- case 90: event.setLocation(height - y, x); break;
- case 180: event.setLocation(width - x, height - y); break;
- case 270: event.setLocation(y, width - x); break;
- }
- boolean result = mChild.dispatchTouchEvent(event);
- event.setLocation(x, y);
- return result;
+ mChild.setRotation(-mOrientation);
}
// Rotate the view counter-clockwise
diff --git a/src/com/android/camera/ui/SharePopup.java b/src/com/android/camera/ui/SharePopup.java
index d182e2d..fc26c90 100644
--- a/src/com/android/camera/ui/SharePopup.java
+++ b/src/com/android/camera/ui/SharePopup.java
@@ -20,7 +20,11 @@ import com.android.camera.R;
import com.android.camera.Util;
import android.app.Activity;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
@@ -29,19 +33,41 @@ import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.WindowManager;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
+import android.widget.AdapterView;
import android.widget.ImageView;
+import android.widget.ListView;
import android.widget.PopupWindow;
+import android.widget.SimpleAdapter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
// A popup window that contains a big thumbnail and a list of apps to share.
public class SharePopup extends PopupWindow implements View.OnClickListener,
- View.OnTouchListener {
+ View.OnTouchListener, AdapterView.OnItemClickListener {
+ private static final String TAG = "SharePopup";
private Context mContext;
private Uri mUri;
+ private String mMimeType;
+ private ImageView mThumbnail;
+ private int mBitmapWidth;
+ private int mBitmapHeight;
+ // A view that contains a thumbnail and a share view.
+ private ViewGroup mRootView;
+ // A view that contains the title and the list of applications to share.
+ private View mShareView;
+ // The list of the applications to share.
+ private ListView mShareList;
+ // A rotated view that contains the share view.
+ private RotateLayout mShareViewRotateLayout;
+ // A rotated view that contains the thumbnail.
+ private RotateLayout mThumbnailRotateLayout;
+ private ArrayList<ComponentName> mComponent = new ArrayList<ComponentName>();
// The maximum width of the thumbnail in landscape orientation.
private final float mImageMaxWidthLandscape;
@@ -51,26 +77,31 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
private final float mImageMaxWidthPortrait;
// The maximum height of the thumbnail in portrait orientation.
private final float mImageMaxHeightPortrait;
+ // The width of the share list in landscape mode.
+ private final float mShareListWidthLandscape;
- private ImageView mThumbnail;
- private int mBitmapWidth, mBitmapHeight;
- private RotateLayout mRotateLayout;
-
- public SharePopup(Activity activity, Uri uri, Bitmap bitmap, int orientation, View anchor) {
+ public SharePopup(Activity activity, Uri uri, Bitmap bitmap, String mimeType, int orientation,
+ View anchor) {
super(activity);
- // Initailize variables
+ // Initialize variables
mContext = activity;
mUri = uri;
+ mMimeType = mimeType;
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
- View contentView = inflater.inflate(R.layout.share_popup, null, false);
+ ViewGroup sharePopup = (ViewGroup) inflater.inflate(R.layout.share_popup, null, false);
// This is required because popup window is full screen.
- contentView.setOnTouchListener(this);
- mRotateLayout = (RotateLayout) contentView.findViewById(R.id.rotate_layout);
- mThumbnail = (ImageView) contentView.findViewById(R.id.expanded_thumbnail);
+ sharePopup.setOnTouchListener(this);
+ mShareViewRotateLayout = (RotateLayout) sharePopup.findViewById(R.id.share_view_rotate_layout);
+ mThumbnailRotateLayout = (RotateLayout) sharePopup.findViewById(R.id.thumbnail_rotate_layout);
+ mShareList = (ListView) sharePopup.findViewById(R.id.share_list);
+ mShareView = sharePopup.findViewById(R.id.share_view);
+ mThumbnail = (ImageView) sharePopup.findViewById(R.id.thumbnail);
+ mRootView = (ViewGroup) sharePopup.findViewById(R.id.root);
mThumbnail.setImageBitmap(bitmap);
mThumbnail.setOnClickListener(this);
+ sharePopup.findViewById(R.id.collapse_button).setOnClickListener(this);
mBitmapWidth = bitmap.getWidth();
mBitmapHeight = bitmap.getHeight();
Resources res = mContext.getResources();
@@ -78,57 +109,77 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
mImageMaxHeightLandscape = res.getDimension(R.dimen.share_image_max_height_landscape);
mImageMaxWidthPortrait = res.getDimension(R.dimen.share_image_max_width_portrait);
mImageMaxHeightPortrait = res.getDimension(R.dimen.share_image_max_height_portrait);
+ mShareListWidthLandscape = res.getDimension(R.dimen.share_list_width_landscape);
// Initialize popup window
setWidth(WindowManager.LayoutParams.MATCH_PARENT);
setHeight(WindowManager.LayoutParams.MATCH_PARENT);
setBackgroundDrawable(new ColorDrawable());
- setContentView(contentView);
+ setContentView(sharePopup);
setOrientation(orientation);
+ setFocusable(true);
+ setAnimationStyle(R.style.AnimationPopup);
+
+ initializeLocation(activity, anchor);
- // Initialize view location
+ createShareMenu();
+ }
+
+ private void initializeLocation(Activity activity, View anchor) {
int location[] = new int[2];
anchor.getLocationOnScreen(location);
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
- MarginLayoutParams params = (MarginLayoutParams) mRotateLayout.getLayoutParams();
- params.topMargin = location[1] / 2;
- params.rightMargin = (metrics.widthPixels - location[0] - anchor.getWidth()) / 2;
- mRotateLayout.setLayoutParams(params);
-
- // Start animation
- Animation fadeIn = AnimationUtils.loadAnimation(mContext, R.anim.grow_fade_in_from_right);
- mRotateLayout.startAnimation(fadeIn);
+ MarginLayoutParams params = (MarginLayoutParams) mRootView.getLayoutParams();
+ params.topMargin = location[1];
+ params.rightMargin = (metrics.widthPixels - location[0] - anchor.getWidth());
+ mRootView.setLayoutParams(params);
}
public void setOrientation(int orientation) {
// Calculate the width and the height of the thumbnail.
- float width, height;
+ float maxWidth, maxHeight;
if (orientation == 90 || orientation == 270) {
- width = mImageMaxWidthPortrait;
- height = mImageMaxHeightPortrait;
+ maxWidth = mImageMaxWidthPortrait;
+ maxHeight = mImageMaxHeightPortrait;
} else {
- width = mImageMaxWidthLandscape;
- height = mImageMaxHeightLandscape;
+ maxWidth = mImageMaxWidthLandscape;
+ maxHeight = mImageMaxHeightLandscape;
}
+ float actualAspect = maxWidth / maxHeight;
+ float desiredAspect = (float) mBitmapWidth / mBitmapHeight;
+
LayoutParams params = mThumbnail.getLayoutParams();
- if (width * mBitmapHeight > height * mBitmapWidth) {
- params.width = Math.round(mBitmapWidth * height / mBitmapHeight);
- params.height = Math.round(height);
+ if (actualAspect > desiredAspect) {
+ params.width = Math.round(maxHeight * desiredAspect);
+ params.height = Math.round(maxHeight);
} else {
- params.width = Math.round(width);
- params.height = Math.round(mBitmapHeight * params.width / mBitmapWidth);
+ params.width = Math.round(maxWidth);
+ params.height = Math.round(maxWidth / desiredAspect);
}
mThumbnail.setLayoutParams(params);
- mRotateLayout.setOrientation(orientation);
+
+ // Calculate the width of the share application list.
+ LayoutParams shareListParams = mShareView.getLayoutParams();
+ if ((orientation == 90 || orientation == 270)) {
+ shareListParams.width = params.width;
+ } else {
+ shareListParams.width = (int) mShareListWidthLandscape;
+ }
+ mShareView.setLayoutParams(shareListParams);
+ if (mShareViewRotateLayout != null) mShareViewRotateLayout.setOrientation(orientation);
+ if (mThumbnailRotateLayout != null) mThumbnailRotateLayout.setOrientation(orientation);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
- case R.id.expanded_thumbnail:
+ case R.id.thumbnail:
Util.viewUri(mUri, mContext);
break;
+ case R.id.collapse_button:
+ dismiss();
+ break;
}
}
@@ -140,4 +191,42 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
}
return false;
}
+
+ public void createShareMenu() {
+ PackageManager packageManager = mContext.getPackageManager();
+ List<ResolveInfo> infos;
+ infos = packageManager.queryIntentActivities(
+ new Intent(Intent.ACTION_SEND).setType(mMimeType), 0);
+
+ ArrayList<HashMap<String, Object>> listItem =
+ new ArrayList<HashMap<String, Object>>();
+ for(ResolveInfo info: infos) {
+ String label = info.loadLabel(packageManager).toString();
+ ComponentName component = new ComponentName(
+ info.activityInfo.packageName, info.activityInfo.name);
+ HashMap<String, Object> map = new HashMap<String, Object>();
+ map.put("text", label);
+ listItem.add(map);
+ mComponent.add(component);
+ }
+ SimpleAdapter listItemAdapter = new SimpleAdapter(mContext, listItem,
+ R.layout.share_item,
+ new String[] {"text"},
+ new int[] {R.id.text});
+ mShareList.setAdapter(listItemAdapter);
+ mShareList.setOnItemClickListener(this);
+ }
+
+ public Uri getUri() {
+ return mUri;
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int index, long id) {
+ Intent intent = new Intent(Intent.ACTION_SEND);
+ intent.setType(mMimeType);
+ intent.putExtra(Intent.EXTRA_STREAM, mUri);
+ intent.setComponent(mComponent.get(index));
+ mContext.startActivity(intent);
+ }
}