summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authornicolasroard <nicolasroard@google.com>2013-04-15 14:41:00 -0700
committernicolasroard <nicolasroard@google.com>2013-04-15 23:13:37 -0700
commit191da1ab42e2a70989ad5527513a4d51af577d79 (patch)
treea0a2ea45525f022f0f318099803b62e8d16d4c73 /src
parent6e8057ea04160a4aeb83dfe3b4f1d4d9520f5c8b (diff)
downloadandroid_packages_apps_Snap-191da1ab42e2a70989ad5527513a4d51af577d79.tar.gz
android_packages_apps_Snap-191da1ab42e2a70989ad5527513a4d51af577d79.tar.bz2
android_packages_apps_Snap-191da1ab42e2a70989ad5527513a4d51af577d79.zip
New state panel
bug:8620913 bug:8503386 Change-Id: I35c95103e3b5097df93fa3f48e5562a479915f06
Diffstat (limited to 'src')
-rw-r--r--src/com/android/gallery3d/filtershow/FilterShowActivity.java53
-rw-r--r--src/com/android/gallery3d/filtershow/PanelController.java3
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/MasterImage.java8
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePreset.java8
-rw-r--r--src/com/android/gallery3d/filtershow/state/DragListener.java110
-rw-r--r--src/com/android/gallery3d/filtershow/state/PanelTrack.java37
-rw-r--r--src/com/android/gallery3d/filtershow/state/State.java66
-rw-r--r--src/com/android/gallery3d/filtershow/state/StateAdapter.java99
-rw-r--r--src/com/android/gallery3d/filtershow/state/StatePanel.java44
-rw-r--r--src/com/android/gallery3d/filtershow/state/StatePanelTrack.java297
-rw-r--r--src/com/android/gallery3d/filtershow/state/StateView.java263
11 files changed, 946 insertions, 42 deletions
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
index 1a7d200f1..e445a5d8d 100644
--- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java
+++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
@@ -17,7 +17,6 @@
package com.android.gallery3d.filtershow;
import android.app.ActionBar;
-import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.app.WallpaperManager;
@@ -35,6 +34,8 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
@@ -75,6 +76,8 @@ import com.android.gallery3d.filtershow.imageshow.ImageTinyPlanet;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
import com.android.gallery3d.filtershow.presets.ImagePreset;
import com.android.gallery3d.filtershow.provider.SharedImageProvider;
+import com.android.gallery3d.filtershow.state.StateAdapter;
+import com.android.gallery3d.filtershow.state.StatePanel;
import com.android.gallery3d.filtershow.tools.BitmapTask;
import com.android.gallery3d.filtershow.tools.SaveCopyTask;
import com.android.gallery3d.filtershow.ui.FilterIconButton;
@@ -88,9 +91,11 @@ import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Vector;
-public class FilterShowActivity extends Activity implements OnItemClickListener,
+public class FilterShowActivity extends FragmentActivity implements OnItemClickListener,
OnShareTargetSelectedListener {
+ private String mPanelFragmentTag = "StatePanel";
+
// fields for supporting crop action
public static final String CROP_ACTION = "com.android.camera.action.CROP";
private CropExtras mCropExtras = null;
@@ -157,10 +162,8 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
} else {
findViewById(R.id.historyPanel).setVisibility(View.GONE);
}
- if (mShowingImageStatePanel) {
- findViewById(R.id.imageStatePanel).setVisibility(View.VISIBLE);
- } else {
- findViewById(R.id.imageStatePanel).setVisibility(View.GONE);
+ if (mShowingImageStatePanel && (savedInstanceState == null)) {
+ loadImageStatePanel();
}
setDefaultPreset();
@@ -174,7 +177,6 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
((ViewStub) findViewById(R.id.stateCategoryStub)).inflate();
((ViewStub) findViewById(R.id.editorPanelStub)).inflate();
((ViewStub) findViewById(R.id.historyPanelStub)).inflate();
- ((ViewStub) findViewById(R.id.statePanelStub)).inflate();
ActionBar actionBar = getActionBar();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
@@ -242,8 +244,6 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
}
public void setupStatePanel() {
- ListView imageStateList = (ListView) findViewById(R.id.imageStateList);
- imageStateList.setAdapter(mMasterImage.getState());
mImageLoader.setAdapter(mMasterImage.getHistory());
mPanelController.setRowPanel(findViewById(R.id.secondRowPanel));
mPanelController.setUtilityPanel(this, findViewById(R.id.filterButtonsList));
@@ -849,21 +849,16 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
}
private void toggleImageStatePanel() {
- final View viewList = findViewById(R.id.imageStatePanel);
+ invalidateOptionsMenu();
+ }
- if (mShowingHistoryPanel) {
- findViewById(R.id.historyPanel).setVisibility(View.GONE);
- mShowingHistoryPanel = false;
+ private void loadImageStatePanel() {
+ StatePanel statePanel = new StatePanel();
+ if (findViewById(R.id.state_panel_container) != null) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ transaction.replace(R.id.state_panel_container, statePanel, mPanelFragmentTag);
+ transaction.commit();
}
-
- if (!mShowingImageStatePanel) {
- mShowingImageStatePanel = true;
- viewList.setVisibility(View.VISIBLE);
- } else {
- mShowingImageStatePanel = false;
- viewList.setVisibility(View.GONE);
- }
- invalidateOptionsMenu();
}
@Override
@@ -878,6 +873,9 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
} else if (mShowingImageStatePanel) {
toggleImageStatePanel();
}
+ if (mShowingImageStatePanel) {
+ loadImageStatePanel();
+ }
if (mShowingHistoryPanel) {
toggleHistoryPanel();
}
@@ -897,9 +895,8 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
HistoryAdapter mHistoryAdapter = new HistoryAdapter(
this, R.layout.filtershow_history_operation_row,
R.id.rowTextView);
- ImageStateAdapter mImageStateAdapter = new ImageStateAdapter(this,
- R.layout.filtershow_imagestate_row);
+ StateAdapter mImageStateAdapter = new StateAdapter(this, 0);
MasterImage.reset();
mMasterImage = MasterImage.getImage();
mMasterImage.setHistoryAdapter(mHistoryAdapter);
@@ -921,10 +918,6 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
final View view = findViewById(R.id.mainPanel);
final View viewList = findViewById(R.id.historyPanel);
- if (mShowingImageStatePanel) {
- findViewById(R.id.imageStatePanel).setVisibility(View.GONE);
- }
-
int translate = translateMainPanel(viewList);
if (!mShowingHistoryPanel) {
mShowingHistoryPanel = true;
@@ -968,10 +961,6 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
} else {
viewList.setVisibility(View.GONE);
findViewById(R.id.filtersPanel).setVisibility(View.VISIBLE);
- // In landscape, bring back the state panel if it was there
- if (mShowingImageStatePanel) {
- findViewById(R.id.imageStatePanel).setVisibility(View.VISIBLE);
- }
}
}
invalidateOptionsMenu();
diff --git a/src/com/android/gallery3d/filtershow/PanelController.java b/src/com/android/gallery3d/filtershow/PanelController.java
index 1d0118f85..e9a913610 100644
--- a/src/com/android/gallery3d/filtershow/PanelController.java
+++ b/src/com/android/gallery3d/filtershow/PanelController.java
@@ -544,6 +544,9 @@ public class PanelController implements OnClickListener {
if (filterRepresentation == null) {
return;
}
+ if (filterRepresentation == MasterImage.getImage().getCurrentFilterRepresentation()) {
+ return;
+ }
Set<View> views = mViews.keySet();
for (View view : views) {
if (view instanceof FilterIconButton) {
diff --git a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
index 94573bc61..c36befc2c 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
@@ -22,11 +22,11 @@ import android.os.Message;
import com.android.gallery3d.filtershow.FilterShowActivity;
import com.android.gallery3d.filtershow.HistoryAdapter;
-import com.android.gallery3d.filtershow.ImageStateAdapter;
import com.android.gallery3d.filtershow.cache.*;
import com.android.gallery3d.filtershow.filters.FilterRepresentation;
import com.android.gallery3d.filtershow.filters.ImageFilter;
import com.android.gallery3d.filtershow.presets.ImagePreset;
+import com.android.gallery3d.filtershow.state.StateAdapter;
import java.util.Vector;
@@ -55,7 +55,7 @@ public class MasterImage implements RenderingRequestCaller {
private ImageLoader mLoader = null;
private HistoryAdapter mHistory = null;
- private ImageStateAdapter mState = null;
+ private StateAdapter mState = null;
private FilterShowActivity mActivity = null;
@@ -192,7 +192,7 @@ public class MasterImage implements RenderingRequestCaller {
return mHistory;
}
- public ImageStateAdapter getState() {
+ public StateAdapter getState() {
return mState;
}
@@ -200,7 +200,7 @@ public class MasterImage implements RenderingRequestCaller {
mHistory = adapter;
}
- public void setStateAdapter(ImageStateAdapter adapter) {
+ public void setStateAdapter(StateAdapter adapter) {
mState = adapter;
}
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
index 00f5977d1..bd2f494cd 100644
--- a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
@@ -21,15 +21,14 @@ import android.graphics.Rect;
import android.support.v8.renderscript.Allocation;
import android.util.Log;
-import com.android.gallery3d.filtershow.ImageStateAdapter;
import com.android.gallery3d.filtershow.cache.CachingPipeline;
import com.android.gallery3d.filtershow.cache.ImageLoader;
import com.android.gallery3d.filtershow.filters.BaseFiltersManager;
import com.android.gallery3d.filtershow.filters.FilterRepresentation;
-import com.android.gallery3d.filtershow.filters.FiltersManager;
import com.android.gallery3d.filtershow.filters.ImageFilter;
import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
+import com.android.gallery3d.filtershow.state.StateAdapter;
import java.util.Vector;
@@ -533,14 +532,11 @@ public class ImagePreset {
return true;
}
- public void fillImageStateAdapter(ImageStateAdapter imageStateAdapter) {
+ public void fillImageStateAdapter(StateAdapter imageStateAdapter) {
if (imageStateAdapter == null) {
return;
}
- imageStateAdapter.clear();
- // TODO: re-enable the state panel
imageStateAdapter.addAll(mFilters);
- imageStateAdapter.notifyDataSetChanged();
}
public void setPartialRendering(boolean partialRendering, Rect bounds) {
diff --git a/src/com/android/gallery3d/filtershow/state/DragListener.java b/src/com/android/gallery3d/filtershow/state/DragListener.java
new file mode 100644
index 000000000..1aa81ed69
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/state/DragListener.java
@@ -0,0 +1,110 @@
+/*
+ * 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.state;
+
+import android.view.DragEvent;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+
+class DragListener implements View.OnDragListener {
+
+ private static final String LOGTAG = "DragListener";
+ private PanelTrack mStatePanelTrack;
+ private static float sSlope = 0.2f;
+
+ public DragListener(PanelTrack statePanelTrack) {
+ mStatePanelTrack = statePanelTrack;
+ }
+
+ private void setState(DragEvent event) {
+ float translation = event.getY() - mStatePanelTrack.getTouchPoint().y;
+ float alpha = 1.0f - (Math.abs(translation)
+ / mStatePanelTrack.getCurrentView().getHeight());
+ if (mStatePanelTrack.getOrientation() == LinearLayout.VERTICAL) {
+ translation = event.getX() - mStatePanelTrack.getTouchPoint().x;
+ alpha = 1.0f - (Math.abs(translation)
+ / mStatePanelTrack.getCurrentView().getWidth());
+ mStatePanelTrack.getCurrentView().setTranslationX(translation);
+ } else {
+ mStatePanelTrack.getCurrentView().setTranslationY(translation);
+ }
+ mStatePanelTrack.getCurrentView().setBackgroundAlpha(alpha);
+ }
+
+ @Override
+ public boolean onDrag(View v, DragEvent event) {
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_STARTED: {
+ break;
+ }
+ case DragEvent.ACTION_DRAG_LOCATION: {
+ if (mStatePanelTrack.getCurrentView() != null) {
+ setState(event);
+ View over = mStatePanelTrack.findChildAt((int) event.getX(),
+ (int) event.getY());
+ if (over != null && over != mStatePanelTrack.getCurrentView()) {
+ StateView stateView = (StateView) over;
+ if (stateView != mStatePanelTrack.getCurrentView()) {
+ int pos = mStatePanelTrack.findChild(over);
+ int origin = mStatePanelTrack.findChild(
+ mStatePanelTrack.getCurrentView());
+ ArrayAdapter array = (ArrayAdapter) mStatePanelTrack.getAdapter();
+ if (origin != -1 && pos != -1) {
+ State current = (State) array.getItem(origin);
+ array.remove(current);
+ array.insert(current, pos);
+ mStatePanelTrack.fillContent(false);
+ mStatePanelTrack.setCurrentView(mStatePanelTrack.getChildAt(pos));
+ }
+ }
+ }
+ }
+ break;
+ }
+ case DragEvent.ACTION_DRAG_ENTERED: {
+ mStatePanelTrack.setExited(false);
+ if (mStatePanelTrack.getCurrentView() != null) {
+ mStatePanelTrack.getCurrentView().setVisibility(View.VISIBLE);
+ }
+ return true;
+ }
+ case DragEvent.ACTION_DRAG_EXITED: {
+ if (mStatePanelTrack.getCurrentView() != null) {
+ setState(event);
+ mStatePanelTrack.getCurrentView().setVisibility(View.INVISIBLE);
+ }
+ mStatePanelTrack.setExited(true);
+ break;
+ }
+ case DragEvent.ACTION_DROP: {
+ break;
+ }
+ case DragEvent.ACTION_DRAG_ENDED: {
+ if (mStatePanelTrack.getCurrentView() != null
+ && mStatePanelTrack.getCurrentView().getAlpha() > sSlope) {
+ setState(event);
+ }
+ mStatePanelTrack.checkEndState();
+ break;
+ }
+ default:
+ break;
+ }
+ return true;
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/state/PanelTrack.java b/src/com/android/gallery3d/filtershow/state/PanelTrack.java
new file mode 100644
index 000000000..d02207d9b
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/state/PanelTrack.java
@@ -0,0 +1,37 @@
+/*
+ * 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.state;
+
+import android.graphics.Point;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.Adapter;
+
+public interface PanelTrack {
+ public int getOrientation();
+ public void onTouch(MotionEvent event, StateView view);
+ public StateView getCurrentView();
+ public void setCurrentView(View view);
+ public Point getTouchPoint();
+ public View findChildAt(int x, int y);
+ public int findChild(View view);
+ public Adapter getAdapter();
+ public void fillContent(boolean value);
+ public View getChildAt(int pos);
+ public void setExited(boolean value);
+ public void checkEndState();
+}
diff --git a/src/com/android/gallery3d/filtershow/state/State.java b/src/com/android/gallery3d/filtershow/state/State.java
new file mode 100644
index 000000000..a853371e7
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/state/State.java
@@ -0,0 +1,66 @@
+/*
+ * 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.state;
+
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+
+public class State {
+ private String mText;
+ private int mType;
+ private FilterRepresentation mFilterRepresentation;
+
+ public State(State state) {
+ this(state.getText(), state.getType());
+ }
+
+ public State(String text) {
+ this(text, StateView.DEFAULT);
+ }
+
+ State(String text, int type) {
+ mText = text;
+ mType = type;
+ }
+
+ public boolean isDraggable() {
+ return mFilterRepresentation != null;
+ }
+
+ String getText() {
+ return mText;
+ }
+
+ void setText(String text) {
+ mText = text;
+ }
+
+ int getType() {
+ return mType;
+ }
+
+ void setType(int type) {
+ mType = type;
+ }
+
+ public FilterRepresentation getFilterRepresentation() {
+ return mFilterRepresentation;
+ }
+
+ public void setFilterRepresentation(FilterRepresentation filterRepresentation) {
+ mFilterRepresentation = filterRepresentation;
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/state/StateAdapter.java b/src/com/android/gallery3d/filtershow/state/StateAdapter.java
new file mode 100644
index 000000000..ae81e0b38
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/state/StateAdapter.java
@@ -0,0 +1,99 @@
+/*
+ * 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.state;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.FilterShowActivity;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+
+import java.util.Vector;
+
+public class StateAdapter extends ArrayAdapter<State> {
+
+ private int mOrientation;
+ private PanelTrack mListener;
+ private String mOriginalText;
+ private String mResultText;
+
+ public StateAdapter(Context context, int textViewResourceId) {
+ super(context, textViewResourceId);
+ mOriginalText = context.getString(R.string.state_panel_original);
+ mResultText = context.getString(R.string.state_panel_result);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ StateView view = null;
+ if (convertView == null) {
+ convertView = new StateView(getContext());
+ }
+ view = (StateView) convertView;
+ State state = getItem(position);
+ view.setState(state);
+ view.setOrientation(mOrientation);
+ view.setBackgroundAlpha(1.0f);
+ return view;
+ }
+
+ public boolean contains(State state) {
+ for (int i = 0; i < getCount(); i++) {
+ if (state == getItem(i)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setOrientation(int orientation) {
+ mOrientation = orientation;
+ }
+
+ @Override
+ public void notifyDataSetChanged() {
+ if (mListener != null) {
+ mListener.fillContent(false);
+ }
+ }
+
+ public void addAll(Vector<FilterRepresentation> filters) {
+ clear();
+ add(new State(mOriginalText));
+ for (FilterRepresentation filter : filters) {
+ State state = new State(filter.getName());
+ state.setFilterRepresentation(filter);
+ add(state);
+ }
+ add(new State(mResultText));
+ notifyDataSetChanged();
+ }
+
+ void setListener(PanelTrack listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public void remove(State state) {
+ super.remove(state);
+ FilterRepresentation filterRepresentation = state.getFilterRepresentation();
+ FilterShowActivity activity = (FilterShowActivity) getContext();
+ activity.getPanelController().removeFilterRepresentation(filterRepresentation);
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/state/StatePanel.java b/src/com/android/gallery3d/filtershow/state/StatePanel.java
new file mode 100644
index 000000000..fd33b051d
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/state/StatePanel.java
@@ -0,0 +1,44 @@
+/*
+ * 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.state;
+
+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.LinearLayout;
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.imageshow.MasterImage;
+
+public class StatePanel extends Fragment {
+ private static final String LOGTAG = "StatePanel";
+ StatePanelTrack track;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ LinearLayout main = (LinearLayout) inflater.inflate(
+ R.layout.filtershow_state_panel_new, container,
+ false);
+
+ View panel = main.findViewById(R.id.listStates);
+ track = (StatePanelTrack) panel;
+ track.setAdapter(MasterImage.getImage().getState());
+ return main;
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/state/StatePanelTrack.java b/src/com/android/gallery3d/filtershow/state/StatePanelTrack.java
new file mode 100644
index 000000000..1f6c27210
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/state/StatePanelTrack.java
@@ -0,0 +1,297 @@
+/*
+ * 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.state;
+
+import android.animation.LayoutTransition;
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.Adapter;
+import android.widget.LinearLayout;
+import com.android.gallery3d.filtershow.FilterShowActivity;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+
+public class StatePanelTrack extends LinearLayout implements PanelTrack {
+
+ private static final String LOGTAG = "StatePanelTrack";
+ private Point mTouchPoint;
+ private StateView mCurrentView;
+ private StateView mCurrentSelectedView;
+ private boolean mExited = false;
+ private boolean mStartedDrag = false;
+ private StateAdapter mAdapter;
+ private DragListener mDragListener = new DragListener(this);
+ GestureDetector mGestureDetector;
+ private int mContainerWidth = 668; // TODO: get this from XML
+ private int mContainerHeight = 200;
+
+ public StatePanelTrack(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ GestureDetector.SimpleOnGestureListener simpleOnGestureListener
+ = new GestureDetector.SimpleOnGestureListener(){
+ @Override
+ public void onLongPress(MotionEvent e) {
+ longPress(e);
+ }
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ addDuplicate(e);
+ return true;
+ }
+ };
+ mGestureDetector = new GestureDetector(context, simpleOnGestureListener);
+ }
+
+ private void addDuplicate(MotionEvent e) {
+ if (mCurrentSelectedView == null) {
+ return;
+ }
+ int pos = findChild(mCurrentSelectedView);
+ if (pos != -1) {
+ mAdapter.insert(new State(mCurrentSelectedView.getState()), pos);
+ fillContent(true);
+ }
+ }
+
+ private void longPress(MotionEvent e) {
+ View view = findChildAt((int) e.getX(), (int) e.getY());
+ if (view == null) {
+ return;
+ }
+ if (view instanceof StateView) {
+ StateView stateView = (StateView) view;
+ stateView.setDuplicateButton(true);
+ }
+ }
+
+ public void setAdapter(StateAdapter adapter) {
+ mAdapter = adapter;
+ mAdapter.setListener(this);
+ mAdapter.setOrientation(getOrientation());
+ fillContent(false);
+ requestLayout();
+ }
+
+ public StateView findChildWithState(State state) {
+ for (int i = 0; i < getChildCount(); i++) {
+ StateView view = (StateView) getChildAt(i);
+ if (view.getState() == state) {
+ return view;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
+ int w = MeasureSpec.getSize(widthMeasureSpec);
+ if (w > 0) {
+ mContainerWidth = w;
+ }
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ fillContent(false);
+ }
+
+ public void fillContent(boolean animate) {
+ if (!animate) {
+ this.setLayoutTransition(null);
+ }
+ int n = mAdapter.getCount();
+ int w = mContainerWidth;
+ int h = mContainerHeight;
+ for (int i = 0; i < getChildCount(); i++) {
+ StateView child = (StateView) getChildAt(i);
+ child.resetPosition();
+ if (!mAdapter.contains(child.getState())) {
+ removeView(child);
+ }
+ }
+ LayoutParams params;
+ params = new LayoutParams(w, h);
+ LayoutParams paramsEnds;
+ paramsEnds = new LayoutParams(w, h/2);
+ for (int i = 0; i < n; i++) {
+ State s = mAdapter.getItem(i);
+ if (findChildWithState(s) == null) {
+ View view = mAdapter.getView(i, null, this);
+ addView(view, i, params);
+ }
+ }
+ for (int i = 0; i < n; i++) {
+ State state = mAdapter.getItem(i);
+ StateView view = (StateView) getChildAt(i);
+ view.setState(state);
+ if (i == 0) {
+ view.setType(StateView.BEGIN);
+ } else if (i == n - 1) {
+ view.setType(StateView.END);
+ }
+ view.resetPosition();
+ if (i == 0 || (i == n -1)) {
+ if (view.getWidth() != w || view.getHeight() != h/2) {
+ view.setLayoutParams(paramsEnds);
+ requestLayout();
+ }
+ } else {
+ if (view.getWidth() != w || view.getHeight() != h) {
+ view.setLayoutParams(params);
+ requestLayout();
+ }
+ }
+ }
+
+ if (!animate) {
+ this.setLayoutTransition(new LayoutTransition());
+ }
+ }
+
+ public void onTouch(MotionEvent event, StateView view) {
+ if (!view.isDraggable()) {
+ return;
+ }
+ mCurrentView = view;
+ if (mCurrentSelectedView == mCurrentView) {
+ return;
+ }
+ if (mCurrentSelectedView != null) {
+ mCurrentSelectedView.setSelected(false);
+ }
+ // We changed the current view -- let's reset the
+ // gesture detector.
+ MotionEvent cancelEvent = MotionEvent.obtain(event);
+ cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
+ mGestureDetector.onTouchEvent(cancelEvent);
+ mCurrentSelectedView = mCurrentView;
+ mCurrentSelectedView.setSelected(true);
+ // We have to send the event to the gesture detector
+ mGestureDetector.onTouchEvent(event);
+ FilterShowActivity activity = (FilterShowActivity) getContext();
+ activity.getPanelController().showComponentWithRepresentation(
+ mCurrentSelectedView.getState().getFilterRepresentation());
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ if (mCurrentView != null) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (mCurrentView == null) {
+ return false;
+ }
+ mGestureDetector.onTouchEvent(event);
+ if (mTouchPoint == null) {
+ mTouchPoint = new Point();
+ mTouchPoint.x = (int) event.getX();
+ mTouchPoint.y = (int) event.getY();
+ }
+ if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
+ float translation = event.getY() - mTouchPoint.y;
+ float alpha = 1.0f - (Math.abs(translation) / mCurrentView.getHeight());
+ if (getOrientation() == LinearLayout.VERTICAL) {
+ translation = event.getX() - mTouchPoint.x;
+ alpha = 1.0f - (Math.abs(translation) / mCurrentView.getWidth());
+ mCurrentView.setTranslationX(translation);
+ } else {
+ mCurrentView.setTranslationY(translation);
+ }
+ mCurrentView.setBackgroundAlpha(alpha);
+ if (alpha < 0.7) {
+ setOnDragListener(mDragListener);
+ DragShadowBuilder shadowBuilder = new DragShadowBuilder(mCurrentView);
+ mCurrentView.startDrag(null, shadowBuilder, mCurrentView, 0);
+ mStartedDrag = true;
+ }
+ }
+ if (event.getActionMasked() == MotionEvent.ACTION_UP
+ || (!mStartedDrag && event.getActionMasked() == MotionEvent.ACTION_CANCEL)) {
+ checkEndState();
+ }
+ return true;
+ }
+
+ public void checkEndState() {
+ mTouchPoint = null;
+ if (mExited || mCurrentView.getAlpha() < 0.2) {
+ int origin = findChild(mCurrentView);
+ if (origin != -1) {
+ State current = mAdapter.getItem(origin);
+ mAdapter.remove(current);
+ fillContent(true);
+ }
+ } else {
+ mCurrentView.setBackgroundAlpha(1.0f);
+ mCurrentView.setTranslationX(0);
+ mCurrentView.setTranslationY(0);
+ }
+ mCurrentView = null;
+ mExited = false;
+ mStartedDrag = false;
+ }
+
+ public View findChildAt(int x, int y) {
+ Rect frame = new Rect();
+ int scrolledXInt = getScrollX() + x;
+ int scrolledYInt = getScrollY() + y;
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ child.getHitRect(frame);
+ if (frame.contains(scrolledXInt, scrolledYInt)) {
+ return child;
+ }
+ }
+ return null;
+ }
+
+ public int findChild(View view) {
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (child == view) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public StateView getCurrentView() {
+ return mCurrentView;
+ }
+
+ public void setCurrentView(View currentView) {
+ mCurrentView = (StateView) currentView;
+ }
+
+ public void setExited(boolean value) {
+ mExited = value;
+ }
+
+ public Point getTouchPoint() {
+ return mTouchPoint;
+ }
+
+ public Adapter getAdapter() {
+ return mAdapter;
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/state/StateView.java b/src/com/android/gallery3d/filtershow/state/StateView.java
new file mode 100644
index 000000000..eb19b5229
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/state/StateView.java
@@ -0,0 +1,263 @@
+/*
+ * 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.state;
+
+import android.content.Context;
+import android.graphics.*;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewParent;
+import android.widget.LinearLayout;
+import com.android.gallery3d.filtershow.FilterShowActivity;
+
+public class StateView extends View {
+
+ private Path mPath = new Path();
+ private Paint mPaint = new Paint();
+
+ public static int DEFAULT = 0;
+ public static int BEGIN = 1;
+ public static int END = 2;
+
+ public static int UP = 1;
+ public static int DOWN = 2;
+ public static int LEFT = 3;
+ public static int RIGHT = 4;
+
+ private int mType = DEFAULT;
+ private float mAlpha = 1.0f;
+ private String mText = "Default";
+ private float mTextSize = 32;
+ private static int sMargin = 16;
+ private static int sArrowHeight = 16;
+ private static int sArrowWidth = 8;
+ private int mOrientation = LinearLayout.VERTICAL;
+ private int mDirection = DOWN;
+ private boolean mDuplicateButton;
+ private State mState;
+
+ public StateView(Context context) {
+ this(context, DEFAULT);
+ }
+
+ public StateView(Context context, int type) {
+ super(context);
+ mType = type;
+ }
+
+ public StateView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public String getText() {
+ return mText;
+ }
+
+ public void setText(String text) {
+ mText = text;
+ invalidate();
+ }
+
+ public void setType(int type) {
+ mType = type;
+ invalidate();
+ }
+
+ @Override
+ public void setSelected(boolean value) {
+ super.setSelected(value);
+ if (!value) {
+ mDuplicateButton = false;
+ }
+ invalidate();
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ ViewParent parent = getParent();
+ if (parent instanceof PanelTrack) {
+ ((PanelTrack) getParent()).onTouch(event, this);
+ }
+ }
+ return true;
+ }
+
+ public void drawText(Canvas canvas) {
+ if (mText == null) {
+ return;
+ }
+ mPaint.reset();
+ if (isSelected()) {
+ mPaint.setColor(Color.BLACK);
+ } else {
+ mPaint.setColor(Color.WHITE);
+ }
+ mPaint.setTextSize(mTextSize);
+ float textWidth = mPaint.measureText(mText);
+ int x = (int) ((canvas.getWidth() - textWidth) / 2);
+ int y = canvas.getHeight() - sMargin;
+ if (canvas.getHeight() > canvas.getWidth()) {
+ y = canvas.getHeight() - (canvas.getHeight() - canvas.getWidth() - 2 * sMargin) / 2;
+ }
+ canvas.drawText(mText, x, y, mPaint);
+ }
+
+ public void onDraw(Canvas canvas) {
+ canvas.drawARGB(0, 0, 0, 0);
+ mPath.reset();
+
+ float w = canvas.getWidth();
+ float h = canvas.getHeight();
+ float r = sArrowHeight;
+ float d = sArrowWidth;
+
+ if (mOrientation == LinearLayout.HORIZONTAL) {
+ drawHorizontalPath(w, h, r, d);
+ } else {
+ if (mDirection == DOWN) {
+ drawVerticalDownPath(w, h, r, d);
+ } else {
+ drawVerticalPath(w, h, r, d);
+ }
+ }
+
+ if (mType == DEFAULT) {
+ if (mDuplicateButton) {
+ mPaint.setARGB(255, 200, 0, 0);
+ } else if (isSelected()) {
+ mPaint.setARGB(255, 200, 200, 200);
+ } else {
+ mPaint.setARGB(255, 70, 70, 70);
+ }
+ } else {
+ mPaint.setARGB(255, 150, 150, 150);
+ }
+ canvas.drawPath(mPath, mPaint);
+ drawText(canvas);
+ }
+
+ private void drawHorizontalPath(float w, float h, float r, float d) {
+ mPath.moveTo(0, 0);
+ if (mType == END) {
+ mPath.lineTo(w, 0);
+ mPath.lineTo(w, h);
+ } else {
+ mPath.lineTo(w - d, 0);
+ mPath.lineTo(w - d, r);
+ mPath.lineTo(w, r + d);
+ mPath.lineTo(w - d, r + d + r);
+ mPath.lineTo(w - d, h);
+ }
+ mPath.lineTo(0, h);
+ if (mType != BEGIN) {
+ mPath.lineTo(0, r + d + r);
+ mPath.lineTo(d, r + d);
+ mPath.lineTo(0, r);
+ }
+ mPath.close();
+ }
+
+ private void drawVerticalPath(float w, float h, float r, float d) {
+ if (mType == BEGIN) {
+ mPath.moveTo(0, 0);
+ mPath.lineTo(w, 0);
+ } else {
+ mPath.moveTo(0, d);
+ mPath.lineTo(r, d);
+ mPath.lineTo(r + d, 0);
+ mPath.lineTo(r + d + r, d);
+ mPath.lineTo(w, d);
+ }
+ mPath.lineTo(w, h);
+ if (mType != END) {
+ mPath.lineTo(r + d + r, h);
+ mPath.lineTo(r + d, h - d);
+ mPath.lineTo(r, h);
+ }
+ mPath.lineTo(0, h);
+ mPath.close();
+ }
+
+ private void drawVerticalDownPath(float w, float h, float r, float d) {
+ mPath.moveTo(0, 0);
+ if (mType != BEGIN) {
+ mPath.lineTo(r, 0);
+ mPath.lineTo(r + d, d);
+ mPath.lineTo(r + d + r, 0);
+ }
+ mPath.lineTo(w, 0);
+
+ if (mType != END) {
+ mPath.lineTo(w, h - d);
+
+ mPath.lineTo(r + d + r, h - d);
+ mPath.lineTo(r + d, h);
+ mPath.lineTo(r, h - d);
+
+ mPath.lineTo(0, h - d);
+ } else {
+ mPath.lineTo(w, h);
+ mPath.lineTo(0, h);
+ }
+
+ mPath.close();
+ }
+
+ public void setBackgroundAlpha(float alpha) {
+ if (mType != DEFAULT) {
+ return;
+ }
+ mAlpha = alpha;
+ invalidate();
+ }
+
+ public float getAlpha() {
+ return mAlpha;
+ }
+
+ public void setOrientation(int orientation) {
+ mOrientation = orientation;
+ }
+
+ public void setDuplicateButton(boolean b) {
+ mDuplicateButton = b;
+ invalidate();
+ }
+
+ public State getState() {
+ return mState;
+ }
+
+ public void setState(State state) {
+ mState = state;
+ mText = mState.getText();
+ mType = mState.getType();
+ setBackgroundAlpha(1.0f);
+ invalidate();
+ }
+
+ public void resetPosition() {
+ setTranslationX(0);
+ setTranslationY(0);
+ }
+
+ public boolean isDraggable() {
+ return mState.isDraggable();
+ }
+}