From: Bobby Georgescu Date: Tue, 18 Sep 2012 01:12:11 +0000 (-0700) Subject: Add bottom bar UI for photo page X-Git-Tag: android-x86-7.1-r1~1802 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=f44499dda32783cc74643723ed01ce636e81b186;p=android-x86%2Fpackages-apps-Gallery2.git Add bottom bar UI for photo page Bug: 7050303 Bug: 7170148 Pulled the handling of the display of the edit (FX) button out into a separate file and put in the groundwork for supporting multiple buttons within a container along the bottom of the screen and managing their display as well as animating them in and out. Also added a button for launching the panorama viewer when appropriate Change-Id: Iee3083e0693ef3c1f55264b922f02b9a702d2103 --- diff --git a/res/layout/photopage_bottom_controls.xml b/res/layout/photopage_bottom_controls.xml new file mode 100644 index 000000000..a8fca2d72 --- /dev/null +++ b/res/layout/photopage_bottom_controls.xml @@ -0,0 +1,22 @@ + + + + + diff --git a/src/com/android/gallery3d/app/PhotoPage.java b/src/com/android/gallery3d/app/PhotoPage.java index 0d61f2f66..8e06794c8 100644 --- a/src/com/android/gallery3d/app/PhotoPage.java +++ b/src/com/android/gallery3d/app/PhotoPage.java @@ -29,10 +29,7 @@ import android.nfc.NfcAdapter; import android.os.Bundle; import android.os.Handler; import android.os.Message; -import android.view.View; -import android.view.View.OnClickListener; import android.view.animation.AccelerateInterpolator; -import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.Toast; @@ -79,7 +76,8 @@ import com.android.gallery3d.util.LightCycleHelper; import com.android.gallery3d.util.MediaSetUtils; public class PhotoPage extends ActivityState implements - PhotoView.Listener, OrientationManager.Listener, AppBridge.Server { + PhotoView.Listener, OrientationManager.Listener, AppBridge.Server, + PhotoPageBottomControls.Delegate { private static final String TAG = "PhotoPage"; private static final int MSG_HIDE_BARS = 1; @@ -90,7 +88,7 @@ public class PhotoPage extends ActivityState implements private static final int MSG_UNFREEZE_GLROOT = 6; private static final int MSG_WANT_BARS = 7; private static final int MSG_REFRESH_GRID_BUTTON = 8; - private static final int MSG_REFRESH_EDIT_BUTTON = 9; + private static final int MSG_REFRESH_BOTTOM_CONTROLS = 9; private static final int HIDE_BARS_TIMEOUT = 3500; private static final int UNFREEZE_GLROOT_TIMEOUT = 250; @@ -140,6 +138,7 @@ public class PhotoPage extends ActivityState implements private volatile boolean mActionBarAllowed = true; private GalleryActionBar mActionBar; private boolean mIsMenuVisible; + private PhotoPageBottomControls mBottomControls; private MediaItem mCurrentPhoto = null; private MenuExecutor mMenuExecutor; private boolean mIsActive; @@ -257,8 +256,8 @@ public class PhotoPage extends ActivityState implements setGridButtonVisibility(mPhotoView.getFilmMode()); break; } - case MSG_REFRESH_EDIT_BUTTON: { - refreshEditButton(); + case MSG_REFRESH_BOTTOM_CONTROLS: { + if (mBottomControls != null) mBottomControls.refresh(); break; } case MSG_LOCK_ORIENTATION: { @@ -407,48 +406,42 @@ public class PhotoPage extends ActivityState implements } mPhotoView.setFilmMode(mStartInFilmstrip && mMediaSet.getMediaItemCount() > 1); - setupEditButton(); + if (mSecureAlbum == null) { + RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity) + .findViewById(mAppBridge != null ? R.id.content : R.id.gallery_root); + if (galleryRoot != null) { + mBottomControls = new PhotoPageBottomControls(this, mActivity, galleryRoot); + } + } } - private ImageView mEditButton; - private void setupEditButton() { - if (mSecureAlbum != null) return; - RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity) - .findViewById(mAppBridge != null ? R.id.content : R.id.gallery_root); - if (galleryRoot == null) return; - - mEditButton = new ImageView(mActivity); - mEditButton.setImageResource(R.drawable.photoeditor_artistic); - mEditButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View arg0) { - launchPhotoEditor(); - } - }); - RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( - RelativeLayout.LayoutParams.WRAP_CONTENT, - RelativeLayout.LayoutParams.WRAP_CONTENT); - lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); - galleryRoot.addView(mEditButton, lp); - refreshEditButton(); + public boolean canDisplayBottomControls() { + return mShowBars && !mPhotoView.getFilmMode(); } - private void cleanupEditButton() { - if (mEditButton == null) return; - RelativeLayout galleryRoot = (RelativeLayout) ((Activity) mActivity) - .findViewById(mAppBridge != null ? R.id.content : R.id.gallery_root); - if (galleryRoot == null) return; - galleryRoot.removeView(mEditButton); - mEditButton = null; + public boolean canDisplayBottomControl(int control) { + if (mCurrentPhoto == null) return false; + switch(control) { + case R.id.photopage_bottom_control_edit: + return mCurrentPhoto.getMediaType() == MediaObject.MEDIA_TYPE_IMAGE; + case R.id.photopage_bottom_control_panorama: + return (mCurrentPhoto.getSupportedOperations() + & MediaItem.SUPPORT_VIEW_PANORAMA) != 0; + default: + return false; + } } - private void refreshEditButton() { - if (mEditButton == null) return; - if (mShowBars && mCurrentPhoto != null && !mPhotoView.getFilmMode() - && mCurrentPhoto.getMediaType() == MediaObject.MEDIA_TYPE_IMAGE) { - mEditButton.setVisibility(View.VISIBLE); - } else { - mEditButton.setVisibility(View.GONE); + public void onBottomControlClicked(int control) { + switch(control) { + case R.id.photopage_bottom_control_edit: + launchPhotoEditor(); + return; + case R.id.photopage_bottom_control_panorama: + LightCycleHelper.viewPanorama(mActivity, mCurrentPhoto.getContentUri()); + return; + default: + return; } } @@ -498,7 +491,7 @@ public class PhotoPage extends ActivityState implements if (mCurrentPhoto == null) return; updateMenuOperations(); updateTitle(); - refreshEditButton(); + if (mBottomControls != null) mBottomControls.refresh(); if (mShowDetails) { mDetailsHelper.reloadDetails(); } @@ -564,7 +557,7 @@ public class PhotoPage extends ActivityState implements mActionBar.show(); mActivity.getGLRoot().setLightsOutMode(false); refreshHidingMessage(); - refreshEditButton(); + if (mBottomControls != null) mBottomControls.refresh(); } private void hideBars() { @@ -573,7 +566,7 @@ public class PhotoPage extends ActivityState implements mActionBar.hide(); mActivity.getGLRoot().setLightsOutMode(true); mHandler.removeMessages(MSG_HIDE_BARS); - refreshEditButton(); + if (mBottomControls != null) mBottomControls.refresh(); } private void refreshHidingMessage() { @@ -1087,7 +1080,7 @@ public class PhotoPage extends ActivityState implements public void onFilmModeChanged(boolean enabled) { mHandler.sendEmptyMessage(MSG_REFRESH_GRID_BUTTON); - mHandler.sendEmptyMessage(MSG_REFRESH_EDIT_BUTTON); + mHandler.sendEmptyMessage(MSG_REFRESH_BOTTOM_CONTROLS); if (enabled) { mHandler.removeMessages(MSG_HIDE_BARS); } else { @@ -1165,7 +1158,7 @@ public class PhotoPage extends ActivityState implements } mOrientationManager.removeListener(this); mActivity.getGLRoot().setOrientationSource(null); - cleanupEditButton(); + if (mBottomControls != null) mBottomControls.cleanup(); // Remove all pending messages. mHandler.removeCallbacksAndMessages(null); diff --git a/src/com/android/gallery3d/app/PhotoPageBottomControls.java b/src/com/android/gallery3d/app/PhotoPageBottomControls.java new file mode 100644 index 000000000..8ba4818db --- /dev/null +++ b/src/com/android/gallery3d/app/PhotoPageBottomControls.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.app; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.ScaleAnimation; +import android.widget.RelativeLayout; + +import com.android.gallery3d.R; + +import java.util.HashMap; +import java.util.Map; + +public class PhotoPageBottomControls implements OnClickListener { + public interface Delegate { + public boolean canDisplayBottomControls(); + public boolean canDisplayBottomControl(int control); + public void onBottomControlClicked(int control); + } + + private Delegate mDelegate; + private ViewGroup mParentLayout; + private ViewGroup mContainer; + + private boolean mContainerVisible = false; + private Map mControlsVisible = new HashMap(); + + private Animation mContainerAnimIn = new AlphaAnimation(0f, 1f); + private Animation mContainerAnimOut = new AlphaAnimation(1f, 0f); + private static final int CONTAINER_ANIM_DURATION_MS = 200; + + private static final int CONTROL_ANIM_DURATION_MS = 150; + private static Animation getControlAnimForVisibility(boolean visible) { + Animation anim = visible ? new ScaleAnimation(0, 1, 1, 1) + : new ScaleAnimation(1, 0, 1, 1); + anim.setDuration(CONTROL_ANIM_DURATION_MS); + return anim; + } + + public PhotoPageBottomControls(Delegate delegate, Context context, RelativeLayout layout) { + mDelegate = delegate; + mParentLayout = layout; + + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + mContainer = (ViewGroup) inflater + .inflate(R.layout.photopage_bottom_controls, mParentLayout, false); + mParentLayout.addView(mContainer); + + for (int i = mContainer.getChildCount() - 1; i >= 0; i--) { + View child = mContainer.getChildAt(i); + child.setOnClickListener(this); + mControlsVisible.put(child, false); + } + + mContainerAnimIn.setDuration(CONTAINER_ANIM_DURATION_MS); + mContainerAnimOut.setDuration(CONTAINER_ANIM_DURATION_MS); + + refresh(); + } + + private void hide() { + mContainer.clearAnimation(); + mContainerAnimOut.reset(); + mContainer.startAnimation(mContainerAnimOut); + mContainer.setVisibility(View.INVISIBLE); + } + + private void show() { + mContainer.clearAnimation(); + mContainerAnimIn.reset(); + mContainer.startAnimation(mContainerAnimIn); + mContainer.setVisibility(View.VISIBLE); + } + + public void refresh() { + boolean visible = mDelegate.canDisplayBottomControls(); + boolean containerVisibilityChanged = (visible != mContainerVisible); + if (containerVisibilityChanged) { + if (visible) { + show(); + } else { + hide(); + } + mContainerVisible = visible; + } + if (!mContainerVisible) { + return; + } + for (View control : mControlsVisible.keySet()) { + Boolean prevVisibility = mControlsVisible.get(control); + boolean curVisibility = mDelegate.canDisplayBottomControl(control.getId()); + if (prevVisibility.booleanValue() != curVisibility) { + if (!containerVisibilityChanged) { + control.clearAnimation(); + control.startAnimation(getControlAnimForVisibility(curVisibility)); + } + control.setVisibility(curVisibility ? View.VISIBLE : View.INVISIBLE); + mControlsVisible.put(control, curVisibility); + } + } + } + + public void cleanup() { + mParentLayout.removeView(mContainer); + mControlsVisible.clear(); + } + + @Override + public void onClick(View view) { + if (mContainerVisible && mControlsVisible.get(view).booleanValue()) { + mDelegate.onBottomControlClicked(view.getId()); + } + } +}