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