summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml4
-rw-r--r--res/drawable-hdpi/bg_camera_pattern.jpgbin0 -> 28524 bytes
-rw-r--r--res/drawable-hdpi/bg_camera_pattern.pngbin59258 -> 0 bytes
-rw-r--r--res/drawable-hdpi/btn_coloreffect_aqua.jpgbin0 -> 9806 bytes
-rw-r--r--res/drawable-hdpi/btn_coloreffect_bluetint.jpgbin0 -> 12850 bytes
-rw-r--r--res/drawable-hdpi/btn_coloreffect_greentint.jpgbin0 -> 12583 bytes
-rw-r--r--res/drawable-hdpi/btn_coloreffect_mono.jpgbin0 -> 9627 bytes
-rw-r--r--res/drawable-hdpi/btn_coloreffect_negative.jpgbin0 -> 11667 bytes
-rw-r--r--res/drawable-hdpi/btn_coloreffect_none.jpgbin0 -> 11957 bytes
-rw-r--r--res/drawable-hdpi/btn_coloreffect_posterize.jpgbin0 -> 14165 bytes
-rw-r--r--res/drawable-hdpi/btn_coloreffect_redtint.jpgbin0 -> 12213 bytes
-rw-r--r--res/drawable-hdpi/btn_coloreffect_sepia.jpgbin0 -> 9928 bytes
-rw-r--r--res/drawable-hdpi/btn_coloreffect_solarize.jpgbin0 -> 11307 bytes
-rw-r--r--res/drawable-hdpi/ic_viewfinder_coloreffect.pngbin0 -> 608 bytes
-rw-r--r--res/drawable-hdpi/ic_viewfinder_coloreffects.pngbin0 -> 568 bytes
-rw-r--r--res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.pngbin0 -> 561 bytes
-rw-r--r--res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_480p.pngbin0 -> 659 bytes
-rw-r--r--res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.pngbin0 -> 553 bytes
-rw-r--r--res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.pngbin0 -> 422 bytes
-rw-r--r--res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.pngbin0 -> 518 bytes
-rw-r--r--res/drawable-mdpi/bg_camera_pattern.jpgbin0 -> 28524 bytes
-rwxr-xr-xres/drawable-mdpi/bg_camera_pattern.pngbin25868 -> 0 bytes
-rw-r--r--res/drawable-mdpi/btn_coloreffect_aqua.jpgbin0 -> 9806 bytes
-rw-r--r--res/drawable-mdpi/btn_coloreffect_bluetint.jpgbin0 -> 12850 bytes
-rw-r--r--res/drawable-mdpi/btn_coloreffect_greentint.jpgbin0 -> 12583 bytes
-rw-r--r--res/drawable-mdpi/btn_coloreffect_mono.jpgbin0 -> 9627 bytes
-rw-r--r--res/drawable-mdpi/btn_coloreffect_negative.jpgbin0 -> 11667 bytes
-rw-r--r--res/drawable-mdpi/btn_coloreffect_none.jpgbin0 -> 11957 bytes
-rw-r--r--res/drawable-mdpi/btn_coloreffect_posterize.jpgbin0 -> 14165 bytes
-rw-r--r--res/drawable-mdpi/btn_coloreffect_redtint.jpgbin0 -> 12213 bytes
-rw-r--r--res/drawable-mdpi/btn_coloreffect_sepia.jpgbin0 -> 9928 bytes
-rw-r--r--res/drawable-mdpi/btn_coloreffect_solarize.jpgbin0 -> 11307 bytes
-rw-r--r--res/drawable-mdpi/btn_wb_auto.jpgbin0 -> 9622 bytes
-rw-r--r--res/drawable-mdpi/btn_wb_cloudy.jpgbin0 -> 7838 bytes
-rw-r--r--res/drawable-mdpi/btn_wb_daylight.jpgbin0 -> 6458 bytes
-rw-r--r--res/drawable-mdpi/btn_wb_fluorescent.jpgbin0 -> 16925 bytes
-rw-r--r--res/drawable-mdpi/btn_wb_incandescent.jpgbin0 -> 9928 bytes
-rw-r--r--res/drawable-mdpi/ic_viewfinder_coloreffect.pngbin0 -> 608 bytes
-rw-r--r--res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.pngbin0 -> 871 bytes
-rw-r--r--res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_480p.pngbin0 -> 981 bytes
-rw-r--r--res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.pngbin0 -> 972 bytes
-rw-r--r--res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.pngbin0 -> 808 bytes
-rw-r--r--res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.pngbin0 -> 736 bytes
-rwxr-xr-xres/drawable-mdpi/zoompicker_down_normal.9.pngbin0 -> 795 bytes
-rwxr-xr-xres/drawable-mdpi/zoompicker_down_pressed.9.pngbin0 -> 1161 bytes
-rwxr-xr-xres/drawable-mdpi/zoompicker_up_normal.9.pngbin0 -> 989 bytes
-rwxr-xr-xres/drawable-mdpi/zoompicker_up_pressed.9.pngbin0 -> 1433 bytes
-rw-r--r--res/drawable/btn_setting_picker.xml20
-rw-r--r--res/drawable/btn_zoom_picker_down.xml20
-rw-r--r--res/drawable/btn_zoom_picker_up.xml20
-rw-r--r--res/drawable/camera_background.xml4
-rw-r--r--res/layout-xlarge/attach_camera_control.xml80
-rw-r--r--res/layout-xlarge/basic_setting_picker.xml38
-rw-r--r--res/layout-xlarge/camera_control.xml110
-rw-r--r--res/layout-xlarge/in_line_setting_picker.xml51
-rw-r--r--res/layout-xlarge/other_setting_popup.xml66
-rw-r--r--res/layout-xlarge/setting_image_item.xml26
-rw-r--r--res/layout-xlarge/setting_scale_image_item.xml27
-rw-r--r--res/layout-xlarge/setting_text_item.xml25
-rw-r--r--res/layout-xlarge/video_camera.xml41
-rw-r--r--res/layout-xlarge/zoom_picker.xml43
-rw-r--r--res/layout/camera.xml1
-rw-r--r--res/layout/thumbnail_item.xml21
-rw-r--r--res/layout/video_camera.xml18
-rw-r--r--res/values-cs/strings.xml16
-rw-r--r--res/values-da/strings.xml16
-rw-r--r--res/values-de/strings.xml16
-rw-r--r--res/values-el/strings.xml16
-rw-r--r--res/values-es-rUS/strings.xml13
-rw-r--r--res/values-es/strings.xml16
-rw-r--r--res/values-fr/strings.xml16
-rw-r--r--res/values-it/strings.xml16
-rw-r--r--res/values-ja/strings.xml16
-rw-r--r--res/values-ko/strings.xml16
-rw-r--r--res/values-nb/strings.xml16
-rw-r--r--res/values-nl/strings.xml16
-rw-r--r--res/values-pl/strings.xml16
-rw-r--r--res/values-pt-rPT/strings.xml16
-rw-r--r--res/values-pt/strings.xml16
-rw-r--r--res/values-ru/strings.xml16
-rw-r--r--res/values-sv/strings.xml16
-rw-r--r--res/values-tr/strings.xml16
-rw-r--r--res/values-zh-rCN/strings.xml16
-rw-r--r--res/values-zh-rTW/strings.xml16
-rw-r--r--res/values/arrays.xml119
-rw-r--r--res/values/attrs.xml4
-rw-r--r--res/values/colors.xml1
-rw-r--r--res/values/ids.xml19
-rw-r--r--res/values/strings.xml52
-rw-r--r--res/values/styles.xml26
-rw-r--r--res/xml/camera_preferences.xml21
-rw-r--r--res/xml/video_preferences.xml32
-rw-r--r--src/com/android/camera/Camera.java418
-rw-r--r--src/com/android/camera/CameraHolder.java8
-rw-r--r--src/com/android/camera/CameraSettings.java30
-rw-r--r--src/com/android/camera/IconListPreference.java38
-rw-r--r--src/com/android/camera/MenuHelper.java1
-rw-r--r--src/com/android/camera/RotateImageView.java147
-rw-r--r--src/com/android/camera/ThumbnailAdapter.java101
-rw-r--r--src/com/android/camera/ThumbnailController.java195
-rw-r--r--src/com/android/camera/Util.java56
-rw-r--r--src/com/android/camera/VideoCamera.java736
-rw-r--r--src/com/android/camera/ui/BasicIndicator.java50
-rw-r--r--src/com/android/camera/ui/BasicSettingPicker.java120
-rw-r--r--src/com/android/camera/ui/CamcorderHeadUpDisplay.java15
-rw-r--r--src/com/android/camera/ui/ControlPanel.java209
-rw-r--r--src/com/android/camera/ui/GLLinearLayout.java (renamed from src/com/android/camera/ui/LinearLayout.java)2
-rw-r--r--src/com/android/camera/ui/GLListView.java27
-rw-r--r--src/com/android/camera/ui/GLPopupWindow.java (renamed from src/com/android/camera/ui/PopupWindow.java)9
-rw-r--r--src/com/android/camera/ui/GLRootView.java10
-rw-r--r--src/com/android/camera/ui/GLView.java24
-rw-r--r--src/com/android/camera/ui/GpsIndicator.java2
-rw-r--r--src/com/android/camera/ui/HeadUpDisplay.java29
-rw-r--r--src/com/android/camera/ui/InLineSettingPicker.java142
-rw-r--r--src/com/android/camera/ui/IndicatorButton.java38
-rw-r--r--src/com/android/camera/ui/IndicatorWheel.java170
-rw-r--r--src/com/android/camera/ui/OtherSettingsPopup.java64
-rw-r--r--src/com/android/camera/ui/RotatePane.java8
-rw-r--r--src/com/android/camera/ui/ZoomIndicator.java4
-rw-r--r--src/com/android/camera/ui/ZoomPicker.java155
-rwxr-xr-xtests/src/com/android/camera/stress/CameraLatency.java3
-rwxr-xr-xtests/src/com/android/camera/stress/ImageCapture.java5
122 files changed, 3242 insertions, 780 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9cdd779..14bf99e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -27,7 +27,7 @@
</receiver>
<activity android:name="com.android.camera.Camera"
android:configChanges="orientation|keyboardHidden"
- android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
+ android:theme="@style/ThemeCamera"
android:screenOrientation="landscape"
android:clearTaskOnLaunch="true"
android:taskAffinity="android.task.camera">
@@ -49,7 +49,7 @@
android:label="@string/video_camera_label"
android:configChanges="orientation|keyboardHidden"
android:icon="@drawable/ic_launcher_video_camera"
- android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
+ android:theme="@style/ThemeCamera"
android:screenOrientation="landscape"
android:clearTaskOnLaunch="true"
android:taskAffinity="android.task.camcorder">
diff --git a/res/drawable-hdpi/bg_camera_pattern.jpg b/res/drawable-hdpi/bg_camera_pattern.jpg
new file mode 100644
index 0000000..d0c290f
--- /dev/null
+++ b/res/drawable-hdpi/bg_camera_pattern.jpg
Binary files differ
diff --git a/res/drawable-hdpi/bg_camera_pattern.png b/res/drawable-hdpi/bg_camera_pattern.png
deleted file mode 100644
index c11b9c4..0000000
--- a/res/drawable-hdpi/bg_camera_pattern.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/btn_coloreffect_aqua.jpg b/res/drawable-hdpi/btn_coloreffect_aqua.jpg
new file mode 100644
index 0000000..d3ca021
--- /dev/null
+++ b/res/drawable-hdpi/btn_coloreffect_aqua.jpg
Binary files differ
diff --git a/res/drawable-hdpi/btn_coloreffect_bluetint.jpg b/res/drawable-hdpi/btn_coloreffect_bluetint.jpg
new file mode 100644
index 0000000..1bfc582
--- /dev/null
+++ b/res/drawable-hdpi/btn_coloreffect_bluetint.jpg
Binary files differ
diff --git a/res/drawable-hdpi/btn_coloreffect_greentint.jpg b/res/drawable-hdpi/btn_coloreffect_greentint.jpg
new file mode 100644
index 0000000..7de8c42
--- /dev/null
+++ b/res/drawable-hdpi/btn_coloreffect_greentint.jpg
Binary files differ
diff --git a/res/drawable-hdpi/btn_coloreffect_mono.jpg b/res/drawable-hdpi/btn_coloreffect_mono.jpg
new file mode 100644
index 0000000..d0477d7
--- /dev/null
+++ b/res/drawable-hdpi/btn_coloreffect_mono.jpg
Binary files differ
diff --git a/res/drawable-hdpi/btn_coloreffect_negative.jpg b/res/drawable-hdpi/btn_coloreffect_negative.jpg
new file mode 100644
index 0000000..4a6bf34
--- /dev/null
+++ b/res/drawable-hdpi/btn_coloreffect_negative.jpg
Binary files differ
diff --git a/res/drawable-hdpi/btn_coloreffect_none.jpg b/res/drawable-hdpi/btn_coloreffect_none.jpg
new file mode 100644
index 0000000..9131f79
--- /dev/null
+++ b/res/drawable-hdpi/btn_coloreffect_none.jpg
Binary files differ
diff --git a/res/drawable-hdpi/btn_coloreffect_posterize.jpg b/res/drawable-hdpi/btn_coloreffect_posterize.jpg
new file mode 100644
index 0000000..09fb1d1
--- /dev/null
+++ b/res/drawable-hdpi/btn_coloreffect_posterize.jpg
Binary files differ
diff --git a/res/drawable-hdpi/btn_coloreffect_redtint.jpg b/res/drawable-hdpi/btn_coloreffect_redtint.jpg
new file mode 100644
index 0000000..b88ebe9
--- /dev/null
+++ b/res/drawable-hdpi/btn_coloreffect_redtint.jpg
Binary files differ
diff --git a/res/drawable-hdpi/btn_coloreffect_sepia.jpg b/res/drawable-hdpi/btn_coloreffect_sepia.jpg
new file mode 100644
index 0000000..192a05b
--- /dev/null
+++ b/res/drawable-hdpi/btn_coloreffect_sepia.jpg
Binary files differ
diff --git a/res/drawable-hdpi/btn_coloreffect_solarize.jpg b/res/drawable-hdpi/btn_coloreffect_solarize.jpg
new file mode 100644
index 0000000..8a37b79
--- /dev/null
+++ b/res/drawable-hdpi/btn_coloreffect_solarize.jpg
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_coloreffect.png b/res/drawable-hdpi/ic_viewfinder_coloreffect.png
new file mode 100644
index 0000000..975b08b
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_coloreffect.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_coloreffects.png b/res/drawable-hdpi/ic_viewfinder_coloreffects.png
new file mode 100644
index 0000000..1d65e4b
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_coloreffects.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
new file mode 100644
index 0000000..d2a39e4
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_480p.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_480p.png
new file mode 100644
index 0000000..398a4b9
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_480p.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.png
new file mode 100644
index 0000000..5567eb0
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_720p.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.png
new file mode 100644
index 0000000..ce0cf42
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_high.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.png b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.png
new file mode 100644
index 0000000..cb66c52
--- /dev/null
+++ b/res/drawable-hdpi/ic_viewfinder_video_time_lapse_quality_low.png
Binary files differ
diff --git a/res/drawable-mdpi/bg_camera_pattern.jpg b/res/drawable-mdpi/bg_camera_pattern.jpg
new file mode 100644
index 0000000..d0c290f
--- /dev/null
+++ b/res/drawable-mdpi/bg_camera_pattern.jpg
Binary files differ
diff --git a/res/drawable-mdpi/bg_camera_pattern.png b/res/drawable-mdpi/bg_camera_pattern.png
deleted file mode 100755
index e9c67ff..0000000
--- a/res/drawable-mdpi/bg_camera_pattern.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/btn_coloreffect_aqua.jpg b/res/drawable-mdpi/btn_coloreffect_aqua.jpg
new file mode 100644
index 0000000..d3ca021
--- /dev/null
+++ b/res/drawable-mdpi/btn_coloreffect_aqua.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_coloreffect_bluetint.jpg b/res/drawable-mdpi/btn_coloreffect_bluetint.jpg
new file mode 100644
index 0000000..1bfc582
--- /dev/null
+++ b/res/drawable-mdpi/btn_coloreffect_bluetint.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_coloreffect_greentint.jpg b/res/drawable-mdpi/btn_coloreffect_greentint.jpg
new file mode 100644
index 0000000..7de8c42
--- /dev/null
+++ b/res/drawable-mdpi/btn_coloreffect_greentint.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_coloreffect_mono.jpg b/res/drawable-mdpi/btn_coloreffect_mono.jpg
new file mode 100644
index 0000000..d0477d7
--- /dev/null
+++ b/res/drawable-mdpi/btn_coloreffect_mono.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_coloreffect_negative.jpg b/res/drawable-mdpi/btn_coloreffect_negative.jpg
new file mode 100644
index 0000000..4a6bf34
--- /dev/null
+++ b/res/drawable-mdpi/btn_coloreffect_negative.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_coloreffect_none.jpg b/res/drawable-mdpi/btn_coloreffect_none.jpg
new file mode 100644
index 0000000..9131f79
--- /dev/null
+++ b/res/drawable-mdpi/btn_coloreffect_none.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_coloreffect_posterize.jpg b/res/drawable-mdpi/btn_coloreffect_posterize.jpg
new file mode 100644
index 0000000..09fb1d1
--- /dev/null
+++ b/res/drawable-mdpi/btn_coloreffect_posterize.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_coloreffect_redtint.jpg b/res/drawable-mdpi/btn_coloreffect_redtint.jpg
new file mode 100644
index 0000000..b88ebe9
--- /dev/null
+++ b/res/drawable-mdpi/btn_coloreffect_redtint.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_coloreffect_sepia.jpg b/res/drawable-mdpi/btn_coloreffect_sepia.jpg
new file mode 100644
index 0000000..192a05b
--- /dev/null
+++ b/res/drawable-mdpi/btn_coloreffect_sepia.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_coloreffect_solarize.jpg b/res/drawable-mdpi/btn_coloreffect_solarize.jpg
new file mode 100644
index 0000000..8a37b79
--- /dev/null
+++ b/res/drawable-mdpi/btn_coloreffect_solarize.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_wb_auto.jpg b/res/drawable-mdpi/btn_wb_auto.jpg
new file mode 100644
index 0000000..a706162
--- /dev/null
+++ b/res/drawable-mdpi/btn_wb_auto.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_wb_cloudy.jpg b/res/drawable-mdpi/btn_wb_cloudy.jpg
new file mode 100644
index 0000000..40b76aa
--- /dev/null
+++ b/res/drawable-mdpi/btn_wb_cloudy.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_wb_daylight.jpg b/res/drawable-mdpi/btn_wb_daylight.jpg
new file mode 100644
index 0000000..7f4b645
--- /dev/null
+++ b/res/drawable-mdpi/btn_wb_daylight.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_wb_fluorescent.jpg b/res/drawable-mdpi/btn_wb_fluorescent.jpg
new file mode 100644
index 0000000..e81d071
--- /dev/null
+++ b/res/drawable-mdpi/btn_wb_fluorescent.jpg
Binary files differ
diff --git a/res/drawable-mdpi/btn_wb_incandescent.jpg b/res/drawable-mdpi/btn_wb_incandescent.jpg
new file mode 100644
index 0000000..db9bf2b
--- /dev/null
+++ b/res/drawable-mdpi/btn_wb_incandescent.jpg
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_coloreffect.png b/res/drawable-mdpi/ic_viewfinder_coloreffect.png
new file mode 100644
index 0000000..975b08b
--- /dev/null
+++ b/res/drawable-mdpi/ic_viewfinder_coloreffect.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
new file mode 100644
index 0000000..199e0ef
--- /dev/null
+++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_1080p.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_480p.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_480p.png
new file mode 100644
index 0000000..e0b4974
--- /dev/null
+++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_480p.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.png
new file mode 100644
index 0000000..1104ce5
--- /dev/null
+++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_720p.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.png
new file mode 100644
index 0000000..8b99109
--- /dev/null
+++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_high.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.png b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.png
new file mode 100644
index 0000000..36e2c1a
--- /dev/null
+++ b/res/drawable-mdpi/ic_viewfinder_video_time_lapse_quality_low.png
Binary files differ
diff --git a/res/drawable-mdpi/zoompicker_down_normal.9.png b/res/drawable-mdpi/zoompicker_down_normal.9.png
new file mode 100755
index 0000000..f17e8f9
--- /dev/null
+++ b/res/drawable-mdpi/zoompicker_down_normal.9.png
Binary files differ
diff --git a/res/drawable-mdpi/zoompicker_down_pressed.9.png b/res/drawable-mdpi/zoompicker_down_pressed.9.png
new file mode 100755
index 0000000..777bcf5
--- /dev/null
+++ b/res/drawable-mdpi/zoompicker_down_pressed.9.png
Binary files differ
diff --git a/res/drawable-mdpi/zoompicker_up_normal.9.png b/res/drawable-mdpi/zoompicker_up_normal.9.png
new file mode 100755
index 0000000..dcd26e0
--- /dev/null
+++ b/res/drawable-mdpi/zoompicker_up_normal.9.png
Binary files differ
diff --git a/res/drawable-mdpi/zoompicker_up_pressed.9.png b/res/drawable-mdpi/zoompicker_up_pressed.9.png
new file mode 100755
index 0000000..7dac778
--- /dev/null
+++ b/res/drawable-mdpi/zoompicker_up_pressed.9.png
Binary files differ
diff --git a/res/drawable/btn_setting_picker.xml b/res/drawable/btn_setting_picker.xml
new file mode 100644
index 0000000..4ecfe95
--- /dev/null
+++ b/res/drawable/btn_setting_picker.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:color="@android:color/white" />
+ <item android:color="@android:color/darker_gray" />
+</selector>
diff --git a/res/drawable/btn_zoom_picker_down.xml b/res/drawable/btn_zoom_picker_down.xml
new file mode 100644
index 0000000..38f1270
--- /dev/null
+++ b/res/drawable/btn_zoom_picker_down.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@drawable/zoompicker_down_pressed" />
+ <item android:drawable="@drawable/zoompicker_down_normal" />
+</selector>
diff --git a/res/drawable/btn_zoom_picker_up.xml b/res/drawable/btn_zoom_picker_up.xml
new file mode 100644
index 0000000..0a2249b
--- /dev/null
+++ b/res/drawable/btn_zoom_picker_up.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@drawable/zoompicker_up_pressed" />
+ <item android:drawable="@drawable/zoompicker_up_normal" />
+</selector>
diff --git a/res/drawable/camera_background.xml b/res/drawable/camera_background.xml
deleted file mode 100644
index 4f04754..0000000
--- a/res/drawable/camera_background.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/bg_camera_pattern"
- android:tileMode="repeat" />
diff --git a/res/layout-xlarge/attach_camera_control.xml b/res/layout-xlarge/attach_camera_control.xml
new file mode 100644
index 0000000..0eab2e6
--- /dev/null
+++ b/res/layout-xlarge/attach_camera_control.xml
@@ -0,0 +1,80 @@
+<?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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:camera="http://schemas.android.com/apk/res/com.android.camera"
+ android:id="@+id/control_bar"
+ android:layout_height="match_parent"
+ android:layout_width="90dp"
+ android:layout_marginTop="20dp"
+ android:layout_marginBottom="20dp"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:layout_alignParentRight="true">
+ <LinearLayout android:orientation="vertical"
+ android:gravity="top|center_horizontal"
+ android:layout_alignParentTop="true"
+ android:layout_centerHorizontal="true"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent">
+ <LinearLayout style="@style/ReviewControlGroup"
+ android:layout_marginBottom="15dp">
+ <ImageView style="@style/ReviewControlIcon"
+ android:id="@+id/btn_cancel"
+ android:src="@drawable/btn_ic_review_cancel"/>
+ <TextView style="@style/ReviewControlText"
+ android:text="@string/review_cancel" />
+ </LinearLayout>
+ <LinearLayout style="@style/ReviewControlGroup"
+ android:visibility="gone"
+ android:layout_marginBottom="15dp">
+ <ImageView style="@style/ReviewControlIcon"
+ android:id="@+id/btn_retake"
+ android:src="@drawable/btn_ic_review_retake_photo"/>
+ <TextView style="@style/ReviewControlText"
+ android:text="@string/review_retake" />
+ </LinearLayout>
+ <LinearLayout style="@style/ReviewControlGroup"
+ android:visibility="gone"
+ android:layout_marginBottom="15dp">
+ <ImageView style="@style/ReviewControlIcon"
+ android:id="@+id/btn_play"
+ android:src="@drawable/btn_ic_review_play"/>
+ <TextView style="@style/ReviewControlText"
+ android:text="@string/review_play" />
+ </LinearLayout>
+ </LinearLayout>
+ <com.android.camera.ShutterButton android:id="@+id/shutter_button"
+ android:layout_centerInParent="true"
+ android:layout_centerHorizontal="true"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:scaleType="center"
+ android:clickable="true"
+ android:focusable="true"
+ android:src="@drawable/btn_ic_camera_shutter"
+ android:background="@drawable/btn_shutter"/>
+ <LinearLayout style="@style/ReviewControlGroup"
+ android:visibility="invisible"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true">
+ <ImageView style="@style/ReviewControlIcon"
+ android:id="@+id/btn_done"
+ android:src="@drawable/btn_ic_review_done"/>
+ <TextView style="@style/ReviewControlText"
+ android:text="@string/review_ok" />
+ </LinearLayout>
+</RelativeLayout>
diff --git a/res/layout-xlarge/basic_setting_picker.xml b/res/layout-xlarge/basic_setting_picker.xml
new file mode 100644
index 0000000..88b03ef
--- /dev/null
+++ b/res/layout-xlarge/basic_setting_picker.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+
+<com.android.camera.ui.BasicSettingPicker xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="96dp"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentLeft="true"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp"
+ android:dividerHeight="6dp" >
+
+ <Button android:id="@+id/setting_exit"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:gravity="center"
+ android:text="@string/camera_setting_picker_exit" />
+</com.android.camera.ui.BasicSettingPicker>
diff --git a/res/layout-xlarge/camera_control.xml b/res/layout-xlarge/camera_control.xml
new file mode 100644
index 0000000..82ddc55
--- /dev/null
+++ b/res/layout-xlarge/camera_control.xml
@@ -0,0 +1,110 @@
+<?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.
+-->
+
+<com.android.camera.ui.ControlPanel xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:camera="http://schemas.android.com/apk/res/com.android.camera"
+ android:id="@+id/control_panel"
+ android:layout_height="match_parent"
+ android:layout_width="240dp"
+ android:layout_marginTop="20dp"
+ android:layout_marginBottom="20dp"
+ android:layout_marginLeft="10dp"
+ android:layout_marginRight="10dp">
+
+ <ListView android:id="@+id/thumbnail_list"
+ android:layout_width="96dp"
+ android:layout_height="match_parent"
+ android:dividerHeight="6dp"
+ android:orientation="vertical"
+ android:gravity="center">
+ </ListView>
+
+ <RelativeLayout
+ android:layout_width="134dp"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="10dp"
+ android:layout_alignParentRight="true">
+
+ <ViewStub android:id="@+id/zoom_stub"
+ android:inflatedId="@+id/zoom_picker"
+ android:layout="@layout/zoom_picker"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp" />
+
+ <TextView android:id="@+id/recording_time"
+ style="@style/RecordingTime"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:layout_marginTop="20dp"
+ android:layout_marginRight="10dp"
+ android:drawablePadding="8dp"
+ android:drawableLeft="@drawable/ic_recording_indicator"
+ android:visibility="gone" />
+
+ <TextView android:id="@+id/time_lapse_recording_time"
+ style="@style/RecordingTime"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/recording_time"
+ android:layout_alignParentRight="true"
+ android:visibility="gone" />
+
+ <com.android.camera.ui.IndicatorWheel android:id="@+id/indicator_wheel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:layout_alignParentRight="true">
+ <com.android.camera.ShutterButton android:id="@+id/shutter_button"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:scaleType="center"
+ android:clickable="true"
+ android:focusable="true"
+ android:src="@drawable/btn_ic_camera_shutter"
+ android:background="@drawable/btn_shutter" />
+ </com.android.camera.ui.IndicatorWheel>
+
+ <LinearLayout android:id="@+id/camera_switch_set"
+ android:orientation="vertical"
+ android:gravity="center"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentRight="true"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginRight="17dp">
+ <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"
+ android:layout_width="wrap_content"
+ android:layout_height="70dp"
+ android:src="@drawable/btn_mode_switch_knob"
+ android:background="@drawable/btn_mode_switch_bg" />
+ <com.android.camera.RotateImageView
+ android:id="@+id/camera_switch_icon"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:src="@drawable/btn_ic_mode_switch_camera"/>
+ </LinearLayout>
+ </RelativeLayout>
+</com.android.camera.ui.ControlPanel>
+
diff --git a/res/layout-xlarge/in_line_setting_picker.xml b/res/layout-xlarge/in_line_setting_picker.xml
new file mode 100644
index 0000000..a2387ae
--- /dev/null
+++ b/res/layout-xlarge/in_line_setting_picker.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+ <Button android:id="@+id/decrement"
+ android:layout_width="24dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:gravity="center"
+ android:text="@string/setting_decrement"
+ android:textColor="@drawable/btn_setting_picker"
+ android:textSize="20dp"
+ android:textStyle="bold"
+ android:background="@android:color/transparent" />
+
+ <TextView android:id="@+id/current_setting"
+ android:layout_width="130dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textColor="@android:color/white"
+ android:textSize="20dp" />
+
+ <Button android:id="@+id/increment"
+ android:layout_width="24dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:gravity="center"
+ android:text="@string/setting_increment"
+ android:textColor="@drawable/btn_setting_picker"
+ android:textSize="20dp"
+ android:textStyle="bold"
+ android:background="@android:color/transparent" />
+</merge>
diff --git a/res/layout-xlarge/other_setting_popup.xml b/res/layout-xlarge/other_setting_popup.xml
new file mode 100644
index 0000000..9d5ccfe
--- /dev/null
+++ b/res/layout-xlarge/other_setting_popup.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:camera="http://schemas.android.com/apk/res/com.android.camera"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" >
+
+ <TableRow style="@style/OtherSettingTableRow">
+ <TextView android:text="@string/pref_camera_recordlocation_title"
+ style="@style/SettingPickerText" />
+ <com.android.camera.ui.InLineSettingPicker
+ camera:prefKey="pref_camera_recordlocation_key" />
+ </TableRow>
+
+ <TableRow style="@style/OtherSettingTableRow">
+ <TextView android:text="@string/pref_camera_focusmode_title"
+ style="@style/SettingPickerText" />
+ <com.android.camera.ui.InLineSettingPicker
+ camera:prefKey="pref_camera_focusmode_key" />
+ </TableRow>
+
+ <TableRow style="@style/OtherSettingTableRow">
+ <TextView android:text="@string/pref_exposure_title"
+ style="@style/SettingPickerText" />
+ <com.android.camera.ui.InLineSettingPicker
+ camera:prefKey="pref_camera_exposure_key" />
+ </TableRow>
+
+ <TableRow style="@style/OtherSettingTableRow">
+ <TextView android:text="@string/pref_camera_picturesize_title"
+ style="@style/SettingPickerText" />
+ <com.android.camera.ui.InLineSettingPicker
+ camera:prefKey="pref_camera_picturesize_key" />
+ </TableRow>
+
+ <TableRow style="@style/OtherSettingTableRow">
+ <TextView android:text="@string/pref_camera_jpegquality_title"
+ style="@style/SettingPickerText" />
+ <com.android.camera.ui.InLineSettingPicker
+ camera:prefKey="pref_camera_jpegquality_key" />
+ </TableRow>
+
+ <TableRow style="@style/OtherSettingTableRow">
+ <TextView android:text="@string/pref_camera_scenemode_title"
+ style="@style/SettingPickerText" />
+ <com.android.camera.ui.InLineSettingPicker
+ camera:prefKey="pref_camera_scenemode_key" />
+ </TableRow>
+</TableLayout>
diff --git a/res/layout-xlarge/setting_image_item.xml b/res/layout-xlarge/setting_image_item.xml
new file mode 100644
index 0000000..a928cc7
--- /dev/null
+++ b/res/layout-xlarge/setting_image_item.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:gravity="center"
+ android:scaleType="fitCenter"
+ android:adjustViewBounds="true" />
+
diff --git a/res/layout-xlarge/setting_scale_image_item.xml b/res/layout-xlarge/setting_scale_image_item.xml
new file mode 100644
index 0000000..c5988fb
--- /dev/null
+++ b/res/layout-xlarge/setting_scale_image_item.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="96dp"
+ android:layout_height="96dp"
+ android:layout_marginTop="10dp"
+ android:gravity="center"
+ android:scaleType="fitCenter"
+ android:minHeight="96dp"
+ android:minWidth="96dp" />
+
diff --git a/res/layout-xlarge/setting_text_item.xml b/res/layout-xlarge/setting_text_item.xml
new file mode 100644
index 0000000..63085b3
--- /dev/null
+++ b/res/layout-xlarge/setting_text_item.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textColor="@drawable/btn_setting_picker"
+ android:textSize="16dp" />
diff --git a/res/layout-xlarge/video_camera.xml b/res/layout-xlarge/video_camera.xml
new file mode 100644
index 0000000..d20a9b3
--- /dev/null
+++ b/res/layout-xlarge/video_camera.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:camera="http://schemas.android.com/apk/res/com.android.camera"
+ android:id="@+id/video_camera"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <com.android.camera.PreviewFrameLayout android:id="@+id/frame_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="2dip"
+ android:layout_weight="1">
+ <FrameLayout android:id="@+id/frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/border_view_finder">
+ <SurfaceView android:id="@+id/camera_preview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+ <ImageView android:id="@+id/video_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
+ </FrameLayout>
+ </com.android.camera.PreviewFrameLayout>
+</LinearLayout>
diff --git a/res/layout-xlarge/zoom_picker.xml b/res/layout-xlarge/zoom_picker.xml
new file mode 100644
index 0000000..fa373f4
--- /dev/null
+++ b/res/layout-xlarge/zoom_picker.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+
+<com.android.camera.ui.ZoomPicker xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView android:id="@+id/zoom_ratio"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:singleLine="true"
+ android:textColor="@android:color/white"
+ android:textSize="24dp" />
+
+ <Button android:id="@+id/increment"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dp"
+ android:background="@drawable/btn_zoom_picker_up" />
+
+ <Button android:id="@+id/decrement"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@drawable/btn_zoom_picker_down" />
+</com.android.camera.ui.ZoomPicker>
diff --git a/res/layout/camera.xml b/res/layout/camera.xml
index 772106b..182084a 100644
--- a/res/layout/camera.xml
+++ b/res/layout/camera.xml
@@ -16,7 +16,6 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:camera="http://schemas.android.com/apk/res/com.android.camera"
- android:background="@drawable/camera_background"
android:id="@+id/camera"
android:orientation="horizontal"
android:layout_width="match_parent"
diff --git a/res/layout/thumbnail_item.xml b/res/layout/thumbnail_item.xml
new file mode 100644
index 0000000..3e67ee4
--- /dev/null
+++ b/res/layout/thumbnail_item.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+<com.android.camera.RotateImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:layout_height="96dp"
+ android:layout_width="96dp"
+ android:background="@drawable/border_last_picture"/>
diff --git a/res/layout/video_camera.xml b/res/layout/video_camera.xml
index ea4cf51..8130971 100644
--- a/res/layout/video_camera.xml
+++ b/res/layout/video_camera.xml
@@ -17,7 +17,6 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:camera="http://schemas.android.com/apk/res/com.android.camera"
android:id="@+id/video_camera"
- android:background="@drawable/camera_background"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -41,23 +40,16 @@
attribute is required because otherwise the
text's drop shadow will be clipped. -->
<TextView android:id="@+id/recording_time"
- android:layout_width="180dp"
+ style="@style/RecordingTime"
+ android:drawablePadding="8dp"
+ android:drawableLeft="@drawable/ic_recording_indicator"
+ android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_gravity="left|bottom"
android:layout_marginBottom="13dp"
android:layout_marginLeft="17dp"
android:paddingRight="2dp"
- android:drawablePadding="8dp"
- android:drawableLeft="@drawable/ic_recording_indicator"
- android:shadowColor="#c0000000"
- android:shadowDx="1"
- android:shadowDy="1"
- android:shadowRadius="1"
- android:gravity="left|center_vertical"
- android:textColor="@color/recording_time_elapsed_text"
- android:textSize="23dp"
- android:textStyle="bold"
- android:visibility="gone"/>
+ android:visibility="gone" />
</FrameLayout>
</com.android.camera.PreviewFrameLayout>
</LinearLayout>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index a3ca990..0002759 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"Pořídit další"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerie"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Přepnout fotoaparát"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Zapnout časosběr"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Vypnout časosběr"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Vybrat fotoaparát"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Zadní"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Přední"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Nízká (30m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (Nízká, 30s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (Vysoká, 10m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Kvalita časoběrného videa"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Nízká"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Vysoká"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Interval mezi snímky"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Nastavení fotoaparátu"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Nastavení videokamery"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Velikost fotografií"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 megapixely"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 megapixely"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 megapixel"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Kvalita fotografií"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Velmi jemná"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Jemná"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Solarizace"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Posterizace"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Voda"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastelové barvy"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mozaika"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Červený nádech"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Modrý nádech"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Zelený nádech"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Na kartě SD je málo místa. Změňte nastavení kvality nebo smažte některé obrázky či jiné soubory."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Bylo dosaženo limitu velikosti."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Přiblížení"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Přepnout do režimu fotoaparát"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Přepnout do režimu video"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 84302e4..acca8f2 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"TAG IGEN"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galleri"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Skift kamera"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Aktiver tidsforløb"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Deaktiver tidsforløb"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Vælg kamera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Bagest"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Forrest"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Lav (30 m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (Lav, 30 s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (Høj, 10 m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Tidsforløb for videokvalitet"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Lav"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Høj"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Rammeinterval"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Indstillinger for kamera"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Indstillinger for videokamera"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Billedstørrelse"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 M pixels"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 M pixels"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 M pixels"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Billedkvalitet"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Superfin"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Fin"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Solarize"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Posterize"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Vand"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastel"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mosaik"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Rød farvetone"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Blå farvetone"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Grøn farvetone"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Der er snart ikke mere plads på dit SD-kort. Rediger indstillingerne for kvalitet, eller slet nogle billeder eller andre filer."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Størrelsesgrænse er nået."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Zoom"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Skift til kamera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Skift til video"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index b32eb8c..4856d94 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"ERNEUT AUFNEHMEN"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerie"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Kamera wechseln"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Zeitraffer ein"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Zeitraffer aus"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Kamera auswählen"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Rückseite"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Vorderseite"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Niedrig (30m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (niedrig, 30s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (hoch, 10m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Zeitraffer-Videoqualität"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Niedrig"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Hoch"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Frameaufnahmeintervall"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Kameraeinstellungen"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Camcordereinstellungen"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Bildgröße"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 Millionen Pixel"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 Millionen Pixel"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 Million Pixel"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Bildqualität"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Extrafein"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Fein"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Solarisieren"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Tontrennung"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Aqua"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastell"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mosaik"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Rottöne"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Blautöne"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Grüntöne"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Auf Ihrer SD-Karte ist nicht mehr genügend Speicherplatz vorhanden. Ändern Sie die Qualitätseinstellung oder löschen Sie Bilder oder andere Dateien."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Maximale Größe erreicht"</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Zoom"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Zu Kamera wechseln"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Zu Video wechseln"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index d4cb839..a3c431f 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"ΝΕΑ ΛΗΨΗ"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Συλλογή"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Εναλλαγή κάμερας"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Εν. παρελ. χρόν."</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Απ. παρελ. χρόν."</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Επιλογή κάμερας"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Πίσω"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Μπροστά"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Χαμηλή (30m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (Χαμηλή, 30s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (Υψηλή, 10m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Ποιότητα βίντεο παρελ. χρόνου"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Χαμηλή"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Υψηλή"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Διάστημα μεταξύ λήψης καρέ"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Ρυθμίσεις φωτογραφικής μηχανής"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Ρυθμίσεις βιντεοκάμερας"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Μέγεθος εικόνας"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3M εικονοστοιχεία"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2M εικονοστοιχεία"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1M εικονοστοιχεία"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Ποιότητα εικόνας"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Πολύ υψηλή"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Λεπτή"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Υπερφώτιση"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Ποστεροποίηση"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Γαλάζιο"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Παστέλ"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Μωσαϊκό"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Κόκκινη απόχρωση"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Μπλε απόχρωση"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Πράσινη απόχρωση"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Ο διαθέσιμος χώρος στην κάρτα SD είναι ελάχιστος. Αλλάξτε τη ρύθμιση ποιότητας ή διαγράψτε κάποιες εικόνες ή άλλα αρχεία."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Συμπληρώθηκε το όριο μεγέθους."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Εστίαση"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Αλλαγή σε λειτουργία φωτογραφικής μηχανής"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Αλλαγή σε λειτουργία βίντεο"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index b46b0c3..b678365 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"VOLVER A TOMAR"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galería"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Cambiar cámara"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Habilitar intervalo de tiempo"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Inhabilitar intervalo de tiempo"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Seleccionar cámara"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Parte trasera"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Parte delantera"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Baja (30 min.)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (Baja, 30 seg.)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (Alta, 10 min.)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Calidad del video según el intervalo de tiempo"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Bajo"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Alta"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Intervalo de captura de marco"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Configuración de cámara"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Configuración de videocámara"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Tamaño de imagen"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3M píxeles"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2M píxeles"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1M píxeles"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Calidad de la imagen"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Súper fino"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Fino"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Solarizar"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Posterizar"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Aguamarina"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastel"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mosaico"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Tinte rojo"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Tinte azul"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Tinte verde"</string>
@@ -111,6 +117,9 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Tu tarjeta SD se está quedando sin espacio. Cambia la configuración de calidad o elimina algunas imágenes u otros archivos."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Se alcanzó el límite del tamaño."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Ampliar"</string>
+ <string name="zoom_increment" msgid="63154013702178400">"+"</string>
+ <string name="zoom_decrement" msgid="2712310206413552821">"-"</string>
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Cambiar a cámara"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Cambiar a video"</string>
+ <string name="camera_setting_picker_exit" msgid="2574026697338481860">"Atrás"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 57b2854..0495817 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"VOLVER A REALIZAR"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galería"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Cambiar cámara"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Habilitar intervalos tiempo"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Inhabilitar intervalos tiempo"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Seleccionar cámara"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Trasera"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Delantera"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Baja (30 m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (baja, 30 s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (alta, 10 min)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Calidad vídeo intervalo tiempo"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Baja"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Alta"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Intervalo de captura de imagen"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Configuración de cámara"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Configuración de videocámara"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Tamaño de imagen"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"Píxeles de 3 M"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"Píxeles de 2 M"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"Píxeles de 1 M"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Calidad de imagen"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Muy buena"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Buena"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Solarizar"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Posterizar"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Agua"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastel"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mosaico"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Tono rojo"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Tono azul"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Tono verde"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"No queda espacio en la tarjeta SD. Cambia la configuración de calidad o elimina algunas imágenes u otros archivos."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Se ha alcanzado el límite de tamaño."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Zoom"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Cambiar a cámara"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Cambiar a vídeo"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 87f9827..e5d0744 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"AUTRE PHOTO"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerie"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Changer d\'appareil photo"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Activer time lapse"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Désact. time lapse"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Choisir appareil ph."</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Arrière"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Avant"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Faible (30 mn)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (faible, 30 s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (élevée, 10 mn)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Qualité de la vidéo time lapse"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Faible"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Élevée"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Intervalle de capture d\'image"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Paramètres de l\'appareil photo"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Mode Caméra"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Taille d\'image"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 M pixels"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 M pixels"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 M pixels"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Qualité d\'image"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Très haute qualité"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Haute qualité"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Soleil direct"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Postérisation"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Aquatique"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastel"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mosaïque"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Teinte rouge"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Teinte bleue"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Teinte verte"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Votre carte SD est pleine. Modifiez le paramètre de qualité ou supprimez des images ou des fichiers."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Taille maximale atteinte."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Zoom"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Passer en mode photo"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Passer en mode vidéo"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index ad5f3e3..6366c38 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"SCATTA DI NUOVO"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galleria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Cambia fotocamera"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Attiva rallentatore"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Disattiva rallentat."</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Seleziona fotocamera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Posteriore"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Frontale"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Bassa (30 m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (bassa, 30 s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (alta, 10 m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Qualità video a rallentatore"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Bassa"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Alta"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Intervallo scatti fotogrammi"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Impostazioni fotocamera"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Impostazioni videocamera"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Dimensioni foto"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 Megapixel"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 Megapixel"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 Megapixel"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Qualità immagine"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Super fine"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Fine"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Solarizza"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Posterizza"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Acqua"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastello"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mosaico"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Tinta rossa"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Tinta blu"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Tinta verde"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Lo spazio della scheda SD si sta esaurendo. Cambia l\'impostazione di qualità o elimina alcune immagini o altri file."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Limite di dimensione raggiunto."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Zoom"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Passa a fotocamera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Passa a video"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 87d5e1f..94e122b 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"撮り直し"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"ギャラリー"</string>
<string name="switch_camera_id" msgid="837545176602471325">"カメラを切り替え"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"低速度撮影を有効にする"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"低速度撮影を無効にする"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"カメラを選択"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"背面"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"前面"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"低(30m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS(低、30s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube(高、10m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"低速度撮影の動画画質"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"低"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"高"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"撮影間隔"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"カメラ設定"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"ビデオ録画設定"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"表示サイズ"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3メガピクセル"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2メガピクセル"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1メガピクセル"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"写真の画質"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"スーパーファイン"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"ファイン"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"ソラライズ"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"ポスタライズ"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"アクア"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"パステル"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"モザイク"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"色合い(赤)"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"色合い(青)"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"色合い(緑)"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"SDカードの空き領域が少なくなっています。画質設定を変更するか、画像などのファイルを一部削除してください。"</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"サイズ制限に達しました。"</string>
<string name="zoom_control_title" msgid="6532562653386981815">"ズーム"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"写真に切替"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"ムービーに切替"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index ae65f57..d62bd2e 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"다시 촬영"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"갤러리"</string>
<string name="switch_camera_id" msgid="837545176602471325">"카메라 전환"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"시간 경과 사용"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"시간 경과 사용안함"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"카메라 선택"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"후방"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"전방"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"낮음(30분)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"멀티미디어 메시지(낮음, 30초)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube(높음, 10분)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"시간 경과 동영상 화질"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"낮음"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"높음"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"프레임 캡처 간격"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"카메라 설정"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"캠코더 설정"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"사진 크기"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3M 픽셀"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2M 픽셀"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1M 픽셀"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"사진 품질"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"최고급"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"고급"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"감광"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"포스터"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"아쿠아"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"파스텔"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"모자이크"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"빨간색 농담"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"파란색 농담"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"녹색 농담"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"SD 카드의 공간이 부족합니다. 화질 설정을 변경하거나 일부 이미지 또는 기타 파일을 삭제하세요."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"크기 한도에 도달했습니다."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"확대/축소"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"카메라로 전환"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"동영상으로 전환"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 554a4b5..b728304 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"Ta på nytt"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galleri"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Bytt kamera"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Aktiver tidsforløp"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Deaktiv. tidsforløp"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Velg kamera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Bakside"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Forside"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Lav (30 m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"Multimediemelding (lav, 30 s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (høy, 10 m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Tidsforløp for videokvalitet"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Lav"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Høy"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Intervall for rammetaking"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Kamerainnstillinger"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Videoinnstillinger"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Bildestørrelse"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3M (2048x1536)"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2M (1600x1200)"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1M (1024x768)"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Bildekvalitet"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Ekstra fin"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Fin"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Overeksponer"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Posteriser"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Vann"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastell"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mosaikk"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Rødskjær"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Blåskjær"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Grønnskjær"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Lagringsplassen på SD-kortet er snart oppbrukt. Endre kvalitetsinnstillingene, eller slett bilder eller andre filer."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Videoen ble for stor."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Zoom"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Bytt til kamera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Bytt til video"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index f31f191..47b2212 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"OPNIEUW OPNEMEN"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galerij"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Camera wijzigen"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Time-lapse aan"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Time-lapse uit"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Camera selecteren"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Achterzijde"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Voorzijde"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Laag (30m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (Laag, 30s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (Hoog, 10m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Videokwaliteit time-lapse"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Laag"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Hoog"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Framevastleggingsinterval"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Camera-instellingen"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Camcorder-instellingen"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Grootte van foto"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 megapixels"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 megapixels"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 megapixels"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Fotokwaliteit"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Zeer fijn"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Fijn"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Solariseren"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Postereffect"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Aqua"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastel"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mozaïek"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Roodtinten"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Blauwtinten"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Groentinten"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Uw SD-kaart is bijna vol. Wijzig de kwaliteitsinstelling of verwijder enkele afbeeldingen of andere bestanden."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Maximale grootte bereikt"</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Zoomen"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Overschakelen naar camera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Overschakelen naar video"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index f868558..0eae301 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"ZRÓB PONOWNIE"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galeria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Przełącz aparat"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Wł. tryb poklatkowy"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Wył. tryb poklatkowy"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Wybierz aparat"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Tył"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Przód"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Niska (30 min)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (niska, 30 s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (wysoka, 10 min)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Jakość filmu poklatkowego"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Niska"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Wysoka"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Częstotliwość rejestrowania"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Ustawienia aparatu"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Ustawienia kamery"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Rozmiar zdjęcia"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 megapiksele"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 megapiksele"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 megapiksel"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Jakość zdjęcia"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Bardzo wysoka"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Wysoka"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Solaryzacja"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Posteryzacja"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Akwarela"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastel"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mozaika"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Odcień czerwony"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Odcień niebieski"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Odcień zielony"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Na karcie SD kończy się miejsce. Zmień ustawienie jakości bądź usuń niektóre zdjęcia lub inne pliki."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Osiągnięto limit rozmiaru."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Powiększenie"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Przełącz na aparat"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Przełącz na wideo"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index ac6b5ae..feb0fec 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"VOLTAR A TIRAR"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galeria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Trocar câmara"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Act. lapso de tempo"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Des. lapso de tempo"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Seleccionar câmara"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Traseira"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Frontal"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Baixa (30 m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (baixa, 30 s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (Alta, 10 m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Qual. do vídeo lapso de tempo"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Baixa"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Alta"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Interv. captura de fotogramas"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Definições da câmara"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Definições da câmara de vídeo"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Tamanho da imagem"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 megapixels"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 megapixels"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 megapixels"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Qualidade de imagem"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Super fina"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Optimizar"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Solarização"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Póster"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Azul-marinho"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastel"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mosaico"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Tonalidade vermelha"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Tonalidade azul"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Tonalidade verde"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Está a ficar sem espaço no cartão SD. Altere as definições de qualidade ou elimine algumas imagens ou outros ficheiros."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Limite de tamanho atingido."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Zoom"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Mudar para câmara"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Mudar para vídeo"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index bfe3ed0..5092c84 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"TIRAR OUTRA"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galeria"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Alternar câmera"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Ativar tempo grav."</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Desat. tempo grav."</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Selecionar câmera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Voltar"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Visão frontal"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Baixa (30m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (Baixo, 30s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (Alta, 10m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Qualidade do vídeo com tempo"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Baixa"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Alta"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Intervalo da captura de frame"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Configurações da câmera"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Configurações da filmadora"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Tamanho da imagem"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3M Pixels"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2M Pixels"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1M Pixels"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Qualidade da imagem"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Muito boa"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Boa"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Solarizar"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Transformar em pôster"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Aqua"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Tons pastéis"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mosaico"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Filtro vermelho"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Filtro azul"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Filtro verde"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Seu cartão SD está sem espaço. Altere a configuração de qualidade ou exclua algumas imagens ou outros arquivos."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Limite de tamanho atingido."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Zoom"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Alternar para câmera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Alternar para vídeo"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index ac1b7a7..9542f29 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"ДРУГОЙ СНИМОК"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Галерея"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Переключить камеру"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Вкл. замедл. съемку"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Откл. замедл. съемку"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Выберите камеру"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Задняя"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Передняя"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Низкое (30 мин.)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (низкое, 30 с.)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (высокое, 10 мин.)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Качество при замедл. съемке"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Низкое"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Высокое"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Интервал между снимками"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Настройки камеры"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Настройки видеокамеры"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Размер фотографии"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 мегапикселя"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 мегапикселя"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 мегапиксель"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Качество фотографий"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Отличное"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Хорошее"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Соляризация"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Постеризация"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Под водой"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Пастель"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Мозаика"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Красный оттенок"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Синий оттенок"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Зеленый оттенок"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Место на вашей SD-карте заканчивается. Измените настройки качества или удалите ненужные изображения и другие файлы."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Достигнут предельный размер видео."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Масштаб"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Переключить на фото"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Переключить на видео"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 16c70c0..39ca5e0 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"TA OM"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galleri"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Växla kamera"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Tidsavvikelse på"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Tidsavvikelse av"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Välj kamera"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Bakre"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Främre"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Låg (30 m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (Låg, 30 s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (Hög, 10 m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Videokvalitet, tidsavvikelse"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Låg"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Hög"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Raminspelningsintervall"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Kamerainställningar"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Videokamerainställningar"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Bildstorlek"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 megapixlar"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 megapixlar"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 megapixel"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Bildkvalitet"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Superfin"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"Fin"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Solarisera"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Färgreduktion"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Aqua"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastell"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mosaik"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Röd ton"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Blå ton"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Grön ton"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"Den delade lagringsenheten börjar bli full. Ändra inställningen för kvalitet eller ta bort några bilder eller andra filer."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Storleksgränsen nådd."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Zoom"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Växla till kamera"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Växla till video"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 988dfc1..53a9ecd 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"YENİDEN ÇEK"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"Galeri"</string>
<string name="switch_camera_id" msgid="837545176602471325">"Kamerayı Değiştir"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"Zaman Atl Etkinlştr"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"Zaman Atl Dvr Dş Brk"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"Kamera seçin"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"Arka"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"Ön"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"Düşük (30m)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (Düşük, 30s)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (Yüksek, 10m)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"Zaman atlamalı video kalitesi"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"Düşük"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"Yüksek"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"Çerçeve yakalama aralığı"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"Kamera ayarları"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"Kamera ayarları"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"Resim boyutu"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3M Piksel"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2M Piksel"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1M Piksel"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"Resim kalitesi"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"Çok iyi"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"İyi"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"Güneş ışığı etkisi"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"Poster efekti ver"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"Su"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"Pastel"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"Mozaik"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"Kırmızı ton"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"Mavi ton"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"Yeşil ton"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"SD kartınızda boş alan azaldı. Kalite ayarını değiştirin veya bazı resimleri ya da diğer dosyaları silin."</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"Boyut sınırına ulaşıldı."</string>
<string name="zoom_control_title" msgid="6532562653386981815">"Zum:"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"Kameraya geç"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"Videoya geç"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index a402e2e..4276599 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"重拍"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"图库"</string>
<string name="switch_camera_id" msgid="837545176602471325">"切换相机"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"启用延时模式"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"停用延时模式"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"选择相机"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"背面相机"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"正面相机"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"低画质(30 分钟)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"彩信(低画质,30 秒)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube(高画质,10 分钟)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"延时视频品质"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"低"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"高"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"帧捕获间隔"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"相机设置"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"摄像机设置"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"照片大小"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 百万像素"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 百万像素"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 百万像素"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"照片质量"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"极精细"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"精细"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"曝光"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"色调分离"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"浅绿色"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"柔和"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"马赛克"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"偏红"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"偏蓝"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"偏绿"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"SD 卡空间不足,请更改照片品质设置,或删除某些照片或者其他文件。"</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"已达到大小上限。"</string>
<string name="zoom_control_title" msgid="6532562653386981815">"缩放"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"切换到相机"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"切换到视频"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index f8af10f..b16dc4a 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -39,6 +39,8 @@
<string name="review_retake" msgid="7804864054896088338">"重拍"</string>
<string name="camera_gallery_photos_text" msgid="6558048736561932758">"圖庫"</string>
<string name="switch_camera_id" msgid="837545176602471325">"切換相機"</string>
+ <string name="enable_time_lapse_mode" msgid="9176865387013576340">"啟用延時攝影"</string>
+ <string name="disable_time_lapse_mode" msgid="1025813874111023552">"停用延時攝影"</string>
<string name="pref_camera_id_title" msgid="6023059405578511534">"選取鏡頭"</string>
<string name="pref_camera_id_entry_back" msgid="5142699735103692485">"後置鏡頭"</string>
<string name="pref_camera_id_entry_front" msgid="5668958706828733669">"前置鏡頭"</string>
@@ -50,6 +52,10 @@
<string name="pref_video_quality_entry_low" msgid="5282945640948667598">"低 (30 分鐘)"</string>
<string name="pref_video_quality_entry_mms" msgid="2271260293894247704">"MMS (低,30 秒)"</string>
<string name="pref_video_quality_entry_youtube" msgid="3731902408685997150">"YouTube (高,10 分鐘)"</string>
+ <string name="pref_video_time_lapse_quality_title" msgid="1163053302966946838">"延時攝影的影片品質"</string>
+ <string name="pref_video_time_lapse_quality_entry_low" msgid="5315843743598116968">"低畫質"</string>
+ <string name="pref_video_time_lapse_quality_entry_high" msgid="3933491126045555205">"高畫質"</string>
+ <string name="pref_video_time_lapse_frame_interval_title" msgid="5023524580863002541">"影像拍攝間隔"</string>
<string name="pref_camera_settings_category" msgid="2576236450859613120">"相機設定"</string>
<string name="pref_camcorder_settings_category" msgid="460313486231965141">"攝錄影機設定"</string>
<string name="pref_camera_picturesize_title" msgid="4333724936665883006">"相片大小"</string>
@@ -57,6 +63,8 @@
<string name="pref_camera_picturesize_entry_2048x1536" msgid="8763841848102861602">"3 百萬像素"</string>
<string name="pref_camera_picturesize_entry_1600x1200" msgid="3802531502504271124">"2 百萬像素"</string>
<string name="pref_camera_picturesize_entry_1024x768" msgid="6557686202570581693">"1 百萬像素"</string>
+ <string name="pref_camera_picturesize_entry_640x480" msgid="5557572917973022995">"VGA"</string>
+ <string name="pref_camera_picturesize_entry_320x240" msgid="5729711026478753025">"QVGA"</string>
<string name="pref_camera_jpegquality_title" msgid="6074540285403193970">"相片品質"</string>
<string name="pref_camera_jpegquality_entry_superfine" msgid="4087830022547613205">"超精細"</string>
<string name="pref_camera_jpegquality_entry_fine" msgid="4474043704802385370">"精細"</string>
@@ -83,8 +91,6 @@
<string name="pref_camera_coloreffect_entry_solarize" msgid="7399297076108412329">"曝光效果"</string>
<string name="pref_camera_coloreffect_entry_posterize" msgid="8596847197608350695">"色調分離"</string>
<string name="pref_camera_coloreffect_entry_aqua" msgid="224075791902166343">"水底效果"</string>
- <string name="pref_camera_coloreffect_entry_pastel" msgid="1263931790863509482">"粉蠟筆效果"</string>
- <string name="pref_camera_coloreffect_entry_mosaic" msgid="1756287704236443515">"馬賽克效果"</string>
<string name="pref_camera_coloreffect_entry_redtint" msgid="7135044258970245718">"紅色調"</string>
<string name="pref_camera_coloreffect_entry_bluetint" msgid="987468567611774716">"藍色調"</string>
<string name="pref_camera_coloreffect_entry_greentint" msgid="4205380735971677893">"綠色調"</string>
@@ -111,6 +117,12 @@
<string name="spaceIsLow_content" product="default" msgid="1732882643101247179">"您 SD 卡的空間即將不足,請變更圖片的品質設定,或是刪除部分圖片或其他檔案。"</string>
<string name="video_reach_size_limit" msgid="6179877322015552390">"已達大小上限。"</string>
<string name="zoom_control_title" msgid="6532562653386981815">"縮放"</string>
+ <!-- no translation found for zoom_increment (63154013702178400) -->
+ <skip />
+ <!-- no translation found for zoom_decrement (2712310206413552821) -->
+ <skip />
<string name="switch_to_camera_lable" msgid="8248495141797448471">"切換為相機"</string>
<string name="switch_to_video_lable" msgid="4525451949497982385">"切換為影片"</string>
+ <!-- no translation found for camera_setting_picker_exit (2574026697338481860) -->
+ <skip />
</resources>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index a743a53..7d6cb8a 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -31,13 +31,65 @@
<item>youtube</item>
</string-array>
- <array name="video_quality_icons" translatable="false">
+ <array name="video_quality_largeicons" translatable="false">
<item>@drawable/ic_viewfinder_video_quality_high</item>
<item>@drawable/ic_viewfinder_video_quality_low</item>
<item>@drawable/ic_viewfinder_video_quality_mms</item>
<item>@drawable/ic_viewfinder_video_quality_youtube</item>
</array>
+ <!-- Camera Preferences Time Lapse Video Quality entries -->
+ <string-array name="pref_video_time_lapse_quality_entries" translatable="false">
+ <item>@string/pref_video_time_lapse_quality_entry_low</item>
+ <item>@string/pref_video_time_lapse_quality_entry_high</item>
+ <item>@string/pref_video_time_lapse_quality_entry_480p</item>
+ <item>@string/pref_video_time_lapse_quality_entry_720p</item>
+ <item>@string/pref_video_time_lapse_quality_entry_1080p</item>
+ </string-array>
+
+ <!-- These values correspond to the quality level integers defined
+ in CamcorderProfile.java. E.g. QUALITY_TIME_LAPSE_480P = 1004 -->
+ <string-array name="pref_video_time_lapse_quality_entryvalues" translatable="false">
+ <item>1000</item>
+ <item>1001</item>
+ <item>1004</item>
+ <item>1005</item>
+ <item>1006</item>
+ </string-array>
+
+ <!-- Camera Preferences Time Lapse Frame Interval entries -->
+ <string-array name="pref_video_time_lapse_frame_interval_entries" translatable="false">
+ <item>@string/pref_video_time_lapse_frame_interval_entry_500</item>
+ <item>@string/pref_video_time_lapse_frame_interval_entry_1000</item>
+ <item>@string/pref_video_time_lapse_frame_interval_entry_1500</item>
+ <item>@string/pref_video_time_lapse_frame_interval_entry_2000</item>
+ <item>@string/pref_video_time_lapse_frame_interval_entry_2500</item>
+ <item>@string/pref_video_time_lapse_frame_interval_entry_3000</item>
+ <item>@string/pref_video_time_lapse_frame_interval_entry_5000</item>
+ <item>@string/pref_video_time_lapse_frame_interval_entry_10000</item>
+ </string-array>
+
+ <!-- These values correspond to the time interval between frame capture in millseconds
+ for time lapse recording -->
+ <string-array name="pref_video_time_lapse_frame_interval_entryvalues" translatable="false">
+ <item>500</item>
+ <item>1000</item>
+ <item>1500</item>
+ <item>2000</item>
+ <item>2500</item>
+ <item>3000</item>
+ <item>5000</item>
+ <item>10000</item>
+ </string-array>
+
+ <array name="video_time_lapse_quality_largeicons" translatable="false">
+ <item>@drawable/ic_viewfinder_video_time_lapse_quality_low</item>
+ <item>@drawable/ic_viewfinder_video_time_lapse_quality_high</item>
+ <item>@drawable/ic_viewfinder_video_time_lapse_quality_480p</item>
+ <item>@drawable/ic_viewfinder_video_time_lapse_quality_720p</item>
+ <item>@drawable/ic_viewfinder_video_time_lapse_quality_1080p</item>
+ </array>
+
<!-- Camera Preferences Picture size dialog box entries -->
<string-array name="pref_camera_picturesize_entries" translatable="false">
<!-- TODO: Change to a better name of the preference.
@@ -109,13 +161,13 @@
<item>off</item>
</string-array>
- <array name="pref_camera_flashmode_icons">
+ <array name="camera_flashmode_icons" translatable="false">
<item>@drawable/ic_menuselect_flash_auto</item>
<item>@drawable/ic_menuselect_flash_on</item>
<item>@drawable/ic_menuselect_flash_off</item>
</array>
- <array name="flashmode_icons">
+ <array name="camera_flashmode_largeicons" translatable="false">
<item>@drawable/ic_viewfinder_flash_auto</item>
<item>@drawable/ic_viewfinder_flash_on</item>
<item>@drawable/ic_viewfinder_flash_off</item>
@@ -132,12 +184,12 @@
<item>off</item>
</string-array>
- <array name="pref_camera_video_flashmode_icons">
+ <array name="video_flashmode_icons" translatable="false">
<item>@drawable/ic_menuselect_flash_on</item>
<item>@drawable/ic_menuselect_flash_off</item>
</array>
- <array name="video_flashmode_icons">
+ <array name="video_flashmode_largeicons" translatable="false">
<item>@drawable/ic_viewfinder_flash_on</item>
<item>@drawable/ic_viewfinder_flash_off</item>
</array>
@@ -152,12 +204,12 @@
<item>@string/pref_camera_recordlocation_entry_on</item>
</array>
- <array name="pref_camera_recordlocation_icons" translatable="false">
+ <array name="camera_recordlocation_icons" translatable="false">
<item>@drawable/ic_menuselect_gps_off</item>
<item>@drawable/ic_menuselect_gps_on</item>
</array>
- <array name="recordlocation_icons">
+ <array name="camera_recordlocation_largeicons" translatable="false">
<item>@drawable/ic_viewfinder_gps_off</item>
<item>@drawable/ic_viewfinder_gps_on</item>
</array>
@@ -179,7 +231,7 @@
<item>cloudy-daylight</item>
</string-array>
- <array name="pref_camera_whitebalance_icons">
+ <array name="whitebalance_icons" translatable="false">
<item>@drawable/ic_menuselect_wb_auto</item>
<item>@drawable/ic_menuselect_wb_incandescent</item>
<item>@drawable/ic_menuselect_wb_daylight</item>
@@ -187,7 +239,7 @@
<item>@drawable/ic_menuselect_wb_cloudy</item>
</array>
- <array name="whitebalance_icons">
+ <array name="whitebalance_largeicons" translatable="false">
<item>@drawable/ic_viewfinder_wb_auto</item>
<item>@drawable/ic_viewfinder_wb_incandescent</item>
<item>@drawable/ic_viewfinder_wb_daylight</item>
@@ -195,6 +247,14 @@
<item>@drawable/ic_viewfinder_wb_cloudy</item>
</array>
+ <array name="whitebalance_images" translatable="false">
+ <item>@drawable/btn_wb_auto</item>
+ <item>@drawable/btn_wb_incandescent</item>
+ <item>@drawable/btn_wb_daylight</item>
+ <item>@drawable/btn_wb_fluorescent</item>
+ <item>@drawable/btn_wb_cloudy</item>
+ </array>
+
<!-- Camera Preferences Color effect dialog box entries -->
<string-array name="pref_camera_coloreffect_entries" translatable="false">
<item>@string/pref_camera_coloreffect_entry_none</item>
@@ -204,8 +264,6 @@
<item>@string/pref_camera_coloreffect_entry_solarize</item>
<item>@string/pref_camera_coloreffect_entry_posterize</item>
<item>@string/pref_camera_coloreffect_entry_aqua</item>
- <item>@string/pref_camera_coloreffect_entry_pastel</item>
- <item>@string/pref_camera_coloreffect_entry_mosaic</item>
<item>@string/pref_camera_coloreffect_entry_redtint</item>
<item>@string/pref_camera_coloreffect_entry_bluetint</item>
<item>@string/pref_camera_coloreffect_entry_greentint</item>
@@ -219,13 +277,38 @@
<item>solarize</item>
<item>posterize</item>
<item>aqua</item>
- <item>pastel</item>
- <item>mosaic</item>
<item>red-tint</item>
<item>blue-tint</item>
<item>green-tint</item>
</string-array>
+ <!-- Color effect has no separate icons. -->
+ <array name="coloreffect_largeicons" translatable="false">
+ <item>@drawable/ic_viewfinder_coloreffect</item>
+ <item>@drawable/ic_viewfinder_coloreffect</item>
+ <item>@drawable/ic_viewfinder_coloreffect</item>
+ <item>@drawable/ic_viewfinder_coloreffect</item>
+ <item>@drawable/ic_viewfinder_coloreffect</item>
+ <item>@drawable/ic_viewfinder_coloreffect</item>
+ <item>@drawable/ic_viewfinder_coloreffect</item>
+ <item>@drawable/ic_viewfinder_coloreffect</item>
+ <item>@drawable/ic_viewfinder_coloreffect</item>
+ <item>@drawable/ic_viewfinder_coloreffect</item>
+ </array>
+
+ <array name="coloreffect_images" translatable="false">
+ <item>@drawable/btn_coloreffect_none</item>
+ <item>@drawable/btn_coloreffect_mono</item>
+ <item>@drawable/btn_coloreffect_sepia</item>
+ <item>@drawable/btn_coloreffect_negative</item>
+ <item>@drawable/btn_coloreffect_solarize</item>
+ <item>@drawable/btn_coloreffect_posterize</item>
+ <item>@drawable/btn_coloreffect_aqua</item>
+ <item>@drawable/btn_coloreffect_redtint</item>
+ <item>@drawable/btn_coloreffect_bluetint</item>
+ <item>@drawable/btn_coloreffect_greentint</item>
+ </array>
+
<!-- Camera Preferences Scene Mode dialog box entries -->
<string-array name="pref_camera_scenemode_entries" translatable="false">
<item>@string/pref_camera_scenemode_entry_auto</item>
@@ -260,4 +343,14 @@
<item>party</item>
<item>candlelight</item>
</string-array>
+
+ <array name="camera_id_icons" translatable="false">
+ <item>@drawable/ic_menuselect_camera_facing_back</item>
+ <item>@drawable/ic_menuselect_camera_facing_front</item>
+ </array>
+
+ <array name="camera_id_largeicons" translatable="false">
+ <item>@drawable/ic_viewfinder_camera_facing_back</item>
+ <item>@drawable/ic_viewfinder_camera_facing_front</item>
+ </array>
</resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 25e997a..5238020 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -30,5 +30,9 @@
<declare-styleable name="IconListPreference">
<attr name="icons" />
<attr name="largeIcons" format="reference" />
+ <attr name="images" format="reference" />
+ </declare-styleable>
+ <declare-styleable name="InLineSettingPicker">
+ <attr name="prefKey" format="string" />
</declare-styleable>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 7193b7c..c5572ca 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -20,4 +20,5 @@
<resources>
<color name="recording_time_elapsed_text">#FFFFFFFF</color>
<color name="recording_time_remaining_text">#FFFF0033</color>
+ <color name="zoom_picker_btn_pressed">#FFFFAD00</color>
</resources>
diff --git a/res/values/ids.xml b/res/values/ids.xml
new file mode 100644
index 0000000..81d920f
--- /dev/null
+++ b/res/values/ids.xml
@@ -0,0 +1,19 @@
+<?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/strings.xml b/res/values/strings.xml
index 38dc7e1..ecfde6a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -113,6 +113,15 @@
<!-- Button indicating to switch to another camera -->
<string name="switch_camera_id">Switch Camera</string>
+ <!-- Button indicating to enable the time lapse mode. Time lapse mode refers
+ to capturing video at a rate much slower than it is played back. Appears as
+ a Menu item in Camcorder mode. [CHAR LIMIT=20] -->
+ <string name="enable_time_lapse_mode">Enable Time Lapse</string>
+
+ <!-- Button indicating to disable the time lapse mode. Appears as a Menu item in
+ Camcorder mode. [CHAR LIMIT=20] -->
+ <string name="disable_time_lapse_mode">Disable Time Lapse</string>
+
<!-- Settings screen, camera selection dialog title. Users can select a camera from the phone (front-facing or back-facing). [CHAR LIMIT=20] -->
<string name="pref_camera_id_title">Select camera</string>
@@ -140,6 +149,35 @@
<string name="pref_video_quality_entry_mms">MMS (Low, 30s)</string>
<string name="pref_video_quality_entry_youtube">YouTube (High, 10m)</string>
+ <!-- Describes the preference dialog for choosing quality for time lapse video.
+ Appears at top of the dialog. [CHAR LIMIT=30] -->
+ <string name="pref_video_time_lapse_quality_title">Time lapse video quality</string>
+ <string name="pref_video_time_lapse_quality_default" translatable="false">1001</string>
+ <!-- Refers to the video quality [CHAR LIMIT=8] -->
+ <string name="pref_video_time_lapse_quality_entry_low">Low</string>
+ <!-- Refers to the video quality [CHAR LIMIT=8] -->
+ <string name="pref_video_time_lapse_quality_entry_high">High</string>
+ <!-- Refers to the video quality -->
+ <string name="pref_video_time_lapse_quality_entry_480p" translatable="false">480p</string>
+ <!-- Refers to the video quality -->
+ <string name="pref_video_time_lapse_quality_entry_720p" translatable="false">720p</string>
+ <!-- Refers to the video quality -->
+ <string name="pref_video_time_lapse_quality_entry_1080p" translatable="false">1080p</string>
+
+ <!-- Describes the preference dialog for choosing interval between frame capture for
+ time lapse recording. Appears at top of the dialog. [CHAR LIMIT=30] -->
+ <string name="pref_video_time_lapse_frame_interval_title">Frame capture interval</string>
+ <string name="pref_video_time_lapse_frame_interval_default" translatable="false">2000</string>
+ <!-- The time interval between frame capture for time lapse recording -->
+ <string name="pref_video_time_lapse_frame_interval_entry_500" translatable="false">0.5s</string>
+ <string name="pref_video_time_lapse_frame_interval_entry_1000" translatable="false">1s</string>
+ <string name="pref_video_time_lapse_frame_interval_entry_1500" translatable="false">1.5s</string>
+ <string name="pref_video_time_lapse_frame_interval_entry_2000" translatable="false">2s</string>
+ <string name="pref_video_time_lapse_frame_interval_entry_2500" translatable="false">2.5s</string>
+ <string name="pref_video_time_lapse_frame_interval_entry_3000" translatable="false">3s</string>
+ <string name="pref_video_time_lapse_frame_interval_entry_5000" translatable="false">5s</string>
+ <string name="pref_video_time_lapse_frame_interval_entry_10000" translatable="false">10s</string>
+
<!-- Settings screen, Camera setting category title -->
<string name="pref_camera_settings_category">Camera settings</string>
@@ -154,8 +192,8 @@
<string name="pref_camera_picturesize_entry_2048x1536">3M Pixels</string>
<string name="pref_camera_picturesize_entry_1600x1200">2M Pixels</string>
<string name="pref_camera_picturesize_entry_1024x768">1M Pixels</string>
- <string name="pref_camera_picturesize_entry_640x480" translatable="false">VGA</string>
- <string name="pref_camera_picturesize_entry_320x240" translatable="false">QVGA</string>
+ <string name="pref_camera_picturesize_entry_640x480">VGA</string>
+ <string name="pref_camera_picturesize_entry_320x240">QVGA</string>
<!-- Default picture quality setting. See
pref_camera_jpegquality_entryvalues for possible values -->
@@ -225,8 +263,6 @@
<string name="pref_camera_coloreffect_entry_solarize">Solarize</string>
<string name="pref_camera_coloreffect_entry_posterize">Posterize</string>
<string name="pref_camera_coloreffect_entry_aqua">Aqua</string>
- <string name="pref_camera_coloreffect_entry_pastel">Pastel</string>
- <string name="pref_camera_coloreffect_entry_mosaic">Mosaic</string>
<string name="pref_camera_coloreffect_entry_redtint">Red tint</string>
<string name="pref_camera_coloreffect_entry_bluetint">Blue tint</string>
<string name="pref_camera_coloreffect_entry_greentint">Green tint</string>
@@ -327,7 +363,15 @@
<!-- The title show on the zoom controller -->
<string name="zoom_control_title">Zoom</string>
+ <string name="zoom_increment" translable="false">+</string>
+ <string name="zoom_decrement" translable="false">-</string>
<string name="switch_to_camera_lable">Switch to camera</string>
<string name="switch_to_video_lable">Switch to video</string>
+
+ <!-- Button indicating to exit the camera setting picker. -->
+ <string name="camera_setting_picker_exit">Back</string>
+
+ <string name="setting_increment" translatable="false">&gt;</string>
+ <string name="setting_decrement" translatable="false">&lt;</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 613ac34..6038c94 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -18,6 +18,9 @@
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style name="ThemeCamera" parent="android:Theme.Black.NoTitleBar.Fullscreen">
+ <item name="android:windowBackground">@drawable/bg_camera_pattern</item>
+ </style>
<style name="OnScreenHintTextAppearance">
<item name="android:textColor">@android:color/primary_text_dark</item>
<item name="android:textColorHighlight">#FFFF9200</item>
@@ -57,4 +60,27 @@
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">match_parent</item>
</style>
+ <style name="RecordingTime">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:shadowColor">#c0000000</item>
+ <item name="android:shadowDx">1</item>
+ <item name="android:shadowDy">1</item>
+ <item name="android:shadowRadius">1</item>
+ <item name="android:textColor">@color/recording_time_elapsed_text</item>
+ <item name="android:textSize">23dp</item>
+ <item name="android:textStyle">bold</item>
+ </style>
+ <style name="SettingPickerText">
+ <item name="android:textSize">20dp</item>
+ <item name="android:gravity">left|center_vertical</item>
+ <item name="android:layout_marginLeft">12dp</item>
+ <item name="android:layout_width">190dp</item>
+ <item name="android:layout_gravity">center_vertical</item>
+ </style>
+ <style name="OtherSettingTableRow">
+ <item name="android:layout_marginTop">16dp</item>
+ <item name="android:layout_marginBottom">16dp</item>
+ <item name="android:gravity">center_vertical</item>
+ </style>
</resources>
diff --git a/res/xml/camera_preferences.xml b/res/xml/camera_preferences.xml
index 6968270..87ce63b 100644
--- a/res/xml/camera_preferences.xml
+++ b/res/xml/camera_preferences.xml
@@ -22,8 +22,8 @@
camera:key="pref_camera_flashmode_key"
camera:defaultValue="@string/pref_camera_flashmode_default"
camera:title="@string/pref_camera_flashmode_title"
- camera:icons="@array/pref_camera_flashmode_icons"
- camera:largeIcons="@array/flashmode_icons"
+ camera:icons="@array/camera_flashmode_icons"
+ camera:largeIcons="@array/camera_flashmode_largeicons"
camera:entries="@array/pref_camera_flashmode_entries"
camera:entryValues="@array/pref_camera_flashmode_entryvalues" />
<ListPreference
@@ -40,22 +40,25 @@
camera:key="pref_camera_whitebalance_key"
camera:defaultValue="@string/pref_camera_whitebalance_default"
camera:title="@string/pref_camera_whitebalance_title"
- camera:icons="@array/pref_camera_whitebalance_icons"
- camera:largeIcons="@array/whitebalance_icons"
+ camera:icons="@array/whitebalance_icons"
+ camera:largeIcons="@array/whitebalance_largeicons"
+ camera:images="@array/whitebalance_images"
camera:entries="@array/pref_camera_whitebalance_entries"
camera:entryValues="@array/pref_camera_whitebalance_entryvalues" />
- <ListPreference
+ <IconListPreference
camera:key="pref_camera_coloreffect_key"
camera:defaultValue="@string/pref_camera_coloreffect_default"
camera:title="@string/pref_camera_coloreffect_title"
+ camera:largeIcons="@array/coloreffect_largeicons"
+ camera:images="@array/coloreffect_images"
camera:entries="@array/pref_camera_coloreffect_entries"
camera:entryValues="@array/pref_camera_coloreffect_entryvalues" />
<RecordLocationPreference
camera:key="pref_camera_recordlocation_key"
camera:defaultValue="@string/pref_camera_recordlocation_default"
camera:title="@string/pref_camera_recordlocation_title"
- camera:icons="@array/pref_camera_recordlocation_icons"
- camera:largeIcons="@array/recordlocation_icons"
+ camera:icons="@array/camera_recordlocation_icons"
+ camera:largeIcons="@array/camera_recordlocation_largeicons"
camera:entries="@array/pref_camera_recordlocation_entries"
camera:entryValues="@array/pref_camera_recordlocation_entryvalues" />
<ListPreference
@@ -78,6 +81,8 @@
<IconListPreference
camera:key="pref_camera_id_key"
camera:defaultValue="@string/pref_camera_id_default"
- camera:title="@string/pref_camera_id_title" />
+ camera:title="@string/pref_camera_id_title"
+ camera:icons="@array/camera_id_icons"
+ camera:largeIcons="@array/camera_id_largeicons" />
</PreferenceGroup>
</PreferenceGroup>
diff --git a/res/xml/video_preferences.xml b/res/xml/video_preferences.xml
index 3929b03..af68abe 100644
--- a/res/xml/video_preferences.xml
+++ b/res/xml/video_preferences.xml
@@ -22,34 +22,52 @@
camera:key="pref_video_quality_key"
camera:defaultValue="@string/pref_video_quality_default"
camera:title="@string/pref_video_quality_title"
- camera:largeIcons="@array/video_quality_icons"
+ camera:largeIcons="@array/video_quality_largeicons"
camera:entries="@array/pref_video_quality_entries"
camera:entryValues="@array/pref_video_quality_entryvalues"/>
<IconListPreference
+ camera:key="pref_video_time_lapse_quality_key"
+ camera:defaultValue="@string/pref_video_time_lapse_quality_default"
+ camera:title="@string/pref_video_time_lapse_quality_title"
+ camera:largeIcons="@array/video_time_lapse_quality_largeicons"
+ camera:entries="@array/pref_video_time_lapse_quality_entries"
+ camera:entryValues="@array/pref_video_time_lapse_quality_entryvalues"/>
+ <ListPreference
+ camera:key="pref_video_time_lapse_frame_interval_key"
+ camera:defaultValue="@string/pref_video_time_lapse_frame_interval_default"
+ camera:title="@string/pref_video_time_lapse_frame_interval_title"
+ camera:entries="@array/pref_video_time_lapse_frame_interval_entries"
+ camera:entryValues="@array/pref_video_time_lapse_frame_interval_entryvalues"/>
+ <IconListPreference
camera:key="pref_camera_video_flashmode_key"
camera:defaultValue="@string/pref_camera_video_flashmode_default"
camera:title="@string/pref_camera_flashmode_title"
- camera:icons="@array/pref_camera_video_flashmode_icons"
- camera:largeIcons="@array/video_flashmode_icons"
+ camera:icons="@array/video_flashmode_icons"
+ camera:largeIcons="@array/video_flashmode_largeicons"
camera:entries="@array/pref_camera_video_flashmode_entries"
camera:entryValues="@array/pref_camera_video_flashmode_entryvalues"/>
<IconListPreference
camera:key="pref_camera_whitebalance_key"
camera:defaultValue="@string/pref_camera_whitebalance_default"
camera:title="@string/pref_camera_whitebalance_title"
- camera:icons="@array/pref_camera_whitebalance_icons"
- camera:largeIcons="@array/whitebalance_icons"
+ camera:icons="@array/whitebalance_icons"
+ camera:largeIcons="@array/whitebalance_largeicons"
+ camera:images="@array/whitebalance_images"
camera:entries="@array/pref_camera_whitebalance_entries"
camera:entryValues="@array/pref_camera_whitebalance_entryvalues"/>
- <ListPreference
+ <IconListPreference
camera:key="pref_camera_coloreffect_key"
camera:defaultValue="@string/pref_camera_coloreffect_default"
camera:title="@string/pref_camera_coloreffect_title"
+ camera:largeIcons="@array/coloreffect_largeicons"
+ camera:images="@array/coloreffect_images"
camera:entries="@array/pref_camera_coloreffect_entries"
camera:entryValues="@array/pref_camera_coloreffect_entryvalues"/>
<IconListPreference
camera:key="pref_camera_id_key"
camera:defaultValue="@string/pref_camera_id_default"
- camera:title="@string/pref_camera_id_title" />
+ camera:title="@string/pref_camera_id_title"
+ camera:icons="@array/camera_id_icons"
+ camera:largeIcons="@array/camera_id_largeicons"/>
</PreferenceGroup>
</PreferenceGroup>
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 8b4de05..a0149df 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -16,6 +16,16 @@
package com.android.camera;
+import com.android.camera.gallery.IImage;
+import com.android.camera.gallery.IImageList;
+import com.android.camera.ui.BasicSettingPicker;
+import com.android.camera.ui.CameraHeadUpDisplay;
+import com.android.camera.ui.GLRootView;
+import com.android.camera.ui.HeadUpDisplay;
+import com.android.camera.ui.ControlPanel;
+import com.android.camera.ui.ZoomControllerListener;
+import com.android.camera.ui.ZoomPicker;
+
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
@@ -24,10 +34,10 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera.CameraInfo;
@@ -43,18 +53,17 @@ import android.media.ToneGenerator;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
-import android.os.Debug;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
-import android.os.SystemClock;
import android.provider.MediaStore;
import android.provider.Settings;
+import android.provider.MediaStore.Images.ImageColumns;
+import android.provider.MediaStore.Images.Media;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.Display;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -66,18 +75,16 @@ import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStub;
import android.view.Window;
import android.view.WindowManager;
import android.view.MenuItem.OnMenuItemClickListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.Button;
+import android.widget.CursorAdapter;
import android.widget.FrameLayout;
-import android.widget.ImageView;
-
-import com.android.camera.gallery.IImage;
-import com.android.camera.gallery.IImageList;
-import com.android.camera.ui.CameraHeadUpDisplay;
-import com.android.camera.ui.GLRootView;
-import com.android.camera.ui.HeadUpDisplay;
-import com.android.camera.ui.ZoomControllerListener;
+import android.widget.ListView;
import java.io.File;
import java.io.FileNotFoundException;
@@ -130,6 +137,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private int mZoomValue; // The current zoom value.
private int mZoomMax;
private int mTargetZoomValue;
+ private ZoomPicker mZoomPicker;
private Parameters mParameters;
private Parameters mInitialParams;
@@ -163,10 +171,15 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private GLRootView mGLRootView;
- // mPostCaptureAlert, mLastPictureButton, mThumbController
- // are non-null only if isImageCaptureIntent() is true.
- private ImageView mLastPictureButton;
- private ThumbnailController mThumbController;
+ // The layouts of small devices have a thumbnail button, which shows the last
+ // captured picture.
+ private RotateImageView mThumbnailButton;
+ // The layouts of xlarge devices have a list of thumbnails, which show the
+ // last captured pictures.
+ private ListView mThumbnailList;
+ private OnItemClickListener mThumbnailItemClickListener =
+ new ThumbnailItemClickListener();
+ private ThumbnailAdapter mThumbnailAdapter;
// mCropValue and mSaveUri are used only if isImageCaptureIntent() is true.
private String mCropValue;
@@ -174,6 +187,15 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private ImageCapture mImageCapture = null;
+ /**
+ * An unpublished intent flag requesting to return as soon as capturing
+ * is completed.
+ *
+ * TODO: consider publishing by moving into MediaStore.
+ */
+ private final static String EXTRA_QUICK_CAPTURE =
+ "android.intent.extra.quickCapture";
+
private boolean mPreviewing;
private boolean mPausing;
private boolean mFirstTimeInitialized;
@@ -230,12 +252,18 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private String mSceneMode;
private final Handler mHandler = new MainHandler();
+ // Small devices use head-up display for camera settings.
private CameraHeadUpDisplay mHeadUpDisplay;
+ // xlarge devices use control panel for camera settings.
+ private ControlPanel mControlPanel;
+ private PreferenceGroup mPreferenceGroup;
// multiple cameras support
private int mNumberOfCameras;
private int mCameraId;
+ private boolean mQuickCapture;
+
/**
* This Handler is used to post message back onto the main thread of the
* application
@@ -323,14 +351,8 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
mContentResolver = getContentResolver();
if (!mIsImageCaptureIntent) {
findViewById(R.id.camera_switch).setOnClickListener(this);
- mLastPictureButton =
- (ImageView) findViewById(R.id.review_thumbnail);
- mLastPictureButton.setOnClickListener(this);
- mThumbController = new ThumbnailController(
- getResources(), mLastPictureButton, mContentResolver);
- mThumbController.loadData(ImageManager.getLastImageThumbPath());
- // Update last image thumbnail.
- updateThumbnailButton();
+ initThumbnailButton();
+ initThumbnailList();
}
// Initialize shutter button.
@@ -345,8 +367,10 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
installIntentFilter();
initializeFocusTone();
initializeZoom();
- mHeadUpDisplay = new CameraHeadUpDisplay(this);
- mHeadUpDisplay.setListener(new MyHeadUpDisplayListener());
+ if (mControlPanel == null) {
+ mHeadUpDisplay = new CameraHeadUpDisplay(this);
+ mHeadUpDisplay.setListener(new MyHeadUpDisplayListener());
+ }
initializeHeadUpDisplay();
mFirstTimeInitialized = true;
changeHeadUpDisplayState();
@@ -363,12 +387,95 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
});
}
+ private void initThumbnailButton() {
+ mThumbnailButton =
+ (RotateImageView) findViewById(R.id.review_thumbnail);
+ if (mThumbnailButton != null) {
+ mThumbnailButton.setOnClickListener(this);
+ mThumbnailButton.loadData(ImageManager.getLastImageThumbPath());
+ updateThumbnailButton();
+ }
+ }
+
private void updateThumbnailButton() {
+ if (mThumbnailButton == null) return;
// Update last image if URI is invalid and the storage is ready.
- if (!mThumbController.isUriValid() && mPicturesRemaining >= 0) {
- updateLastImage();
+ if (!mThumbnailButton.isUriValid() && mPicturesRemaining >= 0) {
+ IImageList list = ImageManager.makeImageList(
+ mContentResolver,
+ dataLocation(),
+ ImageManager.INCLUDE_IMAGES,
+ ImageManager.SORT_ASCENDING,
+ ImageManager.CAMERA_IMAGE_BUCKET_ID);
+ int count = list.getCount();
+ if (count > 0) {
+ IImage image = list.getImageAt(count - 1);
+ Uri uri = image.fullSizeImageUri();
+ mThumbnailButton.setData(uri, image.miniThumbBitmap());
+ } else {
+ mThumbnailButton.setData(null, null);
+ }
+ list.close();
}
- mThumbController.updateDisplayIfNeeded();
+ }
+
+ private void setLastPictureThumb(byte[] data, int degree, Uri uri) {
+ if (mThumbnailButton == null) return;
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inSampleSize = 16;
+ Bitmap lastPictureThumb =
+ BitmapFactory.decodeByteArray(data, 0, data.length, options);
+ lastPictureThumb = Util.rotate(lastPictureThumb, degree);
+ mThumbnailButton.setData(uri, lastPictureThumb);
+ }
+
+ private void initThumbnailList() {
+ mThumbnailList = (ListView) findViewById(R.id.thumbnail_list);
+ if (mThumbnailList == null) return;
+
+ int width = mThumbnailList.getWidth();
+ int height = mThumbnailList.getHeight();
+
+ // Add gallery button to header view.
+ if (mThumbnailList.getHeaderViewsCount() == 0) {
+ LayoutInflater inflater = getLayoutInflater();
+ Button b = new Button(this);
+ ListView.LayoutParams params = new ListView.LayoutParams(width, width);
+ b.setId(R.id.btn_gallery);
+ b.setLayoutParams(params);
+ b.setOnClickListener(this);
+ b.setBackgroundResource(R.drawable.ic_menu_gallery);
+ mThumbnailList.addHeaderView(b);
+ }
+
+ // Set data adapter.
+ int thumbnailCount = (height + mThumbnailList.getDividerHeight())
+ / (width + mThumbnailList.getDividerHeight()) - 1;
+ Cursor cursor = getThumbnailsCursor(thumbnailCount);
+ mThumbnailAdapter = new ThumbnailAdapter(
+ getApplicationContext(), R.layout.thumbnail_item, cursor, true);
+ mThumbnailList.setAdapter(mThumbnailAdapter);
+ mThumbnailList.setOnItemClickListener(mThumbnailItemClickListener);
+ }
+
+ private void updateThumbnailList() {
+ if (mThumbnailList == null) return;
+ mThumbnailAdapter.getCursor().requery();
+ mThumbnailAdapter.notifyDataSetChanged();
+ }
+
+ private Cursor getThumbnailsCursor(int thumbnailCount) {
+ Log.v(TAG, "thumbnailCount=" + thumbnailCount);
+ String[] projections = { MediaStore.Images.Thumbnails._ID };
+ Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ .buildUpon()
+ .appendQueryParameter("limit", String.valueOf(thumbnailCount))
+ .build();
+ // TODO: managedQuery is deprecated.
+ return managedQuery(uri, projections,
+ Media.MIME_TYPE + " = 'image/jpeg' AND " + Media.BUCKET_ID + " = ?",
+ new String[] {ImageManager.CAMERA_IMAGE_BUCKET_ID},
+ ImageColumns._ID + " DESC");
}
// If the activity is paused and resumed, this method will be called in
@@ -402,6 +509,15 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
mZoomMax = mParameters.getMaxZoom();
mSmoothZoomSupported = mParameters.isSmoothZoomSupported();
mGestureDetector = new GestureDetector(this, new ZoomGestureListener());
+ if (mZoomPicker != null) {
+ mZoomPicker.setZoomRatios(getZoomRatios());
+ mZoomPicker.setOnZoomChangeListener(
+ new ZoomPicker.OnZoomChangedListener() {
+ public void onZoomChanged(int index) {
+ onZoomValueChanged(index);
+ }
+ });
+ }
mCameraDevice.setZoomChangeListener(mZoomListener);
}
@@ -447,6 +563,13 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
return false;
}
+ int x = Math.round(e.getX());
+ int y = Math.round(e.getY());
+ if (x < mSurfaceView.getLeft() || x > mSurfaceView.getRight()
+ || y < mSurfaceView.getTop() || y > mSurfaceView.getBottom()) {
+ return false;
+ }
+
if (mZoomValue < mZoomMax) {
// Zoom in to the maximum.
mZoomValue = mZoomMax;
@@ -456,7 +579,11 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
setCameraParametersWhenIdle(UPDATE_PARAM_ZOOM);
- mHeadUpDisplay.setZoomIndex(mZoomValue);
+ if (mZoomPicker != null) {
+ mZoomPicker.setZoomIndex(mZoomValue);
+ } else {
+ mHeadUpDisplay.setZoomIndex(mZoomValue);
+ }
return true;
}
}
@@ -486,6 +613,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
checkStorage();
if (!mIsImageCaptureIntent) {
updateThumbnailButton();
+ updateThumbnailList();
}
}
}
@@ -608,7 +736,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
Log.v(TAG, "mPictureDisplayedToJpegCallbackTime = "
+ mPictureDisplayedToJpegCallbackTime + "ms");
- mHeadUpDisplay.setEnabled(true);
+ enableCameraControls(true);
if (!mIsImageCaptureIntent) {
// We want to show the taken picture for a while, so we wait
@@ -747,10 +875,14 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
"com.android.camera.NEW_PICTURE", mLastContentUri));
setLastPictureThumb(data, degree,
mImageCapture.getLastCaptureUri());
- mThumbController.updateDisplayIfNeeded();
+ updateThumbnailList();
} else {
mCaptureOnlyData = data;
- showPostCaptureAlert();
+ if (!mQuickCapture) {
+ showPostCaptureAlert();
+ } else {
+ doAttach();
+ }
}
}
@@ -839,7 +971,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
mCaptureStartTime = System.currentTimeMillis();
mPostViewPictureCallbackTime = 0;
- mHeadUpDisplay.setEnabled(false);
+ enableCameraControls(false);
mStatus = SNAPSHOT_IN_PROGRESS;
mImageCapture.initiate();
@@ -863,15 +995,6 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
return true;
}
- private void setLastPictureThumb(byte[] data, int degree, Uri uri) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inSampleSize = 16;
- Bitmap lastPictureThumb =
- BitmapFactory.decodeByteArray(data, 0, data.length, options);
- lastPictureThumb = Util.rotate(lastPictureThumb, degree);
- mThumbController.setData(uri, lastPictureThumb);
- }
-
private String createName(long dateTaken) {
Date date = new Date(dateTaken);
SimpleDateFormat dateFormat = new SimpleDateFormat(
@@ -894,6 +1017,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
CameraSettings.upgradeLocalPreferences(mPreferences.getLocal());
mNumberOfCameras = CameraHolder.instance().getNumberOfCameras();
+ mQuickCapture = getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);
// we need to reset exposure for the preview
resetExposureCompensation();
@@ -946,6 +1070,10 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
mSwitcher.addTouchView(findViewById(R.id.camera_switch_set));
}
+ // Show zoom picker.
+ ViewStub zoomStub = (ViewStub) findViewById(R.id.zoom_stub);
+ if (zoomStub != null) mZoomPicker = (ZoomPicker) zoomStub.inflate();
+
// Make sure preview is started.
try {
startPreviewThread.join();
@@ -956,9 +1084,12 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
} catch (InterruptedException ex) {
// ignore
}
+
+ initializeControlPanel();
}
private void changeHeadUpDisplayState() {
+ if (mHeadUpDisplay == null) return;
// If the camera resumes behind the lock screen, the orientation
// will be portrait. That causes OOM when we try to allocation GPU
// memory for the GLSurfaceView again when the orientation changes. So,
@@ -992,13 +1123,32 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
}
+ private void initializeControlPanel() {
+ String[] keys = new String[]{CameraSettings.KEY_FLASH_MODE,
+ CameraSettings.KEY_WHITE_BALANCE,
+ CameraSettings.KEY_COLOR_EFFECT,
+ CameraSettings.KEY_CAMERA_ID};
+ mControlPanel = (ControlPanel) findViewById(R.id.control_panel);
+ if (mControlPanel != null) {
+ CameraSettings settings = new CameraSettings(this, mInitialParams,
+ mCameraId, CameraHolder.instance().getCameraInfo());
+ mPreferenceGroup = settings.getPreferenceGroup(R.xml.camera_preferences);
+ mControlPanel.initialize(this, mPreferenceGroup, keys, true);
+ mControlPanel.setListener(new MyControlPanelListener());
+ }
+ }
+
private void initializeHeadUpDisplay() {
+ if (mHeadUpDisplay == null) return;
CameraSettings settings = new CameraSettings(this, mInitialParams,
- CameraHolder.instance().getCameraInfo());
+ mCameraId, CameraHolder.instance().getCameraInfo());
+ // If we have zoom picker, do not show zoom control on head-up display.
+ float[] zoomRatios = null;
+ if (mZoomPicker == null) zoomRatios = getZoomRatios();
mHeadUpDisplay.initialize(this,
settings.getPreferenceGroup(R.xml.camera_preferences),
- getZoomRatios(), mOrientationCompensation);
- if (mParameters.isZoomSupported()) {
+ zoomRatios, mOrientationCompensation);
+ if (mZoomPicker == null && mParameters.isZoomSupported()) {
mHeadUpDisplay.setZoomListener(new ZoomControllerListener() {
public void onZoomChanged(
int index, float ratio, boolean isMoving) {
@@ -1027,6 +1177,21 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
mGLRootView = null;
}
+ private boolean collapseCameraControls() {
+ if (mHeadUpDisplay != null && mHeadUpDisplay.collapse()) {
+ return true;
+ }
+ if (mControlPanel != null && mControlPanel.hideSettingPicker()) {
+ return true;
+ }
+ return false;
+ }
+
+ private void enableCameraControls(boolean enable) {
+ if (mHeadUpDisplay != null) mHeadUpDisplay.setEnabled(enable);
+ if (mControlPanel != null) mControlPanel.setEnabled(enable);
+ }
+
public static int roundOrientation(int orientation) {
return ((orientation + 45) / 90 * 90) % 360;
}
@@ -1043,24 +1208,27 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// the camera then point the camera to floor or sky, we still have
// the correct orientation.
if (orientation == ORIENTATION_UNKNOWN) return;
- mOrientation = roundOrientation(orientation);
- // When the screen is unlocked, display rotation may change. Always
- // calculate the up-to-date orientationCompensation.
- int orientationCompensation = mOrientation
- + Util.getDisplayRotation(Camera.this);
- if (mOrientationCompensation != orientationCompensation) {
- mOrientationCompensation = orientationCompensation;
+ orientation = roundOrientation(orientation);
+ if (orientation != mOrientation) {
+ mOrientation = orientation;
+ mOrientationCompensation = orientation
+ + Util.getDisplayRotation(Camera.this);
+
if (!mIsImageCaptureIntent) {
setOrientationIndicator(mOrientationCompensation);
}
- mHeadUpDisplay.setOrientation(mOrientationCompensation);
+ if (mHeadUpDisplay != null) {
+ mHeadUpDisplay.setOrientation(mOrientationCompensation);
+ }
}
}
}
private void setOrientationIndicator(int degree) {
- ((RotateImageView) findViewById(
- R.id.review_thumbnail)).setDegree(degree);
+ RotateImageView thumbnail = (RotateImageView) findViewById(
+ R.id.review_thumbnail);
+ if (thumbnail != null) thumbnail.setDegree(degree);
+
((RotateImageView) findViewById(
R.id.camera_switch_icon)).setDegree(degree);
((RotateImageView) findViewById(
@@ -1097,7 +1265,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
break;
case R.id.review_thumbnail:
if (isCameraIdle()) {
- viewLastImage();
+ viewImage(mThumbnailButton);
}
break;
case R.id.btn_done:
@@ -1105,9 +1273,19 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
break;
case R.id.btn_cancel:
doCancel();
+ break;
+ case R.id.btn_gallery:
+ gotoGallery();
+ break;
}
}
+ private class ThumbnailItemClickListener implements OnItemClickListener {
+ public void onItemClick(AdapterView<?> p, View v, int pos, long id) {
+ viewImage((RotateImageView)v);
+ }
+ }
+
private Bitmap createCaptureBitmap(byte[] data) {
// This is really stupid...we just want to read the orientation in
// the jpeg header.
@@ -1337,13 +1515,16 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// Close the camera now because other activities may need to use it.
closeCamera();
resetScreenOn();
+ collapseCameraControls();
changeHeadUpDisplayState();
if (mFirstTimeInitialized) {
mOrientationListener.disable();
if (!mIsImageCaptureIntent) {
- mThumbController.storeData(
- ImageManager.getLastImageThumbPath());
+ if (mThumbnailButton != null) {
+ mThumbnailButton.storeData(
+ ImageManager.getLastImageThumbPath());
+ }
}
hidePostCaptureAlert();
}
@@ -1407,7 +1588,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// Initiate autofocus only when preview is started and snapshot is not
// in progress.
if (canTakePicture()) {
- mHeadUpDisplay.setEnabled(false);
+ enableCameraControls(false);
Log.v(TAG, "Start autofocus.");
mFocusStartTime = System.currentTimeMillis();
mFocusState = FOCUSING;
@@ -1421,7 +1602,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
if (mStatus != SNAPSHOT_IN_PROGRESS && (mFocusState == FOCUSING
|| mFocusState == FOCUS_SUCCESS || mFocusState == FOCUS_FAIL)) {
Log.v(TAG, "Cancel autofocus.");
- mHeadUpDisplay.setEnabled(true);
+ enableCameraControls(true);
mCameraDevice.cancelAutoFocus();
}
if (mFocusState != FOCUSING_SNAP_ON_FINISH) {
@@ -1453,7 +1634,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
if (!isCameraIdle()) {
// ignore backs while we're taking a picture
return;
- } else if (mHeadUpDisplay == null || !mHeadUpDisplay.collapse()) {
+ } else if (!collapseCameraControls()) {
super.onBackPressed();
}
}
@@ -1478,7 +1659,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// Start auto-focus immediately to reduce shutter lag. After
// the shutter button gets the focus, doFocus() will be
// called again but it is fine.
- if (mHeadUpDisplay.collapse()) return true;
+ if (collapseCameraControls()) return true;
doFocus(true);
if (mShutterButton.isInTouchMode()) {
mShutterButton.requestFocusFromTouch();
@@ -1506,7 +1687,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
private void doSnap() {
- if (mHeadUpDisplay.collapse()) return;
+ if (collapseCameraControls()) return;
Log.v(TAG, "doSnap: mFocusState=" + mFocusState);
// If the user has half-pressed the shutter and focus is completed, we
@@ -1530,7 +1711,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private void doFocus(boolean pressed) {
// Do the focus if the mode is not infinity.
- if (mHeadUpDisplay.collapse()) return;
+ if (collapseCameraControls()) return;
if (!(mFocusMode.equals(Parameters.FOCUS_MODE_INFINITY)
|| mFocusMode.equals(Parameters.FOCUS_MODE_FIXED)
|| mFocusMode.equals(Parameters.FOCUS_MODE_EDOF))) {
@@ -1610,24 +1791,6 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
}
- private void updateLastImage() {
- IImageList list = ImageManager.makeImageList(
- mContentResolver,
- dataLocation(),
- ImageManager.INCLUDE_IMAGES,
- ImageManager.SORT_ASCENDING,
- ImageManager.CAMERA_IMAGE_BUCKET_ID);
- int count = list.getCount();
- if (count > 0) {
- IImage image = list.getImageAt(count - 1);
- Uri uri = image.fullSizeImageUri();
- mThumbController.setData(uri, image.miniThumbBitmap());
- } else {
- mThumbController.setData(null, null);
- }
- list.close();
- }
-
private void showCameraErrorAndFinish() {
Resources ress = getResources();
Util.showFatalErrorAndFinish(Camera.this,
@@ -1691,53 +1854,6 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
clearFocusState();
}
- private Size getOptimalPreviewSize(List<Size> sizes, double targetRatio) {
- final double ASPECT_TOLERANCE = 0.05;
- if (sizes == null) return null;
-
- Size optimalSize = null;
- double minDiff = Double.MAX_VALUE;
-
- // Because of bugs of overlay and layout, we sometimes will try to
- // layout the viewfinder in the portrait orientation and thus get the
- // wrong size of mSurfaceView. When we change the preview size, the
- // new overlay will be created before the old one closed, which causes
- // an exception. For now, just get the screen size
-
- Display display = getWindowManager().getDefaultDisplay();
- int targetHeight = Math.min(display.getHeight(), display.getWidth());
-
- if (targetHeight <= 0) {
- // We don't know the size of SurefaceView, use screen height
- WindowManager windowManager = (WindowManager)
- getSystemService(Context.WINDOW_SERVICE);
- targetHeight = windowManager.getDefaultDisplay().getHeight();
- }
-
- // Try to find an size match aspect ratio and size
- for (Size size : sizes) {
- double ratio = (double) size.width / size.height;
- if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
- if (Math.abs(size.height - targetHeight) < minDiff) {
- optimalSize = size;
- minDiff = Math.abs(size.height - targetHeight);
- }
- }
-
- // Cannot find the one match the aspect ratio, ignore the requirement
- if (optimalSize == null) {
- Log.v(TAG, "No preview size match the aspect ratio");
- minDiff = Double.MAX_VALUE;
- for (Size size : sizes) {
- if (Math.abs(size.height - targetHeight) < minDiff) {
- optimalSize = size;
- minDiff = Math.abs(size.height - targetHeight);
- }
- }
- }
- return optimalSize;
- }
-
private static boolean isSupported(String value, List<String> supported) {
return supported == null ? false : supported.indexOf(value) >= 0;
}
@@ -1781,7 +1897,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// Set a preview size that is closest to the viewfinder height and has
// the right aspect ratio.
List<Size> sizes = mParameters.getSupportedPreviewSizes();
- Size optimalSize = getOptimalPreviewSize(
+ Size optimalSize = Util.getOptimalPreviewSize(this,
sizes, (double) size.width / size.height);
if (optimalSize != null) {
Size original = mParameters.getPreviewSize();
@@ -1852,6 +1968,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
if (mHeadUpDisplay != null) updateSceneModeInHud();
+ // TODO: update icons on control panel.
if (Parameters.SCENE_MODE_AUTO.equals(mSceneMode)) {
// Set flash mode.
@@ -1945,21 +2062,22 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
MenuHelper.gotoCameraImageGallery(this);
}
- private void viewLastImage() {
- if (mThumbController.isUriValid()) {
- Intent intent = new Intent(Util.REVIEW_ACTION, mThumbController.getUri());
+ private void viewImage(RotateImageView view) {
+ if(!view.isUriValid()) {
+ Log.e(TAG, "Uri invalid. uri=" + view.getUri());
+ return;
+ }
+
+ try {
+ startActivity(new Intent(
+ Util.REVIEW_ACTION, view.getUri()));
+ } catch (ActivityNotFoundException ex) {
try {
- startActivity(intent);
- } catch (ActivityNotFoundException ex) {
- try {
- intent = new Intent(Intent.ACTION_VIEW, mThumbController.getUri());
- startActivity(intent);
- } catch (ActivityNotFoundException e) {
- Log.e(TAG, "review image fail", e);
- }
+ startActivity(new Intent(
+ Intent.ACTION_VIEW, view.getUri()));
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "review image fail. uri=" + view.getUri(), e);
}
- } else {
- Log.e(TAG, "Can't view last image.");
}
}
@@ -2201,7 +2319,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private class MyHeadUpDisplayListener implements HeadUpDisplay.Listener {
- public void onSharedPreferencesChanged() {
+ public void onSharedPreferenceChanged() {
Camera.this.onSharedPreferenceChanged();
}
@@ -2217,7 +2335,9 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
if (mPausing) return;
Runnable runnable = new Runnable() {
public void run() {
- mHeadUpDisplay.restorePreferences(mParameters);
+ if (mHeadUpDisplay != null) {
+ mHeadUpDisplay.restorePreferences(mParameters);
+ }
}
};
MenuHelper.confirmAction(this,
@@ -2225,6 +2345,12 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
getString(R.string.confirm_restore_message),
runnable);
}
+
+ private class MyControlPanelListener implements ControlPanel.Listener {
+ public void onSharedPreferenceChanged() {
+ Camera.this.onSharedPreferenceChanged();
+ }
+ }
}
class FocusRectangle extends View {
diff --git a/src/com/android/camera/CameraHolder.java b/src/com/android/camera/CameraHolder.java
index a1c1fb8..ec1a61e 100644
--- a/src/com/android/camera/CameraHolder.java
+++ b/src/com/android/camera/CameraHolder.java
@@ -49,7 +49,6 @@ public class CameraHolder {
private final Handler mHandler;
private int mUsers = 0; // number of open() - number of release()
private int mNumberOfCameras;
- private int mCameraId = -1;
private CameraInfo[] mInfo;
// We store the camera parameters when we actually open the device,
@@ -113,16 +112,10 @@ public class CameraHolder {
public synchronized android.hardware.Camera open(int cameraId)
throws CameraHardwareException {
Assert(mUsers == 0);
- if (mCameraDevice != null && mCameraId != cameraId) {
- mCameraDevice.release();
- mCameraDevice = null;
- mCameraId = -1;
- }
if (mCameraDevice == null) {
try {
Log.v(TAG, "open camera " + cameraId);
mCameraDevice = android.hardware.Camera.open(cameraId);
- mCameraId = cameraId;
} catch (RuntimeException e) {
Log.e(TAG, "fail to connect Camera", e);
throw new CameraHardwareException(e);
@@ -178,7 +171,6 @@ public class CameraHolder {
}
mCameraDevice.release();
mCameraDevice = null;
- mCameraId = -1;
}
public synchronized void keep() {
diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java
index 600575e..24ab449 100644
--- a/src/com/android/camera/CameraSettings.java
+++ b/src/com/android/camera/CameraSettings.java
@@ -39,6 +39,8 @@ public class CameraSettings {
public static final String KEY_LOCAL_VERSION = "pref_local_version_key";
public static final String KEY_RECORD_LOCATION = RecordLocationPreference.KEY;
public static final String KEY_VIDEO_QUALITY = "pref_video_quality_key";
+ public static final String KEY_VIDEO_TIME_LAPSE_QUALITY = "pref_video_time_lapse_quality_key";
+ public static final String KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL = "pref_video_time_lapse_frame_interval_key";
public static final String KEY_PICTURE_SIZE = "pref_camera_picturesize_key";
public static final String KEY_JPEG_QUALITY = "pref_camera_jpegquality_key";
public static final String KEY_FOCUS_MODE = "pref_camera_focusmode_key";
@@ -75,11 +77,13 @@ public class CameraSettings {
private final Context mContext;
private final Parameters mParameters;
private final CameraInfo[] mCameraInfo;
+ private final int mCameraId;
public CameraSettings(Activity activity, Parameters parameters,
- CameraInfo[] cameraInfo) {
+ int cameraId, CameraInfo[] cameraInfo) {
mContext = activity;
mParameters = parameters;
+ mCameraId = cameraId;
mCameraInfo = cameraInfo;
}
@@ -133,6 +137,7 @@ public class CameraSettings {
private void initPreference(PreferenceGroup group) {
ListPreference videoQuality = group.findPreference(KEY_VIDEO_QUALITY);
+ ListPreference videoTimeLapseQuality = group.findPreference(KEY_VIDEO_TIME_LAPSE_QUALITY);
ListPreference pictureSize = group.findPreference(KEY_PICTURE_SIZE);
ListPreference whiteBalance = group.findPreference(KEY_WHITE_BALANCE);
ListPreference colorEffect = group.findPreference(KEY_COLOR_EFFECT);
@@ -140,7 +145,7 @@ public class CameraSettings {
ListPreference flashMode = group.findPreference(KEY_FLASH_MODE);
ListPreference focusMode = group.findPreference(KEY_FOCUS_MODE);
ListPreference exposure = group.findPreference(KEY_EXPOSURE);
- IconListPreference cameraId =
+ IconListPreference cameraIdPref =
(IconListPreference)group.findPreference(KEY_CAMERA_ID);
ListPreference videoFlashMode =
group.findPreference(KEY_VIDEOCAMERA_FLASH_MODE);
@@ -163,6 +168,10 @@ public class CameraSettings {
}
// Filter out unsupported settings / options
+ if (videoTimeLapseQuality != null) {
+ filterUnsupportedOptions(group, videoTimeLapseQuality,
+ getSupportedTimeLapseProfiles(mCameraId));
+ }
if (pictureSize != null) {
filterUnsupportedOptions(group, pictureSize, sizeListToStringList(
mParameters.getSupportedPictureSizes()));
@@ -192,7 +201,22 @@ public class CameraSettings {
videoFlashMode, mParameters.getSupportedFlashModes());
}
if (exposure != null) buildExposureCompensation(group, exposure);
- if (cameraId != null) buildCameraId(group, cameraId);
+ if (cameraIdPref != null) buildCameraId(group, cameraIdPref);
+ }
+
+ private static List<String> getSupportedTimeLapseProfiles(int cameraId) {
+ ArrayList<String> supportedProfiles = new ArrayList<String>();
+ if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_TIME_LAPSE_480P)) {
+ supportedProfiles.add(Integer.toString(CamcorderProfile.QUALITY_TIME_LAPSE_480P));
+ }
+ if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_TIME_LAPSE_720P)) {
+ supportedProfiles.add(Integer.toString(CamcorderProfile.QUALITY_TIME_LAPSE_720P));
+ }
+ if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_TIME_LAPSE_1080P)) {
+ supportedProfiles.add(Integer.toString(CamcorderProfile.QUALITY_TIME_LAPSE_1080P));
+ }
+
+ return supportedProfiles;
}
private void buildExposureCompensation(
diff --git a/src/com/android/camera/IconListPreference.java b/src/com/android/camera/IconListPreference.java
index fc23f6c..2a01e7e 100644
--- a/src/com/android/camera/IconListPreference.java
+++ b/src/com/android/camera/IconListPreference.java
@@ -30,36 +30,44 @@ public class IconListPreference extends ListPreference {
private int mIconIds[];
private int mLargeIconIds[];
+ private int mImageIds[];
public IconListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.IconListPreference, 0, 0);
Resources res = context.getResources();
- mIconIds = getIconIds(res, a.getResourceId(
+ mIconIds = getIds(res, a.getResourceId(
R.styleable.IconListPreference_icons, 0));
- mLargeIconIds = getIconIds(res, a.getResourceId(
+ mLargeIconIds = getIds(res, a.getResourceId(
R.styleable.IconListPreference_largeIcons, 0));
+ mImageIds = getIds(res, a.getResourceId(
+ R.styleable.IconListPreference_images, 0));
+ if (mImageIds == null) mImageIds = mLargeIconIds;
a.recycle();
}
- public int[] getLargeIconIds() {
- return mLargeIconIds;
- }
-
public int[] getIconIds() {
return mIconIds;
}
- public void setLargeIconIds(int[] largeIconIds) {
- mLargeIconIds = largeIconIds;
+ public int[] getLargeIconIds() {
+ return mLargeIconIds;
+ }
+
+ public int[] getImageIds() {
+ return mImageIds;
}
public void setIconIds(int[] iconIds) {
mIconIds = iconIds;
}
- private int[] getIconIds(Resources res, int iconsRes) {
+ public void setLargeIconIds(int[] largeIconIds) {
+ mLargeIconIds = largeIconIds;
+ }
+
+ private int[] getIds(Resources res, int iconsRes) {
if (iconsRes == 0) return null;
TypedArray array = res.obtainTypedArray(iconsRes);
int n = array.length();
@@ -76,16 +84,20 @@ public class IconListPreference extends ListPreference {
CharSequence entryValues[] = getEntryValues();
IntArray iconIds = new IntArray();
IntArray largeIconIds = new IntArray();
+ IntArray imageIds = new IntArray();
+ // We allow mIconsIds to be null, but not mLargeIconIds. The reason is that if large icons
+ // are unspecified, the on screen icons will be blank which is a bug.
for (int i = 0, len = entryValues.length; i < len; i++) {
if (supported.indexOf(entryValues[i].toString()) >= 0) {
- iconIds.add(mIconIds[i]);
+ if (mIconIds != null) iconIds.add(mIconIds[i]);
largeIconIds.add(mLargeIconIds[i]);
+ if (mImageIds != null) imageIds.add(mImageIds[i]);
}
}
- int size = iconIds.size();
- mIconIds = iconIds.toArray(new int[size]);
- mLargeIconIds = iconIds.toArray(new int[size]);
+ if (mIconIds != null) mIconIds = iconIds.toArray(new int[iconIds.size()]);
+ mLargeIconIds = largeIconIds.toArray(new int[largeIconIds.size()]);
+ if (mImageIds != null) mImageIds = imageIds.toArray(new int[imageIds.size()]);
super.filterUnsupported(supported);
}
}
diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java
index 629cf87..a90726b 100644
--- a/src/com/android/camera/MenuHelper.java
+++ b/src/com/android/camera/MenuHelper.java
@@ -57,6 +57,7 @@ public class MenuHelper {
public static final int POSITION_SWITCH_CAMERA_MODE = 1;
public static final int POSITION_GOTO_GALLERY = 2;
public static final int POSITION_SWITCH_CAMERA_ID = 3;
+ public static final int POSITION_SWITCH_TIME_LAPSE_MODE = 4;
public static final int NO_STORAGE_ERROR = -1;
public static final int CANNOT_STAT_ERROR = -2;
diff --git a/src/com/android/camera/RotateImageView.java b/src/com/android/camera/RotateImageView.java
index 40fd007..57a7f13 100644
--- a/src/com/android/camera/RotateImageView.java
+++ b/src/com/android/camera/RotateImageView.java
@@ -17,13 +17,30 @@
package com.android.camera;
import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.Canvas;
-import android.graphics.Rect;
+import android.graphics.drawable.TransitionDrawable;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.Rect;
+import android.media.ThumbnailUtils;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.animation.AnimationUtils;
+import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
/**
* A @{code ImageView} which can rotate it's content.
*/
@@ -38,15 +55,21 @@ public class RotateImageView extends ImageView {
private int mStartDegree = 0;
private int mTargetDegree = 0;
- private boolean mClockwise = false;
+ private boolean mClockwise = false, mEnableAnimation = true;
private long mAnimationStartTime = 0;
private long mAnimationEndTime = 0;
+ private Uri mUri;
+
public RotateImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
+ public void enableAnimation(boolean enable) {
+ mEnableAnimation = enable;
+ }
+
public void setDegree(int degree) {
// make sure in the range of [0, 359]
degree = degree >= 0 ? degree % 360 : degree % 360 + 360;
@@ -72,7 +95,6 @@ public class RotateImageView extends ImageView {
@Override
protected void onDraw(Canvas canvas) {
-
Drawable drawable = getDrawable();
if (drawable == null) return;
@@ -110,4 +132,123 @@ public class RotateImageView extends ImageView {
drawable.draw(canvas);
canvas.restoreToCount(saveCount);
}
+
+ private Bitmap mThumb;
+ private Drawable[] mThumbs;
+ private TransitionDrawable mThumbTransition;
+
+ public void setData(Uri uri, Bitmap original) {
+ // Make sure uri and original are consistently both null or both
+ // non-null.
+ if (uri == null || original == null) {
+ uri = null;
+ original = null;
+ }
+ mUri = uri;
+ updateThumb(original);
+ }
+
+ public Uri getUri() {
+ return mUri;
+ }
+
+ private static final int BUFSIZE = 4096;
+
+ // Stores the data from the specified file.
+ // Returns true for success.
+ public boolean storeData(String filePath) {
+ if (mUri == null) {
+ return false;
+ }
+
+ FileOutputStream f = null;
+ BufferedOutputStream b = null;
+ DataOutputStream d = null;
+ try {
+ f = new FileOutputStream(filePath);
+ b = new BufferedOutputStream(f, BUFSIZE);
+ d = new DataOutputStream(b);
+ d.writeUTF(mUri.toString());
+ mThumb.compress(Bitmap.CompressFormat.PNG, 100, d);
+ d.close();
+ } catch (IOException e) {
+ return false;
+ } finally {
+ MenuHelper.closeSilently(f);
+ MenuHelper.closeSilently(b);
+ MenuHelper.closeSilently(d);
+ }
+ return true;
+ }
+
+ // Loads the data from the specified file.
+ // Returns true for success.
+ public boolean loadData(String filePath) {
+ FileInputStream f = null;
+ BufferedInputStream b = null;
+ DataInputStream d = null;
+ try {
+ f = new FileInputStream(filePath);
+ b = new BufferedInputStream(f, BUFSIZE);
+ d = new DataInputStream(b);
+ Uri uri = Uri.parse(d.readUTF());
+ Bitmap thumb = BitmapFactory.decodeStream(d);
+ setData(uri, thumb);
+ d.close();
+ } catch (IOException e) {
+ return false;
+ } finally {
+ MenuHelper.closeSilently(f);
+ MenuHelper.closeSilently(b);
+ MenuHelper.closeSilently(d);
+ }
+ return true;
+ }
+
+ private void updateThumb(Bitmap original) {
+ if (original == null) {
+ mThumb = null;
+ mThumbs = null;
+ setImageDrawable(null);
+ return;
+ }
+
+ LayoutParams param = getLayoutParams();
+ final int miniThumbWidth = param.width
+ - getPaddingLeft() - getPaddingRight();
+ final int miniThumbHeight = param.height
+ - getPaddingTop() - getPaddingBottom();
+ mThumb = ThumbnailUtils.extractThumbnail(
+ original, miniThumbWidth, miniThumbHeight);
+ Drawable drawable;
+ if (mThumbs == null || !mEnableAnimation) {
+ mThumbs = new Drawable[2];
+ mThumbs[1] = new BitmapDrawable(getContext().getResources(), mThumb);
+ setImageDrawable(mThumbs[1]);
+ } else {
+ mThumbs[0] = mThumbs[1];
+ mThumbs[1] = new BitmapDrawable(getContext().getResources(), mThumb);
+ mThumbTransition = new TransitionDrawable(mThumbs);
+ setImageDrawable(mThumbTransition);
+ mThumbTransition.startTransition(500);
+ }
+ }
+
+ public boolean isUriValid() {
+ if (mUri == null) {
+ return false;
+ }
+ try {
+ ParcelFileDescriptor pfd =
+ getContext().getContentResolver().openFileDescriptor(mUri, "r");
+ if (pfd == null) {
+ Log.e(TAG, "Fail to open URI. URI=" + mUri);
+ return false;
+ }
+ pfd.close();
+ } catch (IOException ex) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/src/com/android/camera/ThumbnailAdapter.java b/src/com/android/camera/ThumbnailAdapter.java
new file mode 100644
index 0000000..ba3fb68
--- /dev/null
+++ b/src/com/android/camera/ThumbnailAdapter.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+package com.android.camera;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.provider.MediaStore;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ResourceCursorAdapter;
+import android.util.Log;
+
+import java.lang.Math;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class ThumbnailAdapter extends ResourceCursorAdapter {
+ private final String TAG = "ThumbnailAdapter";
+ private int idIndex;
+ private boolean mIsImage;
+ private LinkedHashMap<String, Bitmap> mMap;
+
+ public ThumbnailAdapter(Context context, int layout, Cursor c,
+ boolean isImage) {
+ super(context, layout, c, false);
+ mIsImage = isImage;
+ if (mIsImage) {
+ idIndex = c.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID);
+ } else {
+ idIndex = c.getColumnIndexOrThrow(MediaStore.Video.Thumbnails._ID);
+ }
+ final int capacity = Math.max(c.getCount() * 2, 16);
+ mMap = new LinkedHashMap<String, Bitmap>(16, 0.75f, true) {
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<String, Bitmap> eldest) {
+ return size() > capacity;
+ }
+ };
+
+ }
+
+ @Override
+ public void bindView(View view, Context context, Cursor cursor) {
+ int id = cursor.getInt(idIndex);
+ Bitmap b;
+ Uri uri;
+ RotateImageView v = (RotateImageView) view;
+
+ if (mIsImage) {
+ uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+ Integer.toString(id));
+ } else {
+ uri = Uri.withAppendedPath(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
+ Integer.toString(id));
+ }
+ long start = System.currentTimeMillis();
+ // Sometimes MetadataRetriever fails to generate video thumbnail. To
+ // avoid wasting time to get thumbnail again, null is still put into
+ // hash map.
+ if (!mMap.containsKey(uri.toString())) {
+ if (mIsImage) {
+ b = MediaStore.Images.Thumbnails.getThumbnail(
+ context.getContentResolver(), id,
+ MediaStore.Images.Thumbnails.MICRO_KIND, null);
+ } else {
+ b = MediaStore.Video.Thumbnails.getThumbnail(
+ context.getContentResolver(), id,
+ MediaStore.Video.Thumbnails.MICRO_KIND, null);
+ }
+ mMap.put(uri.toString(), b);
+ } else {
+ b = mMap.get(uri.toString());
+ }
+ long end = System.currentTimeMillis();
+ Log.v(TAG, "Getting thumbnail takes " + (end - start) + "ms");
+ v.setData(uri, b);
+ }
+
+ @Override
+ public View newView(Context context, Cursor cursor, ViewGroup parent) {
+ View view = super.newView(context, cursor, parent);
+ ((RotateImageView)view).enableAnimation(false);
+ return view;
+ }
+}
diff --git a/src/com/android/camera/ThumbnailController.java b/src/com/android/camera/ThumbnailController.java
deleted file mode 100644
index 6b67cb0..0000000
--- a/src/com/android/camera/ThumbnailController.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * 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.ContentResolver;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.TransitionDrawable;
-import android.media.ThumbnailUtils;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.ImageView;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-/**
- * A controller shows thumbnail picture on a button. The thumbnail picture
- * corresponds to a URI of the original picture/video. The thumbnail bitmap
- * and the URI can be saved to a file (and later loaded from it).
- */
-public class ThumbnailController {
-
- @SuppressWarnings("unused")
- private static final String TAG = "ThumbnailController";
- private final ContentResolver mContentResolver;
- private Uri mUri;
- private Bitmap mThumb;
- private final ImageView mButton;
- private Drawable[] mThumbs;
- private TransitionDrawable mThumbTransition;
- private boolean mShouldAnimateThumb;
- private final Resources mResources;
-
- // The "frame" is a drawable we want to put on top of the thumbnail.
- public ThumbnailController(Resources resources,
- ImageView button, ContentResolver contentResolver) {
- mResources = resources;
- mButton = button;
- mContentResolver = contentResolver;
- }
-
- public void setData(Uri uri, Bitmap original) {
- // Make sure uri and original are consistently both null or both
- // non-null.
- if (uri == null || original == null) {
- uri = null;
- original = null;
- }
- mUri = uri;
- updateThumb(original);
- }
-
- public Uri getUri() {
- return mUri;
- }
-
- private static final int BUFSIZE = 4096;
-
- // Stores the data from the specified file.
- // Returns true for success.
- public boolean storeData(String filePath) {
- if (mUri == null) {
- return false;
- }
-
- FileOutputStream f = null;
- BufferedOutputStream b = null;
- DataOutputStream d = null;
- try {
- f = new FileOutputStream(filePath);
- b = new BufferedOutputStream(f, BUFSIZE);
- d = new DataOutputStream(b);
- d.writeUTF(mUri.toString());
- mThumb.compress(Bitmap.CompressFormat.PNG, 100, d);
- d.close();
- } catch (IOException e) {
- return false;
- } finally {
- MenuHelper.closeSilently(f);
- MenuHelper.closeSilently(b);
- MenuHelper.closeSilently(d);
- }
- return true;
- }
-
- // Loads the data from the specified file.
- // Returns true for success.
- public boolean loadData(String filePath) {
- FileInputStream f = null;
- BufferedInputStream b = null;
- DataInputStream d = null;
- try {
- f = new FileInputStream(filePath);
- b = new BufferedInputStream(f, BUFSIZE);
- d = new DataInputStream(b);
- Uri uri = Uri.parse(d.readUTF());
- Bitmap thumb = BitmapFactory.decodeStream(d);
- setData(uri, thumb);
- d.close();
- } catch (IOException e) {
- return false;
- } finally {
- MenuHelper.closeSilently(f);
- MenuHelper.closeSilently(b);
- MenuHelper.closeSilently(d);
- }
- return true;
- }
-
- public void updateDisplayIfNeeded() {
- if (mUri == null) {
- mButton.setImageDrawable(null);
- return;
- }
-
- if (mShouldAnimateThumb) {
- mThumbTransition.startTransition(500);
- mShouldAnimateThumb = false;
- }
- }
-
- private void updateThumb(Bitmap original) {
- if (original == null) {
- mThumb = null;
- mThumbs = null;
- return;
- }
-
- LayoutParams param = mButton.getLayoutParams();
- final int miniThumbWidth = param.width
- - mButton.getPaddingLeft() - mButton.getPaddingRight();
- final int miniThumbHeight = param.height
- - mButton.getPaddingTop() - mButton.getPaddingBottom();
- mThumb = ThumbnailUtils.extractThumbnail(
- original, miniThumbWidth, miniThumbHeight);
- Drawable drawable;
- if (mThumbs == null) {
- mThumbs = new Drawable[2];
- mThumbs[1] = new BitmapDrawable(mResources, mThumb);
- drawable = mThumbs[1];
- mShouldAnimateThumb = false;
- } else {
- mThumbs[0] = mThumbs[1];
- mThumbs[1] = new BitmapDrawable(mResources, mThumb);
- mThumbTransition = new TransitionDrawable(mThumbs);
- drawable = mThumbTransition;
- mShouldAnimateThumb = true;
- }
- mButton.setImageDrawable(drawable);
- }
-
- public boolean isUriValid() {
- if (mUri == null) {
- return false;
- }
- try {
- ParcelFileDescriptor pfd =
- mContentResolver.openFileDescriptor(mUri, "r");
- if (pfd == null) {
- Log.e(TAG, "Fail to open URI.");
- return false;
- }
- pfd.close();
- } catch (IOException ex) {
- return false;
- }
- return true;
- }
-}
diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java
index d5cd768..71d0c21 100644
--- a/src/com/android/camera/Util.java
+++ b/src/com/android/camera/Util.java
@@ -16,6 +16,8 @@
package com.android.camera;
+import com.android.camera.gallery.IImage;
+
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
@@ -23,16 +25,16 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
+import android.hardware.Camera.Size;
import android.util.Log;
+import android.view.Display;
import android.view.Surface;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
-import com.android.camera.gallery.IImage;
-import com.android.camera.R;
-
import java.io.Closeable;
+import java.util.List;
/**
* Collection of utility functions used in this package.
@@ -44,7 +46,7 @@ public class Util {
public static final int DIRECTION_UP = 2;
public static final int DIRECTION_DOWN = 3;
- public static final String REVIEW_ACTION = "com.cooliris.media.action.REVIEW";
+ public static final String REVIEW_ACTION = "com.android.camera.action.REVIEW";
private Util() {
}
@@ -309,4 +311,50 @@ public class Util {
}
camera.setDisplayOrientation(result);
}
+
+ public static Size getOptimalPreviewSize(Activity currentActivity,
+ List<Size> sizes, double targetRatio) {
+ final double ASPECT_TOLERANCE = 0.05;
+ if (sizes == null) return null;
+
+ Size optimalSize = null;
+ double minDiff = Double.MAX_VALUE;
+
+ // Because of bugs of overlay and layout, we sometimes will try to
+ // layout the viewfinder in the portrait orientation and thus get the
+ // wrong size of mSurfaceView. When we change the preview size, the
+ // new overlay will be created before the old one closed, which causes
+ // an exception. For now, just get the screen size
+
+ Display display = currentActivity.getWindowManager().getDefaultDisplay();
+ int targetHeight = Math.min(display.getHeight(), display.getWidth());
+
+ if (targetHeight <= 0) {
+ // We don't know the size of SurfaceView, use screen height
+ targetHeight = display.getHeight();
+ }
+
+ // Try to find an size match aspect ratio and size
+ for (Size size : sizes) {
+ double ratio = (double) size.width / size.height;
+ if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+
+ // Cannot find the one match the aspect ratio, ignore the requirement
+ if (optimalSize == null) {
+ Log.v(TAG, "No preview size match the aspect ratio");
+ minDiff = Double.MAX_VALUE;
+ for (Size size : sizes) {
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+ }
+ return optimalSize;
+ }
}
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index eae320a..e2732e3 100644
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -19,6 +19,7 @@ package com.android.camera;
import com.android.camera.gallery.IImage;
import com.android.camera.gallery.IImageList;
import com.android.camera.ui.CamcorderHeadUpDisplay;
+import com.android.camera.ui.ControlPanel;
import com.android.camera.ui.GLRootView;
import com.android.camera.ui.GLView;
import com.android.camera.ui.HeadUpDisplay;
@@ -33,9 +34,9 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
-import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.media.CamcorderProfile;
@@ -51,14 +52,16 @@ import android.os.Message;
import android.os.StatFs;
import android.os.SystemClock;
import android.provider.MediaStore;
-import android.provider.Settings;
import android.provider.MediaStore.Video;
+import android.provider.MediaStore.Video.VideoColumns;
+import android.provider.MediaStore.Video.Media;
+import android.provider.Settings;
import android.util.Log;
+import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
-import android.view.OrientationEventListener;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
@@ -68,8 +71,13 @@ import android.view.WindowManager;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.Button;
+import android.widget.CursorAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
@@ -91,6 +99,7 @@ public class VideoCamera extends NoSearchActivity
private static final String TAG = "videocamera";
+ private static final int INIT_RECORDER = 3;
private static final int CLEAR_SCREEN_DELAY = 4;
private static final int UPDATE_RECORD_TIME = 5;
private static final int ENABLE_SHUTTER_BUTTON = 6;
@@ -131,13 +140,22 @@ public class VideoCamera extends NoSearchActivity
private ImageView mVideoFrame;
private GLRootView mGLRootView;
private CamcorderHeadUpDisplay mHeadUpDisplay;
+ private ControlPanel mControlPanel;
+ private MenuItem mSwitchTimeLapseMenuItem;
private boolean mIsVideoCaptureIntent;
private boolean mQuickCapture;
- // mLastPictureButton and mThumbController
- // are non-null only if mIsVideoCaptureIntent is true.
- private ImageView mLastPictureButton;
- private ThumbnailController mThumbController;
+
+ // The layout of small devices has a thumbnail button, which shows the last
+ // captured picture.
+ private RotateImageView mThumbnailButton;
+ // The layout of xlarge devices have a list of thumbnails, which show the
+ // last captured pictures.
+ private ListView mThumbnailList;
+ private OnItemClickListener mThumbnailItemClickListener =
+ new ThumbnailItemClickListener();
+ private ThumbnailAdapter mThumbnailAdapter;
+
private boolean mStartPreviewFail = false;
private int mStorageStatus = STORAGE_STATUS_OK;
@@ -161,13 +179,20 @@ public class VideoCamera extends NoSearchActivity
// The video duration limit. 0 menas no limit.
private int mMaxVideoDurationInMs;
+ // Time Lapse parameters.
+ private boolean mCaptureTimeLapse = false;
+ private int mTimeBetweenTimeLapseFrameCaptureMs = 2000;
+
+ private int mDesiredPreviewWidth;
+ private int mDesiredPreviewHeight;
+
boolean mPausing = false;
boolean mPreviewing = false; // True if preview is started.
private ContentResolver mContentResolver;
private ShutterButton mShutterButton;
- private TextView mRecordingTimeView;
+ private TextView mRecordingTimeView, mTimeLapseRecordingTimeView;
private Switcher mSwitcher;
private boolean mRecordingTimeCountsDown = false;
@@ -180,12 +205,6 @@ public class VideoCamera extends NoSearchActivity
private int mNumberOfCameras;
private int mCameraId;
- private MyOrientationEventListener mOrientationListener;
- // The device orientation in degrees. Default is unknown.
- private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN;
- // The orientation compensation for icons and thumbnails.
- private int mOrientationCompensation = 0;
-
// This Handler is used to post message back onto the main thread of the
// application
private class MainHandler extends Handler {
@@ -208,6 +227,11 @@ public class VideoCamera extends NoSearchActivity
break;
}
+ case INIT_RECORDER: {
+ initializeRecorder();
+ break;
+ }
+
default:
Log.v(TAG, "Unhandled message: " + msg.what);
break;
@@ -226,7 +250,7 @@ public class VideoCamera extends NoSearchActivity
stopVideoRecording();
} else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
updateAndShowStorageHint(true);
- updateThumbnailButton();
+ initializeRecorder();
} else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
// SD card unavailable
// handled in ACTION_MEDIA_EJECT
@@ -334,19 +358,13 @@ public class VideoCamera extends NoSearchActivity
mIsVideoCaptureIntent = isVideoCaptureIntent();
mQuickCapture = getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);
- mRecordingTimeView = (TextView) findViewById(R.id.recording_time);
ViewGroup rootView = (ViewGroup) findViewById(R.id.video_camera);
LayoutInflater inflater = this.getLayoutInflater();
if (!mIsVideoCaptureIntent) {
View controlBar = inflater.inflate(
R.layout.camera_control, rootView);
- mLastPictureButton =
- (ImageView) controlBar.findViewById(R.id.review_thumbnail);
- mThumbController = new ThumbnailController(
- getResources(), mLastPictureButton, mContentResolver);
- mLastPictureButton.setOnClickListener(this);
- mThumbController.loadData(ImageManager.getLastVideoThumbPath());
+ initThumbnailButton();
mSwitcher = ((Switcher) findViewById(R.id.camera_switch));
mSwitcher.setOnSwitchListener(this);
mSwitcher.addTouchView(findViewById(R.id.camera_switch_set));
@@ -367,7 +385,9 @@ public class VideoCamera extends NoSearchActivity
mShutterButton.setOnShutterButtonListener(this);
mShutterButton.requestFocus();
- mOrientationListener = new MyOrientationEventListener(VideoCamera.this);
+ mRecordingTimeView = (TextView) findViewById(R.id.recording_time);
+ mTimeLapseRecordingTimeView = (TextView) findViewById(
+ R.id.time_lapse_recording_time);
// Make sure preview is started.
try {
@@ -385,6 +405,7 @@ public class VideoCamera extends NoSearchActivity
mHeadUpDisplay = new CamcorderHeadUpDisplay(this);
mHeadUpDisplay.setListener(new MyHeadUpDisplayListener());
initializeHeadUpDisplay();
+ initializeControlPanel();
}
private void changeHeadUpDisplayState() {
@@ -404,18 +425,16 @@ public class VideoCamera extends NoSearchActivity
private void initializeHeadUpDisplay() {
CameraSettings settings = new CameraSettings(this, mParameters,
- CameraHolder.instance().getCameraInfo());
+ mCameraId, CameraHolder.instance().getCameraInfo());
- PreferenceGroup group =
- settings.getPreferenceGroup(R.xml.video_preferences);
+ PreferenceGroup group = settings.getPreferenceGroup(R.xml.video_preferences);
if (mIsVideoCaptureIntent) {
group = filterPreferenceScreenByIntent(group);
}
- mHeadUpDisplay.initialize(this, group, mOrientationCompensation);
+ mHeadUpDisplay.initialize(this, group, mCaptureTimeLapse);
}
private void attachHeadUpDisplay() {
- mHeadUpDisplay.setOrientation(mOrientationCompensation);
FrameLayout frame = (FrameLayout) findViewById(R.id.frame);
mGLRootView = new GLRootView(this);
frame.addView(mGLRootView);
@@ -428,45 +447,20 @@ public class VideoCamera extends NoSearchActivity
mGLRootView = null;
}
- public static int roundOrientation(int orientation) {
- return ((orientation + 45) / 90 * 90) % 360;
- }
-
- private class MyOrientationEventListener
- extends OrientationEventListener {
- public MyOrientationEventListener(Context context) {
- super(context);
+ private void initializeControlPanel() {
+ String[] keys = new String[]{CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE,
+ CameraSettings.KEY_WHITE_BALANCE,
+ CameraSettings.KEY_COLOR_EFFECT,
+ CameraSettings.KEY_CAMERA_ID};
+ mControlPanel = (ControlPanel) findViewById(R.id.control_panel);
+ if (mControlPanel != null) {
+ CameraSettings settings = new CameraSettings(this, mParameters,
+ mCameraId, CameraHolder.instance().getCameraInfo());
+ mControlPanel.initialize(this,
+ settings.getPreferenceGroup(R.xml.video_preferences), keys,
+ false);
+ mControlPanel.setListener(new MyControlPanelListener());
}
-
- @Override
- public void onOrientationChanged(int orientation) {
- if (mMediaRecorderRecording) return;
- // We keep the last known orientation. So if the user first orient
- // the camera then point the camera to floor or sky, we still have
- // the correct orientation.
- if (orientation == ORIENTATION_UNKNOWN) return;
- mOrientation = roundOrientation(orientation);
- // When the screen is unlocked, display rotation may change. Always
- // calculate the up-to-date orientationCompensation.
- int orientationCompensation = mOrientation
- + Util.getDisplayRotation(VideoCamera.this);
- if (mOrientationCompensation != orientationCompensation) {
- mOrientationCompensation = orientationCompensation;
- if (!mIsVideoCaptureIntent) {
- setOrientationIndicator(mOrientationCompensation);
- }
- mHeadUpDisplay.setOrientation(mOrientationCompensation);
- }
- }
- }
-
- 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);
}
@Override
@@ -489,8 +483,7 @@ public class VideoCamera extends NoSearchActivity
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_retake:
- deleteCurrentVideo();
- hideAlert();
+ discardCurrentVideoAndInitRecorder();
break;
case R.id.btn_play:
startPlayVideoActivity();
@@ -499,10 +492,14 @@ public class VideoCamera extends NoSearchActivity
doReturnToCaller(true);
break;
case R.id.btn_cancel:
- stopVideoRecordingAndReturn(false);
+ stopVideoRecording();
+ doReturnToCaller(false);
break;
case R.id.review_thumbnail:
- if (!mMediaRecorderRecording) viewLastVideo();
+ if (!mMediaRecorderRecording) viewVideo(mThumbnailButton);
+ break;
+ case R.id.btn_gallery:
+ gotoGallery();
break;
}
}
@@ -512,14 +509,16 @@ public class VideoCamera extends NoSearchActivity
}
private void onStopVideoRecording(boolean valid) {
+ stopVideoRecording();
if (mIsVideoCaptureIntent) {
if (mQuickCapture) {
- stopVideoRecordingAndReturn(valid);
+ doReturnToCaller(valid);
} else {
- stopVideoRecordingAndShowAlert();
+ showAlert();
}
} else {
- stopVideoRecordingAndGetThumbnail();
+ getThumbnail();
+ initializeRecorder();
}
}
@@ -527,10 +526,15 @@ public class VideoCamera extends NoSearchActivity
switch (button.getId()) {
case R.id.shutter_button:
if (mHeadUpDisplay.collapse()) return;
+ if (mControlPanel != null) mControlPanel.hideSettingPicker();
if (mMediaRecorderRecording) {
onStopVideoRecording(true);
- } else {
+ } else if (mMediaRecorder != null) {
+ // If the click comes before recorder initialization, it is
+ // ignored. If users click the button during initialization,
+ // the event is put in the queue and record will be started
+ // eventually.
startVideoRecording();
}
mShutterButton.setEnabled(false);
@@ -540,6 +544,12 @@ public class VideoCamera extends NoSearchActivity
}
}
+ private void discardCurrentVideoAndInitRecorder() {
+ deleteCurrentVideo();
+ hideAlert();
+ mHandler.sendEmptyMessage(INIT_RECORDER);
+ }
+
private OnScreenHint mStorageHint;
private void updateAndShowStorageHint(boolean mayHaveSd) {
@@ -585,7 +595,39 @@ public class VideoCamera extends NoSearchActivity
: STORAGE_STATUS_OK;
}
+ private void readTimeLapseVideoPreferences() {
+ // Read CamcorderProfile quality.
+ String qualityStr = mPreferences.getString(
+ CameraSettings.KEY_VIDEO_TIME_LAPSE_QUALITY,
+ getString(R.string.pref_video_time_lapse_quality_default));
+ mProfile = CamcorderProfile.get(mCameraId, Integer.parseInt(qualityStr));
+
+ // Read interval between frame capture.
+ String frameIntervalStr = mPreferences.getString(
+ CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL,
+ getString(R.string.pref_video_time_lapse_frame_interval_default));
+ mTimeBetweenTimeLapseFrameCaptureMs = Integer.parseInt(frameIntervalStr);
+
+ mMaxVideoDurationInMs = 0; // No limit
+
+ // Time lapse mode can capture video (using the still camera) at resolutions
+ // higher than the supported preview sizes. In that case
+ // mProfile.{videoFrameWidth,videoFrameHeight} will correspond to an unsupported
+ // preview size. So choose preview size optimally from the supported preview
+ // sizes.
+ List<Size> sizes = mParameters.getSupportedPreviewSizes();
+ Size optimalSize = Util.getOptimalPreviewSize(this,
+ sizes, (double) mProfile.videoFrameWidth / mProfile.videoFrameHeight);
+ mDesiredPreviewWidth = optimalSize.width;
+ mDesiredPreviewHeight = optimalSize.height;
+ }
+
private void readVideoPreferences() {
+ if (mCaptureTimeLapse) {
+ readTimeLapseVideoPreferences();
+ return;
+ }
+
String quality = mPreferences.getString(
CameraSettings.KEY_VIDEO_QUALITY,
CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE);
@@ -614,6 +656,9 @@ public class VideoCamera extends NoSearchActivity
videoQualityHigh
? CamcorderProfile.QUALITY_HIGH
: CamcorderProfile.QUALITY_LOW);
+
+ mDesiredPreviewWidth = mProfile.videoFrameWidth;
+ mDesiredPreviewHeight = mProfile.videoFrameHeight;
}
private void resizeForPreviewAspectRatio() {
@@ -626,9 +671,6 @@ public class VideoCamera extends NoSearchActivity
super.onResume();
mPausing = false;
- // Start orientation listener as soon as possible because it takes
- // some time to get first orientation.
- mOrientationListener.enable();
mVideoPreview.setVisibility(View.VISIBLE);
readVideoPreferences();
resizeForPreviewAspectRatio();
@@ -655,9 +697,18 @@ public class VideoCamera extends NoSearchActivity
}
}, 200);
- changeHeadUpDisplayState();
+ if (mSurfaceHolder != null) {
+ mHandler.sendEmptyMessage(INIT_RECORDER);
+ }
- updateThumbnailButton();
+ changeHeadUpDisplayState();
+ // Update the last video thumbnail.
+ if (!mIsVideoCaptureIntent) {
+ if (mThumbnailButton != null && !mThumbnailButton.isUriValid()) {
+ updateThumbnailButton();
+ }
+ updateThumbnailList();
+ }
}
private void setPreviewDisplay(SurfaceHolder holder) {
@@ -677,6 +728,7 @@ public class VideoCamera extends NoSearchActivity
mCameraDevice = CameraHolder.instance().open(mCameraId);
}
+ mCameraDevice.lock();
if (mPreviewing == true) {
mCameraDevice.stopPreview();
mPreviewing = false;
@@ -692,6 +744,13 @@ public class VideoCamera extends NoSearchActivity
closeCamera();
throw new RuntimeException("startPreview failed", ex);
}
+
+ // If setPreviewDisplay has been set with a valid surface, unlock now.
+ // If surface is null, unlock later. Otherwise, setPreviewDisplay in
+ // surfaceChanged will fail.
+ if (mSurfaceHolder != null) {
+ mCameraDevice.unlock();
+ }
}
private void closeCamera() {
@@ -707,17 +766,7 @@ public class VideoCamera extends NoSearchActivity
mPreviewing = false;
}
- @Override
- protected void onPause() {
- super.onPause();
- mPausing = true;
-
- changeHeadUpDisplayState();
-
- // Hide the preview now. Otherwise, the preview may be rotated during
- // onPause and it is annoying to users.
- mVideoPreview.setVisibility(View.INVISIBLE);
-
+ private void finishRecorderAndCloseCamera() {
// This is similar to what mShutterButton.performClick() does,
// but not quite the same.
if (mMediaRecorderRecording) {
@@ -725,12 +774,28 @@ public class VideoCamera extends NoSearchActivity
stopVideoRecording();
showAlert();
} else {
- stopVideoRecordingAndGetThumbnail();
+ stopVideoRecording();
+ getThumbnail();
}
} else {
stopVideoRecording();
}
closeCamera();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mPausing = true;
+
+ changeHeadUpDisplayState();
+ if (mControlPanel != null) mControlPanel.hideSettingPicker();
+
+ // Hide the preview now. Otherwise, the preview may be rotated during
+ // onPause and it is annoying to users.
+ mVideoPreview.setVisibility(View.INVISIBLE);
+
+ finishRecorderAndCloseCamera();
if (mReceiver != null) {
unregisterReceiver(mReceiver);
@@ -738,8 +803,8 @@ public class VideoCamera extends NoSearchActivity
}
resetScreenOn();
- if (!mIsVideoCaptureIntent) {
- mThumbController.storeData(ImageManager.getLastVideoThumbPath());
+ if (!mIsVideoCaptureIntent && mThumbnailButton != null) {
+ mThumbnailButton.storeData(ImageManager.getLastVideoThumbPath());
}
if (mStorageHint != null) {
@@ -747,7 +812,8 @@ public class VideoCamera extends NoSearchActivity
mStorageHint = null;
}
- mOrientationListener.disable();
+ mHandler.removeMessages(INIT_RECORDER);
+
}
@Override
@@ -835,9 +901,17 @@ public class VideoCamera extends NoSearchActivity
// already started.
if (holder.isCreating()) {
setPreviewDisplay(holder);
+ mCameraDevice.unlock();
+ mHandler.sendEmptyMessage(INIT_RECORDER);
+ initThumbnailList();
} else {
stopVideoRecording();
+ // If video quality changes, the surface will change. But we need to
+ // initialize the recorder here. So collpase the head-up display to
+ // keep the state of recorder consistent.
+ mHeadUpDisplay.collapse();
restartPreview();
+ initializeRecorder();
}
}
@@ -923,8 +997,11 @@ public class VideoCamera extends NoSearchActivity
// Prepares media recorder.
private void initializeRecorder() {
Log.v(TAG, "initializeRecorder");
+ if (mMediaRecorder != null) return;
+
+ // We will call initializeRecorder() again when the alert is hidden.
// If the mCameraDevice is null, then this activity is going to finish
- if (mCameraDevice == null) return;
+ if (isAlertVisible() || mCameraDevice == null) return;
Intent intent = getIntent();
Bundle myExtras = intent.getExtras();
@@ -946,13 +1023,18 @@ public class VideoCamera extends NoSearchActivity
}
mMediaRecorder = new MediaRecorder();
- // Unlock the camera object before passing it to media recorder.
- mCameraDevice.unlock();
mMediaRecorder.setCamera(mCameraDevice);
- mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+ if (!mCaptureTimeLapse) {
+ mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+ }
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setProfile(mProfile);
- mMediaRecorder.setMaxDuration(mMaxVideoDurationInMs);
+ if (mMaxVideoDurationInMs != 0) {
+ mMediaRecorder.setMaxDuration(mMaxVideoDurationInMs);
+ }
+ if (mCaptureTimeLapse) {
+ mMediaRecorder.setCaptureRate((1000 / (double) mTimeBetweenTimeLapseFrameCaptureMs));
+ }
// Set output file.
if (mStorageStatus != STORAGE_STATUS_OK) {
@@ -993,29 +1075,14 @@ public class VideoCamera extends NoSearchActivity
// on the size restriction.
}
- // See android.hardware.Camera.Parameters.setRotation for
- // documentation.
- int rotation = 0;
- if (mOrientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
- CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
- if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
- rotation = (info.orientation - mOrientation + 360) % 360;
- } else { // back-facing camera
- rotation = (info.orientation + mOrientation) % 360;
- }
- }
- mMediaRecorder.setOrientationHint(rotation);
-
try {
mMediaRecorder.prepare();
} catch (IOException e) {
- Log.e(TAG, "prepare failed for " + mVideoFilename, e);
+ Log.e(TAG, "prepare failed for " + mVideoFilename);
releaseMediaRecorder();
throw new RuntimeException(e);
}
-
- mMediaRecorder.setOnErrorListener(this);
- mMediaRecorder.setOnInfoListener(this);
+ mMediaRecorderRecording = false;
}
private void releaseMediaRecorder() {
@@ -1026,8 +1093,6 @@ public class VideoCamera extends NoSearchActivity
mMediaRecorder.release();
mMediaRecorder = null;
}
- // Take back the camera object control from media recorder.
- mCameraDevice.lock();
}
private void createVideoPath() {
@@ -1089,6 +1154,14 @@ public class VideoCamera extends NoSearchActivity
}
}
+ private void setTimeLapseSwitchTitle(boolean enableTimeLapse) {
+ int labelId = enableTimeLapse
+ ? R.string.enable_time_lapse_mode
+ : R.string.disable_time_lapse_mode;
+
+ mSwitchTimeLapseMenuItem.setTitle(labelId);
+ }
+
private void addBaseMenuItems(Menu menu) {
MenuHelper.addSwitchModeMenuItem(menu, false, new Runnable() {
public void run() {
@@ -1119,6 +1192,45 @@ public class VideoCamera extends NoSearchActivity
}
}).setIcon(android.R.drawable.ic_menu_camera);
}
+
+ mSwitchTimeLapseMenuItem = menu.add(Menu.NONE, Menu.NONE,
+ MenuHelper.POSITION_SWITCH_TIME_LAPSE_MODE,
+ R.string.enable_time_lapse_mode)
+ .setOnMenuItemClickListener(new OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ switchTimeLapseMode();
+ return true;
+ }
+ }).setIcon(android.R.drawable.ic_menu_camera);
+ }
+
+ private void switchTimeLapseMode() {
+ mCaptureTimeLapse = !mCaptureTimeLapse;
+
+ finishRecorderAndCloseCamera();
+ mHandler.removeMessages(INIT_RECORDER);
+
+ // Read the video preferences
+ readVideoPreferences();
+ resetCameraParameters();
+
+ // Restart preview
+ try {
+ startPreview();
+ } catch (CameraHardwareException e) {
+ showCameraErrorAndFinish();
+ return;
+ }
+
+ // Reload the UI.
+ initializeHeadUpDisplay();
+
+ if (mSurfaceHolder != null) {
+ mHandler.sendEmptyMessage(INIT_RECORDER);
+ }
+
+ // Change menu
+ setTimeLapseSwitchTitle(!mCaptureTimeLapse);
}
private void switchCameraId(int cameraId) {
@@ -1126,19 +1238,8 @@ public class VideoCamera extends NoSearchActivity
mCameraId = cameraId;
CameraSettings.writePreferredCameraId(mPreferences, cameraId);
- // This is similar to what mShutterButton.performClick() does,
- // but not quite the same.
- if (mMediaRecorderRecording) {
- if (mIsVideoCaptureIntent) {
- stopVideoRecording();
- showAlert();
- } else {
- stopVideoRecordingAndGetThumbnail();
- }
- } else {
- stopVideoRecording();
- }
- closeCamera();
+ finishRecorderAndCloseCamera();
+ mHandler.removeMessages(INIT_RECORDER);
// Reload the preferences.
mPreferences.setLocalId(this, mCameraId);
@@ -1150,6 +1251,10 @@ public class VideoCamera extends NoSearchActivity
// Reload the UI.
initializeHeadUpDisplay();
+
+ if (mSurfaceHolder != null) {
+ mHandler.sendEmptyMessage(INIT_RECORDER);
+ }
}
private PreferenceGroup filterPreferenceScreenByIntent(
@@ -1205,35 +1310,43 @@ public class VideoCamera extends NoSearchActivity
private void startVideoRecording() {
Log.v(TAG, "startVideoRecording");
- if (mStorageStatus != STORAGE_STATUS_OK) {
- Log.v(TAG, "Storage issue, ignore the start request");
- return;
- }
+ if (!mMediaRecorderRecording) {
- initializeRecorder();
- if (mMediaRecorder == null) {
- Log.e(TAG, "Fail to initialize media recorder");
- return;
- }
+ if (mStorageStatus != STORAGE_STATUS_OK) {
+ Log.v(TAG, "Storage issue, ignore the start request");
+ return;
+ }
- pauseAudioPlayback();
+ // Check mMediaRecorder to see whether it is initialized or not.
+ if (mMediaRecorder == null) {
+ Log.e(TAG, "MediaRecorder is not initialized.");
+ return;
+ }
- try {
- mMediaRecorder.start(); // Recording is now started
- } catch (RuntimeException e) {
- Log.e(TAG, "Could not start media recorder. ", e);
- releaseMediaRecorder();
- return;
- }
- mHeadUpDisplay.setEnabled(false);
+ pauseAudioPlayback();
- mMediaRecorderRecording = true;
- mRecordingStartTime = SystemClock.uptimeMillis();
- updateRecordingIndicator(false);
- mRecordingTimeView.setText("");
- mRecordingTimeView.setVisibility(View.VISIBLE);
- updateRecordingTime();
- keepScreenOn();
+ try {
+ mMediaRecorder.setOnErrorListener(this);
+ mMediaRecorder.setOnInfoListener(this);
+ mMediaRecorder.start(); // Recording is now started
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Could not start media recorder. ", e);
+ return;
+ }
+ mHeadUpDisplay.setEnabled(false);
+
+ mMediaRecorderRecording = true;
+ mRecordingStartTime = SystemClock.uptimeMillis();
+ updateRecordingIndicator(false);
+ mRecordingTimeView.setText("");
+ mRecordingTimeView.setVisibility(View.VISIBLE);
+ if (mTimeLapseRecordingTimeView != null) {
+ mTimeLapseRecordingTimeView.setText("");
+ mTimeLapseRecordingTimeView.setVisibility(View.VISIBLE);
+ }
+ updateRecordingTime();
+ keepScreenOn();
+ }
}
private void updateRecordingIndicator(boolean showRecording) {
@@ -1244,19 +1357,9 @@ public class VideoCamera extends NoSearchActivity
mShutterButton.setImageDrawable(drawable);
}
- private void stopVideoRecordingAndGetThumbnail() {
- stopVideoRecording();
+ private void getThumbnail() {
acquireVideoThumb();
- }
-
- private void stopVideoRecordingAndReturn(boolean valid) {
- stopVideoRecording();
- doReturnToCaller(valid);
- }
-
- private void stopVideoRecordingAndShowAlert() {
- stopVideoRecording();
- showAlert();
+ updateThumbnailList();
}
private void showAlert() {
@@ -1302,53 +1405,58 @@ public class VideoCamera extends NoSearchActivity
return this.mVideoFrame.getVisibility() == View.VISIBLE;
}
- private void viewLastVideo() {
- Intent intent = null;
- if (mThumbController.isUriValid()) {
- intent = new Intent(Util.REVIEW_ACTION, mThumbController.getUri());
+ private void viewVideo(RotateImageView view) {
+ if(view.isUriValid()) {
+ Intent intent = new Intent(Util.REVIEW_ACTION, view.getUri());
try {
startActivity(intent);
} catch (ActivityNotFoundException ex) {
try {
- intent = new Intent(Intent.ACTION_VIEW, mThumbController.getUri());
+ intent = new Intent(Intent.ACTION_VIEW, view.getUri());
startActivity(intent);
} catch (ActivityNotFoundException e) {
- Log.e(TAG, "review video fail", e);
+ Log.e(TAG, "review video fail. uri=" + view.getUri(), e);
}
}
} else {
- Log.e(TAG, "Can't view last video.");
+ Log.e(TAG, "Uri invalid. uri=" + view.getUri());
}
}
private void stopVideoRecording() {
Log.v(TAG, "stopVideoRecording");
- if (mMediaRecorderRecording) {
- boolean needToRegisterRecording = false;
- mMediaRecorder.setOnErrorListener(null);
- mMediaRecorder.setOnInfoListener(null);
- try {
- mMediaRecorder.stop();
- mCurrentVideoFilename = mVideoFilename;
- Log.v(TAG, "Setting current video filename: "
- + mCurrentVideoFilename);
- needToRegisterRecording = true;
- } catch (RuntimeException e) {
- Log.e(TAG, "stop fail: " + e.getMessage());
- deleteVideoFile(mVideoFilename);
+ boolean needToRegisterRecording = false;
+ if (mMediaRecorderRecording || mMediaRecorder != null) {
+ if (mMediaRecorderRecording && mMediaRecorder != null) {
+ try {
+ mMediaRecorder.setOnErrorListener(null);
+ mMediaRecorder.setOnInfoListener(null);
+ mMediaRecorder.stop();
+ mCurrentVideoFilename = mVideoFilename;
+ Log.v(TAG, "Setting current video filename: "
+ + mCurrentVideoFilename);
+ needToRegisterRecording = true;
+ } catch (RuntimeException e) {
+ Log.e(TAG, "stop fail: " + e.getMessage());
+ deleteVideoFile(mVideoFilename);
+ }
+ mHeadUpDisplay.setEnabled(true);
+ mMediaRecorderRecording = false;
}
- mMediaRecorderRecording = false;
- mHeadUpDisplay.setEnabled(true);
+ releaseMediaRecorder();
updateRecordingIndicator(true);
mRecordingTimeView.setVisibility(View.GONE);
- keepScreenOnAwhile();
- if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) {
- registerVideo();
+ if (mTimeLapseRecordingTimeView != null) {
+ mTimeLapseRecordingTimeView.setVisibility(View.GONE);
}
- mVideoFilename = null;
- mVideoFileDescriptor = null;
+ keepScreenOnAwhile();
+ }
+ if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) {
+ registerVideo();
}
- releaseMediaRecorder(); // always release media recorder
+
+ mVideoFilename = null;
+ mVideoFileDescriptor = null;
}
private void resetScreenOn() {
@@ -1368,27 +1476,22 @@ public class VideoCamera extends NoSearchActivity
}
private void acquireVideoThumb() {
- Bitmap videoFrame = ThumbnailUtils.createVideoThumbnail(
- mCurrentVideoFilename, Video.Thumbnails.MINI_KIND);
- mThumbController.setData(mCurrentVideoUri, videoFrame);
- mThumbController.updateDisplayIfNeeded();
- }
-
- private static ImageManager.DataLocation dataLocation() {
- return ImageManager.DataLocation.EXTERNAL;
+ if (mThumbnailButton != null) {
+ Bitmap videoFrame = ThumbnailUtils.createVideoThumbnail(
+ mCurrentVideoFilename, Video.Thumbnails.MINI_KIND);
+ mThumbnailButton.setData(mCurrentVideoUri, videoFrame);
+ }
}
- private void updateThumbnailButton() {
- // Update the last video thumbnail.
- if (!mIsVideoCaptureIntent) {
- if (!mThumbController.isUriValid()) {
- updateLastVideo();
- }
- mThumbController.updateDisplayIfNeeded();
+ private void initThumbnailButton() {
+ mThumbnailButton = (RotateImageView)findViewById(R.id.review_thumbnail);
+ if (mThumbnailButton != null) {
+ mThumbnailButton.setOnClickListener(this);
+ mThumbnailButton.loadData(ImageManager.getLastVideoThumbPath());
}
}
- private void updateLastVideo() {
+ private void updateThumbnailButton() {
IImageList list = ImageManager.makeImageList(
mContentResolver,
dataLocation(),
@@ -1399,13 +1502,128 @@ public class VideoCamera extends NoSearchActivity
if (count > 0) {
IImage image = list.getImageAt(count - 1);
Uri uri = image.fullSizeImageUri();
- mThumbController.setData(uri, image.miniThumbBitmap());
+ mThumbnailButton.setData(uri, image.miniThumbBitmap());
} else {
- mThumbController.setData(null, null);
+ mThumbnailButton.setData(null, null);
}
list.close();
}
+ private Cursor getThumbnailsCursor(int thumbnailCount) {
+ Log.v(TAG, "thumbnailCount=" + thumbnailCount);
+ String[] projections = { MediaStore.Video.Thumbnails._ID };
+ Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
+ .buildUpon()
+ .appendQueryParameter("limit", String.valueOf(thumbnailCount))
+ .build();
+ // TODO: managedQuery is deprecated. Use CursorLoader.
+ return managedQuery(uri, projections, Media.BUCKET_ID + " = ?",
+ new String[] {ImageManager.CAMERA_IMAGE_BUCKET_ID},
+ VideoColumns._ID + " DESC");
+ }
+
+ private void initThumbnailList() {
+ mThumbnailList = (ListView) findViewById(R.id.thumbnail_list);
+ if (mThumbnailList == null) return;
+
+ int width = mThumbnailList.getWidth();
+ int height = mThumbnailList.getHeight();
+
+ // Add gallery button to header view.
+ if (mThumbnailList.getHeaderViewsCount() == 0) {
+ LayoutInflater inflater = getLayoutInflater();
+ Button b = new Button(this);
+ ListView.LayoutParams params = new ListView.LayoutParams(width, width);
+ b.setId(R.id.btn_gallery);
+ b.setLayoutParams(params);
+ b.setOnClickListener(this);
+ b.setBackgroundResource(R.drawable.ic_menu_gallery);
+ mThumbnailList.addHeaderView(b);
+ }
+
+ // Set cursor adapter.
+ int thumbnailCount = (height + mThumbnailList.getDividerHeight())
+ / (width + mThumbnailList.getDividerHeight()) - 1;
+ Cursor cursor = getThumbnailsCursor(thumbnailCount);
+ mThumbnailAdapter = new ThumbnailAdapter(
+ getApplicationContext(), R.layout.thumbnail_item, cursor,
+ false);
+ mThumbnailList.setAdapter(mThumbnailAdapter);
+ mThumbnailList.setOnItemClickListener(mThumbnailItemClickListener);
+ }
+
+ private void updateThumbnailList() {
+ if (mThumbnailList == null) return;
+ mThumbnailAdapter.getCursor().requery();
+ mThumbnailAdapter.notifyDataSetChanged();
+ }
+
+ private class ThumbnailItemClickListener implements OnItemClickListener {
+ public void onItemClick(AdapterView<?> p, View v, int pos, long id) {
+ viewVideo((RotateImageView)v);
+ }
+ }
+
+ private static ImageManager.DataLocation dataLocation() {
+ return ImageManager.DataLocation.EXTERNAL;
+ }
+
+ private static String millisecondToTimeString(long milliSeconds, boolean displayCentiSeconds) {
+ long seconds = milliSeconds / 1000; // round down to compute seconds
+ long minutes = seconds / 60;
+ long hours = minutes / 60;
+ long remainderMinutes = minutes - (hours * 60);
+ long remainderSeconds = seconds - (minutes * 60);
+
+ StringBuilder timeStringBuilder = new StringBuilder();
+
+ // Hours
+ if (hours > 0) {
+ if (hours < 10) {
+ timeStringBuilder.append('0');
+ }
+ timeStringBuilder.append(hours);
+
+ timeStringBuilder.append(':');
+ }
+
+ // Minutes
+ if (remainderMinutes < 10) {
+ timeStringBuilder.append('0');
+ }
+ timeStringBuilder.append(remainderMinutes);
+ timeStringBuilder.append(':');
+
+ // Seconds
+ if (remainderSeconds < 10) {
+ timeStringBuilder.append('0');
+ }
+ timeStringBuilder.append(remainderSeconds);
+
+ // Centi seconds
+ if (displayCentiSeconds) {
+ timeStringBuilder.append('.');
+ long remainderCentiSeconds = (milliSeconds - seconds * 1000) / 10;
+ if (remainderCentiSeconds < 10) {
+ timeStringBuilder.append('0');
+ }
+ timeStringBuilder.append(remainderCentiSeconds);
+ }
+
+ return timeStringBuilder.toString();
+ }
+
+ // Calculates the time lapse video length till now and returns it in
+ // the format hh:mm:ss.dd, where dd are the centi seconds.
+ private String getTimeLapseVideoLengthString(long deltaMs) {
+ // For better approximation calculate fractional number of frames captured.
+ // This will update the video time at a higher resolution.
+ double numberOfFrames = (double) deltaMs / mTimeBetweenTimeLapseFrameCaptureMs;
+ long videoTimeMs =
+ (long) (numberOfFrames / (double) mProfile.videoFrameRate * 1000);
+ return millisecondToTimeString(videoTimeMs, true);
+ }
+
private void updateRecordingTime() {
if (!mMediaRecorderRecording) {
return;
@@ -1418,36 +1636,27 @@ public class VideoCamera extends NoSearchActivity
boolean countdownRemainingTime = (mMaxVideoDurationInMs != 0
&& delta >= mMaxVideoDurationInMs - 60000);
- long next_update_delay = 1000 - (delta % 1000);
- long seconds;
+ long deltaAdjusted = delta;
if (countdownRemainingTime) {
- delta = Math.max(0, mMaxVideoDurationInMs - delta);
- seconds = (delta + 999) / 1000;
- } else {
- seconds = delta / 1000; // round to nearest
- }
-
- long minutes = seconds / 60;
- long hours = minutes / 60;
- long remainderMinutes = minutes - (hours * 60);
- long remainderSeconds = seconds - (minutes * 60);
-
- String secondsString = Long.toString(remainderSeconds);
- if (secondsString.length() < 2) {
- secondsString = "0" + secondsString;
- }
- String minutesString = Long.toString(remainderMinutes);
- if (minutesString.length() < 2) {
- minutesString = "0" + minutesString;
- }
- String text = minutesString + ":" + secondsString;
- if (hours > 0) {
- String hoursString = Long.toString(hours);
- if (hoursString.length() < 2) {
- hoursString = "0" + hoursString;
+ deltaAdjusted = Math.max(0, mMaxVideoDurationInMs - deltaAdjusted) + 999;
+ }
+ String text = millisecondToTimeString(deltaAdjusted, false);
+
+ if (mCaptureTimeLapse) {
+ // Since the length of time lapse video is different from the length
+ // of the actual wall clock time elapsed, we display the video length
+ // alongside the wall clock time.
+ String timeLapseText = "(" + getTimeLapseVideoLengthString(delta) + ")";
+ // In xlarge layout, recording time and time lapse recording time
+ // are separated in two lines. In other layouts, they are in one
+ // line.
+ if (mTimeLapseRecordingTimeView == null) {
+ text += " " + timeLapseText;
+ } else {
+ mTimeLapseRecordingTimeView.setText(timeLapseText);
}
- text = hoursString + ":" + text;
}
+
mRecordingTimeView.setText(text);
if (mRecordingTimeCountsDown != countdownRemainingTime) {
@@ -1462,8 +1671,9 @@ public class VideoCamera extends NoSearchActivity
mRecordingTimeView.setTextColor(color);
}
+ long nextUpdateDelay = 1000 - (delta % 1000);
mHandler.sendEmptyMessageDelayed(
- UPDATE_RECORD_TIME, next_update_delay);
+ UPDATE_RECORD_TIME, nextUpdateDelay);
}
private static boolean isSupported(String value, List<String> supported) {
@@ -1473,7 +1683,7 @@ public class VideoCamera extends NoSearchActivity
private void setCameraParameters() {
mParameters = mCameraDevice.getParameters();
- mParameters.setPreviewSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight);
+ mParameters.setPreviewSize(mDesiredPreviewWidth, mDesiredPreviewHeight);
mParameters.setPreviewFrameRate(mProfile.videoFrameRate);
// Set flash mode.
@@ -1548,15 +1758,26 @@ public class VideoCamera extends NoSearchActivity
private void resetCameraParameters() {
// We need to restart the preview if preview size is changed.
Size size = mParameters.getPreviewSize();
- if (size.width != mProfile.videoFrameWidth
- || size.height != mProfile.videoFrameHeight) {
+ if (size.width != mDesiredPreviewWidth
+ || size.height != mDesiredPreviewHeight) {
// It is assumed media recorder is released before
// onSharedPreferenceChanged, so we can close the camera here.
closeCamera();
resizeForPreviewAspectRatio();
restartPreview(); // Parameters will be set in startPreview().
} else {
+ try {
+ // We need to lock the camera before writing parameters.
+ mCameraDevice.lock();
+ } catch (RuntimeException e) {
+ // When preferences are added for the first time, this method
+ // will be called. But OnScreenSetting is not displayed yet and
+ // media recorder still owns the camera. Lock will fail and we
+ // just ignore it.
+ return;
+ }
setCameraParameters();
+ mCameraDevice.unlock();
}
}
@@ -1565,10 +1786,10 @@ public class VideoCamera extends NoSearchActivity
}
private class MyHeadUpDisplayListener implements HeadUpDisplay.Listener {
- public void onSharedPreferencesChanged() {
+ public void onSharedPreferenceChanged() {
mHandler.post(new Runnable() {
public void run() {
- VideoCamera.this.onSharedPreferencesChanged();
+ VideoCamera.this.onSharedPreferenceChanged();
}
});
}
@@ -1582,6 +1803,19 @@ public class VideoCamera extends NoSearchActivity
}
public void onPopupWindowVisibilityChanged(final int visibility) {
+ mHandler.post(new Runnable() {
+ public void run() {
+ VideoCamera.this.onPopupWindowVisibilityChanged(visibility);
+ }
+ });
+ }
+ }
+
+ private void onPopupWindowVisibilityChanged(int visibility) {
+ if (visibility == GLView.VISIBLE) {
+ releaseMediaRecorder();
+ } else {
+ if (!mPausing && mSurfaceHolder != null) initializeRecorder();
}
}
@@ -1597,7 +1831,7 @@ public class VideoCamera extends NoSearchActivity
runnable);
}
- private void onSharedPreferencesChanged() {
+ private void onSharedPreferenceChanged() {
// ignore the events after "onPause()" or preview has not started yet
if (mPausing) return;
synchronized (mPreferences) {
@@ -1615,4 +1849,10 @@ public class VideoCamera extends NoSearchActivity
}
}
}
+
+ private class MyControlPanelListener implements ControlPanel.Listener {
+ public void onSharedPreferenceChanged() {
+ VideoCamera.this.onSharedPreferenceChanged();
+ }
+ }
}
diff --git a/src/com/android/camera/ui/BasicIndicator.java b/src/com/android/camera/ui/BasicIndicator.java
index 7630a8e..9f076b8 100644
--- a/src/com/android/camera/ui/BasicIndicator.java
+++ b/src/com/android/camera/ui/BasicIndicator.java
@@ -19,31 +19,47 @@ package com.android.camera.ui;
import android.content.Context;
import com.android.camera.IconListPreference;
+import com.android.camera.ListPreference;
import com.android.camera.R;
import com.android.camera.Util;
import com.android.camera.ui.GLListView.OnItemSelectedListener;
class BasicIndicator extends AbstractIndicator {
+ private static final float FONT_SIZE = 18;
+ private static final int FONT_COLOR = 0xA8FFFFFF;
private static final int COLOR_OPTION_ITEM_HIGHLIGHT = 0xFF181818;
private final ResourceTexture mIcon[];
- private final IconListPreference mPreference;
+ private final ListPreference mPreference;
protected int mIndex;
private GLListView mPopupContent;
private PreferenceAdapter mModel;
private String mOverride;
+ private int mTitleIndex;
+ private StringTexture mTitle;
+ private final float mFontSize;
+ private boolean mIsIconListMode;
- public BasicIndicator(Context context, IconListPreference preference) {
+ public BasicIndicator(Context context, ListPreference preference) {
super(context);
mPreference = preference;
- mIcon = new ResourceTexture[preference.getLargeIconIds().length];
mIndex = preference.findIndexOfValue(preference.getValue());
+ if (preference instanceof IconListPreference) {
+ mIsIconListMode = true;
+ mIcon = new ResourceTexture[((IconListPreference) preference).getLargeIconIds().length];
+ mFontSize = 0;
+ } else {
+ mIsIconListMode = false;
+ mIcon = null;
+ mFontSize = GLRootView.dpToPixel(context, FONT_SIZE);
+ mTitleIndex = -1;
+ }
}
// Set the override and/or reload the value from preferences.
private void updateContent(String override, boolean reloadValue) {
if (!reloadValue && Util.equals(mOverride, override)) return;
- IconListPreference pref = mPreference;
+ ListPreference pref = mPreference;
mOverride = override;
int index = pref.findIndexOfValue(
override == null ? pref.getValue() : override);
@@ -55,7 +71,7 @@ class BasicIndicator extends AbstractIndicator {
@Override
public void overrideSettings(String key, String settings) {
- IconListPreference pref = mPreference;
+ ListPreference pref = mPreference;
if (!pref.getKey().equals(key)) return;
updateContent(settings, false);
}
@@ -104,13 +120,23 @@ class BasicIndicator extends AbstractIndicator {
}
@Override
- protected ResourceTexture getIcon() {
- int index = mIndex;
- if (mIcon[index] == null) {
- Context context = getGLRootView().getContext();
- mIcon[index] = new ResourceTexture(
- context, mPreference.getLargeIconIds()[index]);
+ protected BitmapTexture getIcon() {
+ if (mIsIconListMode) {
+ int index = mIndex;
+ if (mIcon[index] == null) {
+ Context context = getGLRootView().getContext();
+ mIcon[index] = new ResourceTexture(
+ context, ((IconListPreference) mPreference).getLargeIconIds()[index]);
+ }
+ return mIcon[index];
+ } else {
+ if (mTitleIndex != mIndex) {
+ mTitleIndex = mIndex;
+ if (mTitle != null) mTitle.deleteFromGL();
+ String value = mPreference.getEntry();
+ mTitle = StringTexture.newInstance(value, mFontSize, FONT_COLOR);
+ }
+ return mTitle;
}
- return mIcon[index];
}
}
diff --git a/src/com/android/camera/ui/BasicSettingPicker.java b/src/com/android/camera/ui/BasicSettingPicker.java
new file mode 100644
index 0000000..4f2011d
--- /dev/null
+++ b/src/com/android/camera/ui/BasicSettingPicker.java
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+package com.android.camera.ui;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.camera.IconListPreference;
+import com.android.camera.R;
+import com.android.camera.Util;
+import com.android.camera.ui.GLListView.OnItemSelectedListener;
+
+public class BasicSettingPicker extends LinearLayout {
+ private static final String TAG = "BasicSettingPicker";
+ private IconListPreference mPreference;
+ private final Context mContext;
+ private Listener mListener;
+
+ static public interface Listener {
+ public void onSettingChanged();
+ }
+
+ public BasicSettingPicker(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mContext = context;
+ }
+
+ public void initialize(IconListPreference preference) {
+ mPreference = preference;
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ CharSequence[] entries = mPreference.getEntries();
+ CharSequence[] values = mPreference.getEntryValues();
+ int[] imageIds = mPreference.getImageIds();
+ int index = preference.findIndexOfValue(preference.getValue());
+
+ int pos = 0;
+ for (int i = 0, n = entries.length; i < n; ++i) {
+ // Add the image.
+ ImageView image;
+ Drawable drawable = mContext.getResources().getDrawable(imageIds[i]);
+ // Sacle the image if it is too small.
+ if (drawable.getIntrinsicWidth() >= getLayoutParams().width) {
+ image = (ImageView) inflater.inflate(
+ R.layout.setting_image_item, null);
+ } else {
+ image = (ImageView) inflater.inflate(
+ R.layout.setting_scale_image_item, null);
+ }
+ image.setImageDrawable(drawable);
+ image.setClickable(false);
+ addView(image, pos++);
+
+ // Add the text.
+ TextView text = (TextView) inflater.inflate(
+ R.layout.setting_text_item, null);
+ text.setText(entries[i].toString());
+ text.setClickable(false);
+ if (index == i) text.setPressed(true);
+ addView(text, pos++);
+ }
+ requestLayout();
+ }
+
+ public void setSettingChangedListener(Listener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ int action = event.getAction();
+ if (action == MotionEvent.ACTION_MOVE
+ || action == MotionEvent.ACTION_DOWN) {
+ int y = (int) event.getY();
+ // Check which child is pressed.
+ for (int i = 0; i < getChildCount() - 1; i++) {
+ View v = getChildAt(i);
+ if (y >= v.getTop() && y <= v.getBottom()) {
+ int index = i / 2;
+ CharSequence[] values = mPreference.getEntryValues();
+ int oldIndex = mPreference.findIndexOfValue(mPreference.getValue());
+ if (oldIndex != index) {
+ View oldText = getChildAt(oldIndex * 2 + 1);
+ oldText.setPressed(false);
+ View text = getChildAt(index * 2 + 1);
+ text.setPressed(true);
+ mPreference.setValueIndex(index);
+ if (mListener != null) {
+ mListener.onSettingChanged();
+ }
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/com/android/camera/ui/CamcorderHeadUpDisplay.java b/src/com/android/camera/ui/CamcorderHeadUpDisplay.java
index 0c2454f..c69b92b 100644
--- a/src/com/android/camera/ui/CamcorderHeadUpDisplay.java
+++ b/src/com/android/camera/ui/CamcorderHeadUpDisplay.java
@@ -26,16 +26,16 @@ public class CamcorderHeadUpDisplay extends HeadUpDisplay {
private static final String TAG = "CamcorderHeadUpDisplay";
+ private boolean mCaptureTimeLapse;
private OtherSettingsIndicator mOtherSettings;
- private int mInitialOrientation;
public CamcorderHeadUpDisplay(Context context) {
super(context);
}
public void initialize(Context context, PreferenceGroup group,
- int initialOrientation) {
- mInitialOrientation = initialOrientation;
+ boolean captureTimeLapse) {
+ mCaptureTimeLapse = captureTimeLapse;
super.initialize(context, group);
}
@@ -64,9 +64,12 @@ public class CamcorderHeadUpDisplay extends HeadUpDisplay {
addIndicator(context, group, CameraSettings.KEY_WHITE_BALANCE);
addIndicator(context, group, CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE);
- addIndicator(context, group, CameraSettings.KEY_VIDEO_QUALITY);
+ if (mCaptureTimeLapse) {
+ addIndicator(context, group, CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL);
+ addIndicator(context, group, CameraSettings.KEY_VIDEO_TIME_LAPSE_QUALITY);
+ } else {
+ addIndicator(context, group, CameraSettings.KEY_VIDEO_QUALITY);
+ }
addIndicator(context, group, CameraSettings.KEY_CAMERA_ID);
-
- mIndicatorBar.setOrientation(mInitialOrientation);
}
}
diff --git a/src/com/android/camera/ui/ControlPanel.java b/src/com/android/camera/ui/ControlPanel.java
new file mode 100644
index 0000000..b280de7
--- /dev/null
+++ b/src/com/android/camera/ui/ControlPanel.java
@@ -0,0 +1,209 @@
+/*
+ * 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.
+ */
+
+package com.android.camera.ui;
+
+import com.android.camera.CameraSettings;
+import com.android.camera.ComboPreferences;
+import com.android.camera.IconListPreference;
+import com.android.camera.PreferenceGroup;
+import com.android.camera.R;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.graphics.drawable.Drawable;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.PopupWindow;
+import android.widget.RelativeLayout;
+
+public class ControlPanel extends RelativeLayout
+ implements BasicSettingPicker.Listener, IndicatorWheel.Listener,
+ View.OnClickListener, OtherSettingsPopup.Listener,
+ PopupWindow.OnDismissListener {
+ private static final String TAG = "ControlPanel";
+ private Context mContext;
+ private ComboPreferences mSharedPrefs;
+ private PreferenceGroup mPreferenceGroup;
+ private String[] mPreferenceKeys;
+ private Listener mListener;
+ private IndicatorWheel mIndicatorWheel;
+ private BasicSettingPicker[] mSettingPickers;
+ private OtherSettingsPopup mOtherSettingsPopup;
+ private int mActiveIndicator = -1;
+ private boolean mEnabled = true;
+
+ private ListView mThumbnailList;
+
+ static public interface Listener {
+ public void onSharedPreferenceChanged();
+ }
+
+ public void setListener(Listener listener) {
+ mListener = listener;
+ }
+
+ public ControlPanel(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mContext = context;
+ }
+
+ protected void addIndicator(
+ Context context, PreferenceGroup group, String key) {
+ IconListPreference pref = (IconListPreference) group.findPreference(key);
+ if (pref == null) return;
+ IndicatorButton b = new IndicatorButton(context, pref);
+ mIndicatorWheel.addView(b);
+ }
+
+ private void addOtherSettingIndicator(Context context) {
+ Button b = new Button(context);
+ b.setBackgroundResource(R.drawable.ic_viewfinder_settings);
+ b.setClickable(false);
+ mIndicatorWheel.addView(b);
+ }
+
+ public void initialize(Context context, PreferenceGroup group,
+ String[] keys, boolean enableOtherSettings) {
+ mPreferenceGroup = group;
+ mPreferenceKeys = keys;
+ // Add one more for other settings.
+ mSettingPickers = new BasicSettingPicker[mPreferenceKeys.length];
+ mIndicatorWheel = (IndicatorWheel) findViewById(R.id.indicator_wheel);
+ mThumbnailList = (ListView) findViewById(R.id.thumbnail_list);
+ mSharedPrefs = ComboPreferences.get(context);
+ for (int i = 0; i < mPreferenceKeys.length; i++) {
+ addIndicator(context, group, mPreferenceKeys[i]);
+ }
+ if (enableOtherSettings) {
+ addOtherSettingIndicator(context);
+ }
+ requestLayout();
+ mIndicatorWheel.setListener(this);
+ }
+
+ public void onOtherSettingChanged() {
+ if (mListener != null) {
+ mListener.onSharedPreferenceChanged();
+ }
+ }
+
+ public void onSettingChanged() {
+ mIndicatorWheel.updateIndicator(mActiveIndicator);
+ if (mListener != null) {
+ mListener.onSharedPreferenceChanged();
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (!mEnabled) return;
+ switch (v.getId()) {
+ case R.id.setting_exit:
+ hideSettingPicker();
+ break;
+ }
+ }
+ public void onIndicatorClicked(int index) {
+ if (!mEnabled) return;
+ if (index < mSettingPickers.length) {
+ if (mSettingPickers[index] == null) {
+ initializeSettingPicker(index);
+ }
+ } else if (mOtherSettingsPopup == null) {
+ initializeOtherSettingPicker();
+ }
+ if (!showSettingPicker(index)) {
+ hideSettingPicker();
+ }
+ }
+
+ private void initializeSettingPicker(int index) {
+ IconListPreference pref = (IconListPreference)
+ mPreferenceGroup.findPreference(mPreferenceKeys[index]);
+
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.basic_setting_picker, this);
+ mSettingPickers[index] = (BasicSettingPicker) getChildAt(
+ getChildCount() - 1);
+ mSettingPickers[index].setSettingChangedListener(this);
+ mSettingPickers[index].initialize(pref);
+ View v = mSettingPickers[index].findViewById(R.id.setting_exit);
+ v.setOnClickListener(this);
+ }
+
+ private void initializeOtherSettingPicker() {
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ View view = inflater.inflate(R.layout.other_setting_popup, null);
+ // Framework has a bug so WRAP_CONTENT does not work. Hardcode the
+ // dimension for now.
+ mOtherSettingsPopup = new OtherSettingsPopup(view, 420, 410, true);
+ Drawable border = getResources().getDrawable(R.drawable.menu_popup);
+ mOtherSettingsPopup.setBackgroundDrawable(border);
+ mOtherSettingsPopup.setOtherSettingChangedListener(this);
+ mOtherSettingsPopup.setOnDismissListener(this);
+ mOtherSettingsPopup.setFocusable(true);
+ mOtherSettingsPopup.initialize(mPreferenceGroup);
+ }
+
+ private boolean showSettingPicker(int index) {
+ for (int i = 0; i < mSettingPickers.length; i++) {
+ if (i != index && mSettingPickers[i] != null) {
+ mSettingPickers[i].setVisibility(View.INVISIBLE);
+ }
+ }
+ if (index == mSettingPickers.length) {
+ mOtherSettingsPopup.showAtLocation(this, Gravity.CENTER, 0, 0);
+ mThumbnailList.setVisibility(View.VISIBLE);
+ } else {
+ mSettingPickers[index].setVisibility(View.VISIBLE);
+ mThumbnailList.setVisibility(View.INVISIBLE);
+ }
+ mActiveIndicator = index;
+ return true;
+ }
+
+ public boolean hideSettingPicker() {
+ if (mActiveIndicator >= 0) {
+ if (mActiveIndicator == mSettingPickers.length) {
+ mOtherSettingsPopup.dismiss();
+ } else {
+ mSettingPickers[mActiveIndicator].setVisibility(View.INVISIBLE);
+ mThumbnailList.setVisibility(View.VISIBLE);
+ }
+ mActiveIndicator = -1;
+ return true;
+ }
+ return false;
+ }
+
+ public void setEnabled(boolean enabled) {
+ if (mEnabled == enabled) return;
+ mEnabled = enabled;
+ }
+
+ // Popup window is dismissed.
+ public void onDismiss() {
+ mActiveIndicator = -1;
+ }
+}
diff --git a/src/com/android/camera/ui/LinearLayout.java b/src/com/android/camera/ui/GLLinearLayout.java
index 0e812d8..cb0f064 100644
--- a/src/com/android/camera/ui/LinearLayout.java
+++ b/src/com/android/camera/ui/GLLinearLayout.java
@@ -19,7 +19,7 @@ package com.android.camera.ui;
import android.graphics.Rect;
import android.view.View.MeasureSpec;
-class LinearLayout extends GLView {
+class GLLinearLayout extends GLView {
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
diff --git a/src/com/android/camera/ui/GLListView.java b/src/com/android/camera/ui/GLListView.java
index c1bc11a..ed22ea3 100644
--- a/src/com/android/camera/ui/GLListView.java
+++ b/src/com/android/camera/ui/GLListView.java
@@ -17,10 +17,12 @@
package com.android.camera.ui;
import static android.view.View.MeasureSpec.makeMeasureSpec;
+import com.android.camera.Util;
import android.content.Context;
import android.graphics.Rect;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
import android.view.GestureDetector;
import android.view.MotionEvent;
@@ -30,15 +32,13 @@ import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.Scroller;
-import com.android.camera.Util;
-
import javax.microedition.khronos.opengles.GL11;
class GLListView extends GLView {
@SuppressWarnings("unused")
private static final String TAG = "GLListView";
private static final int INDEX_NONE = -1;
- private static final int SCROLL_BAR_TIMEOUT = 2500;
+ private static final int SCROLL_BAR_TIMEOUT = 1000;
private static final int HIDE_SCROLL_BAR = 1;
@@ -77,7 +77,7 @@ class GLListView extends GLView {
public GLListView(Context context) {
mScroller = new Scroller(context);
- mHandler = new Handler() {
+ mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
GLRootView root = getGLRootView();
@@ -102,13 +102,25 @@ class GLListView extends GLView {
context, new MyGestureListener(), mHandler);
}
+ private final Runnable mHideScrollBar = new Runnable() {
+ public void run() {
+ setScrollBarVisible(false);
+ }
+ };
+
@Override
protected void onVisibilityChanged(int visibility) {
super.onVisibilityChanged(visibility);
- if (visibility == GLView.VISIBLE && mScrollHeight > getHeight()) {
+ if (mScrollHeight > getHeight()) updateScrollBar(visibility);
+ }
+
+ private void updateScrollBar(int visibility) {
+ if (isVisible()) {
setScrollBarVisible(true);
mHandler.sendEmptyMessageDelayed(
HIDE_SCROLL_BAR, SCROLL_BAR_TIMEOUT);
+ } else {
+ mHandler.removeMessages(HIDE_SCROLL_BAR);
}
}
@@ -294,7 +306,10 @@ class GLListView extends GLView {
mIsPressed = true;
mHandler.removeMessages(HIDE_SCROLL_BAR);
setScrollBarVisible(mScrollHeight > getHeight());
-
+ if (!mScroller.isFinished()) {
+ mScroller.forceFinished(true);
+ break;
+ }
// fallthrough: we need to highlight the item which is pressed
case MotionEvent.ACTION_MOVE:
if (!mScrollable) {
diff --git a/src/com/android/camera/ui/PopupWindow.java b/src/com/android/camera/ui/GLPopupWindow.java
index c2bf533..79482ac 100644
--- a/src/com/android/camera/ui/PopupWindow.java
+++ b/src/com/android/camera/ui/GLPopupWindow.java
@@ -26,7 +26,7 @@ import android.view.animation.ScaleAnimation;
import javax.microedition.khronos.opengles.GL11;
-class PopupWindow extends GLView {
+class GLPopupWindow extends GLView {
protected BitmapTexture mAnchor;
protected int mAnchorOffset;
@@ -38,7 +38,7 @@ class PopupWindow extends GLView {
protected Texture mBackground;
private boolean mUsingStencil;
- public PopupWindow() {
+ public GLPopupWindow() {
super.addComponent(mRotatePane);
}
@@ -186,11 +186,6 @@ class PopupWindow extends GLView {
mRotatePane.setContent(content);
}
- @Override
- public void clearComponents() {
- throw new UnsupportedOperationException();
- }
-
public void popup() {
setVisibility(GLView.VISIBLE);
diff --git a/src/com/android/camera/ui/GLRootView.java b/src/com/android/camera/ui/GLRootView.java
index e7ac5e3..bdb0a8e 100644
--- a/src/com/android/camera/ui/GLRootView.java
+++ b/src/com/android/camera/ui/GLRootView.java
@@ -30,6 +30,7 @@ import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
+import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
@@ -37,7 +38,6 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Stack;
-
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
@@ -728,4 +728,12 @@ public class GLRootView extends GLSurfaceView
texture.setTextureSize(newWidth, newHeight);
}
+ @Override
+ protected void onVisibilityChanged(View changedView, int v) {
+ super.onVisibilityChanged(changedView, v);
+ if (mContentView != null) {
+ mContentView.onVisibilityChanged(
+ v == View.VISIBLE ? GLView.VISIBLE : GLView.INVISIBLE);
+ }
+ }
}
diff --git a/src/com/android/camera/ui/GLView.java b/src/com/android/camera/ui/GLView.java
index 184016e..811527a 100644
--- a/src/com/android/camera/ui/GLView.java
+++ b/src/com/android/camera/ui/GLView.java
@@ -20,11 +20,11 @@ import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.SystemClock;
import android.view.MotionEvent;
+import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import java.util.ArrayList;
-
import javax.microedition.khronos.opengles.GL11;
public class GLView {
@@ -81,8 +81,22 @@ public class GLView {
} else {
mViewFlags |= FLAG_INVISIBLE;
}
- onVisibilityChanged(visibility);
invalidate();
+
+ // Trigger the onVisibilityChanged() if it is visible on the screen.
+ if (isVisible()) onVisibilityChanged(visibility);
+ }
+
+ public boolean isVisible() {
+ if (mRootView == null || mRootView.getVisibility() != View.VISIBLE) {
+ return false;
+ }
+ GLView parent = mParent;
+ while (parent != null) {
+ if (parent.getVisibility() == GLView.INVISIBLE) return false;
+ parent = parent.mParent;
+ }
+ return true;
}
public int getVisibility() {
@@ -141,6 +155,7 @@ public class GLView {
}
mComponents.add(component);
component.onAddToParent(this);
+ if (isVisible()) component.onVisibilityChanged(VISIBLE);
}
public boolean removeComponent(GLView component) {
@@ -362,10 +377,7 @@ public class GLView {
protected void onVisibilityChanged(int visibility) {
for (int i = 0, n = getComponentCount(); i < n; ++i) {
- GLView child = getComponent(i);
- if (child.getVisibility() == GLView.VISIBLE) {
- child.onVisibilityChanged(visibility);
- }
+ getComponent(i).onVisibilityChanged(visibility);
}
}
diff --git a/src/com/android/camera/ui/GpsIndicator.java b/src/com/android/camera/ui/GpsIndicator.java
index 78a80b8..c1cb2ef 100644
--- a/src/com/android/camera/ui/GpsIndicator.java
+++ b/src/com/android/camera/ui/GpsIndicator.java
@@ -33,7 +33,7 @@ class GpsIndicator extends BasicIndicator {
}
@Override
- protected ResourceTexture getIcon() {
+ protected BitmapTexture getIcon() {
if (mIndex == GPS_ON_INDEX && !mHasSignal) {
if (mNoSignalIcon == null) {
Context context = getGLRootView().getContext();
diff --git a/src/com/android/camera/ui/HeadUpDisplay.java b/src/com/android/camera/ui/HeadUpDisplay.java
index 1b0415f..2f9ac86 100644
--- a/src/com/android/camera/ui/HeadUpDisplay.java
+++ b/src/com/android/camera/ui/HeadUpDisplay.java
@@ -17,8 +17,11 @@
package com.android.camera.ui;
import static com.android.camera.ui.GLRootView.dpToPixel;
-
-import java.util.ArrayList;
+import com.android.camera.CameraSettings;
+import com.android.camera.ComboPreferences;
+import com.android.camera.ListPreference;
+import com.android.camera.PreferenceGroup;
+import com.android.camera.R;
import android.content.Context;
import android.content.SharedPreferences;
@@ -34,12 +37,7 @@ import android.view.View.MeasureSpec;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
-import com.android.camera.CameraSettings;
-import com.android.camera.ComboPreferences;
-import com.android.camera.IconListPreference;
-import com.android.camera.ListPreference;
-import com.android.camera.PreferenceGroup;
-import com.android.camera.R;
+import java.util.ArrayList;
// This is the UI for the on-screen settings. Since the rendering is run in the
// GL thread. If any values will be changed in the main thread, it needs to
@@ -70,7 +68,7 @@ public class HeadUpDisplay extends GLView {
private ComboPreferences mSharedPrefs;
private PreferenceGroup mPreferenceGroup;
- private PopupWindow mPopupWindow;
+ private GLPopupWindow mPopupWindow;
private GLView mAnchorView;
private int mOrientation = 0;
@@ -110,7 +108,7 @@ public class HeadUpDisplay extends GLView {
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
if (mListener != null) {
- mListener.onSharedPreferencesChanged();
+ mListener.onSharedPreferenceChanged();
}
}
};
@@ -134,7 +132,7 @@ public class HeadUpDisplay extends GLView {
static public interface Listener {
public void onPopupWindowVisibilityChanged(int visibility);
public void onRestorePreferencesClicked();
- public void onSharedPreferencesChanged();
+ public void onSharedPreferenceChanged();
}
public void overrideSettings(final String ... keyvalues) {
@@ -272,7 +270,7 @@ public class HeadUpDisplay extends GLView {
}
private void initializePopupWindow(Context context) {
- mPopupWindow = new PopupWindow();
+ mPopupWindow = new GLPopupWindow();
mPopupWindow.setBackground(
new NinePatchTexture(context, R.drawable.menu_popup));
mPopupWindow.setAnchor(new ResourceTexture(
@@ -329,8 +327,7 @@ public class HeadUpDisplay extends GLView {
protected BasicIndicator addIndicator(
Context context, PreferenceGroup group, String key) {
- IconListPreference iconPref =
- (IconListPreference) group.findPreference(key);
+ ListPreference iconPref = group.findPreference(key);
if (iconPref == null) return null;
BasicIndicator indicator = new BasicIndicator(context, iconPref);
mIndicatorBar.addComponent(indicator);
@@ -403,7 +400,7 @@ public class HeadUpDisplay extends GLView {
mSharedPreferenceChangeListener;
// Unregister the listener since "upgrade preference" will
// change bunch of preferences. We can handle them with one
- // onSharedPreferencesChanged();
+ // onSharedPreferenceChanged();
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(l);
Context context = getGLRootView().getContext();
Editor editor = mSharedPrefs.edit();
@@ -413,7 +410,7 @@ public class HeadUpDisplay extends GLView {
CameraSettings.initialCameraPictureSize(context, param);
reloadPreferences();
if (mListener != null) {
- mListener.onSharedPreferencesChanged();
+ mListener.onSharedPreferenceChanged();
}
mSharedPrefs.registerOnSharedPreferenceChangeListener(l);
}
diff --git a/src/com/android/camera/ui/InLineSettingPicker.java b/src/com/android/camera/ui/InLineSettingPicker.java
new file mode 100644
index 0000000..30470fc
--- /dev/null
+++ b/src/com/android/camera/ui/InLineSettingPicker.java
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ */
+
+package com.android.camera.ui;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnTouchListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.camera.R;
+import com.android.camera.ListPreference;
+
+import java.util.Formatter;
+
+public class InLineSettingPicker extends LinearLayout {
+ private final String TAG = "InLineSettingPicker";
+ private TextView mText;
+ private ListPreference mPreference;
+ private boolean mNext, mPrevious;
+ private int mIndex;
+ private String mKey;
+ private Listener mListener;
+
+ static public interface Listener {
+ public void onSettingChanged();
+ }
+
+ private Handler mHandler;
+ private final Runnable mRunnable = new Runnable() {
+ public void run() {
+ if (mNext) {
+ if (changeIndex(mIndex - 1)) {
+ mHandler.postDelayed(this, 100);
+ }
+ } else if (mPrevious) {
+ if (changeIndex(mIndex + 1)) {
+ mHandler.postDelayed(this, 100);
+ }
+ }
+ }
+ };
+
+ public InLineSettingPicker(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ LayoutInflater inflater =
+ (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.in_line_setting_picker, this, true);
+
+ mHandler = new Handler();
+
+ OnTouchListener nextTouchListener = new OnTouchListener() {
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (!mNext && changeIndex(mIndex - 1)) {
+ mNext = true;
+ // Give bigger delay so users can change only one step.
+ mHandler.postDelayed(mRunnable, 300);
+ }
+ } else if (event.getAction() == MotionEvent.ACTION_UP) {
+ mNext = false;
+ }
+ return false;
+ }
+ };
+
+ OnTouchListener previousTouchListener = new OnTouchListener() {
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (!mPrevious && changeIndex(mIndex + 1)) {
+ mPrevious = true;
+ // Give bigger delay so users can change only one step.
+ mHandler.postDelayed(mRunnable, 300);
+ }
+ } else if (event.getAction() == MotionEvent.ACTION_UP) {
+ mPrevious = false;
+ }
+ return false;
+ }
+ };
+
+ Button nextButton = (Button) findViewById(R.id.increment);
+ nextButton.setOnTouchListener(nextTouchListener);
+ Button previousButton = (Button) findViewById(R.id.decrement);
+ previousButton.setOnTouchListener(previousTouchListener);
+ mText = (TextView) findViewById(R.id.current_setting);
+
+ TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.InLineSettingPicker, 0, 0);
+ mKey = a.getString(R.styleable.InLineSettingPicker_prefKey);
+ }
+
+ public String getKey() {
+ return mKey;
+ }
+
+ public void initialize(ListPreference preference) {
+ mPreference = preference;
+ mIndex = mPreference.findIndexOfValue(mPreference.getValue());
+ updateView();
+ }
+
+ private boolean changeIndex(int index) {
+ if (index >= mPreference.getEntryValues().length || index < 0) return false;
+ mIndex = index;
+ mPreference.setValueIndex(mIndex);
+ if (mListener != null) {
+ mListener.onSettingChanged();
+ }
+ updateView();
+ return true;
+ }
+
+ private void updateView() {
+ mText.setText(mPreference.getEntry());
+ }
+
+ public void setSettingChangedListener(Listener listener) {
+ mListener = listener;
+ }
+}
diff --git a/src/com/android/camera/ui/IndicatorButton.java b/src/com/android/camera/ui/IndicatorButton.java
new file mode 100644
index 0000000..c4145de
--- /dev/null
+++ b/src/com/android/camera/ui/IndicatorButton.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+package com.android.camera.ui;
+
+import com.android.camera.IconListPreference;
+
+import android.content.Context;
+import android.widget.Button;
+
+public class IndicatorButton extends Button {
+ private IconListPreference mPreference;
+
+ public IndicatorButton(Context context, IconListPreference pref) {
+ super(context);
+ mPreference = pref;
+ setClickable(false);
+ reloadPreference();
+ }
+
+ public void reloadPreference() {
+ int index = mPreference.findIndexOfValue(mPreference.getValue());
+ setBackgroundResource(mPreference.getLargeIconIds()[index]);
+ }
+}
diff --git a/src/com/android/camera/ui/IndicatorWheel.java b/src/com/android/camera/ui/IndicatorWheel.java
new file mode 100644
index 0000000..aab41fc
--- /dev/null
+++ b/src/com/android/camera/ui/IndicatorWheel.java
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+
+package com.android.camera.ui;
+
+import com.android.camera.ComboPreferences;
+import com.android.camera.PreferenceGroup;
+import com.android.camera.R;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.widget.Button;
+import android.view.MotionEvent;
+import android.view.ViewGroup;
+import android.view.View;
+
+import java.lang.Math;
+
+/**
+ * A view that contains camera settings and shutter buttons. The settings are
+ * spreaded around the shutter button.
+ */
+public class IndicatorWheel extends ViewGroup {
+ private static final String TAG = "IndicatorWheel";
+ private Listener mListener;
+ private int mCenterX, mCenterY;
+ private double mShutterButtonRadius;
+ private double mSectorInitialRadians[];
+
+ static public interface Listener {
+ public void onIndicatorClicked(int index);
+ }
+
+ public void setListener(Listener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ int count = getChildCount();
+ if (mListener == null || count <= 1) return false;
+
+ // Check if any setting is pressed.
+ int action = event.getAction();
+ if (action == MotionEvent.ACTION_DOWN
+ || action == MotionEvent.ACTION_MOVE) {
+ double dx = event.getX() - mCenterX;
+ double dy = mCenterY - event.getY();
+ double radius = Math.sqrt(dx * dx + dy * dy);
+ // Ignore the event if it's too near to the shutter button.
+ if (radius < mShutterButtonRadius) return false;
+
+ double intervalDegrees = 180.0 / (count - 2);
+ double delta = Math.atan2(dy, dx);
+ if (delta < 0) delta += Math.PI * 2;
+ // Check which sector is pressed.
+ if (delta > mSectorInitialRadians[0]) {
+ for (int i = 1; i < count; i++) {
+ if (delta < mSectorInitialRadians[i]) {
+ mListener.onIndicatorClicked(i - 1);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public IndicatorWheel(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onMeasure(int widthSpec, int heightSpec) {
+ // Measure all children.
+ int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ for (int i = 0; i < getChildCount(); i++) {
+ getChildAt(i).measure(freeSpec, freeSpec);
+ }
+
+ // Measure myself.
+ View shutterButton = getChildAt(0);
+ int desiredWidth = (int)(shutterButton.getMeasuredWidth() * 2.5);
+ int desiredHeight = (int)(shutterButton.getMeasuredHeight() * 2.5);
+ int widthMode = MeasureSpec.getMode(widthSpec);
+ int heightMode = MeasureSpec.getMode(heightSpec);
+ int measuredWidth, measuredHeight;
+ if (widthMode == MeasureSpec.UNSPECIFIED) {
+ measuredWidth = desiredWidth;
+ } else if (widthMode == MeasureSpec.AT_MOST) {
+ measuredWidth = Math.min(desiredWidth, MeasureSpec.getSize(widthSpec));
+ } else { // MeasureSpec.EXACTLY
+ measuredWidth = MeasureSpec.getSize(widthSpec);
+ }
+ if (heightMode == MeasureSpec.UNSPECIFIED) {
+ measuredHeight = desiredHeight;
+ } else if (heightMode == MeasureSpec.AT_MOST) {
+ measuredHeight = Math.min(desiredHeight, MeasureSpec.getSize(heightSpec));
+ } else { // MeasureSpec.EXACTLY
+ measuredHeight = MeasureSpec.getSize(heightSpec);
+ }
+ setMeasuredDimension(measuredWidth, measuredHeight);
+ }
+
+ @Override
+ protected void onLayout(
+ boolean changed, int left, int top, int right, int bottom) {
+ int count = getChildCount();
+ if (count == 0) return;
+
+ // Layout the shutter button.
+ View shutterButton = findViewById(R.id.shutter_button);
+ int width = shutterButton.getMeasuredWidth();
+ mShutterButtonRadius = width / 2.0 + 10;
+ int height = shutterButton.getMeasuredHeight();
+ mCenterX = (right - left) - width / 2;
+ mCenterY = (bottom - top) / 2;
+ shutterButton.layout(mCenterX - width / 2, mCenterY - height / 2,
+ mCenterX + width / 2, mCenterY + height / 2);
+
+ // Layout the settings. The icons are spreaded on the left side of the
+ // shutter button. So the angle starts from 90 to 270 degrees.
+ if (count == 1) return;
+ double radius = shutterButton.getMeasuredWidth();
+ double intervalDegrees = 180.0 / (count - 2);
+ double initialDegrees = 90.0;
+ int index = 0;
+ for (int i = 0; i < count; i++) {
+ View view = getChildAt(i);
+ if (view == shutterButton) continue;
+ double degree = initialDegrees + intervalDegrees * index;
+ double radian = Math.toRadians(degree);
+ int x = mCenterX + (int)(radius * Math.cos(radian));
+ int y = mCenterY - (int)(radius * Math.sin(radian));
+ width = view.getMeasuredWidth();
+ height = view.getMeasuredHeight();
+ view.layout(x - width / 2, y - height / 2, x + width / 2,
+ y + height / 2);
+ index++;
+ }
+
+ // Store the radian intervals for each icon.
+ mSectorInitialRadians = new double[count];
+ mSectorInitialRadians[0] = Math.toRadians(
+ initialDegrees - intervalDegrees / 2.0);
+ for (int i = 1; i < count; i++) {
+ mSectorInitialRadians[i] = mSectorInitialRadians[i - 1]
+ + Math.toRadians(intervalDegrees);
+ }
+ }
+
+ public void updateIndicator(int index) {
+ IndicatorButton indicator = (IndicatorButton) getChildAt(index + 1);
+ indicator.reloadPreference();
+ }
+}
diff --git a/src/com/android/camera/ui/OtherSettingsPopup.java b/src/com/android/camera/ui/OtherSettingsPopup.java
new file mode 100644
index 0000000..f5a83ef
--- /dev/null
+++ b/src/com/android/camera/ui/OtherSettingsPopup.java
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+package com.android.camera.ui;
+
+import com.android.camera.ListPreference;
+import com.android.camera.PreferenceGroup;
+
+import android.util.Log;
+import android.view.View;
+import android.widget.PopupWindow;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+
+/* A popup window that contains several camera settings. */
+public class OtherSettingsPopup extends PopupWindow
+ implements InLineSettingPicker.Listener {
+ private static final String TAG = "OtherSettingsPopup";
+ private Listener mListener;
+
+ static public interface Listener {
+ public void onOtherSettingChanged();
+ }
+
+ public void setOtherSettingChangedListener(Listener listener) {
+ mListener = listener;
+ }
+
+ public OtherSettingsPopup(View contentView, int width, int height,
+ boolean focusable) {
+ super(contentView, width, height, focusable);
+ }
+
+ public void initialize(PreferenceGroup group) {
+ TableLayout table = (TableLayout) getContentView();
+ // Initialize each camera setting.
+ for (int i = 0; i < table.getChildCount(); i++) {
+ TableRow row = (TableRow) table.getChildAt(i);
+ InLineSettingPicker picker = (InLineSettingPicker) row.getChildAt(1);
+ ListPreference pref = group.findPreference(picker.getKey());
+ picker.setSettingChangedListener(this);
+ picker.initialize(pref);
+ }
+ }
+
+ public void onSettingChanged() {
+ if (mListener != null) {
+ mListener.onOtherSettingChanged();
+ }
+ }
+}
diff --git a/src/com/android/camera/ui/RotatePane.java b/src/com/android/camera/ui/RotatePane.java
index 9f9effa..45f6a0d 100644
--- a/src/com/android/camera/ui/RotatePane.java
+++ b/src/com/android/camera/ui/RotatePane.java
@@ -117,8 +117,7 @@ class RotatePane extends GLView {
public void setContent(GLView view) {
if (mChild == view) return;
-
- if (mChild != null) super.clearComponents();
+ if (mChild != null) super.removeComponent(mChild);
mChild = view;
if (view != null) super.addComponent(view);
requestLayout();
@@ -128,9 +127,4 @@ class RotatePane extends GLView {
public void addComponent(GLView view) {
throw new UnsupportedOperationException("use setContent(GLView)");
}
-
- @Override
- public void clearComponents() {
- throw new UnsupportedOperationException("use setContent(null)");
- }
}
diff --git a/src/com/android/camera/ui/ZoomIndicator.java b/src/com/android/camera/ui/ZoomIndicator.java
index e74cefd..e2decf1 100644
--- a/src/com/android/camera/ui/ZoomIndicator.java
+++ b/src/com/android/camera/ui/ZoomIndicator.java
@@ -35,7 +35,7 @@ class ZoomIndicator extends AbstractIndicator {
private final float mFontSize;
private ZoomController mZoomController;
- private LinearLayout mPopupContent;
+ private GLLinearLayout mPopupContent;
private ZoomControllerListener mZoomListener;
private int mZoomIndex = 0;
private int mDrawIndex = -1;
@@ -85,7 +85,7 @@ class ZoomIndicator extends AbstractIndicator {
mZoomController.setAvailableZoomRatios(mZoomRatios);
mZoomController.setPaddings(15, 6, 15, 6);
- mPopupContent = new LinearLayout();
+ mPopupContent = new GLLinearLayout();
GLOptionHeader header = new GLOptionHeader(context,
context.getString(R.string.zoom_control_title));
header.setBackground(new ColorTexture(COLOR_OPTION_HEADER));
diff --git a/src/com/android/camera/ui/ZoomPicker.java b/src/com/android/camera/ui/ZoomPicker.java
new file mode 100644
index 0000000..63c9f10
--- /dev/null
+++ b/src/com/android/camera/ui/ZoomPicker.java
@@ -0,0 +1,155 @@
+/*
+ * 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.
+ */
+
+package com.android.camera.ui;
+
+import android.content.Context;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+import android.view.View.OnTouchListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.camera.R;
+
+import java.util.Formatter;
+
+/**
+ * A view for increasing or decresing zoom
+ */
+public class ZoomPicker extends LinearLayout {
+ private final String TAG = "ZoomPicker";
+ private TextView mText;
+ private int mZoomMax, mZoomIndex;
+ private float[] mZoomRatios;
+ private OnZoomChangedListener mListener;
+ private boolean mIncrement, mDecrement;
+ private final StringBuilder mBuilder = new StringBuilder();
+ private final Formatter mFormatter = new Formatter(mBuilder);
+ private final Object[] mFormatterArgs = new Object[1];
+
+ private Handler mHandler;
+ private final Runnable mRunnable = new Runnable() {
+ public void run() {
+ if (mIncrement) {
+ if (changeZoomIndex(mZoomIndex + 1)) {
+ mHandler.postDelayed(this, 65);
+ }
+ } else if (mDecrement) {
+ if (changeZoomIndex(mZoomIndex - 1)) {
+ mHandler.postDelayed(this, 65);
+ }
+ }
+ }
+ };
+
+ public ZoomPicker(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mHandler = new Handler();
+
+ OnTouchListener incrementTouchListener = new OnTouchListener() {
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (!mIncrement && changeZoomIndex(mZoomIndex + 1)) {
+ mIncrement = true;
+ // Give bigger delay so users can tap to change only one
+ // zoom step.
+ mHandler.postDelayed(mRunnable, 200);
+ }
+ } else if (event.getAction() == MotionEvent.ACTION_UP) {
+ mIncrement = false;
+ }
+ return false;
+ }
+ };
+
+ OnTouchListener decrementTouchListener = new OnTouchListener() {
+ public boolean onTouch(View v, MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (!mDecrement && changeZoomIndex(mZoomIndex - 1)) {
+ mDecrement = true;
+ // Give bigger delay so users can tap to change only one
+ // zoom step.
+ mHandler.postDelayed(mRunnable, 200);
+ }
+ } else if (event.getAction() == MotionEvent.ACTION_UP) {
+ mDecrement = false;
+ }
+ return false;
+ }
+ };
+
+ Button incrementButton = (Button) findViewById(R.id.increment);
+ incrementButton.setOnTouchListener(incrementTouchListener);
+ Button decrementButton = (Button) findViewById(R.id.decrement);
+ decrementButton.setOnTouchListener(decrementTouchListener);
+ mText = (TextView) findViewById(R.id.zoom_ratio);
+ mText.setText(formatZoomRatio(1.0f));
+ }
+
+ public void setOnZoomChangeListener(OnZoomChangedListener listener) {
+ mListener = listener;
+ }
+
+ public interface OnZoomChangedListener {
+ void onZoomChanged(int index);
+ }
+
+ public void setZoomRatios(float[] zoomRatios) {
+ mZoomMax = zoomRatios.length - 1;
+ mZoomRatios = zoomRatios;
+ updateView();
+ }
+
+ public void setZoomIndex(int index) {
+ if (index < 0 || index > mZoomMax) {
+ throw new IllegalArgumentException("Invalid zoom value:" + index);
+ }
+ mZoomIndex = index;
+ updateView();
+ }
+
+ private boolean changeZoomIndex(int index) {
+ if (index > mZoomMax || index < 0) return false;
+ mZoomIndex = index;
+ if (mListener != null) {
+ mListener.onZoomChanged(mZoomIndex);
+ }
+ updateView();
+ return true;
+ }
+
+ private void updateView() {
+ mText.setText(formatZoomRatio(mZoomRatios[mZoomIndex]));
+ }
+
+ private String formatZoomRatio(float value) {
+ mFormatterArgs[0] = value;
+ mBuilder.delete(0, mBuilder.length());
+ mFormatter.format("%2.1fx", mFormatterArgs);
+ return mFormatter.toString();
+ }
+}
diff --git a/tests/src/com/android/camera/stress/CameraLatency.java b/tests/src/com/android/camera/stress/CameraLatency.java
index 76805c4..c4cb9ec 100755
--- a/tests/src/com/android/camera/stress/CameraLatency.java
+++ b/tests/src/com/android/camera/stress/CameraLatency.java
@@ -70,10 +70,11 @@ public class CameraLatency extends ActivityInstrumentationTestCase2 <Camera> {
public void testImageCapture() {
Log.v(TAG, "start testImageCapture test");
Instrumentation inst = getInstrumentation();
+ inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
+ inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
try {
for (int i = 0; i < TOTAL_NUMBER_OF_IMAGECAPTURE; i++) {
Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
//skip the first measurement
diff --git a/tests/src/com/android/camera/stress/ImageCapture.java b/tests/src/com/android/camera/stress/ImageCapture.java
index cd2bd29..4960389 100755
--- a/tests/src/com/android/camera/stress/ImageCapture.java
+++ b/tests/src/com/android/camera/stress/ImageCapture.java
@@ -203,10 +203,11 @@ public class ImageCapture extends ActivityInstrumentationTestCase2 <Camera> {
mOut.write("Camera Image Capture\n");
mOut.write("No of loops :" + total_num_of_images + "\n");
mOut.write("loop: ");
-
+ //Move the foucs to the image capture button
+ inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
+ inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_DOWN);
for (int i = 0; i < total_num_of_images; i++) {
Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
- inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_UP);
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
Thread.sleep(WAIT_FOR_IMAGE_CAPTURE_TO_BE_TAKEN);
if (( i % NO_OF_LOOPS_TAKE_MEMORY_SNAPSHOT) == 0){