diff options
author | Sascha Haeberling <haeberling@google.com> | 2013-08-15 17:19:22 -0700 |
---|---|---|
committer | Sascha Haeberling <haeberling@google.com> | 2013-08-19 11:39:16 -0700 |
commit | 88ef7664ba6a888fa5da8693091674e152b56192 (patch) | |
tree | 52c8293d42b394cf09b7d01551df1f2e4787e96a /src/com/android | |
parent | 1571239c21fc4be7fd3c8db6ff1b8dc22f4d7e6f (diff) | |
download | android_packages_apps_Snap-88ef7664ba6a888fa5da8693091674e152b56192.tar.gz android_packages_apps_Snap-88ef7664ba6a888fa5da8693091674e152b56192.tar.bz2 android_packages_apps_Snap-88ef7664ba6a888fa5da8693091674e152b56192.zip |
Bring back the bottom controls in Filmstrip.
Bug: 10367172
Bug: 10074320
Also hooks up the Edit button and the edit menu item.
Change-Id: I0ce3344e09fdfd7794c417ddbe44b3d247a7ed7c
Diffstat (limited to 'src/com/android')
-rw-r--r-- | src/com/android/camera/CameraActivity.java | 35 | ||||
-rw-r--r-- | src/com/android/camera/data/LocalData.java | 6 | ||||
-rw-r--r-- | src/com/android/camera/data/LocalMediaData.java | 15 | ||||
-rw-r--r-- | src/com/android/camera/data/SimpleViewData.java | 10 | ||||
-rw-r--r-- | src/com/android/camera/ui/FilmStripView.java | 173 | ||||
-rw-r--r-- | src/com/android/camera/ui/FilmstripBottomControls.java | 140 |
6 files changed, 300 insertions, 79 deletions
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java index e300b5d08..18fcee6cd 100644 --- a/src/com/android/camera/CameraActivity.java +++ b/src/com/android/camera/CameraActivity.java @@ -57,14 +57,14 @@ import com.android.camera.data.LocalData; import com.android.camera.data.LocalDataAdapter; import com.android.camera.data.MediaDetails; import com.android.camera.data.SimpleViewData; -import com.android.camera.util.ApiHelper; import com.android.camera.ui.CameraSwitcher; import com.android.camera.ui.CameraSwitcher.CameraSwitchListener; import com.android.camera.ui.DetailsDialog; import com.android.camera.ui.FilmStripView; +import com.android.camera.util.ApiHelper; import com.android.camera.util.CameraUtil; -import com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper; import com.android.camera.util.PhotoSphereHelper; +import com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper; import com.android.camera2.R; public class CameraActivity extends Activity @@ -235,12 +235,13 @@ public class CameraActivity extends Activity } @Override - public void onToggleActionBarVisibility() { + public boolean onToggleActionBarVisibility() { if (mActionBar.isShowing()) { mActionBar.hide(); } else { mActionBar.show(); } + return mActionBar.isShowing(); } }; @@ -439,7 +440,7 @@ public class CameraActivity extends Activity // TODO: add the functionality. return true; case R.id.action_edit: - // TODO: add the functionality. + launchEditor(localData); return true; case R.id.action_trim: // This is going to be handled by the Gallery app. @@ -623,12 +624,26 @@ public class CameraActivity extends Activity mCurrentModule.onResumeAfterSuper(); setSwipingEnabled(true); + + // We might be returning from an editor that changed the current item. + updateCurrentDataItem(); + } + + private void updateCurrentDataItem() { + int currentDataId = mFilmStripView.getCurrentId(); + if (currentDataId < 0) { + return; + } + final LocalData localData = mDataAdapter.getLocalData(currentDataId); + if (localData == null) { + return; + } + mDataAdapter.refresh(getContentResolver(), localData.getContentUri()); } @Override public void onStart() { super.onStart(); - mPanoramaViewHelper.onStart(); } @@ -776,6 +791,16 @@ public class CameraActivity extends Activity } } + /** + * Launches an ACTION_EDIT intent for the given local data item. + */ + public void launchEditor(LocalData data) { + Intent intent = new Intent(Intent.ACTION_EDIT) + .setDataAndType(data.getContentUri(), data.getMimeType()) + .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(Intent.createChooser(intent, null)); + } + private void openModule(CameraModule module) { module.init(this, mRootView); module.onResumeBeforeSuper(); diff --git a/src/com/android/camera/data/LocalData.java b/src/com/android/camera/data/LocalData.java index e25e93327..82567120e 100644 --- a/src/com/android/camera/data/LocalData.java +++ b/src/com/android/camera/data/LocalData.java @@ -103,6 +103,12 @@ public interface LocalData extends FilmStripView.ImageData { Uri getContentUri(); /** + * @return The mimetype of this data item, or null, if this item has no + * mimetype associated with it. + */ + String getMimeType(); + + /** * Return media data (such as EXIF) for the item. */ MediaDetails getMediaDetails(Context context); diff --git a/src/com/android/camera/data/LocalMediaData.java b/src/com/android/camera/data/LocalMediaData.java index 131c7e7db..7a63ddf17 100644 --- a/src/com/android/camera/data/LocalMediaData.java +++ b/src/com/android/camera/data/LocalMediaData.java @@ -211,6 +211,11 @@ public abstract class LocalMediaData implements LocalData { } @Override + public String getMimeType() { + return mimeType; + } + + @Override public abstract int getViewType(); protected abstract BitmapLoadTask getBitmapLoadTask( @@ -392,6 +397,11 @@ public abstract class LocalMediaData implements LocalData { } @Override + public boolean isPhoto() { + return true; + } + + @Override protected BitmapLoadTask getBitmapLoadTask( ImageView v, int decodeWidth, int decodeHeight) { return new PhotoBitmapLoadTask(v, decodeWidth, decodeHeight); @@ -616,6 +626,11 @@ public abstract class LocalMediaData implements LocalData { } @Override + public boolean isPhoto() { + return false; + } + + @Override protected BitmapLoadTask getBitmapLoadTask( ImageView v, int decodeWidth, int decodeHeight) { return new VideoBitmapLoadTask(v); diff --git a/src/com/android/camera/data/SimpleViewData.java b/src/com/android/camera/data/SimpleViewData.java index 59d5f2cd5..06ff3501b 100644 --- a/src/com/android/camera/data/SimpleViewData.java +++ b/src/com/android/camera/data/SimpleViewData.java @@ -155,4 +155,14 @@ public class SimpleViewData implements LocalData { public double[] getLatLong() { return null; } + + @Override + public boolean isPhoto() { + return false; + } + + @Override + public String getMimeType() { + return null; + } } diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java index 40f46b650..7b5505769 100644 --- a/src/com/android/camera/ui/FilmStripView.java +++ b/src/com/android/camera/ui/FilmStripView.java @@ -29,14 +29,17 @@ import android.view.View; import android.view.ViewGroup; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; -import android.widget.ImageButton; import android.widget.Scroller; +import com.android.camera.CameraActivity; +import com.android.camera.data.LocalData; import com.android.camera.ui.FilmStripView.ImageData.PanoramaSupportCallback; +import com.android.camera.ui.FilmstripBottomControls.BottomControlsListener; +import com.android.camera.util.CameraUtil; import com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper; import com.android.camera2.R; -public class FilmStripView extends ViewGroup { +public class FilmStripView extends ViewGroup implements BottomControlsListener { @SuppressWarnings("unused") private static final String TAG = "CAM_FilmStripView"; @@ -47,7 +50,7 @@ public class FilmStripView extends ViewGroup { // Only check for intercepting touch events within first 500ms private static final int SWIPE_TIME_OUT = 500; - private Context mContext; + private CameraActivity mActivity; private FilmStripGestureRecognizer mGestureRecognizer; private DataAdapter mDataAdapter; private int mViewGap; @@ -67,7 +70,7 @@ public class FilmStripView extends ViewGroup { private int mSlop; private TimeInterpolator mViewAnimInterpolator; - private ImageButton mViewPhotoSphereButton; + private FilmstripBottomControls mBottomControls; private PanoramaViewHelper mPanoramaViewHelper; private long mLastItemId = -1; @@ -115,10 +118,10 @@ public class FilmStripView extends ViewGroup { /** * SIZE_FULL can be returned by {@link ImageData#getWidth()} and - * {@link ImageData#getHeight()}. - * When SIZE_FULL is returned for width/height, it means the the - * width or height will be disregarded when deciding the view size - * of this ImageData, just use full screen size. + * {@link ImageData#getHeight()}. When SIZE_FULL is returned for + * width/height, it means the the width or height will be disregarded + * when deciding the view size of this ImageData, just use full screen + * size. */ public static final int SIZE_FULL = -2; @@ -155,15 +158,15 @@ public class FilmStripView extends ViewGroup { * Checks if the UI action is supported. * * @param action The UI actions to check. - * @return {@code false} if at least one of the actions is not - * supported. {@code true} otherwise. + * @return {@code false} if at least one of the actions is not + * supported. {@code true} otherwise. */ public boolean isUIActionSupported(int action); /** * Gives the data a hint when its view is going to be displayed. - * {@code FilmStripView} should always call this function before - * showing its corresponding view every time. + * {@code FilmStripView} should always call this function before showing + * its corresponding view every time. */ public void prepare(); @@ -186,6 +189,9 @@ public class FilmStripView extends ViewGroup { * the viewer. */ public void viewPhotoSphere(PanoramaViewHelper helper); + + /** Whether this item is a photo. */ + public boolean isPhoto(); } /** @@ -194,8 +200,8 @@ public class FilmStripView extends ViewGroup { */ public interface DataAdapter { /** - * An interface which defines the update report used to return to - * the {@link com.android.camera.ui.FilmStripView.Listener}. + * An interface which defines the update report used to return to the + * {@link com.android.camera.ui.FilmStripView.Listener}. */ public interface UpdateReporter { /** Checks if the data of dataID is removed. */ @@ -229,10 +235,10 @@ public class FilmStripView extends ViewGroup { /** * Returns the view to visually present the image data. * - * @param context The {@link Context} to create the view. - * @param dataID The ID of the image data to be presented. - * @return The view representing the image data. Null if - * unavailable or the {@code dataID} is out of range. + * @param context The {@link Context} to create the view. + * @param dataID The ID of the image data to be presented. + * @return The view representing the image data. Null if unavailable or + * the {@code dataID} is out of range. */ public View getView(Context context, int dataID); @@ -240,13 +246,13 @@ public class FilmStripView extends ViewGroup { * Returns the {@link ImageData} specified by the ID. * * @param dataID The ID of the {@link ImageData}. - * @return The specified {@link ImageData}. Null if not available. + * @return The specified {@link ImageData}. Null if not available. */ public ImageData getImageData(int dataID); /** - * Suggests the data adapter the maximum possible size of the layout - * so the {@link DataAdapter} can optimize the view returned for the + * Suggests the data adapter the maximum possible size of the layout so + * the {@link DataAdapter} can optimize the view returned for the * {@link ImageData}. * * @param w Maximum width. @@ -266,8 +272,8 @@ public class FilmStripView extends ViewGroup { * gesture when in full-screen. * * @param dataID The ID of the data. - * @return {@code true} if the view can be moved, - * {@code false} otherwise. + * @return {@code true} if the view can be moved, {@code false} + * otherwise. */ public boolean canSwipeInFullScreen(int dataID); } @@ -291,12 +297,12 @@ public class FilmStripView extends ViewGroup { public void onDataDemoted(int dataID); /** - * The callback when the item enters/leaves full-screen. - * TODO: Call this function actually. + * The callback when the item enters/leaves full-screen. TODO: Call this + * function actually. * - * @param dataID The ID of the image data. - * @param fullScreen {@code true} if the data is entering full-screen. - * {@code false} otherwise. + * @param dataID The ID of the image data. + * @param fullScreen {@code true} if the data is entering full-screen. + * {@code false} otherwise. */ public void onDataFullScreenChange(int dataID, boolean fullScreen); @@ -304,23 +310,25 @@ public class FilmStripView extends ViewGroup { * Callback when entering/leaving camera mode. * * @param toCamera {@code true} if entering camera mode. Otherwise, - * {@code false} + * {@code false} */ public void onSwitchMode(boolean toCamera); /** * The callback when the item is centered/off-centered. * - * @param dataID The ID of the image data. - * @param current {@code true} if the data is the current one. - * {@code false} otherwise. + * @param dataID The ID of the image data. + * @param current {@code true} if the data is the current one. + * {@code false} otherwise. */ public void onCurrentDataChanged(int dataID, boolean current); /** * Toggles the visibility of the ActionBar. + * + * @return The ActionBar visibility after the toggle. */ - public void onToggleActionBarVisibility(); + public boolean onToggleActionBarVisibility(); } /** @@ -362,6 +370,7 @@ public class FilmStripView extends ViewGroup { /** * Constructor. + * * @param id The id of the data from {@link DataAdapter}. * @param v The {@code View} representing the data. */ @@ -434,12 +443,12 @@ public class FilmStripView extends ViewGroup { } /** - * Layouts the view in the area assuming the center of the area is at - * a specific point of the whole filmstrip. + * Layouts the view in the area assuming the center of the area is at a + * specific point of the whole filmstrip. * * @param drawArea The area when filmstrip will show in. * @param refCenter The absolute X coordination in the whole filmstrip - * of the center of {@code drawArea}. + * of the center of {@code drawArea}. * @param scale The current scale of the filmstrip. */ public void layoutIn(Rect drawArea, int refCenter, float scale) { @@ -463,37 +472,36 @@ public class FilmStripView extends ViewGroup { } } - /** Constructor. */ public FilmStripView(Context context) { super(context); - init(context); + init((CameraActivity) context); } /** Constructor. */ public FilmStripView(Context context, AttributeSet attrs) { super(context, attrs); - init(context); + init((CameraActivity) context); } /** Constructor. */ public FilmStripView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - init(context); + init((CameraActivity) context); } - private void init(Context context) { + private void init(CameraActivity cameraActivity) { // This is for positioning camera controller at the same place in // different orientations. setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); setWillNotDraw(false); - mContext = context; + mActivity = cameraActivity; mScale = 1.0f; - mController = new MyController(context); + mController = new MyController(cameraActivity); mViewAnimInterpolator = new DecelerateInterpolator(); mGestureRecognizer = - new FilmStripGestureRecognizer(context, new MyGestureReceiver()); + new FilmStripGestureRecognizer(cameraActivity, new MyGestureReceiver()); mSlop = (int) getContext().getResources().getDimension(R.dimen.pie_touch_slop); } @@ -595,7 +603,9 @@ public class FilmStripView extends ViewGroup { } for (ViewInfo info : mViewInfo) { - if (info == null) continue; + if (info == null) { + continue; + } int id = info.getID(); int[] dim = calculateChildDimension( @@ -613,14 +623,13 @@ public class FilmStripView extends ViewGroup { @Override protected boolean fitSystemWindows(Rect insets) { - if (mViewPhotoSphereButton != null) { + if (mBottomControls != null) { // Set the position of the "View Photo Sphere" button. - FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mViewPhotoSphereButton + FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mBottomControls .getLayoutParams(); params.bottomMargin = insets.bottom; - mViewPhotoSphereButton.setLayoutParams(params); + mBottomControls.setLayoutParams(params); } - return super.fitSystemWindows(insets); } @@ -659,7 +668,7 @@ public class FilmStripView extends ViewGroup { return null; } data.prepare(); - View v = mDataAdapter.getView(mContext, dataID); + View v = mDataAdapter.getView(mActivity, dataID); if (v == null) { return null; } @@ -769,13 +778,28 @@ public class FilmStripView extends ViewGroup { * If the current photo is a photo sphere, this will launch the Photo Sphere * panorama viewer. */ - private void showPhotoSphere() { + @Override + public void onViewPhotoSphere() { ViewInfo curr = mViewInfo[mCurrentInfo]; if (curr != null) { mDataAdapter.getImageData(curr.getID()).viewPhotoSphere(mPanoramaViewHelper); } } + @Override + public void onEdit() { + ImageData data = mDataAdapter.getImageData(getCurrentId()); + if (data == null || !(data instanceof LocalData)) { + return; + } + mActivity.launchEditor((LocalData) data); + } + + @Override + public void onTinyPlanet() { + // TODO: Bring tiny planet to Camera2. + } + /** * @return The ID of the current item, or -1. */ @@ -788,19 +812,16 @@ public class FilmStripView extends ViewGroup { } /** - * Updates the visibility of the View Photo Sphere button. + * Updates the visibility of the bottom controls depending on the current + * data item. */ - private void updatePhotoSphereViewButton() { - if (mViewPhotoSphereButton == null) { - mViewPhotoSphereButton = (ImageButton) ((View) getParent()) - .findViewById(R.id.filmstrip_bottom_control_panorama); - mViewPhotoSphereButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View view) { - showPhotoSphere(); - } - }); + private void updateBottomControls() { + if (mBottomControls == null) { + mBottomControls = (FilmstripBottomControls) ((View) getParent()) + .findViewById(R.id.filmstrip_bottom_controls); + mBottomControls.setListener(this); } + final int requestId = getCurrentId(); // Check if the item has changed since the last time we updated the @@ -811,19 +832,20 @@ public class FilmStripView extends ViewGroup { } ImageData data = mDataAdapter.getImageData(requestId); - data.isPhotoSphere(mContext, new PanoramaSupportCallback() { + + // We can only edit photos, not videos. + mBottomControls.setEditButtonVisibility(data.isPhoto()); + + // If this is a photo sphere, show the button to view it. If it's a full + // 360 photo sphere, show the tiny planet button. + data.isPhotoSphere(mActivity, new PanoramaSupportCallback() { @Override public void panoramaInfoAvailable(final boolean isPanorama, boolean isPanorama360) { // Make sure the returned data is for the current image. if (requestId == getCurrentId()) { - mViewPhotoSphereButton.post(new Runnable() { - @Override - public void run() { - mViewPhotoSphereButton.setVisibility(isPanorama ? View.VISIBLE - : View.GONE); - } - }); + mBottomControls.setViewPhotoSphereButtonVisibility(isPanorama); + mBottomControls.setTinyPlanetButtonVisibility(isPanorama360); } } }); @@ -869,8 +891,8 @@ public class FilmStripView extends ViewGroup { int fullScreenWidth = mDrawArea.width() + mViewGap; /** * Transformed scale fraction between 0 and 1. 0 if the scale is - * {@link FILM_STRIP_SCALE}. 1 if the scale is - * {@link FULL_SCREEN_SCALE}. + * {@link FILM_STRIP_SCALE}. 1 if the scale is {@link FULL_SCREEN_SCALE} + * . */ float scaleFraction = mViewAnimInterpolator.getInterpolation( (mScale - FILM_STRIP_SCALE) / (FULL_SCREEN_SCALE - FILM_STRIP_SCALE)); @@ -931,7 +953,7 @@ public class FilmStripView extends ViewGroup { adjustChildZOrder(); snapInCenter(); invalidate(); - updatePhotoSphereViewButton(); + updateBottomControls(); mLastItemId = getCurrentId(); } @@ -1553,6 +1575,7 @@ public class FilmStripView extends ViewGroup { scaleTo(FILM_STRIP_SCALE, DURATION_GEOMETRY_ADJUST); if (mListener != null) { mListener.onSwitchMode(false); + mBottomControls.setVisibility(View.VISIBLE); } } @@ -1572,6 +1595,7 @@ public class FilmStripView extends ViewGroup { // this call when the view on the center of the screen is // camera preview mListener.onSwitchMode(true); + mBottomControls.setVisibility(View.GONE); } if (inFullScreen()) { return; @@ -1645,7 +1669,8 @@ public class FilmStripView extends ViewGroup { return true; } } else if (inFullScreen()) { - mListener.onToggleActionBarVisibility(); + boolean visible = mListener.onToggleActionBarVisibility(); + mBottomControls.setVisibility(visible ? View.VISIBLE : View.GONE); return true; } return false; diff --git a/src/com/android/camera/ui/FilmstripBottomControls.java b/src/com/android/camera/ui/FilmstripBottomControls.java new file mode 100644 index 000000000..3b0435b35 --- /dev/null +++ b/src/com/android/camera/ui/FilmstripBottomControls.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.ui; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageButton; +import android.widget.RelativeLayout; + +import com.android.camera2.R; + +/** + * Shows controls at the bottom of the screen for editing, viewing a photo + * sphere image and creating a tiny planet from a photo sphere image. + */ +public class FilmstripBottomControls extends RelativeLayout { + + /** + * Classes implementing this interface can listen for events on the bottom + * controls. + */ + public static interface BottomControlsListener { + /** + * Called when the user pressed the "view photosphere" button. + */ + public void onViewPhotoSphere(); + + /** + * Called when the user pressed the "edit" button. + */ + public void onEdit(); + + /** + * Called when the user pressed the "tiny planet" button. + */ + public void onTinyPlanet(); + } + + private BottomControlsListener mListener; + private ImageButton mEditButton; + private ImageButton mViewPhotoSphereButton; + private ImageButton mTinyPlanetButton; + + public FilmstripBottomControls(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mEditButton = (ImageButton) + findViewById(R.id.filmstrip_bottom_control_edit); + mEditButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + if (mListener != null) { + mListener.onEdit(); + } + } + }); + + mViewPhotoSphereButton = (ImageButton) + findViewById(R.id.filmstrip_bottom_control_panorama); + mViewPhotoSphereButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + if (mListener != null) { + mListener.onViewPhotoSphere(); + } + } + }); + + mTinyPlanetButton = (ImageButton) + findViewById(R.id.filmstrip_bottom_control_tiny_planet); + mTinyPlanetButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + if (mListener != null) { + mListener.onTinyPlanet(); + } + } + }); + } + + /** + * Sets a new or replaces an existing listener for bottom control events. + */ + public void setListener(BottomControlsListener listener) { + mListener = listener; + } + + /** + * Sets the visibility of the edit button. + */ + public void setEditButtonVisibility(boolean visible) { + setVisibility(mEditButton, visible); + } + + /** + * Sets the visibility of the view-photosphere button. + */ + public void setViewPhotoSphereButtonVisibility(boolean visible) { + setVisibility(mViewPhotoSphereButton, visible); + } + + /** + * Sets the visibility of the tiny-planet button. + */ + public void setTinyPlanetButtonVisibility(final boolean visible) { + setVisibility(mTinyPlanetButton, visible); + } + + /** + * Sets the visibility of the given view. + */ + private static void setVisibility(final View view, final boolean visible) { + view.post(new Runnable() { + @Override + public void run() { + view.setVisibility(visible ? View.VISIBLE + : View.GONE); + } + }); + } +} |