- 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
+++ /dev/null
-<?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>
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>
--- /dev/null
+<?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>
<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>
<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>
}
}
+ 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) {
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);
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() {
}
}
+ 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) {
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);
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() {
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(
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];
}
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
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);
}
public int getRotation() {
return rotation;
}
+
+ @Override
+ public int getWidth() {
+ // TODO
+ return 0;
+ }
+
+ @Override
+ public int getHeight() {
+ // TODO
+ return 0;
+ }
}
}
return details;
}
+
+ @Override
+ public int getWidth() {
+ // TODO
+ return 0;
+ }
+
+ @Override
+ public int getHeight() {
+ // TODO
+ return 0;
+ }
}
}
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();
}
return details;
}
+ @Override
+ public int getWidth() {
+ return mImageWidth;
+ }
+
+ @Override
+ public int getHeight() {
+ return mImageHeight;
+ }
}
super.finalize();
}
}
+
+ @Override
+ public int getWidth() {
+ return 0;
+ }
+
+ @Override
+ public int getHeight() {
+ return 0;
+ }
}
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;
private final int mMediaType;
private Texture mContent;
private final long mDataVersion;
+ private boolean mIsPanorama;
public GalleryDisplayItem(int slotIndex, int coverIndex, MediaItem item) {
super(item);
mCoverIndex = coverIndex;
mMediaType = item.getMediaType();
mDataVersion = item.getDataVersion();
+ mIsPanorama = GalleryUtils.isPanorama(item);
updateContent(mWaitLoadingTexture);
}
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));
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;
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;
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;
}
}
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;
}
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;
private final int mSlotIndex;
private final int mMediaType;
private Texture mContent;
+ private boolean mIsPanorama;
public AlbumDisplayItem(int slotIndex, MediaItem item) {
super(item);
? MediaItem.MEDIA_TYPE_UNKNOWN
: item.getMediaType();
mSlotIndex = slotIndex;
+ mIsPanorama = GalleryUtils.isPanorama(item);
updateContent(mWaitLoadingTexture);
}
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);
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";
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);
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() {
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) {
}
@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;
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
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;
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);
+ }
}
}
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;
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);
}
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();
}
}
- 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
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);
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;
}
}
@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;
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);
}
}
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);
}
private boolean mInSelectionMode;
private boolean mAutoLeave = true;
private int mTotal;
+ private Path mPressedPath;
public interface SelectionListener {
public void onSelectionModeChange(int mode);
}
}
+ 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++) {
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) {}
}
}
- 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;
@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());
@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);
@Override
public void onLongPress(MotionEvent e) {
+ cancelDown();
if (mDownInScrolling) return;
lockRendering();
try {
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
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);
+ }
}
public String getMimeType() {
return null;
}
+
+ @Override
+ public int getWidth() {
+ return 0;
+ }
+
+ @Override
+ public int getHeight() {
+ return 0;
+ }
}