aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorge Ruesga <jorge@ruesga.com>2013-11-02 02:20:56 +0100
committerJorge Ruesga <jorge@ruesga.com>2013-11-02 02:20:56 +0100
commit4effddfe30fd045834232f6bb66070edf079578d (patch)
tree2e57f74d55685891a49b02ec069c118cf5b15110
parentca2f0060cc367ac8174a27a3124cd0124e49c627 (diff)
downloadandroid_packages_wallpapers_PhotoPhase-4effddfe30fd045834232f6bb66070edf079578d.tar.gz
android_packages_wallpapers_PhotoPhase-4effddfe30fd045834232f6bb66070edf079578d.tar.bz2
android_packages_wallpapers_PhotoPhase-4effddfe30fd045834232f6bb66070edf079578d.zip
Multiples fixes
- Fully rewrite the album selection preference - Fix multiple style - Fix lints - Resources cleanup Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
-rw-r--r--AndroidManifest.xml13
-rw-r--r--res/anim/cards_slide_up.xml (renamed from res/anim/cards_animation_up_left.xml)16
-rw-r--r--res/anim/display_with_bounce.xml2
-rw-r--r--res/anim/picture_animation.xml (renamed from res/anim/cards_animation_up_right.xml)18
-rw-r--r--res/anim/pictures_layout_animation.xml19
-rw-r--r--res/animator/cards_rotate_animator.xml25
-rw-r--r--res/drawable-xhdpi/wallpaper_thumb.pngbin58293 -> 0 bytes
-rw-r--r--res/drawable/card.xml2
-rw-r--r--res/drawable/holo_selector.xml2
-rw-r--r--res/layout/album_info.xml107
-rw-r--r--res/layout/album_pictures.xml79
-rw-r--r--res/layout/choose_disposition_fragment.xml2
-rw-r--r--res/layout/choose_picture_fragment.xml26
-rw-r--r--res/layout/color_picker_pref_item.xml2
-rw-r--r--res/layout/picture_item.xml31
-rw-r--r--res/layout/pictures_view.xml (renamed from res/layout/album.xml)28
-rw-r--r--res/layout/preference_widget_seekbar.xml4
-rw-r--r--res/layout/preference_widget_seekbar_progress.xml2
-rw-r--r--res/menu/album_actions.xml8
-rw-r--r--res/menu/albums.xml6
-rw-r--r--res/menu/dispositions.xml2
-rw-r--r--res/menu/main.xml2
-rw-r--r--res/raw/mix_fragment_shader.glsl27
-rw-r--r--res/raw/mix_vertex_shader.glsl27
-rw-r--r--res/values-es/plurals.xml2
-rw-r--r--res/values-es/strings.xml6
-rw-r--r--res/values-land/dimens.xml2
-rw-r--r--res/values-large/dimens.xml2
-rw-r--r--res/values-sw600dp-port/dimens.xml (renamed from res/drawable/frame.xml)11
-rw-r--r--res/values-sw600dp/dimens.xml (renamed from res/menu/pictures_actions.xml)16
-rw-r--r--res/values-sw720dp-port/dimens.xml19
-rw-r--r--res/values-sw720dp-w1280dp/dimens.xml2
-rw-r--r--res/values-sw720dp/dimens.xml3
-rw-r--r--res/values/arrays.xml2
-rw-r--r--res/values/colors.xml4
-rw-r--r--res/values/config.xml2
-rw-r--r--res/values/dimens.xml7
-rw-r--r--res/values/integers.xml7
-rw-r--r--res/values/plurals.xml2
-rw-r--r--res/values/strings.xml6
-rw-r--r--res/values/styles.xml2
-rw-r--r--res/xml/preferences_general.xml2
-rw-r--r--res/xml/preferences_headers.xml2
-rw-r--r--res/xml/preferences_layout.xml2
-rw-r--r--res/xml/preferences_media.xml2
-rw-r--r--res/xml/wallpaper.xml2
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/MediaPictureDiscoverer.java2
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseRenderer.java28
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseWallpaper.java2
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/TextureManager.java10
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/adapters/AlbumCardUiAdapter.java139
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/adapters/AlbumPictureAdapter.java127
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/animations/Flip3dAnimationController.java (renamed from src/org/cyanogenmod/wallpapers/photophase/animations/AlbumsFlip3dAnimationController.java)113
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/animations/Rotate3dAnimation.java93
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/model/Album.java23
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/model/Picture.java64
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/preferences/ChoosePicturesFragment.java805
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/preferences/DispositionFragment.java2
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/preferences/PhotoPhasePreferences.java3
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/preferences/PreferencesProvider.java13
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/tasks/AsyncPictureLoaderTask.java52
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/widgets/AlbumInfoView.java (renamed from src/org/cyanogenmod/wallpapers/photophase/widgets/AlbumInfo.java)159
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/widgets/AlbumPictures.java345
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/widgets/CardLayout.java91
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/widgets/DispositionView.java8
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/widgets/PictureItemView.java204
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/widgets/PicturesView.java164
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/widgets/VerticalEndlessScroller.java114
68 files changed, 1744 insertions, 1372 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 42e2545..57a685d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +22,7 @@
<original-package android:name="org.cyanogenmod.wallpapers.photophase" />
- <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="18" />
+ <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="19" />
<uses-feature android:name="android.software.live_wallpaper" android:required="true" />
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
@@ -40,7 +40,7 @@
android:largeHeap="true">
<service
- android:name="PhotoPhaseWallpaper"
+ android:name=".PhotoPhaseWallpaper"
android:enabled="true"
android:label="@string/app_name"
android:description="@string/app_description"
@@ -71,13 +71,6 @@
</intent-filter>
</activity>
- <activity
- android:name=".SetPhotoPhaseWallpaperActivity"
- android:exported="true"
- android:label="@string/app_name"
- android:description="@string/app_description">
- </activity>
-
</application>
</manifest>
diff --git a/res/anim/cards_animation_up_left.xml b/res/anim/cards_slide_up.xml
index 6d97f6c..6da2e69 100644
--- a/res/anim/cards_animation_up_left.xml
+++ b/res/anim/cards_slide_up.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
+ Copyright (C) 2013 Ahmed Nammari
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,22 +16,17 @@
limitations under the License.
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/accelerate_interpolator" >
+ android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+ android:fillAfter="true">
<translate
- android:duration="@integer/cards_slide_anim"
+ android:duration="@integer/cards_slide_up_anim"
android:fromYDelta="100%p"
android:toYDelta="0" />
<alpha
- android:duration="@integer/cards_slide_anim"
+ android:duration="@integer/cards_slide_up_anim"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
- <rotate
- android:duration="@integer/cards_slide_anim"
- android:fromDegrees="25"
- android:pivotX="0"
- android:pivotY="0"
- android:toDegrees="0" />
</set> \ No newline at end of file
diff --git a/res/anim/display_with_bounce.xml b/res/anim/display_with_bounce.xml
index 3f5a5ad..0a51b53 100644
--- a/res/anim/display_with_bounce.xml
+++ b/res/anim/display_with_bounce.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/anim/cards_animation_up_right.xml b/res/anim/picture_animation.xml
index 7b4ef0d..acf7b83 100644
--- a/res/anim/cards_animation_up_right.xml
+++ b/res/anim/picture_animation.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,22 +15,10 @@
limitations under the License.
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/accelerate_interpolator" >
-
- <translate
- android:duration="@integer/cards_slide_anim"
- android:fromYDelta="100%p"
- android:toYDelta="0" />
+ android:interpolator="@android:anim/accelerate_decelerate_interpolator" >
<alpha
- android:duration="@integer/cards_slide_anim"
+ android:duration="400"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
-
- <rotate
- android:duration="@integer/cards_slide_anim"
- android:fromDegrees="-25"
- android:pivotX="100%"
- android:pivotY="0"
- android:toDegrees="0" />
</set> \ No newline at end of file
diff --git a/res/anim/pictures_layout_animation.xml b/res/anim/pictures_layout_animation.xml
new file mode 100644
index 0000000..95efcaf
--- /dev/null
+++ b/res/anim/pictures_layout_animation.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 The CyanogenMod 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.
+-->
+<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
+ android:animation="@anim/picture_animation"
+ android:delay="5%" />
diff --git a/res/animator/cards_rotate_animator.xml b/res/animator/cards_rotate_animator.xml
new file mode 100644
index 0000000..96bca35
--- /dev/null
+++ b/res/animator/cards_rotate_animator.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 Ahmed Nammari
+ Copyright (C) 2013 The CyanogenMod 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.
+-->
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:duration="@integer/cards_rotate_anim"
+ android:interpolator="@android:anim/decelerate_interpolator"
+ android:propertyName="rotationX"
+ android:repeatCount="0"
+ android:valueFrom="75"
+ android:valueTo="0"
+ android:valueType="floatType" />
diff --git a/res/drawable-xhdpi/wallpaper_thumb.png b/res/drawable-xhdpi/wallpaper_thumb.png
deleted file mode 100644
index 381b7ed..0000000
--- a/res/drawable-xhdpi/wallpaper_thumb.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/card.xml b/res/drawable/card.xml
index 3dd2638..1fe0b38 100644
--- a/res/drawable/card.xml
+++ b/res/drawable/card.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/drawable/holo_selector.xml b/res/drawable/holo_selector.xml
index 1f2f5b6..8ebf30e 100644
--- a/res/drawable/holo_selector.xml
+++ b/res/drawable/holo_selector.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/layout/album_info.xml b/res/layout/album_info.xml
index fc44edd..fa0e30e 100644
--- a/res/layout/album_info.xml
+++ b/res/layout/album_info.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,66 +14,73 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<org.cyanogenmod.wallpapers.photophase.widgets.AlbumInfo
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/PhotoPhase.Album">
+ android:layout_height="wrap_content">
- <ImageView android:id="@+id/album_thumbnail"
- android:layout_width="@dimen/album_size"
- android:layout_height="@dimen/album_size"
- android:scaleType="fitXY"
- android:layout_marginRight="@dimen/album_margin"
- android:contentDescription="@null"
- style="@style/PhotoPhase.Album.Thumbnail" />
-
- <TextView android:id="@+id/album_selected_items"
- android:layout_width="wrap_content"
+ <org.cyanogenmod.wallpapers.photophase.widgets.AlbumInfoView
+ android:id="@+id/album_info"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignRight="@id/album_thumbnail"
- android:layout_alignBottom="@id/album_thumbnail"
- style="@style/PhotoPhase.Notification" />
+ style="@style/PhotoPhase.Album">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_toRightOf="@id/album_thumbnail"
- android:layout_alignTop="@id/album_thumbnail"
- android:layout_alignBottom="@id/album_thumbnail"
- android:orientation="vertical"
- style="@style/PhotoPhase.Album.Info">
+ <ImageView android:id="@+id/album_thumbnail"
+ android:layout_width="@dimen/album_size"
+ android:layout_height="@dimen/album_size"
+ android:scaleType="fitXY"
+ android:layout_marginRight="@dimen/album_margin"
+ android:contentDescription="@null"
+ style="@style/PhotoPhase.Album.Thumbnail" />
- <TextView android:id="@+id/album_name"
+ <TextView android:id="@+id/album_selected_items"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingBottom="@dimen/album_info_margin"
- android:gravity="bottom"
- android:ellipsize="end"
- android:singleLine="true"
- style="@style/PhotoPhase.TextAppearance.Primary" />
+ android:layout_alignRight="@id/album_thumbnail"
+ android:layout_alignBottom="@id/album_thumbnail"
+ style="@style/PhotoPhase.Notification" />
- <TextView android:id="@+id/album_items"
+ <ImageView android:id="@+id/overflow_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingTop="@dimen/album_info_margin"
- android:gravity="top"
- android:ellipsize="end"
- android:singleLine="true"
- style="@style/PhotoPhase.TextAppearance.Secondary" />
+ android:layout_alignParentRight="true"
+ android:layout_alignBottom="@id/album_thumbnail"
+ android:layout_gravity="top"
+ android:padding="@dimen/small_padding"
+ android:contentDescription="@null"
+ style="@style/PhotoPhase.Album.MenuBar.Overflow" />
- </LinearLayout>
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_toRightOf="@id/album_thumbnail"
+ android:layout_toLeftOf="@id/overflow_button"
+ android:layout_alignTop="@id/album_thumbnail"
+ android:layout_alignBottom="@id/album_thumbnail"
+ android:orientation="vertical"
+ style="@style/PhotoPhase.Album.Info">
- <ImageView android:id="@+id/overflow"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_alignBottom="@id/album_thumbnail"
- android:layout_gravity="top"
- android:padding="@dimen/small_padding"
- android:contentDescription="@null"
- style="@style/PhotoPhase.Album.MenuBar.Overflow" />
+ <TextView android:id="@+id/album_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingBottom="@dimen/album_info_margin"
+ android:gravity="bottom"
+ android:ellipsize="end"
+ android:singleLine="true"
+ style="@style/PhotoPhase.TextAppearance.Primary" />
+
+ <TextView android:id="@+id/album_items"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="@dimen/album_info_margin"
+ android:gravity="top"
+ android:ellipsize="end"
+ android:singleLine="true"
+ style="@style/PhotoPhase.TextAppearance.Secondary" />
+
+ </LinearLayout>
-</org.cyanogenmod.wallpapers.photophase.widgets.AlbumInfo>
+ </org.cyanogenmod.wallpapers.photophase.widgets.AlbumInfoView>
+</FrameLayout>
diff --git a/res/layout/album_pictures.xml b/res/layout/album_pictures.xml
deleted file mode 100644
index 6b42ca1..0000000
--- a/res/layout/album_pictures.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2013 The CyanogenMod 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.
--->
-<org.cyanogenmod.wallpapers.photophase.widgets.AlbumPictures xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/card"
- style="@style/PhotoPhase.Album">
-
- <TextView android:id="@+id/album_pictures_title"
- android:layout_width="@dimen/album_size"
- android:layout_height="@dimen/album_title_height"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- style="@style/PhotoPhase.Album.Title" />
-
- <LinearLayout android:id="@+id/album_menubar"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/album_size"
- android:layout_marginLeft="@dimen/small_margin"
- android:layout_marginRight="@dimen/small_margin"
- android:layout_alignParentTop="true"
- android:layout_alignParentRight="true"
- android:orientation="vertical">
-
- <ImageView android:id="@+id/back"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:contentDescription="@null"
- style="@style/PhotoPhase.Album.MenuBar.Return" />
-
- <Space
- android:layout_width="0dp"
- android:layout_height="wrap_content"/>
-
- <ImageView android:id="@+id/overflow"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:contentDescription="@null"
- style="@style/PhotoPhase.Album.MenuBar.Overflow" />
- </LinearLayout>
-
- <org.cyanogenmod.wallpapers.photophase.widgets.PicturesView
- android:id="@+id/album_pictures_scroller"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="@dimen/album_title_height"
- android:layout_alignParentLeft="true"
- android:layout_toLeftOf="@id/album_menubar"
- android:fillViewport="true"
- android:scrollbars="none"
- android:layout_weight="1">
-
- <LinearLayout android:id="@+id/album_pictures_holder"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <!-- Pictures go here -->
-
- </LinearLayout>
- </org.cyanogenmod.wallpapers.photophase.widgets.PicturesView>
-
-</org.cyanogenmod.wallpapers.photophase.widgets.AlbumPictures>
diff --git a/res/layout/choose_disposition_fragment.xml b/res/layout/choose_disposition_fragment.xml
index 1267f2e..a72f148 100644
--- a/res/layout/choose_disposition_fragment.xml
+++ b/res/layout/choose_disposition_fragment.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/layout/choose_picture_fragment.xml b/res/layout/choose_picture_fragment.xml
index 1df53fa..8966c74 100644
--- a/res/layout/choose_picture_fragment.xml
+++ b/res/layout/choose_picture_fragment.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,20 +14,22 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<org.cyanogenmod.wallpapers.photophase.widgets.VerticalEndlessScroller
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fillViewport="true"
- android:scrollbars="none">
+ android:layout_height="match_parent">
- <org.cyanogenmod.wallpapers.photophase.widgets.CardLayout
+ <!-- Albums card view -->
+ <ListView
android:id="@+id/albums_panel"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:paddingTop="@dimen/small_margin" />
+ android:layout_height="match_parent"
+ android:persistentDrawingCache="animation|scrolling"
+ android:listSelector="@android:color/transparent"
+ android:divider="@android:color/transparent"
+ android:dividerHeight="@dimen/one_dp"
+ android:paddingTop="@dimen/small_margin"
+ android:paddingBottom="@dimen/small_padding"
+ android:scrollbars="none"/>
-</org.cyanogenmod.wallpapers.photophase.widgets.VerticalEndlessScroller>
+</FrameLayout>
diff --git a/res/layout/color_picker_pref_item.xml b/res/layout/color_picker_pref_item.xml
index 569da71..cca2efd 100644
--- a/res/layout/color_picker_pref_item.xml
+++ b/res/layout/color_picker_pref_item.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/layout/picture_item.xml b/res/layout/picture_item.xml
index dc33d6c..54f5409 100644
--- a/res/layout/picture_item.xml
+++ b/res/layout/picture_item.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,17 +14,24 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/picture"
- android:layout_width="@dimen/picture_size"
- android:layout_height="@dimen/picture_size"
- style="@style/PhotoPhase.Album.Picture">
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
- <ImageView android:id="@+id/picture_thumbnail"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="fitXY"
- android:background="@color/album_thumbnail_color"
- android:contentDescription="@null" />
+ <org.cyanogenmod.wallpapers.photophase.widgets.PictureItemView
+ android:id="@+id/picture"
+ android:layout_width="@dimen/picture_size"
+ android:layout_height="@dimen/picture_size"
+ style="@style/PhotoPhase.Album.Picture">
+
+ <ImageView android:id="@+id/picture_thumbnail"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="fitXY"
+ android:background="@color/album_thumbnail_color"
+ android:contentDescription="@null" />
+
+ </org.cyanogenmod.wallpapers.photophase.widgets.PictureItemView>
</FrameLayout>
diff --git a/res/layout/album.xml b/res/layout/pictures_view.xml
index 63aa9ad..141fde6 100644
--- a/res/layout/album.xml
+++ b/res/layout/pictures_view.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,19 +14,15 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<GridView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/album_pictures_view"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/small_margin">
-
- <include android:id="@+id/album_info"
- layout="@layout/album_info"
- android:layout_alignParentTop="true"
- android:layout_alignParentLeft="true" />
-
- <include android:id="@+id/album_pictures"
- layout="@layout/album_pictures"
- android:layout_alignParentTop="true"
- android:layout_alignParentLeft="true" />
-
-</RelativeLayout>
+ android:layout_height="match_parent"
+ android:persistentDrawingCache="animation|scrolling"
+ android:listSelector="@android:color/transparent"
+ android:divider="@android:color/transparent"
+ android:dividerHeight="@dimen/one_dp"
+ android:scrollbars="none"
+ android:layoutAnimation="@anim/pictures_layout_animation">
+</GridView>
diff --git a/res/layout/preference_widget_seekbar.xml b/res/layout/preference_widget_seekbar.xml
index 6aa0840..d1fdb1b 100644
--- a/res/layout/preference_widget_seekbar.xml
+++ b/res/layout/preference_widget_seekbar.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The Android Open Source Project
Copyright (C) 2013 The CyanogenMod Project
@@ -35,7 +35,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:minWidth="48dp"
- />
+ android:contentDescription="@null"/>
</LinearLayout>
<RelativeLayout
diff --git a/res/layout/preference_widget_seekbar_progress.xml b/res/layout/preference_widget_seekbar_progress.xml
index 531373b..d0035c1 100644
--- a/res/layout/preference_widget_seekbar_progress.xml
+++ b/res/layout/preference_widget_seekbar_progress.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The Android Open Source Project
Copyright (C) 2013 The CyanogenMod Project
diff --git a/res/menu/album_actions.xml b/res/menu/album_actions.xml
index 2785178..004f3db 100644
--- a/res/menu/album_actions.xml
+++ b/res/menu/album_actions.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -21,4 +21,10 @@
<item android:id="@+id/mnu_deselect_album"
android:title="@string/mnu_deselect_album"
android:showAsAction="never" />
+ <item android:id="@+id/mnu_select_all"
+ android:title="@string/mnu_select_all"
+ android:showAsAction="never" />
+ <item android:id="@+id/mnu_deselect_all"
+ android:title="@string/mnu_deselect_all"
+ android:showAsAction="never" />
</menu>
diff --git a/res/menu/albums.xml b/res/menu/albums.xml
index b5f3af6..1f979d9 100644
--- a/res/menu/albums.xml
+++ b/res/menu/albums.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +15,8 @@
limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:id="@+id/mnu_invert_all"
- android:title="@string/mnu_invert_all"
+ <item android:id="@+id/mnu_invert"
+ android:title="@string/mnu_invert"
android:icon="@drawable/ic_invert"
android:showAsAction="ifRoom|withText" />
<item android:id="@+id/mnu_restore"
diff --git a/res/menu/dispositions.xml b/res/menu/dispositions.xml
index 8fd7a27..0047a6b 100644
--- a/res/menu/dispositions.xml
+++ b/res/menu/dispositions.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/menu/main.xml b/res/menu/main.xml
index fbc301a..71dd90b 100644
--- a/res/menu/main.xml
+++ b/res/menu/main.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/raw/mix_fragment_shader.glsl b/res/raw/mix_fragment_shader.glsl
deleted file mode 100644
index df80f89..0000000
--- a/res/raw/mix_fragment_shader.glsl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod 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.
- */
-
-precision mediump float;
-
-varying vec2 vTextureCoord;
-uniform sampler2D sTexture1;
-uniform sampler2D sTexture2;
-
-void main() {
- vec4 color1 = texture2D(sTexture1, vTextureCoord);
- vec4 color2 = texture2D(sTexture1, vTextureCoord);
- gl_FragColor = color2 * color1;
-}
diff --git a/res/raw/mix_vertex_shader.glsl b/res/raw/mix_vertex_shader.glsl
deleted file mode 100644
index dad4d5a..0000000
--- a/res/raw/mix_vertex_shader.glsl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod 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.
- */
-
-uniform mat4 uMVPMatrix;
-
-attribute vec4 aPosition;
-attribute vec2 aTextureCoord;
-
-varying vec2 vTextureCoord;
-
-void main() {
- gl_Position = uMVPMatrix * aPosition;
- vTextureCoord = aTextureCoord;
-}
diff --git a/res/values-es/plurals.xml b/res/values-es/plurals.xml
index 9865d84..448f035 100644
--- a/res/values-es/plurals.xml
+++ b/res/values-es/plurals.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 4687af0..f6bb32d 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,8 +24,7 @@
<string name="mnu_settings">Ajustes</string>
<string name="mnu_select_all">Seleccionar todo</string>
<string name="mnu_deselect_all">Deseleccionar todo</string>
- <string name="mnu_invert_all">Invertir todo</string>
- <string name="mnu_invert_selection">Invertir selección</string>
+ <string name="mnu_invert">Invertir</string>
<string name="mnu_select_album">Seleccionar álbum</string>
<string name="mnu_deselect_album">Deseleccionar álbum</string>
<string name="pref_general">General</string>
@@ -75,7 +74,6 @@
<string name="pref_about_summary">PhotoPhase v<xliff:g id="version">%1$s</xliff:g>\nCopyright \u00A9 2013 The CyanogenMod Project</string>
<string name="refresh_intervals_disabled">Deshabilitado</string>
<string name="refresh_intervals_1h">1 hora</string>
- <string name="refresh_intervals_2h">2 horas</string>
<string name="refresh_intervals_4h">4 horas</string>
<string name="refresh_intervals_1d">1 día</string>
<string name="refresh_intervals_2d">2 días</string>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 1fc1048..7995c82 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/values-large/dimens.xml b/res/values-large/dimens.xml
index e03dcfb..4eff78c 100644
--- a/res/values-large/dimens.xml
+++ b/res/values-large/dimens.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/drawable/frame.xml b/res/values-sw600dp-port/dimens.xml
index a3fecaf..dc99052 100644
--- a/res/drawable/frame.xml
+++ b/res/values-sw600dp-port/dimens.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <stroke android:width="1dp" android:color="#000" />
- <solid android:color="@android:color/darker_gray"/>
-</shape>
-
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <dimen name="picture_size">96dp</dimen>
+</resources>
diff --git a/res/menu/pictures_actions.xml b/res/values-sw600dp/dimens.xml
index bfb95e2..dc99052 100644
--- a/res/menu/pictures_actions.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,14 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:id="@+id/mnu_select_all"
- android:title="@string/mnu_select_all"
- android:showAsAction="never" />
- <item android:id="@+id/mnu_deselect_all"
- android:title="@string/mnu_deselect_all"
- android:showAsAction="never" />
- <item android:id="@+id/mnu_invert_selection"
- android:title="@string/mnu_invert_selection"
- android:showAsAction="never" />
-</menu>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <dimen name="picture_size">96dp</dimen>
+</resources>
diff --git a/res/values-sw720dp-port/dimens.xml b/res/values-sw720dp-port/dimens.xml
new file mode 100644
index 0000000..71a0db2
--- /dev/null
+++ b/res/values-sw720dp-port/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 The CyanogenMod 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <dimen name="picture_size">100dp</dimen>
+</resources>
diff --git a/res/values-sw720dp-w1280dp/dimens.xml b/res/values-sw720dp-w1280dp/dimens.xml
index 19adc8d..e2c9cc9 100644
--- a/res/values-sw720dp-w1280dp/dimens.xml
+++ b/res/values-sw720dp-w1280dp/dimens.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 3092324..6651de4 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,5 +15,6 @@
limitations under the License.
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <dimen name="picture_size">116dp</dimen>
<dimen name="preference_icon_minWidth">56dp</dimen>
</resources>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 192fa65..3ab44b2 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/values/colors.xml b/res/values/colors.xml
index e8cc096..9f80bce 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +19,7 @@
<color name="wallpaper_background_color">#ff202020</color>
<color name="wallpaper_overlay_color">#aa202020</color>
- <color name="album_thumbnail_color">#aa202020</color>
+ <color name="album_thumbnail_color">#aa606060</color>
<color name="text_color">#404040</color>
<color name="notification_text_color">#ffffffff</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index 1a3b9c9..dc7c0f9 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index ff148dc..1c6e518 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,12 +27,11 @@
<dimen name="album_margin">16dp</dimen>
<dimen name="album_info_margin">2dp</dimen>
- <dimen name="album_title_height">20dp</dimen>
<dimen name="album_title_margin_top">38dp</dimen>
<dimen name="album_title_margin_left">-38dp</dimen>
<dimen name="picture_size">80dp</dimen>
- <dimen name="picture_vertical_margin">8dp</dimen>
+ <dimen name="picture_vertical_margin">4dp</dimen>
<dimen name="picture_horizontal_margin">4dp</dimen>
<dimen name="notification_min_width">32dp</dimen>
@@ -44,11 +43,11 @@
<dimen name="default_margin">16dp</dimen>
<dimen name="small_margin">8dp</dimen>
<dimen name="small_padding">5dp</dimen>
+ <dimen name="one_dp">1dp</dimen>
<dimen name="disposition_frame_margin">12dp</dimen>
<dimen name="disposition_frame_padding">1dp</dimen>
<dimen name="disposition_advise_frame_padding">4dp</dimen>
- <dimen name="resize_frame_padding">12dp</dimen>
<dimen name="resize_frame_extra_handling_space">16dp</dimen>
</resources>
diff --git a/res/values/integers.xml b/res/values/integers.xml
index fc94b4d..64f948c 100644
--- a/res/values/integers.xml
+++ b/res/values/integers.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,7 +15,10 @@
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <integer name="cards_slide_anim">1000</integer>
+ <integer name="cards_slide_up_anim">600</integer>
+ <integer name="cards_rotate_anim">800</integer>
+ <integer name="pictures_anim_in">600</integer>
+ <integer name="pictures_anim_out">400</integer>
<integer name="disposition_show_anim">600</integer>
<integer name="disposition_hide_anim">400</integer>
</resources>
diff --git a/res/values/plurals.xml b/res/values/plurals.xml
index 6e850be..b828ec7 100644
--- a/res/values/plurals.xml
+++ b/res/values/plurals.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b35a1a9..7ec74dc 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -33,8 +33,7 @@
<string name="mnu_settings">Settings</string>
<string name="mnu_select_all">Select all</string>
<string name="mnu_deselect_all">Deselect all</string>
- <string name="mnu_invert_all">Invert all</string>
- <string name="mnu_invert_selection">Invert selection</string>
+ <string name="mnu_invert">Invert</string>
<string name="mnu_select_album">Select album</string>
<string name="mnu_deselect_album">Deselect album</string>
@@ -92,7 +91,6 @@
<!-- Refresh intervals -->
<string name="refresh_intervals_disabled">Disabled</string>
<string name="refresh_intervals_1h">1 hour</string>
- <string name="refresh_intervals_2h">2 hours</string>
<string name="refresh_intervals_4h">4 hours</string>
<string name="refresh_intervals_1d">1 day</string>
<string name="refresh_intervals_2d">2 days</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 6a37f3f..894e9e5 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/xml/preferences_general.xml b/res/xml/preferences_general.xml
index 37eb08d..7e2e4b3 100644
--- a/res/xml/preferences_general.xml
+++ b/res/xml/preferences_general.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/xml/preferences_headers.xml b/res/xml/preferences_headers.xml
index 856fe6c..15cd61f 100644
--- a/res/xml/preferences_headers.xml
+++ b/res/xml/preferences_headers.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/xml/preferences_layout.xml b/res/xml/preferences_layout.xml
index 8ef4e8f..02d12e3 100644
--- a/res/xml/preferences_layout.xml
+++ b/res/xml/preferences_layout.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/xml/preferences_media.xml b/res/xml/preferences_media.xml
index 6d1badc..4325c3c 100644
--- a/res/xml/preferences_media.xml
+++ b/res/xml/preferences_media.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/res/xml/wallpaper.xml b/res/xml/wallpaper.xml
index 068925e..45ad9a1 100644
--- a/res/xml/wallpaper.xml
+++ b/res/xml/wallpaper.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!--
+<!--
Copyright (C) 2013 The CyanogenMod Project
Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/src/org/cyanogenmod/wallpapers/photophase/MediaPictureDiscoverer.java b/src/org/cyanogenmod/wallpapers/photophase/MediaPictureDiscoverer.java
index 4228abf..f45dcd6 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/MediaPictureDiscoverer.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/MediaPictureDiscoverer.java
@@ -264,7 +264,7 @@ public class MediaPictureDiscoverer {
}
}
- /*package*/ final Context mContext;
+ final Context mContext;
private final OnMediaPictureDiscoveredListener mCallback;
private AsyncDiscoverTask mTask;
diff --git a/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseRenderer.java b/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseRenderer.java
index f57d53b..c307023 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseRenderer.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseRenderer.java
@@ -62,25 +62,25 @@ public class PhotoPhaseRenderer implements GLSurfaceView.Renderer {
private final long mInstance;
private static long sInstances;
- /*package*/ final Context mContext;
- /*package*/ EffectContext mEffectContext;
+ final Context mContext;
+ EffectContext mEffectContext;
private final Handler mHandler;
- /*package*/ final GLESSurfaceDispatcher mDispatcher;
- /*package*/ TextureManager mTextureManager;
+ final GLESSurfaceDispatcher mDispatcher;
+ TextureManager mTextureManager;
- /*package*/ PhotoPhaseWallpaperWorld mWorld;
- /*package*/ ColorShape mOverlay;
- /*package*/ OopsShape mOopsShape;
+ PhotoPhaseWallpaperWorld mWorld;
+ ColorShape mOverlay;
+ OopsShape mOopsShape;
- /*package*/ long mLastRunningTransition;
+ long mLastRunningTransition;
private long mLastTouchTime;
private static final long TOUCH_BARRIER_TIME = 1000L;
- /*package*/ int mWidth = -1;
- /*package*/ int mHeight = -1;
+ int mWidth = -1;
+ int mHeight = -1;
private int mStatusBarHeight = 0;
- /*package*/ int mMeasuredHeight = -1;
+ int mMeasuredHeight = -1;
private final float[] mMVPMatrix = new float[16];
private final float[] mProjMatrix = new float[16];
@@ -88,7 +88,7 @@ public class PhotoPhaseRenderer implements GLSurfaceView.Renderer {
private final Object mDrawing = new Object();
- /*package*/ final Object mMediaSync = new Object();
+ final Object mMediaSync = new Object();
private PendingIntent mMediaScanIntent;
private final BroadcastReceiver mSettingsChangedReceiver = new BroadcastReceiver() {
@@ -383,13 +383,13 @@ public class PhotoPhaseRenderer implements GLSurfaceView.Renderer {
/**
* Method that deselect the current transition
*/
- /*package*/ synchronized void deselectCurrentTransition() {
+ synchronized void deselectCurrentTransition() {
mHandler.removeCallbacks(mTransitionThread);
mWorld.deselectTransition(mMVPMatrix);
mLastRunningTransition = 0;
}
- /*package*/ void scheduleOrCancelMediaScan() {
+ void scheduleOrCancelMediaScan() {
int interval = Preferences.Media.getRefreshFrecuency();
if (interval != Preferences.Media.MEDIA_RELOAD_DISABLED) {
scheduleMediaScan(interval);
diff --git a/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseWallpaper.java b/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseWallpaper.java
index 625212c..5152bc8 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseWallpaper.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/PhotoPhaseWallpaper.java
@@ -96,7 +96,7 @@ public class PhotoPhaseWallpaper
class PhotoPhaseWallpaperEngine extends GLES20WallpaperService.GLES20Engine {
private final Handler mHandler;
- /*package*/ final ActivityManager mActivityManager;
+ final ActivityManager mActivityManager;
/**
* Constructor of <code>PhotoPhaseWallpaperEngine<code>
diff --git a/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java b/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java
index 6c8de05..3731a1b 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/TextureManager.java
@@ -59,8 +59,8 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
BackgroundPictureLoaderThread mBackgroundTask;
/*protected*/ final MediaPictureDiscoverer mPictureDiscoverer;
- /*package*/ Rect mScreenDimensions;
- /*package*/ Rect mDimensions;
+ Rect mScreenDimensions;
+ Rect mDimensions;
final GLESSurfaceDispatcher mDispatcher;
@@ -73,7 +73,7 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
/**
* A private runnable that will run in the GLThread
*/
- /*package*/ class PictureDispatcher implements Runnable {
+ class PictureDispatcher implements Runnable {
File mImage;
GLESTextureInfo ti = null;
final Object mWait = new Object();
@@ -428,7 +428,7 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
* @param ti The original texture information
* @param effect The effect to apply to the destination picture
*/
- /*package*/ void fixAspectRatio(TextureRequestor requestor, GLESTextureInfo ti) {
+ void fixAspectRatio(TextureRequestor requestor, GLESTextureInfo ti) {
// Check if we have to apply any correction to the image
if (Preferences.General.isFixAspectRatio()) {
// Transform requestor dimensions to screen dimensions
@@ -472,7 +472,7 @@ public class TextureManager implements OnMediaPictureDiscoveredListener {
boolean mRun;
boolean mTaskPaused;
- /*package*/ boolean mEmpty;
+ boolean mEmpty;
private final List<File> mNewImages;
private final List<File> mUsedImages;
diff --git a/src/org/cyanogenmod/wallpapers/photophase/adapters/AlbumCardUiAdapter.java b/src/org/cyanogenmod/wallpapers/photophase/adapters/AlbumCardUiAdapter.java
new file mode 100644
index 0000000..b321b73
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/adapters/AlbumCardUiAdapter.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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 org.cyanogenmod.wallpapers.photophase.adapters;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+
+import org.cyanogenmod.wallpapers.photophase.R;
+import org.cyanogenmod.wallpapers.photophase.model.Album;
+import org.cyanogenmod.wallpapers.photophase.widgets.AlbumInfoView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An implementation of {@link ArrayAdapter} supporting "Google Now Card Layout" like layout
+ */
+public class AlbumCardUiAdapter extends ArrayAdapter<Album> {
+
+ /**
+ * A class that conforms with the ViewHolder pattern to performance
+ * the list view rendering.
+ */
+ private static class ViewHolder {
+ public ViewHolder() {
+ super();
+ }
+ AlbumInfoView mAlbumInfoView;
+ Animation mCardAnimation;
+ Animator mCardAnimator;
+ }
+
+ private List<Album> mData = new ArrayList<Album>();
+
+ private AlbumInfoView.CallbacksListener mAlbumInfoCallback;
+
+ /**
+ * Constructor of <code>AlbumCardUiAdapter</code>.
+ *
+ * @param context The current context
+ * @param parent The adapter view
+ * @param data The array with all the album data
+ * @param callback The album info view callback
+ */
+ public AlbumCardUiAdapter(Context context, AdapterView<?> parent, List<Album> data,
+ AlbumInfoView.CallbacksListener callback) {
+ super(context, R.id.album_name, data);
+ mData = data;
+ mAlbumInfoCallback = callback;
+ }
+
+ /**
+ * Method that dispose the elements of the adapter.
+ */
+ public void dispose() {
+ clear();
+ this.mData = null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+
+ // Retrieve album
+ final Album album = this.mData.get(position);
+
+ // Check to reuse view
+ View v = convertView;
+ if (v == null) {
+ //Create the view holder
+ LayoutInflater li =
+ (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = li.inflate(R.layout.album_info, parent, false);
+
+ // Create the controller for the view
+ ViewHolder viewHolder = new ViewHolder();
+ viewHolder.mAlbumInfoView = (AlbumInfoView)v.findViewById(R.id.album_info);
+ viewHolder.mAlbumInfoView.setAlbum(album);
+ viewHolder.mAlbumInfoView.addCallBackListener(mAlbumInfoCallback);
+ v.setTag(viewHolder);
+ }
+
+ // Retrieve the view holder
+ ViewHolder viewHolder = (ViewHolder)v.getTag();
+
+ // Retrieve the view holder and update the view
+ viewHolder.mAlbumInfoView.updateView(album);
+
+ // Animate the view?
+ if (!album.isDisplayed()) {
+ album.setDisplayed(true);
+
+ // Reset the animation
+ if (viewHolder.mCardAnimation != null) {
+ viewHolder.mCardAnimation.cancel();
+ }
+ if (viewHolder.mCardAnimator != null) {
+ viewHolder.mCardAnimator.cancel();
+ }
+
+ // Card Animation
+ viewHolder.mCardAnimation = AnimationUtils.loadAnimation(
+ getContext(), R.anim.cards_slide_up);
+ v.startAnimation(viewHolder.mCardAnimation);
+ viewHolder.mCardAnimator = AnimatorInflater.loadAnimator(getContext(),
+ R.animator.cards_rotate_animator);
+ viewHolder.mCardAnimator.setTarget(v);
+ viewHolder.mCardAnimator.start();
+ }
+
+ // Return the view
+ return v;
+ }
+
+}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/adapters/AlbumPictureAdapter.java b/src/org/cyanogenmod/wallpapers/photophase/adapters/AlbumPictureAdapter.java
new file mode 100644
index 0000000..addc298
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/adapters/AlbumPictureAdapter.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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 org.cyanogenmod.wallpapers.photophase.adapters;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+
+import org.cyanogenmod.wallpapers.photophase.R;
+import org.cyanogenmod.wallpapers.photophase.model.Picture;
+import org.cyanogenmod.wallpapers.photophase.widgets.PictureItemView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An implementation of {@link ArrayAdapter} an album picture
+ */
+public class AlbumPictureAdapter extends ArrayAdapter<Picture> {
+
+ /**
+ * A class that conforms with the ViewHolder pattern to performance
+ * the list view rendering.
+ */
+ private static class ViewHolder {
+ public ViewHolder() {
+ super();
+ }
+ PictureItemView mPictureItemView;
+ }
+
+ private List<Picture> mData = new ArrayList<Picture>();
+ private AdapterView<?> mParent;
+
+ /**
+ * Constructor of <code>AlbumPictureAdapter</code>.
+ *
+ * @param context The current context
+ * @param data The pictures data
+ */
+ public AlbumPictureAdapter(Context context, List<Picture> data, AdapterView<?> parent) {
+ super(context, R.id.picture_thumbnail, data);
+ mData = data;
+ mParent = parent;
+ }
+
+ /**
+ * Method that dispose the elements of the adapter.
+ */
+ public void dispose() {
+ clear();
+ this.mData = null;
+ }
+
+ @Override
+ public void notifyDataSetChanged() {
+ int start = mParent.getFirstVisiblePosition();
+ int last = mParent.getLastVisiblePosition();
+ for (int i = start; i <= last; i++) {
+ View v = mParent.getChildAt(i);
+ getView(i, v, mParent, false);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return getView(position, convertView, parent, true);
+ }
+
+ /**
+ * Method that returns a view for a position
+ *
+ * @param position The position
+ * @param convertView A reusable view or null
+ * @param parent The parent of the view
+ * @param refreshIcon If the view should refresh its icon
+ * @return View The view
+ */
+ private View getView(int position, View convertView, ViewGroup parent, boolean refreshIcon) {
+ final Picture picture = this.mData.get(position);
+
+ // Check to reuse view
+ View v = convertView;
+ if (v == null) {
+ //Create the view holder
+ LayoutInflater li =
+ (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = li.inflate(R.layout.picture_item, parent, false);
+
+ // Create the controller for the view
+ ViewHolder viewHolder = new ViewHolder();
+ viewHolder.mPictureItemView = (PictureItemView)v.findViewById(R.id.picture);
+ viewHolder.mPictureItemView.setPicture(picture);
+ v.setTag(viewHolder);
+ }
+
+ // Retrieve the view holder
+ ViewHolder viewHolder = (ViewHolder)v.getTag();
+
+ // Retrieve the view holder and update the view
+ viewHolder.mPictureItemView.updateView(picture, refreshIcon);
+
+ // Return the view
+ return v;
+ }
+
+}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/animations/AlbumsFlip3dAnimationController.java b/src/org/cyanogenmod/wallpapers/photophase/animations/Flip3dAnimationController.java
index 228f827..69f023d 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/animations/AlbumsFlip3dAnimationController.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/animations/Flip3dAnimationController.java
@@ -16,20 +16,14 @@
package org.cyanogenmod.wallpapers.photophase.animations;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
-import org.cyanogenmod.wallpapers.photophase.model.Album;
-import org.cyanogenmod.wallpapers.photophase.widgets.AlbumInfo;
-import org.cyanogenmod.wallpapers.photophase.widgets.AlbumPictures;
-import org.cyanogenmod.wallpapers.photophase.widgets.AlbumPictures.CallbacksListener;
-
/**
- * A class that manages a flip 3d effect of an album
+ * A class that manages a flip 3d effect of two views
*/
-public class AlbumsFlip3dAnimationController {
+public class Flip3dAnimationController {
private static final int DURATION = 200;
@@ -37,13 +31,15 @@ public class AlbumsFlip3dAnimationController {
View mBack;
boolean mFrontFace;
+ final Object mLock = new Object();
+
/**
- * Constructor of <code>AlbumsFlip3dAnimationController</code>
+ * Constructor of <code>Flip3dAnimationController</code>
*
* @param front The front view
* @param back The back view
*/
- public AlbumsFlip3dAnimationController(AlbumInfo front, AlbumPictures back) {
+ public Flip3dAnimationController(View front, View back) {
super();
mFront = front;
mBack = back;
@@ -51,45 +47,48 @@ public class AlbumsFlip3dAnimationController {
mFrontFace = true;
}
+ public boolean isFrontFace() {
+ return mFrontFace;
+ }
+
/**
- * Method that register the controller
+ * Method that reset the controller
*/
- public void register() {
- getFrontView().setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- getBackView().setVisibility(View.INVISIBLE);
- applyAnimation(false);
- }
- });
- ((AlbumPictures)getBackView()).addCallBackListener(new CallbacksListener() {
- @Override
- public void onBackButtonClick(View v) {
- getBackView().setVisibility(View.INVISIBLE);
- applyAnimation(true);
- }
-
- @Override
- public void onSelectionChanged(Album album) {
- // Ignore
- }
- });
+ public void reset() {
+ changeToFrontFace(true);
}
/**
- * Method that unregister the controller
+ * Method that change the view to the front face
+ *
+ * @param animate Do with animation
*/
- public void unregister() {
- getFrontView().setOnClickListener(null);
- getBackView().setOnClickListener(null);
+ public void changeToFrontFace(boolean animate) {
+ if (!mFrontFace) {
+ if (animate) {
+ applyAnimation(true);
+ } else {
+ mBack.setVisibility(View.GONE);
+ mFront.setVisibility(View.VISIBLE);
+ mFrontFace = true;
+ }
+ }
}
/**
- * Method that reset the controller
+ * Method that change the view to the back face
+ *
+ * @param animate Do with animation
*/
- public void reset() {
- if (!mFrontFace) {
- applyAnimation(true);
+ public void changeToBackFace(boolean animate) {
+ if (mFrontFace) {
+ if (animate) {
+ applyAnimation(true);
+ } else {
+ mFront.setVisibility(View.GONE);
+ mBack.setVisibility(View.VISIBLE);
+ mFrontFace = false;
+ }
}
}
@@ -98,11 +97,11 @@ public class AlbumsFlip3dAnimationController {
*
* @param inverse Applies the inverse animation
*/
- /*package*/ void applyAnimation(boolean inverse) {
+ void applyAnimation(boolean inverse) {
applyTransformation(getFrontView(), 0, 90 * (inverse ? -1 : 1), true);
}
- /*package*/ void applyTransformation(final View v, float start, float end, final boolean step1) {
+ void applyTransformation(final View v, float start, float end, final boolean step1) {
final float centerX = v.getWidth() / 2.0f;
final float centerY = v.getHeight() / 2.0f;
@@ -117,8 +116,6 @@ public class AlbumsFlip3dAnimationController {
if (!step1) {
getBackView().setVisibility(View.VISIBLE);
}
- getFrontView().setOnClickListener(null);
- getBackView().setOnClickListener(null);
}
@Override
@@ -128,24 +125,16 @@ public class AlbumsFlip3dAnimationController {
@Override
public void onAnimationEnd(Animation animation) {
- getFrontView().setAnimation(null);
- getBackView().setAnimation(null);
- if (step1) {
- getFrontView().setVisibility(View.INVISIBLE);
- applyTransformation(getBackView(), -90 * (!mFrontFace ? -1 : 1), 0, false);
- } else {
- mFrontFace = !mFrontFace;
- getBackView().setVisibility(View.GONE);
- if (mFrontFace) {
- getFrontView().setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- getBackView().setVisibility(View.INVISIBLE);
- applyAnimation(false);
- }
- });
+ synchronized (mLock) {
+ getFrontView().setAnimation(null);
+ getBackView().setAnimation(null);
+ if (step1) {
+ getFrontView().setVisibility(View.INVISIBLE);
+ applyTransformation(getBackView(),
+ -90 * (!mFrontFace ? -1 : 1), 0, false);
} else {
- ((AlbumPictures)getFrontView()).onShow();
+ mFrontFace = !mFrontFace;
+ getBackView().setVisibility(View.GONE);
}
}
}
@@ -153,11 +142,11 @@ public class AlbumsFlip3dAnimationController {
v.startAnimation(anim);
}
- /*package*/ View getFrontView() {
+ View getFrontView() {
return mFrontFace ? mFront : mBack;
}
- /*package*/ View getBackView() {
+ View getBackView() {
return !mFrontFace ? mFront : mBack;
}
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/animations/Rotate3dAnimation.java b/src/org/cyanogenmod/wallpapers/photophase/animations/Rotate3dAnimation.java
new file mode 100644
index 0000000..814ef0f
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/animations/Rotate3dAnimation.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.cyanogenmod.wallpapers.photophase.animations;
+
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+import android.graphics.Camera;
+import android.graphics.Matrix;
+
+/**
+ * An animation that rotates the view on the Y axis between two specified angles.
+ * This animation also adds a translation on the Z axis (depth) to improve the effect.
+ */
+public class Rotate3dAnimation extends Animation {
+ private final float mFromDegrees;
+ private final float mToDegrees;
+ private final float mCenterX;
+ private final float mCenterY;
+ private final float mDepthZ;
+ private final boolean mReverse;
+ private Camera mCamera;
+
+ /**
+ * Creates a new 3D rotation on the Y axis. The rotation is defined by its
+ * start angle and its end angle. Both angles are in degrees. The rotation
+ * is performed around a center point on the 2D space, definied by a pair
+ * of X and Y coordinates, called centerX and centerY. When the animation
+ * starts, a translation on the Z axis (depth) is performed. The length
+ * of the translation can be specified, as well as whether the translation
+ * should be reversed in time.
+ *
+ * @param fromDegrees the start angle of the 3D rotation
+ * @param toDegrees the end angle of the 3D rotation
+ * @param centerX the X center of the 3D rotation
+ * @param centerY the Y center of the 3D rotation
+ * @param reverse true if the translation should be reversed, false otherwise
+ */
+ public Rotate3dAnimation(float fromDegrees, float toDegrees,
+ float centerX, float centerY, float depthZ, boolean reverse) {
+ mFromDegrees = fromDegrees;
+ mToDegrees = toDegrees;
+ mCenterX = centerX;
+ mCenterY = centerY;
+ mDepthZ = depthZ;
+ mReverse = reverse;
+ }
+
+ @Override
+ public void initialize(int width, int height, int parentWidth, int parentHeight) {
+ super.initialize(width, height, parentWidth, parentHeight);
+ mCamera = new Camera();
+ }
+
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ final float fromDegrees = mFromDegrees;
+ float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
+
+ final float centerX = mCenterX;
+ final float centerY = mCenterY;
+ final Camera camera = mCamera;
+
+ final Matrix matrix = t.getMatrix();
+
+ camera.save();
+ if (mReverse) {
+ camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
+ } else {
+ camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
+ }
+ camera.rotateY(degrees);
+ camera.getMatrix(matrix);
+ camera.restore();
+
+ matrix.preTranslate(-centerX, -centerY);
+ matrix.postTranslate(centerX, centerY);
+ }
+}
+
diff --git a/src/org/cyanogenmod/wallpapers/photophase/model/Album.java b/src/org/cyanogenmod/wallpapers/photophase/model/Album.java
index 83f067d..0c1c2a2 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/model/Album.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/model/Album.java
@@ -24,16 +24,20 @@ import java.util.List;
/**
* A class that represents an album
*/
-public class Album implements Comparable<Album>, Cloneable {
+public class Album implements Comparable<Album>, Cloneable {
private Drawable mIcon;
private String mPath;
private String mName;
private String mDate;
private boolean mSelected;
- private List<String> mItems;
+ private List<Picture> mItems;
+ // We have this array for performance access. Do not forget to sync with Picture#selected
private List<String> mSelectedItems;
+ // Ui properties
+ private boolean mDisplayed = false;
+
public Drawable getIcon() {
return mIcon;
}
@@ -74,11 +78,11 @@ public class Album implements Comparable<Album>, Cloneable {
this.mSelected = selected;
}
- public List<String> getItems() {
+ public List<Picture> getItems() {
return mItems;
}
- public void setItems(List<String> items) {
+ public void setItems(List<Picture> items) {
this.mItems = items;
}
@@ -90,6 +94,14 @@ public class Album implements Comparable<Album>, Cloneable {
this.mSelectedItems = selectedItems;
}
+ public boolean isDisplayed() {
+ return mDisplayed;
+ }
+
+ public void setDisplayed(boolean mDisplayed) {
+ this.mDisplayed = mDisplayed;
+ }
+
@Override
public int compareTo(Album another) {
return mPath.compareTo(another.mPath);
@@ -102,9 +114,10 @@ public class Album implements Comparable<Album>, Cloneable {
album.mPath = mPath;
album.mName = mName;
album.mDate = mDate;
- album.mItems = new ArrayList<String>(mItems);
+ album.mItems = new ArrayList<Picture>(mItems);
album.mSelectedItems = new ArrayList<String>(mSelectedItems);
album.mSelected = mSelected;
+ album.mDisplayed = mDisplayed;
return album;
}
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/model/Picture.java b/src/org/cyanogenmod/wallpapers/photophase/model/Picture.java
new file mode 100644
index 0000000..76b1bb6
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/model/Picture.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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 org.cyanogenmod.wallpapers.photophase.model;
+
+import java.io.File;
+
+/**
+ * A class that represents a picture
+ */
+public class Picture implements Comparable<Picture>, Cloneable {
+
+ private String mPath;
+ private boolean mSelected;
+
+ public Picture(String path, boolean selected) {
+ super();
+ this.mPath = path;
+ this.mSelected = selected;
+ }
+
+ public String getPath() {
+ return mPath;
+ }
+
+ public void setPath(String path) {
+ this.mPath = path;
+ }
+
+ public boolean isSelected() {
+ return mSelected;
+ }
+
+ public void setSelected(boolean selected) {
+ this.mSelected = selected;
+ }
+
+ public String getName() {
+ return new File(mPath).getName();
+ }
+
+ @Override
+ public int compareTo(Picture another) {
+ return mPath.compareTo(another.mPath);
+ }
+
+ @Override
+ public Object clone() {
+ return new Picture(mPath, mSelected);
+ }
+}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/ChoosePicturesFragment.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/ChoosePicturesFragment.java
index 6e41308..00d75a6 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/preferences/ChoosePicturesFragment.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/ChoosePicturesFragment.java
@@ -16,7 +16,9 @@
package org.cyanogenmod.wallpapers.photophase.preferences;
-import android.content.ContentResolver;
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -24,6 +26,8 @@ import android.database.Cursor;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
import android.preference.PreferenceFragment;
import android.provider.MediaStore;
import android.util.Log;
@@ -32,19 +36,30 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.FrameLayout;
+import android.widget.GridView;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
import org.cyanogenmod.wallpapers.photophase.R;
-import org.cyanogenmod.wallpapers.photophase.animations.AlbumsFlip3dAnimationController;
+import org.cyanogenmod.wallpapers.photophase.adapters.AlbumCardUiAdapter;
+import org.cyanogenmod.wallpapers.photophase.adapters.AlbumPictureAdapter;
import org.cyanogenmod.wallpapers.photophase.model.Album;
+import org.cyanogenmod.wallpapers.photophase.model.Picture;
import org.cyanogenmod.wallpapers.photophase.preferences.PreferencesProvider.Preferences;
-import org.cyanogenmod.wallpapers.photophase.widgets.AlbumInfo;
-import org.cyanogenmod.wallpapers.photophase.widgets.AlbumPictures;
-import org.cyanogenmod.wallpapers.photophase.widgets.CardLayout;
-import org.cyanogenmod.wallpapers.photophase.widgets.VerticalEndlessScroller;
-import org.cyanogenmod.wallpapers.photophase.widgets.VerticalEndlessScroller.OnEndScrollListener;
+import org.cyanogenmod.wallpapers.photophase.widgets.AlbumInfoView;
+import org.cyanogenmod.wallpapers.photophase.widgets.PictureItemView;
import java.io.File;
+import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
@@ -56,25 +71,28 @@ import java.util.Set;
/**
* A fragment class for select the picture that will be displayed on the wallpaper
*/
-public class ChoosePicturesFragment extends PreferenceFragment implements OnEndScrollListener {
+public class ChoosePicturesFragment extends PreferenceFragment
+ implements AlbumInfoView.CallbacksListener, OnClickListener {
private static final String TAG = "ChoosePicturesFragment";
private static final boolean DEBUG = false;
- private static final int AMOUNT_OF_ADDED_STEPS = 5;
+ private static final int PROGRESS_STEPS = 5;
+
+ // The album loader task
+ private final AsyncTask<Void, Album, Void> mTask = new AsyncTask<Void, Album, Void>() {
+
+ private DateFormat mDateFormat;
- private final AsyncTask<Void, Album, Void> mAlbumsLoaderTask = new AsyncTask<Void, Album, Void>() {
/**
* {@inheritDoc}
*/
@Override
protected Void doInBackground(Void... params) {
// Query all the external content and classify the pictures in albums and load the cards
- DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
- Album album = null;
- unregister();
- Cursor c = mContentResolver.query(
+ mDateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
+ Cursor c = getActivity().getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{ MediaStore.MediaColumns.DATA },
null,
@@ -84,40 +102,31 @@ public class ChoosePicturesFragment extends PreferenceFragment implements OnEndS
try {
long start = System.currentTimeMillis();
if (DEBUG) Log.v(TAG, "Media library:");
+ int count = 0;
+ List<Album> pending = new ArrayList<Album>();
+ List<Album> all = new ArrayList<Album>();
+ Album album = null;
while (c.moveToNext()) {
- // Only valid files (those i can read)
- String p = c.getString(0);
- if (DEBUG) Log.v(TAG, "\t" + p);
- if (p != null) {
- File f = new File(p);
- if (f.isFile() && f.canRead()) {
- File path = f.getParentFile();
- String name = path.getName();
- if (album == null || album.getPath().compareTo(path.getAbsolutePath()) != 0) {
- if (album != null) {
- mAlbums.add(album);
- mOriginalAlbums.add((Album)album.clone());
- }
- album = new Album();
- album.setPath(path.getAbsolutePath());
- album.setName(name);
- album.setDate(df.format(new Date(path.lastModified())));
- album.setSelected(isSelectedItem(album.getPath()));
- album.setItems(new ArrayList<String>());
- album.setSelectedItems(new ArrayList<String>());
- }
- album.getItems().add(f.getAbsolutePath());
- if (isSelectedItem(f.getAbsolutePath())) {
- album.getSelectedItems().add(f.getAbsolutePath());
- }
- }
+ album = processPath(all, pending, album, c.getString(0));
+ count++;
+ if (count % PROGRESS_STEPS == 0) {
+ // Notify and clean
+ publishProgress(pending.toArray(new Album[pending.size()]));
+ pending.clear();
}
}
- // Add the last album
+ // Add the last albums
if (album != null) {
- mAlbums.add(album);
+ // Add to global structures
+ all.add(album);
mOriginalAlbums.add((Album)album.clone());
+
+ // Add to local structures and notify
+ pending.add(album);
+
+ // Notify
+ publishProgress(pending.toArray(new Album[pending.size()]));
}
long end = System.currentTimeMillis();
if (DEBUG) Log.v(TAG, "Library loaded in " + (end - start) + " miliseconds");
@@ -133,43 +142,139 @@ public class ChoosePicturesFragment extends PreferenceFragment implements OnEndS
* {@inheritDoc}
*/
@Override
+ protected void onProgressUpdate(Album... albums) {
+ for(Album album : albums) {
+ mAlbums.add(album);
+ }
+ mAlbumAdapter.notifyDataSetChanged();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
protected void onPostExecute(Void result) {
- Resources res = getActivity().getResources();
- int size = (int)(res.getDimension(R.dimen.album_size) +
- res.getDimension(R.dimen.small_margin));
- mScroller.setEndPadding(size * AMOUNT_OF_ADDED_STEPS);
- int height = mScroller.getMeasuredHeight();
- int steps = (height / size) + AMOUNT_OF_ADDED_STEPS;
-
- // Create the views an force a redraw the items
- mAlbumViews = new ArrayList<View>(mAlbums.size());
- for (Album item : mAlbums) {
- mAlbumViews.add(createAlbumView(item));
+ mAlbumAdapter.notifyDataSetChanged();
+ }
+
+ /**
+ * Method that process a album path
+ *
+ * @param all All the albums
+ * @param pending Pending albums to notify
+ * @param data The current album data
+ * @param path The path to analyze
+ * @return Album The new current album
+ */
+ private Album processPath(List<Album> all, List<Album> pending, Album data, String path) {
+ // Only valid files (those i can read)
+ if (DEBUG) Log.v(TAG, "\t" + path);
+ Album album = data;
+ if (path != null) {
+ File f = new File(path);
+ if (f.isFile() && f.canRead()) {
+ File p = f.getParentFile();
+ String name = p.getName();
+ if (album == null || album.getPath().compareTo(p.getAbsolutePath()) != 0) {
+ if (album != null) {
+ // Add to global structures
+ all.add(album);
+ mOriginalAlbums.add((Album)album.clone());
+
+ // Add to local structures and notify
+ pending.add(album);
+ }
+ album = new Album();
+ album.setPath(p.getAbsolutePath());
+ album.setName(name);
+ album.setDate(mDateFormat.format(new Date(p.lastModified())));
+ album.setSelected(isSelectedItem(album.getPath()));
+ album.setItems(new ArrayList<Picture>());
+ album.setSelectedItems(new ArrayList<String>());
+ }
+ boolean selected = isSelectedItem(f.getAbsolutePath());
+ album.getItems().add(new Picture(f.getAbsolutePath(), selected));
+ if (selected) {
+ album.getSelectedItems().add(f.getAbsolutePath());
+ }
+ }
}
- doEndScroll(steps, true);
+ return album;
+ }
- // We not need Hardware acceleration anymore (no more animations)
- // Disable drawing cache
- mScroller.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
- mScroller.setDrawingCacheEnabled(false);
- mScroller.setSmoothScrollingEnabled(true);
+ /**
+ * Method that checks if an item is selected
+ *
+ * @param item The item
+ * @return boolean if an item is selected
+ */
+ private boolean isSelectedItem(String item) {
+ Iterator<String> it = mSelectedAlbums.iterator();
+ while (it.hasNext()) {
+ String albumPath = it.next();
+ if (item.compareTo(albumPath) == 0) {
+ return true;
+ }
+ }
+ return false;
}
};
- /*package*/ ContentResolver mContentResolver;
+ private final Handler.Callback mCallback = new Handler.Callback() {
+ @Override
+ public boolean handleMessage(Message msg) {
+ if (msg.what == MSG_LOAD_PICTURES) {
+ loadPictures((Album)msg.obj);
+ return true;
+ }
+ return false;
+ }
+ };
- /*package*/ List<Album> mAlbums;
- /*package*/ List<View> mAlbumViews;
- /*package*/ List<Album> mOriginalAlbums;
- /*package*/ List<AlbumsFlip3dAnimationController> mAnimationControllers;
+ OnItemClickListener mOnItemClickListener = new OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ if (mShowingAlbums) {
+ onHeaderPressed(parent, view, position);
+ } else {
+ onPicturePressed(view);
+ }
+ }
+ };
+
+ private static final int MSG_LOAD_PICTURES = 1;
- /*package*/ Set<String> mSelectedAlbums;
+ List<Album> mAlbums;
+ List<Album> mOriginalAlbums;
+
+ Set<String> mSelectedAlbums;
private Set<String> mOriginalSelectedAlbums;
- /*package*/ VerticalEndlessScroller mScroller;
- private CardLayout mAlbumsPanel;
+ ViewGroup mContainer;
+
+ ListView mAlbumsPanel;
+ AlbumCardUiAdapter mAlbumAdapter;
- /*package*/ boolean mSelectionChanged;
+ GridView mPicturesPanel;
+ AlbumPictureAdapter mPictureAdapter;
+
+ private boolean mSelectionChanged;
+
+ // Animation references
+ ViewGroup mSrcParent;
+ View mSrcView;
+ ViewGroup mDstParent;
+ View mDstView;
+
+ Album mAlbum;
+
+ private int mPicturesAnimDurationIn;
+ private int mPicturesAnimDurationOut;
+
+ Handler mHandler;
+ LayoutInflater mInflater;
+
+ boolean mShowingAlbums;
/**
* {@inheritDoc}
@@ -177,22 +282,26 @@ public class ChoosePicturesFragment extends PreferenceFragment implements OnEndS
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mContentResolver = getActivity().getContentResolver();
+ mHandler = new Handler(mCallback);
+ mShowingAlbums = true;
// Create an empty album
mAlbums = new ArrayList<Album>();
mOriginalAlbums = new ArrayList<Album>();
- mAnimationControllers = new ArrayList<AlbumsFlip3dAnimationController>();
// Change the preference manager
getPreferenceManager().setSharedPreferencesName(PreferencesProvider.PREFERENCES_FILE);
getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE);
// Load the albums user selection
- mOriginalSelectedAlbums = Preferences.Media.getSelectedMedia();
+ mOriginalSelectedAlbums = removeObsoleteAlbumsData(Preferences.Media.getSelectedMedia());
mSelectedAlbums = new HashSet<String>(mOriginalSelectedAlbums);
mSelectionChanged = false;
+ Resources res = getActivity().getResources();
+ mPicturesAnimDurationIn = res.getInteger(R.integer.pictures_anim_in);
+ mPicturesAnimDurationOut = res.getInteger(R.integer.pictures_anim_out);
+
setHasOptionsMenu(true);
}
@@ -202,12 +311,19 @@ public class ChoosePicturesFragment extends PreferenceFragment implements OnEndS
@Override
public void onDestroy() {
super.onDestroy();
- if (mAlbumsLoaderTask.getStatus().compareTo(Status.PENDING) == 0) {
- mAlbumsLoaderTask.cancel(true);
+ if (mTask.getStatus().compareTo(Status.PENDING) == 0) {
+ mTask.cancel(true);
}
unbindDrawables(mAlbumsPanel);
unregister();
+ if (!mShowingAlbums) {
+ mPicturesPanel.setVisibility(View.GONE);
+ mDstView.setVisibility(View.GONE);
+ mDstParent.removeView(mPicturesPanel);
+ mDstParent.removeView(mDstView);
+ }
+
// Notify that the settings was changed
Intent intent = new Intent(PreferencesProvider.ACTION_SETTINGS_CHANGED);
if (mSelectionChanged) {
@@ -218,10 +334,9 @@ public class ChoosePicturesFragment extends PreferenceFragment implements OnEndS
getActivity().sendBroadcast(intent);
}
- /*package*/ void unregister() {
+ private void unregister() {
mAlbums.clear();
mOriginalAlbums.clear();
- mAnimationControllers.clear();
}
/**
@@ -229,7 +344,7 @@ public class ChoosePicturesFragment extends PreferenceFragment implements OnEndS
*
* @param view The root view
*/
- private void unbindDrawables(View view) {
+ void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
@@ -237,7 +352,6 @@ public class ChoosePicturesFragment extends PreferenceFragment implements OnEndS
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
- ((ViewGroup) view).removeAllViews();
}
}
@@ -245,26 +359,43 @@ public class ChoosePicturesFragment extends PreferenceFragment implements OnEndS
* {@inheritDoc}
*/
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+ Bundle savedInstanceState) {
+
+ mContainer = container;
+ mInflater = inflater;
+
// Inflate the layout for this fragment
- mScroller =
- (VerticalEndlessScroller)inflater.inflate(
+ FrameLayout root =
+ (FrameLayout)mInflater.inflate(
R.layout.choose_picture_fragment, container, false);
- mScroller.setCallback(this);
- mAlbumsPanel = (CardLayout)mScroller.findViewById(R.id.albums_panel);
+ mAlbumsPanel = (ListView)root.findViewById(R.id.albums_panel);
+ mAlbumsPanel.setSmoothScrollbarEnabled(true);
+ mAlbumAdapter = new AlbumCardUiAdapter(getActivity(), mAlbumsPanel, mAlbums, this);
+ mAlbumsPanel.setAdapter(mAlbumAdapter);
+ mAlbumsPanel.setOnItemClickListener(mOnItemClickListener);
// Force Hardware acceleration
- if (!mScroller.isHardwareAccelerated()) {
- mScroller.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ if (!root.isHardwareAccelerated()) {
+ root.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
if (!mAlbumsPanel.isHardwareAccelerated()) {
mAlbumsPanel.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
// Load the albums
- mAlbumsLoaderTask.execute();
+ unregister();
+ mTask.execute();
+
+ return root;
+ }
- return mScroller;
+ @Override
+ public void onClick(View v) {
+ // Hide the albums picture with animation
+ if (v.equals(mDstView)) {
+ hideAlbumPictures(mDstParent, mDstView, mSrcParent, mSrcView);
+ }
}
/**
@@ -287,8 +418,12 @@ public class ChoosePicturesFragment extends PreferenceFragment implements OnEndS
case R.id.mnu_restore:
restoreData();
return true;
- case R.id.mnu_invert_all:
- invertAll();
+ case R.id.mnu_invert:
+ if (mShowingAlbums) {
+ invertAll();
+ } else {
+ invertAlbum(mAlbum);
+ }
return true;
default:
return super.onOptionsItemSelected(item);
@@ -301,14 +436,25 @@ public class ChoosePicturesFragment extends PreferenceFragment implements OnEndS
private void restoreData() {
// Restore and the albums the selection
mSelectedAlbums = new HashSet<String>(mOriginalSelectedAlbums);
- mAlbums.clear();
- for (Album album : mOriginalAlbums) {
- mAlbums.add((Album)album.clone());
+ int count = mAlbums.size();
+ for (int i = 0; i < count ; i++) {
+ Album album = mAlbums.get(i);
+ Album originalAlbum = mOriginalAlbums.get(i);
+
+ // Update selected status
+ album.setSelected(originalAlbum.isSelected());
+ album.setItems(new ArrayList<Picture>(originalAlbum.getItems()));
+ album.setSelectedItems(new ArrayList<String>(originalAlbum.getSelectedItems()));
}
+ mAlbumAdapter.notifyDataSetChanged();
- // Update all the views
+ // Update settings
Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums);
- updateAll();
+ mSelectionChanged = true;
+
+ if (!mShowingAlbums) {
+ hideAlbumPictures(mDstParent, mDstView, mSrcParent, mSrcView);
+ }
}
/**
@@ -325,172 +471,431 @@ public class ChoosePicturesFragment extends PreferenceFragment implements OnEndS
} else {
mSelectedAlbums.addAll(album.getSelectedItems());
}
+ for (Picture picture : album.getItems()) {
+ picture.setSelected(false);
+ }
}
+ mAlbumAdapter.notifyDataSetChanged();
- // Update all the views
+ // Update settings
Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums);
- updateAll();
+ mSelectionChanged = true;
}
/**
- * Method that updates the current state of all the albums
+ * Method that inverts the selection of an album
+ *
+ * @param album The album which to invert its selection
*/
- private void updateAll() {
- // Update every view (albums and views should have the same size)
- int count = mAlbumsPanel.getChildCount();
- for (int i = 0; i < count; i++) {
- Album album = mAlbums.get(i);
- View v = mAlbumsPanel.getChildAt(i);
- AlbumInfo albumInfo = (AlbumInfo)v.findViewById(R.id.album_info);
- AlbumPictures albumPictures = (AlbumPictures)v.findViewById(R.id.album_pictures);
- albumInfo.updateView(album);
- albumPictures.updateView(album, true);
+ private void invertAlbum(Album album) {
+ // Remove all pictures of the album
+ removeAlbumItems(album);
+ List<String> origSelectedItems = new ArrayList<String>(album.getSelectedItems());
+ List<String> selectedItems = album.getSelectedItems();
+ album.getSelectedItems().clear();
+ for (Picture picture : album.getItems()) {
+ boolean selected = !origSelectedItems.contains(picture.getPath());
+ if (selected) {
+ selectedItems.add(picture.getPath());
+ }
+ picture.setSelected(selected);
}
- // Restore the preference
+ // Notify pictures dataset changed
+ mPictureAdapter.notifyDataSetChanged();
+ updateAlbumInfo(mDstView, album);
+
+ mSelectedAlbums.addAll(album.getSelectedItems());
Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums);
mSelectionChanged = true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onAlbumSelected(Album album) {
+ updateAlbumSelection(album, true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onAlbumDeselected(Album album) {
+ updateAlbumSelection(album, false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onAllPicturesSelected(Album album) {
+ updateAllPicturesSelection(album, true);
+ }
- // Restore all the animations states
- for (AlbumsFlip3dAnimationController controller : mAnimationControllers) {
- controller.reset();
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onAllPicturesDeselected(Album album) {
+ updateAllPicturesSelection(album, false);
+ }
+
+ /**
+ * Method that update the album selection
+ *
+ * @param album The album to update
+ * @param selected If the album is selected
+ */
+ private void updateAlbumSelection(Album album, boolean selected) {
+ // Remove all pictures of the album
+ removeAlbumItems(album);
+ album.setSelected(selected);
+ album.getSelectedItems().clear();
+ for (Picture picture : album.getItems()) {
+ picture.setSelected(false);
+ }
+ if (selected) {
+ mSelectedAlbums.add(album.getPath());
}
+
+ if (!mShowingAlbums) {
+ // Notify pictures dataset changed
+ updateAlbumInfo(mDstView, album);
+ mPictureAdapter.notifyDataSetChanged();
+ }
+ updateAlbumInfo(mSrcView, album);
+
+ Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums);
+ mSelectionChanged = true;
}
/**
- * Method that creates a new album to the card layout
+ * Method that update the whole picture selection
*
- * @param album The album to create
- * @return View The view create
+ * @param album The album to update
+ * @param selected If all the picture were selected
*/
- View createAlbumView(final Album album) {
- LayoutInflater li = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- final View albumView = li.inflate(R.layout.album, mAlbumsPanel, false);
- final AlbumInfo albumInfo = (AlbumInfo)albumView.findViewById(R.id.album_info);
- final AlbumPictures albumPictures = (AlbumPictures)albumView.findViewById(R.id.album_pictures);
-
- // Load the album info
- albumInfo.post(new Runnable() {
- @Override
- public void run() {
- albumInfo.updateView(album);
+ private void updateAllPicturesSelection(Album album, boolean selected) {
+ // Remove all pictures of the album
+ removeAlbumItems(album);
+ List<String> selectedItems = album.getSelectedItems();
+ selectedItems.clear();
+ for (Picture picture : album.getItems()) {
+ if (selected) {
+ selectedItems.add(picture.getPath());
+ }
+ picture.setSelected(selected);
+ }
+ album.setSelected(false);
+
+ // Notify pictures dataset changed
+ mPictureAdapter.notifyDataSetChanged();
+ updateAlbumInfo(mDstView, album);
+
+ mSelectedAlbums.addAll(album.getSelectedItems());
+ Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums);
+ mSelectionChanged = true;
+ }
+
+ /**
+ * Method that removes the reference to all the items and itself
+ *
+ * @param ref The album
+ */
+ private void removeAlbumItems(Album ref) {
+ Iterator<String> it = mSelectedAlbums.iterator();
+ while (it.hasNext()) {
+ String item = it.next();
+ String parent = new File(item).getParent();
+ if (parent.compareTo(ref.getPath()) == 0) {
+ it.remove();
+ } else if (item.compareTo(ref.getPath()) == 0) {
+ it.remove();
}
- });
- if (album.isSelected()) {
- albumInfo.setSelected(true);
}
- albumInfo.addCallBackListener(new AlbumInfo.CallbacksListener() {
+ }
+
+ /**
+ * Method that shows the album pictures while animating the view
+ *
+ * @param srcParent The source parent view
+ * @param srcView The source view
+ * @param dstParent The destination parent view
+ * @param dstView The destination view
+ */
+ void showAlbumPictures(final ViewGroup srcParent, final View srcView,
+ final ViewGroup dstParent, final View dstView) {
+
+ // Hide the source view
+ srcView.setAlpha(0.0f);
+
+ // Animation from bottom to top
+ ObjectAnimator anim1 = ObjectAnimator.ofFloat(dstView, "translationY",
+ srcView.getY(), srcParent.getPaddingTop());
+ anim1.setDuration(mPicturesAnimDurationIn);
+ anim1.setInterpolator(new AccelerateDecelerateInterpolator());
+ anim1.addListener(new AnimatorListener() {
@Override
- public void onAlbumSelected(Album ref) {
- // Remove all pictures of the album and add the album reference
- removeAlbumItems(ref);
- mSelectedAlbums.add(ref.getPath());
- ref.setSelected(true);
- albumPictures.updateView(ref, true);
-
- Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums);
- mSelectionChanged = true;
+ public void onAnimationStart(Animator animation) {
+ // Ignore
}
@Override
- public void onAlbumDeselected(Album ref) {
- // Remove all pictures of the album
- removeAlbumItems(ref);
- ref.setSelected(false);
- albumPictures.updateView(ref, true);
-
- Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums);
- mSelectionChanged = true;
+ public void onAnimationRepeat(Animator animation) {
+ // Ignore
}
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ // Re-layout the view in its new position
+ dstView.setOnClickListener(ChoosePicturesFragment.this);
+
+ // And now finally show the new album pictures layout
+ // and fill it
+ mPicturesPanel.setVisibility(View.VISIBLE);
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_LOAD_PICTURES, mAlbum));
+ mShowingAlbums = false;
+ }
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ // Ignore
+ }
});
+ anim1.start();
+
+ // Hide the parent view
+ AlphaAnimation anim2 = new AlphaAnimation(1.0f, 0.0f);
+ anim2.setDuration(mPicturesAnimDurationIn);
+ anim2.setFillAfter(true);
+ anim2.setZAdjustment(Animation.ZORDER_BOTTOM);
+ anim2.setInterpolator(new AccelerateDecelerateInterpolator());
+ srcParent.setEnabled(false);
+ srcParent.startAnimation(anim2);
+
+ // Save the references
+ mSrcParent = srcParent;
+ mSrcView = srcView;
+ mDstParent = dstParent;
+ mDstView = dstView;
+ }
+
+ /**
+ * Method that hides the album pictures while animating the view
+ *
+ * @param srcParent The source parent view
+ * @param srcView The source view
+ * @param dstParent The destination parent view
+ * @param dstView The destination view
+ */
+ void hideAlbumPictures(final ViewGroup srcParent, final View srcView,
+ final ViewGroup dstParent, final View dstView) {
+
+ mPicturesPanel.setVisibility(View.INVISIBLE);
+
+ // Animation from top to bottom
+ ObjectAnimator anim1 = ObjectAnimator.ofFloat(srcView, "translationY",
+ dstParent.getPaddingTop(), dstView.getY());
+ anim1.setDuration(mPicturesAnimDurationOut);
+ anim1.setInterpolator(new AccelerateDecelerateInterpolator());
+ anim1.addListener(new AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ // Ignore
+ }
- // Load the album picture data
- albumPictures.updateView(album, false);
- albumPictures.addCallBackListener(new AlbumPictures.CallbacksListener() {
@Override
- public void onBackButtonClick(View v) {
- // Ignored
+ public void onAnimationRepeat(Animator animation) {
+ // Ignore
}
@Override
- public void onSelectionChanged(Album ref) {
- // Remove, add, and persist the selection
- removeAlbumItems(ref);
- mSelectedAlbums.addAll(ref.getSelectedItems());
- ref.setSelected(false);
- albumInfo.updateView(ref);
-
- Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums);
- mSelectionChanged = true;
+ public void onAnimationEnd(Animator animation) {
+ // Remove the source view and show the destination view
+ srcParent.removeView(srcView);
+ dstView.setAlpha(1.0f);
+ dstParent.setEnabled(true);
+ unbindDrawables(mPicturesPanel);
+ srcParent.removeView(mPicturesPanel);
+
+ mShowingAlbums = true;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ // Ignore
}
});
+ anim1.start();
+
+ // Hide the parent view
+ AlphaAnimation anim2 = new AlphaAnimation(0.0f, 1.0f);
+ anim2.setDuration(mPicturesAnimDurationOut);
+ anim2.setFillAfter(true);
+ anim2.setZAdjustment(Animation.ZORDER_BOTTOM);
+ anim2.setInterpolator(new AccelerateDecelerateInterpolator());
+ dstParent.startAnimation(anim2);
+ }
+
+ /**
+ * Method that updates an album info
+ *
+ * @param v The header view
+ * @param album The album data
+ */
+ void updateAlbumInfo(View v, Album album) {
+ Resources res = getActivity().getResources();
+
+ AlbumInfoView info = (AlbumInfoView)v.findViewById(R.id.album_info);
+ info.setAlbum(album);
- // Register the animation controller
- AlbumsFlip3dAnimationController controller = new AlbumsFlip3dAnimationController(albumInfo, albumPictures);
- controller.register();
- mAnimationControllers.add(controller);
+ ImageView icon = (ImageView)info.findViewById(R.id.album_thumbnail);
+ TextView name = (TextView)info.findViewById(R.id.album_name);
+ TextView items = (TextView)info.findViewById(R.id.album_items);
+ TextView selectedItems = (TextView)info.findViewById(R.id.album_selected_items);
- return albumView;
+ icon.setImageDrawable(album.getIcon());
+ name.setText(album.getName());
+
+ int size = album.getItems().size();
+ items.setText(String.format(res.getQuantityText(
+ R.plurals.album_number_of_pictures, size).toString(), Integer.valueOf(size)));
+
+ int selected = album.getSelectedItems().size();
+ String count = String.valueOf(selected);
+ if (selected > 99) {
+ count = "99+";
+ }
+ selectedItems.setText(count);
+ selectedItems.setVisibility(!album.isSelected() ? View.VISIBLE : View.INVISIBLE);
+ info.setSelected(album.isSelected());
}
/**
- * Method that checks if an item is selected
+ * Method that load all the pictures of the album
*
- * @param item The item
- * @return boolean if an item is selected
+ * @param album
*/
- /*package*/ boolean isSelectedItem(String item) {
- Iterator<String> it = mSelectedAlbums.iterator();
- while (it.hasNext()) {
- String albumPath = it.next();
- if (item.compareTo(albumPath) == 0) {
- return true;
- }
+ void loadPictures(Album album) {
+ List<Picture> items = album.getItems();
+
+ // Calculate the grid dimensions
+ Resources res = getActivity().getResources();
+ int pictureWidth = (int)res.getDimension(R.dimen.picture_size);
+ int gridWidth = mPicturesPanel.getWidth();
+ int columns = gridWidth / pictureWidth;
+ int space = (gridWidth / pictureWidth) / (columns - 1);
+ if (columns < items.size()) {
+ space = (int)res.getDimension(R.dimen.small_padding);
}
- return false;
+ mPicturesPanel.setHorizontalSpacing(space);
+ mPicturesPanel.setVerticalSpacing(space);
+ mPicturesPanel.setStretchMode(GridView.STRETCH_SPACING);
+ mPicturesPanel.setColumnWidth(pictureWidth);
+ mPicturesPanel.setNumColumns(columns);
+
+ mPictureAdapter = new AlbumPictureAdapter(getActivity(), items, mPicturesPanel);
+ mPicturesPanel.setAdapter(mPictureAdapter);
}
/**
- * Method that removes the reference to all the items and itself
+ * Method invoked when an album header was pressed
*
- * @param ref The album
+ * @param parent The parent view
+ * @param view The header view
+ * @param position The position
*/
- /*package*/ void removeAlbumItems(Album ref) {
- Iterator<String> it = mSelectedAlbums.iterator();
- while (it.hasNext()) {
- String item = it.next();
- String parent = new File(item).getParent();
- if (parent.compareTo(ref.getPath()) == 0) {
- it.remove();
- } else if (item.compareTo(ref.getPath()) == 0) {
- it.remove();
- }
+ void onHeaderPressed(AdapterView<?> parent, View view, int position) {
+ mAlbum = mAlbumAdapter.getItem(position);
+
+ // Header view
+ View header = mInflater.inflate(R.layout.album_info, null);
+ header.setTranslationY(view.getY() + parent.getPaddingTop());
+ header.setLayoutParams(new ViewGroup.LayoutParams(view.getWidth(), view.getHeight()));
+
+ // Pictures view
+ mPicturesPanel = (GridView) mInflater.inflate(R.layout.pictures_view, null);
+ if (!mPicturesPanel.isHardwareAccelerated()) {
+ mPicturesPanel.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
+ mPicturesPanel.setY(view.getHeight());
+ mPicturesPanel.setLayoutParams(new ViewGroup.LayoutParams(view.getWidth(),
+ parent.getHeight() - view.getHeight() -
+ parent.getPaddingTop() - parent.getPaddingBottom()));
+ mPicturesPanel.setVisibility(View.INVISIBLE);
+ mPicturesPanel.setOnItemClickListener(mOnItemClickListener);
+
+ // Add to the container
+ mContainer.addView(mPicturesPanel);
+ mContainer.addView(header);
+
+ // Update and display the album pictures view
+ AlbumInfoView info = (AlbumInfoView)header.findViewById(R.id.album_info);
+ info.addCallBackListener(ChoosePicturesFragment.this);
+ info.setAlbumMode(false);
+ updateAlbumInfo(header, mAlbum);
+ showAlbumPictures(parent, view, mContainer, header);
}
/**
- * {@inheritDoc}
+ * Method invoked when a picture view was pressed
+ *
+ * @param view The picture view
*/
- @Override
- public void onEndScroll() {
- doEndScroll(AMOUNT_OF_ADDED_STEPS, false);
+ void onPicturePressed(View view) {
+ PictureItemView pictureView = (PictureItemView)view.findViewById(R.id.picture);
+ if (pictureView != null) {
+ Picture picture = pictureView.getPicture();
+ removeAlbumItems(mAlbum);
+ List<String> selectedItems = mAlbum.getSelectedItems();
+ if (selectedItems.contains(picture.getPath())) {
+ selectedItems.remove(picture.getPath());
+ picture.setSelected(false);
+ } else {
+ selectedItems.add(picture.getPath());
+ picture.setSelected(true);
+ mAlbum.setSelected(false);
+ }
+
+ // Notify all the views
+ pictureView.updateView(picture, false);
+ updateAlbumInfo(mDstView, mAlbum);
+ mAlbumAdapter.notifyDataSetChanged();
+
+ // Update settings
+ mSelectedAlbums.addAll(mAlbum.getSelectedItems());
+ Preferences.Media.setSelectedMedia(getActivity(), mSelectedAlbums);
+ mSelectionChanged = true;
+ }
}
/**
- * Method that performs a scroll creating new items
+ * Method that removes all the inexistent albums and pictures
*
- * @param amount The amount of items to create
- * @param animate If the add should be animated
+ * @param data The data to filter
+ * @return Set<String> The data filtered
*/
- /*package*/ synchronized void doEndScroll(int amount, boolean animate) {
- for (int i = 0; i < amount; i++) {
- //Add to the panel of cards
- if (mAlbumViews == null || mAlbumViews.isEmpty()) {
- break;
+ private Set<String> removeObsoleteAlbumsData(Set<String> data) {
+ Set<String> validDataList = new HashSet<String>();
+ Iterator<String> it = data.iterator();
+ while (it.hasNext()) {
+ File f = new File(it.next());
+ if (f.exists()) {
+ try {
+ validDataList.add(f.getCanonicalPath());
+ } catch (IOException ioex) {
+ // Ignore
+ }
}
- mAlbumsPanel.addCard(mAlbumViews.remove(0), animate);
}
+ if (data.size() != validDataList.size()) {
+ // Obsolete entries were removed
+ data.clear();
+ data.addAll(validDataList);
+ Preferences.Media.setSelectedMedia(getActivity(), mOriginalSelectedAlbums);
+ }
+ return data;
}
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/DispositionFragment.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/DispositionFragment.java
index b0204c3..7071e76 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/preferences/DispositionFragment.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/DispositionFragment.java
@@ -53,7 +53,7 @@ public abstract class DispositionFragment
}
};
- /*package*/ DispositionView mDispositionView;
+ DispositionView mDispositionView;
private MenuItem mDeleteMenu;
diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/PhotoPhasePreferences.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/PhotoPhasePreferences.java
index 4e8c46e..b5c0d83 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/preferences/PhotoPhasePreferences.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/PhotoPhasePreferences.java
@@ -47,7 +47,8 @@ public class PhotoPhasePreferences extends PreferenceActivity {
private void initTitleActionBar() {
//Configure the action bar options
getActionBar().setDisplayOptions(
- ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
+ ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME |
+ ActionBar.DISPLAY_SHOW_TITLE);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/preferences/PreferencesProvider.java b/src/org/cyanogenmod/wallpapers/photophase/preferences/PreferencesProvider.java
index 1bf8359..0edc8b7 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/preferences/PreferencesProvider.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/preferences/PreferencesProvider.java
@@ -96,7 +96,7 @@ public final class PreferencesProvider {
/**
* @hide
*/
- /*package*/ static int[] TRANSITIONS_INTERVALS;
+ static int[] TRANSITIONS_INTERVALS;
/**
* Method that loads the all the preferences of the application
@@ -350,7 +350,12 @@ public final class PreferencesProvider {
* @return Set<String> The list of albums and pictures to be displayed
*/
public static Set<String> getLastDiscorevedAlbums() {
- return getStringSet("media_last_disvored_albums", new HashSet<String>());
+ // FIXME Typo. Remove when version 1005 is obsolete and unused
+ Set<String> oldKey = getStringSet("media_last_disvored_albums", new HashSet<String>());
+ if (oldKey.size() > 0) {
+ return oldKey;
+ }
+ return getStringSet("media_last_discovered_albums", new HashSet<String>());
}
/**
@@ -364,7 +369,9 @@ public final class PreferencesProvider {
SharedPreferences preferences =
context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
Editor editor = preferences.edit();
- editor.putStringSet("media_last_disvored_albums", albums);
+ // FIXME Typo. Remove when version 1005 is obsolete and unused
+ editor.remove("media_last_disvored_albums");
+ editor.putStringSet("media_last_discovered_albums", albums);
editor.commit();
reload(context);
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/tasks/AsyncPictureLoaderTask.java b/src/org/cyanogenmod/wallpapers/photophase/tasks/AsyncPictureLoaderTask.java
index bc07b17..3ea1885 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/tasks/AsyncPictureLoaderTask.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/tasks/AsyncPictureLoaderTask.java
@@ -32,8 +32,34 @@ import java.io.File;
*/
public class AsyncPictureLoaderTask extends AsyncTask<File, Void, Drawable> {
+ /**
+ * Notify whether the picture was loaded
+ */
+ public static abstract class OnPictureLoaded {
+ Object[] mRefs;
+
+ /**
+ * Constructor of <code>OnPictureLoaded</code>
+ *
+ * @param refs References to notify
+ */
+ public OnPictureLoaded(Object...refs) {
+ super();
+ mRefs = refs;
+ }
+
+ /**
+ * Invoked when a picture is loaded
+ *
+ * @param o The original object reference
+ * @param drawable The drawable
+ */
+ public abstract void onPictureLoaded(Object o, Drawable drawable);
+ }
+
private final Context mContext;
private final ImageView mView;
+ private final OnPictureLoaded mCallback;
/**
* Constructor of <code>AsyncPictureLoaderTask</code>
@@ -42,9 +68,21 @@ public class AsyncPictureLoaderTask extends AsyncTask<File, Void, Drawable> {
* @param v The associated view
*/
public AsyncPictureLoaderTask(Context context, ImageView v) {
+ this(context, v, null);
+ }
+
+ /**
+ * Constructor of <code>AsyncPictureLoaderTask</code>
+ *
+ * @param context The current context
+ * @param v The associated view
+ * @param callback A callback to notify when the picture was loaded
+ */
+ public AsyncPictureLoaderTask(Context context, ImageView v, OnPictureLoaded callback) {
super();
mContext = context;
mView = v;
+ mCallback = callback;
}
/**
@@ -56,7 +94,15 @@ public class AsyncPictureLoaderTask extends AsyncTask<File, Void, Drawable> {
int height = mView.getMeasuredHeight();
Bitmap bitmap = BitmapUtils.decodeBitmap(params[0], width, height);
if (bitmap != null) {
- return new BitmapDrawable(mContext.getResources(), bitmap);
+ Drawable dw = new BitmapDrawable(mContext.getResources(), bitmap);
+ if (mCallback != null) {
+ for (Object o : mCallback.mRefs) {
+ if (!isCancelled()) {
+ mCallback.onPictureLoaded(o, dw);
+ }
+ }
+ }
+ return dw;
}
return null;
}
@@ -66,6 +112,8 @@ public class AsyncPictureLoaderTask extends AsyncTask<File, Void, Drawable> {
*/
@Override
protected void onPostExecute(Drawable result) {
- mView.setImageDrawable(result);
+ if (!isCancelled()) {
+ mView.setImageDrawable(result);
+ }
}
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/widgets/AlbumInfo.java b/src/org/cyanogenmod/wallpapers/photophase/widgets/AlbumInfoView.java
index 8e335c3..3cfe4d3 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/widgets/AlbumInfo.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/widgets/AlbumInfoView.java
@@ -18,6 +18,8 @@ package org.cyanogenmod.wallpapers.photophase.widgets;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.util.AttributeSet;
import android.view.Menu;
@@ -40,10 +42,10 @@ import java.util.ArrayList;
import java.util.List;
/**
- * A view that contains the info about an album
+ * A view that contains the view of the info of an album
*/
-public class AlbumInfo extends RelativeLayout
- implements OnClickListener, OnMenuItemClickListener {
+public class AlbumInfoView extends RelativeLayout
+ implements OnClickListener, OnMenuItemClickListener {
/**
* A convenient listener for receive events of the AlbumPictures class
@@ -63,43 +65,70 @@ public class AlbumInfo extends RelativeLayout
* @param album The album
*/
void onAlbumDeselected(Album album);
+
+ /**
+ * Invoked when an all of the picture of the album were selected
+ *
+ * @param album The album
+ */
+ void onAllPicturesSelected(Album album);
+
+ /**
+ * Invoked when an all of the picture of the album were deselected
+ *
+ * @param album The album
+ */
+ void onAllPicturesDeselected(Album album);
+ }
+
+ private class OnPictureLoaded extends AsyncPictureLoaderTask.OnPictureLoaded {
+ public OnPictureLoaded(Album album) {
+ super(new Object[]{album});
+ }
+
+ @Override
+ public void onPictureLoaded(Object o, Drawable drawable) {
+ ((Album)o).setIcon(drawable);
+ }
}
private List<CallbacksListener> mCallbacks;
- /*package*/ Album mAlbum;
+ private Album mAlbum;
- /*package*/ AsyncPictureLoaderTask mTask;
+ private AsyncPictureLoaderTask mTask;
- /*package*/ ImageView mIcon;
+ private ImageView mIcon;
private TextView mSelectedItems;
private TextView mName;
private TextView mItems;
private View mOverflowButton;
+ private boolean mAlbumMode;
+
/**
- * Constructor of <code>AlbumInfo</code>.
+ * Constructor of <code>AlbumInfoView</code>.
*
* @param context The current context
*/
- public AlbumInfo(Context context) {
+ public AlbumInfoView(Context context) {
super(context);
init();
}
/**
- * Constructor of <code>AlbumInfo</code>.
+ * Constructor of <code>AlbumInfoView</code>.
*
* @param context The current context
* @param attrs The attributes of the XML tag that is inflating the view.
*/
- public AlbumInfo(Context context, AttributeSet attrs) {
+ public AlbumInfoView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
/**
- * Constructor of <code>AlbumInfo</code>.
+ * Constructor of <code>AlbumInfoView</code>.
*
* @param context The current context
* @param attrs The attributes of the XML tag that is inflating the view.
@@ -108,7 +137,7 @@ public class AlbumInfo extends RelativeLayout
* either be an attribute resource, whose value will be retrieved
* from the current theme, or an explicit style resource.
*/
- public AlbumInfo(Context context, AttributeSet attrs, int defStyle) {
+ public AlbumInfoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
@@ -117,7 +146,17 @@ public class AlbumInfo extends RelativeLayout
* Method that initializes the internal references
*/
private void init() {
- mCallbacks = new ArrayList<AlbumInfo.CallbacksListener>();
+ mCallbacks = new ArrayList<AlbumInfoView.CallbacksListener>();
+ mAlbumMode = true;
+ }
+
+ /**
+ * Method that set the album mode
+ *
+ * @param albumMode The album mode
+ */
+ public void setAlbumMode(boolean albumMode) {
+ this.mAlbumMode = albumMode;
}
/**
@@ -145,13 +184,6 @@ public class AlbumInfo extends RelativeLayout
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- mIcon = (ImageView)findViewById(R.id.album_thumbnail);
- mSelectedItems = (TextView)findViewById(R.id.album_selected_items);
- mName = (TextView)findViewById(R.id.album_name);
- mItems = (TextView)findViewById(R.id.album_items);
- mOverflowButton = findViewById(R.id.overflow);
- mOverflowButton.setOnClickListener(this);
-
updateView(mAlbum);
}
@@ -180,7 +212,6 @@ public class AlbumInfo extends RelativeLayout
onPreparePopupMenu(popup.getMenu());
popup.setOnMenuItemClickListener(this);
popup.show();
- return;
}
}
@@ -195,6 +226,10 @@ public class AlbumInfo extends RelativeLayout
} else {
popup.findItem(R.id.mnu_deselect_album).setVisible(false);
}
+ if (mAlbumMode) {
+ popup.findItem(R.id.mnu_select_all).setVisible(false);
+ popup.findItem(R.id.mnu_deselect_all).setVisible(false);
+ }
}
/**
@@ -211,6 +246,14 @@ public class AlbumInfo extends RelativeLayout
doSelection(false);
break;
+ case R.id.mnu_select_all:
+ notifyPictureSelectionChanged(true);
+ break;
+
+ case R.id.mnu_deselect_all:
+ notifyPictureSelectionChanged(false);
+ break;
+
default:
return false;
}
@@ -226,8 +269,8 @@ public class AlbumInfo extends RelativeLayout
setSelected(selected);
mAlbum.setSelected(selected);
mAlbum.setSelectedItems(new ArrayList<String>());
- updateView(mAlbum);
notifySelectionChanged();
+ updateView(mAlbum);
}
/**
@@ -245,40 +288,80 @@ public class AlbumInfo extends RelativeLayout
}
/**
+ * Method that notifies to all the registered callbacks that the selection
+ * was changed
+ */
+ private void notifyPictureSelectionChanged(boolean selected) {
+ for (CallbacksListener callback : mCallbacks) {
+ if (selected) {
+ callback.onAllPicturesSelected(mAlbum);
+ } else {
+ callback.onAllPicturesDeselected(mAlbum);
+ }
+ }
+ }
+
+ /**
+ * Method that sets the album
+ *
+ * @param album The album
+ */
+ public void setAlbum(Album album) {
+ mAlbum = album;
+ }
+
+ /**
* Method that updates the view
*
* @param album The album data
*/
@SuppressWarnings("boxing")
public void updateView(Album album) {
- mAlbum = album;
+ // Destroy the update drawable task
+ if (mTask != null && (mTask.getStatus() == AsyncTask.Status.RUNNING ||
+ mTask.getStatus() == AsyncTask.Status.PENDING)) {
+ mTask.cancel(true);
+ }
+
+ // Retrieve the views references
+ if (mIcon == null) {
+ mIcon = (ImageView)findViewById(R.id.album_thumbnail);
+ mSelectedItems = (TextView)findViewById(R.id.album_selected_items);
+ mName = (TextView)findViewById(R.id.album_name);
+ mItems = (TextView)findViewById(R.id.album_items);
+ mOverflowButton = findViewById(R.id.overflow_button);
+ mOverflowButton.setOnClickListener(this);
+ }
- if (mAlbum != null && mIcon != null) {
+ // Update the views
+ if (album != null) {
Resources res = getContext().getResources();
- int selectedItems = mAlbum.getSelectedItems().size();
+ setAlbum(album);
+
+ int selectedItems = album.getSelectedItems().size();
String count = String.valueOf(selectedItems);
if (selectedItems > 99) {
- count += "+";
+ count = "99+";
}
mSelectedItems.setText(count);
- mSelectedItems.setVisibility(mAlbum.isSelected() ? View.INVISIBLE : View.VISIBLE);
- mName.setText(mAlbum.getName());
- int items = mAlbum.getItems().size();
+ mSelectedItems.setVisibility(album.isSelected() ? View.INVISIBLE : View.VISIBLE);
+ mName.setText(album.getName());
+ int items = album.getItems().size();
mItems.setText(String.format(res.getQuantityText(
R.plurals.album_number_of_pictures, items).toString(), items));
setSelected(album.isSelected());
- if (mTask == null) {
- post(new Runnable() {
- @Override
- public void run() {
- // Show as icon, the first picture
- mTask = new AsyncPictureLoaderTask(getContext(), mIcon);
- mTask.execute(new File(mAlbum.getItems().get(0)));
- }
- });
+ Drawable dw = album.getIcon();
+ mIcon.setImageDrawable(dw);
+ if (dw == null) {
+ mIcon.setImageDrawable(null);
+
+ // Show as icon, the first picture
+ mTask = new AsyncPictureLoaderTask(getContext(), mIcon, new OnPictureLoaded(album));
+ mTask.execute(new File(album.getItems().get(0).getPath()));
}
}
}
+
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/widgets/AlbumPictures.java b/src/org/cyanogenmod/wallpapers/photophase/widgets/AlbumPictures.java
deleted file mode 100644
index 5d0c60f..0000000
--- a/src/org/cyanogenmod/wallpapers/photophase/widgets/AlbumPictures.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod 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 org.cyanogenmod.wallpapers.photophase.widgets;
-
-import android.content.Context;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.LinearLayout;
-import android.widget.PopupMenu;
-import android.widget.PopupMenu.OnMenuItemClickListener;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import org.cyanogenmod.wallpapers.photophase.R;
-import org.cyanogenmod.wallpapers.photophase.model.Album;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A view that contains the pictures of an album
- */
-public class AlbumPictures extends RelativeLayout
- implements OnClickListener, OnMenuItemClickListener {
-
- private static final int SELECTION_SELECT_ALL = 1;
- private static final int SELECTION_DESELECT_ALL = 2;
- private static final int SELECTION_INVERT = 3;
-
- /**
- * A convenient listener for receive events of the AlbumPictures class
- *
- */
- public interface CallbacksListener {
- /**
- * Invoked when the user pressed the back button
- */
- void onBackButtonClick(View v);
-
- /**
- * Invoked when the selection was changed
- *
- * @param album The album
- */
- void onSelectionChanged(Album album);
- }
-
- private List<CallbacksListener> mCallbacks;
-
- private Handler mHandler;
-
- /*package*/ PicturesView mScroller;
- /*package*/ LinearLayout mHolder;
- private View mBackButton;
- private View mOverflowButton;
-
- private boolean mInitialized;
-
- /*package*/ Album mAlbum;
-
- /**
- * Constructor of <code>AlbumPictures</code>.
- *
- * @param context The current context
- */
- public AlbumPictures(Context context) {
- super(context);
- init();
- }
-
- /**
- * Constructor of <code>AlbumPictures</code>.
- *
- * @param context The current context
- * @param attrs The attributes of the XML tag that is inflating the view.
- */
- public AlbumPictures(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
-
- /**
- * Constructor of <code>AlbumPictures</code>.
- *
- * @param context The current context
- * @param attrs The attributes of the XML tag that is inflating the view.
- * @param defStyle The default style to apply to this view. If 0, no style
- * will be applied (beyond what is included in the theme). This may
- * either be an attribute resource, whose value will be retrieved
- * from the current theme, or an explicit style resource.
- */
- public AlbumPictures(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init();
- }
-
- /**
- * Method that initializes the internal references
- */
- private void init() {
- mCallbacks = new ArrayList<AlbumPictures.CallbacksListener>();
- mHandler = new Handler();
- mInitialized = false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- mScroller = (PicturesView)findViewById(R.id.album_pictures_scroller);
- mHolder = (LinearLayout)findViewById(R.id.album_pictures_holder);
- mBackButton = findViewById(R.id.back);
- mBackButton.setOnClickListener(this);
- mOverflowButton = findViewById(R.id.overflow);
- mOverflowButton.setOnClickListener(this);
- TextView title = (TextView)findViewById(R.id.album_pictures_title);
- title.setText(mAlbum.getName());
-
- updateView(mAlbum, false);
- }
-
- /**
- * Method that adds the class that will be listen for events of this class
- *
- * @param callback The callback class
- */
- public void addCallBackListener(CallbacksListener callback) {
- this.mCallbacks.add(callback);
- }
-
- /**
- * Method that removes the class from the current callbacks
- *
- * @param callback The callback class
- */
- public void removeCallBackListener(CallbacksListener callback) {
- this.mCallbacks.remove(callback);
- }
-
- /**
- * Method that set the data of the view
- *
- * @param album The album data
- * @param recreate If the view should be recreated
- */
- public void updateView(Album album, boolean recreate) {
- mAlbum = album;
- recreateView(false);
- }
-
- /**
- * Method that recreates the the view
- *
- * @param propagateShow If should propagate the show event
- */
- private void recreateView(final boolean propagateShow) {
- if (mHolder != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- int pictures = mHolder.getChildCount();
- if (pictures != mAlbum.getItems().size()) {
- // Recreate the pictures
- final LayoutInflater inflater = (LayoutInflater) getContext().
- getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mScroller.cancelTasks();
- mHolder.removeAllViews();
- for (final String picture : mAlbum.getItems()) {
- View v = createPicture(inflater, picture, isPictureSelected(picture));
- mHolder.addView(v);
- }
- } else {
- int i = 0;
- for (final String picture : mAlbum.getItems()) {
- View v = mHolder.getChildAt(i);
- v.setSelected(isPictureSelected(picture));
- i++;
- }
- }
- if (propagateShow) {
- mScroller.onShow();
- }
- }
- });
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onClick(View v) {
- // Check which is the view pressed
- if (v.equals(mBackButton)) {
- for (CallbacksListener callback : mCallbacks) {
- callback.onBackButtonClick(v);
- }
- return;
- }
- if (v.equals(mOverflowButton)) {
- PopupMenu popup = new PopupMenu(getContext(), v);
- MenuInflater inflater = popup.getMenuInflater();
- inflater.inflate(R.menu.pictures_actions, popup.getMenu());
- popup.setOnMenuItemClickListener(this);
- popup.show();
- return;
- }
-
- // A picture view
- v.setSelected(!v.isSelected());
- notifySelectionChanged();
- }
-
- /**
- * Method that notifies to all the registered callbacks that the selection
- * was changed
- */
- private void notifySelectionChanged() {
- List<String> selection = new ArrayList<String>();
- int count = mHolder.getChildCount();
- for (int i = 0; i < count; i++) {
- View v = mHolder.getChildAt(i);
- if (v.isSelected()) {
- selection.add((String)v.getTag());
- }
- }
- mAlbum.setSelectedItems(selection);
- mAlbum.setSelected(false);
-
- for (CallbacksListener callback : mCallbacks) {
- callback.onSelectionChanged(mAlbum);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.mnu_select_all:
- doSelection(SELECTION_SELECT_ALL);
- break;
-
- case R.id.mnu_deselect_all:
- doSelection(SELECTION_DESELECT_ALL);
- break;
-
- case R.id.mnu_invert_selection:
- doSelection(SELECTION_INVERT);
- break;
-
- default:
- return false;
- }
- return true;
- }
-
- /**
- * Operate over the selection of the pictures of this album.
- *
- * @param action Takes the next values:
- * <ul>
- * <li>SELECTION_SELECT_ALL: select all</li>
- * <li>SELECTION_DESELECT_ALL: deselect all</li>
- * <li>SELECTION_INVERT: invert selection</li>
- * </ul>
- */
- private void doSelection(int action) {
- int count = mHolder.getChildCount();
- for (int i = 0; i < count; i++) {
- View v = mHolder.getChildAt(i);
-
- boolean selected = true;
- if (action == SELECTION_DESELECT_ALL) {
- selected = false;
- } else if (action == SELECTION_INVERT) {
- selected = !v.isSelected();
- }
- v.setSelected(selected);
- }
- notifySelectionChanged();
- }
-
- /**
- * Method invoked when the view is displayed
- */
- public void onShow() {
- if (!mInitialized) {
- mInitialized = true;
- recreateView(true);
- }
- }
-
- /**
- * Method that creates a new picture view
- *
- * @param inflater The inflater of the parent view
- * @param picture The path of the picture
- * @param selected If the picture is selected
- */
- /*package*/ View createPicture(LayoutInflater inflater, String picture, boolean selected) {
- final View v = inflater.inflate(R.layout.picture_item, mHolder, false);
- v.setTag(picture);
- v.setSelected(selected);
- v.setOnClickListener(this);
- return v;
- }
-
- /**
- * Method that check if a picture is selected
- *
- * @param picture The picture to check
- * @return boolean whether the picture is selected
- */
- /*package*/ boolean isPictureSelected(String picture) {
- for (String item : mAlbum.getSelectedItems()) {
- if (item.compareTo(picture) == 0) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/widgets/CardLayout.java b/src/org/cyanogenmod/wallpapers/photophase/widgets/CardLayout.java
deleted file mode 100644
index e1953cd..0000000
--- a/src/org/cyanogenmod/wallpapers/photophase/widgets/CardLayout.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod 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 org.cyanogenmod.wallpapers.photophase.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.animation.AnimationUtils;
-import android.widget.LinearLayout;
-
-import org.cyanogenmod.wallpapers.photophase.R;
-
-/**
- * A "Google Now Card Layout" like layout
- */
-public class CardLayout extends LinearLayout {
-
- boolean inverted = false;
-
- /**
- * Constructor of <code>CardLayout</code>.
- *
- * @param context The current context
- */
- public CardLayout(Context context) {
- super(context);
- }
-
- /**
- * Constructor of <code>CardLayout</code>.
- *
- * @param context The current context
- * @param attrs The attributes of the XML tag that is inflating the view.
- */
- public CardLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- /**
- * Constructor of <code>CardLayout</code>.
- *
- * @param context The current context
- * @param attrs The attributes of the XML tag that is inflating the view.
- * @param defStyle The default style to apply to this view. If 0, no style
- * will be applied (beyond what is included in the theme). This may
- * either be an attribute resource, whose value will be retrieved
- * from the current theme, or an explicit style resource.
- */
- public CardLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- /**
- * Add a new card to the layout
- *
- * @param card The card view to add
- * @param animate If the add should be animated
- */
- public void addCard(final View card, final boolean animate) {
- post(new Runnable() {
- @Override
- public void run() {
- addView(card);
- if (animate) {
- if (inverted) {
- card.startAnimation(AnimationUtils.loadAnimation(
- getContext(), R.anim.cards_animation_up_right));
- } else {
- card.startAnimation(AnimationUtils.loadAnimation(
- getContext(), R.anim.cards_animation_up_left));
- }
- inverted = !inverted;
- }
- }
- });
- }
-}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/widgets/DispositionView.java b/src/org/cyanogenmod/wallpapers/photophase/widgets/DispositionView.java
index 22d00a6..0bc462f 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/widgets/DispositionView.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/widgets/DispositionView.java
@@ -74,7 +74,7 @@ public class DispositionView extends RelativeLayout implements OnLongClickListen
private int mCols;
private int mRows;
- /*package*/ View mTarget;
+ View mTarget;
private ResizeFrame mResizeFrame;
private int mInternalPadding;
private Rect mOldResizeFrameLocation;
@@ -323,7 +323,7 @@ public class DispositionView extends RelativeLayout implements OnLongClickListen
*
* @param target The disposition target
*/
- /*package*/ void finishDeleteAnimation(Disposition target) {
+ void finishDeleteAnimation(Disposition target) {
removeView(mTarget);
mDispositions.remove(target);
Collections.sort(mDispositions);
@@ -514,7 +514,7 @@ public class DispositionView extends RelativeLayout implements OnLongClickListen
*
* @return The target view
*/
- /*package*/ View findTargetFromResizeFrame() {
+ View findTargetFromResizeFrame() {
int count = getChildCount();
for (int i = 0; i < count; i++) {
View v = getChildAt(i);
@@ -552,7 +552,7 @@ public class DispositionView extends RelativeLayout implements OnLongClickListen
*
* @param v The target view
*/
- /*package*/ boolean selectTarget(View v) {
+ boolean selectTarget(View v) {
//Do not do long click if we do not have a target
if (mTarget != null && v.equals(mTarget)) return false;
diff --git a/src/org/cyanogenmod/wallpapers/photophase/widgets/PictureItemView.java b/src/org/cyanogenmod/wallpapers/photophase/widgets/PictureItemView.java
new file mode 100644
index 0000000..aac7e24
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/widgets/PictureItemView.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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 org.cyanogenmod.wallpapers.photophase.widgets;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.AsyncTask.Status;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import org.cyanogenmod.wallpapers.photophase.R;
+import org.cyanogenmod.wallpapers.photophase.model.Picture;
+import org.cyanogenmod.wallpapers.photophase.tasks.AsyncPictureLoaderTask;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A view that contains the view of the picture of an abbum
+ */
+public class PictureItemView extends FrameLayout {
+
+ /**
+ * A convenient listener for receive events of the PictureItemView class
+ *
+ */
+ public interface CallbacksListener {
+ /**
+ * Invoked when an Picture was selected
+ *
+ * @param Picture The Picture
+ */
+ void onPictureSelected(Picture Picture);
+
+ /**
+ * Invoked when an Picture was deselected
+ *
+ * @param Picture The Picture
+ */
+ void onPictureDeselected(Picture Picture);
+ }
+
+ private List<CallbacksListener> mCallbacks;
+
+ private Picture mPicture;
+
+ private AsyncPictureLoaderTask mTask;
+
+ private ImageView mIcon;
+
+ /**
+ * Constructor of <code>PictureItemView</code>.
+ *
+ * @param context The current context
+ */
+ public PictureItemView(Context context) {
+ super(context);
+ init();
+ }
+
+ /**
+ * Constructor of <code>PictureItemView</code>.
+ *
+ * @param context The current context
+ * @param attrs The attributes of the XML tag that is inflating the view.
+ */
+ public PictureItemView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ /**
+ * Constructor of <code>PictureItemView</code>.
+ *
+ * @param context The current context
+ * @param attrs The attributes of the XML tag that is inflating the view.
+ * @param defStyle The default style to apply to this view. If 0, no style
+ * will be applied (beyond what is included in the theme). This may
+ * either be an attribute resource, whose value will be retrieved
+ * from the current theme, or an explicit style resource.
+ */
+ public PictureItemView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ /**
+ * Method that initializes the internal references
+ */
+ private void init() {
+ mCallbacks = new ArrayList<PictureItemView.CallbacksListener>();
+ }
+
+ /**
+ * Method that adds the class that will be listen for events of this class
+ *
+ * @param callback The callback class
+ */
+ public void addCallBackListener(CallbacksListener callback) {
+ this.mCallbacks.add(callback);
+ }
+
+ /**
+ * Method that removes the class from the current callbacks
+ *
+ * @param callback The callback class
+ */
+ public void removeCallBackListener(CallbacksListener callback) {
+ this.mCallbacks.remove(callback);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ updateView(mPicture, true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ // Cancel pending tasks
+ if (mTask != null && mTask.getStatus().compareTo(Status.PENDING) == 0) {
+ mTask.cancel(true);
+ }
+ }
+
+ /**
+ * Method that returns the picture
+ *
+ * @return Picture The picture
+ */
+ public Picture getPicture() {
+ return mPicture;
+ }
+
+ /**
+ * Method that sets the picture
+ *
+ * @param picture The picture
+ */
+ public void setPicture(Picture picture) {
+ mPicture = picture;
+ }
+
+ /**
+ * Method that updates the view
+ *
+ * @param picture The picture data
+ */
+ public void updateView(Picture picture, boolean refreshIcon) {
+ // Destroy the update drawable task
+ if (mTask != null && (mTask.getStatus() == AsyncTask.Status.RUNNING ||
+ mTask.getStatus() == AsyncTask.Status.PENDING)) {
+ mTask.cancel(true);
+ }
+
+ // Retrieve the views references
+ if (mIcon == null) {
+ mIcon = (ImageView)findViewById(R.id.picture_thumbnail);
+ }
+
+ // Update the views
+ if (picture != null) {
+ setPicture(picture);
+
+ setSelected(picture.isSelected());
+
+ // Do no try to cache the images (this generates a lot of memory an we want
+ // to have a low memory footprint)
+ if (refreshIcon) {
+ mIcon.setImageDrawable(null);
+
+ // Show as icon, the first picture
+ mTask = new AsyncPictureLoaderTask(getContext(), mIcon);
+ mTask.execute(new File(picture.getPath()));
+ }
+ }
+ }
+
+}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/widgets/PicturesView.java b/src/org/cyanogenmod/wallpapers/photophase/widgets/PicturesView.java
deleted file mode 100644
index 0744751..0000000
--- a/src/org/cyanogenmod/wallpapers/photophase/widgets/PicturesView.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod 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 org.cyanogenmod.wallpapers.photophase.widgets;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.AsyncTask.Status;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.view.ViewGroup;
-import android.widget.HorizontalScrollView;
-import android.widget.ImageView;
-
-import org.cyanogenmod.wallpapers.photophase.R;
-import org.cyanogenmod.wallpapers.photophase.tasks.AsyncPictureLoaderTask;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Iterator;
-
-/**
- * A view that contains all the pictures of an album
- */
-public class PicturesView extends HorizontalScrollView {
-
- private HashMap<File, AsyncPictureLoaderTask> mTasks;
- private Handler mHandler;
-
- /**
- * Constructor of <code>PicturesView</code>.
- *
- * @param context The current context
- */
- public PicturesView(Context context) {
- super(context);
- init();
- }
-
- /**
- * Constructor of <code>PicturesView</code>.
- *
- * @param context The current context
- * @param attrs The attributes of the XML tag that is inflating the view.
- */
- public PicturesView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
-
- /**
- * Constructor of <code>PicturesView</code>.
- *
- * @param context The current context
- * @param attrs The attributes of the XML tag that is inflating the view.
- * @param defStyle The default style to apply to this view. If 0, no style
- * will be applied (beyond what is included in the theme). This may
- * either be an attribute resource, whose value will be retrieved
- * from the current theme, or an explicit style resource.
- */
- public PicturesView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init();
- }
-
- /**
- * Method that initializes the structures of this class
- */
- private void init() {
- mTasks = new HashMap<File, AsyncPictureLoaderTask>();
- mHandler = new Handler();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- cancelTasks();
- }
-
- /**
- * Method that removes all tasks
- */
- public void cancelTasks() {
- // Cancel all the pending task
- Iterator<AsyncPictureLoaderTask> it = mTasks.values().iterator();
- while (it.hasNext()) {
- AsyncPictureLoaderTask task = it.next();
- if (task.getStatus().compareTo(Status.PENDING) == 0) {
- task.cancel(true);
- }
- }
- mTasks.clear();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void onScrollChanged(int l, int t, int oldl, int oldt) {
- super.onScrollChanged(l, t, oldl, oldt);
- // Estimated velocity (in some moment we must obtain some scrolling with an estimated
- // velocity below of 3)
- int velocity = Math.abs(l - oldl);
- if (velocity <= 3) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- requestLoadOfPendingPictures();
- }
- });
- }
- }
-
- /**
- * Method invoked when the view is displayed
- */
- public void onShow() {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- requestLoadOfPendingPictures();
- }
- });
- }
-
- /**
- * Method that load in background all visible and pending pictures
- */
- /*package*/ void requestLoadOfPendingPictures() {
- // Get the visible rect
- Rect r = new Rect();
- getHitRect(r);
-
- // Get all the image views
- ViewGroup vg = (ViewGroup)getChildAt(0);
- int count = vg.getChildCount();
- for (int i = 0; i < count; i++) {
- ViewGroup picView = (ViewGroup)vg.getChildAt(i);
- File image = new File((String)picView.getTag());
- if (picView.getLocalVisibleRect(r) && !mTasks.containsKey(image)) {
- ImageView iv = (ImageView)picView.findViewById(R.id.picture_thumbnail);
- AsyncPictureLoaderTask task = new AsyncPictureLoaderTask(getContext(), iv);
- task.execute(image);
- mTasks.put(image, task);
- }
- }
- }
-}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/widgets/VerticalEndlessScroller.java b/src/org/cyanogenmod/wallpapers/photophase/widgets/VerticalEndlessScroller.java
deleted file mode 100644
index 67a1f17..0000000
--- a/src/org/cyanogenmod/wallpapers/photophase/widgets/VerticalEndlessScroller.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod 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 org.cyanogenmod.wallpapers.photophase.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ScrollView;
-
-/**
- * A scroll view that notifies the end of the scroll to create new views
- * dynamically.
- */
-public class VerticalEndlessScroller extends ScrollView {
-
- /**
- * Interface to communicate end-scroll events
- */
- public interface OnEndScrollListener {
- /**
- * Called when the scroll reachs the end of the scroll
- */
- void onEndScroll();
- }
-
- private OnEndScrollListener mCallback;
- private int mEndPadding = 0;
- private boolean mSwitch = false;
-
- /**
- * Constructor of <code>VerticalEndlessScroller</code>.
- *
- * @param context The current context
- */
- public VerticalEndlessScroller(Context context) {
- super(context);
- }
-
- /**
- * Constructor of <code>VerticalEndlessScroller</code>.
- *
- * @param context The current context
- * @param attrs The attributes of the XML tag that is inflating the view.
- */
- public VerticalEndlessScroller(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- /**
- * Constructor of <code>VerticalEndlessScroller</code>.
- *
- * @param context The current context
- * @param attrs The attributes of the XML tag that is inflating the view.
- * @param defStyle The default style to apply to this view. If 0, no style
- * will be applied (beyond what is included in the theme). This may
- * either be an attribute resource, whose value will be retrieved
- * from the current theme, or an explicit style resource.
- */
- public VerticalEndlessScroller(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- /**
- * Method that set the callback for notify end-scroll events
- *
- * @param callback The callback
- */
- public void setCallback(OnEndScrollListener callback) {
- mCallback = callback;
- }
-
- /**
- * Method that set the end padding for fired the event
- *
- * @param endPadding The end padding
- */
- public void setEndPadding(int endPadding) {
- this.mEndPadding = endPadding;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void onScrollChanged(int l, int t, int oldl, int oldt) {
- // We take the last child in the scrollview
- View view = getChildAt(getChildCount() - 1);
- int diff = (view.getBottom() - (getHeight() + getScrollY()));
- if ((!mSwitch && diff <= mEndPadding)) {
- if (mCallback != null) {
- mCallback.onEndScroll();
- mSwitch = true;
- return;
- }
- } else if (diff > mEndPadding) {
- mSwitch = false;
- }
- }
-
-}