diff options
73 files changed, 4834 insertions, 1062 deletions
diff --git a/res/drawable-hdpi/ic_scene_mode_auto.png b/res/drawable-hdpi/ic_scene_mode_auto.png Binary files differindex 6b18e9061..c9142c947 100644 --- a/res/drawable-hdpi/ic_scene_mode_auto.png +++ b/res/drawable-hdpi/ic_scene_mode_auto.png diff --git a/res/drawable-hdpi/ic_settings_filter.png b/res/drawable-hdpi/ic_settings_filter.png Binary files differindex 35841c2aa..23abfa623 100644 --- a/res/drawable-hdpi/ic_settings_filter.png +++ b/res/drawable-hdpi/ic_settings_filter.png diff --git a/res/drawable-mdpi/ic_scene_mode_auto.png b/res/drawable-mdpi/ic_scene_mode_auto.png Binary files differindex 8dd66bab3..ea3740cbf 100644 --- a/res/drawable-mdpi/ic_scene_mode_auto.png +++ b/res/drawable-mdpi/ic_scene_mode_auto.png diff --git a/res/drawable-mdpi/ic_settings_filter.png b/res/drawable-mdpi/ic_settings_filter.png Binary files differindex 08b4dab43..6b5c2a225 100644 --- a/res/drawable-mdpi/ic_settings_filter.png +++ b/res/drawable-mdpi/ic_settings_filter.png diff --git a/res/drawable-xhdpi/ic_scene_mode_auto.png b/res/drawable-xhdpi/ic_scene_mode_auto.png Binary files differindex 19a4a2ae0..511f29bf5 100644 --- a/res/drawable-xhdpi/ic_scene_mode_auto.png +++ b/res/drawable-xhdpi/ic_scene_mode_auto.png diff --git a/res/drawable-xhdpi/ic_settings_filter.png b/res/drawable-xhdpi/ic_settings_filter.png Binary files differindex 9d47006dc..cc8736189 100644 --- a/res/drawable-xhdpi/ic_settings_filter.png +++ b/res/drawable-xhdpi/ic_settings_filter.png diff --git a/res/drawable/bg_pressed_exit_fading.xml b/res/drawable/bg_pressed_exit_fading.xml index d317e8b5a..4661467bd 100644 --- a/res/drawable/bg_pressed_exit_fading.xml +++ b/res/drawable/bg_pressed_exit_fading.xml @@ -16,6 +16,7 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime"> + <item android:state_enabled="false" android:drawable="@android:color/transparent" /> <item android:state_pressed="true" android:drawable="@drawable/list_pressed_holo_light" /> <item android:drawable="@android:color/transparent" /> </selector> diff --git a/res/drawable/btn_new_shutter.xml b/res/drawable/btn_new_shutter.xml index 7a3eb81a9..5b9d6f724 100644 --- a/res/drawable/btn_new_shutter.xml +++ b/res/drawable/btn_new_shutter.xml @@ -15,7 +15,7 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_pressed="true" android:drawable="@drawable/btn_shutter_pressed" /> - <item android:drawable="@drawable/btn_shutter_default" /> + <item android:state_pressed="true" android:drawable="@drawable/shutter_button_dim" /> + <item android:drawable="@drawable/shutter_button_0" /> </selector> diff --git a/res/drawable/btn_new_shutter_video.xml b/res/drawable/btn_new_shutter_video.xml index e87b456f6..518b362d8 100644 --- a/res/drawable/btn_new_shutter_video.xml +++ b/res/drawable/btn_new_shutter_video.xml @@ -15,7 +15,7 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_pressed="true" android:drawable="@drawable/btn_shutter_video_pressed" /> - <item android:drawable="@drawable/btn_shutter_video_default" /> + <item android:state_pressed="true" android:drawable="@drawable/shutter_button_video_dim" /> + <item android:drawable="@drawable/shutter_button_video" /> </selector> diff --git a/res/drawable/list_border.xml b/res/drawable/list_border.xml new file mode 100644 index 000000000..1ab11ddfe --- /dev/null +++ b/res/drawable/list_border.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle" > + + <solid android:color="@color/setting_color" /> + + <stroke + android:width="1dip" + android:color="@color/list_divider_color" /> + +</shape> diff --git a/res/drawable/list_selector.xml b/res/drawable/list_selector.xml new file mode 100644 index 000000000..ada9b365a --- /dev/null +++ b/res/drawable/list_selector.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <item android:drawable="@color/setting_color_light" android:state_pressed="true"/> + <item android:drawable="@android:color/transparent"/> + +</selector> diff --git a/res/drawable/scene_mode_view_border.xml b/res/drawable/scene_mode_view_border.xml new file mode 100644 index 000000000..68431ece6 --- /dev/null +++ b/res/drawable/scene_mode_view_border.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle" > + + <stroke + android:width="1dip" + android:color="#cc000000" /> + +</shape> diff --git a/res/drawable/scene_mode_view_border_selected.xml b/res/drawable/scene_mode_view_border_selected.xml new file mode 100644 index 000000000..535e2d168 --- /dev/null +++ b/res/drawable/scene_mode_view_border_selected.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle" > + + <stroke + android:width="1dip" + android:color="#cc33b5e5" /> + +</shape> diff --git a/res/drawable/shutter_button_anim.xml b/res/drawable/shutter_button_anim.xml new file mode 100644 index 000000000..914977244 --- /dev/null +++ b/res/drawable/shutter_button_anim.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<animation-list xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/shutter_button_pressed" + android:oneshot="true" > + + <item + android:drawable="@drawable/shutter_button_0" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_1" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_2" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_3" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_4" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_5" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_6" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_5" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_4" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_3" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_2" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_1" + android:duration="33"/> + <item + android:drawable="@drawable/shutter_button_0" + android:duration="33"/> + +</animation-list> diff --git a/res/drawable/thumb_filter_aqua.png b/res/drawable/thumb_filter_aqua.png Binary files differnew file mode 100644 index 000000000..91fe52046 --- /dev/null +++ b/res/drawable/thumb_filter_aqua.png diff --git a/res/drawable/thumb_filter_emboss.png b/res/drawable/thumb_filter_emboss.png Binary files differnew file mode 100644 index 000000000..ebfc75325 --- /dev/null +++ b/res/drawable/thumb_filter_emboss.png diff --git a/res/drawable/thumb_filter_monochrome.png b/res/drawable/thumb_filter_monochrome.png Binary files differnew file mode 100644 index 000000000..9bfb2d540 --- /dev/null +++ b/res/drawable/thumb_filter_monochrome.png diff --git a/res/drawable/thumb_filter_negative.png b/res/drawable/thumb_filter_negative.png Binary files differnew file mode 100644 index 000000000..8520afe52 --- /dev/null +++ b/res/drawable/thumb_filter_negative.png diff --git a/res/drawable/thumb_filter_neon.png b/res/drawable/thumb_filter_neon.png Binary files differnew file mode 100644 index 000000000..27bb71b21 --- /dev/null +++ b/res/drawable/thumb_filter_neon.png diff --git a/res/drawable/thumb_filter_nofilter.png b/res/drawable/thumb_filter_nofilter.png Binary files differnew file mode 100644 index 000000000..fc790cd5f --- /dev/null +++ b/res/drawable/thumb_filter_nofilter.png diff --git a/res/drawable/thumb_filter_posterize.png b/res/drawable/thumb_filter_posterize.png Binary files differnew file mode 100644 index 000000000..fa8c34c80 --- /dev/null +++ b/res/drawable/thumb_filter_posterize.png diff --git a/res/drawable/thumb_filter_sepia.png b/res/drawable/thumb_filter_sepia.png Binary files differnew file mode 100644 index 000000000..5a77f8cbe --- /dev/null +++ b/res/drawable/thumb_filter_sepia.png diff --git a/res/drawable/thumb_filter_sketch.png b/res/drawable/thumb_filter_sketch.png Binary files differnew file mode 100644 index 000000000..cfd0f55a3 --- /dev/null +++ b/res/drawable/thumb_filter_sketch.png diff --git a/res/drawable/thumb_filter_solarize.png b/res/drawable/thumb_filter_solarize.png Binary files differnew file mode 100644 index 000000000..96ab7ac13 --- /dev/null +++ b/res/drawable/thumb_filter_solarize.png diff --git a/res/layout-land/camera_controls.xml b/res/layout-land/camera_controls.xml index cf27af192..65a17caae 100644 --- a/res/layout-land/camera_controls.xml +++ b/res/layout-land/camera_controls.xml @@ -13,59 +13,100 @@ See the License for the specific language governing permissions and limitations under the License. --> -<com.android.camera.ui.CameraControls - xmlns:android="http://schemas.android.com/apk/res/android" +<com.android.camera.ui.CameraControls xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/camera_controls" android:layout_width="match_parent" android:layout_height="match_parent" > - <View - android:id="@+id/blocker" - android:clickable="true" - android:layout_height="match_parent" - android:layout_width="@dimen/switcher_size" - android:layout_gravity="right" /> - - <include layout="@layout/menu_indicators" - android:layout_width="64dip" - android:layout_height="64dip" - android:layout_marginTop="-5dip" - android:layout_marginRight="6dip" - android:layout_gravity="top|right"/> - - <com.android.camera.ui.PieMenuButton - android:id="@+id/menu" - style="@style/SwitcherButton" - android:contentDescription="@string/accessibility_menu_button" - android:layout_gravity="right|top" - android:layout_marginRight="2dip" /> - - <com.android.camera.ui.ModuleSwitcher - android:id="@+id/camera_switcher" - style="@style/SwitcherButton" - android:layout_gravity="right|bottom" - android:layout_marginRight="2dip" - android:contentDescription="@string/accessibility_mode_picker" /> - - <com.android.camera.ShutterButton - android:id="@+id/shutter_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="right|center_vertical" - android:layout_marginRight="@dimen/shutter_offset" - android:clickable="true" - android:contentDescription="@string/accessibility_shutter_button" - android:focusable="true" - android:scaleType="center" - android:src="@drawable/btn_new_shutter" /> + <View + android:id="@+id/blocker" + android:layout_width="@dimen/switcher_size" + android:layout_height="match_parent" + android:layout_gravity="right" + android:clickable="true" /> + + <include + android:layout_width="64dip" + android:layout_height="64dip" + android:layout_gravity="top|right" + android:layout_marginRight="8dip" + android:layout_marginTop="-8dip" + layout="@layout/menu_indicators" /> + + <com.android.camera.ui.RotatableLayout + android:id="@+id/menu" + style="@style/ToggleButtonOuter" + android:layout_marginRight="2dip" > <ImageView - android:id="@+id/preview_thumb" - android:visibility="invisible" - android:layout_width="@dimen/capture_size" - android:layout_height="@dimen/capture_size" - android:scaleType="centerInside" - android:layout_gravity="top|right" - android:contentDescription="@string/switch_photo_filmstrip" /> + style="@style/MenuButton" + android:layout_gravity="center" + android:contentDescription="@string/accessibility_menu_button" + android:src="@drawable/ic_settings" /> + </com.android.camera.ui.RotatableLayout> + + <com.android.camera.ui.ModuleSwitcher + android:id="@+id/camera_switcher" + style="@style/SwitcherButton" + android:layout_gravity="right|bottom" + android:layout_marginRight="2dip" + android:contentDescription="@string/accessibility_mode_picker" /> + + <com.android.camera.ShutterButton + android:id="@+id/shutter_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="right|center_vertical" + android:layout_marginRight="@dimen/shutter_offset" + android:clickable="true" + android:contentDescription="@string/accessibility_shutter_button" + android:focusable="true" + android:scaleType="center" + android:src="@drawable/btn_new_shutter" /> + + <com.android.camera.ui.RotateImageView + android:id="@+id/preview_thumb" + android:layout_width="@dimen/capture_size" + android:layout_height="@dimen/capture_size" + android:layout_gravity="top|right" + android:background="@android:color/black" + android:contentDescription="@string/switch_photo_filmstrip" + android:scaleType="fitCenter" /> + + <com.android.camera.ui.RotatableLayout + android:id="@+id/front_back_switcher" + style="@style/ToggleButtonOuter" > + + <com.android.camera.ui.RotateImageView + style="@style/ToggleButton" + android:layout_gravity="center" /> + </com.android.camera.ui.RotatableLayout> + + <com.android.camera.ui.RotatableLayout + android:id="@+id/hdr_switcher" + style="@style/ToggleButtonOuter" > + + <com.android.camera.ui.RotateImageView + style="@style/ToggleButton" + android:layout_gravity="center" /> + </com.android.camera.ui.RotatableLayout> + + <com.android.camera.ui.RotatableLayout + android:id="@+id/scene_mode_switcher" + style="@style/ToggleButtonOuter" > + + <com.android.camera.ui.RotateImageView + style="@style/ToggleButton" + android:layout_gravity="center" /> + </com.android.camera.ui.RotatableLayout> + + <com.android.camera.ui.RotatableLayout + android:id="@+id/filter_mode_switcher" + style="@style/ToggleButtonOuter" > + + <com.android.camera.ui.RotateImageView + style="@style/ToggleButton" + android:layout_gravity="center" /> + </com.android.camera.ui.RotatableLayout> </com.android.camera.ui.CameraControls> diff --git a/res/layout-port/camera_controls.xml b/res/layout-port/camera_controls.xml index a98ddff25..bf3cda0ab 100644 --- a/res/layout-port/camera_controls.xml +++ b/res/layout-port/camera_controls.xml @@ -13,59 +13,100 @@ See the License for the specific language governing permissions and limitations under the License. --> -<com.android.camera.ui.CameraControls - xmlns:android="http://schemas.android.com/apk/res/android" +<com.android.camera.ui.CameraControls xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/camera_controls" android:layout_width="match_parent" android:layout_height="match_parent" > - <View - android:id="@+id/blocker" - android:clickable="true" - android:layout_width="match_parent" - android:layout_height="@dimen/switcher_size" - android:layout_gravity="bottom" /> - - <include layout="@layout/menu_indicators" - android:layout_width="64dip" - android:layout_height="64dip" - android:layout_gravity="bottom|right" - android:layout_marginBottom="6dip" - android:layout_marginRight="-5dip" /> - - <com.android.camera.ui.PieMenuButton - android:id="@+id/menu" - style="@style/SwitcherButton" - android:layout_gravity="bottom|right" - android:layout_marginBottom="2dip" - android:contentDescription="@string/accessibility_menu_button" /> - - <com.android.camera.ui.ModuleSwitcher - android:id="@+id/camera_switcher" - style="@style/SwitcherButton" - android:layout_gravity="bottom|left" - android:layout_marginBottom="2dip" - android:contentDescription="@string/accessibility_mode_picker" /> - - <com.android.camera.ShutterButton - android:id="@+id/shutter_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="bottom|center_horizontal" - android:layout_marginBottom="@dimen/shutter_offset" - android:clickable="true" - android:contentDescription="@string/accessibility_shutter_button" - android:focusable="true" - android:scaleType="center" - android:src="@drawable/btn_new_shutter" /> + <View + android:id="@+id/blocker" + android:layout_width="match_parent" + android:layout_height="@dimen/switcher_size" + android:layout_gravity="bottom" + android:clickable="true" /> + + <include + android:layout_width="64dip" + android:layout_height="64dip" + android:layout_gravity="bottom|right" + android:layout_marginBottom="8dip" + android:layout_marginRight="-8dip" + layout="@layout/menu_indicators" /> + + <com.android.camera.ui.RotatableLayout + android:id="@+id/menu" + style="@style/MenuButtonOuter" + android:layout_marginRight="2dip" > <ImageView - android:id="@+id/preview_thumb" - android:visibility="invisible" - android:layout_width="@dimen/capture_size" - android:layout_height="@dimen/capture_size" - android:scaleType="centerInside" - android:layout_gravity="top|right" - android:contentDescription="@string/switch_photo_filmstrip" /> + style="@style/MenuButton" + android:layout_gravity="center" + android:contentDescription="@string/accessibility_menu_button" + android:src="@drawable/ic_settings" /> + </com.android.camera.ui.RotatableLayout> + + <com.android.camera.ui.ModuleSwitcher + android:id="@+id/camera_switcher" + style="@style/SwitcherButton" + android:layout_gravity="bottom|left" + android:layout_marginBottom="2dip" + android:contentDescription="@string/accessibility_mode_picker" /> + + <com.android.camera.ShutterButton + android:id="@+id/shutter_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="bottom|center_horizontal" + android:layout_marginBottom="@dimen/shutter_offset" + android:clickable="true" + android:contentDescription="@string/accessibility_shutter_button" + android:focusable="true" + android:scaleType="center" + android:src="@drawable/btn_new_shutter" /> + + <com.android.camera.ui.RotateImageView + android:id="@+id/preview_thumb" + android:layout_width="@dimen/capture_size" + android:layout_height="@dimen/capture_size" + android:layout_gravity="top|right" + android:background="@android:color/black" + android:contentDescription="@string/switch_photo_filmstrip" + android:scaleType="fitCenter" /> + + <com.android.camera.ui.RotatableLayout + android:id="@+id/front_back_switcher" + style="@style/ToggleButtonOuter" > + + <com.android.camera.ui.RotateImageView + style="@style/ToggleButton" + android:layout_gravity="center" /> + </com.android.camera.ui.RotatableLayout> + + <com.android.camera.ui.RotatableLayout + android:id="@+id/hdr_switcher" + style="@style/ToggleButtonOuter" > + + <com.android.camera.ui.RotateImageView + style="@style/ToggleButton" + android:layout_gravity="center" /> + </com.android.camera.ui.RotatableLayout> + + <com.android.camera.ui.RotatableLayout + android:id="@+id/scene_mode_switcher" + style="@style/ToggleButtonOuter" > + + <com.android.camera.ui.RotateImageView + style="@style/ToggleButton" + android:layout_gravity="center" /> + </com.android.camera.ui.RotatableLayout> + + <com.android.camera.ui.RotatableLayout + android:id="@+id/filter_mode_switcher" + style="@style/ToggleButtonOuter" > + + <com.android.camera.ui.RotateImageView + style="@style/ToggleButton" + android:layout_gravity="center" /> + </com.android.camera.ui.RotatableLayout> </com.android.camera.ui.CameraControls> diff --git a/res/layout/filter_mode_view.xml b/res/layout/filter_mode_view.xml new file mode 100644 index 000000000..dfa036c1f --- /dev/null +++ b/res/layout/filter_mode_view.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="@dimen/filter_mode_width" + android:layout_height="@dimen/filter_mode_height" + android:layout_gravity="center" + android:orientation="vertical" + android:padding="@dimen/filter_mode_padding" > + + <ImageView + android:id="@+id/image" + android:layout_width="80dp" + android:layout_height="80dp" + android:layout_gravity="center" + android:padding="2dp" /> + + <TextView + android:id="@+id/label" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:shadowColor="@android:color/black" + android:shadowDx="1" + android:shadowDy="1" + android:shadowRadius="2" + android:singleLine="true" + android:textColor="@android:color/white" + android:textSize="13sp" + android:textStyle="bold" /> + +</LinearLayout> diff --git a/res/layout/horiz_grid.xml b/res/layout/horiz_grid.xml new file mode 100644 index 000000000..910b0ea66 --- /dev/null +++ b/res/layout/horiz_grid.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:alpha="0.85" + android:background="@color/popup_background" + android:scrollbars="none" > + + <LinearLayout + android:id="@+id/layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" /> + +</HorizontalScrollView> diff --git a/res/layout/list_menu.xml b/res/layout/list_menu.xml new file mode 100644 index 000000000..e110fd571 --- /dev/null +++ b/res/layout/list_menu.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<com.android.camera.ui.ListMenu xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="@dimen/big_setting_popup_window_width" + android:layout_height="wrap_content" + android:alpha="0.85" + android:background="@color/popup_background" + android:scrollbars="none" > + +</com.android.camera.ui.ListMenu> diff --git a/res/layout/list_menu_item.xml b/res/layout/list_menu_item.xml new file mode 100644 index 000000000..fc29f3cba --- /dev/null +++ b/res/layout/list_menu_item.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<com.android.camera.ui.ListMenuItem xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:padding="5dip" > + + <ImageView + android:id="@+id/list_image" + android:layout_width="@dimen/setting_item_icon_width" + android:layout_height="@dimen/setting_item_icon_width" + android:layout_alignParentLeft="true" + android:layout_marginRight="20dp" + android:gravity="center" /> + + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignTop="@+id/list_image" + android:layout_toRightOf="@+id/list_image" + android:textColor="@android:color/white" + android:textStyle="bold" /> + + <TextView + android:id="@+id/current_setting" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_below="@id/title" + android:layout_marginTop="1dip" + android:layout_toRightOf="@+id/list_image" + android:shadowColor="@android:color/black" + android:shadowDx="1" + android:shadowDy="1" + android:shadowRadius="2" + android:text="@string/crop_save" + android:textColor="#33b5e5" + android:textSize="10dip" + android:textStyle="bold" /> + +</com.android.camera.ui.ListMenuItem> diff --git a/res/layout/list_sub_menu.xml b/res/layout/list_sub_menu.xml new file mode 100644 index 000000000..eaab0948e --- /dev/null +++ b/res/layout/list_sub_menu.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<com.android.camera.ui.ListSubMenu xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:alpha="0.85" + android:background="@drawable/list_border" + android:divider="@color/list_divider_color" + android:dividerHeight="1dp" + android:listSelector="@drawable/list_selector" + android:scrollbars="none" > + +</com.android.camera.ui.ListSubMenu> diff --git a/res/layout/list_sub_menu_item.xml b/res/layout/list_sub_menu_item.xml new file mode 100644 index 000000000..a79628b5d --- /dev/null +++ b/res/layout/list_sub_menu_item.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<com.android.camera.ui.CheckedLinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + style="@style/CustomSettingRow" + tools:ignore="UseCompoundDrawables" > + + <ImageView + android:id="@+id/image" + android:layout_width="@dimen/setting_item_icon_width" + android:layout_height="@dimen/setting_item_icon_width" + android:layout_marginRight="@dimen/setting_item_list_margin" + android:adjustViewBounds="true" + android:scaleType="fitCenter" /> + + <TextView + android:id="@+id/text" + style="@style/CustomSettingItemTitle" + android:shadowColor="@android:color/black" + android:shadowDx="1" + android:shadowDy="1" + android:shadowRadius="2" + android:textColor="@android:color/white" + android:textStyle="bold" /> + +</com.android.camera.ui.CheckedLinearLayout> diff --git a/res/layout/photo_module.xml b/res/layout/photo_module.xml index 89bc1ff39..5047112a0 100644 --- a/res/layout/photo_module.xml +++ b/res/layout/photo_module.xml @@ -23,62 +23,68 @@ <merge xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_gravity="center"> - <include layout="@layout/count_down_to_capture"/> - <!-- Wrap a frame layout around texture view so that when scaled, texture - view will not draw outside its unscaled bounds --> + android:layout_gravity="center" > + <include layout="@layout/count_down_to_capture" /> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_gravity="center_vertical|center_horizontal"> - <TextureView - android:id="@+id/preview_content" + android:layout_gravity="center_vertical|center_horizontal" > + <SurfaceView + android:id="@+id/mdp_preview_content" android:layout_width="match_parent" android:layout_height="match_parent" /> - </FrameLayout> - <RelativeLayout android:id="@+id/linear" + </FrameLayout> + <View + android:id="@+id/preview_cover" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@android:color/black" + android:visibility="gone" /> + <RelativeLayout android:id="@+id/linear" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <ProgressBar + style="?android:attr/progressBarStyleHorizontal" + android:id="@+id/progress" android:orientation="vertical" + android:layout_width="200dip" + android:layout_height="wrap_content" + android:layout_marginTop="14dip" + android:layout_marginBottom="14dip" + android:layout_marginLeft="30dip" + android:layout_marginRight="30dip" /> + <com.android.camera.GraphView + android:id="@+id/graph_view" + android:layout_width="200dip" + android:layout_height="200dip" + android:layout_marginTop="60dip" + android:layout_marginLeft="90dip" /> + <com.android.camera.DrawAutoHDR + android:id="@+id/autohdr_view" + android:layout_width="200dip" + android:layout_height="200dip" + android:layout_marginTop="15dip" + android:layout_marginLeft="15dip" /> + <TableLayout + android:id="@+id/relative_seek" android:layout_width="match_parent" - android:layout_height="match_parent"> - <ProgressBar - style="?android:attr/progressBarStyleHorizontal" - android:id="@+id/progress" - android:orientation="vertical" - android:layout_width="200dip" - android:layout_height="wrap_content" - android:layout_marginTop="14dip" - android:layout_marginBottom="14dip" - android:layout_marginLeft="30dip" - android:layout_marginRight="30dip" /> - <com.android.camera.GraphView - android:id="@+id/graph_view" - android:layout_width="200dip" - android:layout_height="200dip" - android:layout_marginTop="60dip" - android:layout_marginLeft="90dip" /> - <com.android.camera.DrawAutoHDR - android:id="@+id/autohdr_view" - android:layout_width="200dip" - android:layout_height="200dip" - android:layout_marginTop="15dip" - android:layout_marginLeft="15dip" /> - <TableLayout - android:id="@+id/relative_seek" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_marginTop="20px" - android:layout_marginRight="20px" - android:layout_marginLeft="20px" - android:stretchColumns="1"> - <TableRow> <TextView + android:layout_height="match_parent" + android:layout_marginTop="20px" + android:layout_marginRight="20px" + android:layout_marginLeft="20px" + android:stretchColumns="1"> + <TableRow> + <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/skintonetitle" android:layout_gravity="center" android:textSize="22.0sp" android:textStyle="bold" /> - </TableRow> - <TableRow> <SeekBar + </TableRow> + <TableRow> + <SeekBar android:id="@+id/skintoneseek" android:layout_below="@+id/skintonetitle" android:layout_width="match_parent" @@ -86,29 +92,23 @@ android:layout_height="33dip" android:layout_marginLeft="25px" android:layout_marginTop="2dip"/> - </TableRow> - <TableRow> - <TextView - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:id="@+id/skintoneleft" - android:textSize="22.0sp" - android:textStyle="bold" /> - <TextView - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:id="@+id/skintoneright" - android:textSize="22.0sp" - android:textStyle="bold"/> - </TableRow> - </TableLayout> - </RelativeLayout> - <View - android:id="@+id/preview_cover" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@android:color/black" - android:visibility="gone" /> + </TableRow> + <TableRow> + <TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:id="@+id/skintoneleft" + android:textSize="22.0sp" + android:textStyle="bold" /> + <TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:id="@+id/skintoneright" + android:textSize="22.0sp" + android:textStyle="bold"/> + </TableRow> + </TableLayout> + </RelativeLayout> <ImageView android:id="@+id/review_image" android:layout_width="match_parent" diff --git a/res/layout/scene_mode_view.xml b/res/layout/scene_mode_view.xml new file mode 100644 index 000000000..e8a9499d6 --- /dev/null +++ b/res/layout/scene_mode_view.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_gravity="center" + android:orientation="vertical" + android:padding="@dimen/scene_mode_padding" > + + <LinearLayout + android:id="@+id/border" + android:layout_width="@dimen/scene_mode_width" + android:layout_height="@dimen/scene_mode_height" + android:layout_gravity="center" + android:background="@drawable/scene_mode_view_border" + android:orientation="vertical" + android:padding="2dp" > + + <ImageView + android:id="@+id/image" + android:layout_width="50dp" + android:layout_height="50dp" + android:layout_gravity="center" /> + + <TextView + android:id="@+id/label" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:gravity="center" + android:shadowColor="@android:color/black" + android:shadowDx="1" + android:shadowDy="1" + android:shadowRadius="2" + android:singleLine="true" + android:textColor="@android:color/white" + android:textSize="13sp" + android:textStyle="bold" /> + </LinearLayout> + +</LinearLayout> diff --git a/res/layout/vertical_grid.xml b/res/layout/vertical_grid.xml new file mode 100644 index 000000000..0754d0483 --- /dev/null +++ b/res/layout/vertical_grid.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (c) 2014, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:alpha="0.85" + android:background="@color/popup_background" + android:scrollbars="none" > + + <LinearLayout + android:id="@+id/layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" /> + +</ScrollView> diff --git a/res/layout/video_module.xml b/res/layout/video_module.xml index af839e774..6f36081e2 100644 --- a/res/layout/video_module.xml +++ b/res/layout/video_module.xml @@ -15,25 +15,26 @@ --> <!-- This layout is shared by phone and tablet in landscape orientation. --> <merge xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_width="match_parent"> - <!-- Wrap a frame layout around texture view so that when scaled, texture - view will not draw outside its unscaled bounds --> + android:layout_gravity="center" > <FrameLayout android:layout_width="match_parent" - android:layout_height="match_parent"> - <TextureView - android:id="@+id/preview_content" - android:layout_width="match_parent" - android:layout_height="match_parent" /> - <View - android:id="@+id/preview_cover" + android:layout_height="match_parent" + android:layout_gravity="center_vertical|center_horizontal" > + <SurfaceView + android:id="@+id/mdp_preview_content" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@android:color/black" android:visibility="gone" /> </FrameLayout> <View + android:id="@+id/preview_cover" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@android:color/black" + android:visibility="gone" /> + <View android:id="@+id/flash_overlay" android:layout_width="match_parent" android:layout_height="match_parent" @@ -41,47 +42,46 @@ android:visibility="gone" android:alpha="0" /> <FrameLayout android:id="@+id/preview_border" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:visibility="gone" - android:background="@drawable/ic_snapshot_border" /> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:visibility="gone" + android:background="@drawable/ic_snapshot_border" /> <com.android.camera.ui.RenderOverlay android:id="@+id/render_overlay" android:layout_width="match_parent" android:layout_height="match_parent" /> <com.android.camera.ui.RotateLayout android:id="@+id/recording_time_rect" - android:layout_height="match_parent" - android:layout_width="match_parent"> - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="horizontal" - android:layout_height="match_parent" - android:layout_width="match_parent"> - <com.android.camera.PauseButton android:id="@+id/video_pause" - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:layout_marginLeft="50dp" - android:padding="23dp" - android:visibility="gone" - android:src="@drawable/btn_pause_recording"/> - <include layout="@layout/viewfinder_labels_video" - android:id="@+id/labels" /> - </LinearLayout> + android:layout_height="match_parent" + android:layout_width="match_parent"> + <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_height="match_parent" + android:layout_width="match_parent"> + <com.android.camera.PauseButton android:id="@+id/video_pause" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_marginLeft="50dp" + android:padding="23dp" + android:visibility="gone" + android:src="@drawable/btn_pause_recording"/> + <include layout="@layout/viewfinder_labels_video" + android:id="@+id/labels" /> + </LinearLayout> </com.android.camera.ui.RotateLayout> <ImageView android:id="@+id/review_image" - android:layout_height="match_parent" - android:layout_width="match_parent" - android:visibility="gone" - android:background="@android:color/black"/> + android:layout_height="match_parent" + android:layout_width="match_parent" + android:visibility="gone" + android:background="@android:color/black"/> <ImageView - android:id="@+id/btn_play" - style="@style/ReviewControlIcon" - android:layout_centerInParent="true" - android:src="@drawable/ic_gallery_play_big" - android:scaleType="center" - android:visibility="gone" - android:onClick="onReviewPlayClicked"/> - + android:id="@+id/btn_play" + style="@style/ReviewControlIcon" + android:layout_centerInParent="true" + android:src="@drawable/ic_gallery_play_big" + android:scaleType="center" + android:visibility="gone" + android:onClick="onReviewPlayClicked"/> <include layout="@layout/camera_controls" android:layout_gravity="center" style="@style/CameraControls"/> diff --git a/res/values/arrays.xml b/res/values/arrays.xml index f82c712a9..408d5064d 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -31,32 +31,19 @@ <item>@string/pref_video_quality_entry_qvga</item> <item>@string/pref_video_quality_entry_qcif</item> </string-array> - <string-array name="pref_video_quality_entryvalues" translatable="false"> - <!-- The integer value of CamcorderProfile.QUALITY_4kDCI --> - <item>13</item> - <!-- The integer value of CamcorderProfile.QUALITY_2160P --> - <item>8</item> - <!-- The integer value of CamcorderProfile.QUALITY_1080P --> - <item>6</item> - <!-- The integer value of CamcorderProfile.QUALITY_720P --> - <item>5</item> - <!-- The integer value of CamcorderProfile.QUALITY_480P --> - <item>4</item> - <!-- The integer value of CamcorderProfile.QUALITY_FWVGA --> - <item>12</item> - <!-- The integer value of CamcorderProfile.QUALITY_WVGA --> - <item>9</item> - <!-- The integer value of CamcorderProfile.QUALITY_VGA --> - <item>10</item> - <!-- The integer value of CamcorderProfile.QUALITY_WQVGA --> - <item>11</item> - <!-- The integer value of CamcorderProfile.QUALITY_CIF --> - <item>@string/pref_video_quality_default</item> - <!-- The integer value of CamcorderProfile.QUALITY_QVGA --> - <item>7</item> - <!-- The integer value of CamcorderProfile.QUALITY_QCIF --> - <item>2</item> + <item>4096x2160</item> + <item>3840x2160</item> + <item>1920x1080</item> + <item>1280x720</item> + <item>720x480</item> + <item>864x480</item> + <item>800x480</item> + <item>640x480</item> + <item>400x240</item> + <item>352x288</item> + <item>320x240</item> + <item>176x144</item> </string-array> <!-- Camera Preference save path entries --> @@ -225,7 +212,7 @@ <item>4160x3120</item> <item>4000x3000</item> <item>3840x2160</item> - <item>3200x2400</item> + <item>3264x2448</item> <item>2976x2976</item> <item>2592x1944</item> <item>2592x1936</item> @@ -407,27 +394,33 @@ <!-- Camera Preferences Scene Mode dialog box entries --> <string-array name="pref_camera_scenemode_entries" translatable="false"> - <item>@string/pref_camera_scenemode_entry_action</item> - <item>@string/pref_camera_scenemode_entry_night</item> <item>@string/pref_camera_scenemode_entry_auto</item> - <item>@string/pref_camera_scenemode_entry_sunset</item> - <item>@string/pref_camera_scenemode_entry_party</item> - <item>@string/pref_camera_scenemode_entry_asd</item> - <item>@string/pref_camera_scenemode_entry_portrait</item> + <!-- <item>@string/pref_camera_scenemode_entry_portrait</item> --> <item>@string/pref_camera_scenemode_entry_landscape</item> - <item>@string/pref_camera_scenemode_entry_night_portrait</item> - <item>@string/pref_camera_scenemode_entry_theatre</item> - <item>@string/pref_camera_scenemode_entry_beach</item> - <item>@string/pref_camera_scenemode_entry_snow</item> - <item>@string/pref_camera_scenemode_entry_steadyphoto</item> - <item>@string/pref_camera_scenemode_entry_fireworks</item> <item>@string/pref_camera_scenemode_entry_sports</item> - <item>@string/pref_camera_scenemode_entry_candlelight</item> - <item>@string/pref_camera_scenemode_entry_backlight</item> <item>@string/pref_camera_scenemode_entry_flowers</item> - <item>@string/pref_camera_scenemode_entry_ar</item> + <item>@string/pref_camera_scenemode_entry_backlight</item> + <item>@string/pref_camera_scenemode_entry_candlelight</item> + <item>@string/pref_camera_scenemode_entry_sunset</item> + <item>@string/pref_camera_scenemode_entry_night</item> + <item>@string/pref_camera_scenemode_entry_beach</item> + <item>@string/pref_camera_scenemode_entry_snow</item> </string-array> + <array name="scenemode_thumbnails" translatable="false"> + <item>@drawable/ic_scene_mode_auto</item> + <!-- <item>@drawable/ic_scene_mode_portrait</item> --> + <item>@drawable/ic_scene_mode_landscape</item> + <item>@drawable/ic_scene_mode_sports</item> + <item>@drawable/ic_scene_mode_flower</item> + <item>@drawable/ic_scene_mode_backlight</item> + <item>@drawable/ic_scene_mode_candlelight</item> + <item>@drawable/ic_scene_mode_sunset</item> + <item>@drawable/ic_scene_mode_night</item> + <item>@drawable/ic_scene_mode_beach</item> + <item>@drawable/ic_scene_mode_snow</item> + </array> + <string-array name="pref_camera_scenemode_labels"> <item>@string/pref_camera_scenemode_label_action</item> <item>@string/pref_camera_scenemode_label_night</item> @@ -445,25 +438,17 @@ </array> <string-array name="pref_camera_scenemode_entryvalues" translatable="false"> - <item>action</item> - <item>night</item> <item>auto</item> - <item>sunset</item> - <item>party</item> - <item>asd</item> - <item>portrait</item> + <!-- <item>portrait</item> --> <item>landscape</item> - <item>night-portrait</item> - <item>theatre</item> - <item>beach</item> - <item>snow</item> - <item>steadyphoto</item> - <item>fireworks</item> <item>sports</item> - <item>candlelight</item> - <item>backlight</item> <item>flowers</item> - <item>AR</item> + <item>backlight</item> + <item>candlelight</item> + <item>sunset</item> + <item>night</item> + <item>beach</item> + <item>snow</item> </string-array> <array name="camera_id_entries" translatable="false"> diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 5a00a695a..b9c04f290 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -40,6 +40,7 @@ <attr name="singleIcon" format="reference" /> <attr name="icons" /> <attr name="largeIcons" format="reference" /> + <attr name="thumbnails" format="reference" /> <attr name="images" format="reference" /> </declare-styleable> diff --git a/res/values/bool.xml b/res/values/bool.xml index 4488d70bb..2bb520bf6 100644 --- a/res/values/bool.xml +++ b/res/values/bool.xml @@ -16,4 +16,5 @@ <resources> <bool name="show_action_bar_title">false</bool> <bool name="force_count_down_sound">false</bool> + <bool name="volume_key_shutter_disable">false</bool> </resources> diff --git a/res/values/colors.xml b/res/values/colors.xml index 4fe918094..cd7f5977d 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -70,4 +70,7 @@ <color name="face_detect_fail">#80d05060</color> <color name="gray">#FFAAAAAA</color> + <color name="setting_color">#ff10aadc</color> + <color name="setting_color_light">#ffade9fd</color> + <color name="list_divider_color">#d8ababab</color> </resources> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index e2d4246df..6b81ab906 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -92,9 +92,13 @@ <dimen name="focus_inner_stroke">2dp</dimen> <dimen name="zoom_ring_min">48dp</dimen> <dimen name="switcher_size">72dp</dimen> + <dimen name="menu_size">52dp</dimen> + <dimen name="menu_outer_size">80dp</dimen> + <dimen name="toggle_size">30dp</dimen> + <dimen name="toggle_outer_size">60dp</dimen> <dimen name="face_circle_stroke">2dip</dimen> <dimen name="zoom_font_size">14pt</dimen> - <dimen name="shutter_offset">-22dp</dimen> + <dimen name="shutter_offset">5dp</dimen> <dimen name="size_thumbnail">200dip</dimen> <dimen name="size_preview">400dip</dimen> <dimen name="navigation_bar_height">48dip</dimen> @@ -153,4 +157,11 @@ <dimen name="photoeditor_text_padding">10dp</dimen> <dimen name="photoeditor_original_text_size">18dp</dimen> <dimen name="photoeditor_original_text_margin">4dp</dimen> + + <dimen name="scene_mode_height">85dp</dimen> + <dimen name="scene_mode_width">90dp</dimen> + <dimen name="scene_mode_padding">10dp</dimen> + <dimen name="filter_mode_height">100dp</dimen> + <dimen name="filter_mode_width">80dp</dimen> + <dimen name="filter_mode_padding">10dp</dimen> </resources> diff --git a/res/values/qcomarrays.xml b/res/values/qcomarrays.xml index 0b1037e72..abe13a117 100644 --- a/res/values/qcomarrays.xml +++ b/res/values/qcomarrays.xml @@ -222,6 +222,24 @@ <item>@string/pref_camera_coloreffect_entry_greentint</item> </string-array> + <array name="coloreffect_thumbnails" translatable="false"> + <item>@drawable/thumb_filter_nofilter</item> + <item>@drawable/thumb_filter_monochrome</item> + <item>@drawable/thumb_filter_sepia</item> + <item>@drawable/thumb_filter_negative</item> + <item>@drawable/thumb_filter_solarize</item> + <item>@drawable/thumb_filter_posterize</item> + <item>@drawable/thumb_filter_aqua</item> + <item>@drawable/thumb_filter_emboss</item> + <item>@drawable/thumb_filter_sketch</item> + <item>@drawable/thumb_filter_neon</item> + <item>0</item> + <item>0</item> + <item>0</item> + <item>0</item> + <item>0</item> + </array> + <string-array name="pref_camera_coloreffect_entryvalues" translatable="false"> <item>none</item> <item>mono</item> diff --git a/res/values/qcomstrings.xml b/res/values/qcomstrings.xml index c72f9bb1e..c76f5c658 100644 --- a/res/values/qcomstrings.xml +++ b/res/values/qcomstrings.xml @@ -283,7 +283,7 @@ <string name="pref_camera_video_tnr_default" translatable="false">off</string> <!-- Default face detection setting. --> - <string name="pref_camera_facedetection_default" translatable="false">on</string> + <string name="pref_camera_facedetection_default" translatable="false">off</string> <!-- Settings screen, Select Face Detection --> <string name="pref_camera_facedetection_title">Face Detection</string> diff --git a/res/values/strings.xml b/res/values/strings.xml index 290f13588..54ef31f9d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -238,8 +238,8 @@ <!-- The Video quality settings in preference [CHAR LIMIT=21] --> <string name="pref_video_quality_title">Video quality</string> - <!-- The default quality value is 3 (CIF) --> - <string name="pref_video_quality_default" translatable="false">3</string> + <!-- The default quality value is (CIF) --> + <string name="pref_video_quality_default" translatable="false">352x288</string> <!-- Video quality setting entry. Videos will be recorded in 4k DCI quality. [CHAR LIMIT=24] --> <string name="pref_video_quality_entry_4kdci" translatable="false"> @@ -375,7 +375,7 @@ <string name="pref_camera_scenemode_title">Scene mode</string> <!-- Settings menu, scene mode choices [CHAR LIMIT=16] --> - <string name="pref_camera_scenemode_entry_auto">Auto</string> + <string name="pref_camera_scenemode_entry_auto">Automatic</string> <!-- Scene mode that uses HDR plus (better HDR) [CHAR LIMIT=16] --> <string name="pref_camera_scenemode_entry_hdr_plus">HDR+</string> <!-- Scene mode that uses HDR (high dynamic range) [CHAR LIMIT=16] --> diff --git a/res/values/styles.xml b/res/values/styles.xml index ad32b0634..682337fe9 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -80,6 +80,14 @@ <item name="android:layout_height">wrap_content</item> <item name="android:listSelector">@drawable/bg_pressed</item> </style> + <style name="CustomSettingItemTitle"> + <item name="android:textSize">14sp</item> + <item name="android:gravity">left|center_vertical</item> + <item name="android:singleLine">true</item> + <item name="android:layout_weight">1</item> + <item name="android:layout_width">0dp</item> + <item name="android:layout_height">match_parent</item> + </style> <style name="SettingItemTitle"> <item name="android:textSize">@dimen/setting_item_text_size</item> <item name="android:gravity">left|center_vertical</item> @@ -107,6 +115,15 @@ <item name="android:paddingRight">@dimen/setting_item_list_margin</item> <item name="android:background">@drawable/setting_picker</item> </style> + <style name="CustomSettingRow"> + <item name="android:gravity">center_vertical</item> + <item name="android:orientation">horizontal</item> + <item name="android:layout_width">3000dp</item> + <item name="android:layout_height">@dimen/setting_row_height</item> + <item name="android:paddingLeft">10dp</item> + <item name="android:paddingRight">@dimen/setting_item_list_margin</item> + <item name="android:background">@drawable/setting_picker</item> + </style> <style name="OnViewfinderLabel"> <item name="android:gravity">center</item> <item name="android:layout_width">wrap_content</item> @@ -230,6 +247,24 @@ <item name="android:layout_height">@dimen/switcher_size</item> <item name="android:background">@drawable/bg_pressed_exit_fading</item> </style> + <style name="MenuButton"> + <item name="android:layout_width">@dimen/menu_size</item> + <item name="android:layout_height">@dimen/menu_size</item> + </style> + <style name="MenuButtonOuter"> + <item name="android:layout_width">@dimen/menu_outer_size</item> + <item name="android:layout_height">@dimen/menu_outer_size</item> + <item name="android:background">@drawable/bg_pressed_exit_fading</item> + </style> + <style name="ToggleButton"> + <item name="android:layout_width">@dimen/toggle_size</item> + <item name="android:layout_height">@dimen/toggle_size</item> + </style> + <style name="ToggleButtonOuter"> + <item name="android:layout_width">@dimen/toggle_outer_size</item> + <item name="android:layout_height">@dimen/toggle_outer_size</item> + <item name="android:background">@drawable/bg_pressed_exit_fading</item> + </style> <style name="MenuIndicator"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> diff --git a/res/xml/camera_preferences.xml b/res/xml/camera_preferences.xml index 39c54daa7..c9008c3a7 100644 --- a/res/xml/camera_preferences.xml +++ b/res/xml/camera_preferences.xml @@ -25,17 +25,19 @@ camera:largeIcons="@array/camera_flashmode_largeicons" camera:entries="@array/pref_camera_flashmode_entries" camera:entryValues="@array/pref_camera_flashmode_entryvalues" - camera:labelList="@array/pref_camera_flashmode_labels" /> + camera:labelList="@array/pref_camera_flashmode_labels" + camera:singleIcon="@drawable/ic_settings_flash" /> <IconListPreference camera:key="pref_camera_exposure_key" camera:defaultValue="@string/pref_exposure_default" camera:title="@string/pref_exposure_title" - camera:singleIcon="@drawable/ic_exposure_holo_light" /> + camera:singleIcon="@drawable/ic_settings_exposure" /> <IconListPreference camera:key="pref_camera_scenemode_key" camera:defaultValue="@string/pref_camera_scenemode_default" camera:title="@string/pref_camera_scenemode_title" - camera:singleIcon="@drawable/ic_sce" + camera:singleIcon="@drawable/ic_settings_scenemode" + camera:thumbnails="@array/scenemode_thumbnails" camera:entries="@array/pref_camera_scenemode_entries" camera:entryValues="@array/pref_camera_scenemode_entryvalues" /> <IconListPreference @@ -43,6 +45,7 @@ camera:defaultValue="@string/pref_camera_whitebalance_default" camera:title="@string/pref_camera_whitebalance_title" camera:icons="@array/whitebalance_icons" + camera:singleIcon="@drawable/ic_settings_lightsource" camera:largeIcons="@array/whitebalance_largeicons" camera:entries="@array/pref_camera_whitebalance_entries" camera:entryValues="@array/pref_camera_whitebalance_entryvalues" @@ -52,19 +55,22 @@ camera:defaultValue="@string/pref_camera_recordlocation_default" camera:title="@string/pref_camera_recordlocation_title" camera:icons="@array/camera_recordlocation_icons" + camera:singleIcon="@drawable/ic_settings_location" camera:largeIcons="@array/camera_recordlocation_largeicons" camera:entries="@array/pref_camera_recordlocation_entries" camera:labelList="@array/pref_camera_recordlocation_labels" camera:entryValues="@array/pref_camera_recordlocation_entryvalues" /> - <ListPreference + <IconListPreference camera:key="pref_camera_picturesize_key" + camera:singleIcon="@drawable/ic_settings_picturesize" camera:title="@string/pref_camera_picturesize_title" camera:entries="@array/pref_camera_picturesize_entries" camera:entryValues="@array/pref_camera_picturesize_entryvalues" /> - <ListPreference + <IconListPreference camera:key="pref_camera_focusmode_key" camera:defaultValue="@array/pref_camera_focusmode_default_array" camera:title="@string/pref_camera_focusmode_title" + camera:singleIcon="@drawable/ic_settings_focus" camera:entries="@array/pref_camera_focusmode_entries" camera:labelList="@array/pref_camera_focusmode_labels" camera:entryValues="@array/pref_camera_focusmode_entryvalues" /> @@ -115,6 +121,7 @@ <CountDownTimerPreference camera:key="pref_camera_timer_key" camera:defaultValue="@string/pref_camera_timer_default" + camera:singleIcon="@drawable/ic_settings_countdowntimer" camera:title="@string/pref_camera_timer_title" /> <ListPreference camera:key="pref_camera_timer_sound_key" @@ -134,16 +141,19 @@ camera:title="@string/pref_camera_facerc_title" camera:entries="@array/pref_camera_facerc_entries" camera:entryValues="@array/pref_camera_facerc_entryvalues" /> - <ListPreference + <IconListPreference camera:key="pref_camera_coloreffect_key" camera:defaultValue="@string/pref_camera_coloreffect_default" camera:title="@string/pref_camera_coloreffect_title" camera:entries="@array/pref_camera_coloreffect_entries" + camera:thumbnails="@array/coloreffect_thumbnails" + camera:singleIcon="@drawable/ic_settings_filter" camera:entryValues="@array/pref_camera_coloreffect_entryvalues" /> - <ListPreference + <IconListPreference camera:key="pref_camera_jpegquality_key" camera:defaultValue="@string/pref_camera_jpegquality_default" camera:title="@string/pref_camera_jpegquality_title" + camera:singleIcon="@drawable/ic_settings_quality" camera:entries="@array/pref_camera_jpegquality_entries" camera:entryValues="@array/pref_camera_jpegquality_entryvalues" /> <ListPreference @@ -152,11 +162,12 @@ camera:title="@string/pref_camera_touchafaec_title" camera:entries="@array/pref_camera_touchafaec_entries" camera:entryValues="@array/pref_camera_touchafaec_entryvalues" /> - <ListPreference + <IconListPreference camera:key="pref_camera_iso_key" camera:defaultValue="@string/pref_camera_iso_default" camera:title="@string/pref_camera_iso_title" camera:entries="@array/pref_camera_iso_entries" + camera:singleIcon="@drawable/ic_settings_iso" camera:entryValues="@array/pref_camera_iso_entryvalues" /> <ListPreference camera:key="pref_camera_histogram_key" @@ -212,17 +223,19 @@ camera:title="@string/pref_camera_skinToneEnhancement_title" camera:entries="@array/pref_camera_skinToneEnhancement_entries" camera:entryValues="@array/pref_camera_skinToneEnhancement_entryvalues" /> - <ListPreference + <IconListPreference camera:key="pref_camera_facedetection_key" camera:defaultValue="@string/pref_camera_facedetection_default" camera:title="@string/pref_camera_facedetection_title" camera:entries="@array/pref_camera_facedetection_entries" + camera:singleIcon="@drawable/ic_settings_facerec" camera:entryValues="@array/pref_camera_facedetection_entryvalues" /> - <ListPreference + <IconListPreference camera:key="pref_camera_redeyereduction_key" camera:defaultValue="@string/pref_camera_redeyereduction_default" camera:title="@string/pref_camera_redeyereduction_title" camera:entries="@array/pref_camera_redeyereduction_entries" + camera:singleIcon="@drawable/ic_settings_redeye" camera:entryValues="@array/pref_camera_redeyereduction_entryvalues" /> <ListPreference camera:key="pref_camera_selectablezoneaf_key" @@ -236,11 +249,12 @@ camera:title="@string/pref_camera_zsl_title" camera:entries="@array/pref_camera_zsl_entries" camera:entryValues="@array/pref_camera_zsl_entryvalues" /> - <ListPreference + <IconListPreference camera:key="pref_camera_savepath_key" camera:defaultValue="@string/pref_camera_savepath_default" camera:title="@string/pref_camera_savepath_title" camera:entries="@array/pref_camera_savepath_entries" + camera:singleIcon="@drawable/ic_settings_storage" camera:entryValues="@array/pref_camera_savepath_entryvalues" /> <ListPreference camera:key="pref_camera_videosnapsize_key" @@ -254,14 +268,13 @@ camera:title="@string/pref_camera_advanced_features_title" camera:entries="@array/pref_camera_advanced_features_entries" camera:entryValues="@array/pref_camera_advanced_features_entryvalues" /> - - <ListPreference + <IconListPreference camera:key="pref_camera_longshot_key" camera:title="@string/pref_camera_longshot_title" camera:defaultValue="@string/pref_camera_longshot_default" camera:entries="@array/pref_camera_longshot_entries" + camera:singleIcon="@drawable/ic_settings_continuous" camera:entryValues="@array/pref_camera_longshot_entryvalues" /> - <ListPreference camera:key="pref_camera_auto_hdr_key" camera:defaultValue="@string/pref_camera_auto_hdr_default" diff --git a/res/xml/video_preferences.xml b/res/xml/video_preferences.xml index 362607cb3..12dfc700f 100644 --- a/res/xml/video_preferences.xml +++ b/res/xml/video_preferences.xml @@ -17,11 +17,12 @@ <PreferenceGroup xmlns:camera="http://schemas.android.com/apk/res/org.codeaurora.snapcam" camera:title="@string/pref_camcorder_settings_category"> - <ListPreference + <IconListPreference camera:key="pref_video_quality_key" camera:defaultValue="@string/pref_video_quality_default" camera:title="@string/pref_video_quality_title" camera:entries="@array/pref_video_quality_entries" + camera:singleIcon="@drawable/ic_settings_quality" camera:entryValues="@array/pref_video_quality_entryvalues"/> <ListPreference camera:key="pref_camera_videoencoder_key" @@ -51,13 +52,13 @@ camera:key="pref_camera_video_duration_key" camera:defaultValue="@string/pref_camera_video_duration_default" camera:title="@string/pref_camera_video_duration_title" + camera:singleIcon="@drawable/ic_settings_duration" camera:entries="@array/pref_camera_video_duration_entries" camera:entryValues="@array/pref_camera_video_duration_entryvalues" /> <IconListPreference 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:singleIcon="@drawable/ic_timelapse_none" camera:entries="@array/pref_video_time_lapse_frame_interval_entries" camera:entryValues="@array/pref_video_time_lapse_frame_interval_entryvalues"/> <IconListPreference @@ -66,6 +67,7 @@ camera:title="@string/pref_camera_flashmode_title" camera:icons="@array/video_flashmode_icons" camera:largeIcons="@array/video_flashmode_largeicons" + camera:singleIcon="@drawable/ic_settings_flash" camera:entries="@array/pref_camera_video_flashmode_entries" camera:labelList="@array/pref_camera_video_flashmode_labels" camera:entryValues="@array/pref_camera_video_flashmode_entryvalues"/> @@ -77,6 +79,7 @@ camera:largeIcons="@array/whitebalance_largeicons" camera:entries="@array/pref_camera_whitebalance_entries" camera:labelList="@array/pref_camera_whitebalance_labels" + camera:singleIcon="@drawable/ic_settings_lightsource" camera:entryValues="@array/pref_camera_whitebalance_entryvalues"/> <IconListPreference camera:key="pref_camera_id_key" @@ -99,6 +102,7 @@ camera:defaultValue="@string/pref_camera_recordlocation_default" camera:title="@string/pref_camera_recordlocation_title" camera:icons="@array/camera_recordlocation_icons" + camera:singleIcon="@drawable/ic_settings_location" camera:largeIcons="@array/camera_recordlocation_largeicons" camera:entries="@array/pref_camera_recordlocation_entries" camera:entryValues="@array/pref_camera_recordlocation_entryvalues" /> @@ -114,16 +118,19 @@ camera:title="@string/pref_camera_dis_title" camera:entries="@array/pref_camera_dis_entries" camera:entryValues="@array/pref_camera_dis_entryvalues" /> - <ListPreference + <IconListPreference camera:key="pref_camera_coloreffect_key" camera:defaultValue="@string/pref_camera_coloreffect_default" camera:title="@string/pref_camera_coloreffect_title" camera:entries="@array/pref_camera_coloreffect_entries" + camera:thumbnails="@array/coloreffect_thumbnails" + camera:singleIcon="@drawable/ic_settings_filter" camera:entryValues="@array/pref_camera_coloreffect_entryvalues" /> - <ListPreference + <IconListPreference camera:key="pref_camera_hfr_key" camera:defaultValue="@string/pref_camera_hfr_default" camera:title="@string/pref_camera_hfr_title" + camera:singleIcon="@drawable/ic_settings_fps" camera:entries="@array/pref_camera_hfr_entries" camera:entryValues="@array/pref_camera_hfr_entryvalues"/> <ListPreference @@ -144,11 +151,12 @@ camera:title="@string/pref_camera_picturesize_title" camera:entries="@array/pref_camera_picturesize_entries" camera:entryValues="@array/pref_camera_picturesize_entryvalues" /> - <ListPreference + <IconListPreference camera:key="pref_camera_savepath_key" camera:defaultValue="@string/pref_camera_savepath_default" camera:title="@string/pref_camera_savepath_title" camera:entries="@array/pref_camera_savepath_entries" + camera:singleIcon="@drawable/ic_settings_storage" camera:entryValues="@array/pref_camera_savepath_entryvalues" /> <ListPreference camera:key="pref_camera_video_rotation_key" diff --git a/src/com/android/camera/AndroidCameraManagerImpl.java b/src/com/android/camera/AndroidCameraManagerImpl.java index 42ae20f02..637a5f5c5 100644 --- a/src/com/android/camera/AndroidCameraManagerImpl.java +++ b/src/com/android/camera/AndroidCameraManagerImpl.java @@ -201,14 +201,7 @@ class AndroidCameraManagerImpl implements CameraManager { try { switch (msg.what) { case OPEN_CAMERA: - try { - mCamera = android.hardware.Camera.openLegacy(msg.arg1, - android.hardware.Camera.CAMERA_HAL_API_VERSION_1_0); - } catch (RuntimeException e) { - /* Retry with open if openLegacy fails */ - Log.v(TAG, "openLegacy failed. Using open instead"); - mCamera = android.hardware.Camera.open(msg.arg1); - } + mCamera = android.hardware.Camera.open(msg.arg1); if (mCamera != null) { mParametersIsDirty = true; diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java index c40dacc0a..b5fc0a676 100644 --- a/src/com/android/camera/CameraActivity.java +++ b/src/com/android/camera/CameraActivity.java @@ -16,6 +16,8 @@ package com.android.camera; +import android.view.Display; +import android.graphics.Point; import android.animation.Animator; import android.annotation.TargetApi; import android.app.ActionBar; @@ -31,8 +33,12 @@ import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.res.Configuration; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.drawable.ColorDrawable; import android.net.Uri; +import android.media.ThumbnailUtils; import android.nfc.NfcAdapter; import android.nfc.NfcAdapter.CreateBeamUrisCallback; import android.nfc.NfcEvent; @@ -81,6 +87,7 @@ import com.android.camera.tinyplanet.TinyPlanetFragment; import com.android.camera.ui.ModuleSwitcher; import com.android.camera.ui.DetailsDialog; import com.android.camera.ui.FilmStripView; +import com.android.camera.ui.FilmStripView.ImageData; import com.android.camera.util.ApiHelper; import com.android.camera.util.CameraUtil; import com.android.camera.util.GcamHelper; @@ -143,6 +150,10 @@ public class CameraActivity extends Activity private static final int SUPPORT_SHOW_ON_MAP = 1 << 9; private static final int SUPPORT_ALL = 0xffffffff; + // Pie Setting Menu enabled + private static boolean PIE_MENU_ENABLED = false; + private boolean mDeveloperMenuEnabled = false; + /** This data adapter is used by FilmStripView. */ private LocalDataAdapter mDataAdapter; /** This data adapter represents the real local camera data. */ @@ -177,6 +188,8 @@ public class CameraActivity extends Activity private boolean mIsUndoingDeletion = false; private boolean mIsEditActivityInProgress = false; protected boolean mIsModuleSwitchInProgress = false; + private View mPreviewCover; + private FrameLayout mPreviewContentLayout; private Uri[] mNfcPushUris = new Uri[1]; @@ -187,12 +200,15 @@ public class CameraActivity extends Activity private LocalMediaObserver mLocalImagesObserver; private LocalMediaObserver mLocalVideosObserver; - private final int DEFAULT_SYSTEM_UI_VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; + private final int DEFAULT_SYSTEM_UI_VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + private boolean mPendingDeletion = false; private Intent mVideoShareIntent; private Intent mImageShareIntent; + public static int SETTING_LIST_WIDTH_1 = 250; + public static int SETTING_LIST_WIDTH_2 = 250; + private Bitmap mPreviewThumbnailBitmap; private class MyOrientationEventListener extends OrientationEventListener { @@ -303,6 +319,18 @@ public class CameraActivity extends Activity return sFirstStartAfterScreenOn; } + public static boolean isPieMenuEnabled() { + return PIE_MENU_ENABLED; + } + + public boolean isDeveloperMenuEnabled() { + return mDeveloperMenuEnabled; + } + + public void enableDeveloperMenu() { + mDeveloperMenuEnabled = true; + } + public static void resetFirstStartAfterScreenOn() { sFirstStartAfterScreenOn = false; } @@ -491,10 +519,13 @@ public class CameraActivity extends Activity }; public void gotoGallery() { - UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, UsageStatistics.ACTION_FILMSTRIP, - "thumbnailTap"); - - mFilmStripView.getController().goToNextItem(); + LocalDataAdapter adapter = getDataAdapter(); + ImageData img = adapter.getImageData(1); + if (img == null) + return; + Uri uri = img.getContentUri(); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + startActivity(intent); } /** @@ -515,9 +546,9 @@ public class CameraActivity extends Activity mMainHandler.removeMessages(HIDE_ACTION_BAR); int currentSystemUIVisibility = mAboveFilmstripControlLayout.getSystemUiVisibility(); - int newSystemUIVisibility = DEFAULT_SYSTEM_UI_VISIBILITY | - (visible ? View.SYSTEM_UI_FLAG_VISIBLE : - View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN); + int newSystemUIVisibility = DEFAULT_SYSTEM_UI_VISIBILITY + | (visible ? View.SYSTEM_UI_FLAG_VISIBLE : View.SYSTEM_UI_FLAG_LOW_PROFILE + | View.SYSTEM_UI_FLAG_FULLSCREEN); if (newSystemUIVisibility != currentSystemUIVisibility) { mAboveFilmstripControlLayout.setSystemUiVisibility(newSystemUIVisibility); } @@ -578,6 +609,98 @@ public class CameraActivity extends Activity mNfcPushUris[0] = uri; } + public LocalDataAdapter getDataAdapter() { + return mDataAdapter; + } + + private String getPathFromUri(Uri uri) { + String[] projection = { + MediaStore.Images.Media.DATA + }; + Cursor cursor = getContentResolver().query(uri, projection, null, null, null); + if (cursor == null) + return null; + int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + cursor.moveToFirst(); + String s = cursor.getString(column_index); + cursor.close(); + return s; + } + + public void setPreviewThumbnailBitmap(Bitmap bitmap) { + mPreviewThumbnailBitmap = bitmap; + } + + public Bitmap getPreviewThumbBitmap() { + return mPreviewThumbnailBitmap; + } + + public void updatePreviewThumbnail() { + if (mCurrentModule != null) { + if (mCurrentModule instanceof VideoModule) { + ((VideoModule) mCurrentModule).updatePreviewThumbnail(); + } + else if (mCurrentModule instanceof WideAnglePanoramaModule) { + ((WideAnglePanoramaModule) mCurrentModule).updatePreviewThumbnail(); + } + else if (mCurrentModule instanceof PhotoModule) { + ((PhotoModule) mCurrentModule).updatePreviewThumbnail(); + } + } + } + + public void updatePreviewThumbnailForVideo() { + if (mCurrentModule != null) { + if (mCurrentModule instanceof VideoModule) { + ((VideoModule) mCurrentModule).updatePreviewThumbnail(); + } + } + } + + public class UpdatePreviewThumbnail extends AsyncTask<Void, Void, Bitmap> { + private ImageView imgView; + private Bitmap imgBitmap = null; + + public UpdatePreviewThumbnail(ImageView view) { + imgView = view; + } + + @Override + protected Bitmap doInBackground(Void... params) { + if (imgBitmap != null) + return imgBitmap; + + LocalDataAdapter adapter = getDataAdapter(); + ImageData img = adapter.getImageData(1); + if (img == null) { + return null; + } + Uri uri = img.getContentUri(); + String path = getPathFromUri(uri); + if (path == null) { + return null; + } + else { + if (img.isPhoto()) { + BitmapFactory.Options opt = new BitmapFactory.Options(); + opt.inSampleSize = 4; + return BitmapFactory.decodeFile(path, opt); + } else { + return ThumbnailUtils + .createVideoThumbnail(path, MediaStore.Video.Thumbnails.MICRO_KIND); + } + } + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (imgView == null) + return; + imgView.setImageBitmap(bitmap); + setPreviewThumbnailBitmap(bitmap); + } + } + private void setStandardShareIntent(Uri contentUri, String mimeType) { mStandardShareIntent = getShareIntentFromType(mimeType); if (mStandardShareIntent != null) { @@ -1182,6 +1305,21 @@ public class CameraActivity extends Activity getContentResolver().registerContentObserver( MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true, mLocalVideosObserver); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + mDeveloperMenuEnabled = prefs.getBoolean(CameraSettings.KEY_DEVELOPER_MENU, false); + + Display display = getWindowManager().getDefaultDisplay(); + Point size = new Point(); + display.getSize(size); + int width = size.x; + int height = size.y; + + int lower = Math.min(width, height); + + int offset = lower * 10 / 100; + SETTING_LIST_WIDTH_1 = lower / 2 + offset; + SETTING_LIST_WIDTH_2 = lower / 2 - offset; } private void setRotationAnimation() { @@ -1201,7 +1339,12 @@ public class CameraActivity extends Activity @Override public boolean dispatchTouchEvent(MotionEvent ev) { - boolean result = super.dispatchTouchEvent(ev); + boolean result = false; + if (mFilmStripView.checkSendToModeView(ev)) { + result = mFilmStripView.sendToModeView(ev); + } + if (result == false) + result = super.dispatchTouchEvent(ev); if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { // Real deletion is postponed until the next user interaction after // the gesture that triggers deletion. Until real deletion is performed, @@ -1354,6 +1497,10 @@ public class CameraActivity extends Activity } } + public void setPreviewGestures(PreviewGestures previewGestures) { + mFilmStripView.setPreviewGestures(previewGestures); + } + public boolean isAutoRotateScreen() { return mAutoRotateScreen; } diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java index 356869b9b..7b5b2e7a6 100644 --- a/src/com/android/camera/CameraSettings.java +++ b/src/com/android/camera/CameraSettings.java @@ -106,6 +106,7 @@ public class CameraSettings { public static final String KEY_ADVANCED_FEATURES = "pref_camera_advanced_features_key"; public static final String KEY_HDR_MODE = "pref_camera_hdr_mode_key"; public static final String KEY_HDR_NEED_1X = "pref_camera_hdr_need_1x_key"; + public static final String KEY_DEVELOPER_MENU = "pref_developer_menu_key"; public static final String KEY_VIDEO_SNAPSHOT_SIZE = "pref_camera_videosnapsize_key"; public static final String KEY_VIDEO_HIGH_FRAME_RATE = "pref_camera_hfr_key"; @@ -246,13 +247,30 @@ public class CameraSettings { private final int mCameraId; private static final HashMap<Integer, String> VIDEO_ENCODER_TABLE = new HashMap<Integer, String>(); + public static final HashMap<String, Integer> + VIDEO_QUALITY_TABLE = new HashMap<String, Integer>(); static { + //video encoders VIDEO_ENCODER_TABLE.put(MediaRecorder.VideoEncoder.H263, "h263"); VIDEO_ENCODER_TABLE.put(MediaRecorder.VideoEncoder.H264, "h264"); VIDEO_ENCODER_TABLE.put(MediaRecorder.VideoEncoder.H265, "h265"); VIDEO_ENCODER_TABLE.put(MediaRecorder.VideoEncoder.MPEG_4_SP, "m4v"); - } + + //video qualities + VIDEO_QUALITY_TABLE.put("4096x2160", CamcorderProfile.QUALITY_4kDCI); + VIDEO_QUALITY_TABLE.put("3840x2160", CamcorderProfile.QUALITY_2160P); + VIDEO_QUALITY_TABLE.put("1920x1080", CamcorderProfile.QUALITY_1080P); + VIDEO_QUALITY_TABLE.put("1280x720", CamcorderProfile.QUALITY_720P); + VIDEO_QUALITY_TABLE.put("720x480", CamcorderProfile.QUALITY_480P); + VIDEO_QUALITY_TABLE.put("864x480", CamcorderProfile.QUALITY_FWVGA); + VIDEO_QUALITY_TABLE.put("800x480", CamcorderProfile.QUALITY_WVGA); + VIDEO_QUALITY_TABLE.put("640x480", CamcorderProfile.QUALITY_VGA); + VIDEO_QUALITY_TABLE.put("400x240", CamcorderProfile.QUALITY_WQVGA); + VIDEO_QUALITY_TABLE.put("352x288", CamcorderProfile.QUALITY_CIF); + VIDEO_QUALITY_TABLE.put("320x240", CamcorderProfile.QUALITY_QVGA); + VIDEO_QUALITY_TABLE.put("176x144", CamcorderProfile.QUALITY_QCIF); + } public CameraSettings(Activity activity, Parameters parameters, int cameraId, CameraInfo[] cameraInfo) { @@ -274,7 +292,7 @@ public class CameraSettings { String defaultQuality,Parameters parameters) { // When launching the camera app first time, we will set the video quality // to the first one (i.e. highest quality) in the supported list - List<String> supported = getSupportedVideoQuality(cameraId,parameters); + List<String> supported = getSupportedVideoQualities(cameraId,parameters); if (supported == null) { Log.e(TAG, "No supported video quality is found"); return defaultQuality; @@ -733,7 +751,7 @@ public class CameraSettings { } if (videoQuality != null) { - filterUnsupportedOptions(group, videoQuality, getSupportedVideoQuality( + filterUnsupportedOptions(group, videoQuality, getSupportedVideoQualities( mCameraId,mParameters)); } @@ -826,7 +844,6 @@ public class CameraSettings { exposure.setEntries(entries); exposure.setLabels(labels); exposure.setEntryValues(entryValues); - exposure.setLargeIconIds(icons); } private void buildCameraId( @@ -1151,6 +1168,20 @@ public class CameraSettings { } } + + public static ArrayList<String> getSupportedVideoQualities(int cameraId,Parameters parameters) { + ArrayList<String> supported = new ArrayList<String>(); + List<String> temp = sizeListToStringList(parameters.getSupportedVideoSizes()); + for (String videoSize : temp) { + if (VIDEO_QUALITY_TABLE.containsKey(videoSize)) { + int profile = VIDEO_QUALITY_TABLE.get(videoSize); + if (CamcorderProfile.hasProfile(cameraId, profile)) { + supported.add(videoSize); + } + } + } + return supported; + } public static int getVideoDurationInMillis(String quality) { if (VIDEO_QUALITY_MMS.equals(quality)) { return MMS_VIDEO_DURATION * 1000; diff --git a/src/com/android/camera/CountDownTimerPreference.java b/src/com/android/camera/CountDownTimerPreference.java index c256f0783..3d5f3a4c7 100644 --- a/src/com/android/camera/CountDownTimerPreference.java +++ b/src/com/android/camera/CountDownTimerPreference.java @@ -21,7 +21,7 @@ import android.util.AttributeSet; import org.codeaurora.snapcam.R; -public class CountDownTimerPreference extends ListPreference { +public class CountDownTimerPreference extends IconListPreference { private static final int[] DURATIONS = { 0, 1, 2, 3, 4, 5, 10, 15, 20, 30, 60 }; diff --git a/src/com/android/camera/IconListPreference.java b/src/com/android/camera/IconListPreference.java index eab0d613e..9c7463eda 100644 --- a/src/com/android/camera/IconListPreference.java +++ b/src/com/android/camera/IconListPreference.java @@ -31,6 +31,7 @@ public class IconListPreference extends ListPreference { private int mIconIds[]; private int mLargeIconIds[]; private int mImageIds[]; + private int mThumbnailIds[]; private boolean mUseSingleIcon; public IconListPreference(Context context, AttributeSet attrs) { @@ -46,6 +47,8 @@ public class IconListPreference extends ListPreference { R.styleable.IconListPreference_largeIcons, 0)); mImageIds = getIds(res, a.getResourceId( R.styleable.IconListPreference_images, 0)); + mThumbnailIds = getIds(res, a.getResourceId( + R.styleable.IconListPreference_thumbnails, 0)); a.recycle(); } @@ -61,6 +64,10 @@ public class IconListPreference extends ListPreference { return mLargeIconIds; } + public int[] getThumbnailIds() { + return mThumbnailIds; + } + public int[] getImageIds() { return mImageIds; } @@ -77,6 +84,10 @@ public class IconListPreference extends ListPreference { mLargeIconIds = largeIconIds; } + public void setThumbnailIds(int[] thumbnailIds) { + mThumbnailIds = thumbnailIds; + } + public void setUseSingleIcon(boolean useSingle) { mUseSingleIcon = useSingle; } @@ -99,12 +110,14 @@ public class IconListPreference extends ListPreference { IntArray iconIds = new IntArray(); IntArray largeIconIds = new IntArray(); IntArray imageIds = new IntArray(); + IntArray thumbnailIds = new IntArray(); for (int i = 0, len = entryValues.length; i < len; i++) { if (supported.indexOf(entryValues[i].toString()) >= 0) { if (mIconIds != null) iconIds.add(mIconIds[i]); if (mLargeIconIds != null) largeIconIds.add(mLargeIconIds[i]); if (mImageIds != null) imageIds.add(mImageIds[i]); + if (mThumbnailIds != null) thumbnailIds.add(mThumbnailIds[i]); } } if (mIconIds != null) mIconIds = iconIds.toArray(new int[iconIds.size()]); @@ -112,6 +125,7 @@ public class IconListPreference extends ListPreference { mLargeIconIds = largeIconIds.toArray(new int[largeIconIds.size()]); } if (mImageIds != null) mImageIds = imageIds.toArray(new int[imageIds.size()]); + if (mThumbnailIds != null) mThumbnailIds = thumbnailIds.toArray(new int[thumbnailIds.size()]); super.filterUnsupported(supported); } } diff --git a/src/com/android/camera/MenuController.java b/src/com/android/camera/MenuController.java new file mode 100644 index 000000000..333a5f2aa --- /dev/null +++ b/src/com/android/camera/MenuController.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright (C) 2012 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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import android.app.Activity; +import android.util.Log; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.ImageView; + +import com.android.camera.CameraPreference.OnPreferenceChangedListener; +import com.android.camera.ui.RotateImageView; + +public class MenuController { + + private static String TAG = "CAM_menucontrol"; + + protected static final int MODE_PHOTO = 0; + protected static final int MODE_VIDEO = 1; + + protected Activity mActivity; + protected PreferenceGroup mPreferenceGroup; + protected OnPreferenceChangedListener mListener; + protected List<IconListPreference> mPreferences; + protected Map<IconListPreference, View> mPreferenceMap; + private Map<IconListPreference, String> mOverrides; + + public void setListener(OnPreferenceChangedListener listener) { + mListener = listener; + } + + public MenuController(Activity activity) { + mActivity = activity; + mPreferences = new ArrayList<IconListPreference>(); + mPreferenceMap = new HashMap<IconListPreference, View>(); + mOverrides = new HashMap<IconListPreference, String>(); + } + + public void initialize(PreferenceGroup group) { + mPreferenceMap.clear(); + setPreferenceGroup(group); + mPreferences.clear(); + mOverrides.clear(); + } + + public void onSettingChanged(ListPreference pref) { + if (mListener != null) { + mListener.onSharedPreferenceChanged(); + } + } + + protected void setCameraId(int cameraId) { + ListPreference pref = mPreferenceGroup.findPreference(CameraSettings.KEY_CAMERA_ID); + pref.setValue("" + cameraId); + } + + public void setPreferenceGroup(PreferenceGroup group) { + mPreferenceGroup = group; + } + + public void reloadPreferences() { + mPreferenceGroup.reloadValue(); + for (IconListPreference pref : mPreferences) { + reloadPreference(pref); + } + } + + protected void reloadPreference(IconListPreference pref) { + View switcher = mPreferenceMap.get(pref); + if (switcher == null) + return; + String overrideValue = mOverrides.get(pref); + int index; + if (overrideValue == null) { + index = pref.findIndexOfValue(pref.getValue()); + } else { + index = pref.findIndexOfValue(overrideValue); + if (index == -1) { + // Avoid the crash if camera driver has bugs. + Log.e(TAG, "Fail to find override value=" + overrideValue); + pref.print(); + return; + } + } + ImageView iv = (ImageView) ((FrameLayout) switcher).getChildAt(0); + iv.setImageResource(pref.getLargeIconIds()[index]); + + } + + // Scene mode may override other camera settings (ex: flash mode). + public void overrideSettings(final String... keyvalues) { + if (keyvalues.length % 2 != 0) { + throw new IllegalArgumentException(); + } + for (IconListPreference pref : mPreferences) { + override(pref, keyvalues); + } + } + + private void override(IconListPreference pref, final String... keyvalues) { + mOverrides.remove(pref); + for (int i = 0; i < keyvalues.length; i += 2) { + String key = keyvalues[i]; + String value = keyvalues[i + 1]; + if (key.equals(pref.getKey())) { + mOverrides.put(pref, value); + break; + } + } + reloadPreference(pref); + } +} diff --git a/src/com/android/camera/OnScreenIndicators.java b/src/com/android/camera/OnScreenIndicators.java index 5f5dbc311..67cbad1c9 100644 --- a/src/com/android/camera/OnScreenIndicators.java +++ b/src/com/android/camera/OnScreenIndicators.java @@ -63,6 +63,12 @@ public class OnScreenIndicators { R.id.menu_timer_indicator); mWBIndicator = (ImageView) onScreenIndicatorsView.findViewById( R.id.menu_wb_indicator); + mExposureIndicator.setVisibility(View.GONE); + mFlashIndicator.setVisibility(View.GONE); + mSceneIndicator.setVisibility(View.GONE); + mLocationIndicator.setVisibility(View.GONE); + mTimerIndicator.setVisibility(View.GONE); + mWBIndicator.setVisibility(View.GONE); } /** @@ -120,7 +126,7 @@ public class OnScreenIndicators { id = R.drawable.ic_indicator_ev_p3; break; } - mExposureIndicator.setImageResource(id); + mExposureIndicator.setImageResource(R.drawable.ic_settings); } public void updateWBIndicator(int wbIndex) { diff --git a/src/com/android/camera/PhotoMenu.java b/src/com/android/camera/PhotoMenu.java index 629d91526..c8522ee94 100644 --- a/src/com/android/camera/PhotoMenu.java +++ b/src/com/android/camera/PhotoMenu.java @@ -18,105 +18,154 @@ package com.android.camera; import java.util.Locale; +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.content.Context; +import android.content.SharedPreferences; import android.content.res.Resources; import android.hardware.Camera.Parameters; - -import com.android.camera.ui.AbstractSettingPopup; -import com.android.camera.ui.CountdownTimerPopup; -import com.android.camera.ui.ListPrefSettingPopup; -import com.android.camera.ui.MoreSettingPopup; -import com.android.camera.ui.PieItem; -import com.android.camera.ui.PieItem.OnClickListener; -import com.android.camera.ui.PieRenderer; -import org.codeaurora.snapcam.R; -import android.content.Context; +import android.graphics.Rect; +import android.preference.PreferenceManager; +import android.util.Log; import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewPropertyAnimator; +import android.widget.ListView; import android.widget.Toast; -import android.util.Log; +import android.widget.TextView; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.FrameLayout; +import android.widget.FrameLayout.LayoutParams; -import java.util.Locale; +import com.android.camera.CameraPreference.OnPreferenceChangedListener; +import com.android.camera.ui.CameraControls; +import com.android.camera.ui.CountdownTimerPopup; +import com.android.camera.ui.ListSubMenu; +import com.android.camera.ui.ListMenu; +import com.android.camera.ui.RotateImageView; +import org.codeaurora.snapcam.R; +import android.widget.HorizontalScrollView; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.Display; +import com.android.camera.util.CameraUtil; -public class PhotoMenu extends PieController - implements MoreSettingPopup.Listener, - CountdownTimerPopup.Listener, - ListPrefSettingPopup.Listener { +public class PhotoMenu extends MenuController + implements ListMenu.Listener, + CountdownTimerPopup.Listener, + ListSubMenu.Listener { private static String TAG = "PhotoMenu"; private final String mSettingOff; private String[] mOtherKeys1; private String[] mOtherKeys2; - private String[] mOtherKeys3; - private MoreSettingPopup mPopup1; - private MoreSettingPopup mPopup2; - private MoreSettingPopup mPopup3; + private ListMenu mListMenu; + private View mPreviewMenu; private static final int POPUP_NONE = 0; private static final int POPUP_FIRST_LEVEL = 1; private static final int POPUP_SECOND_LEVEL = 2; + private static final int POPUP_IN_ANIMATION = 3; + private static final int PREVIEW_MENU_NONE = 0; + private static final int PREVIEW_MENU_IN_ANIMATION = 1; + private static final int PREVIEW_MENU_ON = 2; + private static final int MODE_SCENE = 0; + private static final int MODE_FILTER = 1; + private static final int DEVELOPER_MENU_TOUCH_COUNT = 10; + private int mSceneStatus; + private View mHdrSwitcher; + private View mFrontBackSwitcher; + private View mSceneModeSwitcher; + private View mFilterModeSwitcher; private PhotoUI mUI; private int mPopupStatus; - private AbstractSettingPopup mPopup; + private int mPreviewMenuStatus; + private ListSubMenu mListSubMenu; private CameraActivity mActivity; - private int popupNum = 0; - private PieItem mHdrItem = null; - private PieItem mHdrPlusItem = null; private String mPrevSavedCDS; private boolean mIsTNREnabled = false; private boolean mIsCDSUpdated = false; + private int privateCounter = 0; + private static final int ANIMATION_DURATION = 300; + private static final int CLICK_THRESHOLD = 200; + private int previewMenuSize; - public PhotoMenu(CameraActivity activity, PhotoUI ui, PieRenderer pie) { - super(activity, pie); + public PhotoMenu(CameraActivity activity, PhotoUI ui) { + super(activity); mUI = ui; mSettingOff = activity.getString(R.string.setting_off_value); mActivity = activity; + mFrontBackSwitcher = ui.getRootView().findViewById(R.id.front_back_switcher); + mHdrSwitcher = ui.getRootView().findViewById(R.id.hdr_switcher); + mSceneModeSwitcher = ui.getRootView().findViewById(R.id.scene_mode_switcher); + mFilterModeSwitcher = ui.getRootView().findViewById(R.id.filter_mode_switcher); } public void initialize(PreferenceGroup group) { super.initialize(group); - mPopup = null; - mPopup1 = null; - mPopup2 = null; - mPopup3 = null; + mListSubMenu = null; + mListMenu = null; mPopupStatus = POPUP_NONE; - PieItem item = null; - popupNum = 0; + mPreviewMenuStatus = POPUP_NONE; final Resources res = mActivity.getResources(); Locale locale = res.getConfiguration().locale; // The order is from left to right in the menu. - // HDR+ (GCam). - if (group.findPreference(CameraSettings.KEY_CAMERA_HDR_PLUS) != null) { - mHdrPlusItem = makeSwitchItem(CameraSettings.KEY_CAMERA_HDR_PLUS, true); - mRenderer.addItem(mHdrPlusItem); - } + initSceneModeButton(mSceneModeSwitcher); + initFilterModeButton(mFilterModeSwitcher); + mHdrSwitcher.setVisibility(View.INVISIBLE); + mFrontBackSwitcher.setVisibility(View.INVISIBLE); // HDR. if (group.findPreference(CameraSettings.KEY_CAMERA_HDR) != null) { - mHdrItem = makeSwitchItem(CameraSettings.KEY_CAMERA_HDR, true); - mRenderer.addItem(mHdrItem); + mHdrSwitcher.setVisibility(View.VISIBLE); + initSwitchItem(CameraSettings.KEY_CAMERA_HDR, mHdrSwitcher); + } else { + mHdrSwitcher.setVisibility(View.INVISIBLE); } mOtherKeys1 = new String[] { - CameraSettings.KEY_SCENE_MODE, CameraSettings.KEY_RECORD_LOCATION, CameraSettings.KEY_PICTURE_SIZE, - CameraSettings.KEY_HISTOGRAM, CameraSettings.KEY_JPEG_QUALITY, - CameraSettings.KEY_ZSL, CameraSettings.KEY_TIMER, - CameraSettings.KEY_TIMER_SOUND_EFFECTS, CameraSettings.KEY_CAMERA_SAVEPATH, CameraSettings.KEY_LONGSHOT, - CameraSettings.KEY_AUTO_HDR, - CameraSettings.KEY_HDR_MODE, - CameraSettings.KEY_HDR_NEED_1X, - CameraSettings.KEY_CDS_MODE, - CameraSettings.KEY_TNR_MODE + CameraSettings.KEY_FACE_DETECTION, + CameraSettings.KEY_ISO, + CameraSettings.KEY_EXPOSURE, + CameraSettings.KEY_WHITE_BALANCE, + CameraSettings.KEY_FLASH_MODE, + CameraSettings.KEY_FOCUS_MODE, + CameraSettings.KEY_REDEYE_REDUCTION }; mOtherKeys2 = new String[] { - CameraSettings.KEY_COLOR_EFFECT, + CameraSettings.KEY_RECORD_LOCATION, + CameraSettings.KEY_PICTURE_SIZE, + CameraSettings.KEY_JPEG_QUALITY, + CameraSettings.KEY_TIMER, + CameraSettings.KEY_CAMERA_SAVEPATH, + CameraSettings.KEY_LONGSHOT, CameraSettings.KEY_FACE_DETECTION, + CameraSettings.KEY_ISO, + CameraSettings.KEY_EXPOSURE, + CameraSettings.KEY_WHITE_BALANCE, + CameraSettings.KEY_FLASH_MODE, + CameraSettings.KEY_FOCUS_MODE, + CameraSettings.KEY_REDEYE_REDUCTION, + CameraSettings.KEY_AUTO_HDR, + CameraSettings.KEY_HDR_MODE, + CameraSettings.KEY_HDR_NEED_1X, + CameraSettings.KEY_CDS_MODE, + CameraSettings.KEY_TNR_MODE, + CameraSettings.KEY_HISTOGRAM, + CameraSettings.KEY_ZSL, + CameraSettings.KEY_TIMER_SOUND_EFFECTS, CameraSettings.KEY_FACE_RECOGNITION, CameraSettings.KEY_TOUCH_AF_AEC, CameraSettings.KEY_SELECTABLE_ZONE_AF, @@ -124,106 +173,294 @@ public class PhotoMenu extends PieController CameraSettings.KEY_SATURATION, CameraSettings.KEY_CONTRAST, CameraSettings.KEY_SHARPNESS, - CameraSettings.KEY_AUTOEXPOSURE - }; - - mOtherKeys3 = new String[] { + CameraSettings.KEY_AUTOEXPOSURE, CameraSettings.KEY_ANTIBANDING, - CameraSettings.KEY_ISO, CameraSettings.KEY_DENOISE, CameraSettings.KEY_ADVANCED_FEATURES, - CameraSettings.KEY_EXPOSURE, - CameraSettings.KEY_WHITE_BALANCE, - CameraSettings.KEY_FLASH_MODE, - CameraSettings.KEY_FOCUS_MODE, - CameraSettings.KEY_REDEYE_REDUCTION, CameraSettings.KEY_AE_BRACKET_HDR, CameraSettings.KEY_MANUAL_EXPOSURE, CameraSettings.KEY_MANUAL_WB, CameraSettings.KEY_MANUAL_FOCUS }; - PieItem item1 = makeItem(R.drawable.ic_settings_holo_light_01); - item1.setLabel(mActivity.getResources().getString(R.string.camera_menu_more_label)); - item1.setOnClickListener(new OnClickListener() { - @Override - public void onClick(PieItem item) { - if (mPopup1 == null || mPopupStatus != POPUP_FIRST_LEVEL){ + initSwitchItem(CameraSettings.KEY_CAMERA_ID, mFrontBackSwitcher); + } + + @Override + // Hit when an item in a popup gets selected + public void onListPrefChanged(ListPreference pref) { + animateFadeOut(mListSubMenu, 2); + onSettingChanged(pref); + ((ListMenu) mListMenu).resetHighlight(); + } + + public boolean handleBackKey() { + if (mPreviewMenuStatus == PREVIEW_MENU_ON) { + animateSlideOut(mPreviewMenu); + return true; + } + if (mPopupStatus == POPUP_NONE) + return false; + if (mPopupStatus == POPUP_FIRST_LEVEL) { + animateSlideOut(mListMenu, 1); + } else if (mPopupStatus == POPUP_SECOND_LEVEL) { + animateFadeOut(mListSubMenu, 2); + ((ListMenu) mListMenu).resetHighlight(); + } + return true; + } + + public void closeSceneMode() { + mUI.removeSceneModeMenu(); + } + + public void tryToCloseSubList() { + if (mListMenu != null) + ((ListMenu) mListMenu).resetHighlight(); + + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } + + private void animateFadeOut(final ListView v, final int level) { + if (v == null || mPopupStatus == POPUP_IN_ANIMATION) + return; + mPopupStatus = POPUP_IN_ANIMATION; + + ViewPropertyAnimator vp = v.animate(); + vp.alpha(0f).setDuration(ANIMATION_DURATION); + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); initializePopup(); - mPopupStatus = POPUP_FIRST_LEVEL; + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; } - mUI.showPopup(mPopup1); - popupNum = 1; } - }); - mRenderer.addItem(item1); - - PieItem item2 = makeItem(R.drawable.ic_settings_holo_light_02); - item2.setLabel(mActivity.getResources().getString(R.string.camera_menu_more_label)); - item2.setOnClickListener(new OnClickListener() { - @Override - public void onClick(PieItem item) { - if (mPopup2 == null || mPopupStatus != POPUP_FIRST_LEVEL) { + + @Override + public void onAnimationCancel(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); mPopupStatus = POPUP_FIRST_LEVEL; } - mUI.showPopup(mPopup2); - popupNum = 2; + } }); - mRenderer.addItem(item2); - - PieItem item3= makeItem(R.drawable.ic_settings_holo_light_03); - item3.setLabel(mActivity.getResources().getString(R.string.camera_menu_more_label)); - item3.setOnClickListener(new OnClickListener() { - @Override - public void onClick(PieItem item) { - if (mPopup3 == null || mPopupStatus != POPUP_FIRST_LEVEL) { + vp.start(); + } + + private void animateSlideOut(final ListView v, final int level) { + if (v == null || mPopupStatus == POPUP_IN_ANIMATION) + return; + mPopupStatus = POPUP_IN_ANIMATION; + + ViewPropertyAnimator vp = v.animate(); + vp.translationX(v.getX() - v.getWidth()).setDuration(ANIMATION_DURATION); + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); mPopupStatus = POPUP_FIRST_LEVEL; } - mUI.showPopup(mPopup3); - popupNum = 3; } - }); - mRenderer.addItem(item3); - // Camera switcher. - if (group.findPreference(CameraSettings.KEY_CAMERA_ID) != null) { - item = makeSwitchItem(CameraSettings.KEY_CAMERA_ID, false); - final PieItem fitem = item; - item.setOnClickListener(new OnClickListener() { - @Override - public void onClick(PieItem item) { - // Find the index of next camera. - ListPreference pref = mPreferenceGroup - .findPreference(CameraSettings.KEY_CAMERA_ID); - if (pref != null) { - int index = pref.findIndexOfValue(pref.getValue()); - CharSequence[] values = pref.getEntryValues(); - index = (index + 1) % values.length; - pref.setValueIndex(index); - mListener.onCameraPickerClicked(index); - } - updateItem(fitem, CameraSettings.KEY_CAMERA_ID); + @Override + public void onAnimationCancel(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); } - }); - mRenderer.addItem(item); + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + + } + }); + vp.start(); + } + + public void animateFadeIn(final ListView v) { + ViewPropertyAnimator vp = v.animate(); + vp.alpha(0.85f).setDuration(ANIMATION_DURATION); + vp.start(); + } + + public void animateSlideIn(final View v, int delta, boolean settingMenu) { + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + boolean portrait = (rotation == 0) || (rotation == 180); + if (settingMenu) + portrait = true; + ViewPropertyAnimator vp = v.animate(); + if (portrait) { + float dest = v.getX(); + v.setX(dest - delta); + vp.translationX(dest).setDuration(ANIMATION_DURATION); + } + else { + float dest = v.getY(); + v.setY(dest + delta); + vp.translationY(dest).setDuration(ANIMATION_DURATION); } + vp.start(); } - @Override - // Hit when an item in a popup gets selected - public void onListPrefChanged(ListPreference pref) { - if (mPopup != null && mPopup1 != null && mPopup2 != null && mPopup3 != null) { - mUI.dismissPopup(); + public void animateSlideOutPreviewMenu() { + if (mPreviewMenu == null) + return; + animateSlideOut(mPreviewMenu); + } + + private void animateSlideOut(final View v) { + if (v == null || mPreviewMenuStatus == PREVIEW_MENU_IN_ANIMATION) + return; + mPreviewMenuStatus = PREVIEW_MENU_IN_ANIMATION; + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; } - onSettingChanged(pref); + boolean portrait = (rotation == 0) || (rotation == 180); + ViewPropertyAnimator vp = v.animate(); + if (portrait) { + vp.translationX(v.getX() - v.getWidth()).setDuration(ANIMATION_DURATION); + + } else { + vp.translationY(v.getY() + v.getHeight()).setDuration(ANIMATION_DURATION); + + } + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + closeSceneMode(); + mPreviewMenuStatus = PREVIEW_MENU_NONE; + } + + @Override + public void onAnimationCancel(Animator animation) { + closeSceneMode(); + mPreviewMenuStatus = PREVIEW_MENU_NONE; + + } + }); + vp.start(); + } + + private void buttonSetEnabled(View v, boolean enable) { + v.setEnabled(enable); + if (v instanceof ViewGroup) { + View v2 = ((ViewGroup) v).getChildAt(0); + if (v2 != null) + v2.setEnabled(enable); + + } + + } + + public boolean isOverMenu(MotionEvent ev) { + if (mPopupStatus == POPUP_NONE || mPopupStatus == POPUP_IN_ANIMATION) + return false; + if (mUI.getMenuLayout() == null) + return false; + Rect rec = new Rect(); + mUI.getMenuLayout().getChildAt(0).getHitRect(rec); + return rec.contains((int) ev.getX(), (int) ev.getY()); + } + + public boolean isOverPreviewMenu(MotionEvent ev) { + if (mPreviewMenuStatus != PREVIEW_MENU_ON) + return false; + if (mUI.getPreviewMenuLayout() == null) + return false; + Rect rec = new Rect(); + mUI.getPreviewMenuLayout().getChildAt(0).getHitRect(rec); + rec.top += (int) mUI.getPreviewMenuLayout().getY(); + rec.bottom += (int) mUI.getPreviewMenuLayout().getY(); + return rec.contains((int) ev.getX(), (int) ev.getY()); + } + + public boolean isMenuBeingShown() { + return mPopupStatus != POPUP_NONE; + } + + public boolean isMenuBeingAnimated() { + return mPopupStatus == POPUP_IN_ANIMATION; + } + + public boolean isPreviewMenuBeingShown() { + return mPreviewMenuStatus == PREVIEW_MENU_ON; + } + + public boolean isPreviewMenuBeingAnimated() { + return mPreviewMenuStatus == PREVIEW_MENU_IN_ANIMATION; + } + + public boolean sendTouchToPreviewMenu(MotionEvent ev) { + return mUI.sendTouchToPreviewMenu(ev); + } + + public boolean sendTouchToMenu(MotionEvent ev) { + return mUI.sendTouchToMenu(ev); } @Override - public void overrideSettings(final String ... keyvalues) { - if (mPopup1 != null) { + public void overrideSettings(final String... keyvalues) { + if (mListMenu != null) { ListPreference pref_tnr = mPreferenceGroup.findPreference(CameraSettings.KEY_TNR_MODE); ListPreference pref_cds = mPreferenceGroup.findPreference(CameraSettings.KEY_CDS_MODE); @@ -234,11 +471,11 @@ public class PhotoMenu extends PieController mPrevSavedCDS = cds; } - mPopup1.setPreferenceEnabled(CameraSettings.KEY_TNR_MODE, false); + mListMenu.setPreferenceEnabled(CameraSettings.KEY_TNR_MODE, false); if ((tnr != null) && !mActivity.getString(R.string. pref_camera_tnr_default).equals(tnr)) { - mPopup1.setPreferenceEnabled(CameraSettings.KEY_CDS_MODE, false); - mPopup1.overrideSettings(CameraSettings.KEY_CDS_MODE, + mListMenu.setPreferenceEnabled(CameraSettings.KEY_CDS_MODE, false); + mListMenu.overrideSettings(CameraSettings.KEY_CDS_MODE, mActivity.getString(R.string.pref_camera_cds_value_off)); mIsTNREnabled = true; if (!mIsCDSUpdated) { @@ -248,187 +485,547 @@ public class PhotoMenu extends PieController mIsCDSUpdated = true; } } else if (tnr != null) { - mPopup1.setPreferenceEnabled(CameraSettings.KEY_CDS_MODE, true); + mListMenu.setPreferenceEnabled(CameraSettings.KEY_CDS_MODE, true); if (mIsTNREnabled && mPrevSavedCDS != cds) { - mPopup1.overrideSettings(CameraSettings.KEY_CDS_MODE, mPrevSavedCDS); + mListMenu.overrideSettings(CameraSettings.KEY_CDS_MODE, mPrevSavedCDS); mIsTNREnabled = false; mIsCDSUpdated = false; } } } - + for (int i = 0; i < keyvalues.length; i += 2) { + if (keyvalues[i].equals(CameraSettings.KEY_SCENE_MODE)) { + buttonSetEnabled(mSceneModeSwitcher, keyvalues[i + 1] == null); + } + } super.overrideSettings(keyvalues); - if ((mPopup1 == null) || (mPopup2 == null) || (mPopup3 == null)) initializePopup(); - - mPopup1.overrideSettings(keyvalues); - mPopup2.overrideSettings(keyvalues); - mPopup3.overrideSettings(keyvalues); + if ((mListMenu == null)) + initializePopup(); + mListMenu.overrideSettings(keyvalues); } protected void initializePopup() { - LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - MoreSettingPopup popup1 = (MoreSettingPopup) inflater.inflate( - R.layout.more_setting_popup, null, false); - popup1.setSettingChangedListener(this); - popup1.initialize(mPreferenceGroup, mOtherKeys1); - if (mActivity.isSecureCamera()) { - // Prevent location preference from getting changed in secure camera mode - popup1.setPreferenceEnabled(CameraSettings.KEY_RECORD_LOCATION,false); - } - mPopup1 = popup1; - - MoreSettingPopup popup2 = (MoreSettingPopup) inflater.inflate( - R.layout.more_setting_popup, null, false); - popup2.setSettingChangedListener(this); - popup2.initialize(mPreferenceGroup, mOtherKeys2); - mPopup2 = popup2; - - MoreSettingPopup popup3 = (MoreSettingPopup) inflater.inflate( - R.layout.more_setting_popup, null, false); - popup3.setSettingChangedListener(this); - popup3.initialize(mPreferenceGroup, mOtherKeys3); - mPopup3 = popup3; - - ListPreference pref = mPreferenceGroup.findPreference( - CameraSettings.KEY_SCENE_MODE); - String sceneMode = (pref != null) ? pref.getValue() : null; - pref = mPreferenceGroup.findPreference(CameraSettings.KEY_FACE_DETECTION); - String faceDetection = (pref != null) ? pref.getValue() : null; - pref = mPreferenceGroup.findPreference(CameraSettings.KEY_ZSL); - String zsl = (pref != null) ? pref.getValue() : null; - pref = mPreferenceGroup.findPreference (CameraSettings.KEY_AUTO_HDR); - String autohdr = (pref != null) ? pref.getValue() : null; - if (((sceneMode != null) && !Parameters.SCENE_MODE_AUTO.equals(sceneMode)) - || ((autohdr != null) && autohdr.equals("enable"))) { - popup3.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE,false); - popup2.setPreferenceEnabled(CameraSettings.KEY_AUTOEXPOSURE,false); - popup2.setPreferenceEnabled(CameraSettings.KEY_TOUCH_AF_AEC,false); - popup2.setPreferenceEnabled(CameraSettings.KEY_SATURATION,false); - popup2.setPreferenceEnabled(CameraSettings.KEY_CONTRAST,false); - popup2.setPreferenceEnabled(CameraSettings.KEY_SHARPNESS,false); - popup2.setPreferenceEnabled(CameraSettings.KEY_COLOR_EFFECT,false); - popup3.setPreferenceEnabled(CameraSettings.KEY_FLASH_MODE,false); - popup3.setPreferenceEnabled(CameraSettings.KEY_WHITE_BALANCE,false); - popup3.setPreferenceEnabled(CameraSettings.KEY_EXPOSURE,false); - } - if ((autohdr != null) && autohdr.equals("enable")) { - popup1.setPreferenceEnabled(CameraSettings.KEY_SCENE_MODE,false); - } - if ((zsl != null) && Parameters.ZSL_ON.equals(zsl)) { - popup3.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE,false); - popup3.setPreferenceEnabled(CameraSettings.KEY_MANUAL_EXPOSURE,false); - popup3.setPreferenceEnabled(CameraSettings.KEY_MANUAL_WB,false); - popup3.setPreferenceEnabled(CameraSettings.KEY_MANUAL_FOCUS,false); - } - if ((faceDetection != null) && !Parameters.FACE_DETECTION_ON.equals(faceDetection)){ - popup2.setPreferenceEnabled(CameraSettings.KEY_FACE_RECOGNITION,false); - } - popup1.setPreferenceEnabled(CameraSettings.KEY_ZSL, !mUI.isCountingDown()); - - pref = mPreferenceGroup.findPreference(CameraSettings.KEY_ADVANCED_FEATURES); - String advancedFeatures = (pref != null) ? pref.getValue() : null; - - String ubiFocusOn = mActivity.getString(R.string. - pref_camera_advanced_feature_value_ubifocus_on); - String reFocusOn = mActivity.getString(R.string. - pref_camera_advanced_feature_value_refocus_on); - String chromaFlashOn = mActivity.getString(R.string. - pref_camera_advanced_feature_value_chromaflash_on); - String optiZoomOn = mActivity.getString(R.string. - pref_camera_advanced_feature_value_optizoom_on); - String fssrOn = mActivity.getString(R.string. - pref_camera_advanced_feature_value_FSSR_on); - String truePortraitOn = mActivity.getString(R.string. - pref_camera_advanced_feature_value_trueportrait_on); - String multiTouchFocusOn = mActivity.getString(R.string. - pref_camera_advanced_feature_value_multi_touch_focus_on); - - if ((zsl != null) && Parameters.ZSL_OFF.equals(zsl)) { - popup3.overrideSettings(CameraSettings.KEY_ADVANCED_FEATURES, - mActivity.getString(R.string.pref_camera_advanced_feature_default)); - - popup3.setPreferenceEnabled(CameraSettings.KEY_ADVANCED_FEATURES,false); - if (mHdrItem != null) { - mHdrItem.setEnabled(true); - } - if (mHdrPlusItem != null) { - mHdrPlusItem.setEnabled(true); - } - } else { - if ((advancedFeatures != null) && (advancedFeatures.equals(ubiFocusOn) || - advancedFeatures.equals(chromaFlashOn) || - advancedFeatures.equals(reFocusOn) || - advancedFeatures.equals(optiZoomOn) || - advancedFeatures.equals(fssrOn) || - advancedFeatures.equals(truePortraitOn) || - advancedFeatures.equals(multiTouchFocusOn))) { - popup3.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE,false); - popup3.setPreferenceEnabled(CameraSettings.KEY_FLASH_MODE,false); - popup3.setPreferenceEnabled(CameraSettings.KEY_AE_BRACKET_HDR,false); - popup3.setPreferenceEnabled(CameraSettings.KEY_REDEYE_REDUCTION,false); - popup3.setPreferenceEnabled(CameraSettings.KEY_EXPOSURE,false); - popup2.setPreferenceEnabled(CameraSettings.KEY_COLOR_EFFECT,false); - popup2.setPreferenceEnabled(CameraSettings.KEY_TOUCH_AF_AEC,false); - popup1.setPreferenceEnabled(CameraSettings.KEY_SCENE_MODE,false); - - setPreference(CameraSettings.KEY_CAMERA_HDR, mSettingOff); - - if (mHdrItem != null) { - mHdrItem.setEnabled(false); - } - if (mHdrPlusItem != null) { - mHdrPlusItem.setEnabled(false); - } - } else { - if (mHdrItem != null) { - mHdrItem.setEnabled(true); - } - if (mHdrPlusItem != null) { - mHdrPlusItem.setEnabled(true); - } - } - } - - if (mListener != null) { - mListener.onSharedPreferenceChanged(); - } - } + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + ListMenu popup1 = (ListMenu) inflater.inflate( + R.layout.list_menu, null, false); + + popup1.setSettingChangedListener(this); + + String[] keys = mOtherKeys1; + if (mActivity.isDeveloperMenuEnabled()) + keys = mOtherKeys2; + popup1.initialize(mPreferenceGroup, keys); + if (mActivity.isSecureCamera()) { + // Prevent location preference from getting changed in secure camera + // mode + popup1.setPreferenceEnabled(CameraSettings.KEY_RECORD_LOCATION, false); + } + mListMenu = popup1; + + ListPreference pref = mPreferenceGroup.findPreference( + CameraSettings.KEY_SCENE_MODE); + String sceneMode = (pref != null) ? pref.getValue() : null; + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_FACE_DETECTION); + String faceDetection = (pref != null) ? pref.getValue() : null; + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_ZSL); + String zsl = (pref != null) ? pref.getValue() : null; + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_AUTO_HDR); + String autohdr = (pref != null) ? pref.getValue() : null; + if (((sceneMode != null) && !Parameters.SCENE_MODE_AUTO.equals(sceneMode)) + || ((autohdr != null) && autohdr.equals("enable"))) { + popup1.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_AUTOEXPOSURE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_TOUCH_AF_AEC, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_SATURATION, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_CONTRAST, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_SHARPNESS, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_COLOR_EFFECT, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_FLASH_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_WHITE_BALANCE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_EXPOSURE, false); + } + if ((autohdr != null) && autohdr.equals("enable")) { + popup1.setPreferenceEnabled(CameraSettings.KEY_SCENE_MODE, false); + } + if ((zsl != null) && Parameters.ZSL_ON.equals(zsl)) { + popup1.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_MANUAL_EXPOSURE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_MANUAL_WB, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_MANUAL_FOCUS, false); + } + if ((faceDetection != null) && !Parameters.FACE_DETECTION_ON.equals(faceDetection)) { + popup1.setPreferenceEnabled(CameraSettings.KEY_FACE_RECOGNITION, false); + } + popup1.setPreferenceEnabled(CameraSettings.KEY_ZSL, !mUI.isCountingDown()); + + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_ADVANCED_FEATURES); + String advancedFeatures = (pref != null) ? pref.getValue() : null; + + String ubiFocusOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_ubifocus_on); + String reFocusOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_refocus_on); + String chromaFlashOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_chromaflash_on); + String optiZoomOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_optizoom_on); + String fssrOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_FSSR_on); + String truePortraitOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_trueportrait_on); + String multiTouchFocusOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_multi_touch_focus_on); + + if ((zsl != null) && Parameters.ZSL_OFF.equals(zsl)) { + popup1.overrideSettings(CameraSettings.KEY_ADVANCED_FEATURES, + mActivity.getString(R.string.pref_camera_advanced_feature_default)); + + popup1.setPreferenceEnabled(CameraSettings.KEY_ADVANCED_FEATURES, false); + if (mHdrSwitcher.getVisibility() == View.VISIBLE) { + buttonSetEnabled(mHdrSwitcher, true); + } + } else { + if ((advancedFeatures != null) && (advancedFeatures.equals(ubiFocusOn) || + advancedFeatures.equals(chromaFlashOn) || + advancedFeatures.equals(reFocusOn) || + advancedFeatures.equals(optiZoomOn) || + advancedFeatures.equals(fssrOn) || + advancedFeatures.equals(truePortraitOn) || + advancedFeatures.equals(multiTouchFocusOn))) { + popup1.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_FLASH_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_AE_BRACKET_HDR, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_REDEYE_REDUCTION, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_EXPOSURE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_COLOR_EFFECT, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_TOUCH_AF_AEC, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_SCENE_MODE, false); + + setPreference(CameraSettings.KEY_CAMERA_HDR, mSettingOff); + if (mHdrSwitcher.getVisibility() == View.VISIBLE) { + buttonSetEnabled(mHdrSwitcher, false); + } + } else { + if (mHdrSwitcher.getVisibility() == View.VISIBLE) { + buttonSetEnabled(mHdrSwitcher, true); + } + } + } + + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_SCENE_MODE); + if (pref != null) { + if (notSame(pref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)) { + buttonSetEnabled(mFilterModeSwitcher, false); + } else { + buttonSetEnabled(mFilterModeSwitcher, true); + } + } + + if (mListener != null) { + mListener.onSharedPreferenceChanged(); + } + } + + public void initSwitchItem(final String prefKey, View switcher) { + final IconListPreference pref = + (IconListPreference) mPreferenceGroup.findPreference(prefKey); + if (pref == null) + return; + + int[] iconIds = pref.getLargeIconIds(); + int resid = -1; + int index = pref.findIndexOfValue(pref.getValue()); + if (!pref.getUseSingleIcon() && iconIds != null) { + // Each entry has a corresponding icon. + resid = iconIds[index]; + } else { + // The preference only has a single icon to represent it. + resid = pref.getSingleIcon(); + } + ImageView iv = (ImageView) ((FrameLayout) switcher).getChildAt(0); + iv.setImageResource(resid); + switcher.setVisibility(View.VISIBLE); + mPreferences.add(pref); + mPreferenceMap.put(pref, switcher); + switcher.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(prefKey); + if (pref == null) + return; + int index = pref.findIndexOfValue(pref.getValue()); + CharSequence[] values = pref.getEntryValues(); + index = (index + 1) % values.length; + pref.setValueIndex(index); + ImageView iv = (ImageView) ((FrameLayout) v).getChildAt(0); + iv.setImageResource(((IconListPreference) pref).getLargeIconIds()[index]); + if (prefKey.equals(CameraSettings.KEY_CAMERA_ID)) + mListener.onCameraPickerClicked(index); + reloadPreference(pref); + onSettingChanged(pref); + } + }); + } + + public void initSceneModeButton(View button) { + button.setVisibility(View.INVISIBLE); + updateSceneModeIcon(); + button.setVisibility(View.VISIBLE); + button.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + addSceneMode(); + View view = mUI.getPreviewMenuLayout().getChildAt(0); + animateSlideIn(view, previewMenuSize, false); + } + }); + } + + public void addModeBack() { + if (mSceneStatus == MODE_SCENE) { + addSceneMode(); + } + if (mSceneStatus == MODE_FILTER) { + addFilterMode(); + } + } + + public void addSceneMode() { + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_SCENE_MODE); + if (pref == null) + return; + + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + + CharSequence[] entries = pref.getEntries(); + + int[] thumbnails = pref.getThumbnailIds(); + + Resources r = mActivity.getResources(); + int height = (int) (r.getDimension(R.dimen.scene_mode_height) + 2 + * r.getDimension(R.dimen.scene_mode_padding) + 1); + int width = (int) (r.getDimension(R.dimen.scene_mode_width) + 2 + * r.getDimension(R.dimen.scene_mode_padding) + 1); + + int gridRes = 0; + boolean portrait = (rotation == 0) || (rotation == 180); + int size = height; + if (portrait) { + gridRes = R.layout.vertical_grid; + size = width; + } else { + gridRes = R.layout.horiz_grid; + } + previewMenuSize = size; + mUI.hideUI(); + mPreviewMenuStatus = PREVIEW_MENU_ON; + mSceneStatus = MODE_SCENE; + + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + FrameLayout basic = (FrameLayout) inflater.inflate( + gridRes, null, false); + + mUI.dismissSceneModeMenu(); + LinearLayout previewMenuLayout = new LinearLayout(mActivity); + mUI.setPreviewMenuLayout(previewMenuLayout); + ViewGroup.LayoutParams params = null; + if (portrait) { + params = new ViewGroup.LayoutParams(size, LayoutParams.MATCH_PARENT); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + } else { + params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, size); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + previewMenuLayout.setY(display.getHeight() - size); + } + basic.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)); + LinearLayout layout = (LinearLayout) basic.findViewById(R.id.layout); + + final View[] views = new View[entries.length]; + int init = pref.getCurrentIndex(); + for (int i = 0; i < entries.length; i++) { + LinearLayout layout2 = (LinearLayout) inflater.inflate( + R.layout.scene_mode_view, null, false); + + ImageView imageView = (ImageView) layout2.findViewById(R.id.image); + TextView label = (TextView) layout2.findViewById(R.id.label); + final int j = i; + + layout2.setOnTouchListener(new View.OnTouchListener() { + private long startTime; + + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + startTime = System.currentTimeMillis(); + } else if (event.getAction() == MotionEvent.ACTION_UP) { + if (System.currentTimeMillis() - startTime < CLICK_THRESHOLD) { + pref.setValueIndex(j); + onSettingChanged(pref); + updateSceneModeIcon(); + for (View v1 : views) { + v1.setBackgroundResource(R.drawable.scene_mode_view_border); + } + View border = v.findViewById(R.id.border); + border.setBackgroundResource(R.drawable.scene_mode_view_border_selected); + } + + } + return true; + } + }); + + View border = layout2.findViewById(R.id.border); + views[j] = border; + if (i == init) + border.setBackgroundResource(R.drawable.scene_mode_view_border_selected); + imageView.setImageResource(thumbnails[i]); + label.setText(entries[i]); + layout.addView(layout2); + } + previewMenuLayout.addView(basic); + mPreviewMenu = basic; + } + + public void updateSceneModeIcon() { + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_SCENE_MODE); + if (pref == null) + return; + ImageView iv = (ImageView) ((FrameLayout) mSceneModeSwitcher).getChildAt(0); + int[] thumbnails = pref.getThumbnailIds(); + int ind = pref.getCurrentIndex(); + if (ind == -1) + ind = 0; + iv.setImageResource(thumbnails[ind]); + } + + public void initFilterModeButton(View button) { + button.setVisibility(View.INVISIBLE); + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_COLOR_EFFECT); + if (pref == null) + return; + + int[] iconIds = pref.getLargeIconIds(); + int resid = -1; + // The preference only has a single icon to represent it. + resid = pref.getSingleIcon(); + ImageView iv = (ImageView) ((FrameLayout) button).getChildAt(0); + iv.setImageResource(resid); + button.setVisibility(View.VISIBLE); + button.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + addFilterMode(); + View view = mUI.getPreviewMenuLayout().getChildAt(0); + animateSlideIn(view, previewMenuSize, false); + } + }); + } + + public void addFilterMode() { + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_COLOR_EFFECT); + if (pref == null) + return; + + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + CharSequence[] entries = pref.getEntries(); + + Resources r = mActivity.getResources(); + int height = (int) (r.getDimension(R.dimen.filter_mode_height) + 2 + * r.getDimension(R.dimen.filter_mode_padding) + 1); + int width = (int) (r.getDimension(R.dimen.filter_mode_width) + 2 + * r.getDimension(R.dimen.filter_mode_padding) + 1); + + int gridRes = 0; + boolean portrait = (rotation == 0) || (rotation == 180); + int size = height; + if (portrait) { + gridRes = R.layout.vertical_grid; + size = width; + } else { + gridRes = R.layout.horiz_grid; + } + previewMenuSize = size; + mUI.hideUI(); + mPreviewMenuStatus = PREVIEW_MENU_ON; + mSceneStatus = MODE_FILTER; + + int[] thumbnails = pref.getThumbnailIds(); + + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + FrameLayout basic = (FrameLayout) inflater.inflate( + gridRes, null, false); + + mUI.dismissSceneModeMenu(); + LinearLayout previewMenuLayout = new LinearLayout(mActivity); + mUI.setPreviewMenuLayout(previewMenuLayout); + ViewGroup.LayoutParams params = null; + if (portrait) { + params = new ViewGroup.LayoutParams(size, LayoutParams.MATCH_PARENT); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + } else { + params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, size); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + previewMenuLayout.setY(display.getHeight() - size); + } + basic.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)); + LinearLayout layout = (LinearLayout) basic.findViewById(R.id.layout); + final View[] views = new View[entries.length]; + int init = pref.getCurrentIndex(); + for (int i = 0; i < entries.length; i++) { + LinearLayout layout2 = (LinearLayout) inflater.inflate( + R.layout.filter_mode_view, null, false); + ImageView imageView = (ImageView) layout2.findViewById(R.id.image); + final int j = i; + + layout2.setOnTouchListener(new View.OnTouchListener() { + private long startTime; + + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + startTime = System.currentTimeMillis(); + } else if (event.getAction() == MotionEvent.ACTION_UP) { + if (System.currentTimeMillis() - startTime < CLICK_THRESHOLD) { + pref.setValueIndex(j); + onSettingChanged(pref); + for (View v1 : views) { + v1.setBackground(null); + } + ImageView image = (ImageView) v.findViewById(R.id.image); + image.setBackgroundColor(0xff33b5e5); + } + } + return true; + } + }); + + views[j] = imageView; + if (i == init) + imageView.setBackgroundColor(0xff33b5e5); + TextView label = (TextView) layout2.findViewById(R.id.label); + imageView.setImageResource(thumbnails[i]); + label.setText(entries[i]); + layout.addView(layout2); + } + previewMenuLayout.addView(basic); + mPreviewMenu = basic; + } + + public void openFirstLevel() { + if (isMenuBeingShown() || CameraControls.isAnimating()) + return; + if (mListMenu == null || mPopupStatus != POPUP_FIRST_LEVEL) { + initializePopup(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + mUI.showPopup(mListMenu, 1, true); + + } public void popupDismissed(boolean dismissAll) { if (!dismissAll && mPopupStatus == POPUP_SECOND_LEVEL) { initializePopup(); mPopupStatus = POPUP_FIRST_LEVEL; - if (popupNum == 1) - mUI.showPopup(mPopup1); - else if (popupNum == 2) - mUI.showPopup(mPopup2); - else if (popupNum == 3) - mUI.showPopup(mPopup3); + mUI.showPopup(mListMenu, 1, false); + if (mListMenu != null) + mListMenu = null; + } else { initializePopup(); } } - @Override + @Override // Hit when an item in the first-level popup gets selected, then bring up // the second-level popup public void onPreferenceClicked(ListPreference pref) { - if (mPopupStatus != POPUP_FIRST_LEVEL) return; + onPreferenceClicked(pref, 0); + } + + public void onPreferenceClicked(ListPreference pref, int y) { + if (!mActivity.isDeveloperMenuEnabled()) { + if (pref.getKey().equals(CameraSettings.KEY_REDEYE_REDUCTION)) { + privateCounter++; + if (privateCounter >= DEVELOPER_MENU_TOUCH_COUNT) { + mActivity.enableDeveloperMenu(); + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(mActivity); + prefs.edit().putBoolean(CameraSettings.KEY_DEVELOPER_MENU, true).apply(); + Toast toast = Toast.makeText(mActivity, + "Camera developer option is enabled now", Toast.LENGTH_SHORT); + toast.show(); + } + } else { + privateCounter = 0; + } + } LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( Context.LAYOUT_INFLATER_SERVICE); - ListPrefSettingPopup basic = (ListPrefSettingPopup) inflater.inflate( - R.layout.list_pref_setting_popup, null, false); - basic.initialize(pref); + ListSubMenu basic = (ListSubMenu) inflater.inflate( + R.layout.list_sub_menu, null, false); + basic.initialize(pref, y); basic.setSettingChangedListener(this); - mUI.dismissPopup(); - mPopup = basic; - mUI.showPopup(mPopup); + basic.setAlpha(0f); + mListSubMenu = basic; + mUI.removeLevel2(); + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mUI.showPopup(mListSubMenu, 2, false); + } else { + mUI.showPopup(mListSubMenu, 2, true); + } mPopupStatus = POPUP_SECOND_LEVEL; } + public void onListMenuTouched() { + mUI.removeLevel2(); + } + + public void closeAllView() { + if (mUI != null) + mUI.removeLevel2(); + + if (mListMenu != null) { + animateSlideOut(mListMenu, 1); + } + animateSlideOutPreviewMenu(); + } + + public void closeView() { + if (mUI != null) + mUI.removeLevel2(); + + if (mListMenu != null && mPopupStatus != POPUP_NONE) + animateSlideOut(mListMenu, 1); + } + // Return true if the preference has the specified key but not the value. private static boolean notSame(ListPreference pref, String key, String value) { return (key.equals(pref.getKey()) && !value.equals(pref.getValue())); @@ -496,6 +1093,12 @@ public class PhotoMenu extends PieController setPreference(CameraSettings.KEY_LONGSHOT, mSettingOff); } } + + if (notSame(pref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)) { + buttonSetEnabled(mFilterModeSwitcher, false); + } else { + buttonSetEnabled(mFilterModeSwitcher, true); + } super.onSettingChanged(pref); } diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java index 299540010..c45d02703 100644 --- a/src/com/android/camera/PhotoModule.java +++ b/src/com/android/camera/PhotoModule.java @@ -26,7 +26,6 @@ import android.content.SharedPreferences.Editor; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Rect; -import android.graphics.SurfaceTexture; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Parameters; import android.hardware.Camera.Size; @@ -49,6 +48,7 @@ import android.provider.MediaStore; import android.util.Log; import android.view.KeyEvent; import android.view.OrientationEventListener; +import android.view.SurfaceHolder; import android.view.View; import android.view.WindowManager; import android.widget.Toast; @@ -297,6 +297,7 @@ public class PhotoModule private ContentResolver mContentResolver; private LocationManager mLocationManager; + private boolean mLocationPromptTriggered = false; private final PostViewPictureCallback mPostViewPictureCallback = new PostViewPictureCallback(); @@ -538,6 +539,7 @@ public class PhotoModule CameraSettings.KEY_BRIGHTNESS, DEFAULT_BRIGHTNESS); brightnessProgressBar.setProgress(mbrightness); + brightnessProgressBar.setVisibility(View.INVISIBLE); skinToneSeekBar = (SeekBar) mRootView.findViewById(R.id.skintoneseek); skinToneSeekBar.setOnSeekBarChangeListener(mskinToneSeekListener); skinToneSeekBar.setVisibility(View.INVISIBLE); @@ -571,16 +573,20 @@ public class PhotoModule // Prompt the user to pick to record location for the very first run of // camera only private void locationFirstRun() { - if (RecordLocationPreference.isSet(mPreferences)) { + /* Do not prompt if the preference is already set, this is a secure + * camera session, or the prompt has already been triggered. */ + if (RecordLocationPreference.isSet(mPreferences) || + mActivity.isSecureCamera() || mLocationPromptTriggered) { return; } - if (mActivity.isSecureCamera()) return; // Check if the back camera exists int backCameraId = CameraHolder.instance().getBackCameraId(); if (backCameraId == -1) { // If there is no back camera, do not show the prompt. return; } + + mLocationPromptTriggered = true; mUI.showLocationDialog(); } @@ -599,12 +605,12 @@ public class PhotoModule if (mCameraState == PREVIEW_STOPPED || mCameraState == INIT) { startPreview(); } else { - SurfaceTexture st = mUI.getSurfaceTexture(); - if (st == null) { - Log.w(TAG, "startPreview: surfaceTexture is not ready."); + SurfaceHolder sh = mUI.getSurfaceHolder(); + if (sh == null) { + Log.w(TAG, "startPreview: holder for preview are not ready."); return; } - mCameraDevice.setPreviewTexture(st); + mCameraDevice.setPreviewDisplay(sh); } } @@ -613,8 +619,7 @@ public class PhotoModule if (mCameraDevice == null) { return; } - Log.v(TAG, "onPreviewUIDestroyed"); - mCameraDevice.setPreviewTexture(null); + mCameraDevice.setPreviewDisplay(null); stopPreview(); } @@ -770,7 +775,7 @@ public class PhotoModule } setPreviewFrameLayoutCameraOrientation(); Size size = mParameters.getPreviewSize(); - Log.e(TAG,"Width = "+ size.width+ "Height = "+size.height); + Log.i(TAG, "Using preview width = " + size.width + "& height = " + size.height); mUI.setAspectRatio((float) size.width / size.height); } @@ -951,6 +956,8 @@ public class PhotoModule return; } + mUI.doShutterAnimation(); + if (mLongshotSave) { mCameraDevice.takePicture(mHandler, new LongshotShutterCallback(), @@ -1891,6 +1898,7 @@ public class PhotoModule // need to re-initialize mGraphView to show histogram on rotate mGraphView = (GraphView)mRootView.findViewById(R.id.graph_view); if(mGraphView != null){ + mGraphView.setAlpha(0.75f); mGraphView.setPhotoModuleObject(this); mGraphView.PreviewChanged(); } @@ -2210,7 +2218,6 @@ public class PhotoModule mJpegPictureCallbackTime = 0; mZoomValue = 0; - resetExposureCompensation(); if (mSkinToneSeekBar != true) { @@ -2438,6 +2445,9 @@ public class PhotoModule switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: + if (CameraUtil.volumeKeyShutterDisable(mActivity)) { + return false; + } case KeyEvent.KEYCODE_FOCUS: if (/*TODO: mActivity.isInCameraApp() &&*/ mFirstTimeInitialized) { if (event.getRepeatCount() == 0) { @@ -2468,7 +2478,7 @@ public class PhotoModule Editor editor = mPreferences.edit(); editor.putInt(CameraSettings.KEY_BRIGHTNESS, mbrightness); editor.apply(); - brightnessProgressBar.setVisibility(View.VISIBLE); + brightnessProgressBar.setVisibility(View.INVISIBLE); mBrightnessVisible = true; } break; @@ -2489,7 +2499,7 @@ public class PhotoModule Editor editor = mPreferences.edit(); editor.putInt(CameraSettings.KEY_BRIGHTNESS, mbrightness); editor.apply(); - brightnessProgressBar.setVisibility(View.VISIBLE); + brightnessProgressBar.setVisibility(View.INVISIBLE); mBrightnessVisible = true; } break; @@ -2513,7 +2523,8 @@ public class PhotoModule switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: - if (/*mActivity.isInCameraApp() && */ mFirstTimeInitialized) { + if (/*mActivity.isInCameraApp() && */ mFirstTimeInitialized + && !CameraUtil.volumeKeyShutterDisable(mActivity)) { onShutterButtonClick(); return true; } @@ -2550,6 +2561,10 @@ public class PhotoModule } } + public void updatePreviewThumbnail() { + mUI.updatePreviewThumbnail(); + } + private void setDisplayOrientation() { mDisplayRotation = CameraUtil.getDisplayRotation(mActivity); mDisplayOrientation = CameraUtil.getDisplayOrientation(mDisplayRotation, mCameraId); @@ -2577,24 +2592,22 @@ public class PhotoModule /** This can run on a background thread, so don't do UI updates here. Post any view updates to MainHandler or do it on onPreviewStarted() . */ private void startPreview() { - if (mPaused || mCameraDevice == null) { + if (mPaused || mCameraDevice == null || mParameters == null) { return; } - Log.v(TAG, "startPreview"); - - SurfaceTexture st = null; + SurfaceHolder sh = null; + Log.v(TAG, "startPreview: SurfaceHolder (MDP path)"); if (mUI != null) { - st = mUI.getSurfaceTexture(); + sh = mUI.getSurfaceHolder(); } - // Surfacetexture could be null here, but its still valid and safe to set null - // surface before startpreview. This will help in basic preview setup and - // surface creation in parallel. Once valid surface is ready in onPreviewUIReady() - // we set the surface to camera to actually start preview. - mCameraDevice.setPreviewTexture(st); + + setCameraParameters(UPDATE_PARAM_ALL); + // Let UI set its expected aspect ratio + mCameraDevice.setPreviewDisplay(sh); if (!mCameraPreviewParamsReady) { - Log.w(TAG, "startPreview: parameters for preview is not ready."); + Log.w(TAG, "startPreview: parameters for preview are not ready."); return; } mCameraDevice.setErrorCallback(mErrorCallback); @@ -4060,7 +4073,7 @@ public class PhotoModule mPreferences, mContentResolver); mLocationManager.recordLocation(recordLocation); if(needRestart()){ - Log.v(TAG, "Restarting Preview... Camera Mode Changhed"); + Log.v(TAG, "Restarting Preview... Camera Mode Changed"); stopPreview(); startPreview(); setCameraState(IDLE); @@ -4293,6 +4306,7 @@ public class PhotoModule } skinToneSeekBar.setProgress(progress); mActivity.findViewById(R.id.linear).bringToFront(); + mActivity.findViewById(R.id.progress).setVisibility(View.GONE); skinToneSeekBar.bringToFront(); Title.setText("Skin Tone Enhancement"); Title.setVisibility(View.VISIBLE); @@ -4313,7 +4327,7 @@ public class PhotoModule Integer.toString(mskinToneValue - MIN_SCE_FACTOR)); editor.apply(); if ((brightnessProgressBar != null) && mBrightnessVisible) - brightnessProgressBar.setVisibility(View.VISIBLE); + brightnessProgressBar.setVisibility(View.INVISIBLE); } /* diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java index eb077c3b2..48fb2f704 100644 --- a/src/com/android/camera/PhotoUI.java +++ b/src/com/android/camera/PhotoUI.java @@ -17,6 +17,8 @@ package com.android.camera; +import java.util.List; + import android.app.AlertDialog; import android.content.DialogInterface; import android.content.res.Configuration; @@ -24,24 +26,34 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.RectF; -import android.graphics.SurfaceTexture; import android.graphics.drawable.ColorDrawable; import android.hardware.Camera; import android.hardware.Camera.Face; import android.os.AsyncTask; +import android.os.Handler; import android.util.Log; import android.view.Gravity; -import android.view.TextureView; +import android.view.Surface; +import android.view.SurfaceView; +import android.view.SurfaceHolder; +import android.view.SurfaceHolder.Callback; +import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLayoutChangeListener; import android.view.ViewGroup; +import android.view.ViewPropertyAnimator; import android.view.ViewStub; +import android.widget.FrameLayout; import android.widget.FrameLayout.LayoutParams; import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; import android.widget.PopupWindow; import android.widget.Toast; +import android.graphics.drawable.AnimationDrawable; +import com.android.camera.CameraActivity.UpdatePreviewThumbnail; import com.android.camera.CameraPreference.OnPreferenceChangedListener; import com.android.camera.FocusOverlayManager.FocusUI; import com.android.camera.ui.AbstractSettingPopup; @@ -59,13 +71,13 @@ import com.android.camera.ui.ZoomRenderer; import com.android.camera.util.CameraUtil; import org.codeaurora.snapcam.R; -import java.util.List; - public class PhotoUI implements PieListener, - PreviewGestures.SingleTapListener, - FocusUI, TextureView.SurfaceTextureListener, - LocationManager.Listener, CameraRootView.MyDisplayListener, - CameraManager.CameraFaceDetectionCallback { + PreviewGestures.SingleTapListener, + FocusUI, + SurfaceHolder.Callback, + LocationManager.Listener, + CameraRootView.MyDisplayListener, + CameraManager.CameraFaceDetectionCallback { private static final String TAG = "CAM_UI"; private int mDownSampleFactor = 4; @@ -75,7 +87,7 @@ public class PhotoUI implements PieListener, private PreviewGestures mGestures; private View mRootView; - private SurfaceTexture mSurfaceTexture; + private SurfaceHolder mSurfaceHolder; private PopupWindow mPopup; private ShutterButton mShutterButton; @@ -107,6 +119,9 @@ public class PhotoUI implements PieListener, private int mPreviewWidth = 0; private int mPreviewHeight = 0; + private int mOriginalPreviewWidth = 0; + private int mOriginalPreviewHeight = 0; + public boolean mMenuInitialized = false; private float mSurfaceTextureUncroppedWidth; private float mSurfaceTextureUncroppedHeight; @@ -115,7 +130,7 @@ public class PhotoUI implements PieListener, private View mFlashOverlay; private SurfaceTextureSizeChangedListener mSurfaceTextureSizeListener; - private TextureView mTextureView; + private SurfaceView mSurfaceView = null; private Matrix mMatrix = null; private float mAspectRatio = 4f / 3f; private boolean mAspectRatioResize; @@ -123,7 +138,29 @@ public class PhotoUI implements PieListener, private boolean mOrientationResize; private boolean mPrevOrientationResize; private View mPreviewCover; - private final Object mSurfaceTextureLock = new Object(); + private LinearLayout mMenuLayout; + private LinearLayout mSubMenuLayout; + private LinearLayout mPreviewMenuLayout; + private boolean mUIhidden = false; + private int mPreviewOrientation = -1; + + // temporary variables for updating SurfaceView + private int mTempWidth; + private int mTempHeight; + + private final Handler mSurfaceViewUpdateHandler = new Handler(); + + private Runnable updateSurfaceView = new Runnable() { + + @Override + public void run() { + FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mSurfaceView + .getLayoutParams(); + params.width = mTempWidth; + params.height = mTempHeight; + mSurfaceView.setLayoutParams(params); + } + }; public interface SurfaceTextureSizeChangedListener { public void onSurfaceTextureSizeChanged(int uncroppedWidth, int uncroppedHeight); @@ -135,16 +172,38 @@ public class PhotoUI implements PieListener, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { int width = right - left; int height = bottom - top; + + int orientation = mActivity.getResources().getConfiguration().orientation; + if ((orientation == Configuration.ORIENTATION_PORTRAIT && width > height) + || (orientation == Configuration.ORIENTATION_LANDSCAPE && width < height)) { + // The screen has rotated; swap SurfaceView width & height + // to ensure correct preview + int oldWidth = width; + width = height; + height = oldWidth; + Log.d(TAG, "Swapping SurfaceView width & height dimensions"); + if (mOriginalPreviewWidth != 0 && mOriginalPreviewHeight != 0) { + int temp = mOriginalPreviewWidth; + mOriginalPreviewWidth = mOriginalPreviewHeight; + mOriginalPreviewHeight = temp; + } + } + if (mPreviewWidth != width || mPreviewHeight != height || (mOrientationResize != mPrevOrientationResize) || mAspectRatioResize) { + if (mOriginalPreviewWidth == 0) mOriginalPreviewWidth = width; + if (mOriginalPreviewHeight == 0) mOriginalPreviewHeight = height; mPreviewWidth = width; mPreviewHeight = height; - setTransformMatrix(width, height); + setTransformMatrix(mOriginalPreviewWidth, mOriginalPreviewHeight); mController.onScreenSizeChanged((int) mSurfaceTextureUncroppedWidth, (int) mSurfaceTextureUncroppedHeight); mAspectRatioResize = false; } + + if (mMenu != null) + mMenu.tryToCloseSubList(); } }; @@ -179,7 +238,7 @@ public class PhotoUI implements PieListener, @Override protected void onPostExecute(Bitmap bitmap) { mPreviewThumb.setImageBitmap(bitmap); - mAnimationManager.startCaptureAnimation(mPreviewThumb); + updatePreviewThumbnail(bitmap); } } @@ -203,23 +262,26 @@ public class PhotoUI implements PieListener, mActivity = activity; mController = controller; mRootView = parent; - mActivity.getLayoutInflater().inflate(R.layout.photo_module, (ViewGroup) mRootView, true); - mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_overlay); - mFlashOverlay = mRootView.findViewById(R.id.flash_overlay); mPreviewCover = mRootView.findViewById(R.id.preview_cover); // display the view - mTextureView = (TextureView) mRootView.findViewById(R.id.preview_content); - mTextureView.setSurfaceTextureListener(this); - mTextureView.addOnLayoutChangeListener(mLayoutListener); - initIndicators(); + mSurfaceView = (SurfaceView) mRootView.findViewById(R.id.mdp_preview_content); + mSurfaceView.setVisibility(View.VISIBLE); + mSurfaceHolder = mSurfaceView.getHolder(); + mSurfaceHolder.addCallback(this); + mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + mSurfaceView.addOnLayoutChangeListener(mLayoutListener); + Log.v(TAG, "Using mdp_preview_content (MDP path)"); + mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_overlay); + mFlashOverlay = mRootView.findViewById(R.id.flash_overlay); mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button); mSwitcher = (ModuleSwitcher) mRootView.findViewById(R.id.camera_switcher); mSwitcher.setCurrentIndex(ModuleSwitcher.PHOTO_MODULE_INDEX); mSwitcher.setSwitchListener(mActivity); mMenuButton = mRootView.findViewById(R.id.menu); + mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls); ViewStub faceViewStub = (ViewStub) mRootView .findViewById(R.id.face_view_stub); if (faceViewStub != null) { @@ -227,13 +289,30 @@ public class PhotoUI implements PieListener, mFaceView = (FaceView) mRootView.findViewById(R.id.face_view); setSurfaceTextureSizeChangedListener(mFaceView); } - mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls); + initIndicators(); mAnimationManager = new AnimationManager(); - mOrientationResize = false; mPrevOrientationResize = false; } + public void updatePreviewThumbnail() { + mPreviewThumb.setVisibility(View.VISIBLE); + Bitmap bitmap = mActivity.getPreviewThumbBitmap(); + if (bitmap != null) { + mPreviewThumb.setImageBitmap(bitmap); + } + else { + UpdatePreviewThumbnail task = mActivity.new UpdatePreviewThumbnail(mPreviewThumb); + task.execute(); + } + } + + public void updatePreviewThumbnail(Bitmap bitmap) { + mPreviewThumb.setVisibility(View.VISIBLE); + mPreviewThumb.setImageBitmap(bitmap); + mActivity.setPreviewThumbnailBitmap(bitmap); + } + public void setDownFactor(int factor) { mDownSampleFactor = factor; } @@ -252,12 +331,13 @@ public class PhotoUI implements PieListener, ratio = 1 / ratio; } - if (mAspectRatio != ratio) { - Log.d(TAG,"setAspectRatio() ratio["+ratio+"] mAspectRatio["+mAspectRatio+"]"); - mAspectRatio = ratio; + Log.d(TAG, "setAspectRatio() ratio[" + ratio + "] mAspectRatio[" + mAspectRatio + "]"); + if (ratio != mAspectRatio) { mAspectRatioResize = true; - mTextureView.requestLayout(); + mAspectRatio = ratio; } + + mSurfaceView.requestLayout(); } public void setSurfaceTextureSizeChangedListener(SurfaceTextureSizeChangedListener listener) { @@ -265,12 +345,12 @@ public class PhotoUI implements PieListener, } private void setTransformMatrix(int width, int height) { - mMatrix = mTextureView.getTransform(mMatrix); - float scaleX = 1f, scaleY = 1f; + mMatrix = mSurfaceView.getMatrix(); + float scaledTextureWidth, scaledTextureHeight; - if (mOrientationResize){ + if (mOrientationResize) { scaledTextureWidth = height * mAspectRatio; - if(scaledTextureWidth > width){ + if (scaledTextureWidth > width) { scaledTextureWidth = width; scaledTextureHeight = scaledTextureWidth / mAspectRatio; } else { @@ -292,13 +372,16 @@ public class PhotoUI implements PieListener, mSurfaceTextureUncroppedHeight = scaledTextureHeight; if (mSurfaceTextureSizeListener != null) { mSurfaceTextureSizeListener.onSurfaceTextureSizeChanged( - (int) mSurfaceTextureUncroppedWidth, (int) mSurfaceTextureUncroppedHeight); + (int) mSurfaceTextureUncroppedWidth, + (int) mSurfaceTextureUncroppedHeight); } } - scaleX = scaledTextureWidth / width; - scaleY = scaledTextureHeight / height; - mMatrix.setScale(scaleX, scaleY, (float) width / 2, (float) height / 2); - mTextureView.setTransform(mMatrix); + + Log.v(TAG, "setTransformMatrix: scaledTextureWidth = " + scaledTextureWidth + + ", scaledTextureHeight = " + scaledTextureHeight); + mTempWidth = (int) scaledTextureWidth; + mTempHeight = (int) scaledTextureHeight; + mSurfaceViewUpdateHandler.post(updateSurfaceView); // Calculate the new preview rectangle. RectF previewRect = new RectF(0, 0, width, height); @@ -306,45 +389,33 @@ public class PhotoUI implements PieListener, mController.onPreviewRectChanged(CameraUtil.rectFToRect(previewRect)); } - protected Object getSurfaceTextureLock() { - return mSurfaceTextureLock; - } - + // SurfaceHolder callbacks @Override - public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { - synchronized (mSurfaceTextureLock) { - Log.v(TAG, "SurfaceTexture ready."); - mSurfaceTexture = surface; - mController.onPreviewUIReady(); - // Workaround for b/11168275, see b/10981460 for more details - if (mPreviewWidth != 0 && mPreviewHeight != 0) { - // Re-apply transform matrix for new surface texture - setTransformMatrix(mPreviewWidth, mPreviewHeight); - } + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + Log.v(TAG, "surfaceChanged: width =" + width + ", height = " + height); + // Make sure preview cover is hidden if preview data is available. + if (mPreviewCover.getVisibility() != View.GONE) { + mPreviewCover.setVisibility(View.GONE); } } @Override - public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { - // Ignored, Camera does all the work for us - } - - @Override - public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { - synchronized (mSurfaceTextureLock) { - mSurfaceTexture = null; - mController.onPreviewUIDestroyed(); - Log.w(TAG, "SurfaceTexture destroyed"); - return true; + public void surfaceCreated(SurfaceHolder holder) { + Log.v(TAG, "surfaceCreated"); + mSurfaceHolder = holder; + mController.onPreviewUIReady(); + if (mPreviewWidth != 0 && mPreviewHeight != 0) { + // Re-apply transform matrix for new surface texture + setTransformMatrix(mPreviewWidth, mPreviewHeight); } + updatePreviewThumbnail(); } @Override - public void onSurfaceTextureUpdated(SurfaceTexture surface) { - // Make sure preview cover is hidden if preview data is available. - if (mPreviewCover.getVisibility() != View.GONE) { - mPreviewCover.setVisibility(View.GONE); - } + public void surfaceDestroyed(SurfaceHolder holder) { + Log.v(TAG, "surfaceDestroyed"); + mSurfaceHolder = null; + mController.stopPreview(); } public View getRootView() { @@ -365,7 +436,7 @@ public class PhotoUI implements PieListener, } if (mMenu == null) { - mMenu = new PhotoMenu(mActivity, this, mPieRenderer); + mMenu = new PhotoMenu(mActivity, this); mMenu.setListener(listener); } mMenu.initialize(prefGroup); @@ -381,12 +452,15 @@ public class PhotoUI implements PieListener, mGestures = new PreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer); mRenderOverlay.setGestures(mGestures); } + mGestures.setPhotoMenu(mMenu); + mGestures.setZoomEnabled(params.isZoomSupported()); mGestures.setRenderOverlay(mRenderOverlay); mRenderOverlay.requestLayout(); initializeZoom(params); updateOnScreenIndicators(params, prefGroup, prefs); + mActivity.setPreviewGestures(mGestures); } public void animateCapture(final byte[] jpegData, int orientation, boolean mirror) { @@ -411,14 +485,15 @@ public class PhotoUI implements PieListener, mPreviewThumb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - mActivity.gotoGallery(); + if (!CameraControls.isAnimating()) + mActivity.gotoGallery(); } }); mMenuButton = mRootView.findViewById(R.id.menu); mMenuButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - openMenu(); + mMenu.openFirstLevel(); } }); if (mController.isImageCaptureIntent()) { @@ -455,16 +530,22 @@ public class PhotoUI implements PieListener, } public void hideUI() { - mCameraControls.setVisibility(View.INVISIBLE); mSwitcher.closePopup(); + if (mUIhidden) + return; + mUIhidden = true; + mCameraControls.hideUI(); } public void showUI() { - mCameraControls.setVisibility(View.VISIBLE); + if (!mUIhidden || (mMenu != null && mMenu.isMenuBeingShown())) + return; + mUIhidden = false; + mCameraControls.showUI(); } public boolean arePreviewControlsVisible() { - return (mCameraControls.getVisibility() == View.VISIBLE); + return !mUIhidden; } public void hideSwitcher() { @@ -476,13 +557,29 @@ public class PhotoUI implements PieListener, mSwitcher.setVisibility(View.VISIBLE); } // called from onResume but only the first time - public void initializeFirstTime() { + public void initializeFirstTime() { // Initialize shutter button. - mShutterButton.setImageResource(R.drawable.btn_new_shutter); + mShutterButton.setImageBitmap(null); + mShutterButton.setBackgroundResource(R.drawable.shutter_button_anim); + mShutterButton.setOnClickListener(new OnClickListener() + { + @Override + public void onClick(View v) { + if (!CameraControls.isAnimating()) + doShutterAnimation(); + } + }); + mShutterButton.setOnShutterButtonListener(mController); mShutterButton.setVisibility(View.VISIBLE); } + public void doShutterAnimation() { + AnimationDrawable frameAnimation = (AnimationDrawable) mShutterButton.getBackground(); + frameAnimation.stop(); + frameAnimation.start(); + } + // called from onResume every other time public void initializeSecondTime(Camera.Parameters params) { initializeZoom(params); @@ -545,7 +642,8 @@ public class PhotoUI implements PieListener, public void hideGpsOnScreenIndicator() { } public void overrideSettings(final String ... keyvalues) { - if (mMenu == null) return; + if (mMenu == null) + return; mMenu.overrideSettings(keyvalues); } @@ -593,6 +691,10 @@ public class PhotoUI implements PieListener, } public boolean onBackPressed() { + if (mMenu != null && mMenu.handleBackKey()) { + return true; + } + if (mPieRenderer != null && mPieRenderer.showsItems()) { mPieRenderer.hide(); return true; @@ -606,6 +708,9 @@ public class PhotoUI implements PieListener, } else if (!mController.isCameraIdle()) { // ignore backs while we're taking a picture return true; + } if (mSwitcher != null && mSwitcher.showsPopup()) { + mSwitcher.closePopup(); + return true; } else { return false; } @@ -634,6 +739,59 @@ public class PhotoUI implements PieListener, if (!previewFocused && mCountDownView != null) mCountDownView.cancelCountDown(); } + public ViewGroup getMenuLayout() { + return mMenuLayout; + } + + public void setPreviewMenuLayout(LinearLayout layout) { + mPreviewMenuLayout = layout; + } + + public ViewGroup getPreviewMenuLayout() { + return mPreviewMenuLayout; + } + + public void showPopup(ListView popup, int level, boolean animate) { + hideUI(); + + popup.setVisibility(View.VISIBLE); + if (level == 1) { + if (mMenuLayout == null) { + mMenuLayout = new LinearLayout(mActivity); + ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_1, LayoutParams.WRAP_CONTENT); + mMenuLayout.setLayoutParams(params); + ((ViewGroup) mRootView).addView(mMenuLayout); + } + mMenuLayout.addView(popup); + } + if (level == 2) { + if (mSubMenuLayout == null) { + mSubMenuLayout = new LinearLayout(mActivity); + ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_2, LayoutParams.WRAP_CONTENT); + mSubMenuLayout.setLayoutParams(params); + ((ViewGroup) mRootView).addView(mSubMenuLayout); + } + mSubMenuLayout.addView(popup); + mSubMenuLayout.setX(CameraActivity.SETTING_LIST_WIDTH_1); + } + if (animate) { + if (level == 1) + mMenu.animateSlideIn(popup, CameraActivity.SETTING_LIST_WIDTH_1, true); + if (level == 2) + mMenu.animateFadeIn(popup); + } else + popup.setAlpha(0.85f); + } + + public void removeLevel2() { + if (mSubMenuLayout != null) { + View v = mSubMenuLayout.getChildAt(0); + mSubMenuLayout.removeView(v); + } + } + public void showPopup(AbstractSettingPopup popup) { hideUI(); @@ -646,7 +804,7 @@ public class PhotoUI implements PieListener, @Override public void onDismiss() { mPopup = null; - mMenu.popupDismissed(mDismissAll); + // mMenu.popupDismissed(mDismissAll); mDismissAll = false; showUI(); @@ -661,6 +819,11 @@ public class PhotoUI implements PieListener, mPopup.showAtLocation(mRootView, Gravity.CENTER, 0, 0); } + public void cleanupListview() { + showUI(); + mActivity.setSystemBarsVisibility(false); + } + public void dismissPopup() { if (mPopup != null && mPopup.isShowing()) { mPopup.dismiss(); @@ -675,6 +838,44 @@ public class PhotoUI implements PieListener, } } + public void dismissLevel1() { + if (mMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mMenuLayout); + mMenuLayout = null; + } + } + + public void dismissLevel2() { + if (mSubMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mSubMenuLayout); + mSubMenuLayout = null; + } + } + + public boolean sendTouchToPreviewMenu(MotionEvent ev) { + return mPreviewMenuLayout.dispatchTouchEvent(ev); + } + + public boolean sendTouchToMenu(MotionEvent ev) { + View v = mMenuLayout.getChildAt(0); + return v.dispatchTouchEvent(ev); + } + + public void dismissSceneModeMenu() { + if (mPreviewMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mPreviewMenuLayout); + mPreviewMenuLayout = null; + } + } + + public void removeSceneModeMenu() { + if (mPreviewMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mPreviewMenuLayout); + mPreviewMenuLayout = null; + } + cleanupListview(); + } + public void onShowSwitcherPopup() { if (mPieRenderer != null && mPieRenderer.showsItems()) { mPieRenderer.hide(); @@ -685,9 +886,6 @@ public class PhotoUI implements PieListener, if (mOnScreenIndicators != null) { mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE); } - if (mMenuButton != null) { - mMenuButton.setVisibility(show ? View.VISIBLE : View.GONE); - } } public boolean collapseCameraControls() { @@ -696,6 +894,9 @@ public class PhotoUI implements PieListener, mSwitcher.closePopup(); // Remove all the popups/dialog boxes boolean ret = false; + if (mMenu != null) { + mMenu.closeAllView(); + } if (mPopup != null) { dismissAllPopup(); ret = true; @@ -732,6 +933,12 @@ public class PhotoUI implements PieListener, if (mFaceView != null) { mFaceView.setDisplayOrientation(orientation); } + if ((mPreviewOrientation == -1 || mPreviewOrientation != orientation) + && mMenu != null && mMenu.isPreviewMenuBeingShown()) { + dismissSceneModeMenu(); + mMenu.addModeBack(); + } + mPreviewOrientation = orientation; } // shutter button handling @@ -805,8 +1012,8 @@ public class PhotoUI implements PieListener, mActivity.setSwipingEnabled(enable); } - public SurfaceTexture getSurfaceTexture() { - return mSurfaceTexture; + public SurfaceHolder getSurfaceHolder() { + return mSurfaceHolder; } // Countdown timer diff --git a/src/com/android/camera/PreviewGestures.java b/src/com/android/camera/PreviewGestures.java index 91f567530..ce461aadd 100644 --- a/src/com/android/camera/PreviewGestures.java +++ b/src/com/android/camera/PreviewGestures.java @@ -21,6 +21,8 @@ import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.View; +import com.android.camera.PhotoMenu; +import com.android.camera.VideoMenu; import com.android.camera.ui.PieRenderer; import com.android.camera.ui.RenderOverlay; import com.android.camera.ui.ZoomRenderer; @@ -54,6 +56,10 @@ public class PreviewGestures private boolean mEnabled; private boolean mZoomOnly; private GestureDetector mGestureDetector; + private PhotoMenu mPhotoMenu; + private VideoMenu mVideoMenu; + private boolean waitUntilNextDown; + private boolean setToFalse; private GestureDetector.SimpleOnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener() { @Override @@ -90,6 +96,23 @@ public class PreviewGestures return true; } } + + if (deltaX < 0 && Math.abs(deltaX) > 2 * Math.abs(deltaY)) { + // Open menu on swipe left + waitUntilNextDown = true; + if (mPhotoMenu != null) { + if (!mPhotoMenu.isMenuBeingShown()) { + mPhotoMenu.openFirstLevel(); + } + } + + if (mVideoMenu != null) { + if (!mVideoMenu.isMenuBeingShown()) { + mVideoMenu.openFirstLevel(); + } + } + return true; + } return false; } }; @@ -129,7 +152,36 @@ public class PreviewGestures return mEnabled; } + public void setPhotoMenu(PhotoMenu menu) { + mPhotoMenu = menu; + } + + public void setVideoMenu(VideoMenu menu) { + mVideoMenu = menu; + } + + public PhotoMenu getPhotoMenu() { + return mPhotoMenu; + } + + public VideoMenu getVideoMenu() { + return mVideoMenu; + } + public boolean dispatchTouch(MotionEvent m) { + if (setToFalse) { + waitUntilNextDown = false; + setToFalse = false; + } + if (waitUntilNextDown) { + if (MotionEvent.ACTION_UP != m.getActionMasked() + && MotionEvent.ACTION_CANCEL != m.getActionMasked()) + return true; + else { + setToFalse = true; + return true; + } + } if (!mEnabled) { return false; } @@ -144,6 +196,37 @@ public class PreviewGestures return sendToPie(m); } + if (mPhotoMenu != null) { + if (mPhotoMenu.isMenuBeingShown()) { + if (!mPhotoMenu.isMenuBeingAnimated()) { + waitUntilNextDown = true; + mPhotoMenu.closeView(); + } + return true; + } + if (mPhotoMenu.isPreviewMenuBeingShown()) { + waitUntilNextDown = true; + mPhotoMenu.animateSlideOutPreviewMenu(); + return true; + } + } + + if (mVideoMenu != null) { + if (mVideoMenu.isMenuBeingShown()) { + if (!mVideoMenu.isMenuBeingAnimated()) { + waitUntilNextDown = true; + mVideoMenu.closeView(); + } + return true; + } + + if (mVideoMenu.isPreviewMenuBeingShown()) { + waitUntilNextDown = true; + mVideoMenu.animateSlideOutPreviewMenu(); + return true; + } + } + // If pie is not open, send touch events to gesture detector and scale // listener to recognize the gesture. mGestureDetector.onTouchEvent(m); @@ -162,6 +245,10 @@ public class PreviewGestures return true; } + public boolean waitUntilNextDown() { + return waitUntilNextDown; + } + private MotionEvent makeCancelEvent(MotionEvent m) { MotionEvent c = MotionEvent.obtain(m); c.setAction(MotionEvent.ACTION_CANCEL); diff --git a/src/com/android/camera/VideoMenu.java b/src/com/android/camera/VideoMenu.java index 08cb3849c..3f9cde7f0 100644 --- a/src/com/android/camera/VideoMenu.java +++ b/src/com/android/camera/VideoMenu.java @@ -16,155 +16,559 @@ package com.android.camera; +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; import android.content.Context; +import android.content.res.Resources; +import android.content.SharedPreferences; +import android.graphics.Rect; +import android.preference.PreferenceManager; +import android.util.Log; import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewPropertyAnimator; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.FrameLayout; +import android.widget.FrameLayout.LayoutParams; -import com.android.camera.ui.AbstractSettingPopup; -import com.android.camera.ui.ListPrefSettingPopup; -import com.android.camera.ui.MoreSettingPopup; -import com.android.camera.ui.PieItem; -import com.android.camera.ui.PieItem.OnClickListener; -import com.android.camera.ui.PieRenderer; +import com.android.camera.ui.CameraControls; +import com.android.camera.ui.ListSubMenu; +import com.android.camera.ui.ListMenu; import com.android.camera.ui.TimeIntervalPopup; +import com.android.camera.ui.RotateImageView; import org.codeaurora.snapcam.R; +import android.widget.HorizontalScrollView; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.Display; +import com.android.camera.util.CameraUtil; -public class VideoMenu extends PieController - implements MoreSettingPopup.Listener, - ListPrefSettingPopup.Listener, +public class VideoMenu extends MenuController + implements ListMenu.Listener, + ListSubMenu.Listener, TimeIntervalPopup.Listener { - private static String TAG = "CAM_VideoMenu"; + private static String TAG = "VideoMenu"; private VideoUI mUI; private String[] mOtherKeys1; private String[] mOtherKeys2; - private AbstractSettingPopup mPopup1; - private AbstractSettingPopup mPopup2; - + private ListMenu mListMenu; + private ListSubMenu mListSubMenu; + private View mPreviewMenu; private static final int POPUP_NONE = 0; private static final int POPUP_FIRST_LEVEL = 1; private static final int POPUP_SECOND_LEVEL = 2; + private static final int POPUP_IN_ANIMATION = 3; + private static final int PREVIEW_MENU_NONE = 0; + private static final int PREVIEW_MENU_IN_ANIMATION = 1; + private static final int PREVIEW_MENU_ON = 2; + private static final int MODE_FILTER = 1; + private int mSceneStatus; + private View mFrontBackSwitcher; + private View mFilterModeSwitcher; private int mPopupStatus; - private int popupNum; + private int mPreviewMenuStatus; private CameraActivity mActivity; private String mPrevSavedVideoCDS; private boolean mIsVideoTNREnabled = false; private boolean mIsVideoCDSUpdated = false; + private static final int ANIMATION_DURATION = 300; + private static final int CLICK_THRESHOLD = 200; + private int previewMenuSize; - public VideoMenu(CameraActivity activity, VideoUI ui, PieRenderer pie) { - super(activity, pie); + public VideoMenu(CameraActivity activity, VideoUI ui) { + super(activity); mUI = ui; mActivity = activity; + mFrontBackSwitcher = ui.getRootView().findViewById(R.id.front_back_switcher); + mFilterModeSwitcher = ui.getRootView().findViewById(R.id.filter_mode_switcher); } public void initialize(PreferenceGroup group) { super.initialize(group); - mPopup1 = null; - mPopup2 = null; - popupNum = 0; + mListMenu = null; + mListSubMenu = null; mPopupStatus = POPUP_NONE; - PieItem item = null; + mPreviewMenuStatus = POPUP_NONE; + initFilterModeButton(mFilterModeSwitcher); // settings popup mOtherKeys1 = new String[] { - CameraSettings.KEY_DIS, - CameraSettings.KEY_VIDEO_EFFECT, - CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL, CameraSettings.KEY_VIDEO_QUALITY, - CameraSettings.KEY_VIDEO_ENCODER, - CameraSettings.KEY_AUDIO_ENCODER, CameraSettings.KEY_VIDEO_DURATION, CameraSettings.KEY_RECORD_LOCATION, - CameraSettings.KEY_CAMERA_SAVEPATH + CameraSettings.KEY_CAMERA_SAVEPATH, + CameraSettings.KEY_WHITE_BALANCE, + CameraSettings.KEY_VIDEO_HIGH_FRAME_RATE, + CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE }; - - //settings popup - mOtherKeys2 = new String[] { - CameraSettings.KEY_COLOR_EFFECT, - CameraSettings.KEY_VIDEO_HDR, - CameraSettings.KEY_POWER_MODE, + mOtherKeys2 = new String[] { + CameraSettings.KEY_VIDEO_QUALITY, + CameraSettings.KEY_VIDEO_DURATION, + CameraSettings.KEY_RECORD_LOCATION, + CameraSettings.KEY_CAMERA_SAVEPATH, CameraSettings.KEY_WHITE_BALANCE, CameraSettings.KEY_VIDEO_HIGH_FRAME_RATE, CameraSettings.KEY_SEE_MORE, CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE, + CameraSettings.KEY_DIS, + CameraSettings.KEY_VIDEO_EFFECT, + CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL, + CameraSettings.KEY_VIDEO_ENCODER, + CameraSettings.KEY_AUDIO_ENCODER, + CameraSettings.KEY_VIDEO_HDR, + CameraSettings.KEY_POWER_MODE, CameraSettings.KEY_VIDEO_ROTATION, CameraSettings.KEY_VIDEO_CDS_MODE, CameraSettings.KEY_VIDEO_TNR_MODE - }; + }; + mFrontBackSwitcher.setVisibility(View.INVISIBLE); + initSwitchItem(CameraSettings.KEY_CAMERA_ID, mFrontBackSwitcher); + } + + public boolean handleBackKey() { + if (mPreviewMenuStatus == PREVIEW_MENU_ON) { + animateSlideOut(mPreviewMenu); + return true; + } + if (mPopupStatus == POPUP_NONE) + return false; + if (mPopupStatus == POPUP_FIRST_LEVEL) { + animateSlideOut(mListMenu, 1); + } else if (mPopupStatus == POPUP_SECOND_LEVEL) { + animateFadeOut(mListSubMenu, 2); + ((ListMenu) mListMenu).resetHighlight(); + } + return true; + } + + public void closeSceneMode() { + mUI.removeSceneModeMenu(); + } + + public void tryToCloseSubList() { + if (mListMenu != null) + ((ListMenu) mListMenu).resetHighlight(); + + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } + + private void animateFadeOut(final ListView v, final int level) { + if (v == null || mPopupStatus == POPUP_IN_ANIMATION) + return; + mPopupStatus = POPUP_IN_ANIMATION; + + ViewPropertyAnimator vp = v.animate(); + vp.alpha(0f).setDuration(ANIMATION_DURATION); + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } - PieItem item1 = makeItem(R.drawable.ic_settings_holo_light_01); - item1.setLabel(mActivity.getResources().getString(R.string.camera_menu_more_label)); - item1.setOnClickListener(new OnClickListener() { @Override - public void onClick(PieItem item) { - if (mPopup1 == null || mPopupStatus != POPUP_FIRST_LEVEL) { + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); mPopupStatus = POPUP_FIRST_LEVEL; } - mUI.showPopup(mPopup1); - popupNum = 1; + } + + @Override + public void onAnimationCancel(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } }); - mRenderer.addItem(item1); + vp.start(); + } + + private void animateSlideOut(final ListView v, final int level) { + if (v == null || mPopupStatus == POPUP_IN_ANIMATION) + return; + mPopupStatus = POPUP_IN_ANIMATION; + + ViewPropertyAnimator vp = v.animate(); + vp.translationX(v.getX() - v.getWidth()).setDuration(ANIMATION_DURATION); + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } - PieItem item2 = makeItem(R.drawable.ic_settings_holo_light_02); - item2.setLabel(mActivity.getResources().getString(R.string.camera_menu_more_label)); - item2.setOnClickListener(new OnClickListener() { @Override - public void onClick(PieItem item) { - if (mPopup2 == null || mPopupStatus != POPUP_FIRST_LEVEL) { + public void onAnimationCancel(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); mPopupStatus = POPUP_FIRST_LEVEL; } - mUI.showPopup(mPopup2); - popupNum = 2; + + } + }); + vp.start(); + } + + public void animateFadeIn(final ListView v) { + ViewPropertyAnimator vp = v.animate(); + vp.alpha(0.85f).setDuration(ANIMATION_DURATION); + vp.start(); + } + + public void animateSlideIn(final View v, int delta, boolean settingMenu) { + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + boolean portrait = (rotation == 0) || (rotation == 180); + if (settingMenu) + portrait = true; + ViewPropertyAnimator vp = v.animate(); + if (portrait) { + float dest = v.getX(); + v.setX(dest - delta); + vp.translationX(dest).setDuration(ANIMATION_DURATION); + } + else { + float dest = v.getY(); + v.setY(dest + delta); + vp.translationY(dest).setDuration(ANIMATION_DURATION); + } + vp.start(); + } + + public void animateSlideOutPreviewMenu() { + if (mPreviewMenu == null) + return; + animateSlideOut(mPreviewMenu); + } + + private void animateSlideOut(final View v) { + if (v == null || mPreviewMenuStatus == PREVIEW_MENU_IN_ANIMATION) + return; + mPreviewMenuStatus = PREVIEW_MENU_IN_ANIMATION; + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + boolean portrait = (rotation == 0) || (rotation == 180); + ViewPropertyAnimator vp = v.animate(); + if (portrait) { + vp.translationX(v.getX() - v.getWidth()).setDuration(ANIMATION_DURATION); + + } else { + vp.translationY(v.getY() + v.getHeight()).setDuration(ANIMATION_DURATION); + + } + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + closeSceneMode(); + mPreviewMenuStatus = PREVIEW_MENU_NONE; + } + + @Override + public void onAnimationCancel(Animator animation) { + closeSceneMode(); + mPreviewMenuStatus = PREVIEW_MENU_NONE; } }); - mRenderer.addItem(item2); + vp.start(); + } - // camera switcher - if (group.findPreference(CameraSettings.KEY_CAMERA_ID) != null) { - item = makeItem(R.drawable.ic_switch_back); - IconListPreference lpref = (IconListPreference) group.findPreference( - CameraSettings.KEY_CAMERA_ID); - item.setLabel(lpref.getLabel()); - item.setImageResource(mActivity, - ((IconListPreference) lpref).getIconIds() - [lpref.findIndexOfValue(lpref.getValue())]); + public boolean isOverMenu(MotionEvent ev) { + if (mPopupStatus == POPUP_NONE || mPopupStatus == POPUP_IN_ANIMATION) + return false; + if (mUI.getMenuLayout() == null) + return false; + Rect rec = new Rect(); + mUI.getMenuLayout().getChildAt(0).getHitRect(rec); + return rec.contains((int) ev.getX(), (int) ev.getY()); + } - final PieItem fitem = item; - item.setOnClickListener(new OnClickListener() { + public boolean isOverPreviewMenu(MotionEvent ev) { + if (mPreviewMenuStatus != PREVIEW_MENU_ON) + return false; + if (mUI.getPreviewMenuLayout() == null) + return false; + Rect rec = new Rect(); + mUI.getPreviewMenuLayout().getChildAt(0).getHitRect(rec); + rec.top += (int) mUI.getPreviewMenuLayout().getY(); + rec.bottom += (int) mUI.getPreviewMenuLayout().getY(); + return rec.contains((int) ev.getX(), (int) ev.getY()); + } + + public boolean isMenuBeingShown() { + return mPopupStatus != POPUP_NONE; + } + + public boolean isMenuBeingAnimated() { + return mPopupStatus == POPUP_IN_ANIMATION; + } + + public boolean isPreviewMenuBeingShown() { + return mPreviewMenuStatus == PREVIEW_MENU_ON; + } + + public boolean isPreviewMenuBeingAnimated() { + return mPreviewMenuStatus == PREVIEW_MENU_IN_ANIMATION; + } + + public boolean sendTouchToPreviewMenu(MotionEvent ev) { + return mUI.sendTouchToPreviewMenu(ev); + } + + public boolean sendTouchToMenu(MotionEvent ev) { + return mUI.sendTouchToMenu(ev); + } + + public void initSwitchItem(final String prefKey, View switcher) { + final IconListPreference pref = + (IconListPreference) mPreferenceGroup.findPreference(prefKey); + if (pref == null) + return; + + int[] iconIds = pref.getLargeIconIds(); + int resid = -1; + int index = pref.findIndexOfValue(pref.getValue()); + if (!pref.getUseSingleIcon() && iconIds != null) { + // Each entry has a corresponding icon. + resid = iconIds[index]; + } else { + // The preference only has a single icon to represent it. + resid = pref.getSingleIcon(); + } + ImageView iv = (ImageView) ((FrameLayout) switcher).getChildAt(0); + iv.setImageResource(resid); + switcher.setVisibility(View.VISIBLE); + mPreferences.add(pref); + mPreferenceMap.put(pref, switcher); + switcher.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(prefKey); + if (pref == null) + return; + int index = pref.findIndexOfValue(pref.getValue()); + CharSequence[] values = pref.getEntryValues(); + index = (index + 1) % values.length; + pref.setValueIndex(index); + ImageView iv = (ImageView) ((FrameLayout) v).getChildAt(0); + iv.setImageResource(((IconListPreference) pref).getLargeIconIds()[index]); + if (prefKey.equals(CameraSettings.KEY_CAMERA_ID)) + mListener.onCameraPickerClicked(index); + reloadPreference(pref); + onSettingChanged(pref); + } + }); + } + + public void initFilterModeButton(View button) { + button.setVisibility(View.INVISIBLE); + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_COLOR_EFFECT); + if (pref == null) + return; + + int[] iconIds = pref.getLargeIconIds(); + int resid = -1; + // The preference only has a single icon to represent it. + resid = pref.getSingleIcon(); + ImageView iv = (ImageView) ((FrameLayout) button).getChildAt(0); + iv.setImageResource(resid); + button.setVisibility(View.VISIBLE); + button.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + addFilterMode(); + View view = mUI.getPreviewMenuLayout().getChildAt(0); + animateSlideIn(view, previewMenuSize, false); + } + }); + } + + public void addModeBack() { + if (mSceneStatus == MODE_FILTER) { + addFilterMode(); + } + } + + public void addFilterMode() { + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_COLOR_EFFECT); + if (pref == null) + return; + + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + CharSequence[] entries = pref.getEntries(); + + Resources r = mActivity.getResources(); + int height = (int) (r.getDimension(R.dimen.filter_mode_height) + 2 + * r.getDimension(R.dimen.filter_mode_padding) + 1); + int width = (int) (r.getDimension(R.dimen.filter_mode_width) + 2 + * r.getDimension(R.dimen.filter_mode_padding) + 1); + + int gridRes = 0; + boolean portrait = (rotation == 0) || (rotation == 180); + int size = height; + if (portrait) { + gridRes = R.layout.vertical_grid; + size = width; + } else { + gridRes = R.layout.horiz_grid; + } + previewMenuSize = size; + mUI.hideUI(); + mPreviewMenuStatus = PREVIEW_MENU_ON; + mSceneStatus = MODE_FILTER; + + int[] thumbnails = pref.getThumbnailIds(); + + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + FrameLayout basic = (FrameLayout) inflater.inflate( + gridRes, null, false); + + mUI.dismissSceneModeMenu(); + LinearLayout previewMenuLayout = new LinearLayout(mActivity); + mUI.setPreviewMenuLayout(previewMenuLayout); + ViewGroup.LayoutParams params = null; + if (portrait) { + params = new ViewGroup.LayoutParams(size, LayoutParams.MATCH_PARENT); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + } else { + params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, size); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + previewMenuLayout.setY(display.getHeight() - size); + } + basic.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)); + LinearLayout layout = (LinearLayout) basic.findViewById(R.id.layout); + + final View[] views = new View[entries.length]; + int init = pref.getCurrentIndex(); + for (int i = 0; i < entries.length; i++) { + LinearLayout layout2 = (LinearLayout) inflater.inflate( + R.layout.filter_mode_view, null, false); + + ImageView imageView = (ImageView) layout2.findViewById(R.id.image); + final int j = i; + + layout2.setOnTouchListener(new View.OnTouchListener() { + private long startTime; @Override - public void onClick(PieItem item) { - // Find the index of next camera. - ListPreference pref = - mPreferenceGroup.findPreference(CameraSettings.KEY_CAMERA_ID); - if (pref != null) { - int index = pref.findIndexOfValue(pref.getValue()); - CharSequence[] values = pref.getEntryValues(); - index = (index + 1) % values.length; - int newCameraId = Integer.parseInt((String) values[index]); - fitem.setImageResource(mActivity, - ((IconListPreference) pref).getIconIds()[index]); - fitem.setLabel(pref.getLabel()); - mListener.onCameraPickerClicked(newCameraId); + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + startTime = System.currentTimeMillis(); + } else if (event.getAction() == MotionEvent.ACTION_UP) { + if (System.currentTimeMillis() - startTime < CLICK_THRESHOLD) { + pref.setValueIndex(j); + for (View v1 : views) { + v1.setBackground(null); + } + ImageView image = (ImageView) v.findViewById(R.id.image); + image.setBackgroundColor(0xff33b5e5); + onSettingChanged(pref); + } + } + return true; } }); - mRenderer.addItem(item); + + views[j] = imageView; + if (i == init) + imageView.setBackgroundColor(0xff33b5e5); + TextView label = (TextView) layout2.findViewById(R.id.label); + imageView.setImageResource(thumbnails[i]); + label.setText(entries[i]); + layout.addView(layout2); } + previewMenuLayout.addView(basic); + mPreviewMenu = basic; } - @Override - public void reloadPreferences() { - super.reloadPreferences(); - if (mPopup1 != null) { - mPopup1.reloadPreference(); - } - if (mPopup2 != null) { - mPopup2.reloadPreference(); + public void openFirstLevel() { + if (isMenuBeingShown() || CameraControls.isAnimating()) + return; + if (mListMenu == null || mPopupStatus != POPUP_FIRST_LEVEL) { + initializePopup(); + mPopupStatus = POPUP_FIRST_LEVEL; } + mUI.showPopup(mListMenu, 1, true); } public void setPreference(String key, String value) { @@ -176,7 +580,7 @@ public class VideoMenu extends PieController } public void overrideCDSMode() { - if (mPopup2 != null) { + if (mListMenu != null) { ListPreference pref_tnr = mPreferenceGroup. findPreference(CameraSettings.KEY_VIDEO_TNR_MODE); ListPreference pref_cds = mPreferenceGroup. @@ -190,9 +594,9 @@ public class VideoMenu extends PieController if ((tnr != null) && !mActivity.getString(R.string. pref_camera_video_tnr_default).equals(tnr)) { - ((MoreSettingPopup) mPopup2).setPreferenceEnabled( + mListMenu.setPreferenceEnabled( CameraSettings.KEY_VIDEO_CDS_MODE,false); - ((MoreSettingPopup) mPopup2).overrideSettings( + mListMenu.overrideSettings( CameraSettings.KEY_VIDEO_CDS_MODE, mActivity.getString(R.string.pref_camera_video_cds_value_off)); mIsVideoTNREnabled = true; @@ -203,10 +607,10 @@ public class VideoMenu extends PieController mIsVideoCDSUpdated = true; } } else if (tnr != null) { - ((MoreSettingPopup) mPopup2).setPreferenceEnabled( + mListMenu.setPreferenceEnabled( CameraSettings.KEY_VIDEO_CDS_MODE,true); if (mIsVideoTNREnabled) { - ((MoreSettingPopup) mPopup2).overrideSettings( + mListMenu.overrideSettings( CameraSettings.KEY_VIDEO_CDS_MODE, mPrevSavedVideoCDS); mIsVideoTNREnabled = false; mIsVideoCDSUpdated = false; @@ -216,49 +620,46 @@ public class VideoMenu extends PieController } @Override - public void overrideSettings(final String ... keyvalues) { + public void overrideSettings(final String... keyvalues) { overrideCDSMode(); super.overrideSettings(keyvalues); - if (((mPopup1 == null) && (mPopup2 == null)) || mPopupStatus != POPUP_FIRST_LEVEL) { + if (((mListMenu == null)) || mPopupStatus != POPUP_FIRST_LEVEL) { mPopupStatus = POPUP_FIRST_LEVEL; initializePopup(); } - ((MoreSettingPopup) mPopup1).overrideSettings(keyvalues); - ((MoreSettingPopup) mPopup2).overrideSettings(keyvalues); + mListMenu.overrideSettings(keyvalues); + } @Override // Hit when an item in the second-level popup gets selected public void onListPrefChanged(ListPreference pref) { - if (mPopup1 != null && mPopup2 != null) { - if (mPopupStatus == POPUP_SECOND_LEVEL) { - mUI.dismissPopup(true); - mPopup1.reloadPreference(); - mPopup2.reloadPreference(); - } + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mListMenu.reloadPreference(); + animateFadeOut(mListSubMenu, 2); } super.onSettingChanged(pref); + ((ListMenu) mListMenu).resetHighlight(); } protected void initializePopup() { LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( Context.LAYOUT_INFLATER_SERVICE); - MoreSettingPopup popup1 = (MoreSettingPopup) inflater.inflate( - R.layout.more_setting_popup, null, false); + ListMenu popup1 = (ListMenu) inflater.inflate( + R.layout.list_menu, null, false); popup1.setSettingChangedListener(this); - popup1.initialize(mPreferenceGroup, mOtherKeys1); + String[] keys = mOtherKeys1; + if (mActivity.isDeveloperMenuEnabled()) + keys = mOtherKeys2; + popup1.initialize(mPreferenceGroup, keys); if (mActivity.isSecureCamera()) { - // Prevent location preference from getting changed in secure camera mode + // Prevent location preference from getting changed in secure camera + // mode popup1.setPreferenceEnabled(CameraSettings.KEY_RECORD_LOCATION, false); } - mPopup1 = popup1; + mListMenu = popup1; - MoreSettingPopup popup2 = (MoreSettingPopup) inflater.inflate( - R.layout.more_setting_popup, null, false); - popup2.setSettingChangedListener(this); - popup2.initialize(mPreferenceGroup, mOtherKeys2); - mPopup2 = popup2; overrideCDSMode(); } @@ -268,40 +669,75 @@ public class VideoMenu extends PieController initializePopup(); mPopupStatus = POPUP_FIRST_LEVEL; if (topPopupOnly) { - if(popupNum == 1) mUI.showPopup(mPopup1); - else if(popupNum == 2) mUI.showPopup(mPopup2); + mUI.showPopup(mListMenu, 1, false); } } else { initializePopup(); } } + public void hideUI() { + mFrontBackSwitcher.setVisibility(View.INVISIBLE); + mFilterModeSwitcher.setVisibility(View.INVISIBLE); + } + + public void showUI() { + mFrontBackSwitcher.setVisibility(View.VISIBLE); + mFilterModeSwitcher.setVisibility(View.VISIBLE); + } + @Override // Hit when an item in the first-level popup gets selected, then bring up // the second-level popup public void onPreferenceClicked(ListPreference pref) { - if (mPopupStatus != POPUP_FIRST_LEVEL) return; + onPreferenceClicked(pref, 0); + } + @Override + // Hit when an item in the first-level popup gets selected, then bring up + // the second-level popup + public void onPreferenceClicked(ListPreference pref, int y) { LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( Context.LAYOUT_INFLATER_SERVICE); - if (CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL.equals(pref.getKey())) { - TimeIntervalPopup timeInterval = (TimeIntervalPopup) inflater.inflate( - R.layout.time_interval_popup, null, false); - timeInterval.initialize((IconListPreference) pref); - timeInterval.setSettingChangedListener(this); - mUI.dismissPopup(true); - mPopup1 = timeInterval; + ListSubMenu basic = (ListSubMenu) inflater.inflate( + R.layout.list_sub_menu, null, false); + basic.initialize(pref, y); + basic.setSettingChangedListener(this); + mUI.removeLevel2(); + mListSubMenu = basic; + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mUI.showPopup(mListSubMenu, 2, false); } else { - ListPrefSettingPopup basic = (ListPrefSettingPopup) inflater.inflate( - R.layout.list_pref_setting_popup, null, false); - basic.initialize(pref); - basic.setSettingChangedListener(this); - mUI.dismissPopup(true); - mPopup1 = basic; + mUI.showPopup(mListSubMenu, 2, true); } - mUI.showPopup(mPopup1); mPopupStatus = POPUP_SECOND_LEVEL; } + public void onListMenuTouched() { + mUI.removeLevel2(); + } + + public void closeAllView() { + if (mUI != null) + mUI.removeLevel2(); + + if (mListMenu != null) + animateSlideOut(mListMenu, 1); + animateSlideOutPreviewMenu(); + } + + public void closeView() { + if (mUI != null) + mUI.removeLevel2(); + + if (mListMenu != null) + animateSlideOut(mListMenu, 1); + } + + @Override + public void onSettingChanged(ListPreference pref) { + super.onSettingChanged(pref); + } + } diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java index 77e041d0b..e66d529b3 100755..100644 --- a/src/com/android/camera/VideoModule.java +++ b/src/com/android/camera/VideoModule.java @@ -28,7 +28,6 @@ import android.content.IntentFilter; import android.content.SharedPreferences.Editor; import android.content.res.Configuration; import android.graphics.Bitmap; -import android.graphics.SurfaceTexture; import android.graphics.ImageFormat; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; @@ -52,6 +51,7 @@ import android.provider.MediaStore.Video; import android.util.Log; import android.view.KeyEvent; import android.view.OrientationEventListener; +import android.view.SurfaceHolder; import android.view.View; import android.view.WindowManager; import android.widget.Toast; @@ -686,8 +686,10 @@ public class VideoModule implements CameraModule, if (stop) { onStopVideoRecording(); + mUI.showUIafterRecording(); } else { startVideoRecording(); + mUI.hideUIwhileRecording(); } mUI.enableShutter(false); @@ -768,11 +770,11 @@ public class VideoModule implements CameraModule, String videoQuality = mPreferences.getString(CameraSettings.KEY_VIDEO_QUALITY, null); if (videoQuality == null) { - mParameters = mCameraDevice.getParameters(); + mParameters = mCameraDevice.getParameters(); String defaultQuality = mActivity.getResources().getString( R.string.pref_video_quality_default); boolean hasProfile = CamcorderProfile.hasProfile( - Integer.parseInt(defaultQuality)); + CameraSettings.VIDEO_QUALITY_TABLE.get(defaultQuality)); if (hasProfile == true){ videoQuality = defaultQuality; } else { @@ -782,7 +784,7 @@ public class VideoModule implements CameraModule, } mPreferences.edit().putString(CameraSettings.KEY_VIDEO_QUALITY, videoQuality); } - int quality = Integer.valueOf(videoQuality); + int quality = CameraSettings.VIDEO_QUALITY_TABLE.get(videoQuality); // Set video quality. Intent intent = mActivity.getIntent(); @@ -1026,6 +1028,7 @@ public class VideoModule implements CameraModule, private void setDisplayOrientation() { mDisplayRotation = CameraUtil.getDisplayRotation(mActivity); mCameraDisplayOrientation = CameraUtil.getDisplayOrientation(mDisplayRotation, mCameraId); + mUI.setDisplayOrientation(mCameraDisplayOrientation); // Change the camera display orientation if (mCameraDevice != null) { mCameraDevice.setDisplayOrientation(mCameraDisplayOrientation); @@ -1058,9 +1061,11 @@ public class VideoModule implements CameraModule, Log.v(TAG, "startPreview"); mStartPrevPending = true; - SurfaceTexture surfaceTexture = mUI.getSurfaceTexture(); - if (!mPreferenceRead || surfaceTexture == null || mPaused == true || - mCameraDevice == null) { + SurfaceHolder sh = null; + Log.v(TAG, "startPreview: SurfaceHolder (MDP path)"); + sh = mUI.getSurfaceHolder(); + + if (!mPreferenceRead || mPaused == true || mCameraDevice == null) { mStartPrevPending = false; return; } @@ -1075,7 +1080,7 @@ public class VideoModule implements CameraModule, setCameraParameters(); try { - mCameraDevice.setPreviewTexture(surfaceTexture); + mCameraDevice.setPreviewDisplay(sh); mCameraDevice.startPreview(); mPreviewing = true; onPreviewStarted(); @@ -1180,10 +1185,10 @@ public class VideoModule implements CameraModule, if (mMediaRecorderRecording) { onStopVideoRecording(); return true; - } else if (mUI.hidePieRenderer()) { + } else if (mUI.hideSwitcherPopup()) { return true; } else { - return mUI.removeTopLevelPopup(); + return mUI.onBackPressed(); } } @@ -1519,6 +1524,10 @@ public class VideoModule implements CameraModule, mCurrentVideoValues = null; } + public void updatePreviewThumbnail() { + mUI.updateWithNewPreviewThumbnail(); + } + private void deleteVideoFile(String fileName) { Log.v(TAG, "Deleting video " + fileName); File f = new File(fileName); diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java index 899226bb4..3e23fca83 100644 --- a/src/com/android/camera/VideoUI.java +++ b/src/com/android/camera/VideoUI.java @@ -16,11 +16,12 @@ package com.android.camera; +import java.util.List; + import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Matrix; -import android.graphics.SurfaceTexture; import android.graphics.drawable.ColorDrawable; import android.hardware.Camera.Parameters; import android.os.Handler; @@ -28,19 +29,23 @@ import android.os.Message; import android.util.Log; import android.view.Gravity; import android.view.SurfaceHolder; +import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; -import android.view.TextureView; -import android.view.TextureView.SurfaceTextureListener; +import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLayoutChangeListener; import android.view.ViewGroup; +import android.view.ViewPropertyAnimator; +import android.widget.FrameLayout; import android.widget.FrameLayout.LayoutParams; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.ListView; import android.widget.PopupWindow; import android.widget.TextView; +import com.android.camera.CameraActivity.UpdatePreviewThumbnail; import com.android.camera.CameraPreference.OnPreferenceChangedListener; import com.android.camera.ui.AbstractSettingPopup; import com.android.camera.ui.CameraControls; @@ -49,24 +54,21 @@ import com.android.camera.ui.ModuleSwitcher; import com.android.camera.ui.PieRenderer; import com.android.camera.ui.RenderOverlay; import com.android.camera.ui.RotateLayout; -import com.android.camera.PauseButton.OnPauseButtonListener; import com.android.camera.ui.ZoomRenderer; import com.android.camera.util.CameraUtil; import org.codeaurora.snapcam.R; -import java.util.List; - public class VideoUI implements PieRenderer.PieListener, PreviewGestures.SingleTapListener, CameraRootView.MyDisplayListener, - SurfaceTextureListener, SurfaceHolder.Callback, + SurfaceHolder.Callback, PauseButton.OnPauseButtonListener { private static final String TAG = "CAM_VideoUI"; private static final int UPDATE_TRANSFORM_MATRIX = 1; // module fields private CameraActivity mActivity; private View mRootView; - private TextureView mTextureView; + private SurfaceHolder mSurfaceHolder; // An review image having same size as preview. It is displayed when // recording is stopped in capture intent. private ImageView mReviewImage; @@ -90,26 +92,35 @@ public class VideoUI implements PieRenderer.PieListener, private OnScreenIndicators mOnScreenIndicators; private RotateLayout mRecordingTimeRect; private boolean mRecordingStarted = false; - private SurfaceTexture mSurfaceTexture; private VideoController mController; private int mZoomMax; private List<Integer> mZoomRatios; - private View mPreviewThumb; + private ImageView mPreviewThumb; private View mFlashOverlay; private boolean mOrientationResize; private boolean mPrevOrientationResize; private boolean mIsTimeLapse = false; + private LinearLayout mMenuLayout; + private LinearLayout mSubMenuLayout; + private LinearLayout mPreviewMenuLayout; private View mPreviewCover; private SurfaceView mSurfaceView = null; private int mPreviewWidth = 0; private int mPreviewHeight = 0; - private float mSurfaceTextureUncroppedWidth; - private float mSurfaceTextureUncroppedHeight; + private int mOriginalPreviewWidth = 0; + private int mOriginalPreviewHeight = 0; private float mAspectRatio = 4f / 3f; private boolean mAspectRatioResize; private Matrix mMatrix = null; private final AnimationManager mAnimationManager; + private boolean mUIhidden = false; + private int mPreviewOrientation = -1; + + // temporary variables for updating SurfaceView + private int mTempWidth; + private int mTempHeight; + private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { @@ -122,27 +133,54 @@ public class VideoUI implements PieRenderer.PieListener, } } }; + + private final Handler mSurfaceViewUpdateHandler = new Handler(); + + private Runnable updateSurfaceView = new Runnable() { + + @Override + public void run() { + FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mSurfaceView + .getLayoutParams(); + params.width = mTempWidth; + params.height = mTempHeight; + mSurfaceView.setLayoutParams(params); + } + }; + private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { int width = right - left; int height = bottom - top; - // Full-screen screennail - int w = width; - int h = height; - if (CameraUtil.getDisplayRotation(mActivity) % 180 != 0) { - w = height; - h = width; + + int orientation = mActivity.getResources().getConfiguration().orientation; + if ((orientation == Configuration.ORIENTATION_PORTRAIT && width > height) + || (orientation == Configuration.ORIENTATION_LANDSCAPE && width < height)) { + // The screen has rotated; swap SurfaceView width & height + // to ensure correct preview + int oldWidth = width; + width = height; + height = oldWidth; + Log.d(TAG, "Swapping SurfaceView width & height dimensions"); + if (mOriginalPreviewWidth != 0 && mOriginalPreviewHeight != 0) { + int temp = mOriginalPreviewWidth; + mOriginalPreviewWidth = mOriginalPreviewHeight; + mOriginalPreviewHeight = temp; + } } if (mPreviewWidth != width || mPreviewHeight != height || (mOrientationResize != mPrevOrientationResize) - || (mAspectRatioResize)) { + || mAspectRatioResize) { + if (mOriginalPreviewWidth == 0) mOriginalPreviewWidth = width; + if (mOriginalPreviewHeight == 0) mOriginalPreviewHeight = height; mPreviewWidth = width; mPreviewHeight = height; - onScreenSizeChanged(width, height, w, h); + setTransformMatrix(mOriginalPreviewWidth, mOriginalPreviewHeight); mAspectRatioResize = false; } + mVideoMenu.tryToCloseSubList(); } }; @@ -165,7 +203,7 @@ public class VideoUI implements PieRenderer.PieListener, super.dismiss(); popupDismissed(); showUI(); - mVideoMenu.popupDismissed(topLevelOnly); + // mVideoMenu.popupDismissed(topLevelOnly); // Switch back into fullscreen/lights-out mode after popup // is dimissed. @@ -183,16 +221,24 @@ public class VideoUI implements PieRenderer.PieListener, mActivity = activity; mController = controller; mRootView = parent; - mActivity.getLayoutInflater().inflate(R.layout.video_module, (ViewGroup) mRootView, true); + mActivity.getLayoutInflater().inflate(R.layout.video_module, + (ViewGroup) mRootView, true); mPreviewCover = mRootView.findViewById(R.id.preview_cover); - mTextureView = (TextureView) mRootView.findViewById(R.id.preview_content); - mTextureView.setSurfaceTextureListener(this); - mTextureView.addOnLayoutChangeListener(mLayoutListener); + // display the view + mSurfaceView = (SurfaceView) mRootView.findViewById(R.id.mdp_preview_content); + mSurfaceView.setVisibility(View.VISIBLE); + mSurfaceHolder = mSurfaceView.getHolder(); + mSurfaceHolder.addCallback(this); + mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + mSurfaceView.addOnLayoutChangeListener(mLayoutListener); + Log.v(TAG, "Using mdp_preview_content (MDP path)"); + mFlashOverlay = mRootView.findViewById(R.id.flash_overlay); mShutterButton = (ShutterButton) mRootView.findViewById(R.id.shutter_button); mSwitcher = (ModuleSwitcher) mRootView.findViewById(R.id.camera_switcher); mSwitcher.setCurrentIndex(ModuleSwitcher.VIDEO_MODULE_INDEX); mSwitcher.setSwitchListener(mActivity); + initializeMiscControls(); initializeControlByIntent(); initializeOverlay(); @@ -202,15 +248,35 @@ public class VideoUI implements PieRenderer.PieListener, mPrevOrientationResize = false; } + public void updatePreviewThumbnail() { + mPreviewThumb.setVisibility(View.VISIBLE); + Bitmap bitmap = mActivity.getPreviewThumbBitmap(); + if (bitmap != null) + mPreviewThumb.setImageBitmap(bitmap); + else { + UpdatePreviewThumbnail task = mActivity.new UpdatePreviewThumbnail(mPreviewThumb); + task.execute(); + } + } + + public void updateWithNewPreviewThumbnail() { + mPreviewThumb.setVisibility(View.VISIBLE); + UpdatePreviewThumbnail task = mActivity.new UpdatePreviewThumbnail(mPreviewThumb); + task.execute(); + } + public void cameraOrientationPreviewResize(boolean orientation){ mPrevOrientationResize = mOrientationResize; mOrientationResize = orientation; } public void initializeSurfaceView() { - mSurfaceView = new SurfaceView(mActivity); - ((ViewGroup) mRootView).addView(mSurfaceView, 0); - mSurfaceView.getHolder().addCallback(this); + if (mSurfaceView == null) { + mSurfaceView = new SurfaceView(mActivity); + ((ViewGroup) mRootView).addView(mSurfaceView, 0); + mSurfaceHolder = mSurfaceView.getHolder(); + mSurfaceHolder.addCallback(this); + } } private void initializeControlByIntent() { @@ -218,9 +284,7 @@ public class VideoUI implements PieRenderer.PieListener, mMenuButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - if (mPieRenderer != null) { - mPieRenderer.showInCenter(); - } + mVideoMenu.openFirstLevel(); } }); @@ -281,7 +345,10 @@ public class VideoUI implements PieRenderer.PieListener, mAspectRatioResize = true; mAspectRatio = ratio; } - mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX); + + if (mPreviewWidth > 0 && mPreviewHeight > 0) { + mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX); + } } public int getPreviewWidth() { @@ -292,22 +359,17 @@ public class VideoUI implements PieRenderer.PieListener, return mPreviewHeight; } - public void onScreenSizeChanged(int width, int height, int previewWidth, int previewHeight) { - setTransformMatrix(width, height); - } - private void setTransformMatrix(int width, int height) { - mMatrix = mTextureView.getTransform(mMatrix); - int orientation = CameraUtil.getDisplayRotation(mActivity); - float scaleX = 1f, scaleY = 1f; + mMatrix = mSurfaceView.getMatrix(); + float scaledTextureWidth, scaledTextureHeight; - if (mOrientationResize){ - if (width/mAspectRatio > height){ - scaledTextureHeight = height; - scaledTextureWidth = (int)(height * mAspectRatio + 0.5f); - } else { + if (mOrientationResize) { + scaledTextureWidth = height * mAspectRatio; + if (scaledTextureWidth > width) { scaledTextureWidth = width; - scaledTextureHeight = (int)(width / mAspectRatio + 0.5f); + scaledTextureHeight = scaledTextureWidth / mAspectRatio; + } else { + scaledTextureHeight = height; } } else { if (width > height) { @@ -319,23 +381,11 @@ public class VideoUI implements PieRenderer.PieListener, } } - if (mSurfaceTextureUncroppedWidth != scaledTextureWidth || - mSurfaceTextureUncroppedHeight != scaledTextureHeight) { - mSurfaceTextureUncroppedWidth = scaledTextureWidth; - mSurfaceTextureUncroppedHeight = scaledTextureHeight; - } - scaleX = scaledTextureWidth / width; - scaleY = scaledTextureHeight / height; - mMatrix.setScale(scaleX, scaleY, (float) width / 2, (float) height / 2); - mTextureView.setTransform(mMatrix); - - if (mSurfaceView != null && mSurfaceView.getVisibility() == View.VISIBLE) { - LayoutParams lp = (LayoutParams) mSurfaceView.getLayoutParams(); - lp.width = (int) mSurfaceTextureUncroppedWidth; - lp.height = (int) mSurfaceTextureUncroppedHeight; - lp.gravity = Gravity.CENTER; - mSurfaceView.requestLayout(); - } + Log.v(TAG, "setTransformMatrix: scaledTextureWidth = " + scaledTextureWidth + + ", scaledTextureHeight = " + scaledTextureHeight); + mTempWidth = (int) scaledTextureWidth; + mTempHeight = (int) scaledTextureHeight; + mHandler.post(updateSurfaceView); } /** @@ -350,10 +400,6 @@ public class VideoUI implements PieRenderer.PieListener, */ public void animateCapture() { Bitmap bitmap = null; - if (mTextureView != null) { - bitmap = mTextureView.getBitmap((int) mSurfaceTextureUncroppedWidth / 2, - (int) mSurfaceTextureUncroppedHeight / 2); - } animateCapture(bitmap); } @@ -366,7 +412,7 @@ public class VideoUI implements PieRenderer.PieListener, Log.e(TAG, "No valid bitmap for capture animation."); return; } - ((ImageView) mPreviewThumb).setImageBitmap(bitmap); + mPreviewThumb.setImageBitmap(bitmap); mAnimationManager.startCaptureAnimation(mPreviewThumb); } @@ -378,16 +424,22 @@ public class VideoUI implements PieRenderer.PieListener, } public void hideUI() { - mCameraControls.setVisibility(View.INVISIBLE); mSwitcher.closePopup(); + if (mUIhidden) + return; + mUIhidden = true; + mCameraControls.hideUI(); } public void showUI() { - mCameraControls.setVisibility(View.VISIBLE); + if (!mUIhidden || (mVideoMenu != null && mVideoMenu.isMenuBeingShown())) + return; + mUIhidden = false; + mCameraControls.showUI(); } public boolean arePreviewControlsVisible() { - return (mCameraControls.getVisibility() == View.VISIBLE); + return !mUIhidden; } public void hideSwitcher() { @@ -401,6 +453,10 @@ public class VideoUI implements PieRenderer.PieListener, public boolean collapseCameraControls() { boolean ret = false; + mSwitcher.closePopup(); + if (mVideoMenu != null) { + mVideoMenu.closeAllView(); + } if (mPopup != null) { dismissPopup(false); ret = true; @@ -429,10 +485,20 @@ public class VideoUI implements PieRenderer.PieListener, ((CameraRootView) mRootView).setDisplayChangeListener(this); } + public void setDisplayOrientation(int orientation) { + if ((mPreviewOrientation == -1 || mPreviewOrientation != orientation) + && mVideoMenu != null && mVideoMenu.isPreviewMenuBeingShown()) { + dismissSceneModeMenu(); + mVideoMenu.addModeBack(); + } + mPreviewOrientation = orientation; + } + public void removeDisplayChangeListener() { ((CameraRootView) mRootView).removeDisplayChangeListener(); } +// no customvideo? public void overrideSettings(final String... keyvalues) { if (mVideoMenu != null) { mVideoMenu.overrideSettings(keyvalues); @@ -453,18 +519,18 @@ public class VideoUI implements PieRenderer.PieListener, } public SurfaceHolder getSurfaceHolder() { - return mSurfaceView.getHolder(); + return mSurfaceHolder; } public void hideSurfaceView() { mSurfaceView.setVisibility(View.GONE); - mTextureView.setVisibility(View.VISIBLE); + setTransformMatrix(mPreviewWidth, mPreviewHeight); } public void showSurfaceView() { mSurfaceView.setVisibility(View.VISIBLE); - mTextureView.setVisibility(View.GONE); + setTransformMatrix(mPreviewWidth, mPreviewHeight); } @@ -472,9 +538,12 @@ public class VideoUI implements PieRenderer.PieListener, mRenderOverlay = (RenderOverlay) mRootView.findViewById(R.id.render_overlay); if (mPieRenderer == null) { mPieRenderer = new PieRenderer(mActivity); - mVideoMenu = new VideoMenu(mActivity, this, mPieRenderer); + // mVideoMenu = new VideoMenu(mActivity, this, mPieRenderer); mPieRenderer.setPieListener(this); } + if (mVideoMenu == null) { + mVideoMenu = new VideoMenu(mActivity, this); + } mRenderOverlay.addRenderer(mPieRenderer); if (mZoomRenderer == null) { mZoomRenderer = new ZoomRenderer(mActivity); @@ -484,18 +553,22 @@ public class VideoUI implements PieRenderer.PieListener, mGestures = new PreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer); mRenderOverlay.setGestures(mGestures); } + mGestures.setVideoMenu(mVideoMenu); + mGestures.setRenderOverlay(mRenderOverlay); - mPreviewThumb = mRootView.findViewById(R.id.preview_thumb); + mPreviewThumb = (ImageView) mRootView.findViewById(R.id.preview_thumb); mPreviewThumb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // Do not allow navigation to filmstrip during video recording - if (!mRecordingStarted) { + if (!mRecordingStarted && !CameraControls.isAnimating()) { mActivity.gotoGallery(); } } }); + + mActivity.setPreviewGestures(mGestures); } public void setPrefChangedListener(OnPreferenceChangedListener listener) { @@ -537,12 +610,16 @@ public class VideoUI implements PieRenderer.PieListener, ratio = 1 / ratio; } - if (ratio != mAspectRatio){ + if (ratio != mAspectRatio) { mAspectRatioResize = true; mAspectRatio = (float)ratio; } - mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX); + mSurfaceView.requestLayout(); + + if (mPreviewWidth > 0 && mPreviewHeight > 0) { + mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX); + } } public void showTimeLapseUI(boolean enable) { @@ -570,6 +647,115 @@ public class VideoUI implements PieRenderer.PieListener, mPopup = null; } + public boolean onBackPressed() { + if (mVideoMenu != null && mVideoMenu.handleBackKey()) { + return true; + } + if (hidePieRenderer()) { + return true; + } else { + return removeTopLevelPopup(); + } + } + + public void cleanupListview() { + showUI(); + mActivity.setSystemBarsVisibility(false); + } + + public void dismissLevel1() { + if (mMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mMenuLayout); + mMenuLayout = null; + } + } + + public void dismissLevel2() { + if (mSubMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mSubMenuLayout); + mSubMenuLayout = null; + } + } + + public boolean sendTouchToPreviewMenu(MotionEvent ev) { + return mPreviewMenuLayout.dispatchTouchEvent(ev); + } + + public boolean sendTouchToMenu(MotionEvent ev) { + View v = mMenuLayout.getChildAt(0); + return v.dispatchTouchEvent(ev); + } + + public void dismissSceneModeMenu() { + if (mPreviewMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mPreviewMenuLayout); + mPreviewMenuLayout = null; + } + } + + public void removeSceneModeMenu() { + if (mPreviewMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mPreviewMenuLayout); + mPreviewMenuLayout = null; + } + cleanupListview(); + } + + public void removeLevel2() { + if (mSubMenuLayout != null) { + View v = mSubMenuLayout.getChildAt(0); + mSubMenuLayout.removeView(v); + } + } + + public void showPopup(ListView popup, int level, boolean animate) { + hideUI(); + + popup.setVisibility(View.VISIBLE); + if (level == 1) { + if (mMenuLayout == null) { + mMenuLayout = new LinearLayout(mActivity); + ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_1, LayoutParams.WRAP_CONTENT); + mMenuLayout.setLayoutParams(params); + ((ViewGroup) mRootView).addView(mMenuLayout); + } + mMenuLayout.addView(popup); + } + if (level == 2) { + if (mSubMenuLayout == null) { + mSubMenuLayout = new LinearLayout(mActivity); + ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_2, LayoutParams.WRAP_CONTENT); + mSubMenuLayout.setLayoutParams(params); + + ((ViewGroup) mRootView).addView(mSubMenuLayout); + } + mSubMenuLayout.addView(popup); + mSubMenuLayout.setX(CameraActivity.SETTING_LIST_WIDTH_1); + } + if (animate) { + if (level == 1) + mVideoMenu.animateSlideIn(popup, CameraActivity.SETTING_LIST_WIDTH_1, true); + if (level == 2) + mVideoMenu.animateFadeIn(popup); + } + else + popup.setAlpha(0.85f); + } + + public ViewGroup getMenuLayout() { + return mMenuLayout; + } + + public void setPreviewMenuLayout(LinearLayout layout) { + mPreviewMenuLayout = layout; + } + + public ViewGroup getPreviewMenuLayout() { + return mPreviewMenuLayout; + } + public void showPopup(AbstractSettingPopup popup) { hideUI(); @@ -636,7 +822,7 @@ public class VideoUI implements PieRenderer.PieListener, mMenuButton.setVisibility(recording ? View.GONE : View.VISIBLE); mOnScreenIndicators.setVisibility(recording ? View.GONE : View.VISIBLE); if (recording) { - mShutterButton.setImageResource(R.drawable.btn_shutter_video_recording); + mShutterButton.setImageResource(R.drawable.shutter_button_video_stop); hideSwitcher(); mRecordingTimeView.setText(""); mRecordingTimeView.setVisibility(View.VISIBLE); @@ -651,6 +837,14 @@ public class VideoUI implements PieRenderer.PieListener, } } + public void hideUIwhileRecording() { + mVideoMenu.hideUI(); + } + + public void showUIafterRecording() { + mVideoMenu.showUI(); + } + public void showReviewImage(Bitmap bitmap) { mReviewImage.setImageBitmap(bitmap); mReviewImage.setVisibility(View.VISIBLE); @@ -681,9 +875,6 @@ public class VideoUI implements PieRenderer.PieListener, if (mOnScreenIndicators != null) { mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE); } - if (mMenuButton != null) { - mMenuButton.setVisibility(show ? View.VISIBLE : View.GONE); - } } public void onPreviewFocusChanged(boolean previewFocused) { @@ -777,65 +968,50 @@ public class VideoUI implements PieRenderer.PieListener, } } - public SurfaceTexture getSurfaceTexture() { - return mSurfaceTexture; - } - - // SurfaceTexture callbacks - @Override - public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { - mSurfaceTexture = surface; - mController.onPreviewUIReady(); - } - - @Override - public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { - mSurfaceTexture = null; - mController.onPreviewUIDestroyed(); - Log.d(TAG, "surfaceTexture is destroyed"); - return true; - } - - @Override - public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { - } - + // SurfaceHolder callbacks @Override - public void onSurfaceTextureUpdated(SurfaceTexture surface) { + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + Log.v(TAG, "surfaceChanged: width = " + width + ", height = " + height); // Make sure preview cover is hidden if preview data is available. if (mPreviewCover.getVisibility() != View.GONE) { mPreviewCover.setVisibility(View.GONE); } } - // SurfaceHolder callbacks - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - Log.v(TAG, "Surface changed. width=" + width + ". height=" + height); - } - @Override public void surfaceCreated(SurfaceHolder holder) { - Log.v(TAG, "Surface created"); + Log.v(TAG, "surfaceCreated"); + mSurfaceHolder = holder; + mController.onPreviewUIReady(); + if (mPreviewWidth != 0 && mPreviewHeight != 0) { + // Re-apply transform matrix for new surface texture + setTransformMatrix(mPreviewWidth, mPreviewHeight); + } + updatePreviewThumbnail(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { - Log.v(TAG, "Surface destroyed"); - mController.stopPreview(); + Log.v(TAG, "surfaceDestroyed"); + mSurfaceHolder = null; + mController.onPreviewUIDestroyed(); + } + + public View getRootView() { + return mRootView; } @Override public void onButtonPause() { mRecordingTimeView.setCompoundDrawablesWithIntrinsicBounds( - R.drawable.ic_pausing_indicator, 0, 0, 0); - mController.onButtonPause(); + R.drawable.ic_pausing_indicator, 0, 0, 0); + mController.onButtonPause(); } @Override public void onButtonContinue() { mRecordingTimeView.setCompoundDrawablesWithIntrinsicBounds( - R.drawable.ic_recording_indicator, 0, 0, 0); + R.drawable.ic_recording_indicator, 0, 0, 0); mController.onButtonContinue(); } @@ -848,4 +1024,12 @@ public class VideoUI implements PieRenderer.PieListener, public void setPreference(String key, String value) { mVideoMenu.setPreference(key, value); } + + public boolean hideSwitcherPopup() { + if (mSwitcher != null && mSwitcher.showsPopup()) { + mSwitcher.closePopup(); + return true; + } + return false; + } } diff --git a/src/com/android/camera/WideAnglePanoramaModule.java b/src/com/android/camera/WideAnglePanoramaModule.java index b612ee9e8..40878581e 100644 --- a/src/com/android/camera/WideAnglePanoramaModule.java +++ b/src/com/android/camera/WideAnglePanoramaModule.java @@ -736,6 +736,10 @@ public class WideAnglePanoramaModule } } + public void updatePreviewThumbnail() { + mUI.updatePreviewThumbnail(); + } + // This function will be called upon the first camera frame is available. private void reset() { mCaptureState = CAPTURE_STATE_VIEWFINDER; @@ -1061,6 +1065,10 @@ public class WideAnglePanoramaModule // If panorama is generating low res or high res mosaic, ignore back // key. So the activity will not be destroyed. if (mThreadRunning) return true; + + if (mUI.hideSwitcherPopup()) + return true; + return false; } diff --git a/src/com/android/camera/WideAnglePanoramaUI.java b/src/com/android/camera/WideAnglePanoramaUI.java index 57b414a43..8f9643971 100644 --- a/src/com/android/camera/WideAnglePanoramaUI.java +++ b/src/com/android/camera/WideAnglePanoramaUI.java @@ -34,12 +34,14 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.TextureView; import android.view.View; +import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import com.android.camera.CameraActivity.UpdatePreviewThumbnail; import com.android.camera.ui.CameraControls; import com.android.camera.ui.CameraRootView; import com.android.camera.ui.ModuleSwitcher; @@ -78,6 +80,7 @@ public class WideAnglePanoramaUI implements private TextureView mTextureView; private ShutterButton mShutterButton; private CameraControls mCameraControls; + private ImageView mPreviewThumb; private Matrix mProgressDirectionMatrix = new Matrix(); private float[] mProgressAngle = new float[2]; @@ -104,11 +107,19 @@ public class WideAnglePanoramaUI implements mSwitcher = (ModuleSwitcher) mRootView.findViewById(R.id.camera_switcher); mSwitcher.setCurrentIndex(ModuleSwitcher.WIDE_ANGLE_PANO_MODULE_INDEX); mSwitcher.setSwitchListener(mActivity); + mPreviewThumb = (ImageView) mRootView.findViewById(R.id.preview_thumb); + mPreviewThumb.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (!CameraControls.isAnimating()) + mActivity.gotoGallery(); + } + }); } public void onStartCapture() { hideSwitcher(); - mShutterButton.setImageResource(R.drawable.btn_shutter_recording); + mShutterButton.setImageResource(R.drawable.shutter_button_stop); mCaptureIndicator.setVisibility(View.VISIBLE); showDirectionIndicators(PanoProgressBar.DIRECTION_NONE); } @@ -202,6 +213,23 @@ public class WideAnglePanoramaUI implements mProgressDirectionMatrix.postRotate(orientation); } + public void updatePreviewThumbnail(Bitmap bitmap) { + mPreviewThumb.setVisibility(View.VISIBLE); + mPreviewThumb.setImageBitmap(bitmap); + mActivity.setPreviewThumbnailBitmap(bitmap); + } + + public void updatePreviewThumbnail() { + mPreviewThumb.setVisibility(View.VISIBLE); + Bitmap bitmap = mActivity.getPreviewThumbBitmap(); + if (bitmap != null) + mPreviewThumb.setImageBitmap(bitmap); + else { + UpdatePreviewThumbnail task = mActivity.new UpdatePreviewThumbnail(mPreviewThumb); + task.execute(); + } + } + public void showDirectionIndicators(int direction) { switch (direction) { case PanoProgressBar.DIRECTION_NONE: @@ -227,6 +255,7 @@ public class WideAnglePanoramaUI implements public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) { mSurfaceTexture = surfaceTexture; mController.onPreviewUIReady(); + updatePreviewThumbnail(); } @Override @@ -282,6 +311,9 @@ public class WideAnglePanoramaUI implements // is sometimes not shown due to wrong layout result. It's likely to be // a framework bug. Call requestLayout() as a workaround. mSavingProgressBar.requestLayout(); + + updatePreviewThumbnail(Bitmap.createScaledBitmap(bitmap, + bitmap.getWidth() / 2, bitmap.getHeight() / 2, false)); } public void onConfigurationChanged( @@ -535,4 +567,12 @@ public class WideAnglePanoramaUI implements canvas.restore(); } } + + public boolean hideSwitcherPopup() { + if (mSwitcher != null && mSwitcher.showsPopup()) { + mSwitcher.closePopup(); + return true; + } + return false; + } } diff --git a/src/com/android/camera/data/FixedFirstDataAdapter.java b/src/com/android/camera/data/FixedFirstDataAdapter.java index e26ec2785..03402da43 100644 --- a/src/com/android/camera/data/FixedFirstDataAdapter.java +++ b/src/com/android/camera/data/FixedFirstDataAdapter.java @@ -158,6 +158,7 @@ public class FixedFirstDataAdapter extends AbstractLocalDataAdapterWrapper return (dataID != 0); } }); + mListener.onDataLoaded(); } @Override diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java index 9e0964b4f..1c9419569 100644 --- a/src/com/android/camera/ui/CameraControls.java +++ b/src/com/android/camera/ui/CameraControls.java @@ -16,13 +16,21 @@ package com.android.camera.ui; +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; import android.content.Context; +import android.util.Log; +import android.graphics.drawable.AnimationDrawable; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; +import android.view.ViewPropertyAnimator; import android.widget.FrameLayout; +import java.util.ArrayList; import org.codeaurora.snapcam.R; +import com.android.camera.ui.ModuleSwitcher; +import com.android.camera.ShutterButton; public class CameraControls extends RotatableLayout { @@ -32,8 +40,103 @@ public class CameraControls extends RotatableLayout { private View mShutter; private View mSwitcher; private View mMenu; + private View mFrontBackSwitcher; + private View mHdrSwitcher; private View mIndicators; private View mPreview; + private View mSceneModeSwitcher; + private View mFilterModeSwitcher; + private int mSize; + private static final int WIDTH_GRID = 5; + private static final int HEIGHT_GRID = 7; + private static boolean isAnimating = false; + private ArrayList<View> mViewList; + private static final int FRONT_BACK_INDEX = 0; + private static final int HDR_INDEX = 1; + private static final int SCENE_MODE_INDEX = 2; + private static final int FILTER_MODE_INDEX = 3; + private static final int MENU_INDEX = 4; + private static final int SWITCHER_INDEX = 5; + private static final int SHUTTER_INDEX = 6; + private static final int PREVIEW_INDEX = 7; + private static final int INDICATOR_INDEX = 8; + private static final int ANIME_DURATION = 300; + private float[][] mLocX = new float[4][9]; + private float[][] mLocY = new float[4][9]; + private boolean[] mTempEnabled = new boolean[9]; + private boolean mLocSet = false; + + AnimatorListener outlistener = new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + resetLocation(0, 0); + + mFrontBackSwitcher.setVisibility(View.INVISIBLE); + mHdrSwitcher.setVisibility(View.INVISIBLE); + mSceneModeSwitcher.setVisibility(View.INVISIBLE); + mFilterModeSwitcher.setVisibility(View.INVISIBLE); + + mSwitcher.setVisibility(View.INVISIBLE); + mShutter.setVisibility(View.INVISIBLE); + mMenu.setVisibility(View.INVISIBLE); + mIndicators.setVisibility(View.INVISIBLE); + mPreview.setVisibility(View.INVISIBLE); + isAnimating = false; + enableTouch(true); + } + + @Override + public void onAnimationCancel(Animator animation) { + resetLocation(0, 0); + + mFrontBackSwitcher.setVisibility(View.INVISIBLE); + mHdrSwitcher.setVisibility(View.INVISIBLE); + mSceneModeSwitcher.setVisibility(View.INVISIBLE); + mFilterModeSwitcher.setVisibility(View.INVISIBLE); + + mSwitcher.setVisibility(View.INVISIBLE); + mShutter.setVisibility(View.INVISIBLE); + mMenu.setVisibility(View.INVISIBLE); + mIndicators.setVisibility(View.INVISIBLE); + mPreview.setVisibility(View.INVISIBLE); + isAnimating = false; + enableTouch(true); + } + }; + + AnimatorListener inlistener = new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + isAnimating = false; + resetLocation(0, 0); + enableTouch(true); + } + + @Override + public void onAnimationCancel(Animator animation) { + isAnimating = false; + resetLocation(0, 0); + enableTouch(true); + } + }; public CameraControls(Context context, AttributeSet attrs) { super(context, attrs); @@ -45,15 +148,63 @@ public class CameraControls extends RotatableLayout { setMeasureAllChildren(true); } + public static boolean isAnimating() { + return isAnimating; + } + + public void enableTouch(boolean enable) { + if (enable) { + ((ShutterButton) mShutter).setPressed(false); + mSwitcher.setPressed(false); + mMenu.setPressed(false); + mFrontBackSwitcher.setPressed(false); + mHdrSwitcher.setPressed(false); + mSceneModeSwitcher.setPressed(false); + mFilterModeSwitcher.setPressed(false); + } else { + mTempEnabled[FILTER_MODE_INDEX] = mFilterModeSwitcher.isEnabled(); + } + ((ShutterButton) mShutter).enableTouch(enable); + ((ModuleSwitcher) mSwitcher).enableTouch(enable); + mMenu.setEnabled(enable); + mFrontBackSwitcher.setEnabled(enable); + mHdrSwitcher.setEnabled(enable); + mSceneModeSwitcher.setEnabled(enable); + mPreview.setEnabled(enable); + mFilterModeSwitcher.setEnabled(enable && mTempEnabled[FILTER_MODE_INDEX]); + } + + private void markVisibility() { + mViewList = new ArrayList<View>(); + if (mFrontBackSwitcher.getVisibility() == View.VISIBLE) + mViewList.add(mFrontBackSwitcher); + if (mHdrSwitcher.getVisibility() == View.VISIBLE) + mViewList.add(mHdrSwitcher); + if (mSceneModeSwitcher.getVisibility() == View.VISIBLE) + mViewList.add(mSceneModeSwitcher); + if (mFilterModeSwitcher.getVisibility() == View.VISIBLE) + mViewList.add(mFilterModeSwitcher); + if (mShutter.getVisibility() == View.VISIBLE) + mViewList.add(mShutter); + if (mMenu.getVisibility() == View.VISIBLE) + mViewList.add(mMenu); + if (mIndicators.getVisibility() == View.VISIBLE) + mViewList.add(mIndicators); + } + @Override public void onFinishInflate() { super.onFinishInflate(); mBackgroundView = findViewById(R.id.blocker); mSwitcher = findViewById(R.id.camera_switcher); mShutter = findViewById(R.id.shutter_button); + mFrontBackSwitcher = findViewById(R.id.front_back_switcher); + mHdrSwitcher = findViewById(R.id.hdr_switcher); mMenu = findViewById(R.id.menu); mIndicators = findViewById(R.id.on_screen_indicators); mPreview = findViewById(R.id.preview_thumb); + mSceneModeSwitcher = findViewById(R.id.scene_mode_switcher); + mFilterModeSwitcher = findViewById(R.id.filter_mode_switcher); } @Override @@ -73,27 +224,12 @@ public class CameraControls extends RotatableLayout { v.layout(l, t, r, b); } Rect shutter = new Rect(); - topRight(mPreview, l, t, r, b); - if (size > 0) { - // restrict controls to size - switch (rotation) { - case 0: - case 180: - l = (l + r - size) / 2; - r = l + size; - break; - case 90: - case 270: - t = (t + b - size) / 2; - b = t + size; - break; - } - } - center(mShutter, l, t, r, b, orientation, rotation, shutter); - center(mBackgroundView, l, t, r, b, orientation, rotation, new Rect()); - toLeft(mSwitcher, shutter, rotation); - toRight(mMenu, shutter, rotation); - toRight(mIndicators, shutter, rotation); + center(mShutter, l, t, r, b, orientation, rotation, shutter, SHUTTER_INDEX); + mSize = (int) (Math.max(shutter.right - shutter.left, shutter.bottom - shutter.top) * 1.2f); + center(mBackgroundView, l, t, r, b, orientation, rotation, new Rect(), -1); + mBackgroundView.setVisibility(View.GONE); + setLocation(r - l, b - t); + View retake = findViewById(R.id.btn_retake); if (retake != null) { center(retake, shutter, rotation); @@ -104,41 +240,241 @@ public class CameraControls extends RotatableLayout { } } - private void center(View v, int l, int t, int r, int b, int orientation, int rotation, Rect result) { + private void setLocation(int w, int h) { + int rotation = getUnifiedRotation(); + toIndex(mSwitcher, w, h, rotation, 4, 6, SWITCHER_INDEX); + toIndex(mMenu, w, h, rotation, 4, 0, MENU_INDEX); + toIndex(mIndicators, w, h, rotation, 0, 6, INDICATOR_INDEX); + toIndex(mFrontBackSwitcher, w, h, rotation, 2, 0, FRONT_BACK_INDEX); + toIndex(mPreview, w, h, rotation, 0, 6, PREVIEW_INDEX); + toIndex(mHdrSwitcher, w, h, rotation, 3, 0, HDR_INDEX); + toIndex(mFilterModeSwitcher, w, h, rotation, 1, 0, FILTER_MODE_INDEX); + toIndex(mSceneModeSwitcher, w, h, rotation, 0, 0, SCENE_MODE_INDEX); + } + + private void center(View v, int l, int t, int r, int b, int orientation, int rotation, + Rect result, int idx) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams(); int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin; int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin; switch (rotation) { - case 0: - // phone portrait; controls bottom - result.left = (r + l) / 2 - tw / 2 + lp.leftMargin; - result.right = (r + l) / 2 + tw / 2 - lp.rightMargin; - result.bottom = b - lp.bottomMargin; - result.top = b - th + lp.topMargin; - break; - case 90: - // phone landscape: controls right - result.right = r - lp.rightMargin; - result.left = r - tw + lp.leftMargin; - result.top = (b + t) / 2 - th / 2 + lp.topMargin; - result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin; - break; - case 180: - // phone upside down: controls top - result.left = (r + l) / 2 - tw / 2 + lp.leftMargin; - result.right = (r + l) / 2 + tw / 2 - lp.rightMargin; - result.top = t + lp.topMargin; - result.bottom = t + th - lp.bottomMargin; - break; - case 270: - // reverse landscape: controls left - result.left = l + lp.leftMargin; - result.right = l + tw - lp.rightMargin; - result.top = (b + t) / 2 - th / 2 + lp.topMargin; - result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin; - break; + case 0: + // phone portrait; controls bottom + result.left = (r + l) / 2 - tw / 2 + lp.leftMargin; + result.right = (r + l) / 2 + tw / 2 - lp.rightMargin; + result.bottom = b - lp.bottomMargin; + result.top = b - th + lp.topMargin; + break; + case 90: + // phone landscape: controls right + result.right = r - lp.rightMargin; + result.left = r - tw + lp.leftMargin; + result.top = (b + t) / 2 - th / 2 + lp.topMargin; + result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin; + break; + case 180: + // phone upside down: controls top + result.left = (r + l) / 2 - tw / 2 + lp.leftMargin; + result.right = (r + l) / 2 + tw / 2 - lp.rightMargin; + result.top = t + lp.topMargin; + result.bottom = t + th - lp.bottomMargin; + break; + case 270: + // reverse landscape: controls left + result.left = l + lp.leftMargin; + result.right = l + tw - lp.rightMargin; + result.top = (b + t) / 2 - th / 2 + lp.topMargin; + result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin; + break; } v.layout(result.left, result.top, result.right, result.bottom); + if (idx != -1) { + int idx1 = rotation / 90; + int idx2 = idx; + mLocX[idx1][idx2] = result.left; + mLocY[idx1][idx2] = result.top; + } + } + + private void resetLocation(float x, float y) { + int rotation = getUnifiedRotation(); + int idx1 = rotation / 90; + + mFrontBackSwitcher.setX(mLocX[idx1][FRONT_BACK_INDEX] + x); + mHdrSwitcher.setX(mLocX[idx1][HDR_INDEX] + x); + mSceneModeSwitcher.setX(mLocX[idx1][SCENE_MODE_INDEX] + x); + mFilterModeSwitcher.setX(mLocX[idx1][FILTER_MODE_INDEX] + x); + mMenu.setX(mLocX[idx1][MENU_INDEX] + x); + mSwitcher.setX(mLocX[idx1][SWITCHER_INDEX] - x); + mShutter.setX(mLocX[idx1][SHUTTER_INDEX] - x); + mIndicators.setX(mLocX[idx1][INDICATOR_INDEX] - x); + mPreview.setX(mLocX[idx1][PREVIEW_INDEX] - x); + + mFrontBackSwitcher.setY(mLocY[idx1][FRONT_BACK_INDEX] + y); + mHdrSwitcher.setY(mLocY[idx1][HDR_INDEX] + y); + mSceneModeSwitcher.setY(mLocY[idx1][SCENE_MODE_INDEX] + y); + mFilterModeSwitcher.setY(mLocY[idx1][FILTER_MODE_INDEX] + y); + mMenu.setY(mLocY[idx1][MENU_INDEX] + y); + mSwitcher.setY(mLocY[idx1][SWITCHER_INDEX] - y); + mShutter.setY(mLocY[idx1][SHUTTER_INDEX] - y); + mIndicators.setY(mLocY[idx1][INDICATOR_INDEX] - y); + mPreview.setY(mLocY[idx1][PREVIEW_INDEX] - y); + } + + public void hideUI() { + isAnimating = true; + enableTouch(false); + int rotation = getUnifiedRotation(); + mFrontBackSwitcher.animate().cancel(); + mHdrSwitcher.animate().cancel(); + mSceneModeSwitcher.animate().cancel(); + mFilterModeSwitcher.animate().cancel(); + mSwitcher.animate().cancel(); + mShutter.animate().cancel(); + mMenu.animate().cancel(); + mIndicators.animate().cancel(); + mPreview.animate().cancel(); + mFrontBackSwitcher.animate().setListener(outlistener); + ((ModuleSwitcher) mSwitcher).removePopup(); + resetLocation(0, 0); + markVisibility(); + switch (rotation) { + case 0: + mFrontBackSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mPreview.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + break; + case 90: + mFrontBackSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mPreview.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + break; + case 180: + mFrontBackSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mPreview.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + break; + case 270: + mFrontBackSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mPreview.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + break; + } + } + + public void showUI() { + isAnimating = true; + enableTouch(false); + int rotation = getUnifiedRotation(); + mFrontBackSwitcher.animate().cancel(); + mHdrSwitcher.animate().cancel(); + mSceneModeSwitcher.animate().cancel(); + mFilterModeSwitcher.animate().cancel(); + mSwitcher.animate().cancel(); + mShutter.animate().cancel(); + mMenu.animate().cancel(); + mIndicators.animate().cancel(); + mPreview.animate().cancel(); + if (mViewList != null) + for (View v : mViewList) { + v.setVisibility(View.VISIBLE); + } + ((ModuleSwitcher) mSwitcher).removePopup(); + AnimationDrawable shutterAnim = (AnimationDrawable) mShutter.getBackground(); + if (shutterAnim != null) + shutterAnim.stop(); + + mMenu.setVisibility(View.VISIBLE); + mIndicators.setVisibility(View.VISIBLE); + mPreview.setVisibility(View.VISIBLE); + + mFrontBackSwitcher.animate().setListener(inlistener); + switch (rotation) { + case 0: + resetLocation(0, -mSize); + + mFrontBackSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mPreview.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + break; + case 90: + resetLocation(-mSize, 0); + + mFrontBackSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mPreview.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + break; + case 180: + resetLocation(0, mSize); + + mFrontBackSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mPreview.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + break; + case 270: + resetLocation(mSize, 0); + + mFrontBackSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mPreview.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + break; + } } private void center(View v, Rect other, int rotation) { @@ -153,6 +489,65 @@ public class CameraControls extends RotatableLayout { cy + th / 2 - lp.bottomMargin); } + private void toIndex(View v, int w, int h, int rotation, int index, int index2, int index3) { + FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams(); + int tw = v.getMeasuredWidth(); + int th = v.getMeasuredHeight(); + int l = 0, r = 0, t = 0, b = 0; + + int wnumber = WIDTH_GRID; + int hnumber = HEIGHT_GRID; + int windex = 0; + int hindex = 0; + switch (rotation) { + case 0: + // portrait, to left of anchor at bottom + wnumber = WIDTH_GRID; + hnumber = HEIGHT_GRID; + windex = index; + hindex = index2; + break; + case 90: + // phone landscape: below anchor on right + wnumber = HEIGHT_GRID; + hnumber = WIDTH_GRID; + windex = index2; + hindex = hnumber - index - 1; + break; + case 180: + // phone upside down: right of anchor at top + wnumber = WIDTH_GRID; + hnumber = HEIGHT_GRID; + windex = wnumber - index - 1; + hindex = hnumber - index2 - 1; + break; + case 270: + // reverse landscape: above anchor on left + wnumber = HEIGHT_GRID; + hnumber = WIDTH_GRID; + windex = wnumber - index2 - 1; + hindex = index; + break; + } + int boxh = h / hnumber; + int boxw = w / wnumber; + int cx = (2 * windex + 1) * boxw / 2; + int cy = (2 * hindex + 1) * boxh / 2; + + l = cx - tw / 2; + r = cx + tw / 2; + t = cy - th / 2; + b = cy + th / 2; + + if (index3 != -1) { + int idx1 = rotation / 90; + int idx2 = index3; + mLocX[idx1][idx2] = l; + mLocY[idx1][idx2] = t; + } + v.layout(l, t, r, b); + } + private void toLeft(View v, Rect other, int rotation) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams(); int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin; @@ -161,34 +556,34 @@ public class CameraControls extends RotatableLayout { int cy = (other.top + other.bottom) / 2; int l = 0, r = 0, t = 0, b = 0; switch (rotation) { - case 0: - // portrait, to left of anchor at bottom - l = other.left - tw + lp.leftMargin; - r = other.left - lp.rightMargin; - t = cy - th / 2 + lp.topMargin; - b = cy + th / 2 - lp.bottomMargin; - break; - case 90: - // phone landscape: below anchor on right - l = cx - tw / 2 + lp.leftMargin; - r = cx + tw / 2 - lp.rightMargin; - t = other.bottom + lp.topMargin; - b = other.bottom + th - lp.bottomMargin; - break; - case 180: - // phone upside down: right of anchor at top - l = other.right + lp.leftMargin; - r = other.right + tw - lp.rightMargin; - t = cy - th / 2 + lp.topMargin; - b = cy + th / 2 - lp.bottomMargin; - break; - case 270: - // reverse landscape: above anchor on left - l = cx - tw / 2 + lp.leftMargin; - r = cx + tw / 2 - lp.rightMargin; - t = other.top - th + lp.topMargin; - b = other.top - lp.bottomMargin; - break; + case 0: + // portrait, to left of anchor at bottom + l = other.left - tw + lp.leftMargin; + r = other.left - lp.rightMargin; + t = cy - th / 2 + lp.topMargin; + b = cy + th / 2 - lp.bottomMargin; + break; + case 90: + // phone landscape: below anchor on right + l = cx - tw / 2 + lp.leftMargin; + r = cx + tw / 2 - lp.rightMargin; + t = other.bottom + lp.topMargin; + b = other.bottom + th - lp.bottomMargin; + break; + case 180: + // phone upside down: right of anchor at top + l = other.right + lp.leftMargin; + r = other.right + tw - lp.rightMargin; + t = cy - th / 2 + lp.topMargin; + b = cy + th / 2 - lp.bottomMargin; + break; + case 270: + // reverse landscape: above anchor on left + l = cx - tw / 2 + lp.leftMargin; + r = cx + tw / 2 - lp.rightMargin; + t = other.top - th + lp.topMargin; + b = other.top - lp.bottomMargin; + break; } v.layout(l, t, r, b); } @@ -201,48 +596,42 @@ public class CameraControls extends RotatableLayout { int cy = (other.top + other.bottom) / 2; int l = 0, r = 0, t = 0, b = 0; switch (rotation) { - case 0: - l = other.right + lp.leftMargin; - r = other.right + tw - lp.rightMargin; - t = cy - th / 2 + lp.topMargin; - b = cy + th / 2 - lp.bottomMargin; - break; - case 90: - l = cx - tw / 2 + lp.leftMargin; - r = cx + tw / 2 - lp.rightMargin; - t = other.top - th + lp.topMargin; - b = other.top - lp.bottomMargin; - break; - case 180: - l = other.left - tw + lp.leftMargin; - r = other.left - lp.rightMargin; - t = cy - th / 2 + lp.topMargin; - b = cy + th / 2 - lp.bottomMargin; - break; - case 270: - l = cx - tw / 2 + lp.leftMargin; - r = cx + tw / 2 - lp.rightMargin; - t = other.bottom + lp.topMargin; - b = other.bottom + th - lp.bottomMargin; - break; + case 0: + l = other.right + lp.leftMargin; + r = other.right + tw - lp.rightMargin; + t = cy - th / 2 + lp.topMargin; + b = cy + th / 2 - lp.bottomMargin; + break; + case 90: + l = cx - tw / 2 + lp.leftMargin; + r = cx + tw / 2 - lp.rightMargin; + t = other.top - th + lp.topMargin; + b = other.top - lp.bottomMargin; + break; + case 180: + l = other.left - tw + lp.leftMargin; + r = other.left - lp.rightMargin; + t = cy - th / 2 + lp.topMargin; + b = cy + th / 2 - lp.bottomMargin; + break; + case 270: + l = cx - tw / 2 + lp.leftMargin; + r = cx + tw / 2 - lp.rightMargin; + t = other.bottom + lp.topMargin; + b = other.bottom + th - lp.bottomMargin; + break; } v.layout(l, t, r, b); } - private void topRight(View v, int l, int t, int r, int b) { - // layout using the specific margins; the rotation code messes up the others - int mt = getContext().getResources().getDimensionPixelSize(R.dimen.capture_margin_top); - int mr = getContext().getResources().getDimensionPixelSize(R.dimen.capture_margin_right); - v.layout(r - v.getMeasuredWidth() - mr, t + mt, r - mr, t + mt + v.getMeasuredHeight()); - } - private void adjustBackground() { int rotation = getUnifiedRotation(); // remove current drawable and reset rotation mBackgroundView.setBackgroundDrawable(null); mBackgroundView.setRotationX(0); mBackgroundView.setRotationY(0); - // if the switcher background is top aligned we need to flip the background + // if the switcher background is top aligned we need to flip the + // background // drawable vertically; if left aligned, flip horizontally switch (rotation) { case 180: diff --git a/src/com/android/camera/ui/FaceView.java b/src/com/android/camera/ui/FaceView.java index f697a5df9..6181937ee 100644 --- a/src/com/android/camera/ui/FaceView.java +++ b/src/com/android/camera/ui/FaceView.java @@ -127,7 +127,10 @@ public class FaceView extends View mHandler.removeMessages(MSG_SWITCH_FACES); } mFaces = faces; - invalidate(); + if (!mBlocked && (mFaces != null) && (mFaces.length > 0)) { + invalidate(); + } + } public void setDisplayOrientation(int orientation) { @@ -205,8 +208,8 @@ public class FaceView extends View rh = temp; } CameraUtil.prepareMatrix(mMatrix, mMirror, mDisplayOrientation, rw, rh); - int dx = (getWidth() - rw) / 2; - int dy = (getHeight() - rh) / 2; + int dx = 0; + int dy = 0; // Focus indicator is directional. Rotate the matrix and the canvas // so it looks correctly in all orientations. diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java index f892934e2..8c2909881 100644 --- a/src/com/android/camera/ui/FilmStripView.java +++ b/src/com/android/camera/ui/FilmStripView.java @@ -37,10 +37,14 @@ import android.view.ViewGroup; import android.view.animation.DecelerateInterpolator; import android.widget.Scroller; +import com.android.camera.PhotoMenu; +import com.android.camera.VideoMenu; +import com.android.camera.PreviewGestures; import com.android.camera.CameraActivity; import com.android.camera.data.LocalData; import com.android.camera.ui.FilmStripView.ImageData.PanoramaSupportCallback; import com.android.camera.ui.FilmstripBottomControls.BottomControlsListener; +import com.android.camera.ui.RenderOverlay; import com.android.camera.util.CameraUtil; import com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper; import com.android.camera.util.UsageStatistics; @@ -97,6 +101,12 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { private float mOverScaleFactor = 1f; private int mLastTotalNumber = 0; + private RenderOverlay mRenderOverlay; + private PreviewGestures mPreviewGestures; + private boolean mSendToPreviewMenu; + private boolean mSendToMenu; + private boolean mReset; + private boolean mIsLoaded = false; /** * Common interface for all images in the filmstrip. @@ -705,6 +715,13 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { } } + public void setRenderOverlay(RenderOverlay renderOverlay) { + mRenderOverlay = renderOverlay; + } + public void setPreviewGestures(PreviewGestures previewGestures) { + mPreviewGestures = previewGestures; + } + /** * Returns the controller. * @@ -1718,7 +1735,10 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { mDataAdapter.setListener(new DataAdapter.Listener() { @Override public void onDataLoaded() { - reload(); + mActivity.updatePreviewThumbnail(); + if (!mIsLoaded) + reload(); + mIsLoaded = true; } @Override @@ -1734,6 +1754,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { return; } updateInsertion(dataID); + mActivity.updatePreviewThumbnailForVideo(); } @Override @@ -1792,9 +1813,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { && deltaX < mSlop * (-1)) { // intercept left swipe if (Math.abs(deltaX) >= Math.abs(deltaY) * 2) { - UsageStatistics.onEvent(UsageStatistics.COMPONENT_CAMERA, - UsageStatistics.ACTION_FILMSTRIP, null); - return true; + return false; } } } @@ -1807,6 +1826,95 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { return true; } + public boolean checkSendToModeView(MotionEvent ev) { + if (mSendToPreviewMenu || mSendToMenu || mPreviewGestures == null) + return true; + PhotoMenu pMenu = mPreviewGestures.getPhotoMenu(); + VideoMenu vMenu = mPreviewGestures.getVideoMenu(); + if (pMenu != null) { + if (pMenu.isMenuBeingShown()) { + if (pMenu.isMenuBeingAnimated()) { + if (pMenu.isOverMenu(ev)) { + mSendToMenu = true; + return true; + } + } + } + + if (pMenu.isPreviewMenuBeingShown()) { + if (pMenu.isOverPreviewMenu(ev)) { + mSendToPreviewMenu = true; + return true; + } + } + } + if (vMenu != null) { + if (vMenu.isMenuBeingShown()) { + if (vMenu.isMenuBeingAnimated()) { + if (vMenu.isOverMenu(ev)) { + mSendToMenu = true; + return true; + } + } + } + + if (vMenu.isPreviewMenuBeingShown()) { + if (vMenu.isOverPreviewMenu(ev)) { + mSendToPreviewMenu = true; + return true; + } + } + } + return false; + } + + public boolean sendToModeView(MotionEvent ev) { + if (mPreviewGestures == null) { + return false; + } + if (mReset) { + mSendToPreviewMenu = false; + mSendToMenu = false; + mReset = false; + } + if (mSendToPreviewMenu || mSendToMenu) { + if (MotionEvent.ACTION_UP == ev.getActionMasked() + || MotionEvent.ACTION_CANCEL == ev.getActionMasked()) + mReset = true; + } + PhotoMenu pMenu = mPreviewGestures.getPhotoMenu(); + VideoMenu vMenu = mPreviewGestures.getVideoMenu(); + + if (pMenu != null) { + if (mSendToPreviewMenu) + return pMenu.sendTouchToPreviewMenu(ev); + if (mSendToMenu) + return pMenu.sendTouchToMenu(ev); + if (pMenu.isMenuBeingShown()) { + return pMenu.sendTouchToMenu(ev); + } + + if (pMenu.isPreviewMenuBeingShown()) { + return pMenu.sendTouchToPreviewMenu(ev); + } + } + + if (vMenu != null) { + if (mSendToPreviewMenu) + return vMenu.sendTouchToPreviewMenu(ev); + if (mSendToMenu) + return vMenu.sendTouchToMenu(ev); + if (vMenu.isMenuBeingShown()) { + return vMenu.sendTouchToMenu(ev); + } + + if (vMenu.isPreviewMenuBeingShown()) { + return vMenu.sendTouchToPreviewMenu(ev); + } + } + return false; + } + private void updateViewItem(int itemID) { ViewItem item = mViewItem[itemID]; if (item == null) { @@ -2714,6 +2822,8 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { @Override public boolean onScroll(float x, float y, float dx, float dy) { + if (mPreviewGestures != null && mPreviewGestures.waitUntilNextDown()) + return false; ViewItem currItem = mViewItem[mCurrentItem]; if (currItem == null) { return false; @@ -2779,6 +2889,8 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { @Override public boolean onFling(float velocityX, float velocityY) { + if (mPreviewGestures != null && mPreviewGestures.waitUntilNextDown()) + return false; final ViewItem currItem = mViewItem[mCurrentItem]; if (currItem == null) { return false; diff --git a/src/com/android/camera/ui/ListMenu.java b/src/com/android/camera/ui/ListMenu.java new file mode 100644 index 000000000..64bdc342b --- /dev/null +++ b/src/com/android/camera/ui/ListMenu.java @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * 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 java.util.ArrayList; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +import com.android.camera.ListPreference; +import com.android.camera.PreferenceGroup; +import org.codeaurora.snapcam.R; + +/* A popup window that contains several camera settings. */ +public class ListMenu extends ListView + implements ListMenuItem.Listener, + AdapterView.OnItemClickListener { + @SuppressWarnings("unused") + private static final String TAG = "ListMenu"; + private Listener mListener; + private ArrayList<ListPreference> mListItem = new ArrayList<ListPreference>(); + + // Keep track of which setting items are disabled + // e.g. White balance will be disabled when scene mode is set to non-auto + private boolean[] mEnabled; + + static public interface Listener { + public void onSettingChanged(ListPreference pref); + + public void onPreferenceClicked(ListPreference pref); + + public void onPreferenceClicked(ListPreference pref, int y); + + public void onListMenuTouched(); + } + + private class MoreSettingAdapter extends ArrayAdapter<ListPreference> { + LayoutInflater mInflater; + String mOnString; + String mOffString; + + MoreSettingAdapter() { + super(ListMenu.this.getContext(), 0, mListItem); + Context context = getContext(); + mInflater = LayoutInflater.from(context); + mOnString = context.getString(R.string.setting_on); + mOffString = context.getString(R.string.setting_off); + } + + private int getSettingLayoutId(ListPreference pref) { + return R.layout.list_menu_item; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ListPreference pref = mListItem.get(position); + int viewLayoutId = getSettingLayoutId(pref); + ListMenuItem view = (ListMenuItem) convertView; + + view = (ListMenuItem) + mInflater.inflate(viewLayoutId, parent, false); + + view.initialize(pref); // no init for restore one + view.setSettingChangedListener(ListMenu.this); + if (position >= 0 && position < mEnabled.length) { + view.setEnabled(mEnabled[position]); + } else { + Log.w(TAG, "Invalid input: enabled list length, " + mEnabled.length + + " position " + position); + } + return view; + } + + @Override + public boolean isEnabled(int position) { + if (position >= 0 && position < mEnabled.length) { + return mEnabled[position]; + } + return true; + } + } + + public void setSettingChangedListener(Listener listener) { + mListener = listener; + } + + public ListMenu(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void initialize(PreferenceGroup group, String[] keys) { + // Prepare the setting items. + for (int i = 0; i < keys.length; ++i) { + ListPreference pref = group.findPreference(keys[i]); + if (pref != null) + mListItem.add(pref); + } + + ArrayAdapter<ListPreference> mListItemAdapter = new MoreSettingAdapter(); + setAdapter(mListItemAdapter); + setOnItemClickListener(this); + setSelector(android.R.color.transparent); + // Initialize mEnabled + mEnabled = new boolean[mListItem.size()]; + for (int i = 0; i < mEnabled.length; i++) { + mEnabled[i] = true; + } + } + + // When preferences are disabled, we will display them grayed out. Users + // will not be able to change the disabled preferences, but they can still + // see + // the current value of the preferences + public void setPreferenceEnabled(String key, boolean enable) { + int count = mEnabled == null ? 0 : mEnabled.length; + for (int j = 0; j < count; j++) { + ListPreference pref = mListItem.get(j); + if (pref != null && key.equals(pref.getKey())) { + mEnabled[j] = enable; + break; + } + } + } + + public void onSettingChanged(ListPreference pref) { + if (mListener != null) { + mListener.onSettingChanged(pref); + } + } + + // Scene mode can override other camera settings (ex: flash mode). + public void overrideSettings(final String... keyvalues) { + int count = mEnabled == null ? 0 : mEnabled.length; + for (int i = 0; i < keyvalues.length; i += 2) { + String key = keyvalues[i]; + String value = keyvalues[i + 1]; + for (int j = 0; j < count; j++) { + ListPreference pref = mListItem.get(j); + if (pref != null && key.equals(pref.getKey())) { + // Change preference + if (value != null) + pref.setValue(value); + // If the preference is overridden, disable the preference + boolean enable = value == null; + mEnabled[j] = enable; + int offset = getFirstVisiblePosition(); + if (offset >= 0) { + int indexInView = j - offset; + if (getChildCount() > indexInView && indexInView >= 0) { + getChildAt(indexInView).setEnabled(enable); + } + } + } + } + } + reloadPreference(); + } + + public void resetHighlight() { + int count = getChildCount(); + for (int i = 0; i < count; i++) { + View v = getChildAt(i); + v.setBackground(null); + } + + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + if (ev.getAction() == MotionEvent.ACTION_MOVE) { + mListener.onListMenuTouched(); + resetHighlight(); + } + return super.onTouchEvent(ev); + } + + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, + long id) { + if (mListener != null) { + resetHighlight(); + ListPreference pref = mListItem.get(position); + view.setBackgroundColor(getContext().getResources().getColor(R.color.setting_color)); + mListener.onPreferenceClicked(pref, (int) view.getY()); + } + + } + + public void reloadPreference() { + int count = getChildCount(); + for (int i = 0; i < count; i++) { + ListPreference pref = mListItem.get(i); + if (pref != null) { + ListMenuItem listMenuItem = + (ListMenuItem) getChildAt(i); + listMenuItem.reloadPreference(); + } + } + } +} diff --git a/src/com/android/camera/ui/ListMenuItem.java b/src/com/android/camera/ui/ListMenuItem.java new file mode 100644 index 000000000..f3c7f017e --- /dev/null +++ b/src/com/android/camera/ui/ListMenuItem.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.camera.ui; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.ImageView; + +import com.android.camera.ListPreference; +import com.android.camera.IconListPreference; +import org.codeaurora.snapcam.R; + +/** + * A one-line camera setting could be one of three types: knob, switch or + * restore preference button. The setting includes a title for showing the + * preference title which is initialized in the SimpleAdapter. A knob also + * includes (ex: Picture size), a previous button, the current value (ex: 5MP), + * and a next button. A switch, i.e. the preference RecordLocationPreference, + * has only two values on and off which will be controlled in a switch button. + * Other setting popup window includes several InLineSettingItem items with + * different types if possible. + */ +public class ListMenuItem extends RelativeLayout { + private static final String TAG = "ListMenuItem"; + private Listener mListener; + protected ListPreference mPreference; + protected int mIndex; + // Scene mode can override the original preference value. + protected String mOverrideValue; + protected TextView mTitle; + private TextView mEntry; + private ImageView mIcon; + + static public interface Listener { + public void onSettingChanged(ListPreference pref); + } + + public ListMenuItem(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mEntry = (TextView) findViewById(R.id.current_setting); + mIcon = (ImageView) findViewById(R.id.list_image); + } + + protected void setTitle(ListPreference preference) { + mTitle = ((TextView) findViewById(R.id.title)); + mTitle.setText(preference.getTitle()); + } + + protected void setIcon(ListPreference preference) { + if (preference instanceof IconListPreference) { + int resId = ((IconListPreference) preference).getSingleIcon(); + mIcon.setImageResource(resId); + } + + } + + public void initialize(ListPreference preference) { + setTitle(preference); + if (preference == null) + return; + setIcon(preference); + mPreference = preference; + reloadPreference(); + } + + protected void updateView() { + if (mOverrideValue == null) { + mEntry.setText(mPreference.getEntry()); + } else { + int index = mPreference.findIndexOfValue(mOverrideValue); + if (index != -1) { + mEntry.setText(mPreference.getEntries()[index]); + } else { + // Avoid the crash if camera driver has bugs. + Log.e(TAG, "Fail to find override value=" + mOverrideValue); + mPreference.print(); + } + } + } + + protected boolean changeIndex(int index) { + if (index >= mPreference.getEntryValues().length || index < 0) + return false; + mIndex = index; + mPreference.setValueIndex(mIndex); + if (mListener != null) { + mListener.onSettingChanged(mPreference); + } + updateView(); + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + return true; + } + + // The value of the preference may have changed. Update the UI. + public void reloadPreference() { + mIndex = mPreference.findIndexOfValue(mPreference.getValue()); + updateView(); + } + + public void setSettingChangedListener(Listener listener) { + mListener = listener; + } + + public void overrideSettings(String value) { + mOverrideValue = value; + updateView(); + } + + @Override + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { + event.getText().add(mPreference.getTitle() + mPreference.getEntry()); + return true; + } + + @Override + public void setEnabled(boolean enable) { + super.setEnabled(enable); + if (enable) + setAlpha(1f); + else + setAlpha(0.3f); + if (mTitle != null) { + mTitle.setEnabled(enable); + if (enable) + setAlpha(1f); + else + setAlpha(0.3f); + } + if (mEntry != null) { + mEntry.setEnabled(enable); + if (enable) + setAlpha(1f); + else + setAlpha(0.3f); + } + } +} diff --git a/src/com/android/camera/ui/ListSubMenu.java b/src/com/android/camera/ui/ListSubMenu.java new file mode 100644 index 000000000..af38b162a --- /dev/null +++ b/src/com/android/camera/ui/ListSubMenu.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * 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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import android.content.Context; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.SimpleAdapter; + +import com.android.camera.IconListPreference; +import com.android.camera.ListPreference; +import org.codeaurora.snapcam.R; + +// A popup window that shows one camera setting. The title is the name of the +// setting (ex: white-balance). The entries are the supported values (ex: +// daylight, incandescent, etc). If initialized with an IconListPreference, +// the entries will contain both text and icons. Otherwise, entries will be +// shown in text. +public class ListSubMenu extends ListView implements + AdapterView.OnItemClickListener { + private static final String TAG = "ListPrefSettingPopup"; + private ListPreference mPreference; + private Listener mListener; + private int mY; + + static public interface Listener { + public void onListPrefChanged(ListPreference pref); + } + + public ListSubMenu(Context context, int listRes) { + super(context); + } + + public ListSubMenu(Context context, AttributeSet attrs) { + super(context, attrs); + } + + private class ListPrefSettingAdapter extends SimpleAdapter { + ListPrefSettingAdapter(Context context, List<? extends Map<String, ?>> data, + int resource, String[] from, int[] to) { + super(context, data, resource, from, to); + } + + @Override + public void setViewImage(ImageView v, String value) { + if ("".equals(value)) { + // Some settings have no icons. Ex: exposure compensation. + v.setVisibility(View.GONE); + } else { + super.setViewImage(v, value); + } + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + int screenHeight = ((LinearLayout) getParent()).getHeight(); + super.onLayout(changed, l, t, r, b); + setY(Math.max(0, mY)); + if (mY + (b - t) > screenHeight) { + setY(Math.max(0, mY - (mY + (b - t) - screenHeight))); + } + } + + public void initialize(ListPreference preference, int y) { + mPreference = preference; + Context context = getContext(); + CharSequence[] entries = mPreference.getEntries(); + int[] iconIds = null; + if (preference instanceof IconListPreference) { + iconIds = ((IconListPreference) mPreference).getImageIds(); + if (iconIds == null) { + iconIds = ((IconListPreference) mPreference).getLargeIconIds(); + } + } + mY = y; + + // Prepare the ListView. + ArrayList<HashMap<String, Object>> listItem = + new ArrayList<HashMap<String, Object>>(); + for (int i = 0; i < entries.length; ++i) { + HashMap<String, Object> map = new HashMap<String, Object>(); + map.put("text", entries[i].toString()); + if (iconIds != null) + map.put("image", iconIds[i]); + listItem.add(map); + } + SimpleAdapter listItemAdapter = new ListPrefSettingAdapter(context, listItem, + R.layout.list_sub_menu_item, + new String[] { + "text", "image" + }, + new int[] { + R.id.text, R.id.image + }); + setAdapter(listItemAdapter); + setOnItemClickListener(this); + reloadPreference(); + } + + // The value of the preference may have changed. Update the UI. + // @Override + public void reloadPreference() { + int index = mPreference.findIndexOfValue(mPreference.getValue()); + if (index != -1) { + setItemChecked(index, true); + } else { + Log.e(TAG, "Invalid preference value."); + mPreference.print(); + } + } + + public void setSettingChangedListener(Listener listener) { + mListener = listener; + } + + @Override + public void onItemClick(AdapterView<?> parent, View view, + int index, long id) { + mPreference.setValueIndex(index); + if (mListener != null) + mListener.onListPrefChanged(mPreference); + } + + @Override + protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { + super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); + } +} diff --git a/src/com/android/camera/ui/ModuleSwitcher.java b/src/com/android/camera/ui/ModuleSwitcher.java index 60fed24ad..3f9ccd5ec 100644 --- a/src/com/android/camera/ui/ModuleSwitcher.java +++ b/src/com/android/camera/ui/ModuleSwitcher.java @@ -52,6 +52,7 @@ public class ModuleSwitcher extends RotateImageView public static final int WIDE_ANGLE_PANO_MODULE_INDEX = 2; public static final int LIGHTCYCLE_MODULE_INDEX = 3; public static final int GCAM_MODULE_INDEX = 4; + private boolean mTouchEnabled = true; private static final int[] DRAW_IDS = { R.drawable.ic_switch_camera, @@ -146,6 +147,20 @@ public class ModuleSwitcher extends RotateImageView } @Override + public boolean dispatchTouchEvent(MotionEvent m) { + if (mTouchEnabled) { + return super.dispatchTouchEvent(m); + } else { + setBackground(null); + return false; + } + } + + public void enableTouch(boolean enable) { + mTouchEnabled = enable; + } + + @Override public void onClick(View v) { showSwitcher(); mListener.onShowSwitcherPopup(); @@ -254,6 +269,16 @@ public class ModuleSwitcher extends RotateImageView mParent.setOnTouchListener(null); } + public void removePopup() { + mShowingPopup = false; + setVisibility(View.VISIBLE); + if (mPopup != null) { + ((ViewGroup) mParent).removeView(mPopup); + mPopup = null; + } + setAlpha(1f); + } + @Override public void onConfigurationChanged(Configuration config) { if (showsPopup()) { diff --git a/src/com/android/camera/ui/PieRenderer.java b/src/com/android/camera/ui/PieRenderer.java index 13ead421e..324e0fe98 100644 --- a/src/com/android/camera/ui/PieRenderer.java +++ b/src/com/android/camera/ui/PieRenderer.java @@ -36,6 +36,7 @@ import android.view.ViewConfiguration; import android.view.animation.Animation; import android.view.animation.Transformation; +import com.android.camera.CameraActivity; import com.android.camera.drawable.TextDrawable; import com.android.camera.ui.ProgressRenderer.VisibilityListener; import org.codeaurora.snapcam.R; @@ -636,6 +637,8 @@ public class PieRenderer extends OverlayRenderer @Override public boolean onTouchEvent(MotionEvent evt) { + if (!CameraActivity.isPieMenuEnabled()) + return false; float x = evt.getX(); float y = evt.getY(); int action = evt.getActionMasked(); diff --git a/src/com/android/camera/util/CameraUtil.java b/src/com/android/camera/util/CameraUtil.java index 4cfc211bc..a80db9f09 100644 --- a/src/com/android/camera/util/CameraUtil.java +++ b/src/com/android/camera/util/CameraUtil.java @@ -1057,4 +1057,8 @@ public class CameraUtil { } return ret; } + + public static boolean volumeKeyShutterDisable(Context context) { + return context.getResources().getBoolean(R.bool.volume_key_shutter_disable); + } } |