DragEvent.java revision c02c7af0ec88ec56089a11138d5fcfafcf891c58
1a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate/*
2a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate * Copyright (C) 2010 The Android Open Source Project
3a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate *
4a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate * Licensed under the Apache License, Version 2.0 (the "License");
5a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate * you may not use this file except in compliance with the License.
6a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate * You may obtain a copy of the License at
7a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate *
8a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate *      http://www.apache.org/licenses/LICENSE-2.0
9a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate *
10a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate * Unless required by applicable law or agreed to in writing, software
11a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate * distributed under the License is distributed on an "AS IS" BASIS,
12a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate * See the License for the specific language governing permissions and
14a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate * limitations under the License.
15a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate */
16a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
17a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tatepackage android.view;
18a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
19a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tateimport android.content.ClipData;
20a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tateimport android.content.ClipDescription;
21a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tateimport android.os.Parcel;
22a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tateimport android.os.Parcelable;
23a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
24a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate/** !!! TODO: real docs */
25a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tatepublic class DragEvent implements Parcelable {
26a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    private static final boolean TRACK_RECYCLED_LOCATION = false;
27a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
28a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    int mAction;
29a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    float mX, mY;
30a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    ClipDescription mClipDescription;
31a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    ClipData mClipData;
32a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
33a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    private DragEvent mNext;
34a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    private RuntimeException mRecycledLocation;
35a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    private boolean mRecycled;
36a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
37a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    private static final int MAX_RECYCLED = 10;
38a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    private static final Object gRecyclerLock = new Object();
39a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    private static int gRecyclerUsed = 0;
40a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    private static DragEvent gRecyclerTop = null;
41a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
42a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    /**
43a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate     * action constants for DragEvent dispatch
44a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate     */
45a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public static final int ACTION_DRAG_STARTED = 1;
46a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public static final int ACTION_DRAG_LOCATION = 2;
47a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public static final int ACTION_DROP = 3;
48a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public static final int ACTION_DRAG_ENDED = 4;
49a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public static final int ACTION_DRAG_ENTERED = 5;
50a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public static final int ACTION_DRAG_EXITED = 6;
51a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
52a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    /* hide the constructor behind package scope */
532c095f367779ef32130c72849936a2e3013c8492Christopher Tate    private DragEvent() {
54a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
55a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
56c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate    private void init(int action, float x, float y, ClipDescription description, ClipData data) {
57c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate        mAction = action;
58c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate        mX = x;
59c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate        mY = y;
60c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate        mClipDescription = description;
61c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate        mClipData = data;
62c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate    }
63c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate
642c095f367779ef32130c72849936a2e3013c8492Christopher Tate    static DragEvent obtain() {
65a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        return DragEvent.obtain(0, 0f, 0f, null, null);
66a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
67a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
68a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public static DragEvent obtain(int action, float x, float y,
69a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            ClipDescription description, ClipData data) {
70a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        final DragEvent ev;
71a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        synchronized (gRecyclerLock) {
72a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            if (gRecyclerTop == null) {
73c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate                ev = new DragEvent();
74c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate                ev.init(action, x, y, description, data);
75c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate                return ev;
76a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
77a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            ev = gRecyclerTop;
78a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            gRecyclerTop = ev.mNext;
79a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            gRecyclerUsed -= 1;
80a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        }
81a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        ev.mRecycledLocation = null;
82a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        ev.mRecycled = false;
83a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        ev.mNext = null;
84a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
85c02c7af0ec88ec56089a11138d5fcfafcf891c58Chris Tate        ev.init(action, x, y, description, data);
86a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
87a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        return ev;
88a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
89a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
902c095f367779ef32130c72849936a2e3013c8492Christopher Tate    public static DragEvent obtain(DragEvent source) {
912c095f367779ef32130c72849936a2e3013c8492Christopher Tate        return obtain(source.mAction, source.mX, source.mY,
922c095f367779ef32130c72849936a2e3013c8492Christopher Tate                source.mClipDescription, source.mClipData);
932c095f367779ef32130c72849936a2e3013c8492Christopher Tate    }
942c095f367779ef32130c72849936a2e3013c8492Christopher Tate
95a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public int getAction() {
96a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        return mAction;
97a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
98a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
99a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public float getX() {
100a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        return mX;
101a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
102a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
103a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public float getY() {
104a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        return mY;
105a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
106a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
107a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public ClipData getClipData() {
108a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        return mClipData;
109a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
110a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
111a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public ClipDescription getClipDescription() {
112a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        return mClipDescription;
113a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
114a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
115a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    /**
116a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate     * Recycle the DragEvent, to be re-used by a later caller.  After calling
117a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate     * this function you must never touch the event again.
118a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate     */
119a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public final void recycle() {
120a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        // Ensure recycle is only called once!
121a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        if (TRACK_RECYCLED_LOCATION) {
122a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            if (mRecycledLocation != null) {
123a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation);
124a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
125a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            mRecycledLocation = new RuntimeException("Last recycled here");
126a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        } else {
127a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            if (mRecycled) {
128a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                throw new RuntimeException(toString() + " recycled twice!");
129a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
130a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            mRecycled = true;
131a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        }
132a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
133a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        mClipData = null;
134a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        mClipDescription = null;
135a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
136a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        synchronized (gRecyclerLock) {
137a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            if (gRecyclerUsed < MAX_RECYCLED) {
138a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                gRecyclerUsed++;
139a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                mNext = gRecyclerTop;
140a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                gRecyclerTop = this;
141a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
142a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        }
143a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
144a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
145a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    @Override
146a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public String toString() {
147a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        return "DragEvent{" + Integer.toHexString(System.identityHashCode(this))
148a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        + " action=" + mAction + " @ (" + mX + ", " + mY + ") desc=" + mClipDescription
149a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        + " data=" + mClipData
150a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        + "}";
151a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
152a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
153a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    /* Parcelable interface */
154a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
155a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public int describeContents() {
156a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        return 0;
157a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
158a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
159a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public void writeToParcel(Parcel dest, int flags) {
160a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        dest.writeInt(mAction);
161a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        dest.writeFloat(mX);
162a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        dest.writeFloat(mY);
163a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        if (mClipData == null) {
164a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            dest.writeInt(0);
165a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        } else {
166a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            dest.writeInt(1);
167a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            mClipData.writeToParcel(dest, flags);
168a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        }
169a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        if (mClipDescription == null) {
170a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            dest.writeInt(0);
171a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        } else {
172a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            dest.writeInt(1);
173a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            mClipDescription.writeToParcel(dest, flags);
174a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        }
175a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    }
176a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
177a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    public static final Parcelable.Creator<DragEvent> CREATOR =
178a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        new Parcelable.Creator<DragEvent>() {
179a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        public DragEvent createFromParcel(Parcel in) {
180a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            DragEvent event = DragEvent.obtain();
181a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            event.mAction = in.readInt();
182a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            event.mX = in.readFloat();
183a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            event.mY = in.readFloat();
184a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            if (in.readInt() != 0) {
185a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                event.mClipData = ClipData.CREATOR.createFromParcel(in);
186a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
187a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            if (in.readInt() != 0) {
188a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate                event.mClipDescription = ClipDescription.CREATOR.createFromParcel(in);
189a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            }
190a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            return event;
191a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        }
192a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate
193a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        public DragEvent[] newArray(int size) {
194a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate            return new DragEvent[size];
195a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate        }
196a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate    };
197a53146c5569f8ff5f7eb55e9ad35d23ddacf2addChristopher Tate}
198