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;
2200259461be82e601b58d3e970afbf0c012c5f3e7nicolasroardimport android.database.DataSetObserver;
2300259461be82e601b58d3e970afbf0c012c5f3e7nicolasroardimport android.graphics.Canvas;
24fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.graphics.Point;
25fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.graphics.Rect;
26fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.util.AttributeSet;
27f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport android.util.Log;
28fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.view.GestureDetector;
29fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.view.MotionEvent;
30fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.view.View;
31f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport android.view.ViewGroup;
32fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.widget.Adapter;
33fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport android.widget.LinearLayout;
34f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport com.android.gallery3d.R;
35fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport com.android.gallery3d.filtershow.FilterShowActivity;
36f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport com.android.gallery3d.filtershow.editors.ImageOnlyEditor;
37fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardimport com.android.gallery3d.filtershow.filters.FilterRepresentation;
38f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroardimport com.android.gallery3d.filtershow.imageshow.MasterImage;
39fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
40fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroardpublic class StatePanelTrack extends LinearLayout implements PanelTrack {
41fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
42fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private static final String LOGTAG = "StatePanelTrack";
43fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private Point mTouchPoint;
44fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private StateView mCurrentView;
45fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private StateView mCurrentSelectedView;
46fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private boolean mExited = false;
47fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private boolean mStartedDrag = false;
48fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private StateAdapter mAdapter;
49fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private DragListener mDragListener = new DragListener(this);
50f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private float mDeleteSlope = 0.2f;
51f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private GestureDetector mGestureDetector;
52f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mElemWidth;
53f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mElemHeight;
54f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mElemSize;
55f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mElemEndSize;
56f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mEndElemWidth;
57f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mEndElemHeight;
58f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private long mTouchTime;
59f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private int mMaxTouchDelay = 300; // 300ms delay for touch
60f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard    private static final boolean ALLOWS_DRAG = false;
6120667d21eac2074b0e265d8839539bd9cfec9f92nicolasroard    private static final boolean ALLOWS_DUPLICATES = false;
6200259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard    private DataSetObserver mObserver = new DataSetObserver() {
6300259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard        @Override
6400259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard        public void onChanged() {
6500259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard            super.onChanged();
6600259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard            fillContent(false);
6700259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard        }
6800259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard
6900259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard        @Override
7000259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard        public void onInvalidated() {
7100259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard            super.onInvalidated();
7200259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard            fillContent(false);
7300259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard        }
7400259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard    };
75fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
76fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public StatePanelTrack(Context context, AttributeSet attrs) {
77fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        super(context, attrs);
78f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.StatePanelTrack);
79f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        mElemSize = a.getDimensionPixelSize(R.styleable.StatePanelTrack_elemSize, 0);
80f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        mElemEndSize = a.getDimensionPixelSize(R.styleable.StatePanelTrack_elemEndSize, 0);
81f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (getOrientation() == LinearLayout.HORIZONTAL) {
82f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mElemWidth = mElemSize;
83f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mElemHeight = LayoutParams.MATCH_PARENT;
84f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mEndElemWidth = mElemEndSize;
85f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mEndElemHeight = LayoutParams.MATCH_PARENT;
86f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        } else {
87f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mElemWidth = LayoutParams.MATCH_PARENT;
88f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mElemHeight = mElemSize;
89f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mEndElemWidth = LayoutParams.MATCH_PARENT;
90f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mEndElemHeight = mElemEndSize;
91f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        }
92fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        GestureDetector.SimpleOnGestureListener simpleOnGestureListener
93fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                = new GestureDetector.SimpleOnGestureListener(){
94fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            @Override
95fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            public void onLongPress(MotionEvent e) {
96fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                longPress(e);
97fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
98fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            @Override
99fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            public boolean onDoubleTap(MotionEvent e) {
100fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                addDuplicate(e);
101fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                return true;
102fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
103fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        };
104fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mGestureDetector = new GestureDetector(context, simpleOnGestureListener);
105fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
106fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
107fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private void addDuplicate(MotionEvent e) {
10820667d21eac2074b0e265d8839539bd9cfec9f92nicolasroard        if (!ALLOWS_DUPLICATES) {
10920667d21eac2074b0e265d8839539bd9cfec9f92nicolasroard            return;
11020667d21eac2074b0e265d8839539bd9cfec9f92nicolasroard        }
111fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mCurrentSelectedView == null) {
112fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return;
113fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
114fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        int pos = findChild(mCurrentSelectedView);
115fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (pos != -1) {
116fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mAdapter.insert(new State(mCurrentSelectedView.getState()), pos);
117fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            fillContent(true);
118fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
119fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
120fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
121fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    private void longPress(MotionEvent e) {
12220667d21eac2074b0e265d8839539bd9cfec9f92nicolasroard        if (!ALLOWS_DUPLICATES) {
12320667d21eac2074b0e265d8839539bd9cfec9f92nicolasroard            return;
12420667d21eac2074b0e265d8839539bd9cfec9f92nicolasroard        }
125fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        View view = findChildAt((int) e.getX(), (int) e.getY());
126fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (view == null) {
127fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return;
128fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
129fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (view instanceof StateView) {
130fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            StateView stateView = (StateView) view;
131fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            stateView.setDuplicateButton(true);
132fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
133fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
134fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
135fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void setAdapter(StateAdapter adapter) {
136fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mAdapter = adapter;
13700259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard        mAdapter.registerDataSetObserver(mObserver);
138fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mAdapter.setOrientation(getOrientation());
139fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        fillContent(false);
140fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        requestLayout();
141fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
142fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
143fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public StateView findChildWithState(State state) {
144fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < getChildCount(); i++) {
145fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            StateView view = (StateView) getChildAt(i);
146fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (view.getState() == state) {
147fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                return view;
148fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
149fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
150fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return null;
151fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
152fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
153fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void fillContent(boolean animate) {
154fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (!animate) {
155fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            this.setLayoutTransition(null);
156fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
157fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        int n = mAdapter.getCount();
158fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < getChildCount(); i++) {
159fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            StateView child = (StateView) getChildAt(i);
160fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            child.resetPosition();
161fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (!mAdapter.contains(child.getState())) {
162fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                removeView(child);
163fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
164fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
165f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        LayoutParams params = new LayoutParams(mElemWidth, mElemHeight);
166fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < n; i++) {
167fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            State s = mAdapter.getItem(i);
168fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (findChildWithState(s) == null) {
169fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                View view = mAdapter.getView(i, null, this);
170fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                addView(view, i, params);
171fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
172fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
173f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard
174fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < n; i++) {
175fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            State state = mAdapter.getItem(i);
176fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            StateView view = (StateView) getChildAt(i);
177fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            view.setState(state);
178fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (i == 0) {
179fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                view.setType(StateView.BEGIN);
180fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            } else if (i == n - 1) {
181fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                view.setType(StateView.END);
182fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            } else {
183f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                view.setType(StateView.DEFAULT);
184fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
185f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            view.resetPosition();
186fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
187fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
188fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (!animate) {
189fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            this.setLayoutTransition(new LayoutTransition());
190fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
191fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
192fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
193fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void onTouch(MotionEvent event, StateView view) {
194fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (!view.isDraggable()) {
195fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return;
196fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
197fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mCurrentView = view;
198fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mCurrentSelectedView == mCurrentView) {
199fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return;
200fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
201fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mCurrentSelectedView != null) {
202fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mCurrentSelectedView.setSelected(false);
203fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
204fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        // We changed the current view -- let's reset the
205fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        // gesture detector.
206fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        MotionEvent cancelEvent = MotionEvent.obtain(event);
207fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
208fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mGestureDetector.onTouchEvent(cancelEvent);
209fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mCurrentSelectedView = mCurrentView;
210fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        // We have to send the event to the gesture detector
211fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mGestureDetector.onTouchEvent(event);
212f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        mTouchTime = System.currentTimeMillis();
213fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
214fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
215fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    @Override
216fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public boolean onInterceptTouchEvent(MotionEvent event) {
217fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mCurrentView != null) {
218fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return true;
219fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
220fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return false;
221fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
222fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
223fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    @Override
224fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public boolean onTouchEvent(MotionEvent event) {
225fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mCurrentView == null) {
226fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            return false;
227fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
228f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (mTouchTime == 0) {
229f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mTouchTime = System.currentTimeMillis();
230f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        }
231fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mGestureDetector.onTouchEvent(event);
232fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (mTouchPoint == null) {
233fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mTouchPoint = new Point();
234fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mTouchPoint.x = (int) event.getX();
235fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mTouchPoint.y = (int) event.getY();
236fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
237f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard
238fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {
239fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            float translation = event.getY() - mTouchPoint.y;
240fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            float alpha = 1.0f - (Math.abs(translation) / mCurrentView.getHeight());
241fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (getOrientation() == LinearLayout.VERTICAL) {
242fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                translation = event.getX() - mTouchPoint.x;
243fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                alpha = 1.0f - (Math.abs(translation) / mCurrentView.getWidth());
244fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                mCurrentView.setTranslationX(translation);
245fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            } else {
246fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                mCurrentView.setTranslationY(translation);
247fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
248fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mCurrentView.setBackgroundAlpha(alpha);
249f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            if (ALLOWS_DRAG && alpha < 0.7) {
250fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                setOnDragListener(mDragListener);
251fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                DragShadowBuilder shadowBuilder = new DragShadowBuilder(mCurrentView);
252fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                mCurrentView.startDrag(null, shadowBuilder, mCurrentView, 0);
253fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                mStartedDrag = true;
254fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
255fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
256f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (!mExited && mCurrentView != null
257f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                && mCurrentView.getBackgroundAlpha() > mDeleteSlope
258f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                && event.getActionMasked() == MotionEvent.ACTION_UP
259f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                && System.currentTimeMillis() - mTouchTime < mMaxTouchDelay) {
260f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            FilterRepresentation representation = mCurrentView.getState().getFilterRepresentation();
26100259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard            mCurrentView.setSelected(true);
262f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            if (representation != MasterImage.getImage().getCurrentFilterRepresentation()) {
263f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                FilterShowActivity activity = (FilterShowActivity) getContext();
264f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                activity.showRepresentation(representation);
26500259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard                mCurrentView.setSelected(false);
266f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            }
267f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        }
268fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        if (event.getActionMasked() == MotionEvent.ACTION_UP
269fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                || (!mStartedDrag && event.getActionMasked() == MotionEvent.ACTION_CANCEL)) {
270fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            checkEndState();
27100259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard            if (mCurrentView != null) {
27200259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard                FilterRepresentation representation = mCurrentView.getState().getFilterRepresentation();
27300259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard                if (representation.getEditorId() == ImageOnlyEditor.ID) {
27400259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard                    mCurrentView.setSelected(false);
27500259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard                }
27600259461be82e601b58d3e970afbf0c012c5f3e7nicolasroard            }
277fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
278fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return true;
279fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
280fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
281fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void checkEndState() {
282fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mTouchPoint = null;
283f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        mTouchTime = 0;
284f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (mExited || mCurrentView.getBackgroundAlpha() < mDeleteSlope) {
285fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            int origin = findChild(mCurrentView);
286fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (origin != -1) {
287fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                State current = mAdapter.getItem(origin);
288f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                FilterRepresentation currentRep = MasterImage.getImage().getCurrentFilterRepresentation();
289f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                FilterRepresentation removedRep = current.getFilterRepresentation();
290fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                mAdapter.remove(current);
291fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                fillContent(true);
292f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                if (currentRep != null && removedRep != null
293f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                        && currentRep.getFilterClass() == removedRep.getFilterClass()) {
294f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                    FilterShowActivity activity = (FilterShowActivity) getContext();
295f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                    activity.backToMain();
296f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                    return;
297f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard                }
298fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
299fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        } else {
300fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mCurrentView.setBackgroundAlpha(1.0f);
301fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mCurrentView.setTranslationX(0);
302fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            mCurrentView.setTranslationY(0);
303fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
304f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (mCurrentSelectedView != null) {
305f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mCurrentSelectedView.invalidate();
306f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        }
307f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        if (mCurrentView != null) {
308f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard            mCurrentView.invalidate();
309f5eedf1635eba7edfa7d41fd4e991cced978c4b2nicolasroard        }
310fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mCurrentView = null;
311fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mExited = false;
312fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mStartedDrag = false;
313fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
314fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
315fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public View findChildAt(int x, int y) {
316fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        Rect frame = new Rect();
317fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        int scrolledXInt = getScrollX() + x;
318fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        int scrolledYInt = getScrollY() + y;
319fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < getChildCount(); i++) {
320fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            View child = getChildAt(i);
321fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            child.getHitRect(frame);
322fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (frame.contains(scrolledXInt, scrolledYInt)) {
323fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                return child;
324fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
325fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
326fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return null;
327fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
328fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
329fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public int findChild(View view) {
330fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        for (int i = 0; i < getChildCount(); i++) {
331fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            View child = getChildAt(i);
332fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            if (child == view) {
333fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard                return i;
334fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard            }
335fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        }
336fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return -1;
337fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
338fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
339fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public StateView getCurrentView() {
340fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return mCurrentView;
341fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
342fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
343fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void setCurrentView(View currentView) {
344fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mCurrentView = (StateView) currentView;
345fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
346fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
347fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public void setExited(boolean value) {
348fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        mExited = value;
349fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
350fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
351fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public Point getTouchPoint() {
352fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return mTouchPoint;
353fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
354fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard
355fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    public Adapter getAdapter() {
356fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard        return mAdapter;
357fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard    }
358fb6a8e166f0a46d2a994a408b1679e3a67fdcb52nicolasroard}
359