diff options
author | nicolasroard <nicolasroard@google.com> | 2013-08-09 14:09:56 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-08-09 14:09:56 +0000 |
commit | 5bf3bf4b44dee73e2ba54680460a2237cd1258ec (patch) | |
tree | ccd0ab3f7dbe03ef5bdd9445394147c470b0a920 /src | |
parent | 723bf81990245a07739146ac10357703c9839de1 (diff) | |
parent | 860af325f2030a03c526e8551a85230d17df7b15 (diff) | |
download | android_packages_apps_Gallery2-5bf3bf4b44dee73e2ba54680460a2237cd1258ec.tar.gz android_packages_apps_Gallery2-5bf3bf4b44dee73e2ba54680460a2237cd1258ec.tar.bz2 android_packages_apps_Gallery2-5bf3bf4b44dee73e2ba54680460a2237cd1258ec.zip |
Merge "Add version category Fix bugs when loading Add info panel" into gb-ub-photos-carlsbad
Diffstat (limited to 'src')
12 files changed, 644 insertions, 6 deletions
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java index 0d1d6a34e..7e15bf143 100644 --- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java +++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java @@ -45,6 +45,7 @@ import android.util.Log; import android.util.TypedValue; import android.view.Menu; import android.view.MenuItem; +import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewPropertyAnimator; @@ -63,6 +64,7 @@ import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.category.Action; import com.android.gallery3d.filtershow.category.CategoryAdapter; import com.android.gallery3d.filtershow.category.MainPanel; +import com.android.gallery3d.filtershow.category.SwipableView; import com.android.gallery3d.filtershow.data.UserPresetsManager; import com.android.gallery3d.filtershow.editors.BasicEditor; import com.android.gallery3d.filtershow.editors.Editor; @@ -87,6 +89,7 @@ import com.android.gallery3d.filtershow.history.HistoryManager; import com.android.gallery3d.filtershow.imageshow.ImageShow; import com.android.gallery3d.filtershow.imageshow.MasterImage; import com.android.gallery3d.filtershow.imageshow.Spline; +import com.android.gallery3d.filtershow.info.InfoPanel; import com.android.gallery3d.filtershow.pipeline.CachingPipeline; import com.android.gallery3d.filtershow.pipeline.ImagePreset; import com.android.gallery3d.filtershow.pipeline.ProcessingService; @@ -129,6 +132,8 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL private boolean mShowingTinyPlanet = false; private boolean mShowingImageStatePanel = false; + private boolean mShowingVersionsPanel = false; + private boolean mShowingInformationPanel = false; private final Vector<ImageShow> mImageViews = new Vector<ImageShow>(); @@ -152,7 +157,16 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL private CategoryAdapter mCategoryBordersAdapter = null; private CategoryAdapter mCategoryGeometryAdapter = null; private CategoryAdapter mCategoryFiltersAdapter = null; + private CategoryAdapter mCategoryVersionsAdapter = null; private int mCurrentPanel = MainPanel.LOOKS; + private Vector<FilterUserPresetRepresentation> mVersions = + new Vector<FilterUserPresetRepresentation>(); + private int mVersionsCounter = 0; + + private boolean mHandlingSwipeButton = false; + private View mHandledSwipeView = null; + private float mHandledSwipeViewLastDelta = 0; + private float mSwipeStartY = 0; private ProcessingService mBoundService; private boolean mIsBound = false; @@ -303,6 +317,37 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL } } + private void hideInformationPanel() { + FrameLayout infoLayout = (FrameLayout) findViewById(R.id.central_panel_container); + infoLayout.setVisibility(View.GONE); + Fragment fragment = getSupportFragmentManager().findFragmentByTag(InfoPanel.FRAGMENT_TAG); + if (fragment != null) { + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + transaction.remove(fragment); + transaction.commit(); + } + mShowingInformationPanel = false; + } + + public void showInformationPanel() { + mShowingInformationPanel = !mShowingInformationPanel; + if (!mShowingInformationPanel) { + hideInformationPanel(); + showDefaultImageView(); + return; + } + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + transaction.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left); + FrameLayout infoLayout = (FrameLayout) findViewById(R.id.central_panel_container); + infoLayout.setVisibility(View.VISIBLE); + mEditorPlaceHolder.hide(); + mImageShow.setVisibility(View.GONE); + + InfoPanel panel = new InfoPanel(); + transaction.replace(R.id.central_panel_container, panel, InfoPanel.FRAGMENT_TAG); + transaction.commit(); + } + private void loadXML() { setContentView(R.layout.filtershow_activity); @@ -335,12 +380,50 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL fillBorders(); fillTools(); fillEffects(); + fillVersions(); } public void setupStatePanel() { MasterImage.getImage().setHistoryManager(mMasterImage.getHistory()); } + private void fillVersions() { + mCategoryVersionsAdapter = new CategoryAdapter(this); + mCategoryVersionsAdapter.setShowAddButton(true); + } + + public void updateVersions() { + mCategoryVersionsAdapter.clear(); + FilterUserPresetRepresentation originalRep = new FilterUserPresetRepresentation( + getString(R.string.filtershow_version_original), new ImagePreset(), -1); + mCategoryVersionsAdapter.add( + new Action(this, originalRep, Action.FULL_VIEW)); + ImagePreset current = new ImagePreset(MasterImage.getImage().getPreset()); + FilterUserPresetRepresentation currentRep = new FilterUserPresetRepresentation( + getString(R.string.filtershow_version_current), current, -1); + mCategoryVersionsAdapter.add( + new Action(this, currentRep, Action.FULL_VIEW)); + for (FilterUserPresetRepresentation rep : mVersions) { + mCategoryVersionsAdapter.add( + new Action(this, rep, Action.FULL_VIEW)); + } + mCategoryVersionsAdapter.notifyDataSetInvalidated(); + } + + public void addCurrentVersion() { + ImagePreset current = new ImagePreset(MasterImage.getImage().getPreset()); + mVersionsCounter++; + FilterUserPresetRepresentation rep = new FilterUserPresetRepresentation( + "" + mVersionsCounter, current, -1); + mVersions.add(rep); + updateVersions(); + } + + public void removeVersion(Action action) { + mVersions.remove(action.getRepresentation()); + updateVersions(); + } + private void fillEffects() { FiltersManager filtersManager = FiltersManager.getManager(); ArrayList<FilterRepresentation> filtersRepresentations = filtersManager.getEffects(); @@ -466,6 +549,10 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL return mCategoryFiltersAdapter; } + public CategoryAdapter getCategoryVersionsAdapter() { + return mCategoryVersionsAdapter; + } + public void removeFilterRepresentation(FilterRepresentation filterRepresentation) { if (filterRepresentation == null) { return; @@ -517,6 +604,7 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL // show representation Editor mCurrentEditor = mEditorPlaceHolder.showEditor(representation.getEditorId()); loadEditorPanel(representation, mCurrentEditor); + hideInformationPanel(); } public Editor getEditor(int editorID) { @@ -622,6 +710,7 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL Bitmap largeBitmap = MasterImage.getImage().getOriginalBitmapLarge(); mBoundService.setOriginalBitmap(largeBitmap); + MasterImage.getImage().resetGeometryImages(); float previewScale = (float) largeBitmap.getWidth() / (float) MasterImage.getImage().getOriginalBounds().width(); @@ -836,6 +925,10 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL manageUserPresets(); return true; } + case R.id.showInfoPanel: { + showInformationPanel(); + return true; + } } return false; } @@ -960,6 +1053,15 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL } } + public void toggleVersionsPanel() { + mShowingVersionsPanel = !mShowingVersionsPanel; + Fragment panel = getSupportFragmentManager().findFragmentByTag(MainPanel.FRAGMENT_TAG); + if (panel != null && panel instanceof MainPanel) { + MainPanel mainPanel = (MainPanel) panel; + mainPanel.loadCategoryVersionsPanel(); + } + } + @Override public void onConfigurationChanged(Configuration newConfig) { @@ -1005,6 +1107,7 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL } public void showDefaultImageView() { + hideInformationPanel(); mEditorPlaceHolder.hide(); mImageShow.setVisibility(View.VISIBLE); MasterImage.getImage().setCurrentFilter(null); @@ -1123,4 +1226,39 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL return mSelectedImageUri; } + public void setHandlesSwipeForView(View view, float startY) { + if (view != null) { + mHandlingSwipeButton = true; + } else { + mHandlingSwipeButton = false; + } + mHandledSwipeView = view; + int[] location = new int[2]; + view.getLocationInWindow(location); + mSwipeStartY = location[1] + startY; + } + + public boolean dispatchTouchEvent (MotionEvent ev) { + if (mHandlingSwipeButton) { + if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) { + float delta = ev.getY() - mSwipeStartY; + mHandledSwipeView.setTranslationY(delta); + delta = Math.abs(delta); + float transparency = Math.min(1, delta / mHandledSwipeView.getHeight()); + mHandledSwipeView.setAlpha(1.f - transparency); + mHandledSwipeViewLastDelta = delta; + } + if (ev.getActionMasked() == MotionEvent.ACTION_CANCEL + || ev.getActionMasked() == MotionEvent.ACTION_UP) { + mHandledSwipeView.setTranslationY(0); + mHandledSwipeView.setAlpha(1.f); + mHandlingSwipeButton = false; + if (mHandledSwipeViewLastDelta > mHandledSwipeView.getHeight()) { + ((SwipableView) mHandledSwipeView).delete(); + } + } + return true; + } + return super.dispatchTouchEvent(ev); + } } diff --git a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java index b6c72fd9d..30a0bfadc 100644 --- a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java +++ b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java @@ -18,7 +18,6 @@ package com.android.gallery3d.filtershow.cache; import android.content.ContentResolver; import android.content.Context; -import android.content.Intent; import android.content.res.Resources; import android.database.Cursor; import android.database.sqlite.SQLiteException; @@ -34,15 +33,17 @@ import android.webkit.MimeTypeMap; import com.adobe.xmp.XMPException; import com.adobe.xmp.XMPMeta; -import com.android.gallery3d.R; import com.android.gallery3d.common.Utils; import com.android.gallery3d.exif.ExifInterface; +import com.android.gallery3d.exif.ExifTag; import com.android.gallery3d.filtershow.imageshow.MasterImage; +import com.android.gallery3d.filtershow.tools.XmpPresets; import com.android.gallery3d.util.XmpUtilHelper; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.util.List; public final class ImageLoader { @@ -77,6 +78,14 @@ public final class ImageLoader { return ret; } + public static String getLocalPathFromUri(Context context, Uri uri) { + Cursor cursor = context.getContentResolver().query(uri, + new String[]{MediaStore.Images.Media.DATA}, null, null, null); + int index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + cursor.moveToFirst(); + return cursor.getString(index); + } + /** * Returns the image's orientation flag. Defaults to ORI_NORMAL if no valid * orientation was found. @@ -499,4 +508,24 @@ public final class ImageLoader { Utils.closeSilently(is); } } + + public static List<ExifTag> getExif(Context context, Uri uri) { + String path = getLocalPathFromUri(context, uri); + if (path != null) { + Uri localUri = Uri.parse(path); + String mimeType = getMimeType(localUri); + if (!JPEG_MIME_TYPE.equals(mimeType)) { + return null; + } + try { + ExifInterface exif = new ExifInterface(); + exif.readExif(path); + List<ExifTag> taglist = exif.getAllTags(); + return taglist; + } catch (IOException e) { + Log.w(LOGTAG, "Failed to read EXIF tags", e); + } + } + return null; + } } diff --git a/src/com/android/gallery3d/filtershow/category/CategoryAdapter.java b/src/com/android/gallery3d/filtershow/category/CategoryAdapter.java index 6451c39df..ad8601094 100644 --- a/src/com/android/gallery3d/filtershow/category/CategoryAdapter.java +++ b/src/com/android/gallery3d/filtershow/category/CategoryAdapter.java @@ -22,6 +22,8 @@ import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListView; +import com.android.gallery3d.R; +import com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.filters.FilterRepresentation; import com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation; import com.android.gallery3d.filtershow.pipeline.ImagePreset; @@ -35,6 +37,8 @@ public class CategoryAdapter extends ArrayAdapter<Action> { private int mSelectedPosition; int mCategory; private int mOrientation; + private boolean mShowAddButton = false; + private String mAddButtonText; public CategoryAdapter(Context context, int textViewResourceId) { super(context, textViewResourceId); @@ -64,10 +68,14 @@ public class CategoryAdapter extends ArrayAdapter<Action> { mSelectedPosition = -1; if (category == MainPanel.LOOKS) { mSelectedPosition = 0; + mAddButtonText = getContext().getString(R.string.filtershow_add_button_looks); } if (category == MainPanel.BORDERS) { mSelectedPosition = 0; } + if (category == MainPanel.VERSIONS) { + mAddButtonText = getContext().getString(R.string.filtershow_add_button_versions); + } } @Override @@ -138,12 +146,22 @@ public class CategoryAdapter extends ArrayAdapter<Action> { if (action.getRepresentation() != null && action.getRepresentation() instanceof FilterTinyPlanetRepresentation) { - remove(action); + super.remove(action); return; } } } + @Override + public void remove(Action action) { + if (mCategory != MainPanel.VERSIONS) { + return; + } + super.remove(action); + FilterShowActivity activity = (FilterShowActivity) getContext(); + activity.removeVersion(action); + } + public void setOrientation(int orientation) { mOrientation = orientation; } @@ -179,4 +197,16 @@ public class CategoryAdapter extends ArrayAdapter<Action> { this.notifyDataSetChanged(); } } + + public boolean showAddButton() { + return mShowAddButton; + } + + public void setShowAddButton(boolean showAddButton) { + mShowAddButton = showAddButton; + } + + public String getAddButtonText() { + return mAddButtonText; + } } diff --git a/src/com/android/gallery3d/filtershow/category/CategoryPanel.java b/src/com/android/gallery3d/filtershow/category/CategoryPanel.java index de2481f3f..0dfe7cb3c 100644 --- a/src/com/android/gallery3d/filtershow/category/CategoryPanel.java +++ b/src/com/android/gallery3d/filtershow/category/CategoryPanel.java @@ -17,23 +17,28 @@ package com.android.gallery3d.filtershow.category; import android.app.Activity; +import android.graphics.Rect; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.ListView; +import android.widget.TextView; import com.android.gallery3d.R; import com.android.gallery3d.filtershow.FilterShowActivity; -public class CategoryPanel extends Fragment { +public class CategoryPanel extends Fragment implements View.OnClickListener { public static final String FRAGMENT_TAG = "CategoryPanel"; private static final String PARAMETER_TAG = "currentPanel"; private int mCurrentAdapter = MainPanel.LOOKS; private CategoryAdapter mAdapter; + private ImageButton mAddButton; + private TextView mAddButtonText; public void setAdapter(int value) { mCurrentAdapter = value; @@ -70,7 +75,13 @@ public class CategoryPanel extends Fragment { mAdapter.initializeSelection(MainPanel.FILTERS); break; } + case MainPanel.VERSIONS: { + mAdapter = activity.getCategoryVersionsAdapter(); + mAdapter.initializeSelection(MainPanel.VERSIONS); + break; + } } + updateAddButtonVisibility(); } @Override @@ -102,7 +113,38 @@ public class CategoryPanel extends Fragment { panel.setAdapter(mAdapter); mAdapter.setContainer(panel); } + + mAddButton = (ImageButton) main.findViewById(R.id.addButton); + mAddButtonText = (TextView) main.findViewById(R.id.addButtonText); + if (mAddButton != null) { + mAddButton.setOnClickListener(this); + updateAddButtonVisibility(); + } return main; } + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.addButton: + FilterShowActivity activity = (FilterShowActivity) getActivity(); + activity.addCurrentVersion(); + break; + } + } + + public void updateAddButtonVisibility() { + if (mAddButton == null) { + return; + } + FilterShowActivity activity = (FilterShowActivity) getActivity(); + if (activity.isShowingImageStatePanel() && mAdapter.showAddButton()) { + mAddButton.setVisibility(View.VISIBLE); + if (mAdapter != null) { + mAddButtonText.setText(mAdapter.getAddButtonText()); + } + } else { + mAddButton.setVisibility(View.GONE); + } + } } diff --git a/src/com/android/gallery3d/filtershow/category/CategoryTrack.java b/src/com/android/gallery3d/filtershow/category/CategoryTrack.java index ac8245a3b..1371fe876 100644 --- a/src/com/android/gallery3d/filtershow/category/CategoryTrack.java +++ b/src/com/android/gallery3d/filtershow/category/CategoryTrack.java @@ -19,8 +19,10 @@ package com.android.gallery3d.filtershow.category; import android.content.Context; import android.content.res.TypedArray; import android.database.DataSetObserver; +import android.graphics.Rect; import android.util.AttributeSet; import android.util.Log; +import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout; import com.android.gallery3d.R; @@ -29,11 +31,17 @@ public class CategoryTrack extends LinearLayout { private CategoryAdapter mAdapter; private int mElemSize; + private View mSelectedView; + private float mStartTouchY; private DataSetObserver mDataSetObserver = new DataSetObserver() { @Override public void onChanged() { super.onChanged(); - invalidate(); + if (getChildCount() != mAdapter.getCount()) { + fillContent(); + } else { + invalidate(); + } } @Override public void onInvalidated() { diff --git a/src/com/android/gallery3d/filtershow/category/CategoryView.java b/src/com/android/gallery3d/filtershow/category/CategoryView.java index c456dc207..dc2b63a89 100644 --- a/src/com/android/gallery3d/filtershow/category/CategoryView.java +++ b/src/com/android/gallery3d/filtershow/category/CategoryView.java @@ -24,13 +24,16 @@ import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; +import android.util.Log; +import android.view.MotionEvent; import android.view.View; import com.android.gallery3d.R; import com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.filters.FilterRepresentation; import com.android.gallery3d.filtershow.ui.SelectionRenderer; -public class CategoryView extends View implements View.OnClickListener { +public class CategoryView extends View + implements View.OnClickListener, SwipableView{ private static final String LOGTAG = "CategoryView"; public static final int VERTICAL = 0; @@ -48,6 +51,8 @@ public class CategoryView extends View implements View.OnClickListener { private Paint mBorderPaint; private int mBorderStroke; private int mOrientation = VERTICAL; + private float mStartTouchY = 0; + private float mDeleteSlope = 20; public CategoryView(Context context) { super(context); @@ -173,4 +178,28 @@ public class CategoryView extends View implements View.OnClickListener { public void setOrientation(int orientation) { mOrientation = orientation; } + + @Override + public boolean onTouchEvent(MotionEvent event) { + super.onTouchEvent(event); + if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { + mStartTouchY = event.getY(); + } + if (event.getActionMasked() == MotionEvent.ACTION_UP) { + setTranslationY(0); + } + if (event.getActionMasked() == MotionEvent.ACTION_MOVE) { + float delta = event.getY() - mStartTouchY; + if (Math.abs(delta) > mDeleteSlope) { + FilterShowActivity activity = (FilterShowActivity) getContext(); + activity.setHandlesSwipeForView(this, mStartTouchY); + } + } + return true; + } + + @Override + public void delete() { + mAdapter.remove(mAction); + } } diff --git a/src/com/android/gallery3d/filtershow/category/MainPanel.java b/src/com/android/gallery3d/filtershow/category/MainPanel.java index 9a64ffbf3..47f575d4d 100644 --- a/src/com/android/gallery3d/filtershow/category/MainPanel.java +++ b/src/com/android/gallery3d/filtershow/category/MainPanel.java @@ -44,8 +44,10 @@ public class MainPanel extends Fragment { public static final int BORDERS = 1; public static final int GEOMETRY = 2; public static final int FILTERS = 3; + public static final int VERSIONS = 4; private int mCurrentSelected = -1; + private int mPreviousToggleVersions = -1; private void selection(int position, boolean value) { if (value) { @@ -146,6 +148,7 @@ public class MainPanel extends Fragment { public void loadCategoryLookPanel() { if (mCurrentSelected == LOOKS) { + return; } boolean fromRight = isRightAnimation(LOOKS); @@ -196,6 +199,21 @@ public class MainPanel extends Fragment { selection(mCurrentSelected, true); } + public void loadCategoryVersionsPanel() { + if (mCurrentSelected == VERSIONS) { + return; + } + FilterShowActivity activity = (FilterShowActivity) getActivity(); + activity.updateVersions(); + boolean fromRight = isRightAnimation(VERSIONS); + selection(mCurrentSelected, false); + CategoryPanel categoryPanel = new CategoryPanel(); + categoryPanel.setAdapter(VERSIONS); + setCategoryFragment(categoryPanel, fromRight); + mCurrentSelected = VERSIONS; + selection(mCurrentSelected, true); + } + public void showPanel(int currentPanel) { switch (currentPanel) { case LOOKS: { @@ -214,18 +232,43 @@ public class MainPanel extends Fragment { loadCategoryFiltersPanel(); break; } + case VERSIONS: { + loadCategoryVersionsPanel(); + break; + } } } + public void setToggleVersionsPanelButton(ImageButton button) { + if (button == null) { + return; + } + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mCurrentSelected == VERSIONS) { + showPanel(mPreviousToggleVersions); + } else { + mPreviousToggleVersions = mCurrentSelected; + showPanel(VERSIONS); + } + } + }); + } + public void showImageStatePanel(boolean show) { if (mMainView.findViewById(R.id.state_panel_container) == null) { return; } FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); final View container = mMainView.findViewById(R.id.state_panel_container); + int currentPanel = mCurrentSelected; if (show) { container.setVisibility(View.VISIBLE); StatePanel statePanel = new StatePanel(); + statePanel.setMainPanel(this); + FilterShowActivity activity = (FilterShowActivity) getActivity(); + activity.updateVersions(); transaction.replace(R.id.state_panel_container, statePanel, StatePanel.FRAGMENT_TAG); } else { container.setVisibility(View.GONE); @@ -233,7 +276,12 @@ public class MainPanel extends Fragment { if (statePanel != null) { transaction.remove(statePanel); } + if (currentPanel == VERSIONS) { + currentPanel = LOOKS; + } } + mCurrentSelected = -1; + showPanel(currentPanel); transaction.commit(); } } diff --git a/src/com/android/gallery3d/filtershow/category/SwipableView.java b/src/com/android/gallery3d/filtershow/category/SwipableView.java new file mode 100644 index 000000000..cb69f0cbb --- /dev/null +++ b/src/com/android/gallery3d/filtershow/category/SwipableView.java @@ -0,0 +1,21 @@ +/* + * 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.gallery3d.filtershow.category; + +public interface SwipableView { + public void delete(); +} diff --git a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java index c75465ec0..9880c41d9 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java +++ b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java @@ -25,6 +25,7 @@ import android.net.Uri; import android.os.Handler; import android.os.Message; +import com.android.gallery3d.exif.ExifTag; import com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.filters.FilterRepresentation; @@ -39,6 +40,7 @@ import com.android.gallery3d.filtershow.pipeline.SharedBuffer; import com.android.gallery3d.filtershow.pipeline.SharedPreset; import com.android.gallery3d.filtershow.state.StateAdapter; +import java.util.List; import java.util.Vector; public class MasterImage implements RenderingRequestCaller { @@ -91,6 +93,7 @@ public class MasterImage implements RenderingRequestCaller { private Point mImageShowSize = new Point(); private boolean mShowsOriginal; + private List<ExifTag> mEXIF; private MasterImage() { } @@ -170,6 +173,7 @@ public class MasterImage implements RenderingRequestCaller { public boolean loadBitmap(Uri uri, int size) { setUri(uri); + mEXIF = ImageLoader.getExif(getActivity(), uri); mOrientation = ImageLoader.getMetadataOrientation(mActivity, uri); Rect originalBounds = new Rect(); mOriginalBitmapLarge = ImageLoader.loadOrientedConstrainedBitmap(uri, mActivity, @@ -582,4 +586,8 @@ public class MasterImage implements RenderingRequestCaller { return mLoadedPreset; } + public List<ExifTag> getEXIF() { + return mEXIF; + } + } diff --git a/src/com/android/gallery3d/filtershow/info/HistogramView.java b/src/com/android/gallery3d/filtershow/info/HistogramView.java new file mode 100644 index 000000000..6d820ec39 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/info/HistogramView.java @@ -0,0 +1,143 @@ +/* + * 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.gallery3d.filtershow.info; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.os.AsyncTask; +import android.util.AttributeSet; +import android.view.View; +import com.android.gallery3d.filtershow.imageshow.Spline; + +public class HistogramView extends View { + + private Bitmap mBitmap; + int[] redHistogram = new int[256]; + int[] greenHistogram = new int[256]; + int[] blueHistogram = new int[256]; + Path gHistoPath = new Path(); + + class ComputeHistogramTask extends AsyncTask<Bitmap, Void, int[]> { + @Override + protected int[] doInBackground(Bitmap... params) { + int[] histo = new int[256 * 3]; + Bitmap bitmap = params[0]; + int w = bitmap.getWidth(); + int h = bitmap.getHeight(); + int[] pixels = new int[w * h]; + bitmap.getPixels(pixels, 0, w, 0, 0, w, h); + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + int index = j * w + i; + int r = Color.red(pixels[index]); + int g = Color.green(pixels[index]); + int b = Color.blue(pixels[index]); + histo[r]++; + histo[256 + g]++; + histo[512 + b]++; + } + } + return histo; + } + + @Override + protected void onPostExecute(int[] result) { + System.arraycopy(result, 0, redHistogram, 0, 256); + System.arraycopy(result, 256, greenHistogram, 0, 256); + System.arraycopy(result, 512, blueHistogram, 0, 256); + invalidate(); + } + } + + public HistogramView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void setBitmap(Bitmap bitmap) { + mBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); + new ComputeHistogramTask().execute(mBitmap); + } + + private void drawHistogram(Canvas canvas, int[] histogram, int color, PorterDuff.Mode mode) { + int max = 0; + for (int i = 0; i < histogram.length; i++) { + if (histogram[i] > max) { + max = histogram[i]; + } + } + float w = getWidth() - Spline.curveHandleSize(); + float h = getHeight() - Spline.curveHandleSize() / 2.0f; + float dx = Spline.curveHandleSize() / 2.0f; + float wl = w / histogram.length; + float wh = (0.3f * h) / max; + Paint paint = new Paint(); + paint.setARGB(100, 255, 255, 255); + paint.setStrokeWidth((int) Math.ceil(wl)); + + // Draw grid + paint.setStyle(Paint.Style.STROKE); + canvas.drawRect(dx, 0, dx + w, h, paint); + canvas.drawLine(dx + w / 3, 0, dx + w / 3, h, paint); + canvas.drawLine(dx + 2 * w / 3, 0, dx + 2 * w / 3, h, paint); + paint.setStyle(Paint.Style.FILL_AND_STROKE); + + Paint paint2 = new Paint(); + paint2.setColor(color); + paint2.setStrokeWidth(6); + paint2.setXfermode(new PorterDuffXfermode(mode)); + gHistoPath.reset(); + gHistoPath.moveTo(dx, h); + boolean firstPointEncountered = false; + float prev = 0; + float last = 0; + for (int i = 0; i < histogram.length; i++) { + float x = i * wl + dx; + float l = histogram[i] * wh; + if (l != 0) { + float v = h - (l + prev) / 2.0f; + if (!firstPointEncountered) { + gHistoPath.lineTo(x, h); + firstPointEncountered = true; + } + gHistoPath.lineTo(x, v); + prev = l; + last = x; + } + } + gHistoPath.lineTo(last, h); + gHistoPath.lineTo(w, h); + gHistoPath.close(); + canvas.drawPath(gHistoPath, paint2); + paint2.setStrokeWidth(2); + paint2.setStyle(Paint.Style.STROKE); + paint2.setARGB(255, 200, 200, 200); + canvas.drawPath(gHistoPath, paint2); + } + + public void onDraw(Canvas canvas) { + canvas.drawARGB(0, 0, 0, 0); + drawHistogram(canvas, redHistogram, Color.RED, PorterDuff.Mode.SCREEN); + drawHistogram(canvas, greenHistogram, Color.GREEN, PorterDuff.Mode.SCREEN); + drawHistogram(canvas, blueHistogram, Color.BLUE, PorterDuff.Mode.SCREEN); + } +} diff --git a/src/com/android/gallery3d/filtershow/info/InfoPanel.java b/src/com/android/gallery3d/filtershow/info/InfoPanel.java new file mode 100644 index 000000000..a06527f3a --- /dev/null +++ b/src/com/android/gallery3d/filtershow/info/InfoPanel.java @@ -0,0 +1,128 @@ +/* + * 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.gallery3d.filtershow.info; + +import android.graphics.Bitmap; +import android.graphics.Rect; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.text.Html; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import com.android.gallery3d.R; +import com.android.gallery3d.exif.ExifInterface; +import com.android.gallery3d.exif.ExifTag; +import com.android.gallery3d.filtershow.cache.ImageLoader; +import com.android.gallery3d.filtershow.imageshow.MasterImage; + +import java.util.List; + +public class InfoPanel extends Fragment { + public static final String FRAGMENT_TAG = "InfoPanel"; + private static final String LOGTAG = FRAGMENT_TAG; + private LinearLayout mMainView; + private ImageView mImageThumbnail; + private TextView mImageName; + private TextView mImageSize; + private TextView mExifData; + + private String createStringFromIfFound(ExifTag exifTag, int tag, int str) { + String exifString = ""; + short tagId = exifTag.getTagId(); + if (tagId == ExifInterface.getTrueTagKey(tag)) { + String label = getActivity().getString(str); + exifString += "<b>" + label + ": </b>"; + exifString += exifTag.forceGetValueAsString(); + exifString += "<br>"; + } + return exifString; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + mMainView = (LinearLayout) inflater.inflate( + R.layout.filtershow_info_panel, null, false); + + mImageThumbnail = (ImageView) mMainView.findViewById(R.id.imageThumbnail); + Bitmap bitmap = MasterImage.getImage().getFilteredImage(); + mImageThumbnail.setImageBitmap(bitmap); + + mImageName = (TextView) mMainView.findViewById(R.id.imageName); + mImageSize = (TextView) mMainView.findViewById(R.id.imageSize); + mExifData = (TextView) mMainView.findViewById(R.id.exifData); + HistogramView histogramView = (HistogramView) mMainView.findViewById(R.id.histogramView); + + histogramView.setBitmap(bitmap); + + Uri uri = MasterImage.getImage().getUri(); + String path = ImageLoader.getLocalPathFromUri(getActivity(), uri); + Uri localUri = null; + if (path != null) { + localUri = Uri.parse(path); + } + + if (localUri != null) { + mImageName.setText(localUri.getLastPathSegment()); + } + Rect originalBounds = MasterImage.getImage().getOriginalBounds(); + mImageSize.setText("" + originalBounds.width() + " x " + originalBounds.height()); + + List<ExifTag> exif = MasterImage.getImage().getEXIF(); + String exifString = ""; + if (exif != null) { + for (ExifTag tag : exif) { + exifString += createStringFromIfFound(tag, + ExifInterface.TAG_MODEL, + R.string.filtershow_exif_model); + exifString += createStringFromIfFound(tag, + ExifInterface.TAG_APERTURE_VALUE, + R.string.filtershow_exif_aperture); + exifString += createStringFromIfFound(tag, + ExifInterface.TAG_FOCAL_LENGTH, + R.string.filtershow_exif_focal_length); + exifString += createStringFromIfFound(tag, + ExifInterface.TAG_ISO_SPEED_RATINGS, + R.string.filtershow_exif_iso); + exifString += createStringFromIfFound(tag, + ExifInterface.TAG_SUBJECT_DISTANCE, + R.string.filtershow_exif_subject_distance); + exifString += createStringFromIfFound(tag, + ExifInterface.TAG_DATE_TIME_ORIGINAL, + R.string.filtershow_exif_date); + exifString += createStringFromIfFound(tag, + ExifInterface.TAG_F_NUMBER, + R.string.filtershow_exif_f_stop); + exifString += createStringFromIfFound(tag, + ExifInterface.TAG_EXPOSURE_TIME, + R.string.filtershow_exif_exposure_time); + exifString += createStringFromIfFound(tag, + ExifInterface.TAG_COPYRIGHT, + R.string.filtershow_exif_copyright); + } + } + mExifData.setText(Html.fromHtml(exifString)); + return mMainView; + } +} diff --git a/src/com/android/gallery3d/filtershow/state/StatePanel.java b/src/com/android/gallery3d/filtershow/state/StatePanel.java index df470f23e..044c2b4a2 100644 --- a/src/com/android/gallery3d/filtershow/state/StatePanel.java +++ b/src/com/android/gallery3d/filtershow/state/StatePanel.java @@ -22,16 +22,24 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageButton; import android.widget.LinearLayout; import com.android.gallery3d.R; +import com.android.gallery3d.filtershow.category.MainPanel; import com.android.gallery3d.filtershow.imageshow.MasterImage; public class StatePanel extends Fragment { private static final String LOGTAG = "StatePanel"; + private MainPanel mMainPanel; private StatePanelTrack track; private LinearLayout mMainView; + private ImageButton mToggleVersionsPanel; public static final String FRAGMENT_TAG = "StatePanel"; + public void setMainPanel(MainPanel mainPanel) { + mMainPanel = mainPanel; + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -39,6 +47,12 @@ public class StatePanel extends Fragment { View panel = mMainView.findViewById(R.id.listStates); track = (StatePanelTrack) panel; track.setAdapter(MasterImage.getImage().getState()); + mToggleVersionsPanel = (ImageButton) mMainView.findViewById(R.id.toggleVersionsPanel); + if (mMainPanel != null) { + mMainPanel.setToggleVersionsPanelButton(mToggleVersionsPanel); + } else { + mToggleVersionsPanel.setVisibility(View.GONE); + } return mMainView; } } |