StatePanelTrack.java revision f5eedf1635eba7edfa7d41fd4e991cced978c4b2
1fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard/*
2fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard * Copyright (C) 2013 The Android Open Source Project
3fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard *
4fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard * Licensed under the Apache License, Version 2.0 (the "License");
5fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard * you may not use this file except in compliance with the License.
6fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard * You may obtain a copy of the License at
7fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard *
8fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard *      http://www.apache.org/licenses/LICENSE-2.0
9fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard *
10fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard * Unless required by applicable law or agreed to in writing, software
11fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard * distributed under the License is distributed on an "AS IS" BASIS,
12fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard * See the License for the specific language governing permissions and
14fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard * limitations under the License.
15fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard */
16fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
17fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardpackage com.android.gallery3d.filtershow.state;
18fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
19fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.animation.LayoutTransition;
20fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.content.Context;
21f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport android.content.res.TypedArray;
22fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.graphics.Point;
23fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.graphics.Rect;
24fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.util.AttributeSet;
25f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport android.util.Log;
26fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.view.GestureDetector;
27fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.view.MotionEvent;
28fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.view.View;
29f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport android.view.ViewGroup;
30fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.widget.Adapter;
31fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.widget.LinearLayout;
32f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport com.android.gallery3d.R;
33fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport com.android.gallery3d.filtershow.FilterShowActivity;
34f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport com.android.gallery3d.filtershow.editors.ImageOnlyEditor;
35fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport com.android.gallery3d.filtershow.filters.FilterRepresentation;
36f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport com.android.gallery3d.filtershow.imageshow.MasterImage;
37fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
38fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardpublic class StatePanelTrack extends LinearLayout implements PanelTrack {
39fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
40fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private static final String LOGTAG = "StatePanelTrack";
41fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private Point mTouchPoint;
42fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private StateView mCurrentView;
43fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private StateView mCurrentSelectedView;
44fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private boolean mExited = false;
45fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private boolean mStartedDrag = false;
46fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private StateAdapter mAdapter;
47fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private DragListener mDragListener = new DragListener(this);
48f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private float mDeleteSlope = 0.2f;
49f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private GestureDetector mGestureDetector;
50f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mElemWidth;
51f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mElemHeight;
52f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mElemSize;
53f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mElemEndSize;
54f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mEndElemWidth;
55f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mEndElemHeight;
56f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private long mTouchTime;
57f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mMaxTouchDelay = 300; // 300ms delay for touch
58f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private static final boolean ALLOWS_DRAG = false;
59fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
60fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public StatePanelTrack(Context context, AttributeSet attrs) {
61fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        super(context, attrs);
62f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.StatePanelTrack);
63f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        mElemSize = a.getDimensionPixelSize(R.styleable.StatePanelTrack_elemSize, 0);
64f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        mElemEndSize = a.getDimensionPixelSize(R.styleable.StatePanelTrack_elemEndSize, 0);
65f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (getOrientation() == LinearLayout.HORIZONTAL) {
66f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mElemWidth = mElemSize;
67f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mElemHeight = LayoutParams.MATCH_PARENT;
68f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mEndElemWidth = mElemEndSize;
69f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mEndElemHeight = LayoutParams.MATCH_PARENT;
70f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        } else {
71f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mElemWidth = LayoutParams.MATCH_PARENT;
72f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mElemHeight = mElemSize;
73f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mEndElemWidth = LayoutParams.MATCH_PARENT;
74f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mEndElemHeight = mElemEndSize;
75f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        }
76fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        GestureDetector.SimpleOnGestureListener simpleOnGestureListener
77fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                = new GestureDetector.SimpleOnGestureListener(){
78fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            @Override
79fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            public void onLongPress(MotionEvent e) {
80fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                longPress(e);
81fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
82fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            @Override
83fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            public boolean onDoubleTap(MotionEvent e) {
84fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                addDuplicate(e);
85fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                return true;
86fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
87fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        };
88fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mGestureDetector = new GestureDetector(context, simpleOnGestureListener);
89fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
90fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
91fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private void addDuplicate(MotionEvent e) {
92fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mCurrentSelectedView == null) {
93fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return;
94fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
95fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        int pos = findChild(mCurrentSelectedView);
96fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (pos != -1) {
97fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mAdapter.insert(new State(mCurrentSelectedView.getState()), pos);
98fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            fillContent(true);
99fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
100fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
101fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
102fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private void longPress(MotionEvent e) {
103fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        View view = findChildAt((int) e.getX(), (int) e.getY());
104fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (view == null) {
105fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return;
106fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
107fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (view instanceof StateView) {
108fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            StateView stateView = (StateView) view;
109fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            stateView.setDuplicateButton(true);
110fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
111fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
112fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
113fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void setAdapter(StateAdapter adapter) {
114fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mAdapter = adapter;
115fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mAdapter.setListener(this);
116fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mAdapter.setOrientation(getOrientation());
117fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        fillContent(false);
118fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        requestLayout();
119fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
120fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
121fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public StateView findChildWithState(State state) {
122fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < getChildCount(); i++) {
123fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            StateView view = (StateView) getChildAt(i);
124fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (view.getState() == state) {
125fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                return view;
126fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
127fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
128fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return null;
129fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
130fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
131fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void fillContent(boolean animate) {
132fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (!animate) {
133fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            this.setLayoutTransition(null);
134fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
135fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        int n = mAdapter.getCount();
136fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < getChildCount(); i++) {
137fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            StateView child = (StateView) getChildAt(i);
138fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            child.resetPosition();
139fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (!mAdapter.contains(child.getState())) {
140fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                removeView(child);
141fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
142fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
143f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        LayoutParams params = new LayoutParams(mElemWidth, mElemHeight);
144fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < n; i++) {
145fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            State s = mAdapter.getItem(i);
146fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (findChildWithState(s) == null) {
147fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                View view = mAdapter.getView(i, null, this);
148fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                addView(view, i, params);
149fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
150fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
151f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard
152fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < n; i++) {
153fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            State state = mAdapter.getItem(i);
154fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            StateView view = (StateView) getChildAt(i);
155fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            view.setState(state);
156fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (i == 0) {
157fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                view.setType(StateView.BEGIN);
158fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            } else if (i == n - 1) {
159fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                view.setType(StateView.END);
160fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            } else {
161f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                view.setType(StateView.DEFAULT);
162fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
163f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            view.resetPosition();
164fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
165fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
166fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (!animate) {
167fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            this.setLayoutTransition(new LayoutTransition());
168fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
169fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
170fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
171fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void onTouch(MotionEvent event, StateView view) {
172fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (!view.isDraggable()) {
173fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return;
174fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
175fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mCurrentView = view;
176fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mCurrentSelectedView == mCurrentView) {
177fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return;
178fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
179fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mCurrentSelectedView != null) {
180fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mCurrentSelectedView.setSelected(false);
181fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
182fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        // We changed the current view -- let's reset the
183fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        // gesture detector.
184fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        MotionEvent cancelEvent = MotionEvent.obtain(event);
185fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
186fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mGestureDetector.onTouchEvent(cancelEvent);
187fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mCurrentSelectedView = mCurrentView;
188fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        // We have to send the event to the gesture detector
189fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mGestureDetector.onTouchEvent(event);
190f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        mTouchTime = System.currentTimeMillis();
191fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
192fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
193fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    @Override
194fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public boolean onInterceptTouchEvent(MotionEvent event) {
195fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mCurrentView != null) {
196fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return true;
197fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
198fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return false;
199fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
200fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
201fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    @Override
202fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public boolean onTouchEvent(MotionEvent event) {
203fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mCurrentView == null) {
204fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return false;
205fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
206f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (mTouchTime == 0) {
207f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mTouchTime = System.currentTimeMillis();
208f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        }
209fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mGestureDetector.onTouchEvent(event);
210fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mTouchPoint == null) {
211fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mTouchPoint = new Point();
212fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mTouchPoint.x = (int) event.getX();
213fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mTouchPoint.y = (int) event.getY();
214fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
215f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard
216fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
217fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            float translation = event.getY() - mTouchPoint.y;
218fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            float alpha = 1.0f - (Math.abs(translation) / mCurrentView.getHeight());
219fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (getOrientation() == LinearLayout.VERTICAL) {
220fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                translation = event.getX() - mTouchPoint.x;
221fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                alpha = 1.0f - (Math.abs(translation) / mCurrentView.getWidth());
222fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                mCurrentView.setTranslationX(translation);
223fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            } else {
224fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                mCurrentView.setTranslationY(translation);
225fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
226fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mCurrentView.setBackgroundAlpha(alpha);
227f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            if (ALLOWS_DRAG && alpha < 0.7) {
228fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                setOnDragListener(mDragListener);
229fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                DragShadowBuilder shadowBuilder = new DragShadowBuilder(mCurrentView);
230fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                mCurrentView.startDrag(null, shadowBuilder, mCurrentView, 0);
231fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                mStartedDrag = true;
232fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
233fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
234f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (!mExited && mCurrentView != null
235f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                && mCurrentView.getBackgroundAlpha() > mDeleteSlope
236f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                && event.getActionMasked() == MotionEvent.ACTION_UP
237f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                && System.currentTimeMillis() - mTouchTime < mMaxTouchDelay) {
238f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            FilterRepresentation representation = mCurrentView.getState().getFilterRepresentation();
239f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            if (representation != MasterImage.getImage().getCurrentFilterRepresentation()) {
240f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                FilterShowActivity activity = (FilterShowActivity) getContext();
241f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                activity.showRepresentation(representation);
242f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            }
243f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            if (representation.getEditorId() != ImageOnlyEditor.ID) {
244f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                mCurrentView.setSelected(true);
245f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            }
246f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        }
247fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (event.getActionMasked() == MotionEvent.ACTION_UP
248fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                || (!mStartedDrag && event.getActionMasked() == MotionEvent.ACTION_CANCEL)) {
249fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            checkEndState();
250fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
251fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return true;
252fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
253fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
254fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void checkEndState() {
255fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mTouchPoint = null;
256f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        mTouchTime = 0;
257f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (mExited || mCurrentView.getBackgroundAlpha() < mDeleteSlope) {
258fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            int origin = findChild(mCurrentView);
259fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (origin != -1) {
260fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                State current = mAdapter.getItem(origin);
261f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                FilterRepresentation currentRep = MasterImage.getImage().getCurrentFilterRepresentation();
262f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                FilterRepresentation removedRep = current.getFilterRepresentation();
263fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                mAdapter.remove(current);
264fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                fillContent(true);
265f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                if (currentRep != null && removedRep != null
266f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                        && currentRep.getFilterClass() == removedRep.getFilterClass()) {
267f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                    FilterShowActivity activity = (FilterShowActivity) getContext();
268f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                    activity.backToMain();
269f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                    return;
270f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                }
271fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
272fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        } else {
273fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mCurrentView.setBackgroundAlpha(1.0f);
274fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mCurrentView.setTranslationX(0);
275fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mCurrentView.setTranslationY(0);
276fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
277f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (mCurrentSelectedView != null) {
278f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mCurrentSelectedView.invalidate();
279f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        }
280f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (mCurrentView != null) {
281f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mCurrentView.invalidate();
282f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        }
283fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mCurrentView = null;
284fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mExited = false;
285fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mStartedDrag = false;
286fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
287fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
288fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public View findChildAt(int x, int y) {
289fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        Rect frame = new Rect();
290fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        int scrolledXInt = getScrollX() + x;
291fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        int scrolledYInt = getScrollY() + y;
292fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < getChildCount(); i++) {
293fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            View child = getChildAt(i);
294fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            child.getHitRect(frame);
295fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (frame.contains(scrolledXInt, scrolledYInt)) {
296fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                return child;
297fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
298fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
299fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return null;
300fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
301fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
302fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public int findChild(View view) {
303fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < getChildCount(); i++) {
304fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            View child = getChildAt(i);
305fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (child == view) {
306fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                return i;
307fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
308fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
309fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return -1;
310fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
311fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
312fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public StateView getCurrentView() {
313fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return mCurrentView;
314fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
315fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
316fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void setCurrentView(View currentView) {
317fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mCurrentView = (StateView) currentView;
318fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
319fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
320fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void setExited(boolean value) {
321fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mExited = value;
322fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
323fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
324fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public Point getTouchPoint() {
325fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return mTouchPoint;
326fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
327fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
328fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public Adapter getAdapter() {
329fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return mAdapter;
330fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
331fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard}
332