OSDN Git Service

Fix 5299746: New UI layout, part 2.
authorChih-Chung Chang <chihchung@google.com>
Mon, 19 Sep 2011 03:09:39 +0000 (11:09 +0800)
committerChih-Chung Chang <chihchung@google.com>
Tue, 20 Sep 2011 04:18:21 +0000 (12:18 +0800)
- Replace various icons and add xhdpi/sw600dp-mdpi versions of them.
- When user press on the thumbnails, show a color overlay on it.
- For a wide (w/h > 2) picture, add panorama overlay on it.
- Align photo count label position when there is no icon for it.
- Adjust offline page layout.

Change-Id: I327d25806e99843bfa05d3ca0e9be5a8f9375595

50 files changed:
res/drawable-hdpi/frame_overlay_gallery_ptp.png [new file with mode: 0644]
res/drawable-hdpi/grid_pressed.9.png [new file with mode: 0644]
res/drawable-hdpi/ic_album_overlay_ptp_holo.png [deleted file]
res/drawable-hdpi/ic_gallery_play.png
res/drawable-hdpi/manage_bar.9.png [deleted file]
res/drawable-mdpi/frame_overlay_gallery_ptp.png [new file with mode: 0644]
res/drawable-mdpi/grid_pressed.9.png [new file with mode: 0644]
res/drawable-mdpi/ic_album_overlay_ptp_holo.png [deleted file]
res/drawable-mdpi/ic_gallery_play.png
res/drawable-mdpi/manage_bar.9.png [deleted file]
res/drawable-sw600dp-mdpi/ic_pan_thumb.png [new file with mode: 0644]
res/drawable-sw600dp-mdpi/ic_video_thumb.png [new file with mode: 0644]
res/drawable-xhdpi/frame_overlay_gallery_camera.png [new file with mode: 0644]
res/drawable-xhdpi/frame_overlay_gallery_folder.png [new file with mode: 0644]
res/drawable-xhdpi/frame_overlay_gallery_picasa.png [new file with mode: 0644]
res/drawable-xhdpi/frame_overlay_gallery_ptp.png [new file with mode: 0644]
res/drawable-xhdpi/grid_pressed.9.png [new file with mode: 0644]
res/drawable-xhdpi/grid_selected.9.png [new file with mode: 0644]
res/drawable-xhdpi/ic_gallery_play.png [new file with mode: 0644]
res/drawable-xhdpi/ic_menu_make_offline.png [new file with mode: 0644]
res/drawable-xhdpi/ic_pan_thumb.png [new file with mode: 0644]
res/drawable-xhdpi/ic_video_thumb.png [new file with mode: 0644]
res/drawable-xhdpi/thumb_selected.png [new file with mode: 0644]
res/layout-w480dp/manage_offline_bar.xml [deleted file]
res/layout/manage_offline_bar.xml
res/values-land/dimensions.xml [new file with mode: 0644]
res/values/dimensions.xml
src/com/android/gallery3d/app/AlbumPage.java
src/com/android/gallery3d/app/AlbumSetPage.java
src/com/android/gallery3d/app/Config.java
src/com/android/gallery3d/app/ManageCachePage.java
src/com/android/gallery3d/data/LocalImage.java
src/com/android/gallery3d/data/LocalVideo.java
src/com/android/gallery3d/data/MediaItem.java
src/com/android/gallery3d/data/MtpImage.java
src/com/android/gallery3d/data/UriImage.java
src/com/android/gallery3d/ui/AlbumSetSlidingWindow.java
src/com/android/gallery3d/ui/AlbumSetView.java
src/com/android/gallery3d/ui/AlbumSlidingWindow.java
src/com/android/gallery3d/ui/FilmStripView.java
src/com/android/gallery3d/ui/GridDrawer.java
src/com/android/gallery3d/ui/HighlightDrawer.java
src/com/android/gallery3d/ui/IconDrawer.java
src/com/android/gallery3d/ui/ManageCacheDrawer.java
src/com/android/gallery3d/ui/SelectionDrawer.java
src/com/android/gallery3d/ui/SelectionManager.java
src/com/android/gallery3d/ui/SlotView.java
src/com/android/gallery3d/ui/StripDrawer.java
src/com/android/gallery3d/util/GalleryUtils.java
tests/src/com/android/gallery3d/data/MockItem.java

diff --git a/res/drawable-hdpi/frame_overlay_gallery_ptp.png b/res/drawable-hdpi/frame_overlay_gallery_ptp.png
new file mode 100644 (file)
index 0000000..cb9ef50
Binary files /dev/null and b/res/drawable-hdpi/frame_overlay_gallery_ptp.png differ
diff --git a/res/drawable-hdpi/grid_pressed.9.png b/res/drawable-hdpi/grid_pressed.9.png
new file mode 100644 (file)
index 0000000..36486ae
Binary files /dev/null and b/res/drawable-hdpi/grid_pressed.9.png differ
diff --git a/res/drawable-hdpi/ic_album_overlay_ptp_holo.png b/res/drawable-hdpi/ic_album_overlay_ptp_holo.png
deleted file mode 100644 (file)
index b725840..0000000
Binary files a/res/drawable-hdpi/ic_album_overlay_ptp_holo.png and /dev/null differ
index e475e1f..e4060e5 100644 (file)
Binary files a/res/drawable-hdpi/ic_gallery_play.png and b/res/drawable-hdpi/ic_gallery_play.png differ
diff --git a/res/drawable-hdpi/manage_bar.9.png b/res/drawable-hdpi/manage_bar.9.png
deleted file mode 100644 (file)
index 336c2d7..0000000
Binary files a/res/drawable-hdpi/manage_bar.9.png and /dev/null differ
diff --git a/res/drawable-mdpi/frame_overlay_gallery_ptp.png b/res/drawable-mdpi/frame_overlay_gallery_ptp.png
new file mode 100644 (file)
index 0000000..95ba8f0
Binary files /dev/null and b/res/drawable-mdpi/frame_overlay_gallery_ptp.png differ
diff --git a/res/drawable-mdpi/grid_pressed.9.png b/res/drawable-mdpi/grid_pressed.9.png
new file mode 100644 (file)
index 0000000..ecb51bd
Binary files /dev/null and b/res/drawable-mdpi/grid_pressed.9.png differ
diff --git a/res/drawable-mdpi/ic_album_overlay_ptp_holo.png b/res/drawable-mdpi/ic_album_overlay_ptp_holo.png
deleted file mode 100644 (file)
index adbd3d1..0000000
Binary files a/res/drawable-mdpi/ic_album_overlay_ptp_holo.png and /dev/null differ
index 183d75e..753231d 100644 (file)
Binary files a/res/drawable-mdpi/ic_gallery_play.png and b/res/drawable-mdpi/ic_gallery_play.png differ
diff --git a/res/drawable-mdpi/manage_bar.9.png b/res/drawable-mdpi/manage_bar.9.png
deleted file mode 100644 (file)
index e42b92b..0000000
Binary files a/res/drawable-mdpi/manage_bar.9.png and /dev/null differ
diff --git a/res/drawable-sw600dp-mdpi/ic_pan_thumb.png b/res/drawable-sw600dp-mdpi/ic_pan_thumb.png
new file mode 100644 (file)
index 0000000..e249029
Binary files /dev/null and b/res/drawable-sw600dp-mdpi/ic_pan_thumb.png differ
diff --git a/res/drawable-sw600dp-mdpi/ic_video_thumb.png b/res/drawable-sw600dp-mdpi/ic_video_thumb.png
new file mode 100644 (file)
index 0000000..743cec2
Binary files /dev/null and b/res/drawable-sw600dp-mdpi/ic_video_thumb.png differ
diff --git a/res/drawable-xhdpi/frame_overlay_gallery_camera.png b/res/drawable-xhdpi/frame_overlay_gallery_camera.png
new file mode 100644 (file)
index 0000000..e9bc7cc
Binary files /dev/null and b/res/drawable-xhdpi/frame_overlay_gallery_camera.png differ
diff --git a/res/drawable-xhdpi/frame_overlay_gallery_folder.png b/res/drawable-xhdpi/frame_overlay_gallery_folder.png
new file mode 100644 (file)
index 0000000..cbafc85
Binary files /dev/null and b/res/drawable-xhdpi/frame_overlay_gallery_folder.png differ
diff --git a/res/drawable-xhdpi/frame_overlay_gallery_picasa.png b/res/drawable-xhdpi/frame_overlay_gallery_picasa.png
new file mode 100644 (file)
index 0000000..e7463a4
Binary files /dev/null and b/res/drawable-xhdpi/frame_overlay_gallery_picasa.png differ
diff --git a/res/drawable-xhdpi/frame_overlay_gallery_ptp.png b/res/drawable-xhdpi/frame_overlay_gallery_ptp.png
new file mode 100644 (file)
index 0000000..57fb7e4
Binary files /dev/null and b/res/drawable-xhdpi/frame_overlay_gallery_ptp.png differ
diff --git a/res/drawable-xhdpi/grid_pressed.9.png b/res/drawable-xhdpi/grid_pressed.9.png
new file mode 100644 (file)
index 0000000..f2fed2d
Binary files /dev/null and b/res/drawable-xhdpi/grid_pressed.9.png differ
diff --git a/res/drawable-xhdpi/grid_selected.9.png b/res/drawable-xhdpi/grid_selected.9.png
new file mode 100644 (file)
index 0000000..d0f4a22
Binary files /dev/null and b/res/drawable-xhdpi/grid_selected.9.png differ
diff --git a/res/drawable-xhdpi/ic_gallery_play.png b/res/drawable-xhdpi/ic_gallery_play.png
new file mode 100644 (file)
index 0000000..70901e5
Binary files /dev/null and b/res/drawable-xhdpi/ic_gallery_play.png differ
diff --git a/res/drawable-xhdpi/ic_menu_make_offline.png b/res/drawable-xhdpi/ic_menu_make_offline.png
new file mode 100644 (file)
index 0000000..808e2d1
Binary files /dev/null and b/res/drawable-xhdpi/ic_menu_make_offline.png differ
diff --git a/res/drawable-xhdpi/ic_pan_thumb.png b/res/drawable-xhdpi/ic_pan_thumb.png
new file mode 100644 (file)
index 0000000..6e3405c
Binary files /dev/null and b/res/drawable-xhdpi/ic_pan_thumb.png differ
diff --git a/res/drawable-xhdpi/ic_video_thumb.png b/res/drawable-xhdpi/ic_video_thumb.png
new file mode 100644 (file)
index 0000000..e0f53b3
Binary files /dev/null and b/res/drawable-xhdpi/ic_video_thumb.png differ
diff --git a/res/drawable-xhdpi/thumb_selected.png b/res/drawable-xhdpi/thumb_selected.png
new file mode 100644 (file)
index 0000000..c6536bc
Binary files /dev/null and b/res/drawable-xhdpi/thumb_selected.png differ
diff --git a/res/layout-w480dp/manage_offline_bar.xml b/res/layout-w480dp/manage_offline_bar.xml
deleted file mode 100644 (file)
index d44ecf0..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="@drawable/manage_bar">
-    <LinearLayout android:id="@+id/cache_bar"
-            android:gravity="center_vertical"
-            android:orientation="horizontal"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-        <TextView android:layout_width="wrap_content"
-                android:paddingLeft="2dp"
-                android:layout_height="wrap_content"
-                android:gravity="center_vertical|left"
-                android:drawablePadding="3dp"
-                android:text="@string/make_available_offline"
-                android:drawableLeft="@drawable/ic_manage_pin"/>
-        <ProgressBar android:id="@+id/progress"
-                style="?android:attr/progressBarStyleHorizontal"
-                android:max="100"
-                android:progress="30"
-                android:secondaryProgress="65"
-                android:layout_marginLeft="5dp"
-                android:layout_marginRight="5dp"
-                android:layout_weight="1"
-                android:layout_width="match_parent"
-                android:layout_height="10dp"/>
-        <TextView android:id="@+id/status"
-                android:paddingRight="2dp"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"/>
-        <View android:layout_width="2dp"
-                android:layout_height="match_parent"
-                android:background="@android:drawable/divider_horizontal_dark" />
-        <Button android:id="@+id/done"
-                style="?android:attr/borderlessButtonStyle"
-                android:text="@string/done"
-                android:layout_weight="0"
-                android:layout_alignParentBottom="true"
-                android:layout_alignParentLeft="true"
-                android:layout_alignParentRight="true"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"/>
-    </LinearLayout>
-</FrameLayout>
index b4bcec2..81853ed 100644 (file)
      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:background="@drawable/manage_bar">
-    <LinearLayout android:id="@+id/cache_bar"
-            android:orientation="horizontal"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-        <LinearLayout android:orientation="vertical"
-                android:paddingLeft="10dp"
-                android:paddingRight="5dp"
-                android:paddingBottom="5dp"
-                android:paddingTop="5dp"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_weight="1">
-            <TextView android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:gravity="bottom"
-                    android:drawablePadding="3dp"
-                    android:text="@string/make_available_offline"
-                    android:drawableRight="@drawable/ic_manage_pin_small"/>
-            <ProgressBar android:id="@+id/progress"
-                    style="?android:attr/progressBarStyleHorizontal"
-                    android:max="100"
-                    android:progress="30"
-                    android:secondaryProgress="65"
-                    android:layout_marginTop="2dp"
-                    android:layout_marginBottom="2dp"
-                    android:layout_width="match_parent"
-                    android:layout_height="3dp"/>
-            <TextView android:id="@+id/status"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"/>
-        </LinearLayout>
-        <View android:layout_width="2dp"
-                android:layout_height="match_parent"
-                android:background="@android:drawable/divider_horizontal_dark" />
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+    <RelativeLayout
+            android:layout_width="fill_parent"
+            android:layout_height="40dp">
+        <TextView android:id="@+id/status"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
+            android:layout_centerHorizontal="true" />
+        <ProgressBar android:id="@+id/progress"
+            style="?android:attr/progressBarStyleHorizontal"
+            android:max="100"
+            android:progress="30"
+            android:secondaryProgress="65"
+            android:layout_marginTop="2dp"
+            android:layout_marginBottom="2dp"
+            android:layout_width="130dp"
+            android:layout_height="4dp"
+            android:layout_below="@id/status"
+            android:layout_centerHorizontal="true"/>
+    </RelativeLayout>
+    <RelativeLayout android:layout_width="fill_parent"
+                android:layout_height="@dimen/manage_cache_bottom_height"
+                android:background="#1f1f1f">
+        <TextView android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/make_available_offline"
+            android:layout_alignParentLeft="true"
+            android:layout_centerVertical="true"
+            android:drawableLeft="@drawable/ic_manage_pin_small"
+            android:drawablePadding="3dp"/>
         <Button android:id="@+id/done"
-                style="?android:attr/borderlessButtonStyle"
-                android:text="@string/done"
-                android:layout_weight="0"
-                android:layout_alignParentBottom="true"
-                android:layout_alignParentLeft="true"
-                android:layout_alignParentRight="true"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"/>
-    </LinearLayout>
-</FrameLayout>
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:text="@string/done"
+            android:layout_alignParentRight="true"/>
+    </RelativeLayout>
+</LinearLayout>
diff --git a/res/values-land/dimensions.xml b/res/values-land/dimensions.xml
new file mode 100644 (file)
index 0000000..b5c5ed3
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <!-- for manage cache bar -->
+    <dimen name="manage_cache_bottom_height">39dp</dimen>
+</resources>
index 428de3a..2804bc9 100644 (file)
     <integer name="albumset_rows_port">4</integer>
     <dimen name="albumset_slot_gap">1dp</dimen>
 
-    <dimen name="albumset_dark_strip_height">40dp</dimen>
+    <dimen name="albumset_label_background_height">40dp</dimen>
     <dimen name="albumset_title_offset">3dp</dimen>
-    <dimen name="albumset_number_offset">4dp</dimen>
+    <dimen name="albumset_count_offset">4dp</dimen>
     <dimen name="albumset_title_font_size">14sp</dimen>
-    <dimen name="albumset_number_font_size">12sp</dimen>
+    <dimen name="albumset_count_font_size">12sp</dimen>
     <dimen name="albumset_left_margin">6dp</dimen>
     <dimen name="albumset_icon_size">26dp</dimen>
 
@@ -54,4 +54,6 @@
     <dimen name="filmstrip_bar_size">10dp</dimen>
     <dimen name="filmstrip_grip_width">96dp</dimen>
 
+    <!-- for manage cache bar -->
+    <dimen name="manage_cache_bottom_height">48dp</dimen>
 </resources>
index 1feb96e..55feb38 100644 (file)
@@ -148,6 +148,18 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
         }
     }
 
+    private void onDown(int index) {
+        MediaItem item = mAlbumDataAdapter.get(index);
+        Path path = (item == null) ? null : item.getPath();
+        mSelectionManager.setPressedPath(path);
+        mAlbumView.invalidate();
+    }
+
+    private void onUp() {
+        mSelectionManager.setPressedPath(null);
+        mAlbumView.invalidate();
+    }
+
     public void onSingleTapUp(int slotIndex) {
         MediaItem item = mAlbumDataAdapter.get(slotIndex);
         if (item == null) {
@@ -363,9 +375,20 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
         mRootPane.addComponent(mAlbumView);
         mAlbumView.setListener(new SlotView.SimpleListener() {
             @Override
+            public void onDown(int index) {
+                AlbumPage.this.onDown(index);
+            }
+
+            @Override
+            public void onUp() {
+                AlbumPage.this.onUp();
+            }
+
+            @Override
             public void onSingleTapUp(int slotIndex) {
                 AlbumPage.this.onSingleTapUp(slotIndex);
             }
+
             @Override
             public void onLongTap(int slotIndex) {
                 AlbumPage.this.onLongTap(slotIndex);
@@ -395,7 +418,8 @@ public class AlbumPage extends ActivityState implements GalleryActionBar.Cluster
     private void showDetails() {
         mShowDetails = true;
         if (mDetailsHelper == null) {
-            mHighlightDrawer = new HighlightDrawer(mActivity.getAndroidContext());
+            mHighlightDrawer = new HighlightDrawer(mActivity.getAndroidContext(),
+                    mSelectionManager);
             mDetailsHelper = new DetailsHelper(mActivity, mRootPane, mDetailsSource);
             mDetailsHelper.setCloseListener(new CloseListener() {
                 public void onClose() {
index eac1abc..0726ba1 100644 (file)
@@ -210,6 +210,18 @@ public class AlbumSetPage extends ActivityState implements
         }
     }
 
+    private void onDown(int index) {
+        MediaSet set = mAlbumSetDataAdapter.getMediaSet(index);
+        Path path = (set == null) ? null : set.getPath();
+        mSelectionManager.setPressedPath(path);
+        mAlbumSetView.invalidate();
+    }
+
+    private void onUp() {
+        mSelectionManager.setPressedPath(null);
+        mAlbumSetView.invalidate();
+    }
+
     public void onLongTap(int slotIndex) {
         if (mGetContent || mGetAlbum) return;
         if (mShowDetails) {
@@ -317,9 +329,20 @@ public class AlbumSetPage extends ActivityState implements
                 config.slotViewSpec, config.labelSpec);
         mAlbumSetView.setListener(new SlotView.SimpleListener() {
             @Override
+            public void onDown(int index) {
+                AlbumSetPage.this.onDown(index);
+            }
+
+            @Override
+            public void onUp() {
+                AlbumSetPage.this.onUp();
+            }
+
+            @Override
             public void onSingleTapUp(int slotIndex) {
                 AlbumSetPage.this.onSingleTapUp(slotIndex);
             }
+
             @Override
             public void onLongTap(int slotIndex) {
                 AlbumSetPage.this.onLongTap(slotIndex);
@@ -518,7 +541,8 @@ public class AlbumSetPage extends ActivityState implements
     private void showDetails() {
         mShowDetails = true;
         if (mDetailsHelper == null) {
-            mHighlightDrawer = new HighlightDrawer(mActivity.getAndroidContext());
+            mHighlightDrawer = new HighlightDrawer(mActivity.getAndroidContext(),
+                    mSelectionManager);
             mDetailsHelper = new DetailsHelper(mActivity, mRootPane, mDetailsSource);
             mDetailsHelper.setCloseListener(new CloseListener() {
                 public void onClose() {
index 0cea6c8..be1417a 100644 (file)
@@ -46,16 +46,16 @@ final class Config {
             slotViewSpec.slotGap = r.getDimensionPixelSize(R.dimen.albumset_slot_gap);
 
             labelSpec = new AlbumSetView.LabelSpec();
-            labelSpec.darkStripHeight = r.getDimensionPixelSize(
-                    R.dimen.albumset_dark_strip_height);
+            labelSpec.labelBackgroundHeight = r.getDimensionPixelSize(
+                    R.dimen.albumset_label_background_height);
             labelSpec.titleOffset = r.getDimensionPixelSize(
                     R.dimen.albumset_title_offset);
-            labelSpec.numberOffset = r.getDimensionPixelSize(
-                    R.dimen.albumset_number_offset);
+            labelSpec.countOffset = r.getDimensionPixelSize(
+                    R.dimen.albumset_count_offset);
             labelSpec.titleFontSize = r.getDimensionPixelSize(
                     R.dimen.albumset_title_font_size);
-            labelSpec.numberFontSize = r.getDimensionPixelSize(
-                    R.dimen.albumset_number_font_size);
+            labelSpec.countFontSize = r.getDimensionPixelSize(
+                    R.dimen.albumset_count_font_size);
             labelSpec.leftMargin = r.getDimensionPixelSize(
                     R.dimen.albumset_left_margin);
             labelSpec.iconSize = r.getDimensionPixelSize(
index 7e301f2..01efaea 100644 (file)
@@ -113,10 +113,10 @@ public class ManageCachePage extends ActivityState implements
             int slotViewTop = GalleryActionBar.getHeight(activity);
             int slotViewBottom = bottom - top;
 
-            View cacheBar = activity.findViewById(R.id.cache_bar);
-            if (cacheBar != null) {
+            View footer = activity.findViewById(R.id.footer);
+            if (footer != null) {
                 int location[] = {0, 0};
-                cacheBar.getLocationOnScreen(location);
+                footer.getLocationOnScreen(location);
                 slotViewBottom = location[1];
             }
 
@@ -143,6 +143,18 @@ public class ManageCachePage extends ActivityState implements
         mRootPane.invalidate();
     }
 
+    private void onDown(int index) {
+        MediaSet set = mAlbumSetDataAdapter.getMediaSet(index);
+        Path path = (set == null) ? null : set.getPath();
+        mSelectionManager.setPressedPath(path);
+        mAlbumSetView.invalidate();
+    }
+
+    private void onUp() {
+        mSelectionManager.setPressedPath(null);
+        mAlbumSetView.invalidate();
+    }
+
     public void onSingleTapUp(int slotIndex) {
         MediaSet targetSet = mAlbumSetDataAdapter.getMediaSet(slotIndex);
         if (targetSet == null) return; // Content is dirty, we shall reload soon
@@ -286,6 +298,16 @@ public class ManageCachePage extends ActivityState implements
                 config.slotViewSpec, config.labelSpec);
         mAlbumSetView.setListener(new SlotView.SimpleListener() {
             @Override
+            public void onDown(int index) {
+                ManageCachePage.this.onDown(index);
+            }
+
+            @Override
+            public void onUp() {
+                ManageCachePage.this.onUp();
+            }
+
+            @Override
             public void onSingleTapUp(int slotIndex) {
                 ManageCachePage.this.onSingleTapUp(slotIndex);
             }
index 7ab04c5..ca87b94 100644 (file)
@@ -306,4 +306,16 @@ public class LocalImage extends LocalMediaItem {
     public int getRotation() {
         return rotation;
     }
+
+    @Override
+    public int getWidth() {
+        // TODO
+        return 0;
+    }
+
+    @Override
+    public int getHeight() {
+        // TODO
+        return 0;
+    }
 }
index d1498e8..785bed1 100644 (file)
@@ -210,4 +210,16 @@ public class LocalVideo extends LocalMediaItem {
         }
         return details;
     }
+
+    @Override
+    public int getWidth() {
+        // TODO
+        return 0;
+    }
+
+    @Override
+    public int getHeight() {
+        // TODO
+        return 0;
+    }
 }
index 0906251..a0c6d8c 100644 (file)
@@ -78,4 +78,9 @@ public abstract class MediaItem extends MediaObject {
     }
 
     public abstract String getMimeType();
+
+    // Returns width and height of the media item.
+    // Returns 0, 0 if the information is not available.
+    public abstract int getWidth();
+    public abstract int getHeight();
 }
index 218f704..211b2f2 100644 (file)
@@ -157,4 +157,13 @@ public class MtpImage extends MediaItem {
         return details;
     }
 
+    @Override
+    public int getWidth() {
+        return mImageWidth;
+    }
+
+    @Override
+    public int getHeight() {
+        return mImageHeight;
+    }
 }
index 3a7ed7c..e97b035 100644 (file)
@@ -263,4 +263,14 @@ public class UriImage extends MediaItem {
             super.finalize();
         }
     }
+
+    @Override
+    public int getWidth() {
+        return 0;
+    }
+
+    @Override
+    public int getHeight() {
+        return 0;
+    }
 }
index 9ad0937..4253685 100644 (file)
@@ -25,6 +25,7 @@ import com.android.gallery3d.data.Path;
 import com.android.gallery3d.ui.AlbumSetView.AlbumSetItem;
 import com.android.gallery3d.util.Future;
 import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.GalleryUtils;
 import com.android.gallery3d.util.MediaSetUtils;
 import com.android.gallery3d.util.ThreadPool;
 
@@ -337,6 +338,7 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener {
         private final int mMediaType;
         private Texture mContent;
         private final long mDataVersion;
+        private boolean mIsPanorama;
 
         public GalleryDisplayItem(int slotIndex, int coverIndex, MediaItem item) {
             super(item);
@@ -344,6 +346,7 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener {
             mCoverIndex = coverIndex;
             mMediaType = item.getMediaType();
             mDataVersion = item.getDataVersion();
+            mIsPanorama = GalleryUtils.isPanorama(item);
             updateContent(mWaitLoadingTexture);
         }
 
@@ -392,7 +395,7 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener {
 
             mSelectionDrawer.draw(canvas, mContent, width, height,
                     getRotation(), path, mCoverIndex, sourceType, mMediaType,
-                    mLabelSpec.darkStripHeight,
+                    mIsPanorama, mLabelSpec.labelBackgroundHeight,
                     cacheFlag == MediaSet.CACHE_FLAG_FULL,
                     (cacheFlag == MediaSet.CACHE_FLAG_FULL)
                     && (cacheStatus != MediaSet.CACHE_STATUS_CACHED_FULL));
@@ -471,14 +474,15 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener {
 
     private class LabelDisplayItem extends DisplayItem {
         private static final int FONT_COLOR_TITLE = Color.WHITE;
-        private static final int FONT_COLOR_NUMBER = 0x80FFFFFF;  // 50% white
+        private static final int FONT_COLOR_COUNT = 0x80FFFFFF;  // 50% white
 
         private StringTexture mTextureTitle;
-        private StringTexture mTextureNumber;
+        private StringTexture mTextureCount;
         private String mTitle;
-        private String mNumber;
+        private String mCount;
         private int mLastWidth;
         private final int mSlotIndex;
+        private boolean mHasIcon;
 
         public LabelDisplayItem(int slotIndex) {
             mSlotIndex = slotIndex;
@@ -486,27 +490,29 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener {
 
         public boolean updateContent() {
             String title = mLoadingLabel;
-            String number = "";
+            String count = "";
             MediaSet set = mSource.getMediaSet(mSlotIndex);
             if (set != null) {
                 title = Utils.ensureNotNull(set.getName());
-                number = "" + set.getTotalMediaItemCount();
+                count = "" + set.getTotalMediaItemCount();
             }
             if (Utils.equals(title, mTitle)
-                    && Utils.equals(number, mNumber)
+                    && Utils.equals(count, mCount)
                     && Utils.equals(mBoxWidth, mLastWidth)) {
                     return false;
             }
             mTitle = title;
-            mNumber = number;
+            mCount = count;
             mLastWidth = mBoxWidth;
+            mHasIcon = (identifySourceType(set) !=
+                    SelectionDrawer.DATASOURCE_TYPE_NOT_CATEGORIZED);
 
             AlbumSetView.LabelSpec s = mLabelSpec;
             mTextureTitle = StringTexture.newInstance(
                     title, s.titleFontSize, FONT_COLOR_TITLE,
                     mBoxWidth - s.leftMargin, false);
-            mTextureNumber = StringTexture.newInstance(
-                    number, s.numberFontSize, FONT_COLOR_NUMBER,
+            mTextureCount = StringTexture.newInstance(
+                    count, s.countFontSize, FONT_COLOR_COUNT,
                     mBoxWidth - s.leftMargin, true);
 
             return true;
@@ -520,11 +526,12 @@ public class AlbumSetSlidingWindow implements AlbumSetView.ModelListener {
 
             AlbumSetView.LabelSpec s = mLabelSpec;
             int x = -mBoxWidth / 2;
-            int y = (mBoxHeight + 1) / 2 - s.darkStripHeight;
+            int y = (mBoxHeight + 1) / 2 - s.labelBackgroundHeight;
             y += s.titleOffset;
             mTextureTitle.draw(canvas, x + s.leftMargin, y);
-            y += s.titleFontSize + s.numberOffset;
-            mTextureNumber.draw(canvas, x + s.iconSize, y);
+            y += s.titleFontSize + s.countOffset;
+            x += mHasIcon ? s.iconSize : s.leftMargin;
+            mTextureCount.draw(canvas, x, y);
             return false;
         }
 
index c122fe7..89dfe4a 100644 (file)
@@ -64,11 +64,11 @@ public class AlbumSetView extends SlotView {
     }
 
     public static class LabelSpec {
-        public int darkStripHeight;
+        public int labelBackgroundHeight;
         public int titleOffset;
-        public int numberOffset;
+        public int countOffset;
         public int titleFontSize;
-        public int numberFontSize;
+        public int countFontSize;
         public int leftMargin;
         public int iconSize;
     }
index 46d9e9e..5184d1c 100644 (file)
@@ -24,6 +24,7 @@ import com.android.gallery3d.data.MediaItem;
 import com.android.gallery3d.data.Path;
 import com.android.gallery3d.util.Future;
 import com.android.gallery3d.util.FutureListener;
+import com.android.gallery3d.util.GalleryUtils;
 import com.android.gallery3d.util.JobLimiter;
 import com.android.gallery3d.util.ThreadPool.Job;
 import com.android.gallery3d.util.ThreadPool.JobContext;
@@ -283,6 +284,7 @@ public class AlbumSlidingWindow implements AlbumView.ModelListener {
         private final int mSlotIndex;
         private final int mMediaType;
         private Texture mContent;
+        private boolean mIsPanorama;
 
         public AlbumDisplayItem(int slotIndex, MediaItem item) {
             super(item);
@@ -290,6 +292,7 @@ public class AlbumSlidingWindow implements AlbumView.ModelListener {
                     ? MediaItem.MEDIA_TYPE_UNKNOWN
                     : item.getMediaType();
             mSlotIndex = slotIndex;
+            mIsPanorama = GalleryUtils.isPanorama(item);
             updateContent(mWaitLoadingTexture);
         }
 
@@ -332,7 +335,7 @@ public class AlbumSlidingWindow implements AlbumView.ModelListener {
                 Path path = null;
                 if (mMediaItem != null) path = mMediaItem.getPath();
                 mSelectionDrawer.draw(canvas, mContent, width, height,
-                        getRotation(), path, mMediaType);
+                        getRotation(), path, mMediaType, mIsPanorama);
                 return (mFocusIndex == mSlotIndex);
             } else if (pass == 1) {
                 mSelectionDrawer.drawFocus(canvas, width, height);
index 6a80564..eaf041e 100644 (file)
@@ -20,14 +20,16 @@ import com.android.gallery3d.R;
 import com.android.gallery3d.anim.AlphaAnimation;
 import com.android.gallery3d.app.AlbumDataAdapter;
 import com.android.gallery3d.app.GalleryActivity;
+import com.android.gallery3d.data.MediaItem;
 import com.android.gallery3d.data.MediaSet;
+import com.android.gallery3d.data.Path;
 
 import android.content.Context;
 import android.view.MotionEvent;
 import android.view.View.MeasureSpec;
 
-public class FilmStripView extends GLView implements SlotView.Listener,
-        ScrollBarView.Listener, UserInteractionListener {
+public class FilmStripView extends GLView implements ScrollBarView.Listener,
+        UserInteractionListener {
     @SuppressWarnings("unused")
     private static final String TAG = "FilmStripView";
 
@@ -79,7 +81,28 @@ public class FilmStripView extends GLView implements SlotView.Listener,
         mAlbumView = new AlbumView(activity, spec, thumbSize);
         mAlbumView.setOverscrollEffect(SlotView.OVERSCROLL_SYSTEM);
         mAlbumView.setSelectionDrawer(mStripDrawer);
-        mAlbumView.setListener(this);
+        mAlbumView.setListener(new SlotView.SimpleListener() {
+            @Override
+            public void onDown(int index) {
+                FilmStripView.this.onDown(index);
+            }
+            @Override
+            public void onUp() {
+                FilmStripView.this.onUp();
+            }
+            @Override
+            public void onSingleTapUp(int slotIndex) {
+                FilmStripView.this.onSingleTapUp(slotIndex);
+            }
+            @Override
+            public void onLongTap(int slotIndex) {
+                FilmStripView.this.onLongTap(slotIndex);
+            }
+            @Override
+            public void onScrollPositionChanged(int position, int total) {
+                FilmStripView.this.onScrollPositionChanged(position, total);
+            }
+        });
         mAlbumView.setUserInteractionListener(this);
         mAlbumDataAdapter = new AlbumDataAdapter(activity, mediaSet);
         addComponent(mAlbumView);
@@ -172,20 +195,32 @@ public class FilmStripView extends GLView implements SlotView.Listener,
         super.render(canvas);
     }
 
-    // Called by AlbumView
-    @Override
-    public void onSingleTapUp(int slotIndex) {
+    private void onDown(int index) {
+        MediaItem item = mAlbumDataAdapter.get(index);
+        Path path = (item == null) ? null : item.getPath();
+        mStripDrawer.setPressedPath(path);
+        mAlbumView.invalidate();
+    }
+
+    private void onUp() {
+        mStripDrawer.setPressedPath(null);
+        mAlbumView.invalidate();
+    }
+
+    private void onSingleTapUp(int slotIndex) {
         if (mListener.onSlotSelected(slotIndex)) {
             mAlbumView.setFocusIndex(slotIndex);
         }
     }
 
-    // Called by AlbumView
-    @Override
-    public void onLongTap(int slotIndex) {
+    private void onLongTap(int slotIndex) {
         onSingleTapUp(slotIndex);
     }
 
+    private void onScrollPositionChanged(int position, int total) {
+        mScrollBarView.setContentPosition(position, total);
+    }
+
     // Called by AlbumView
     @Override
     public void onUserInteractionBegin() {
@@ -204,12 +239,6 @@ public class FilmStripView extends GLView implements SlotView.Listener,
         mUIListener.onUserInteraction();
     }
 
-    // Called by AlbumView
-    @Override
-    public void onScrollPositionChanged(int position, int total) {
-        mScrollBarView.setContentPosition(position, total);
-    }
-
     // Called by ScrollBarView
     @Override
     public void onScrollBarPositionChanged(int position) {
index cc86184..394a6c7 100644 (file)
@@ -47,10 +47,10 @@ public class GridDrawer extends IconDrawer {
     }
 
     @Override
-    public void draw(GLCanvas canvas, Texture content, int width, int height,
-            int rotation, Path path, int topIndex, int dataSourceType,
-            int mediaType, int darkStripHeight, boolean wantCache,
-            boolean isCaching) {
+    public void draw(GLCanvas canvas, Texture content, int width,
+            int height, int rotation, Path path, int topIndex,
+            int dataSourceType, int mediaType, boolean isPanorama,
+            int labelBackgroundHeight, boolean wantCache, boolean isCaching) {
 
         int x = -width / 2;
         int y = -height / 2;
@@ -66,19 +66,22 @@ public class GridDrawer extends IconDrawer {
             y = -height / 2;
         }
 
-        drawVideoOverlay(canvas, mediaType, x, y, width, height, topIndex);
-
-        if (mSelectionMode && mSelectionManager.isItemSelected(path)) {
-            drawFrame(canvas, mFrameSelected, x, y, width, height);
-        }
+        drawMediaTypeOverlay(canvas, mediaType, isPanorama, x, y, width, height,
+                topIndex);
 
         if (topIndex == 0) {
-            drawDarkStrip(canvas, width, height, darkStripHeight);
+            drawLabelBackground(canvas, width, height, labelBackgroundHeight);
             drawIcon(canvas, width, height, dataSourceType);
             if (dataSourceType == DATASOURCE_TYPE_MTP) {
                 drawImportLabel(canvas, width, height);
             }
         }
+
+        if (mSelectionManager.isPressedPath(path)) {
+            drawPressedFrame(canvas, x, y, width, height);
+        } else if (mSelectionMode && mSelectionManager.isItemSelected(path)) {
+            drawFrame(canvas, mFrameSelected, x, y, width, height);
+        }
     }
 
     // Draws the "click to import" label at the center of the frame
index 52c31f7..ee37d26 100644 (file)
@@ -25,19 +25,21 @@ public class HighlightDrawer extends IconDrawer {
     private SelectionManager mSelectionManager;
     private Path mHighlightItem;
 
-    public HighlightDrawer(Context context) {
+    public HighlightDrawer(Context context, SelectionManager selectionManager) {
         super(context);
         mFrameSelected = new NinePatchTexture(context, R.drawable.grid_selected);
+        mSelectionManager = selectionManager;
     }
 
     public void setHighlightItem(Path item) {
         mHighlightItem = item;
     }
 
-    public void draw(GLCanvas canvas, Texture content, int width, int height,
-            int rotation, Path path, int topIndex, int dataSourceType,
-            int mediaType, int darkStripHeight, boolean wantCache,
-            boolean isCaching) {
+    @Override
+    public void draw(GLCanvas canvas, Texture content, int width,
+            int height, int rotation, Path path, int topIndex,
+            int dataSourceType, int mediaType, boolean isPanorama,
+            int labelBackgroundHeight, boolean wantCache, boolean isCaching) {
         int x = -width / 2;
         int y = -height / 2;
 
@@ -52,15 +54,18 @@ public class HighlightDrawer extends IconDrawer {
             y = -height / 2;
         }
 
-        drawVideoOverlay(canvas, mediaType, x, y, width, height, topIndex);
-
-        if (path == mHighlightItem) {
-            drawFrame(canvas, mFrameSelected, x, y, width, height);
-        }
+        drawMediaTypeOverlay(canvas, mediaType, isPanorama, x, y, width, height,
+                topIndex);
 
         if (topIndex == 0) {
-            drawDarkStrip(canvas, width, height, darkStripHeight);
+            drawLabelBackground(canvas, width, height, labelBackgroundHeight);
             drawIcon(canvas, width, height, dataSourceType);
         }
+
+        if (mSelectionManager.isPressedPath(path)) {
+            drawPressedFrame(canvas, x, y, width, height);
+        } else  if (path == mHighlightItem) {
+            drawFrame(canvas, mFrameSelected, x, y, width, height);
+        }
     }
 }
index 86fdf68..781046c 100644 (file)
@@ -22,12 +22,14 @@ import android.content.Context;
 
 public abstract class IconDrawer extends SelectionDrawer {
     private static final String TAG = "IconDrawer";
-    private static final int DARK_STRIP_COLOR = 0x99000000;  // 60% black
+    private static final int LABEL_BACKGROUND_COLOR = 0x99000000;  // 60% black
 
     private final ResourceTexture mLocalSetIcon;
     private final ResourceTexture mCameraIcon;
     private final ResourceTexture mPicasaIcon;
     private final ResourceTexture mMtpIcon;
+    private final NinePatchTexture mFramePressed;
+    private final ResourceTexture mPanoramaBorder;
     private final Texture mVideoOverlay;
     private final Texture mVideoPlayIcon;
     private final int mIconSize;
@@ -43,9 +45,11 @@ public abstract class IconDrawer extends SelectionDrawer {
         mLocalSetIcon = new ResourceTexture(context, R.drawable.frame_overlay_gallery_folder);
         mCameraIcon = new ResourceTexture(context, R.drawable.frame_overlay_gallery_camera);
         mPicasaIcon = new ResourceTexture(context, R.drawable.frame_overlay_gallery_picasa);
-        mMtpIcon = new ResourceTexture(context, R.drawable.ic_album_overlay_ptp_holo);
+        mMtpIcon = new ResourceTexture(context, R.drawable.frame_overlay_gallery_ptp);
         mVideoOverlay = new ResourceTexture(context, R.drawable.ic_video_thumb);
         mVideoPlayIcon = new ResourceTexture(context, R.drawable.ic_gallery_play);
+        mPanoramaBorder = new ResourceTexture(context, R.drawable.ic_pan_thumb);
+        mFramePressed = new NinePatchTexture(context, R.drawable.grid_pressed);
         mIconSize = context.getResources().getDimensionPixelSize(
                 R.dimen.albumset_icon_size);
     }
@@ -95,14 +99,23 @@ public abstract class IconDrawer extends SelectionDrawer {
         id.width = Math.round(scale * icon.getWidth());
         id.height = Math.round(scale * icon.getHeight());
         id.x = -width / 2;
-        id.y = height / 2 - id.height;
+        id.y = (height + 1) / 2 - id.height;
         return id;
     }
 
-    protected void drawVideoOverlay(GLCanvas canvas, int mediaType,
-            int x, int y, int width, int height, int topIndex) {
-        if (mediaType != MediaObject.MEDIA_TYPE_VIDEO) return;
+    protected void drawMediaTypeOverlay(GLCanvas canvas, int mediaType,
+            boolean isPanorama, int x, int y, int width, int height,
+            int topIndex) {
+        if (mediaType == MediaObject.MEDIA_TYPE_VIDEO) {
+            drawVideoOverlay(canvas, x, y, width, height, topIndex);
+        }
+        if (isPanorama) {
+            drawPanoramaBorder(canvas, x, y, width, height);
+        }
+    }
 
+    protected void drawVideoOverlay(GLCanvas canvas, int x, int y,
+            int width, int height, int topIndex) {
         // Scale the video overlay to the height of the thumbnail and put it
         // on the left side.
         float scale = (float) height / mVideoOverlay.getHeight();
@@ -116,11 +129,27 @@ public abstract class IconDrawer extends SelectionDrawer {
         }
     }
 
-    protected void drawDarkStrip(GLCanvas canvas, int width, int height,
-            int darkStripHeight) {
+    protected void drawPanoramaBorder(GLCanvas canvas, int x, int y,
+            int width, int height) {
+        float scale = (float) width / mPanoramaBorder.getWidth();
+        int w = Math.round(scale * mPanoramaBorder.getWidth());
+        int h = Math.round(scale * mPanoramaBorder.getHeight());
+        // draw at the top
+        mPanoramaBorder.draw(canvas, x, y, w, h);
+        // draw at the bottom
+        mPanoramaBorder.draw(canvas, x, y + width - h, w, h);
+    }
+
+    protected void drawLabelBackground(GLCanvas canvas, int width, int height,
+            int drawLabelBackground) {
         int x = -width / 2;
-        int y = (height + 1) / 2 - darkStripHeight;
-        canvas.fillRect(x, y, width, darkStripHeight, DARK_STRIP_COLOR);
+        int y = (height + 1) / 2 - drawLabelBackground;
+        canvas.fillRect(x, y, width, drawLabelBackground, LABEL_BACKGROUND_COLOR);
+    }
+
+    protected void drawPressedFrame(GLCanvas canvas, int x, int y, int width,
+            int height) {
+        drawFrame(canvas, mFramePressed, x, y, width, height);
     }
 
     @Override
index e25e779..ed84a18 100644 (file)
@@ -23,14 +23,13 @@ import com.android.gallery3d.data.Path;
 import android.content.Context;
 
 public class ManageCacheDrawer extends IconDrawer {
-    private static final int COLOR_CACHING_BACKGROUND = 0x7F000000;
     private static final int ICON_SIZE = 36;
     private final ResourceTexture mCheckedItem;
     private final ResourceTexture mUnCheckedItem;
     private final SelectionManager mSelectionManager;
 
     private final ResourceTexture mLocalAlbumIcon;
-    private final StringTexture mCaching;
+    private final StringTexture mCachingText;
 
     public ManageCacheDrawer(Context context, SelectionManager selectionManager) {
         super(context);
@@ -38,7 +37,7 @@ public class ManageCacheDrawer extends IconDrawer {
         mUnCheckedItem = new ResourceTexture(context, R.drawable.btn_make_offline_normal_off_holo_dark);
         mLocalAlbumIcon = new ResourceTexture(context, R.drawable.btn_make_offline_disabled_on_holo_dark);
         String cachingLabel = context.getString(R.string.caching_label);
-        mCaching = StringTexture.newInstance(cachingLabel, 12, 0xffffffff);
+        mCachingText = StringTexture.newInstance(cachingLabel, 12, 0xffffffff);
         mSelectionManager = selectionManager;
     }
 
@@ -51,13 +50,11 @@ public class ManageCacheDrawer extends IconDrawer {
     }
 
     @Override
-    public void draw(GLCanvas canvas, Texture content, int width, int height,
-            int rotation, Path path, int topIndex, int dataSourceType,
-            int mediaType, int darkStripHeight, boolean wantCache,
-            boolean isCaching) {
+    public void draw(GLCanvas canvas, Texture content, int width,
+            int height, int rotation, Path path, int topIndex,
+            int dataSourceType, int mediaType, boolean isPanorama,
+            int labelBackgroundHeight, boolean wantCache, boolean isCaching) {
 
-        boolean selected = mSelectionManager.isItemSelected(path);
-        boolean chooseToCache = wantCache ^ selected;
 
         int x = -width / 2;
         int y = -height / 2;
@@ -73,48 +70,53 @@ public class ManageCacheDrawer extends IconDrawer {
             y = -height / 2;
         }
 
-        drawVideoOverlay(canvas, mediaType, x, y, width, height, topIndex);
+        drawMediaTypeOverlay(canvas, mediaType, isPanorama, x, y, width, height,
+                topIndex);
 
         if (topIndex == 0) {
-            drawDarkStrip(canvas, width, height, darkStripHeight);
+            drawLabelBackground(canvas, width, height, labelBackgroundHeight);
             drawIcon(canvas, width, height, dataSourceType);
         }
 
         if (topIndex == 0) {
-            ResourceTexture icon = null;
-            if (isLocal(dataSourceType)) {
-                icon = mLocalAlbumIcon;
-            } else if (chooseToCache) {
-                icon = mCheckedItem;
-            } else {
-                icon = mUnCheckedItem;
-            }
-
-            int w = ICON_SIZE;
-            int h = ICON_SIZE;
-            x = width / 2 - w;
-            y = -height / 2;
+            drawCachingIcon(canvas, path, dataSourceType, isCaching, wantCache,
+                    width, height);
+        }
+
+        if (mSelectionManager.isPressedPath(path)) {
+            drawPressedFrame(canvas, x, y, width, height);
+        }
+    }
+
+    private void drawCachingIcon(GLCanvas canvas, Path path, int dataSourceType,
+            boolean isCaching, boolean wantCache, int width, int height) {
+        boolean selected = mSelectionManager.isItemSelected(path);
+        boolean chooseToCache = wantCache ^ selected;
+
+        ResourceTexture icon = null;
+        if (isLocal(dataSourceType)) {
+            icon = mLocalAlbumIcon;
+        } else if (chooseToCache) {
+            icon = mCheckedItem;
+        } else {
+            icon = mUnCheckedItem;
+        }
 
-            icon.draw(canvas, x, y, w, h);
-
-            if (isCaching) {
-                int textWidth = mCaching.getWidth();
-                int textHeight = mCaching.getHeight();
-                x = -textWidth / 2;
-                y = height / 2 - textHeight;
-
-                // Leave a few pixels of margin in the background rect.
-                float sideMargin = Utils.clamp(textWidth * 0.1f, 2.0f,
-                        6.0f);
-                float clearance = Utils.clamp(textHeight * 0.1f, 2.0f,
-                        6.0f);
-
-                // Overlay the "Caching" wording at the bottom-center of the content.
-                canvas.fillRect(x - sideMargin, y - clearance,
-                        textWidth + sideMargin * 2, textHeight + clearance,
-                        COLOR_CACHING_BACKGROUND);
-                mCaching.draw(canvas, x, y);
-            }
+        int w = ICON_SIZE;
+        int h = ICON_SIZE;
+        int right = (width + 1) / 2;
+        int bottom = (height + 1) / 2;
+        int x = right - w;
+        int y = bottom - h;
+
+        icon.draw(canvas, x, y, w, h);
+
+        if (isCaching) {
+            int textWidth = mCachingText.getWidth();
+            int textHeight = mCachingText.getHeight();
+            x = right - ICON_SIZE - textWidth;
+            y = bottom - textHeight;
+            mCachingText.draw(canvas, x, y);
         }
     }
 
index 05f346c..70d8ad5 100644 (file)
@@ -34,14 +34,14 @@ public abstract class SelectionDrawer {
     public abstract void prepareDrawing();
     public abstract void draw(GLCanvas canvas, Texture content,
             int width, int height, int rotation, Path path,
-            int topIndex, int dataSourceType, int mediaType,
-            int darkStripHeight, boolean wantCache, boolean isCaching);
+            int topIndex, int dataSourceType, int mediaType, boolean isPanorama,
+            int labelBackgroundHeight, boolean wantCache, boolean isCaching);
     public abstract void drawFocus(GLCanvas canvas, int width, int height);
 
     public void draw(GLCanvas canvas, Texture content, int width, int height,
-            int rotation, Path path, int mediaType) {
+            int rotation, Path path, int mediaType, boolean isPanorama) {
         draw(canvas, content, width, height, rotation, path, 0,
-                DATASOURCE_TYPE_NOT_CATEGORIZED, mediaType,
+                DATASOURCE_TYPE_NOT_CATEGORIZED, mediaType, isPanorama,
                 0, false, false);
     }
 
index 9599f5b..0ab69d2 100644 (file)
@@ -47,6 +47,7 @@ public class SelectionManager {
     private boolean mInSelectionMode;
     private boolean mAutoLeave = true;
     private int mTotal;
+    private Path mPressedPath;
 
     public interface SelectionListener {
         public void onSelectionModeChange(int mode);
@@ -141,6 +142,14 @@ public class SelectionManager {
         }
     }
 
+    public void setPressedPath(Path path) {
+        mPressedPath = path;
+    }
+
+    public boolean isPressedPath(Path path) {
+        return path != null && path == mPressedPath;
+    }
+
     private static void expandMediaSet(ArrayList<Path> items, MediaSet set) {
         int subCount = set.getSubMediaSetCount();
         for (int i = 0; i < subCount; i++) {
index 11dbfaa..3eb3f17 100644 (file)
@@ -39,12 +39,16 @@ public class SlotView extends GLView {
     private static final int INDEX_NONE = -1;
 
     public interface Listener {
+        public void onDown(int index);
+        public void onUp();
         public void onSingleTapUp(int index);
         public void onLongTap(int index);
         public void onScrollPositionChanged(int position, int total);
     }
 
     public static class SimpleListener implements Listener {
+        public void onDown(int index) {}
+        public void onUp() {}
         public void onSingleTapUp(int index) {}
         public void onLongTap(int index) {}
         public void onScrollPositionChanged(int position, int total) {}
@@ -597,12 +601,37 @@ public class SlotView extends GLView {
         }
     }
 
-    private class MyGestureListener
-            extends GestureDetector.SimpleOnGestureListener {
+    private class MyGestureListener implements
+            GestureDetector.OnGestureListener {
+        private boolean isDown;
+
+        // We call the listener's onDown() when our onShowPress() is called and
+        // call the listener's onUp() when we receive any further event.
+        @Override
+        public void onShowPress(MotionEvent e) {
+            if (isDown) return;
+            int index = mLayout.getSlotIndexByPosition(e.getX(), e.getY());
+            if (index != INDEX_NONE) {
+                isDown = true;
+                mListener.onDown(index);
+            }
+        }
+
+        private void cancelDown() {
+            if (!isDown) return;
+            isDown = false;
+            mListener.onUp();
+        }
+
+        @Override
+        public boolean onDown(MotionEvent e) {
+            return false;
+        }
 
         @Override
         public boolean onFling(MotionEvent e1,
                 MotionEvent e2, float velocityX, float velocityY) {
+            cancelDown();
             int scrollLimit = mLayout.getScrollLimit();
             if (scrollLimit == 0) return false;
             float velocity = WIDE ? velocityX : velocityY;
@@ -615,6 +644,7 @@ public class SlotView extends GLView {
         @Override
         public boolean onScroll(MotionEvent e1,
                 MotionEvent e2, float distanceX, float distanceY) {
+            cancelDown();
             float distance = WIDE ? distanceX : distanceY;
             boolean canMove = mScroller.startScroll(
                     Math.round(distance), 0, mLayout.getScrollLimit());
@@ -627,6 +657,7 @@ public class SlotView extends GLView {
 
         @Override
         public boolean onSingleTapUp(MotionEvent e) {
+            cancelDown();
             if (mDownInScrolling) return true;
             int index = mLayout.getSlotIndexByPosition(e.getX(), e.getY());
             if (index != INDEX_NONE) mListener.onSingleTapUp(index);
@@ -635,6 +666,7 @@ public class SlotView extends GLView {
 
         @Override
         public void onLongPress(MotionEvent e) {
+            cancelDown();
             if (mDownInScrolling) return;
             lockRendering();
             try {
index be98ae0..5120a0c 100644 (file)
@@ -23,28 +23,43 @@ import android.content.Context;
 import android.graphics.Rect;
 
 public class StripDrawer extends SelectionDrawer {
+    private NinePatchTexture mFramePressed;
     private NinePatchTexture mFocusBox;
     private Rect mFocusBoxPadding;
+    private Path mPressedPath;
 
     public StripDrawer(Context context) {
+        mFramePressed = new NinePatchTexture(context, R.drawable.grid_pressed);
         mFocusBox = new NinePatchTexture(context, R.drawable.focus_box);
         mFocusBoxPadding = mFocusBox.getPaddings();
     }
 
+    public void setPressedPath(Path path) {
+        mPressedPath = path;
+    }
+
+    private boolean isPressedPath(Path path) {
+        return path != null && path == mPressedPath;
+    }
+
     @Override
     public void prepareDrawing() {
     }
 
     @Override
-    public void draw(GLCanvas canvas, Texture content, int width, int height,
-            int rotation, Path path, int topIndex, int dataSourceType,
-            int mediaType, int darkStripHeight, boolean wantCache,
-            boolean isCaching) {
+    public void draw(GLCanvas canvas, Texture content,
+            int width, int height, int rotation, Path path, int topIndex,
+            int dataSourceType, int mediaType, boolean isPanorama,
+            int labelBackgroundHeight, boolean wantCache, boolean isCaching) {
 
         int x = -width / 2;
         int y = -height / 2;
 
         drawWithRotation(canvas, content, x, y, width, height, rotation);
+
+        if (isPressedPath(path)) {
+            drawFrame(canvas, mFramePressed, x, y, width, height);
+        }
     }
 
     @Override
index 9c08dea..6803611 100644 (file)
@@ -352,4 +352,11 @@ public class GalleryUtils {
             output[0] = number;
         }
     }
+
+    public static boolean isPanorama(MediaItem item) {
+        if (item == null) return false;
+        int w = item.getWidth();
+        int h = item.getHeight();
+        return (h > 0 && w / h >= 2);
+    }
 }
index bd6dcd9..2901979 100644 (file)
@@ -40,4 +40,14 @@ public class MockItem extends MediaItem {
     public String getMimeType() {
         return null;
     }
+
+    @Override
+    public int getWidth() {
+        return 0;
+    }
+
+    @Override
+    public int getHeight() {
+        return 0;
+    }
 }