OSDN Git Service

UI changes
authornicolasroard <nicolasroard@google.com>
Sat, 20 Apr 2013 00:13:30 +0000 (17:13 -0700)
committernicolasroard <nicolasroard@google.com>
Thu, 25 Apr 2013 03:23:36 +0000 (20:23 -0700)
bug:8664728

Change-Id: I133328543af534c745526d0d58aa7a61f5748a9d

53 files changed:
res/anim/slide_in_left.xml [new file with mode: 0644]
res/anim/slide_in_right.xml [new file with mode: 0644]
res/anim/slide_out_left.xml [new file with mode: 0644]
res/anim/slide_out_right.xml [new file with mode: 0644]
res/drawable-nodpi/filtershow_icon_vignette.png [new file with mode: 0644]
res/layout-land/filtershow_activity.xml
res/layout-land/filtershow_category_panel_new.xml [new file with mode: 0644]
res/layout-land/filtershow_editor_panel.xml [new file with mode: 0644]
res/layout-land/filtershow_main_panel.xml [new file with mode: 0644]
res/layout-land/filtershow_state_panel_new.xml [new file with mode: 0644]
res/layout/filtershow_activity.xml
res/layout/filtershow_category_panel_new.xml [new file with mode: 0644]
res/layout/filtershow_control_title_slider.xml
res/layout/filtershow_editor_panel.xml
res/layout/filtershow_imagestate_row.xml [deleted file]
res/layout/filtershow_main_panel.xml [new file with mode: 0644]
res/layout/filtershow_seekbar.xml
res/layout/filtershow_state_panel_new.xml
res/values-large/filtershow_values.xml [new file with mode: 0644]
res/values-xlarge/filtershow_values.xml [new file with mode: 0644]
res/values/attrs.xml
res/values/dimensions.xml
res/values/filtershow_color.xml
res/values/filtershow_strings.xml
res/values/filtershow_values.xml [new file with mode: 0644]
res/values/filtershow_values_attrs.xml
src/com/android/gallery3d/filtershow/EditorPlaceHolder.java
src/com/android/gallery3d/filtershow/FilterShowActivity.java
src/com/android/gallery3d/filtershow/ImageStateAdapter.java [deleted file]
src/com/android/gallery3d/filtershow/MovableLinearLayout.java [deleted file]
src/com/android/gallery3d/filtershow/PanelController.java [deleted file]
src/com/android/gallery3d/filtershow/category/Action.java [new file with mode: 0644]
src/com/android/gallery3d/filtershow/category/CategoryAdapter.java [new file with mode: 0644]
src/com/android/gallery3d/filtershow/category/CategoryPanel.java [new file with mode: 0644]
src/com/android/gallery3d/filtershow/category/CategoryTrack.java [new file with mode: 0644]
src/com/android/gallery3d/filtershow/category/CategoryView.java [new file with mode: 0644]
src/com/android/gallery3d/filtershow/category/MainPanel.java [new file with mode: 0644]
src/com/android/gallery3d/filtershow/editors/BasicEditor.java
src/com/android/gallery3d/filtershow/editors/Editor.java
src/com/android/gallery3d/filtershow/editors/EditorPanel.java [new file with mode: 0644]
src/com/android/gallery3d/filtershow/editors/ParametricEditor.java
src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java
src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java
src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
src/com/android/gallery3d/filtershow/presets/ImagePreset.java
src/com/android/gallery3d/filtershow/state/StateAdapter.java
src/com/android/gallery3d/filtershow/state/StatePanel.java
src/com/android/gallery3d/filtershow/state/StatePanelTrack.java
src/com/android/gallery3d/filtershow/state/StateView.java
src/com/android/gallery3d/filtershow/ui/FilterIconButton.java
src/com/android/gallery3d/filtershow/ui/ImageCurves.java

diff --git a/res/anim/slide_in_left.xml b/res/anim/slide_in_left.xml
new file mode 100644 (file)
index 0000000..6b1de4b
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2013, 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.
+-->
+
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+           android:fromXDelta="-100%"
+           android:toXDelta="0%"
+           android:interpolator="@android:anim/decelerate_interpolator"
+           android:duration="300"/>
\ No newline at end of file
diff --git a/res/anim/slide_in_right.xml b/res/anim/slide_in_right.xml
new file mode 100644 (file)
index 0000000..12f7efe
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2013, 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.
+-->
+
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+           android:fromXDelta="100%"
+           android:toXDelta="0"
+           android:interpolator="@android:anim/decelerate_interpolator"
+           android:duration="300"/>
\ No newline at end of file
diff --git a/res/anim/slide_out_left.xml b/res/anim/slide_out_left.xml
new file mode 100644 (file)
index 0000000..be28e55
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2013, 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.
+-->
+
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+           android:fromXDelta="0%"
+           android:toXDelta="100%"
+           android:interpolator="@android:anim/decelerate_interpolator"
+           android:duration="300"/>
\ No newline at end of file
diff --git a/res/anim/slide_out_right.xml b/res/anim/slide_out_right.xml
new file mode 100644 (file)
index 0000000..4c786e6
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2013, 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.
+-->
+
+<translate xmlns:android="http://schemas.android.com/apk/res/android"
+           android:fromXDelta="0"
+           android:toXDelta="-100%"
+           android:interpolator="@android:anim/decelerate_interpolator"
+           android:duration="300"/>
\ No newline at end of file
diff --git a/res/drawable-nodpi/filtershow_icon_vignette.png b/res/drawable-nodpi/filtershow_icon_vignette.png
new file mode 100644 (file)
index 0000000..88d1a96
Binary files /dev/null and b/res/drawable-nodpi/filtershow_icon_vignette.png differ
index 311a3e6..4d098e6 100644 (file)
@@ -16,7 +16,6 @@
 -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-             xmlns:iconbutton="http://schemas.android.com/apk/res/com.android.gallery3d"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:id="@+id/mainView"
                     android:layout_height="wrap_content"
                     android:layout_weight="1" />
 
-            <com.android.gallery3d.filtershow.imageshow.ImageTinyPlanet
-                    android:id="@+id/imageTinyPlanet"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:layout_weight="1" />
-
         </LinearLayout>
 
         <LinearLayout
                 android:id="@+id/mainPanel"
                 android:layout_width="350dip"
                 android:layout_height="match_parent"
-                android:orientation="vertical">
+                android:orientation="vertical"
+                android:animateLayoutChanges="true" >
 
-            <FrameLayout android:id="@+id/state_panel_container"
+            <FrameLayout android:id="@+id/main_panel_container"
                          android:layout_width="350dip"
                          android:layout_height="0dip"
                          android:layout_weight="1" />
 
-            <ViewStub android:id="@+id/historyPanelStub"
-                      android:inflatedId="@+id/historyPanel"
-                      android:layout="@layout/filtershow_history_panel"
-                      android:layout_width="match_parent"
-                      android:layout_height="0dip"
-                      android:visibility="gone"/>
-
             <FrameLayout
                     android:layout_gravity="bottom"
                     android:layout_width="match_parent"
 
             </FrameLayout>
 
-            <com.android.gallery3d.filtershow.CenteredLinearLayout
-                    xmlns:custom="http://schemas.android.com/apk/res/com.android.gallery3d"
-                    android:id="@+id/filtersPanel"
-                    android:layout_width="match_parent"
-                    android:layout_height="177dip"
-                    android:layout_gravity="center|bottom"
-                    custom:max_width="600dip"
-                    android:orientation="vertical">
-
-                <FrameLayout
-                        android:id="@+id/secondRowPanel"
-                        android:layout_width="fill_parent"
-                        android:layout_height="128dip">
-
-                    <LinearLayout
-                            android:id="@+id/filterButtonsList"
-                            android:layout_width="fill_parent"
-                            android:layout_height="@dimen/thumbnail_size"
-                            android:orientation="horizontal"
-                            android:visibility="gone">
-
-                        <ViewStub android:id="@+id/editorPanelStub"
-                                  android:inflatedId="@+id/editorPanel"
-                                  android:layout="@layout/filtershow_editor_panel"
-                                  android:layout_width="match_parent"
-                                  android:layout_height="wrap_content"
-                                  android:visibility="visible"/>
-
-                    </LinearLayout>
-
-                    <HorizontalScrollView
-                            android:id="@+id/fxList"
-                            android:layout_width="match_parent"
-                            android:layout_height="@dimen/thumbnail_size"
-                            android:background="@color/background_main_toolbar"
-                            android:scrollbars="none">
-
-                        <LinearLayout
-                                android:id="@+id/listFilters"
-                                android:layout_width="wrap_content"
-                                android:layout_height="match_parent"
-                                android:layout_marginLeft="@dimen/thumbnail_margin"
-                                android:orientation="horizontal">
-                        </LinearLayout>
-                    </HorizontalScrollView>
-
-                    <HorizontalScrollView
-                            android:id="@+id/bordersList"
-                            android:layout_width="match_parent"
-                            android:layout_height="@dimen/thumbnail_size"
-                            android:background="@color/background_main_toolbar"
-                            android:visibility="gone"
-                            android:scrollbars="none">
-
-                        <LinearLayout
-                                android:id="@+id/listBorders"
-                                android:layout_width="wrap_content"
-                                android:layout_height="match_parent"
-                                android:layout_marginLeft="@dimen/thumbnail_margin"
-                                android:orientation="horizontal">
-                        </LinearLayout>
-                    </HorizontalScrollView>
-
-                    <HorizontalScrollView
-                            android:id="@+id/geometryList"
-                            android:layout_width="fill_parent"
-                            android:layout_height="@dimen/thumbnail_size"
-                            android:background="@color/background_main_toolbar"
-                            android:visibility="gone"
-                            android:scrollbars="none">
-
-                        <LinearLayout
-                                android:id="@+id/listGeometry"
-                                android:layout_width="wrap_content"
-                                android:layout_height="fill_parent"
-                                android:layout_gravity="left"
-                                android:orientation="horizontal"/>
-
-                    </HorizontalScrollView>
-
-                    <HorizontalScrollView
-                            android:id="@+id/colorsFxList"
-                            android:layout_width="fill_parent"
-                            android:layout_height="wrap_content"
-                            android:background="@color/background_main_toolbar"
-                            android:visibility="gone"
-                            android:scrollbars="none">
-
-                        <LinearLayout
-                                android:id="@+id/listColorsFx"
-                                android:layout_width="wrap_content"
-                                android:layout_height="@dimen/thumbnail_size"
-                                android:background="@color/background_main_toolbar"
-                                android:layout_marginLeft="@dimen/thumbnail_margin"
-                                android:orientation="horizontal">
-
-                        </LinearLayout>
-                    </HorizontalScrollView>
-                </FrameLayout>
-
-                <View
-                        android:background="@color/toolbar_separation_line"
-                        android:layout_height="1dip"
-                        android:layout_width="match_parent"/>
-
-                <com.android.gallery3d.filtershow.CenteredLinearLayout
-                        android:layout_width="match_parent"
-                        android:layout_height="48dip"
-                        android:layout_gravity="center"
-                        custom:max_width="400dip"
-                        android:orientation="vertical">
-
-                    <ViewStub android:id="@+id/stateCategoryStub"
-                              android:inflatedId="@+id/imageCategoryPanel"
-                              android:layout="@layout/filtershow_category_panel"
-                              android:layout_width="match_parent"
-                              android:layout_height="48dip"
-                              android:visibility="visible"/>
-
-                </com.android.gallery3d.filtershow.CenteredLinearLayout>
-
-            </com.android.gallery3d.filtershow.CenteredLinearLayout>
-
         </LinearLayout>
 
     </LinearLayout>
diff --git a/res/layout-land/filtershow_category_panel_new.xml b/res/layout-land/filtershow_category_panel_new.xml
new file mode 100644 (file)
index 0000000..10a6c97
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="horizontal"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <ListView
+            android:id="@+id/listItems"
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="8dip"
+            android:divider="@android:color/transparent"
+            android:dividerHeight="8dip" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout-land/filtershow_editor_panel.xml b/res/layout-land/filtershow_editor_panel.xml
new file mode 100644 (file)
index 0000000..85ab010
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/top"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="vertical"
+              android:visibility="visible">
+
+    <Button
+            android:id="@+id/toggle_state"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/imageState"
+            android:background="@color/background_main_toolbar"
+            />
+
+    <FrameLayout android:id="@+id/state_panel_container"
+                 android:layout_width="match_parent"
+                 android:layout_height="0dip"
+                 android:visibility="visible"
+                 android:layout_gravity="top"
+                 android:layout_weight="1" />
+
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:layout_gravity="bottom">
+
+        <LinearLayout
+                android:id="@+id/controlArea"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:layout_alignParentBottom="true"
+                android:visibility="visible">
+
+            <SeekBar
+                    android:id="@+id/primarySeekBar"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_vertical"
+                    style="@style/FilterShowSlider"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="56dip"
+                android:background="@color/background_main_toolbar"
+                android:orientation="horizontal"
+                android:baselineAligned="false"
+                android:visibility="visible">
+
+            <ImageButton
+                    android:id="@+id/cancelFilter"
+                    android:layout_width="wrap_content"
+                    android:layout_height="fill_parent"
+                    android:layout_gravity="left|center_vertical"
+                    android:background="@android:color/transparent"
+                    android:layout_weight=".1"
+                    android:gravity="center"
+                    android:src="@drawable/ic_menu_cancel_holo_light"
+                    android:textSize="18dip"/>
+
+            <ImageView
+                    android:layout_width="2dp"
+                    android:layout_height="fill_parent"
+                    android:src="@drawable/filtershow_vertical_bar"/>
+
+            <LinearLayout
+                    android:id="@+id/panelAccessoryViewList"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:orientation="horizontal"
+                    android:visibility="visible">
+
+                <com.android.gallery3d.filtershow.editors.SwapButton
+                        android:id="@+id/applyEffect"
+                        android:layout_width="fill_parent"
+                        android:layout_height="fill_parent"
+                        android:layout_gravity="center"
+                        android:background="@android:color/transparent"
+                        android:gravity="center"
+                        android:text="@string/apply_effect"
+                        android:textSize="18dip"
+                        android:drawableRight="@drawable/filtershow_menu_marker"/>
+
+            </LinearLayout>
+
+            <ImageView
+                    android:layout_width="2dp"
+                    android:layout_height="fill_parent"
+                    android:src="@drawable/filtershow_vertical_bar"/>
+
+            <ImageButton
+                    android:id="@+id/applyFilter"
+                    android:layout_width="wrap_content"
+                    android:layout_height="fill_parent"
+                    android:layout_gravity="right|center_vertical"
+                    android:layout_weight=".1"
+                    android:background="@android:color/transparent"
+                    android:gravity="center"
+                    android:src="@drawable/ic_menu_done_holo_light"
+                    android:textSize="18dip"/>
+        </LinearLayout>
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/res/layout-land/filtershow_main_panel.xml b/res/layout-land/filtershow_main_panel.xml
new file mode 100644 (file)
index 0000000..705eb69
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:baselineAligned="false"
+              android:orientation="vertical"
+              android:animateLayoutChanges="true"
+              android:visibility="visible" >
+
+    <FrameLayout android:id="@+id/state_panel_container"
+                 android:layout_width="match_parent"
+                 android:layout_height="0dip"
+                 android:visibility="visible"
+                 android:layout_gravity="top"
+                 android:layout_weight="1" />
+
+    <FrameLayout android:id="@+id/category_panel_container"
+                 android:layout_width="match_parent"
+                 android:layout_height="0dip"
+                 android:layout_weight="1"/>
+
+    <View
+            android:background="@color/toolbar_separation_line"
+            android:layout_height="1dip"
+            android:layout_width="match_parent"/>
+
+    <com.android.gallery3d.filtershow.CenteredLinearLayout
+            xmlns:custom="http://schemas.android.com/apk/res/com.android.gallery3d"
+            android:layout_width="match_parent"
+            android:layout_height="48dip"
+            android:layout_gravity="center|bottom"
+            custom:max_width="400dip"
+            android:orientation="vertical">
+
+        <LinearLayout android:layout_width="wrap_content"
+                      android:layout_height="match_parent"
+                      android:background="@color/background_main_toolbar">
+
+            <ImageButton
+                    android:id="@+id/fxButton"
+                    android:layout_width="@dimen/thumbnail_size"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:background="@drawable/filtershow_button_background"
+                    android:scaleType="centerInside"
+                    android:src="@drawable/ic_photoeditor_effects"/>
+
+            <ImageButton
+                    android:id="@+id/borderButton"
+                    android:layout_width="@dimen/thumbnail_size"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:background="@drawable/filtershow_button_background"
+                    android:padding="2dip"
+                    android:scaleType="centerInside"
+                    android:src="@drawable/ic_photoeditor_border"/>
+
+            <ImageButton
+                    android:id="@+id/geometryButton"
+                    android:layout_width="@dimen/thumbnail_size"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:background="@drawable/filtershow_button_background"
+                    android:padding="2dip"
+                    android:scaleType="centerInside"
+                    android:src="@drawable/ic_photoeditor_fix"/>
+
+            <ImageButton
+                    android:id="@+id/colorsButton"
+                    android:layout_width="@dimen/thumbnail_size"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:background="@drawable/filtershow_button_background"
+                    android:padding="2dip"
+                    android:scaleType="centerInside"
+                    android:src="@drawable/ic_photoeditor_color"/>
+
+        </LinearLayout>
+
+    </com.android.gallery3d.filtershow.CenteredLinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout-land/filtershow_state_panel_new.xml b/res/layout-land/filtershow_state_panel_new.xml
new file mode 100644 (file)
index 0000000..c83cd88
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:custom="http://schemas.android.com/apk/res/com.android.gallery3d"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1"
+            android:scrollbars="none">
+
+        <com.android.gallery3d.filtershow.state.StatePanelTrack
+                android:id="@+id/listStates"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                custom:elemSize="72dip"
+                custom:elemEndSize="32dip"
+                android:layout_margin="8dip"
+                android:animateLayoutChanges="true" />
+
+    </ScrollView>
+
+    <View
+            android:background="@color/state_panel_separation_line"
+            android:layout_height="6dip"
+            android:layout_width="match_parent"
+            android:paddingTop="8dip"/>
+
+</LinearLayout>
index c3c593b..f5684ff 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2012 The Android Open Source Project
+     Copyright (C) 2013 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.
 -->
 
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:iconbutton="http://schemas.android.com/apk/res/com.android.gallery3d"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:id="@+id/mainView"
-    android:background="@drawable/filtershow_tiled_background">
+             android:layout_width="match_parent"
+             android:layout_height="match_parent"
+             android:id="@+id/mainView"
+             android:background="@drawable/filtershow_tiled_background">
 
     <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:orientation="horizontal"
-            android:animateLayoutChanges="false">
+            android:orientation="vertical">
 
         <LinearLayout
-        android:id="@+id/mainPanel"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:orientation="vertical" >
-
-        <FrameLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_weight="1" >
-
-            <FrameLayout
-                android:id="@+id/editorContainer"
+                android:layout_weight="1"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_weight="1"  />
-
-            <com.android.gallery3d.filtershow.imageshow.ImageShow
-                android:id="@+id/imageShow"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content" />
+                android:orientation="horizontal">
 
-            <com.android.gallery3d.filtershow.imageshow.ImageTinyPlanet
-                android:id="@+id/imageTinyPlanet"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content" />
+            <FrameLayout
+                    android:id="@+id/editorContainer"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"/>
 
-            <ProgressBar
-                android:id="@+id/loading"
-                style="@android:style/Widget.Holo.ProgressBar.Large"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center"
-                android:indeterminate="true"
-                android:indeterminateOnly="true"
-                android:background="@color/background_screen" />
+            <com.android.gallery3d.filtershow.imageshow.ImageShow
+                    android:id="@+id/imageShow"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1" />
 
-        </FrameLayout>
+        </LinearLayout>
 
         <com.android.gallery3d.filtershow.CenteredLinearLayout
-              xmlns:custom="http://schemas.android.com/apk/res/com.android.gallery3d"
-              android:id="@+id/filtersPanel"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:layout_gravity="center"
-              custom:max_width="600dip"
-              android:orientation="vertical">
-
-              <FrameLayout
-                    android:id="@+id/secondRowPanel"
-                    android:layout_width="fill_parent"
-                    android:layout_height="wrap_content" >
-
-                    <LinearLayout
-                        android:id="@+id/filterButtonsList"
-                        android:layout_width="fill_parent"
-                        android:layout_height="@dimen/thumbnail_size"
-                        android:orientation="horizontal"
-                        android:visibility="gone" >
-
-                        <ViewStub android:id="@+id/editorPanelStub"
-                            android:inflatedId="@+id/editorPanel"
-                            android:layout="@layout/filtershow_editor_panel"
-                            android:layout_width="match_parent"
-                            android:layout_height="match_parent"
-                            android:visibility="visible"  />
-                    </LinearLayout>
-
-            <HorizontalScrollView
-                android:id="@+id/fxList"
-                android:layout_width="match_parent"
-                android:layout_height="@dimen/thumbnail_size"
-                android:background="@color/background_main_toolbar"
-                android:scrollbars="none" >
-
-                <LinearLayout
-                    android:id="@+id/listFilters"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    android:layout_marginLeft="@dimen/thumbnail_margin"
-                    android:orientation="horizontal" >
-                </LinearLayout>
-            </HorizontalScrollView>
-
-            <HorizontalScrollView
-                android:id="@+id/bordersList"
+                xmlns:custom="http://schemas.android.com/apk/res/com.android.gallery3d"
+                android:id="@+id/mainPanel"
                 android:layout_width="match_parent"
-                android:layout_height="@dimen/thumbnail_size"
-                android:background="@color/background_main_toolbar"
-                android:visibility="gone"
-                android:scrollbars="none" >
-
-                <LinearLayout
-                    android:id="@+id/listBorders"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    android:layout_marginLeft="@dimen/thumbnail_margin"
-                    android:orientation="horizontal" >
-                </LinearLayout>
-            </HorizontalScrollView>
-
-            <HorizontalScrollView
-                android:id="@+id/geometryList"
-                android:layout_width="fill_parent"
-                android:layout_height="@dimen/thumbnail_size"
-                android:background="@color/background_main_toolbar"
-                android:visibility="gone"
-                android:scrollbars="none" >
-
-                <LinearLayout
-                    android:id="@+id/listGeometry"
-                    android:layout_width="wrap_content"
-                    android:layout_height="fill_parent"
-                    android:layout_gravity="left"
-                    android:orientation="horizontal" />
-
-            </HorizontalScrollView>
-
-            <HorizontalScrollView
-                android:id="@+id/colorsFxList"
-                android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
-                android:background="@color/background_main_toolbar"
-                android:visibility="gone"
-                android:scrollbars="none" >
-
-                <LinearLayout
-                    android:id="@+id/listColorsFx"
-                    android:layout_width="wrap_content"
-                    android:layout_height="@dimen/thumbnail_size"
-                    android:background="@color/background_main_toolbar"
-                    android:layout_marginLeft="@dimen/thumbnail_margin"
-                    android:orientation="horizontal" >
-
-                </LinearLayout>
-            </HorizontalScrollView>
-        </FrameLayout>
-
-        <View
-            android:background="@color/toolbar_separation_line"
-            android:layout_height="1dip"
-            android:layout_width="match_parent" />
+                android:layout_gravity="center|bottom"
+                custom:max_width="650dip"
+                android:orientation="vertical" >
 
-        <com.android.gallery3d.filtershow.CenteredLinearLayout
-              xmlns:custom="http://schemas.android.com/apk/res/com.android.gallery3d"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:layout_gravity="center"
-              custom:max_width="400dip"
-              android:orientation="vertical">
-
-             <ViewStub android:id="@+id/stateCategoryStub"
-                  android:inflatedId="@+id/imageCategoryPanel"
-                  android:layout="@layout/filtershow_category_panel"
-                  android:layout_width="match_parent"
-                  android:layout_height="48dip"
-                  android:visibility="visible" />
+            <FrameLayout android:id="@+id/main_panel_container"
+                         android:layout_gravity="center"
+                         android:layout_width="match_parent"
+                         android:layout_height="0dip"
+                         android:layout_weight="1" />
 
-        </com.android.gallery3d.filtershow.CenteredLinearLayout>
+            <FrameLayout
+                    android:layout_gravity="bottom"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:visibility="gone">
 
-        </com.android.gallery3d.filtershow.CenteredLinearLayout>
 
-    </LinearLayout>
+                <ProgressBar
+                        android:id="@+id/loading"
+                        style="@android:style/Widget.Holo.ProgressBar.Large"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="center"
+                        android:indeterminate="true"
+                        android:indeterminateOnly="true"
+                        android:background="@color/background_screen"/>
 
-        <ViewStub android:id="@+id/statePanelStub"
-                  android:inflatedId="@+id/imageStatePanel"
-                  android:layout="@layout/filtershow_state_panel"
-                  android:layout_width="200dip"
-                  android:layout_height="match_parent"
-                  android:layout_gravity="right"
-                  android:visibility="visible" />
+            </FrameLayout>
 
-    </LinearLayout>
+        </com.android.gallery3d.filtershow.CenteredLinearLayout>
 
-    <ViewStub android:id="@+id/historyPanelStub"
-              android:inflatedId="@+id/historyPanel"
-              android:layout="@layout/filtershow_history_panel"
-              android:layout_width="200dip"
-              android:layout_height="match_parent"
-              android:layout_gravity="right"
-              android:visibility="invisible"  />
+    </LinearLayout>
 
 </FrameLayout>
diff --git a/res/layout/filtershow_category_panel_new.xml b/res/layout/filtershow_category_panel_new.xml
new file mode 100644 (file)
index 0000000..0dce498
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:custom="http://schemas.android.com/apk/res/com.android.gallery3d"
+              android:orientation="horizontal"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content">
+
+    <HorizontalScrollView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:scrollbars="none"
+            android:background="@color/background_main_toolbar" >
+
+        <com.android.gallery3d.filtershow.category.CategoryTrack
+                android:id="@+id/listItems"
+                android:layout_width="match_parent"
+                android:layout_height="128dip"
+                custom:iconSize="84dip"
+                android:divider="@android:color/transparent"
+                android:dividerPadding="8dip"
+                />
+
+    </HorizontalScrollView>
+
+</LinearLayout>
\ No newline at end of file
index a2c65cf..ac08153 100644 (file)
 -->
 
 <GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res/com.example.imagefilterharness"
     android:layout_width="match_parent"
-    android:layout_height="150dp"
+    android:layout_height="wrap_content"
     android:columnCount="2"
     android:orientation="horizontal" >
 
     <TextView
         android:id="@+id/controlName"
-        android:layout_gravity="left" />
+        android:layout_gravity="left"
+        android:layout_marginLeft="8dip" />
 
     <TextView
         android:id="@+id/controlValue"
-        android:layout_gravity="right" />
+        android:layout_gravity="right"
+        android:layout_marginRight="8dip" />
 
     <SeekBar
         android:id="@+id/controlValueSeekBar"
index 6822d98..c559319 100644 (file)
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/top"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_weight="0"
-    android:baselineAligned="false"
+    android:layout_height="wrap_content"
     android:orientation="vertical"
     android:visibility="visible" >
 
     <LinearLayout
-        android:id="@+id/controlArea"
         android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:orientation="horizontal"
-        android:visibility="visible" >
-
-        <SeekBar
-            android:id="@+id/primarySeekBar"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:layout_weight="1"
-            style="@style/FilterShowSlider" />
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
 
-    </LinearLayout>
+        <LinearLayout
+                android:id="@+id/controlArea"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:layout_alignParentBottom="true"
+                android:visibility="visible">
+
+            <SeekBar
+                    android:id="@+id/primarySeekBar"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_vertical"
+                    style="@style/FilterShowSlider"/>
 
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="56dip"
-        android:layout_weight="0"
-        android:layout_gravity="bottom"
-        android:background="@color/background_main_toolbar"
-        android:orientation="horizontal"
-        android:baselineAligned="false"
-        android:visibility="visible" >
-
-        <ImageButton
-            android:id="@+id/cancelFilter"
-            android:layout_width="wrap_content"
-            android:layout_height="fill_parent"
-            android:layout_gravity="left|center_vertical"
-            android:background="@android:color/transparent"
-            android:layout_weight=".1"
-            android:gravity="center"
-            android:src="@drawable/ic_menu_cancel_holo_light"
-            android:textSize="18dip" />
-
-        <ImageView
-            android:layout_width="2dp"
-            android:layout_height="fill_parent"
-            android:src="@drawable/filtershow_vertical_bar" />
+        </LinearLayout>
 
         <LinearLayout
-            android:id="@+id/panelAccessoryViewList"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            android:orientation="horizontal"
-            android:visibility="visible" >
-
-            <com.android.gallery3d.filtershow.editors.SwapButton
-                android:id="@+id/applyEffect"
-                android:layout_width="fill_parent"
-                android:layout_height="fill_parent"
-                android:layout_gravity="center"
-                android:background="@android:color/transparent"
-                android:gravity="center"
-                android:text="@string/apply_effect"
-                android:textSize="18dip"
-                android:drawableRight="@drawable/filtershow_menu_marker"/>
-
+                android:layout_width="match_parent"
+                android:layout_height="56dip"
+                android:background="@color/background_main_toolbar"
+                android:orientation="horizontal"
+                android:baselineAligned="false"
+                android:visibility="visible">
+
+            <ImageButton
+                    android:id="@+id/cancelFilter"
+                    android:layout_width="wrap_content"
+                    android:layout_height="fill_parent"
+                    android:layout_gravity="left|center_vertical"
+                    android:background="@android:color/transparent"
+                    android:layout_weight=".1"
+                    android:gravity="center"
+                    android:src="@drawable/ic_menu_cancel_holo_light"
+                    android:textSize="18dip"/>
+
+            <ImageView
+                    android:layout_width="2dp"
+                    android:layout_height="fill_parent"
+                    android:src="@drawable/filtershow_vertical_bar"/>
+
+            <LinearLayout
+                    android:id="@+id/panelAccessoryViewList"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:orientation="horizontal"
+                    android:visibility="visible">
+
+                <com.android.gallery3d.filtershow.editors.SwapButton
+                        android:id="@+id/applyEffect"
+                        android:layout_width="fill_parent"
+                        android:layout_height="fill_parent"
+                        android:layout_gravity="center"
+                        android:background="@android:color/transparent"
+                        android:gravity="center"
+                        android:text="@string/apply_effect"
+                        android:textSize="18dip"
+                        android:drawableRight="@drawable/filtershow_menu_marker"/>
+
+            </LinearLayout>
+
+            <ImageView
+                    android:layout_width="2dp"
+                    android:layout_height="fill_parent"
+                    android:src="@drawable/filtershow_vertical_bar"/>
+
+            <ImageButton
+                    android:id="@+id/applyFilter"
+                    android:layout_width="wrap_content"
+                    android:layout_height="fill_parent"
+                    android:layout_gravity="right|center_vertical"
+                    android:layout_weight=".1"
+                    android:background="@android:color/transparent"
+                    android:gravity="center"
+                    android:src="@drawable/ic_menu_done_holo_light"
+                    android:textSize="18dip"/>
         </LinearLayout>
 
-        <ImageView
-            android:layout_width="2dp"
-            android:layout_height="fill_parent"
-            android:src="@drawable/filtershow_vertical_bar" />
-
-        <ImageButton
-            android:id="@+id/applyFilter"
-            android:layout_width="wrap_content"
-            android:layout_height="fill_parent"
-            android:layout_gravity="right|center_vertical"
-            android:layout_weight=".1"
-            android:background="@android:color/transparent"
-            android:gravity="center"
-            android:src="@drawable/ic_menu_done_holo_light"
-            android:textSize="18dip" />
+        <FrameLayout android:id="@+id/state_panel_container"
+                     android:layout_width="match_parent"
+                     android:layout_height="wrap_content"
+                     android:visibility="visible"
+                     android:layout_gravity="top"
+                     android:layout_weight="1" />
+
     </LinearLayout>
 
 </LinearLayout>
diff --git a/res/layout/filtershow_imagestate_row.xml b/res/layout/filtershow_imagestate_row.xml
deleted file mode 100644 (file)
index d62f54c..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<com.android.gallery3d.filtershow.MovableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="128dip"
-    android:orientation="horizontal"
-    android:background="@drawable/filtershow_button_background">
-
-    <ImageView
-            android:id="@+id/selectedMark"
-            android:src="@drawable/camera_crop"
-            android:background="@android:color/transparent"
-            android:layout_width="32dip"
-            android:layout_height="match_parent"
-            android:scaleType="centerInside"
-            android:visibility="visible"
-            android:layout_weight="1"
-            >
-    </ImageView>
-
-    <TextView
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@+id/imagestate_label"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:gravity="left"
-        android:padding="10dip"
-        android:textSize="16dip" >
-    </TextView>
-
-    <TextView
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:id="@+id/imagestate_parameter"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:gravity="right"
-        android:padding="10dip"
-        android:textSize="16dip"
-        android:textStyle="bold" >
-    </TextView>
-
-</com.android.gallery3d.filtershow.MovableLinearLayout>
\ No newline at end of file
diff --git a/res/layout/filtershow_main_panel.xml b/res/layout/filtershow_main_panel.xml
new file mode 100644 (file)
index 0000000..768d3df
--- /dev/null
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:baselineAligned="false"
+              android:orientation="vertical"
+              android:animateLayoutChanges="false"
+              android:visibility="visible"
+              android:background="@color/background_main_toolbar" >
+
+    <FrameLayout android:id="@+id/state_panel_container"
+                 android:layout_width="match_parent"
+                 android:layout_height="wrap_content"
+                 android:visibility="visible"
+                 android:layout_gravity="top"
+                 android:layout_weight="1" />
+
+    <FrameLayout android:id="@+id/category_panel_container"
+                 android:layout_width="wrap_content"
+                 android:visibility="visible"
+                 android:layout_height="0dip"
+                 android:layout_gravity="center"
+                 android:layout_weight="1"/>
+
+    <View
+            android:background="@color/toolbar_separation_line"
+            android:layout_height="1dip"
+            android:layout_width="match_parent"/>
+
+    <com.android.gallery3d.filtershow.CenteredLinearLayout
+            xmlns:custom="http://schemas.android.com/apk/res/com.android.gallery3d"
+            android:layout_width="match_parent"
+            android:layout_height="48dip"
+            android:layout_gravity="center|bottom"
+            custom:max_width="400dip"
+            android:orientation="vertical">
+
+        <LinearLayout android:layout_width="wrap_content"
+                      android:layout_height="match_parent"
+                      android:background="@color/background_main_toolbar">
+
+            <ImageButton
+                    android:id="@+id/fxButton"
+                    android:layout_width="@dimen/thumbnail_size"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:background="@drawable/filtershow_button_background"
+                    android:scaleType="centerInside"
+                    android:src="@drawable/ic_photoeditor_effects"/>
+
+            <ImageButton
+                    android:id="@+id/borderButton"
+                    android:layout_width="@dimen/thumbnail_size"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:background="@drawable/filtershow_button_background"
+                    android:padding="2dip"
+                    android:scaleType="centerInside"
+                    android:src="@drawable/ic_photoeditor_border"/>
+
+            <ImageButton
+                    android:id="@+id/geometryButton"
+                    android:layout_width="@dimen/thumbnail_size"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:background="@drawable/filtershow_button_background"
+                    android:padding="2dip"
+                    android:scaleType="centerInside"
+                    android:src="@drawable/ic_photoeditor_fix"/>
+
+            <ImageButton
+                    android:id="@+id/colorsButton"
+                    android:layout_width="@dimen/thumbnail_size"
+                    android:layout_height="match_parent"
+                    android:layout_weight="1"
+                    android:background="@drawable/filtershow_button_background"
+                    android:padding="2dip"
+                    android:scaleType="centerInside"
+                    android:src="@drawable/ic_photoeditor_color"/>
+
+        </LinearLayout>
+
+    </com.android.gallery3d.filtershow.CenteredLinearLayout>
+
+</LinearLayout>
\ No newline at end of file
index 53f5980..6463ca8 100644 (file)
@@ -19,7 +19,6 @@
     android:id="@+id/top"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_weight="0"
     android:orientation="vertical"
     android:visibility="visible" >
 
@@ -27,7 +26,6 @@
         android:id="@+id/primarySeekBar"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_weight="1"
         style="@style/FilterShowSlider" />
 
 </LinearLayout>
index 7711221..ea891a3 100644 (file)
@@ -1,47 +1,27 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:custom="http://schemas.android.com/apk/res/com.android.gallery3d"
               android:orientation="horizontal"
               android:layout_width="match_parent"
-              android:layout_height="match_parent">
+              android:layout_height="wrap_content">
 
-    <!--
-    <com.example.StatePanel.VerticalStatePanelTrack
-            android:id="@+id/listStates"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_margin="8dip"
-            android:background="@android:color/holo_red_dark" />
-            -->
-
-    <ScrollView
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:scrollbars="none">
-
-    <com.android.gallery3d.filtershow.state.StatePanelTrack
-            android:id="@+id/listStates"
-            android:orientation="vertical"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_margin="8dip"
-            android:animateLayoutChanges="true" />
-
-    </ScrollView>
-
-    <!--
     <HorizontalScrollView
             android:layout_width="match_parent"
-            android:layout_height="128dip"
+            android:layout_height="wrap_content"
             android:scrollbars="none">
 
-        <com.example.StatePanel.StatePanelTrack
+        <com.android.gallery3d.filtershow.state.StatePanelTrack
                 android:id="@+id/listStates"
+                android:orientation="horizontal"
                 android:layout_width="match_parent"
-                android:layout_height="128dip"
+                android:layout_height="48dip"
+                custom:elemEndSize="128dip"
+                custom:elemSize="128dip"
+                android:layout_margin="8dip"
                 android:animateLayoutChanges="true" />
 
     </HorizontalScrollView>
-    -->
+
 
 </LinearLayout>
diff --git a/res/values-large/filtershow_values.xml b/res/values-large/filtershow_values.xml
new file mode 100644 (file)
index 0000000..1098ee0
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <!-- Specify the screen orientation -->
+    <bool name="only_use_portrait">false</bool>
+</resources>
\ No newline at end of file
diff --git a/res/values-xlarge/filtershow_values.xml b/res/values-xlarge/filtershow_values.xml
new file mode 100644 (file)
index 0000000..1098ee0
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <!-- Specify the screen orientation -->
+    <bool name="only_use_portrait">false</bool>
+</resources>
\ No newline at end of file
index 582ddcb..5a00a69 100644 (file)
@@ -18,9 +18,6 @@
         <attr name="listPreferredItemHeightSmall" format="dimension" />
         <attr name="switchStyle" format="reference" />
     </declare-styleable>
-    <declare-styleable name="CenteredLinearLayout">
-        <attr name="max_width" format="dimension" />
-    </declare-styleable>
 
     <!-- Camera resources below -->
 
index aba596f..94697d1 100644 (file)
@@ -50,6 +50,7 @@
     <!--  configuration for filtershow UI -->
     <dimen name="thumbnail_size">96dip</dimen>
     <dimen name="thumbnail_margin">3dip</dimen>
+    <dimen name="action_item_height">175dip</dimen>
 
     <!-- configuration for album set page -->
     <dimen name="album_set_item_image_height">120dp</dimen>
index 70191fd..f6bf7fb 100644 (file)
     <color name="toolbar_separation_line">#333333</color>
     <color name="slider_dot_color">#6464FF</color>
     <color name="slider_line_color">#33B5E5</color>
+    <color name="state_panel_separation_line">#232323</color>
     <color name="filtershow_background">#333333</color>
     <color name="filtershow_graphic">#717171</color>
-
+    <color name="filtershow_stateview_end_background">#232323</color>
+    <color name="filtershow_stateview_end_text">#a7a7a7</color>
+    <color name="filtershow_stateview_background">#464646</color>
+    <color name="filtershow_stateview_text">#FFFFFF</color>
+    <color name="filtershow_stateview_selected_background">#c8c8c8</color>
+    <color name="filtershow_stateview_selected_text">#000000</color>
+    <color name="filtershow_categoryview_background">#1a1a1a</color>
+    <color name="filtershow_categoryview_text">#a7a7a7</color>
 </resources>
\ No newline at end of file
index b8d4929..c8ad2a9 100644 (file)
@@ -15,7 +15,6 @@
 -->
 
 <resources>
-
     <!--  Title for the image editor activity [CHAR LIMIT=NONE]-->
     <string name="title_activity_filter_show">Photo Editor</string>
 
diff --git a/res/values/filtershow_values.xml b/res/values/filtershow_values.xml
new file mode 100644 (file)
index 0000000..f516a39
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <!-- Specify the screen orientation -->
+    <bool name="only_use_portrait">true</bool>
+</resources>
\ No newline at end of file
index 67c645d..32a3a87 100644 (file)
         <attr name="android:text"/>
         <attr name="android:textColor"/>
     </declare-styleable>
+    <declare-styleable name="CenteredLinearLayout">
+        <attr name="max_width" format="dimension" />
+    </declare-styleable>
+    <declare-styleable name="StatePanelTrack">
+        <attr name="elemSize" format="dimension" />
+        <attr name="elemEndSize" format="dimension" />
+    </declare-styleable>
+    <declare-styleable name="CategoryTrack">
+        <attr name="iconSize" format="dimension" />
+    </declare-styleable>
 </resources>
\ No newline at end of file
index 38424ec..30d4dde 100644 (file)
@@ -12,7 +12,7 @@ import java.util.HashMap;
 import java.util.Vector;
 
 public class EditorPlaceHolder {
-    private static final String LOGTAG = "PanelController";
+    private static final String LOGTAG = "EditorPlaceHolder";
 
     private FilterShowActivity mActivity = null;
     private FrameLayout mContainer = null;
@@ -88,4 +88,5 @@ public class EditorPlaceHolder {
     public Editor getEditor(int editorId) {
         return mEditors.get(editorId);
     }
+
 }
index 20061ee..eb5c258 100644 (file)
@@ -21,66 +21,54 @@ import android.app.AlertDialog;
 import android.app.ProgressDialog;
 import android.app.WallpaperManager;
 import android.content.ContentValues;
-import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
-import android.provider.MediaStore;
+import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentActivity;
 import android.support.v4.app.FragmentTransaction;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.TypedValue;
-import android.view.*;
+import android.view.Display;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
 import android.view.View.OnClickListener;
+import android.view.WindowManager;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.FrameLayout;
-import android.widget.ImageButton;
-import android.widget.LinearLayout;
-import android.widget.ListView;
 import android.widget.ShareActionProvider;
 import android.widget.ShareActionProvider.OnShareTargetSelectedListener;
-import android.widget.Toast;
 
+import android.widget.Toast;
 import com.android.gallery3d.R;
 import com.android.gallery3d.data.LocalAlbum;
 import com.android.gallery3d.filtershow.cache.CachingPipeline;
 import com.android.gallery3d.filtershow.cache.FilteringPipeline;
 import com.android.gallery3d.filtershow.cache.ImageLoader;
+import com.android.gallery3d.filtershow.category.*;
 import com.android.gallery3d.filtershow.crop.CropExtras;
-import com.android.gallery3d.filtershow.editors.BasicEditor;
-import com.android.gallery3d.filtershow.editors.EditorCrop;
-import com.android.gallery3d.filtershow.editors.EditorDraw;
-import com.android.gallery3d.filtershow.editors.EditorFlip;
-import com.android.gallery3d.filtershow.editors.EditorInfo;
-import com.android.gallery3d.filtershow.editors.EditorManager;
-import com.android.gallery3d.filtershow.editors.EditorRedEye;
-import com.android.gallery3d.filtershow.editors.EditorRotate;
-import com.android.gallery3d.filtershow.editors.EditorStraighten;
-import com.android.gallery3d.filtershow.editors.EditorTinyPlanet;
-import com.android.gallery3d.filtershow.editors.ImageOnlyEditor;
+import com.android.gallery3d.filtershow.editors.*;
 import com.android.gallery3d.filtershow.filters.*;
 import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
 import com.android.gallery3d.filtershow.imageshow.ImageCrop;
 import com.android.gallery3d.filtershow.imageshow.ImageShow;
-import com.android.gallery3d.filtershow.imageshow.ImageTinyPlanet;
 import com.android.gallery3d.filtershow.imageshow.MasterImage;
 import com.android.gallery3d.filtershow.presets.ImagePreset;
 import com.android.gallery3d.filtershow.provider.SharedImageProvider;
 import com.android.gallery3d.filtershow.state.StateAdapter;
-import com.android.gallery3d.filtershow.state.StatePanel;
 import com.android.gallery3d.filtershow.tools.BitmapTask;
 import com.android.gallery3d.filtershow.tools.SaveCopyTask;
-import com.android.gallery3d.filtershow.ui.FilterIconButton;
 import com.android.gallery3d.filtershow.ui.FramedTextButton;
 import com.android.gallery3d.filtershow.ui.Spline;
 import com.android.gallery3d.util.GalleryUtils;
@@ -94,8 +82,6 @@ import java.util.Vector;
 public class FilterShowActivity extends FragmentActivity implements OnItemClickListener,
         OnShareTargetSelectedListener {
 
-    private String mPanelFragmentTag = "StatePanel";
-
     // fields for supporting crop action
     public static final String CROP_ACTION = "com.android.camera.action.CROP";
     private CropExtras mCropExtras = null;
@@ -107,10 +93,8 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
     public static final String TINY_PLANET_ACTION = "com.android.camera.action.TINY_PLANET";
     public static final String LAUNCH_FULLSCREEN = "launch-fullscreen";
     public static final int MAX_BMAP_IN_INTENT = 990000;
-    private final PanelController mPanelController = new PanelController();
     private ImageLoader mImageLoader = null;
     private ImageShow mImageShow = null;
-    private ImageTinyPlanet mImageTinyPlanet = null;
 
     private View mSaveButton = null;
 
@@ -133,16 +117,22 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
     private WeakReference<ProgressDialog> mSavingProgressDialog;
 
     private LoadBitmapTask mLoadBitmapTask;
-    private FilterIconButton mNullFxFilter;
-    private FilterIconButton mNullBorderFilter;
-    private int mIconSeedSize = 140;
 
-    private View mImageCategoryPanel = null;
+    private CategoryAdapter mCategoryLooksAdapter = null;
+    private CategoryAdapter mCategoryBordersAdapter = null;
+    private CategoryAdapter mCategoryGeometryAdapter = null;
+    private CategoryAdapter mCategoryFiltersAdapter = null;
+    private int mCurrentPanel = MainPanel.LOOKS;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        boolean onlyUsePortrait = getResources().getBoolean(R.bool.only_use_portrait);
+        if (onlyUsePortrait) {
+            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+        }
+
         clearGalleryBitmapPool();
 
         CachingPipeline.createRenderscriptContext(this);
@@ -151,27 +141,45 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
         fillEditors();
 
         loadXML();
-
-        if (getResources().getConfiguration().orientation
-                == Configuration.ORIENTATION_LANDSCAPE) {
-            mShowingImageStatePanel = true;
-        }
-
-        if (mShowingImageStatePanel && (savedInstanceState == null)) {
-            loadImageStatePanel();
-        }
+        loadMainPanel();
 
         setDefaultPreset();
 
         processIntent();
     }
 
+    public boolean isShowingImageStatePanel() {
+        return mShowingImageStatePanel;
+    }
+
+    public void loadMainPanel() {
+        if (findViewById(R.id.main_panel_container) == null) {
+            return;
+        }
+        MainPanel panel = new MainPanel();
+        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+        transaction.replace(R.id.main_panel_container, panel, MainPanel.FRAGMENT_TAG);
+        transaction.commit();
+    }
+
+    public void loadEditorPanel(FilterRepresentation representation,
+                                Editor currentEditor) {
+        if (representation.getEditorId() == ImageOnlyEditor.ID) {
+            currentEditor.getImageShow().select();
+            currentEditor.reflectCurrentFilter();
+            return;
+        }
+        EditorPanel panel = new EditorPanel();
+        panel.setEditor(currentEditor.getID());
+        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+        transaction.remove(getSupportFragmentManager().findFragmentByTag(MainPanel.FRAGMENT_TAG));
+        transaction.replace(R.id.main_panel_container, panel, MainPanel.FRAGMENT_TAG);
+        transaction.commit();
+    }
+
     private void loadXML() {
         setContentView(R.layout.filtershow_activity);
 
-        ((ViewStub) findViewById(R.id.stateCategoryStub)).inflate();
-        ((ViewStub) findViewById(R.id.editorPanelStub)).inflate();
-
         ActionBar actionBar = getActionBar();
         actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
         actionBar.setCustomView(R.layout.filtershow_actionbar);
@@ -185,70 +193,38 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
         });
 
         mImageShow = (ImageShow) findViewById(R.id.imageShow);
-        mImageTinyPlanet = (ImageTinyPlanet) findViewById(R.id.imageTinyPlanet);
         mImageViews.add(mImageShow);
-        mImageViews.add(mImageTinyPlanet);
 
         setupEditors();
 
         mEditorPlaceHolder.hide();
 
         mImageShow.setImageLoader(mImageLoader);
-        mImageTinyPlanet.setImageLoader(mImageLoader);
-
-        mPanelController.clear();
-        mPanelController.setActivity(this);
-        mPanelController.setEditorPlaceHolder(mEditorPlaceHolder);
 
-        mPanelController.addImageView(findViewById(R.id.imageShow));
-        mPanelController.addImageView(findViewById(R.id.imageTinyPlanet));
-
-        mPanelController.addPanel(R.id.fxButton, R.id.fxList, 0);
-        mPanelController.addPanel(R.id.borderButton, R.id.bordersList, 1);
-        mPanelController.addPanel(R.id.geometryButton, R.id.geometryList, 2);
-        mPanelController.addPanel(R.id.colorsButton, R.id.colorsFxList, 3);
-
-        fillFx((LinearLayout) findViewById(R.id.listFilters), R.id.fxButton);
-        setupBorders();
+        fillFx();
+        fillBorders();
         fillGeometry();
         fillFilters();
 
-        mPanelController.addView(findViewById(R.id.applyEffect));
-
         setupStatePanel();
-
-        mImageCategoryPanel = findViewById(R.id.imageCategoryPanel);
-    }
-
-    public void hideCategoryPanel() {
-        mImageCategoryPanel.setVisibility(View.GONE);
-    }
-
-    public void showCategoryPanel() {
-        mImageCategoryPanel.setVisibility(View.VISIBLE);
     }
 
     public void setupStatePanel() {
         mImageLoader.setAdapter(mMasterImage.getHistory());
-        mPanelController.setRowPanel(findViewById(R.id.secondRowPanel));
-        mPanelController.setUtilityPanel(this, findViewById(R.id.filterButtonsList));
-        mPanelController.setCurrentPanel(R.id.fxButton);
-    }
-
-    private void fillPanel(Vector<FilterRepresentation> representations, int layoutId, int buttonId) {
-        ImageButton button = (ImageButton) findViewById(buttonId);
-        LinearLayout layout = (LinearLayout) findViewById(layoutId);
-
-        for (FilterRepresentation representation : representations) {
-            setupFilterRepresentationButton(representation, layout, button);
-        }
     }
 
     private void fillFilters() {
         Vector<FilterRepresentation> filtersRepresentations = new Vector<FilterRepresentation>();
         FiltersManager filtersManager = FiltersManager.getManager();
         filtersManager.addEffects(filtersRepresentations);
-        fillPanel(filtersRepresentations, R.id.listColorsFx, R.id.colorsButton);
+
+        mCategoryFiltersAdapter = new CategoryAdapter(this);
+        for (FilterRepresentation representation : filtersRepresentations) {
+            if (representation.getTextId() != 0) {
+                representation.setName(getString(representation.getTextId()));
+            }
+            mCategoryFiltersAdapter.add(new Action(this, representation));
+        }
     }
 
     private void fillGeometry() {
@@ -265,11 +241,18 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
             geometry.setTextId(editorInfo.getTextId());
             geometry.setOverlayId(editorInfo.getOverlayId());
             geometry.setOverlayOnly(editorInfo.getOverlayOnly());
+            if (geometry.getTextId() != 0) {
+                geometry.setName(getString(geometry.getTextId()));
+            }
             filtersRepresentations.add(geometry);
         }
 
         filtersManager.addTools(filtersRepresentations);
-        fillPanel(filtersRepresentations, R.id.listGeometry, R.id.geometryButton);
+
+        mCategoryGeometryAdapter = new CategoryAdapter(this);
+        for (FilterRepresentation representation : filtersRepresentations) {
+            mCategoryGeometryAdapter.add(new Action(this, representation));
+        }
     }
 
     private void processIntent() {
@@ -285,41 +268,6 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
         } else {
             pickImage();
         }
-
-        // Handle behavior for various actions
-        if (mAction.equalsIgnoreCase(CROP_ACTION)) {
-            Bundle extras = intent.getExtras();
-            if (extras != null) {
-                mCropExtras = new CropExtras(extras.getInt(CropExtras.KEY_OUTPUT_X, 0),
-                        extras.getInt(CropExtras.KEY_OUTPUT_Y, 0),
-                        extras.getBoolean(CropExtras.KEY_SCALE, true) &&
-                                extras.getBoolean(CropExtras.KEY_SCALE_UP_IF_NEEDED, false),
-                        extras.getInt(CropExtras.KEY_ASPECT_X, 0),
-                        extras.getInt(CropExtras.KEY_ASPECT_Y, 0),
-                        extras.getBoolean(CropExtras.KEY_SET_AS_WALLPAPER, false),
-                        extras.getBoolean(CropExtras.KEY_RETURN_DATA, false),
-                        (Uri) extras.getParcelable(MediaStore.EXTRA_OUTPUT),
-                        extras.getString(CropExtras.KEY_OUTPUT_FORMAT),
-                        extras.getBoolean(CropExtras.KEY_SHOW_WHEN_LOCKED, false),
-                        extras.getFloat(CropExtras.KEY_SPOTLIGHT_X),
-                        extras.getFloat(CropExtras.KEY_SPOTLIGHT_Y));
-
-                if (mCropExtras.getShowWhenLocked()) {
-                    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
-                }
-                mImageShow.getImagePreset().mGeoData.setCropExtras(mCropExtras);
-
-                // FIXME: moving to editors breaks the crop action
-                EditorCrop crop = (EditorCrop) mEditorPlaceHolder.getEditor(EditorCrop.ID);
-
-                crop.setExtras(mCropExtras);
-                String s = getString(R.string.Fixed);
-                crop.setAspectString(s);
-                crop.setCropActionFlag(true);
-                mPanelController.setFixedAspect(mCropExtras.getAspectX() > 0
-                        && mCropExtras.getAspectY() > 0);
-            }
-        }
     }
 
     private void setupEditors() {
@@ -347,6 +295,9 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
         Resources res = getResources();
         FiltersManager.setResources(res);
 
+        CategoryView.setMargin((int) getPixelsFromDip(8));
+        CategoryView.setTextSize((int) getPixelsFromDip(16));
+
         ImageShow.setDefaultBackgroundColor(res.getColor(R.color.background_screen));
         // TODO: get those values from XML.
         FramedTextButton.setTextSize((int) getPixelsFromDip(14));
@@ -357,9 +308,6 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
         ImageShow.setOriginalTextMargin((int) getPixelsFromDip(4));
         ImageShow.setOriginalTextSize((int) getPixelsFromDip(18));
         ImageShow.setOriginalText(res.getString(R.string.original_picture_text));
-        mIconSeedSize = res.getDimensionPixelSize(R.dimen.thumbnail_size);
-        // TODO: pick correct value
-        // MasterImage.setIconSeedSize(mIconSeedSize);
 
         Drawable curveHandle = res.getDrawable(R.drawable.camera_crop);
         int curveHandleSize = (int) res.getDimension(R.dimen.crop_indicator_size);
@@ -372,26 +320,17 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
     }
 
     private void startLoadBitmap(Uri uri) {
-        final View filters = findViewById(R.id.filtersPanel);
         final View loading = findViewById(R.id.loading);
         final View imageShow = findViewById(R.id.imageShow);
         imageShow.setVisibility(View.INVISIBLE);
-        filters.setVisibility(View.INVISIBLE);
         loading.setVisibility(View.VISIBLE);
-
-        View tinyPlanetView = findViewById(EditorTinyPlanet.ID);
-        if (tinyPlanetView != null) {
-            mShowingTinyPlanet = false;
-            tinyPlanetView.setVisibility(View.GONE);
-        }
-        mLoadBitmapTask = new LoadBitmapTask(tinyPlanetView);
+        mShowingTinyPlanet = false;
+        mLoadBitmapTask = new LoadBitmapTask();
         mLoadBitmapTask.execute(uri);
     }
 
-    private void setupBorders() {
-        LinearLayout list = (LinearLayout) findViewById(R.id.listBorders);
+    private void fillBorders() {
         Vector<FilterRepresentation> borders = new Vector<FilterRepresentation>();
-        ImageButton borderButton = (ImageButton) findViewById(R.id.borderButton);
 
         // The "no border" implementation
         borders.add(new FilterImageBorderRepresentation(0));
@@ -404,20 +343,95 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
             if (i == 0) {
                 filter.setName(getString(R.string.none));
             }
-            FilterIconButton b = setupFilterRepresentationButton(filter, list, borderButton);
-            if (i == 0) {
-                mNullBorderFilter = b;
-                mNullBorderFilter.setSelected(true);
+        }
+
+        mCategoryBordersAdapter = new CategoryAdapter(this);
+        for (FilterRepresentation representation : borders) {
+            if (representation.getTextId() != 0) {
+                representation.setName(getString(representation.getTextId()));
+            }
+            mCategoryBordersAdapter.add(new Action(this, representation));
+        }
+    }
+
+    public CategoryAdapter getCategoryLooksAdapter() {
+        return mCategoryLooksAdapter;
+    }
+
+    public CategoryAdapter getCategoryBordersAdapter() {
+        return mCategoryBordersAdapter;
+    }
+
+    public CategoryAdapter getCategoryGeometryAdapter() {
+        return mCategoryGeometryAdapter;
+    }
+
+    public CategoryAdapter getCategoryFiltersAdapter() {
+        return mCategoryFiltersAdapter;
+    }
+
+    public void removeFilterRepresentation(FilterRepresentation filterRepresentation) {
+        if (filterRepresentation == null) {
+            return;
+        }
+        ImagePreset oldPreset = MasterImage.getImage().getPreset();
+        ImagePreset copy = new ImagePreset(oldPreset);
+        copy.removeFilter(filterRepresentation);
+        MasterImage.getImage().setPreset(copy, true);
+        if (MasterImage.getImage().getCurrentFilterRepresentation() == filterRepresentation) {
+            FilterRepresentation lastRepresentation = copy.getLastRepresentation();
+            MasterImage.getImage().setCurrentFilterRepresentation(lastRepresentation);
+        }
+    }
+
+    public void useFilterRepresentation(FilterRepresentation filterRepresentation) {
+        if (filterRepresentation == null) {
+            return;
+        }
+        if (MasterImage.getImage().getCurrentFilterRepresentation() == filterRepresentation) {
+            return;
+        }
+        ImagePreset oldPreset = MasterImage.getImage().getPreset();
+        ImagePreset copy = new ImagePreset(oldPreset);
+        FilterRepresentation representation = copy.getRepresentation(filterRepresentation);
+        if (representation == null) {
+            copy.addFilter(filterRepresentation);
+        } else {
+            if (filterRepresentation.allowsMultipleInstances()) {
+                representation.updateTempParametersFrom(filterRepresentation);
+                copy.setHistoryName(filterRepresentation.getName());
+                representation.synchronizeRepresentation();
             }
+            filterRepresentation = representation;
         }
+        MasterImage.getImage().setPreset(copy, true);
+        MasterImage.getImage().setCurrentFilterRepresentation(filterRepresentation);
+    }
+
+    public void showRepresentation(FilterRepresentation representation) {
+        useFilterRepresentation(representation);
+
+        // show representation
+        Editor mCurrentEditor = mEditorPlaceHolder.showEditor(representation.getEditorId());
+        loadEditorPanel(representation, mCurrentEditor);
+    }
+
+    public Editor getEditor(int editorID) {
+        return mEditorPlaceHolder.getEditor(editorID);
+    }
+
+    public void setCurrentPanel(int currentPanel) {
+        mCurrentPanel = currentPanel;
+    }
+
+    public int getCurrentPanel() {
+        return mCurrentPanel;
     }
 
     private class LoadBitmapTask extends AsyncTask<Uri, Boolean, Boolean> {
-        View mTinyPlanetButton;
         int mBitmapSize;
 
-        public LoadBitmapTask(View button) {
-            mTinyPlanetButton = button;
+        public LoadBitmapTask() {
             mBitmapSize = getScreenImageSize();
         }
 
@@ -438,7 +452,6 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
             }
             if (values[0]) {
                 mShowingTinyPlanet = true;
-                mTinyPlanetButton.setVisibility(View.VISIBLE);
             }
         }
 
@@ -455,13 +468,6 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
 
             final View loading = findViewById(R.id.loading);
             loading.setVisibility(View.GONE);
-            final View filters = findViewById(R.id.filtersPanel);
-            filters.setVisibility(View.VISIBLE);
-            if (PanelController.useAnimationsLayer()) {
-                float y = filters.getY();
-                filters.setY(y + filters.getHeight());
-                filters.animate().setDuration(600).y(y).withLayer().start();
-            }
             final View imageShow = findViewById(R.id.imageShow);
             imageShow.setVisibility(View.VISIBLE);
 
@@ -475,15 +481,19 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
                 float highResPreviewScale = (float) highresBitmap.getWidth() / (float) mImageLoader.getOriginalBounds().width();
                 pipeline.setHighResPreviewScaleFactor(highResPreviewScale);
             }
+            if (!mShowingTinyPlanet) {
+                mCategoryFiltersAdapter.removeTinyPlanet();
+            }
             pipeline.turnOnPipeline(true);
             MasterImage.getImage().setOriginalGeometry(largeBitmap);
+            mCategoryLooksAdapter.imageLoaded();
+            mCategoryBordersAdapter.imageLoaded();
+            mCategoryGeometryAdapter.imageLoaded();
+            mCategoryFiltersAdapter.imageLoaded();
             mLoadBitmapTask = null;
 
-            if (mAction == CROP_ACTION) {
-                mPanelController.showComponent(findViewById(EditorCrop.ID));
-            } else if (mAction == TINY_PLANET_ACTION) {
-                FilterIconButton button = (FilterIconButton) findViewById(EditorTinyPlanet.ID);
-                button.onClick(button);
+            if (mAction == TINY_PLANET_ACTION) {
+                showRepresentation(mCategoryFiltersAdapter.getTinyPlanet());
             }
             super.onPostExecute(result);
         }
@@ -506,8 +516,7 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
         if (mLoadBitmapTask != null) {
             mLoadBitmapTask.cancel(false);
         }
-        // TODO:  Using singletons is a bad design choice for many of these
-        // due static reference leaks and in general.  Please refactor.
+        // TODO:  refactor, don't use so many singletons.
         FilteringPipeline.getPipeline().turnOnPipeline(false);
         MasterImage.reset();
         FilteringPipeline.reset();
@@ -520,30 +529,6 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
         super.onDestroy();
     }
 
-    private int translateMainPanel(View viewPanel) {
-        int accessoryPanelWidth = viewPanel.getWidth();
-        if (accessoryPanelWidth == 0) {
-            // TODO: fixes this by using a fragment. Currently,
-            // the first time we get called the panel hasn't been
-            // layed out yet, so we get a size zero.
-            accessoryPanelWidth = (int) getPixelsFromDip(200);
-        }
-        int mainViewWidth = findViewById(R.id.mainView).getWidth();
-        int mainPanelWidth = mImageShow.getDisplayedImageBounds().width();
-        if (mainPanelWidth == 0) {
-            mainPanelWidth = mainViewWidth;
-        }
-        int filtersPanelWidth = findViewById(R.id.filtersPanel).getWidth();
-        if (mainPanelWidth < filtersPanelWidth) {
-            mainPanelWidth = filtersPanelWidth;
-        }
-        int leftOver = mainViewWidth - mainPanelWidth - accessoryPanelWidth;
-        if (leftOver < 0) {
-            return -accessoryPanelWidth;
-        }
-        return 0;
-    }
-
     private int getScreenImageSize() {
         DisplayMetrics metrics = new DisplayMetrics();
         Display display = getWindowManager().getDefaultDisplay();
@@ -666,7 +651,6 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.undoButton: {
-                mPanelController.resetParameters();
                 HistoryAdapter adapter = mMasterImage.getHistory();
                 int position = adapter.undo();
                 mMasterImage.onHistoryItemClick(position);
@@ -703,36 +687,18 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
             mSaveButton.setEnabled(enable);
     }
 
-    public FilterIconButton setupFilterRepresentationButton(FilterRepresentation representation, LinearLayout panel, View button) {
-        LayoutInflater inflater =
-                (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        FilterIconButton icon = (FilterIconButton) inflater.inflate(R.layout.filtericonbutton,
-                panel, false);
-        if (representation.getTextId() != 0) {
-            representation.setName(getString(representation.getTextId()));
-        }
-        String text = representation.getName();
-        icon.setup(text, mPanelController, panel);
-        icon.setFilterRepresentation(representation);
-        icon.setId(representation.getEditorId());
-        mPanelController.addComponent(button, icon);
-        panel.addView(icon);
-        return icon;
-    }
-
-    private void fillFx(LinearLayout listFilters, int buttonId) {
-        ImageButton button = (ImageButton) findViewById(buttonId);
-
+    private void fillFx() {
         FilterFxRepresentation nullFx = new FilterFxRepresentation(getString(R.string.none), 0, R.string.none);
-        mNullFxFilter = setupFilterRepresentationButton(nullFx, listFilters, button);
-        mNullFxFilter.setSelected(true);
-
         Vector<FilterRepresentation> filtersRepresentations = new Vector<FilterRepresentation>();
         FiltersManager.getManager().addLooks(this, filtersRepresentations);
+
+        mCategoryLooksAdapter = new CategoryAdapter(this);
+        int verticalItemHeight = (int) getResources().getDimension(R.dimen.action_item_height);
+        mCategoryLooksAdapter.setItemHeight(verticalItemHeight);
+        mCategoryLooksAdapter.add(new Action(this, nullFx, Action.CROP_VIEW));
         for (FilterRepresentation representation : filtersRepresentations) {
-            setupFilterRepresentationButton(representation, listFilters, button);
+            mCategoryLooksAdapter.add(new Action(this, representation, Action.FULL_VIEW));
         }
-
     }
 
     public void setDefaultPreset() {
@@ -764,16 +730,18 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
     // //////////////////////////////////////////////////////////////////////////////
     // imageState panel...
 
-    private void toggleImageStatePanel() {
+    public void toggleImageStatePanel() {
         invalidateOptionsMenu();
-    }
-
-    private void loadImageStatePanel() {
-        StatePanel statePanel = new StatePanel();
-        if (findViewById(R.id.state_panel_container) != null) {
-            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
-            transaction.replace(R.id.state_panel_container, statePanel, mPanelFragmentTag);
-            transaction.commit();
+        mShowingImageStatePanel = !mShowingImageStatePanel;
+        Fragment panel = getSupportFragmentManager().findFragmentByTag(MainPanel.FRAGMENT_TAG);
+        if (panel != null) {
+            if (panel instanceof EditorPanel) {
+                EditorPanel editorPanel = (EditorPanel) panel;
+                editorPanel.showImageStatePanel(mShowingImageStatePanel);
+            } else if (panel instanceof MainPanel) {
+                MainPanel mainPanel = (MainPanel) panel;
+                mainPanel.showImageStatePanel(mShowingImageStatePanel);
+            }
         }
     }
 
@@ -783,20 +751,10 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
         super.onConfigurationChanged(newConfig);
         setDefaultValues();
         loadXML();
-        if (getResources().getConfiguration().orientation
-                == Configuration.ORIENTATION_LANDSCAPE) {
-            mShowingImageStatePanel = true;
-        } else if (mShowingImageStatePanel) {
-            toggleImageStatePanel();
-        }
-        if (mShowingImageStatePanel) {
-            loadImageStatePanel();
-        }
-        if (mShowingTinyPlanet == false) {
-            View tinyPlanetView = findViewById(EditorTinyPlanet.ID);
-            if (tinyPlanetView != null) {
-                tinyPlanetView.setVisibility(View.GONE);
-            }
+        loadMainPanel();
+
+        if (!mShowingTinyPlanet) {
+            mCategoryFiltersAdapter.removeTinyPlanet();
         }
         final View loading = findViewById(R.id.loading);
         loading.setVisibility(View.GONE);
@@ -824,27 +782,35 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
         }
     }
 
-    public void dispatchNullFilterClick() {
-        mNullFxFilter.onClick(mNullFxFilter);
-        mNullBorderFilter.onClick(mNullBorderFilter);
-    }
-
     void resetHistory() {
-        dispatchNullFilterClick();
         HistoryAdapter adapter = mMasterImage.getHistory();
         adapter.reset();
         ImagePreset original = new ImagePreset(adapter.getItem(0));
         mMasterImage.setPreset(original, true);
-        mPanelController.resetParameters();
         invalidateViews();
     }
 
+    public void showDefaultImageView() {
+        mEditorPlaceHolder.hide();
+        mImageShow.setVisibility(View.VISIBLE);
+        MasterImage.getImage().setCurrentFilter(null);
+        MasterImage.getImage().setCurrentFilterRepresentation(null);
+    }
+
+    public void backToMain() {
+        Fragment currentPanel = getSupportFragmentManager().findFragmentByTag(MainPanel.FRAGMENT_TAG);
+        if (currentPanel instanceof MainPanel) {
+            return;
+        }
+        loadMainPanel();
+        showDefaultImageView();
+    }
+
     @Override
     public void onBackPressed() {
-        if (mPanelController.onBackPressed()) {
-            if (detectSpecialExitCases()) {
-                saveImage();
-            } else if(!mImageShow.hasModifications()) {
+        Fragment currentPanel = getSupportFragmentManager().findFragmentByTag(MainPanel.FRAGMENT_TAG);
+        if (currentPanel instanceof MainPanel) {
+            if (!mImageShow.hasModifications()) {
                 done();
             } else {
                 AlertDialog.Builder builder = new AlertDialog.Builder(this);
@@ -861,13 +827,11 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
                 });
                 builder.show();
             }
+        } else {
+            backToMain();
         }
     }
 
-    public PanelController getPanelController() {
-        return mPanelController;
-    }
-
     public void cannotLoadImage() {
         CharSequence text = getString(R.string.cannot_load_image);
         Toast toast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
diff --git a/src/com/android/gallery3d/filtershow/ImageStateAdapter.java b/src/com/android/gallery3d/filtershow/ImageStateAdapter.java
deleted file mode 100644 (file)
index 62633e2..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.gallery3d.filtershow;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.filtershow.filters.FilterRepresentation;
-import com.android.gallery3d.filtershow.filters.ImageFilter;
-import com.android.gallery3d.filtershow.imageshow.MasterImage;
-
-public class ImageStateAdapter extends ArrayAdapter<FilterRepresentation> {
-    private static final String LOGTAG = "ImageStateAdapter";
-
-    public ImageStateAdapter(Context context, int textViewResourceId) {
-        super(context, textViewResourceId);
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        MovableLinearLayout view = (MovableLinearLayout) convertView;
-        if (view == null) {
-            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
-            view = (MovableLinearLayout) inflater.inflate(R.layout.filtershow_imagestate_row, null);
-        }
-        FilterRepresentation filter = getItem(position);
-        view.setFilterRepresentation(filter);
-        ImageView markView = (ImageView) view.findViewById(R.id.selectedMark);
-        if (filter == MasterImage.getImage().getCurrentFilterRepresentation()) {
-                markView.setVisibility(View.VISIBLE);
-        } else {
-            markView.setVisibility(View.INVISIBLE);
-        }
-        if (filter != null) {
-            TextView itemLabel = (TextView) view.findViewById(R.id.imagestate_label);
-            itemLabel.setText(filter.getName());
-            TextView itemParameter = (TextView) view.findViewById(R.id.imagestate_parameter);
-            itemParameter.setText(filter.getStateRepresentation());
-        }
-        return view;
-    }
-}
diff --git a/src/com/android/gallery3d/filtershow/MovableLinearLayout.java b/src/com/android/gallery3d/filtershow/MovableLinearLayout.java
deleted file mode 100644 (file)
index 9eddb41..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2013 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.gallery3d.filtershow;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.Point;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.widget.LinearLayout;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.filtershow.filters.FilterRepresentation;
-import com.android.gallery3d.filtershow.imageshow.MasterImage;
-
-public class MovableLinearLayout extends LinearLayout {
-
-    private Point mTouchDown = new Point();
-    private FilterRepresentation mFilterRepresentation;
-    private int mTouchSlope = 3;
-    private static final String LOGTAG = "MovableLinearLayout";
-
-    public MovableLinearLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    private void resetView() {
-        setTranslationX(0);
-        mTouchDown.x = 0;
-        mTouchDown.y = 0;
-        setAlpha(1.0f);
-        setBackgroundResource(R.drawable.filtershow_button_background);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        int ex = (int) event.getX();
-        int ey = (int) event.getY();
-        if (event.getAction() == MotionEvent.ACTION_DOWN) {
-            mTouchDown.x = ex;
-            mTouchDown.y = ey;
-            FilterShowActivity activity = (FilterShowActivity) getContext();
-            activity.getPanelController().showComponentWithRepresentation(mFilterRepresentation);
-        }
-        if (event.getAction() == MotionEvent.ACTION_MOVE) {
-            int delta = ex - mTouchDown.x;
-            if (delta > 0 && (delta - getTranslationX()) > mTouchSlope) {
-                setTranslationX(delta);
-                float alpha = (getWidth() - getTranslationX()) / getWidth();
-                int backgroundColor = Color.argb((int) (1.0f - alpha * 255), 255, 0, 0);
-                setBackgroundColor(backgroundColor);
-                setAlpha(alpha);
-            }
-        }
-        if (event.getAction() == MotionEvent.ACTION_UP
-                || event.getAction() == MotionEvent.ACTION_CANCEL) {
-            if (getTranslationX() > getWidth() / 4) {
-                delete(mFilterRepresentation);
-            } else {
-                resetView();
-            }
-        }
-        return true;
-    }
-
-    private void delete(FilterRepresentation filterRepresentation) {
-        FilterShowActivity activity = (FilterShowActivity) getContext();
-        activity.getPanelController().removeFilterRepresentation(filterRepresentation);
-    }
-
-    public void setFilterRepresentation(FilterRepresentation filterRepresentation) {
-        mFilterRepresentation = filterRepresentation;
-        resetView();
-    }
-
-}
diff --git a/src/com/android/gallery3d/filtershow/PanelController.java b/src/com/android/gallery3d/filtershow/PanelController.java
deleted file mode 100644 (file)
index 2cd70e3..0000000
+++ /dev/null
@@ -1,684 +0,0 @@
-/*
- * 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.gallery3d.filtershow;
-
-import android.content.Context;
-import android.os.Handler;
-import android.text.Html;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewPropertyAnimator;
-import android.widget.Button;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import android.util.Log;
-
-import com.android.gallery3d.R;
-import com.android.gallery3d.filtershow.editors.Editor;
-import com.android.gallery3d.filtershow.editors.EditorTinyPlanet;
-import com.android.gallery3d.filtershow.editors.ImageOnlyEditor;
-import com.android.gallery3d.filtershow.filters.FilterRepresentation;
-import com.android.gallery3d.filtershow.filters.ImageFilter;
-import com.android.gallery3d.filtershow.filters.ImageFilterTinyPlanet;
-import com.android.gallery3d.filtershow.imageshow.ImageShow;
-import com.android.gallery3d.filtershow.imageshow.MasterImage;
-import com.android.gallery3d.filtershow.presets.ImagePreset;
-import com.android.gallery3d.filtershow.ui.FilterIconButton;
-
-import java.util.HashMap;
-import java.util.Set;
-import java.util.Vector;
-
-public class PanelController implements OnClickListener {
-    private static int PANEL = 0;
-    private static int COMPONENT = 1;
-    private static int VERTICAL_MOVE = 0;
-    private static int HORIZONTAL_MOVE = 1;
-    private static final int ANIM_DURATION = 200;
-    private static final String LOGTAG = "PanelController";
-    private boolean mFixedAspect = false;
-
-    final Handler mHandler = new Handler();
-
-    public static boolean useAnimationsLayer() {
-        int currentapiVersion = android.os.Build.VERSION.SDK_INT;
-        if (currentapiVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
-            return true;
-        }
-        return false;
-    }
-
-    public void setFixedAspect(boolean t) {
-        mFixedAspect = t;
-    }
-
-    class Panel {
-        private final View mView;
-        private final View mContainer;
-        private int mPosition = 0;
-        private final Vector<View> mSubviews = new Vector<View>();
-
-        public Panel(View view, View container, int position) {
-            mView = view;
-            mContainer = container;
-            mPosition = position;
-        }
-
-        public void addView(View view) {
-            mSubviews.add(view);
-        }
-
-        public int getPosition() {
-            return mPosition;
-        }
-
-        public ViewPropertyAnimator unselect(int newPos, int move) {
-            ViewPropertyAnimator anim = mContainer.animate();
-            mView.setSelected(false);
-            mContainer.setX(0);
-            mContainer.setY(0);
-            int delta = 0;
-            int w = mRowPanel.getWidth();
-            int h = mRowPanel.getHeight();
-            if (move == HORIZONTAL_MOVE) {
-                if (newPos > mPosition) {
-                    delta = -w;
-                } else {
-                    delta = w;
-                }
-                anim.x(delta);
-            } else if (move == VERTICAL_MOVE) {
-                anim.y(h);
-            }
-            anim.setDuration(ANIM_DURATION);
-            Runnable action = new Runnable() {
-                @Override
-                public void run() {
-                    mContainer.setVisibility(View.GONE);
-                }
-            };
-            if (PanelController.useAnimationsLayer()) {
-                anim.withLayer().withEndAction(action);
-            } else {
-                mHandler.postDelayed(action, ANIM_DURATION);
-            }
-            return anim;
-        }
-
-        public ViewPropertyAnimator select(int oldPos, int move) {
-            mView.setSelected(true);
-            mContainer.setVisibility(View.VISIBLE);
-            mContainer.setX(0);
-            mContainer.setY(0);
-            ViewPropertyAnimator anim = mContainer.animate();
-            int w = mRowPanel.getWidth();
-            int h = mRowPanel.getHeight();
-            if (move == HORIZONTAL_MOVE) {
-                if (oldPos < mPosition) {
-                    mContainer.setX(w);
-                } else {
-                    mContainer.setX(-w);
-                }
-                anim.x(0);
-            } else if (move == VERTICAL_MOVE) {
-                mContainer.setY(h);
-                anim.y(0);
-            }
-            anim.setDuration(ANIM_DURATION);
-            if (PanelController.useAnimationsLayer()) {
-                anim.withLayer();
-            }
-            return anim;
-        }
-    }
-
-    class UtilityPanel {
-        private final Context mContext;
-        private final View mView;
-        private final LinearLayout mAccessoryViewList;
-        private Vector<View> mAccessoryViews = new Vector<View>();
-        private final Button mTextView;
-        private boolean mSelected = false;
-        private String mEffectName = null;
-        private int mParameterValue = 0;
-        private boolean mShowParameterValue = false;
-
-        public UtilityPanel(Context context, View utilityPanel) {
-            mView = utilityPanel;
-            View accessoryViewList = mView.findViewById(R.id.panelAccessoryViewList);
-            mTextView = (Button) mView.findViewById(R.id.applyEffect);
-            mContext = context;
-            mAccessoryViewList = (LinearLayout) accessoryViewList;
-        }
-
-        public boolean selected() {
-            return mSelected;
-        }
-
-        public void hideAccessoryViews() {
-            int childCount = mAccessoryViewList.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                View child = mAccessoryViewList.getChildAt(i);
-                child.setVisibility(View.GONE);
-            }
-        }
-
-        public void onNewValue(int value) {
-            mParameterValue = value;
-            updateText();
-        }
-
-        public void setEffectName(String effectName) {
-            mEffectName = effectName;
-            setShowParameter(true);
-        }
-
-        public void setShowParameter(boolean s) {
-            mShowParameterValue = s;
-            updateText();
-        }
-
-        public void showMenu(boolean show) {
-            mTextView.setOnClickListener(null);
-            if (show){
-                mAccessoryViewList.setVisibility(View.VISIBLE);
-                mTextView.setVisibility(View.VISIBLE);
-            } else {
-                mAccessoryViewList.setVisibility(View.VISIBLE);
-                mTextView.setVisibility(View.VISIBLE);
-            }
-
-        }
-
-        public View getActionControl() {
-            return mView.findViewById(R.id.panelAccessoryViewList);
-        }
-
-        public View getEditControl() {
-            return mView.findViewById(R.id.controlArea);
-        }
-
-        public void removeControlChildren() {
-            LinearLayout controlArea = (LinearLayout) mView.findViewById(R.id.controlArea);
-            controlArea.removeAllViews();
-        }
-
-        public Button getEditTitle() {
-            return mTextView;
-        }
-
-        public void updateText() {
-            String s;
-            if (mCurrentEditor == null) {
-                String apply = mContext.getString(R.string.apply_effect);
-                s = apply + " " + mEffectName + " " + mParameterValue;
-            } else {
-                s = mCurrentEditor.calculateUserMessage(mContext, mEffectName, mParameterValue);
-            }
-            mTextView.setText(Html.fromHtml(s));
-        }
-
-        public ViewPropertyAnimator unselect() {
-            ViewPropertyAnimator anim = mView.animate();
-            mView.setX(0);
-            mView.setY(0);
-            int h = mRowPanel.getHeight();
-            anim.y(-h);
-            Runnable action = new Runnable() {
-                @Override
-                public void run() {
-                    mView.setVisibility(View.GONE);
-                }
-            };
-            if (PanelController.useAnimationsLayer()) {
-                anim.setDuration(ANIM_DURATION).withLayer().withEndAction(action);
-            } else {
-                mHandler.postDelayed(action, ANIM_DURATION);
-            }
-            mSelected = false;
-            return anim;
-        }
-
-        public ViewPropertyAnimator select() {
-            mView.setVisibility(View.VISIBLE);
-            int h = mRowPanel.getHeight();
-            mView.setX(0);
-            mView.setY(-h);
-            updateText();
-            mSelected = true;
-            ViewPropertyAnimator anim = mView.animate();
-            anim.y(0);
-            anim.setDuration(ANIM_DURATION);
-            if (PanelController.useAnimationsLayer()) {
-                anim.withLayer();
-            }
-            return anim;
-        }
-
-    }
-
-    class ViewType {
-        private final int mType;
-        private final View mView;
-
-        public ViewType(View view, int type) {
-            mView = view;
-            mType = type;
-        }
-
-        public int type() {
-            return mType;
-        }
-    }
-
-    private final HashMap<View, Panel> mPanels = new HashMap<View, Panel>();
-    private final HashMap<View, ViewType> mViews = new HashMap<View, ViewType>();
-    private final HashMap<String, ImageFilter> mFilters = new HashMap<String, ImageFilter>();
-    private final Vector<View> mImageViews = new Vector<View>();
-    private View mCurrentPanel = null;
-    private View mRowPanel = null;
-    private UtilityPanel mUtilityPanel = null;
-    private ImageShow mCurrentImage = null;
-    private Editor mCurrentEditor = null;
-    private FilterShowActivity mActivity = null;
-    private EditorPlaceHolder mEditorPlaceHolder = null;
-
-    public void clear() {
-        mPanels.clear();
-        mViews.clear();
-        mFilters.clear();
-        mImageViews.clear();
-    }
-
-    public void setActivity(FilterShowActivity activity) {
-        mActivity = activity;
-    }
-
-    public void addView(View view) {
-        view.setOnClickListener(this);
-        mViews.put(view, new ViewType(view, COMPONENT));
-    }
-
-    public View getViewFromId(int viewId) {
-        for (View view : mPanels.keySet()) {
-            if (view.getId() == viewId) {
-                return view;
-            }
-        }
-        return null;
-    }
-
-    public void addPanel(int viewId, int containerId, int position) {
-        View view = mActivity.findViewById(viewId);
-        View container = mActivity.findViewById(containerId);
-        mPanels.put(view, new Panel(view, container, position));
-        view.setOnClickListener(this);
-        mViews.put(view, new ViewType(view, PANEL));
-    }
-
-    public void addComponent(View aPanel, View component) {
-        Panel panel = mPanels.get(aPanel);
-        if (panel == null) {
-            return;
-        }
-        panel.addView(component);
-        component.setOnClickListener(this);
-        mViews.put(component, new ViewType(component, COMPONENT));
-    }
-
-    public void addFilter(ImageFilter filter) {
-        mFilters.put(filter.getName(), filter);
-    }
-
-    public void addImageView(View view) {
-        mImageViews.add(view);
-        ImageShow imageShow = (ImageShow) view;
-        imageShow.setPanelController(this);
-    }
-
-    public void resetParameters() {
-        showPanel(mCurrentPanel);
-        if (mCurrentImage != null) {
-            mCurrentImage.resetParameter();
-            mCurrentImage.select();
-            if (mCurrentEditor != null) {
-                mCurrentEditor.reflectCurrentFilter();
-            }
-        }
-    }
-
-    public boolean onBackPressed() {
-        if (mUtilityPanel == null || !mUtilityPanel.selected()) {
-            return true;
-        }
-        HistoryAdapter adapter = MasterImage.getImage().getHistory();
-        int position = adapter.undo();
-        MasterImage.getImage().onHistoryItemClick(position);
-        mActivity.showCategoryPanel();
-        showPanel(mCurrentPanel);
-        mCurrentImage.select();
-        if (mCurrentEditor != null) {
-            mCurrentEditor.reflectCurrentFilter();
-        }
-        return false;
-    }
-
-    public void onNewValue(int value) {
-        mUtilityPanel.onNewValue(value);
-    }
-
-    public void showParameter(boolean s) {
-        mUtilityPanel.setShowParameter(s);
-    }
-
-    public void setCurrentPanel(int panelId) {
-        showPanel(getViewFromId(panelId));
-    }
-
-    public void setRowPanel(View rowPanel) {
-        mRowPanel = rowPanel;
-    }
-
-    public void setUtilityPanel(Context context, View utilityPanel) {
-        addView(utilityPanel.findViewById(R.id.applyEffect));
-        addView(utilityPanel.findViewById(R.id.applyFilter));
-        // TODO rename applyFilter to panelFilterDescription
-        addView(utilityPanel.findViewById(R.id.cancelFilter));
-        mUtilityPanel = new UtilityPanel(context, utilityPanel);
-    }
-
-    @Override
-    public void onClick(View view) {
-        ViewType type = mViews.get(view);
-        if (type.type() == PANEL) {
-            showPanel(view);
-        } else if (type.type() == COMPONENT) {
-            showComponent(view);
-        }
-    }
-
-    public ImageShow showImageView(int id) {
-        ImageShow image = null;
-        mActivity.hideImageViews();
-        for (View view : mImageViews) {
-            image = (ImageShow) view;
-            if (view.getId() == id) {
-                view.setVisibility(View.VISIBLE);
-                image.select();
-            } else {
-                view.setVisibility(View.GONE);
-                image.unselect();
-            }
-        }
-        return image;
-    }
-
-    public void showDefaultImageView() {
-        showImageView(R.id.imageShow);
-        MasterImage.getImage().setCurrentFilter(null);
-        MasterImage.getImage().setCurrentFilterRepresentation(null);
-    }
-
-    public void showPanel(View view) {
-        view.setVisibility(View.VISIBLE);
-        boolean removedUtilityPanel = false;
-        Panel current = mPanels.get(mCurrentPanel);
-        if (mUtilityPanel != null && mUtilityPanel.selected()) {
-            ViewPropertyAnimator anim1 = mUtilityPanel.unselect();
-            removedUtilityPanel = true;
-            if (anim1 != null) {
-                anim1.start();
-            }
-            if (mCurrentPanel == view) {
-                ViewPropertyAnimator anim2 = current.select(-1, VERTICAL_MOVE);
-                if (anim2 != null) {
-                    anim2.start();
-                }
-                showDefaultImageView();
-            }
-        }
-
-        if (mCurrentPanel == view) {
-            return;
-        }
-
-        Panel panel = mPanels.get(view);
-        if (!removedUtilityPanel) {
-            int currentPos = -1;
-            if (current != null) {
-                currentPos = current.getPosition();
-            }
-            ViewPropertyAnimator anim1 = panel.select(currentPos, HORIZONTAL_MOVE);
-            if (anim1 != null) {
-                anim1.start();
-            }
-            if (current != null) {
-                ViewPropertyAnimator anim2 = current.unselect(panel.getPosition(), HORIZONTAL_MOVE);
-                if (anim2 != null) {
-                    anim2.start();
-                }
-            }
-        } else {
-            ViewPropertyAnimator anim = panel.select(-1, VERTICAL_MOVE);
-            if (anim != null) {
-                anim.start();
-            }
-        }
-
-        showDefaultImageView();
-        mCurrentPanel = view;
-    }
-
-    public ImagePreset getImagePreset() {
-        return MasterImage.getImage().getPreset();
-    }
-
-    public void setEffectName(String ename) {
-        mUtilityPanel.setEffectName(ename);
-    }
-
-    public void removeFilterRepresentation(FilterRepresentation filterRepresentation) {
-        if (filterRepresentation == null) {
-            Log.v(LOGTAG, "RemoveFilterRepresentation: " + filterRepresentation);
-            return;
-        }
-        ImagePreset oldPreset = MasterImage.getImage().getPreset();
-        ImagePreset copy = new ImagePreset(oldPreset);
-        copy.removeFilter(filterRepresentation);
-        MasterImage.getImage().setPreset(copy, true);
-        if (MasterImage.getImage().getCurrentFilterRepresentation() == filterRepresentation) {
-            FilterRepresentation lastRepresentation = copy.getLastRepresentation();
-            MasterImage.getImage().setCurrentFilterRepresentation(lastRepresentation);
-        }
-        // Now let's reset the panel
-        if (mUtilityPanel == null || !mUtilityPanel.selected()) {
-            return;
-        }
-        showPanel(mCurrentPanel);
-        mCurrentImage.select();
-        if (mCurrentEditor != null) {
-            mCurrentEditor.reflectCurrentFilter();
-        }
-    }
-
-    public void useFilterRepresentation(FilterRepresentation filterRepresentation) {
-        if (filterRepresentation == null) {
-            return;
-        }
-        if (MasterImage.getImage().getCurrentFilterRepresentation() == filterRepresentation) {
-            return;
-        }
-        ImagePreset oldPreset = MasterImage.getImage().getPreset();
-        ImagePreset copy = new ImagePreset(oldPreset);
-        FilterRepresentation representation = copy.getRepresentation(filterRepresentation);
-        if (representation == null) {
-            copy.addFilter(filterRepresentation);
-        } else {
-            if (filterRepresentation.allowsMultipleInstances()) {
-                representation.updateTempParametersFrom(filterRepresentation);
-                copy.setHistoryName(filterRepresentation.getName());
-                representation.synchronizeRepresentation();
-            }
-            filterRepresentation = representation;
-        }
-        MasterImage.getImage().setPreset(copy, true);
-        MasterImage.getImage().setCurrentFilterRepresentation(filterRepresentation);
-    }
-
-    public void showComponentWithRepresentation(FilterRepresentation filterRepresentation) {
-        if (filterRepresentation == null) {
-            return;
-        }
-        if (filterRepresentation == MasterImage.getImage().getCurrentFilterRepresentation()) {
-            return;
-        }
-        Set<View> views = mViews.keySet();
-        for (View view : views) {
-            if (view instanceof FilterIconButton) {
-                FilterIconButton button = (FilterIconButton) view;
-                if (button.getFilterRepresentation().getFilterClass() == filterRepresentation.getFilterClass()) {
-                    MasterImage.getImage().setCurrentFilterRepresentation(filterRepresentation);
-                    showComponent(view);
-                    return;
-                }
-            }
-        }
-    }
-
-    public void showComponent(View view) {
-
-        boolean doPanelTransition = true;
-        if (view instanceof FilterIconButton) {
-            FilterRepresentation f = ((FilterIconButton) view).getFilterRepresentation();
-            if (f != null) {
-                // FIXME: this check shouldn't be necessary (f shouldn't be null)
-                doPanelTransition = f.showUtilityPanel();
-            }
-        }
-
-        if (mUtilityPanel != null && !mUtilityPanel.selected() && doPanelTransition) {
-            Panel current = mPanels.get(mCurrentPanel);
-            ViewPropertyAnimator anim1 = current.unselect(-1, VERTICAL_MOVE);
-            if (anim1 != null) {
-                anim1.start();
-            }
-            if (mUtilityPanel != null) {
-                ViewPropertyAnimator anim2 = mUtilityPanel.select();
-                if (anim2 != null) {
-                    anim2.start();
-                }
-            }
-        }
-
-        if (mCurrentImage != null) {
-            mCurrentImage.unselect();
-        }
-        mUtilityPanel.hideAccessoryViews();
-        mUtilityPanel.showMenu(false);
-
-        if (view instanceof FilterIconButton) {
-            if (mCurrentEditor != null) {
-                mCurrentEditor.detach();
-            }
-            mCurrentEditor = null;
-            FilterIconButton component = (FilterIconButton) view;
-            FilterRepresentation representation = component.getFilterRepresentation();
-
-            if (representation != null) {
-                mUtilityPanel.setEffectName(representation.getName());
-                mUtilityPanel.setShowParameter(representation.showParameterValue());
-
-                if (representation.getEditorId() != 0) {
-                    if (representation.getEditorId() != ImageOnlyEditor.ID) {
-                        mActivity.hideCategoryPanel();
-                    }
-                    if (mEditorPlaceHolder.contains(representation.getEditorId())) {
-                        mCurrentEditor = mEditorPlaceHolder.showEditor(
-                                representation.getEditorId());
-                        mUtilityPanel.removeControlChildren();
-                        mCurrentEditor.setUpEditorUI(
-                                mUtilityPanel.getActionControl(), mUtilityPanel.getEditControl(),
-                                mUtilityPanel.getEditTitle());
-                        mCurrentImage = mCurrentEditor.getImageShow();
-                        mCurrentEditor.setPanelController(this);
-
-                    } else {
-                        mCurrentImage = showImageView(representation.getEditorId());
-                    }
-                }
-                mUtilityPanel.setShowParameter(representation.showParameterValue());
-
-                mCurrentImage.select();
-                if (mCurrentEditor != null) {
-                    mCurrentEditor.reflectCurrentFilter();
-                    if (mCurrentEditor.useUtilityPanel()) {
-                        mUtilityPanel.showMenu(true);
-                        mCurrentEditor.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
-                    }
-                } else if (mCurrentImage.useUtilityPanel()) {
-                    mCurrentImage.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
-                }
-            }
-            return;
-        }
-
-        mActivity.showCategoryPanel();
-        int id = view.getId();
-        if (id == EditorTinyPlanet.ID) {
-            mCurrentImage = showImageView(R.id.imageTinyPlanet);
-            String ename = mCurrentImage.getContext().getString(R.string.tinyplanet);
-            mUtilityPanel.setEffectName(ename);
-
-        } else {
-            if (id == R.id.cancelFilter) {
-                cancelCurrentFilter();
-            } else if (id == R.id.applyEffect || id == R.id.applyFilter) {
-                if (MasterImage.getImage().getCurrentFilter() instanceof ImageFilterTinyPlanet) {
-                    mActivity.saveImage();
-                } else {
-                    showPanel(mCurrentPanel);
-                }
-                MasterImage.getImage().invalidateFiltersOnly();
-
-            }
-        }
-        mCurrentImage.select();
-        if (mCurrentEditor != null) {
-            mCurrentEditor.reflectCurrentFilter();
-            if (mCurrentEditor.useUtilityPanel()) {
-                mCurrentEditor.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
-            }
-        } else if (mCurrentImage.useUtilityPanel()) {
-            mCurrentImage.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
-        }
-    }
-
-    public void cancelCurrentFilter() {
-        resetParameters();
-        MasterImage masterImage = MasterImage.getImage();
-        HistoryAdapter adapter = masterImage.getHistory();
-
-        int position = adapter.undo();
-        masterImage.onHistoryItemClick(position);
-        mActivity.invalidateViews();
-    }
-
-    public void setEditorPlaceHolder(EditorPlaceHolder editorPlaceHolder) {
-        mEditorPlaceHolder = editorPlaceHolder;
-    }
-}
diff --git a/src/com/android/gallery3d/filtershow/category/Action.java b/src/com/android/gallery3d/filtershow/category/Action.java
new file mode 100644 (file)
index 0000000..667a897
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2013 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.gallery3d.filtershow.category;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import com.android.gallery3d.filtershow.cache.RenderingRequest;
+import com.android.gallery3d.filtershow.cache.RenderingRequestCaller;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+import com.android.gallery3d.filtershow.imageshow.MasterImage;
+import com.android.gallery3d.filtershow.presets.ImagePreset;
+
+public class Action implements RenderingRequestCaller {
+
+    private static final String LOGTAG = "Action";
+    private FilterRepresentation mRepresentation;
+    private String mName;
+    private Rect mImageFrame;
+    private Bitmap mImage;
+    private CategoryAdapter mAdapter;
+    public static final int FULL_VIEW = 0;
+    public static final int CROP_VIEW = 1;
+    private int mType = CROP_VIEW;
+    private Bitmap mPortraitImage;
+    private Bitmap mOverlayBitmap;
+    private Context mContext;
+
+    public Action(Context context, FilterRepresentation representation, int type) {
+        mContext = context;
+        setRepresentation(representation);
+        setType(type);
+    }
+
+    public Action(Context context, FilterRepresentation representation) {
+        this(context, representation, CROP_VIEW);
+    }
+
+    public FilterRepresentation getRepresentation() {
+        return mRepresentation;
+    }
+
+    public void setRepresentation(FilterRepresentation representation) {
+        mRepresentation = representation;
+        mName = representation.getName();
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public void setName(String name) {
+        mName = name;
+    }
+
+    public void setImageFrame(Rect imageFrame) {
+        if (mImageFrame != null && mImageFrame.equals(imageFrame)) {
+            return;
+        }
+        Bitmap bitmap = MasterImage.getImage().getLargeThumbnailBitmap();
+        if (bitmap != null) {
+            mImageFrame = imageFrame;
+            int w = mImageFrame.width();
+            int h = mImageFrame.height();
+            if (mType == CROP_VIEW) {
+                w /= 2;
+            }
+            Bitmap bitmapCrop = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+            drawCenteredImage(bitmap, bitmapCrop, true);
+
+            postNewIconRenderRequest(bitmapCrop);
+        }
+    }
+
+    public Bitmap getImage() {
+        return mImage;
+    }
+
+    public void setImage(Bitmap image) {
+        mImage = image;
+    }
+
+    public void setAdapter(CategoryAdapter adapter) {
+        mAdapter = adapter;
+    }
+
+    public void setType(int type) {
+        mType = type;
+    }
+
+    private void postNewIconRenderRequest(Bitmap bitmap) {
+        if (bitmap != null && mRepresentation != null) {
+            ImagePreset preset = new ImagePreset();
+            preset.addFilter(mRepresentation);
+            RenderingRequest.post(bitmap,
+                    preset, RenderingRequest.ICON_RENDERING, this);
+        }
+    }
+
+    private void drawCenteredImage(Bitmap source, Bitmap destination, boolean scale) {
+        RectF image = new RectF(0, 0, source.getWidth(), source.getHeight());
+        int border = 0;
+        if (!scale) {
+            border = destination.getWidth() - destination.getHeight();
+            if (border < 0) {
+                border = 0;
+            }
+        }
+        RectF frame = new RectF(border, 0,
+                destination.getWidth() - border,
+                destination.getHeight());
+        Matrix m = new Matrix();
+        m.setRectToRect(frame, image, Matrix.ScaleToFit.CENTER);
+        image.set(frame);
+        m.mapRect(image);
+        m.setRectToRect(image, frame, Matrix.ScaleToFit.FILL);
+        Canvas canvas = new Canvas(destination);
+        canvas.drawBitmap(source, m, new Paint());
+    }
+
+    @Override
+    public void available(RenderingRequest request) {
+        mImage = request.getBitmap();
+        if (mImage == null) {
+            return;
+        }
+        if (mRepresentation.getOverlayId() != 0 && mOverlayBitmap == null) {
+            mOverlayBitmap = BitmapFactory.decodeResource(
+                    mContext.getResources(),
+                    mRepresentation.getOverlayId());
+        }
+        if (mOverlayBitmap != null) {
+            drawCenteredImage(mOverlayBitmap, mImage, false);
+        }
+        if (mAdapter != null) {
+            mAdapter.notifyDataSetChanged();
+        }
+    }
+
+    public void setPortraitImage(Bitmap portraitImage) {
+        mPortraitImage = portraitImage;
+    }
+
+    public Bitmap getPortraitImage() {
+        return mPortraitImage;
+    }
+
+    public Bitmap getOverlayBitmap() {
+        return mOverlayBitmap;
+    }
+
+    public void setOverlayBitmap(Bitmap overlayBitmap) {
+        mOverlayBitmap = overlayBitmap;
+    }
+}
diff --git a/src/com/android/gallery3d/filtershow/category/CategoryAdapter.java b/src/com/android/gallery3d/filtershow/category/CategoryAdapter.java
new file mode 100644 (file)
index 0000000..e310b2f
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2013 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.gallery3d.filtershow.category;
+
+import android.content.Context;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+import com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation;
+import com.android.gallery3d.filtershow.filters.ImageFilter;
+import com.android.gallery3d.filtershow.filters.ImageFilterTinyPlanet;
+import com.android.gallery3d.filtershow.ui.FilterIconButton;
+
+public class CategoryAdapter extends ArrayAdapter<Action> {
+
+    private static final String LOGTAG = "CategoryAdapter";
+    private int mItemHeight = 200;
+    private ListView mContainer;
+    private int mItemWidth = ListView.LayoutParams.MATCH_PARENT;
+    private boolean mUseFilterIconButton = false;
+
+    public CategoryAdapter(Context context, int textViewResourceId) {
+        super(context, textViewResourceId);
+    }
+
+    public CategoryAdapter(Context context) {
+        this(context, 0);
+    }
+
+    public void setItemHeight(int height) {
+        mItemHeight = height;
+    }
+
+    public void setItemWidth(int width) {
+        mItemWidth = width;
+    }
+
+    @Override
+    public void add(Action action) {
+        super.add(action);
+        action.setAdapter(this);
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (mUseFilterIconButton) {
+            if (convertView == null) {
+                LayoutInflater inflater =
+                        (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+                convertView = inflater.inflate(R.layout.filtericonbutton, parent, false);
+            }
+            FilterIconButton view = (FilterIconButton) convertView;
+            Action action = getItem(position);
+            view.setAction(action);
+            view.setup(action.getName(), null);
+            view.setLayoutParams(
+                    new ListView.LayoutParams(mItemWidth, mItemHeight));
+            return view;
+        }
+        if (convertView == null) {
+            convertView = new CategoryView(getContext());
+        }
+        CategoryView view = (CategoryView) convertView;
+        view.setAction(getItem(position));
+        view.setLayoutParams(
+                new ListView.LayoutParams(mItemWidth, mItemHeight));
+        return view;
+    }
+
+    public void setContainer(ListView container) {
+        mContainer = container;
+    }
+
+    public ListView getContainer() {
+        return mContainer;
+    }
+
+    public void imageLoaded() {
+        notifyDataSetChanged();
+    }
+
+    public void setUseFilterIconButton(boolean useFilterIconButton) {
+        mUseFilterIconButton = useFilterIconButton;
+    }
+
+    public boolean isUseFilterIconButton() {
+        return mUseFilterIconButton;
+    }
+
+    public FilterRepresentation getTinyPlanet() {
+        for (int i = 0; i < getCount(); i++) {
+            Action action = getItem(i);
+            if (action.getRepresentation() != null
+                    && action.getRepresentation().getFilterClass()
+                    == ImageFilterTinyPlanet.class) {
+                return action.getRepresentation();
+            }
+        }
+        return null;
+    }
+
+    public void removeTinyPlanet() {
+        for (int i = 0; i < getCount(); i++) {
+            Action action = getItem(i);
+            if (action.getRepresentation() != null
+                    && action.getRepresentation().getFilterClass()
+                    == ImageFilterTinyPlanet.class) {
+                remove(action);
+                return;
+            }
+        }
+    }
+}
diff --git a/src/com/android/gallery3d/filtershow/category/CategoryPanel.java b/src/com/android/gallery3d/filtershow/category/CategoryPanel.java
new file mode 100644 (file)
index 0000000..9ddfcab
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013 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.gallery3d.filtershow.category;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.FilterShowActivity;
+
+public class CategoryPanel extends Fragment {
+
+    public static final String FRAGMENT_TAG = "CategoryPanel";
+    private static final String PARAMETER_TAG = "currentPanel";
+
+    private int mCurrentAdapter = MainPanel.LOOKS;
+    private CategoryAdapter mAdapter;
+
+    public void setAdapter(int value) {
+        mCurrentAdapter = value;
+    }
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        loadAdapter(mCurrentAdapter);
+    }
+
+    private void loadAdapter(int adapter) {
+        FilterShowActivity activity = (FilterShowActivity) getActivity();
+        switch (adapter) {
+            case MainPanel.LOOKS: {
+                mAdapter = activity.getCategoryLooksAdapter();
+                break;
+            }
+            case MainPanel.BORDERS: {
+                mAdapter = activity.getCategoryBordersAdapter();
+                break;
+            }
+            case MainPanel.GEOMETRY: {
+                mAdapter = activity.getCategoryGeometryAdapter();
+                break;
+            }
+            case MainPanel.FILTERS: {
+                mAdapter = activity.getCategoryFiltersAdapter();
+                break;
+            }
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle state) {
+        super.onSaveInstanceState(state);
+        state.putInt(PARAMETER_TAG, mCurrentAdapter);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        LinearLayout main = (LinearLayout) inflater.inflate(
+                R.layout.filtershow_category_panel_new, container,
+                false);
+
+        if (savedInstanceState != null) {
+            int selectedPanel = savedInstanceState.getInt(PARAMETER_TAG);
+            loadAdapter(selectedPanel);
+        }
+
+        View panelView = main.findViewById(R.id.listItems);
+        if (panelView instanceof CategoryTrack) {
+            CategoryTrack panel = (CategoryTrack) panelView;
+            mAdapter.setUseFilterIconButton(true);
+            panel.setAdapter(mAdapter);
+        } else {
+            ListView panel = (ListView) main.findViewById(R.id.listItems);
+            panel.setAdapter(mAdapter);
+            mAdapter.setContainer(panel);
+        }
+        return main;
+    }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/category/CategoryTrack.java b/src/com/android/gallery3d/filtershow/category/CategoryTrack.java
new file mode 100644 (file)
index 0000000..e0a8a2f
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2013 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.gallery3d.filtershow.category;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import com.android.gallery3d.R;
+
+public class CategoryTrack extends LinearLayout {
+
+    private CategoryAdapter mAdapter;
+    private int mElemSize;
+
+    public CategoryTrack(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CategoryTrack);
+        mElemSize = a.getDimensionPixelSize(R.styleable.CategoryTrack_iconSize, 0);
+    }
+
+    public void setAdapter(CategoryAdapter adapter) {
+        mAdapter = adapter;
+        mAdapter.setItemWidth(mElemSize);
+        mAdapter.setItemHeight(LayoutParams.MATCH_PARENT);
+        fillContent();
+    }
+
+    public void fillContent() {
+        removeAllViews();
+        int n = mAdapter.getCount();
+        for (int i = 0; i < n; i++) {
+            View view = mAdapter.getView(i, null, this);
+            addView(view, i);
+        }
+        requestLayout();
+    }
+
+}
diff --git a/src/com/android/gallery3d/filtershow/category/CategoryView.java b/src/com/android/gallery3d/filtershow/category/CategoryView.java
new file mode 100644 (file)
index 0000000..5467841
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2013 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.gallery3d.filtershow.category;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.util.Log;
+import android.view.View;
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.FilterShowActivity;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+
+public class CategoryView extends View implements View.OnClickListener {
+
+    private static final String LOGTAG = "CategoryView";
+    private Paint mPaint = new Paint();
+    private Action mAction;
+    private Rect mTextBounds = new Rect();
+    private static int sMargin = 16;
+    private static int sTextSize = 32;
+    private int mTextColor;
+    private int mBackgroundColor;
+
+    public static void setTextSize(int size) {
+        sTextSize = size;
+    }
+
+    public static void setMargin(int margin) {
+        sMargin = margin;
+    }
+
+    public CategoryView(Context context) {
+        super(context);
+        setOnClickListener(this);
+        Resources res = getResources();
+        mBackgroundColor = res.getColor(R.color.filtershow_categoryview_background);
+        mTextColor = res.getColor(R.color.filtershow_categoryview_text);
+    }
+
+    public void drawText(Canvas canvas, String text) {
+        if (text == null) {
+            return;
+        }
+        text = text.toUpperCase();
+        mPaint.reset();
+        mPaint.setColor(mTextColor);
+        mPaint.setTextSize(sTextSize);
+        mPaint.setTypeface(Typeface.DEFAULT_BOLD);
+        mPaint.setAntiAlias(true);
+        float textWidth = mPaint.measureText(text);
+        mPaint.getTextBounds(text, 0, text.length(), mTextBounds);
+        int x = (int) (canvas.getWidth() - textWidth - sMargin);
+        int y = canvas.getHeight() - sMargin;
+        canvas.drawText(text, x, y, mPaint);
+    }
+
+    public void onDraw(Canvas canvas) {
+        canvas.drawColor(mBackgroundColor);
+        if (mAction != null) {
+            drawText(canvas, mAction.getName());
+            if (mAction.getImage() == null) {
+                mAction.setImageFrame(new Rect(0, 0, canvas.getWidth(), canvas.getHeight()));
+            } else {
+                Bitmap bitmap = mAction.getImage();
+                canvas.drawBitmap(bitmap, 0, 0, mPaint);
+            }
+        }
+    }
+
+    public void setAction(Action action) {
+        mAction = action;
+        invalidate();
+    }
+
+    public FilterRepresentation getRepresentation() {
+        return mAction.getRepresentation();
+    }
+
+    @Override
+    public void onClick(View view) {
+        FilterShowActivity activity = (FilterShowActivity) getContext();
+        activity.showRepresentation(mAction.getRepresentation());
+    }
+}
diff --git a/src/com/android/gallery3d/filtershow/category/MainPanel.java b/src/com/android/gallery3d/filtershow/category/MainPanel.java
new file mode 100644 (file)
index 0000000..7cadbc3
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2013 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.gallery3d.filtershow.category;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.FilterShowActivity;
+import com.android.gallery3d.filtershow.state.StatePanel;
+
+public class MainPanel extends Fragment {
+
+    private static final String LOGTAG = "MainPanel";
+
+    private LinearLayout mMainView;
+    private ImageButton looksButton;
+    private ImageButton bordersButton;
+    private ImageButton geometryButton;
+    private ImageButton filtersButton;
+
+    public static final String FRAGMENT_TAG = "MainPanel";
+    public static final int LOOKS = 0;
+    public static final int BORDERS = 1;
+    public static final int GEOMETRY = 2;
+    public static final int FILTERS = 3;
+
+    private int mCurrentSelected = -1;
+
+    private void selection(int position, boolean value) {
+        if (value) {
+            FilterShowActivity activity = (FilterShowActivity) getActivity();
+            activity.setCurrentPanel(position);
+        }
+        switch (position) {
+            case LOOKS: {
+                looksButton.setSelected(value);
+                break;
+            }
+            case BORDERS: {
+                bordersButton.setSelected(value);
+                break;
+            }
+            case GEOMETRY: {
+                geometryButton.setSelected(value);
+                break;
+            }
+            case FILTERS: {
+                filtersButton.setSelected(value);
+                break;
+            }
+        }
+    }
+
+    @Override
+    public void onDestroyView() {
+        super.onDestroyView();
+        if (mMainView != null) {
+            if (mMainView.getParent() != null) {
+                ViewGroup parent = (ViewGroup) mMainView.getParent();
+                parent.removeView(mMainView);
+            }
+        }
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+
+        mMainView = (LinearLayout) inflater.inflate(
+                R.layout.filtershow_main_panel, null, false);
+
+        looksButton = (ImageButton) mMainView.findViewById(R.id.fxButton);
+        bordersButton = (ImageButton) mMainView.findViewById(R.id.borderButton);
+        geometryButton = (ImageButton) mMainView.findViewById(R.id.geometryButton);
+        filtersButton = (ImageButton) mMainView.findViewById(R.id.colorsButton);
+
+        looksButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showPanel(LOOKS);
+            }
+        });
+        bordersButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showPanel(BORDERS);
+            }
+        });
+        geometryButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showPanel(GEOMETRY);
+            }
+        });
+        filtersButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showPanel(FILTERS);
+            }
+        });
+
+        FilterShowActivity activity = (FilterShowActivity) getActivity();
+        showImageStatePanel(activity.isShowingImageStatePanel());
+        showPanel(activity.getCurrentPanel());
+        return mMainView;
+    }
+
+    private boolean isRightAnimation(int newPos) {
+        if (newPos < mCurrentSelected) {
+            return false;
+        }
+        return true;
+    }
+
+    private void setCategoryFragment(CategoryPanel category, boolean fromRight) {
+        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
+        if (fromRight) {
+            transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_right);
+        } else {
+            transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_left);
+        }
+        transaction.replace(R.id.category_panel_container, category, CategoryPanel.FRAGMENT_TAG);
+        transaction.commit();
+    }
+
+    public void loadCategoryLookPanel() {
+        if (mCurrentSelected == LOOKS) {
+            return;
+        }
+        boolean fromRight = isRightAnimation(LOOKS);
+        selection(mCurrentSelected, false);
+        CategoryPanel categoryPanel = new CategoryPanel();
+        categoryPanel.setAdapter(LOOKS);
+        setCategoryFragment(categoryPanel, fromRight);
+        mCurrentSelected = LOOKS;
+        selection(mCurrentSelected, true);
+    }
+
+    public void loadCategoryBorderPanel() {
+        if (mCurrentSelected == BORDERS) {
+            return;
+        }
+        boolean fromRight = isRightAnimation(BORDERS);
+        selection(mCurrentSelected, false);
+        CategoryPanel categoryPanel = new CategoryPanel();
+        categoryPanel.setAdapter(BORDERS);
+        setCategoryFragment(categoryPanel, fromRight);
+        mCurrentSelected = BORDERS;
+        selection(mCurrentSelected, true);
+    }
+
+    public void loadCategoryGeometryPanel() {
+        if (mCurrentSelected == GEOMETRY) {
+            return;
+        }
+        boolean fromRight = isRightAnimation(GEOMETRY);
+        selection(mCurrentSelected, false);
+        CategoryPanel categoryPanel = new CategoryPanel();
+        categoryPanel.setAdapter(GEOMETRY);
+        setCategoryFragment(categoryPanel, fromRight);
+        mCurrentSelected = GEOMETRY;
+        selection(mCurrentSelected, true);
+    }
+
+    public void loadCategoryFiltersPanel() {
+        if (mCurrentSelected == FILTERS) {
+            return;
+        }
+        boolean fromRight = isRightAnimation(FILTERS);
+        selection(mCurrentSelected, false);
+        CategoryPanel categoryPanel = new CategoryPanel();
+        categoryPanel.setAdapter(FILTERS);
+        setCategoryFragment(categoryPanel, fromRight);
+        mCurrentSelected = FILTERS;
+        selection(mCurrentSelected, true);
+    }
+
+    public void showPanel(int currentPanel) {
+        switch (currentPanel) {
+            case LOOKS: {
+                loadCategoryLookPanel();
+                break;
+            }
+            case BORDERS: {
+                loadCategoryBorderPanel();
+                break;
+            }
+            case GEOMETRY: {
+                loadCategoryGeometryPanel();
+                break;
+            }
+            case FILTERS: {
+                loadCategoryFiltersPanel();
+                break;
+            }
+        }
+    }
+
+    public void showImageStatePanel(boolean show) {
+        if (mMainView.findViewById(R.id.state_panel_container) == null) {
+            return;
+        }
+        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
+        final View container = mMainView.findViewById(R.id.state_panel_container);
+        if (show) {
+            container.setVisibility(View.VISIBLE);
+            StatePanel statePanel = new StatePanel();
+            transaction.replace(R.id.state_panel_container, statePanel, StatePanel.FRAGMENT_TAG);
+        } else {
+            container.setVisibility(View.GONE);
+            Fragment statePanel = getChildFragmentManager().findFragmentByTag(StatePanel.FRAGMENT_TAG);
+            if (statePanel != null) {
+                transaction.remove(statePanel);
+            }
+        }
+        transaction.commit();
+    }
+}
index 987b499..44296e2 100644 (file)
@@ -51,9 +51,6 @@ public class BasicEditor extends ParametricEditor implements ParameterInteger {
         super.reflectCurrentFilter();
         if (getLocalRepresentation() != null && getLocalRepresentation() instanceof FilterBasicRepresentation) {
             FilterBasicRepresentation interval = (FilterBasicRepresentation) getLocalRepresentation();
-            Context context = mContext;
-            interval.getTextId();
-
         }
     }
 
index dc13b3e..b543750 100644 (file)
@@ -32,7 +32,6 @@ import android.widget.SeekBar;
 import android.widget.SeekBar.OnSeekBarChangeListener;
 
 import com.android.gallery3d.R;
-import com.android.gallery3d.filtershow.PanelController;
 import com.android.gallery3d.filtershow.cache.ImageLoader;
 import com.android.gallery3d.filtershow.controller.Control;
 import com.android.gallery3d.filtershow.filters.FilterRepresentation;
@@ -50,19 +49,16 @@ public class Editor implements OnSeekBarChangeListener, SwapButton.SwapButtonLis
     protected FrameLayout mFrameLayout;
     protected SeekBar mSeekBar;
     Button mEditTitle;
-    protected PanelController mPanelController;
+    protected Button mFilterTitle;
     protected int mID;
     private final String LOGTAG = "Editor";
     protected FilterRepresentation mLocalRepresentation = null;
     protected byte mShowParameter = SHOW_VALUE_UNDEFINED;
+    private Button mButton;
     public static byte SHOW_VALUE_UNDEFINED = -1;
     public static byte SHOW_VALUE_OFF = 0;
     public static byte SHOW_VALUE_INT = 1;
 
-    public void setPanelController(PanelController panelController) {
-        this.mPanelController = panelController;
-    }
-
     public String calculateUserMessage(Context context, String effectName, Object parameterValue) {
         return effectName + " " + parameterValue;
     }
@@ -83,8 +79,11 @@ public class Editor implements OnSeekBarChangeListener, SwapButton.SwapButtonLis
         return true;
     }
 
-    public void setUpEditorUI(View actionButton, View editControl, Button editTitle) {
-        this.mEditTitle = editTitle;
+    public void setUpEditorUI(View actionButton, View editControl,
+                              Button editTitle, Button stateButton) {
+        mEditTitle = editTitle;
+        mFilterTitle = stateButton;
+        mButton = editTitle;
         setMenuIcon(true);
         setUtilityPanelUI(actionButton, editControl);
     }
@@ -115,13 +114,12 @@ public class Editor implements OnSeekBarChangeListener, SwapButton.SwapButtonLis
             mSeekBar.setVisibility(View.INVISIBLE);
         }
 
-        Button button = (Button) actionButton.findViewById(R.id.applyEffect);
-        if (button != null) {
+        if (mButton != null) {
             if (showsPopupIndicator()) {
-                button.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0,
+                mButton.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0,
                         R.drawable.filtershow_menu_marker, 0);
             } else {
-                button.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0);
+                mButton.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0);
             }
         }
     }
@@ -200,17 +198,25 @@ public class Editor implements OnSeekBarChangeListener, SwapButton.SwapButtonLis
                 boolean show = filterRepresentation.showParameterValue();
                 mShowParameter = show ? SHOW_VALUE_INT : SHOW_VALUE_OFF;
             }
-        }
 
+        }
         return mLocalRepresentation;
     }
 
     public void commitLocalRepresentation() {
         ImagePreset preset = MasterImage.getImage().getPreset();
         preset.updateFilterRepresentation(getLocalRepresentation());
-        if (mPanelController != null) {
-            mPanelController.onNewValue(-1);
+        if (mButton != null) {
+            updateText();
+        }
+    }
+
+    protected void updateText() {
+        String s = "";
+        if (mLocalRepresentation != null) {
+            s = mContext.getString(mLocalRepresentation.getTextId());
         }
+        mButton.setText(calculateUserMessage(mContext, s, ""));
     }
 
     /**
@@ -218,6 +224,12 @@ public class Editor implements OnSeekBarChangeListener, SwapButton.SwapButtonLis
      */
     public void reflectCurrentFilter() {
         mLocalRepresentation = null;
+        FilterRepresentation representation = getLocalRepresentation();
+        if (representation != null && mFilterTitle != null && representation.getTextId() != 0) {
+            String text = mContext.getString(representation.getTextId()).toUpperCase();
+            mFilterTitle.setText(text);
+            updateText();
+        }
     }
 
     public boolean useUtilityPanel() {
@@ -235,6 +247,7 @@ public class Editor implements OnSeekBarChangeListener, SwapButton.SwapButtonLis
         mEditTitle.setCompoundDrawablesRelativeWithIntrinsicBounds(
                 0, 0, on ? R.drawable.filtershow_menu_marker : 0, 0);
     }
+
     protected void createMenu(int[] strId, View button) {
         PopupMenu pmenu = new PopupMenu(mContext, button);
         Menu menu = pmenu.getMenu();
@@ -269,6 +282,8 @@ public class Editor implements OnSeekBarChangeListener, SwapButton.SwapButtonLis
     }
 
     public void detach() {
-
+        if (mImageShow != null) {
+            mImageShow.unselect();
+        }
     }
 }
diff --git a/src/com/android/gallery3d/filtershow/editors/EditorPanel.java b/src/com/android/gallery3d/filtershow/editors/EditorPanel.java
new file mode 100644 (file)
index 0000000..e35bc8f
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.gallery3d.filtershow.editors;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.FilterShowActivity;
+import com.android.gallery3d.filtershow.HistoryAdapter;
+import com.android.gallery3d.filtershow.category.MainPanel;
+import com.android.gallery3d.filtershow.imageshow.MasterImage;
+import com.android.gallery3d.filtershow.state.StatePanel;
+
+public class EditorPanel extends Fragment {
+
+    private static final String LOGTAG = "EditorPanel";
+
+    private LinearLayout mMainView;
+    private Editor mEditor;
+    private int mEditorID;
+
+    public void setEditor(int editor) {
+        mEditorID = editor;
+    }
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        FilterShowActivity filterShowActivity = (FilterShowActivity) activity;
+        mEditor = filterShowActivity.getEditor(mEditorID);
+    }
+
+    public void cancelCurrentFilter() {
+        MasterImage masterImage = MasterImage.getImage();
+        HistoryAdapter adapter = masterImage.getHistory();
+
+        int position = adapter.undo();
+        masterImage.onHistoryItemClick(position);
+        ((FilterShowActivity)getActivity()).invalidateViews();
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        FilterShowActivity activity = (FilterShowActivity) getActivity();
+        if (mMainView != null) {
+            if (mMainView.getParent() != null) {
+                ViewGroup parent = (ViewGroup) mMainView.getParent();
+                parent.removeView(mMainView);
+            }
+            showImageStatePanel(activity.isShowingImageStatePanel());
+            return mMainView;
+        }
+        mMainView = (LinearLayout) inflater.inflate(R.layout.filtershow_editor_panel, null);
+
+        View actionControl = mMainView.findViewById(R.id.panelAccessoryViewList);
+        View editControl = mMainView.findViewById(R.id.controlArea);
+        ImageButton cancelButton = (ImageButton) mMainView.findViewById(R.id.cancelFilter);
+        ImageButton applyButton = (ImageButton) mMainView.findViewById(R.id.applyFilter);
+        Button editTitle = (Button) mMainView.findViewById(R.id.applyEffect);
+        cancelButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                cancelCurrentFilter();
+                FilterShowActivity activity = (FilterShowActivity) getActivity();
+                activity.backToMain();
+            }
+        });
+        applyButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                MasterImage.getImage().invalidateFiltersOnly();
+                FilterShowActivity activity = (FilterShowActivity) getActivity();
+                activity.backToMain();
+            }
+        });
+
+        Button toggleState = (Button) mMainView.findViewById(R.id.toggle_state);
+
+        mEditor = activity.getEditor(mEditorID);
+        if (mEditor != null) {
+            mEditor.setUpEditorUI(actionControl, editControl, editTitle, toggleState);
+            mEditor.getImageShow().select();
+            mEditor.reflectCurrentFilter();
+            if (mEditor.useUtilityPanel()) {
+                mEditor.openUtilityPanel((LinearLayout) actionControl);
+            }
+        }
+
+        showImageStatePanel(activity.isShowingImageStatePanel());
+        return mMainView;
+    }
+
+    @Override
+    public void onDetach() {
+        if (mEditor != null) {
+            mEditor.detach();
+        }
+        super.onDetach();
+    }
+
+    public void showImageStatePanel(boolean show) {
+        if (mMainView.findViewById(R.id.state_panel_container) == null) {
+            return;
+        }
+        FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
+        Fragment panel = getActivity().getSupportFragmentManager().findFragmentByTag(
+                MainPanel.FRAGMENT_TAG);
+        if (panel == null || panel instanceof MainPanel) {
+            transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
+        }
+        if (show) {
+            StatePanel statePanel = new StatePanel();
+            transaction.replace(R.id.state_panel_container, statePanel, StatePanel.FRAGMENT_TAG);
+        } else {
+            Fragment statePanel = getChildFragmentManager().findFragmentByTag(StatePanel.FRAGMENT_TAG);
+            if (statePanel != null) {
+                transaction.remove(statePanel);
+            }
+        }
+        transaction.commit();
+    }
+}
index 33ed143..02a1c71 100644 (file)
@@ -195,15 +195,6 @@ public class ParametricEditor extends Editor {
     }
 
     @Override
-    public void commitLocalRepresentation() {
-        super.commitLocalRepresentation();
-        FilterRepresentation rep = getLocalRepresentation();
-        if (mPanelController != null) {
-            mPanelController.onNewValue(-1);
-        }
-    }
-
-    @Override
     public void onProgressChanged(SeekBar sbar, int progress, boolean arg2) {
     }
 
index 0a7ee3c..e06f544 100644 (file)
 
 package com.android.gallery3d.filtershow.filters;
 
+import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Matrix;
+import android.graphics.Rect;
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.presets.ImagePreset;
 
 public class ImageFilterVignette extends SimpleImageFilter {
     private static final String LOGTAG = "ImageFilterVignette";
+    private Bitmap mOverlayBitmap;
 
     public ImageFilterVignette() {
         mName = "Vignette";
@@ -51,6 +57,18 @@ public class ImageFilterVignette extends SimpleImageFilter {
 
     @Override
     public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
+        if (SIMPLE_ICONS && ImagePreset.QUALITY_ICON == quality) {
+            if (mOverlayBitmap == null) {
+                Resources res = getEnvironment().getCachingPipeline().getResources();
+                mOverlayBitmap = IconUtilities.getFXBitmap(res,
+                        R.drawable.filtershow_icon_vignette);
+            }
+            Canvas c = new Canvas(bitmap);
+            int dim = Math.max(bitmap.getWidth(), bitmap.getHeight());
+            Rect r = new Rect(0, 0, dim, dim);
+            c.drawBitmap(mOverlayBitmap, null, r, null);
+            return bitmap;
+        }
         FilterVignetteRepresentation rep = (FilterVignetteRepresentation) getParameters();
         if (rep == null) {
             return bitmap;
index 68a74dc..0c51b16 100644 (file)
@@ -284,9 +284,6 @@ public abstract class ImageGeometry extends ImageShow {
             default:
                 setNoAction();
         }
-        if (getPanelController() != null) {
-            getPanelController().onNewValue(getLocalValue());
-        }
         invalidate();
         return true;
     }
index 045c1a5..e19a755 100644 (file)
@@ -28,7 +28,6 @@ import android.graphics.RectF;
 import android.net.Uri;
 import android.os.Handler;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.GestureDetector;
 import android.view.GestureDetector.OnDoubleTapListener;
 import android.view.GestureDetector.OnGestureListener;
@@ -38,7 +37,6 @@ import android.view.View;
 import android.widget.LinearLayout;
 
 import com.android.gallery3d.filtershow.FilterShowActivity;
-import com.android.gallery3d.filtershow.PanelController;
 import com.android.gallery3d.filtershow.cache.ImageLoader;
 import com.android.gallery3d.filtershow.filters.ImageFilter;
 import com.android.gallery3d.filtershow.presets.ImagePreset;
@@ -101,8 +99,6 @@ public class ImageShow extends View implements OnGestureListener,
         return new GeometryMetadata(getImagePreset().mGeoData);
     }
 
-    private PanelController mController = null;
-
     private FilterShowActivity mActivity = null;
 
     public static void setDefaultBackgroundColor(int value) {
@@ -156,18 +152,7 @@ public class ImageShow extends View implements OnGestureListener,
         // TODO: implement reset
     }
 
-    public void setPanelController(PanelController controller) {
-        mController = controller;
-    }
-
-    public PanelController getPanelController() {
-        return mController;
-    }
-
     public void onNewValue(int parameter) {
-        if (getPanelController() != null) {
-            getPanelController().onNewValue(parameter);
-        }
         invalidate();
         mActivity.enableSave(hasModifications());
     }
@@ -409,7 +394,8 @@ public class ImageShow extends View implements OnGestureListener,
     }
 
     public void drawPartialImage(Canvas canvas, Bitmap image) {
-        if (!mTouchShowOriginal)
+        boolean showsOriginal = MasterImage.getImage().showsOriginal();
+        if (!showsOriginal && !mTouchShowOriginal)
             return;
         canvas.save();
         if (image != null) {
@@ -429,6 +415,9 @@ public class ImageShow extends View implements OnGestureListener,
             } else {
                 px = (int) (mTouch.x - mImageBounds.left);
                 py = mImageBounds.height();
+                if (showsOriginal) {
+                    px = mImageBounds.width();
+                }
             }
 
             Rect d = new Rect(mImageBounds.left, mImageBounds.top,
index 866b1b0..5f906ea 100644 (file)
@@ -92,9 +92,6 @@ public class ImageStraighten extends ImageGeometry {
     @Override
     public void onNewValue(int value) {
         setLocalStraighten(GeometryMath.clamp(value, MIN_STRAIGHTEN_ANGLE, MAX_STRAIGHTEN_ANGLE));
-        if (getPanelController() != null) {
-            getPanelController().onNewValue((int) getLocalStraighten());
-        }
         invalidate();
     }
 
index 304d2db..658d8bc 100644 (file)
@@ -72,6 +72,8 @@ public class MasterImage implements RenderingRequestCaller {
 
     private Point mImageShowSize = new Point();
 
+    private boolean mShowsOriginal;
+
     final private static int NEW_GEOMETRY = 1;
 
     private final Handler mHandler = new Handler() {
@@ -478,6 +480,10 @@ public class MasterImage implements RenderingRequestCaller {
         return mLoader.getOriginalBitmapSmall();
     }
 
+    public Bitmap getLargeThumbnailBitmap() {
+        return mLoader.getOriginalBitmapLarge();
+    }
+
     public float getMaxScaleFactor() {
         return mMaxScaleFactor;
     }
@@ -489,4 +495,13 @@ public class MasterImage implements RenderingRequestCaller {
     public boolean supportsHighRes() {
         return mSupportsHighRes;
     }
+
+    public void setShowsOriginal(boolean value) {
+        mShowsOriginal = value;
+        notifyObservers();
+    }
+
+    public boolean showsOriginal() {
+        return mShowsOriginal;
+    }
 }
index ca97761..e0ff0b3 100644 (file)
@@ -28,6 +28,7 @@ import com.android.gallery3d.filtershow.filters.FilterRepresentation;
 import com.android.gallery3d.filtershow.filters.ImageFilter;
 import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
 import com.android.gallery3d.filtershow.imageshow.MasterImage;
+import com.android.gallery3d.filtershow.state.State;
 import com.android.gallery3d.filtershow.state.StateAdapter;
 
 import java.util.Vector;
@@ -369,6 +370,11 @@ public class ImagePreset {
     }
 
     public void removeFilter(FilterRepresentation filterRepresentation) {
+        if (filterRepresentation.getPriority() == FilterRepresentation.TYPE_BORDER) {
+            setBorder(null);
+            setHistoryName("Remove");
+            return;
+        }
         for (int i = 0; i < mFilters.size(); i++) {
             if (mFilters.elementAt(i).getFilterClass() == filterRepresentation.getFilterClass()) {
                 mFilters.remove(i);
@@ -539,7 +545,20 @@ public class ImagePreset {
         if (imageStateAdapter == null) {
             return;
         }
+        imageStateAdapter.clear();
+        imageStateAdapter.addOriginal();
+        // TODO: supports Geometry representations in the state panel.
+        if (false && mGeoData != null && mGeoData.hasModifications()) {
+            State geo = new State("Geometry");
+            geo.setFilterRepresentation(mGeoData);
+            imageStateAdapter.add(geo);
+        }
         imageStateAdapter.addAll(mFilters);
+        if (mBorder != null) {
+            State border = new State(mBorder.getName());
+            border.setFilterRepresentation(mBorder);
+            imageStateAdapter.add(border);
+        }
     }
 
     public void setPartialRendering(boolean partialRendering, Rect bounds) {
index ae81e0b..58f9a7f 100644 (file)
@@ -22,7 +22,9 @@ import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import com.android.gallery3d.R;
 import com.android.gallery3d.filtershow.FilterShowActivity;
+import com.android.gallery3d.filtershow.editors.ImageOnlyEditor;
 import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+import com.android.gallery3d.filtershow.imageshow.MasterImage;
 
 import java.util.Vector;
 
@@ -49,7 +51,15 @@ public class StateAdapter extends ArrayAdapter<State> {
         State state = getItem(position);
         view.setState(state);
         view.setOrientation(mOrientation);
-        view.setBackgroundAlpha(1.0f);
+        FilterRepresentation currentRep = MasterImage.getImage().getCurrentFilterRepresentation();
+        FilterRepresentation stateRep = state.getFilterRepresentation();
+        if (currentRep != null && stateRep != null
+            && currentRep.getFilterClass() == stateRep.getFilterClass()
+            && currentRep.getEditorId() != ImageOnlyEditor.ID) {
+            view.setSelected(true);
+        } else {
+            view.setSelected(false);
+        }
         return view;
     }
 
@@ -73,15 +83,16 @@ public class StateAdapter extends ArrayAdapter<State> {
         }
     }
 
-    public void addAll(Vector<FilterRepresentation> filters) {
-        clear();
+    public void addOriginal() {
         add(new State(mOriginalText));
+    }
+
+    public void addAll(Vector<FilterRepresentation> filters) {
         for (FilterRepresentation filter : filters) {
             State state = new State(filter.getName());
             state.setFilterRepresentation(filter);
             add(state);
         }
-        add(new State(mResultText));
         notifyDataSetChanged();
     }
 
@@ -94,6 +105,6 @@ public class StateAdapter extends ArrayAdapter<State> {
         super.remove(state);
         FilterRepresentation filterRepresentation = state.getFilterRepresentation();
         FilterShowActivity activity = (FilterShowActivity) getContext();
-        activity.getPanelController().removeFilterRepresentation(filterRepresentation);
+        activity.removeFilterRepresentation(filterRepresentation);
     }
 }
index fd33b05..df470f2 100644 (file)
@@ -18,6 +18,7 @@ package com.android.gallery3d.filtershow.state;
 
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -27,18 +28,17 @@ import com.android.gallery3d.filtershow.imageshow.MasterImage;
 
 public class StatePanel extends Fragment {
     private static final String LOGTAG = "StatePanel";
-    StatePanelTrack track;
+    private StatePanelTrack track;
+    private LinearLayout mMainView;
+    public static final String FRAGMENT_TAG = "StatePanel";
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState) {
-        LinearLayout main = (LinearLayout) inflater.inflate(
-                R.layout.filtershow_state_panel_new, container,
-                false);
-
-        View panel = main.findViewById(R.id.listStates);
+        mMainView = (LinearLayout) inflater.inflate(R.layout.filtershow_state_panel_new, null);
+        View panel = mMainView.findViewById(R.id.listStates);
         track = (StatePanelTrack) panel;
         track.setAdapter(MasterImage.getImage().getState());
-        return main;
+        return mMainView;
     }
 }
index 1f6c272..4fb1b11 100644 (file)
@@ -18,16 +18,22 @@ package com.android.gallery3d.filtershow.state;
 
 import android.animation.LayoutTransition;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.GestureDetector;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.Adapter;
 import android.widget.LinearLayout;
+import com.android.gallery3d.R;
 import com.android.gallery3d.filtershow.FilterShowActivity;
+import com.android.gallery3d.filtershow.editors.ImageOnlyEditor;
 import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+import com.android.gallery3d.filtershow.imageshow.MasterImage;
 
 public class StatePanelTrack extends LinearLayout implements PanelTrack {
 
@@ -39,12 +45,34 @@ public class StatePanelTrack extends LinearLayout implements PanelTrack {
     private boolean mStartedDrag = false;
     private StateAdapter mAdapter;
     private DragListener mDragListener = new DragListener(this);
-    GestureDetector mGestureDetector;
-    private int mContainerWidth = 668; // TODO: get this from XML
-    private int mContainerHeight = 200;
+    private float mDeleteSlope = 0.2f;
+    private GestureDetector mGestureDetector;
+    private int mElemWidth;
+    private int mElemHeight;
+    private int mElemSize;
+    private int mElemEndSize;
+    private int mEndElemWidth;
+    private int mEndElemHeight;
+    private long mTouchTime;
+    private int mMaxTouchDelay = 300; // 300ms delay for touch
+    private static final boolean ALLOWS_DRAG = false;
 
     public StatePanelTrack(Context context, AttributeSet attrs) {
         super(context, attrs);
+        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.StatePanelTrack);
+        mElemSize = a.getDimensionPixelSize(R.styleable.StatePanelTrack_elemSize, 0);
+        mElemEndSize = a.getDimensionPixelSize(R.styleable.StatePanelTrack_elemEndSize, 0);
+        if (getOrientation() == LinearLayout.HORIZONTAL) {
+            mElemWidth = mElemSize;
+            mElemHeight = LayoutParams.MATCH_PARENT;
+            mEndElemWidth = mElemEndSize;
+            mEndElemHeight = LayoutParams.MATCH_PARENT;
+        } else {
+            mElemWidth = LayoutParams.MATCH_PARENT;
+            mElemHeight = mElemSize;
+            mEndElemWidth = LayoutParams.MATCH_PARENT;
+            mEndElemHeight = mElemEndSize;
+        }
         GestureDetector.SimpleOnGestureListener simpleOnGestureListener
                 = new GestureDetector.SimpleOnGestureListener(){
             @Override
@@ -100,23 +128,11 @@ public class StatePanelTrack extends LinearLayout implements PanelTrack {
         return null;
     }
 
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
-        int w = MeasureSpec.getSize(widthMeasureSpec);
-        if (w > 0) {
-            mContainerWidth = w;
-        }
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        fillContent(false);
-    }
-
     public void fillContent(boolean animate) {
         if (!animate) {
             this.setLayoutTransition(null);
         }
         int n = mAdapter.getCount();
-        int w = mContainerWidth;
-        int h = mContainerHeight;
         for (int i = 0; i < getChildCount(); i++) {
             StateView child = (StateView) getChildAt(i);
             child.resetPosition();
@@ -124,10 +140,7 @@ public class StatePanelTrack extends LinearLayout implements PanelTrack {
                 removeView(child);
             }
         }
-        LayoutParams params;
-        params = new LayoutParams(w, h);
-        LayoutParams paramsEnds;
-        paramsEnds = new LayoutParams(w, h/2);
+        LayoutParams params = new LayoutParams(mElemWidth, mElemHeight);
         for (int i = 0; i < n; i++) {
             State s = mAdapter.getItem(i);
             if (findChildWithState(s) == null) {
@@ -135,6 +148,7 @@ public class StatePanelTrack extends LinearLayout implements PanelTrack {
                 addView(view, i, params);
             }
         }
+
         for (int i = 0; i < n; i++) {
             State state = mAdapter.getItem(i);
             StateView view = (StateView) getChildAt(i);
@@ -143,19 +157,10 @@ public class StatePanelTrack extends LinearLayout implements PanelTrack {
                 view.setType(StateView.BEGIN);
             } else if (i == n - 1) {
                 view.setType(StateView.END);
-            }
-            view.resetPosition();
-            if (i == 0 || (i == n -1)) {
-                if (view.getWidth() != w || view.getHeight() != h/2) {
-                    view.setLayoutParams(paramsEnds);
-                    requestLayout();
-                }
             } else {
-                if (view.getWidth() != w || view.getHeight() != h) {
-                    view.setLayoutParams(params);
-                    requestLayout();
-                }
+                view.setType(StateView.DEFAULT);
             }
+            view.resetPosition();
         }
 
         if (!animate) {
@@ -180,12 +185,9 @@ public class StatePanelTrack extends LinearLayout implements PanelTrack {
         cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
         mGestureDetector.onTouchEvent(cancelEvent);
         mCurrentSelectedView = mCurrentView;
-        mCurrentSelectedView.setSelected(true);
         // We have to send the event to the gesture detector
         mGestureDetector.onTouchEvent(event);
-        FilterShowActivity activity = (FilterShowActivity) getContext();
-        activity.getPanelController().showComponentWithRepresentation(
-                mCurrentSelectedView.getState().getFilterRepresentation());
+        mTouchTime = System.currentTimeMillis();
     }
 
     @Override
@@ -201,12 +203,16 @@ public class StatePanelTrack extends LinearLayout implements PanelTrack {
         if (mCurrentView == null) {
             return false;
         }
+        if (mTouchTime == 0) {
+            mTouchTime = System.currentTimeMillis();
+        }
         mGestureDetector.onTouchEvent(event);
         if (mTouchPoint == null) {
             mTouchPoint = new Point();
             mTouchPoint.x = (int) event.getX();
             mTouchPoint.y = (int) event.getY();
         }
+
         if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
             float translation = event.getY() - mTouchPoint.y;
             float alpha = 1.0f - (Math.abs(translation) / mCurrentView.getHeight());
@@ -218,13 +224,26 @@ public class StatePanelTrack extends LinearLayout implements PanelTrack {
                 mCurrentView.setTranslationY(translation);
             }
             mCurrentView.setBackgroundAlpha(alpha);
-            if (alpha < 0.7) {
+            if (ALLOWS_DRAG && alpha < 0.7) {
                 setOnDragListener(mDragListener);
                 DragShadowBuilder shadowBuilder = new DragShadowBuilder(mCurrentView);
                 mCurrentView.startDrag(null, shadowBuilder, mCurrentView, 0);
                 mStartedDrag = true;
             }
         }
+        if (!mExited && mCurrentView != null
+                && mCurrentView.getBackgroundAlpha() > mDeleteSlope
+                && event.getActionMasked() == MotionEvent.ACTION_UP
+                && System.currentTimeMillis() - mTouchTime < mMaxTouchDelay) {
+            FilterRepresentation representation = mCurrentView.getState().getFilterRepresentation();
+            if (representation != MasterImage.getImage().getCurrentFilterRepresentation()) {
+                FilterShowActivity activity = (FilterShowActivity) getContext();
+                activity.showRepresentation(representation);
+            }
+            if (representation.getEditorId() != ImageOnlyEditor.ID) {
+                mCurrentView.setSelected(true);
+            }
+        }
         if (event.getActionMasked() == MotionEvent.ACTION_UP
                 || (!mStartedDrag && event.getActionMasked() == MotionEvent.ACTION_CANCEL)) {
             checkEndState();
@@ -234,18 +253,33 @@ public class StatePanelTrack extends LinearLayout implements PanelTrack {
 
     public void checkEndState() {
         mTouchPoint = null;
-        if (mExited || mCurrentView.getAlpha() < 0.2) {
+        mTouchTime = 0;
+        if (mExited || mCurrentView.getBackgroundAlpha() < mDeleteSlope) {
             int origin = findChild(mCurrentView);
             if (origin != -1) {
                 State current = mAdapter.getItem(origin);
+                FilterRepresentation currentRep = MasterImage.getImage().getCurrentFilterRepresentation();
+                FilterRepresentation removedRep = current.getFilterRepresentation();
                 mAdapter.remove(current);
                 fillContent(true);
+                if (currentRep != null && removedRep != null
+                        && currentRep.getFilterClass() == removedRep.getFilterClass()) {
+                    FilterShowActivity activity = (FilterShowActivity) getContext();
+                    activity.backToMain();
+                    return;
+                }
             }
         } else {
             mCurrentView.setBackgroundAlpha(1.0f);
             mCurrentView.setTranslationX(0);
             mCurrentView.setTranslationY(0);
         }
+        if (mCurrentSelectedView != null) {
+            mCurrentSelectedView.invalidate();
+        }
+        if (mCurrentView != null) {
+            mCurrentView.invalidate();
+        }
         mCurrentView = null;
         mExited = false;
         mStartedDrag = false;
index eb19b52..45ca382 100644 (file)
 package com.android.gallery3d.filtershow.state;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.*;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewParent;
 import android.widget.LinearLayout;
+import com.android.gallery3d.R;
 import com.android.gallery3d.filtershow.FilterShowActivity;
+import com.android.gallery3d.filtershow.imageshow.MasterImage;
 
 public class StateView extends View {
 
+    private static final String LOGTAG = "StateView";
     private Path mPath = new Path();
     private Paint mPaint = new Paint();
 
@@ -51,6 +56,14 @@ public class StateView extends View {
     private boolean mDuplicateButton;
     private State mState;
 
+    private int mEndsBackgroundColor;
+    private int mEndsTextColor;
+    private int mBackgroundColor;
+    private int mTextColor;
+    private int mSelectedBackgroundColor;
+    private int mSelectedTextColor;
+    private Rect mTextBounds = new Rect();
+
     public StateView(Context context) {
         this(context, DEFAULT);
     }
@@ -58,10 +71,13 @@ public class StateView extends View {
     public StateView(Context context, int type) {
         super(context);
         mType = type;
-    }
-
-    public StateView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        Resources res = getResources();
+        mEndsBackgroundColor = res.getColor(R.color.filtershow_stateview_end_background);
+        mEndsTextColor = res.getColor(R.color.filtershow_stateview_end_text);
+        mBackgroundColor = res.getColor(R.color.filtershow_stateview_background);
+        mTextColor = res.getColor(R.color.filtershow_stateview_text);
+        mSelectedBackgroundColor = res.getColor(R.color.filtershow_stateview_selected_background);
+        mSelectedTextColor = res.getColor(R.color.filtershow_stateview_selected_text);
     }
 
     public String getText() {
@@ -94,6 +110,13 @@ public class StateView extends View {
             if (parent instanceof PanelTrack) {
                 ((PanelTrack) getParent()).onTouch(event, this);
             }
+            if (mType == BEGIN) {
+                MasterImage.getImage().setShowsOriginal(true);
+            }
+        }
+        if (event.getActionMasked() == MotionEvent.ACTION_UP
+                || event.getActionMasked() == MotionEvent.ACTION_CANCEL) {
+            MasterImage.getImage().setShowsOriginal(false);
         }
         return true;
     }
@@ -104,17 +127,19 @@ public class StateView extends View {
         }
         mPaint.reset();
         if (isSelected()) {
-            mPaint.setColor(Color.BLACK);
+            mPaint.setColor(mSelectedTextColor);
         } else {
-            mPaint.setColor(Color.WHITE);
+            mPaint.setColor(mTextColor);
         }
-        mPaint.setTextSize(mTextSize);
-        float textWidth = mPaint.measureText(mText);
-        int x = (int) ((canvas.getWidth() - textWidth) / 2);
-        int y = canvas.getHeight() - sMargin;
-        if (canvas.getHeight() > canvas.getWidth()) {
-            y = canvas.getHeight() - (canvas.getHeight() - canvas.getWidth() - 2 * sMargin) / 2;
+        if (mType == BEGIN) {
+            mPaint.setColor(mEndsTextColor);
         }
+        mPaint.setTypeface(Typeface.DEFAULT_BOLD);
+        mPaint.setAntiAlias(true);
+        mPaint.setTextSize(mTextSize);
+        mPaint.getTextBounds(mText, 0, mText.length(), mTextBounds);
+        int x = (canvas.getWidth() - mTextBounds.width()) / 2;
+        int y = mTextBounds.height() + (canvas.getHeight() - mTextBounds.height()) / 2;
         canvas.drawText(mText, x, y, mPaint);
     }
 
@@ -137,16 +162,16 @@ public class StateView extends View {
             }
         }
 
-        if (mType == DEFAULT) {
+        if (mType == DEFAULT || mType == END) {
             if (mDuplicateButton) {
                 mPaint.setARGB(255, 200, 0, 0);
             } else if (isSelected()) {
-                mPaint.setARGB(255, 200, 200, 200);
+                mPaint.setColor(mSelectedBackgroundColor);
             } else {
-                mPaint.setARGB(255, 70, 70, 70);
+                mPaint.setColor(mBackgroundColor);
             }
         } else {
-            mPaint.setARGB(255, 150, 150, 150);
+            mPaint.setColor(mEndsBackgroundColor);
         }
         canvas.drawPath(mPath, mPaint);
         drawText(canvas);
@@ -220,14 +245,15 @@ public class StateView extends View {
     }
 
     public void setBackgroundAlpha(float alpha) {
-        if (mType != DEFAULT) {
+        if (mType == BEGIN) {
             return;
         }
         mAlpha = alpha;
+        setAlpha(alpha);
         invalidate();
     }
 
-    public float getAlpha() {
+    public float getBackgroundAlpha() {
         return mAlpha;
     }
 
@@ -246,15 +272,15 @@ public class StateView extends View {
 
     public void setState(State state) {
         mState = state;
-        mText = mState.getText();
+        mText = mState.getText().toUpperCase();
         mType = mState.getType();
-        setBackgroundAlpha(1.0f);
         invalidate();
     }
 
     public void resetPosition() {
         setTranslationX(0);
         setTranslationY(0);
+        setBackgroundAlpha(1.0f);
     }
 
     public boolean isDraggable() {
index 7d4071d..a15060b 100644 (file)
@@ -21,13 +21,13 @@ import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 import android.widget.LinearLayout;
 
-import com.android.gallery3d.filtershow.PanelController;
+import com.android.gallery3d.filtershow.FilterShowActivity;
 import com.android.gallery3d.filtershow.cache.RenderingRequest;
 import com.android.gallery3d.filtershow.cache.RenderingRequestCaller;
+import com.android.gallery3d.filtershow.category.Action;
 import com.android.gallery3d.filtershow.filters.FilterRepresentation;
 import com.android.gallery3d.filtershow.imageshow.GeometryListener;
 import com.android.gallery3d.filtershow.imageshow.MasterImage;
@@ -40,11 +40,9 @@ public class FilterIconButton extends IconButton implements View.OnClickListener
     private static final String LOGTAG = "FilterIconButton";
     private Bitmap mOverlayBitmap = null;
     private boolean mOverlayOnly = false;
-    private PanelController mController = null;
     private FilterRepresentation mFilterRepresentation = null;
-    private LinearLayout mParentContainer = null;
-    private View.OnClickListener mListener = null;
     private Bitmap mIconBitmap = null;
+    private Action mAction;
     public FilterIconButton(Context context) {
         super(context);
     }
@@ -57,42 +55,46 @@ public class FilterIconButton extends IconButton implements View.OnClickListener
         super(context, attrs, defStyle);
     }
 
-    public void setup(String text, PanelController controller, LinearLayout parent) {
-        mController = controller;
+    public void setup(String text, LinearLayout parent) {
         setText(text);
         setContentDescription(text);
-        mParentContainer = parent;
         super.setOnClickListener(this);
         MasterImage.getImage().addGeometryListener(this);
         invalidate();
     }
 
     @Override
-    public void setOnClickListener(View.OnClickListener listener) {
-        mListener = listener;
-    }
-
-    @Override
     public void onClick(View v) {
-        if (mController != null) {
-            mController.useFilterRepresentation(mFilterRepresentation);
-            mParentContainer.dispatchSetSelected(false);
-            setSelected(true);
-        }
-        if (mListener != null && mListener != this) {
-            mListener.onClick(v);
-        }
+        FilterShowActivity activity = (FilterShowActivity) getContext();
+        activity.showRepresentation(mFilterRepresentation);
     }
 
     public FilterRepresentation getFilterRepresentation() {
         return mFilterRepresentation;
     }
 
-    public void setFilterRepresentation(FilterRepresentation filterRepresentation) {
+    public void setAction(Action action) {
+        mAction = action;
+        if (action == null) {
+            return;
+        }
+        if (mAction.getPortraitImage() != null) {
+            mIconBitmap = mAction.getPortraitImage();
+            setIcon(mIconBitmap);
+        }
+        setFilterRepresentation(mAction.getRepresentation());
+    }
+
+    private void setFilterRepresentation(FilterRepresentation filterRepresentation) {
         mFilterRepresentation = filterRepresentation;
         if (mFilterRepresentation != null && mFilterRepresentation.getOverlayId() != 0) {
-            mOverlayBitmap = BitmapFactory.decodeResource(getResources(),
+            if (mAction.getOverlayBitmap() == null) {
+                mOverlayBitmap = BitmapFactory.decodeResource(getResources(),
                     mFilterRepresentation.getOverlayId());
+                mAction.setOverlayBitmap(mOverlayBitmap);
+            } else {
+                mOverlayBitmap = mAction.getOverlayBitmap();
+            }
         }
         mOverlayOnly = mFilterRepresentation.getOverlayOnly();
         if (mOverlayOnly) {
@@ -106,8 +108,9 @@ public class FilterIconButton extends IconButton implements View.OnClickListener
     protected void onDraw(Canvas canvas) {
         if (mIconBitmap == null && !mOverlayOnly) {
             postNewIconRenderRequest();
+        } else {
+            super.onDraw(canvas);
         }
-        super.onDraw(canvas);
     }
 
     @Override
@@ -125,6 +128,9 @@ public class FilterIconButton extends IconButton implements View.OnClickListener
                 IconFactory.drawIcon(mIconBitmap, mOverlayBitmap, false);
             }
             setIcon(mIconBitmap);
+            if (mAction != null) {
+                mAction.setPortraitImage(mIconBitmap);
+            }
         }
     }
 
@@ -139,7 +145,7 @@ public class FilterIconButton extends IconButton implements View.OnClickListener
 
     private void postNewIconRenderRequest() {
         Bitmap dst = MasterImage.getImage().getThumbnailBitmap();
-        if (dst != null) {
+        if (dst != null && mAction != null) {
             ImagePreset mPreset = new ImagePreset();
             mPreset.addFilter(mFilterRepresentation);
             RenderingRequest.post(dst.copy(Bitmap.Config.ARGB_8888, true),
index be5df0a..4755b90 100644 (file)
@@ -179,6 +179,9 @@ public class ImageCurves extends ImageShow {
     @Override
     public void onDraw(Canvas canvas) {
         super.onDraw(canvas);
+        if (mFilterCurvesRepresentation == null) {
+            return;
+        }
 
         gPaint.setAntiAlias(true);