summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authornicolasroard <nicolasroard@google.com>2013-08-09 14:09:56 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-08-09 14:09:56 +0000
commit5bf3bf4b44dee73e2ba54680460a2237cd1258ec (patch)
treeccd0ab3f7dbe03ef5bdd9445394147c470b0a920 /src
parent723bf81990245a07739146ac10357703c9839de1 (diff)
parent860af325f2030a03c526e8551a85230d17df7b15 (diff)
downloadandroid_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')
-rw-r--r--src/com/android/gallery3d/filtershow/FilterShowActivity.java138
-rw-r--r--src/com/android/gallery3d/filtershow/cache/ImageLoader.java33
-rw-r--r--src/com/android/gallery3d/filtershow/category/CategoryAdapter.java32
-rw-r--r--src/com/android/gallery3d/filtershow/category/CategoryPanel.java44
-rw-r--r--src/com/android/gallery3d/filtershow/category/CategoryTrack.java10
-rw-r--r--src/com/android/gallery3d/filtershow/category/CategoryView.java31
-rw-r--r--src/com/android/gallery3d/filtershow/category/MainPanel.java48
-rw-r--r--src/com/android/gallery3d/filtershow/category/SwipableView.java21
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/MasterImage.java8
-rw-r--r--src/com/android/gallery3d/filtershow/info/HistogramView.java143
-rw-r--r--src/com/android/gallery3d/filtershow/info/InfoPanel.java128
-rw-r--r--src/com/android/gallery3d/filtershow/state/StatePanel.java14
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;
}
}