1 11 package org.eclipse.jdt.internal.ui.dnd; 12 13 import org.eclipse.core.runtime.Assert; 14 15 import org.eclipse.swt.dnd.DND; 16 import org.eclipse.swt.dnd.DropTargetEvent; 17 import org.eclipse.swt.dnd.DropTargetListener; 18 import org.eclipse.swt.graphics.Point; 19 import org.eclipse.swt.graphics.Rectangle; 20 import org.eclipse.swt.widgets.Item; 21 import org.eclipse.swt.widgets.TableItem; 22 import org.eclipse.swt.widgets.TreeItem; 23 24 import org.eclipse.jface.viewers.StructuredViewer; 25 26 32 public class JdtViewerDropAdapter implements DropTargetListener { 33 34 39 public static final int LOCATION_NONE= DND.FEEDBACK_NONE; 40 41 46 public static final int LOCATION_ON= DND.FEEDBACK_SELECT; 47 48 53 public static final int LOCATION_BEFORE= DND.FEEDBACK_INSERT_BEFORE; 54 55 60 public static final int LOCATION_AFTER= DND.FEEDBACK_INSERT_AFTER; 61 62 66 private static final int LOCATION_EPSILON= 5; 67 68 69 private static final int ITEM_MARGIN_LEFT= 40; 70 private static final int ITEM_MARGIN_RIGTH= 10; 71 72 75 public static final int INSERTION_FEEDBACK= 1 << 1; 76 77 private StructuredViewer fViewer; 78 private int fFeedback; 79 private boolean fShowInsertionFeedback; 80 private boolean fFullWidthMatchesItem; 81 private int fRequestedOperation; 82 private int fLastOperation; 83 protected int fLocation; 84 protected Object fTarget; 85 86 87 88 public JdtViewerDropAdapter(StructuredViewer viewer, int feedback) { 89 Assert.isNotNull(viewer); 90 fViewer= viewer; 91 fFeedback= feedback; 92 fLastOperation= -1; 93 fFullWidthMatchesItem= true; 94 } 95 96 102 public void showInsertionFeedback(boolean showInsertionFeedback) { 103 fShowInsertionFeedback= showInsertionFeedback; 104 } 105 106 112 protected void setFullWidthMatchesItem(boolean enable) { 113 fFullWidthMatchesItem= enable; 114 } 115 116 119 protected StructuredViewer getViewer() { 120 return fViewer; 121 } 122 123 125 130 public void drop(DropTargetEvent event) { 131 drop(fTarget, event); 132 } 133 134 139 public void drop(Object target, DropTargetEvent event) { 140 } 141 142 148 public void validateDrop(DropTargetEvent event) { 149 validateDrop(fTarget, event, fRequestedOperation); 150 } 151 152 160 public void validateDrop(Object target, DropTargetEvent event, int operation) { 161 } 162 163 public void dragEnter(DropTargetEvent event) { 164 dragOperationChanged(event); 165 } 166 167 public void dragLeave(DropTargetEvent event) { 168 fTarget= null; 169 fLocation= LOCATION_NONE; 170 } 171 172 public void dragOperationChanged(DropTargetEvent event) { 173 fRequestedOperation= event.detail; 174 fTarget= computeTarget(event); 175 fLocation= computeLocation(event); 176 validateDrop(event); 177 fLastOperation= event.detail; 178 computeFeedback(event); 179 } 180 181 public void dragOver(DropTargetEvent event) { 182 Object oldTarget= fTarget; 183 fTarget= computeTarget(event); 184 185 int oldLocation= fLocation; 187 fLocation= computeLocation(event); 188 if (oldLocation != fLocation || oldTarget != fTarget || fLastOperation != event.detail) { 189 validateDrop(event); 190 fLastOperation= event.detail; 191 } else { 192 event.detail= fLastOperation; 193 } 194 computeFeedback(event); 195 } 196 197 public void dropAccept(DropTargetEvent event) { 198 fTarget= computeTarget(event); 199 validateDrop(event); 200 fLastOperation= event.detail; 201 } 202 203 207 protected Object computeTarget(DropTargetEvent event) { 208 if (event.item == null) { 209 return null; 210 } 211 if (!fFullWidthMatchesItem) { 212 Point coordinates= fViewer.getControl().toControl(new Point(event.x, event.y)); 213 Rectangle bounds= getBounds((Item) event.item); 214 if (coordinates.x < bounds.x - ITEM_MARGIN_LEFT || coordinates.x >= bounds.x + bounds.width + ITEM_MARGIN_RIGTH) { 215 event.item= null; return null; 217 } 218 } 219 return event.item.getData(); 220 } 221 222 228 protected int computeLocation(DropTargetEvent event) { 229 if (!(event.item instanceof Item)) 230 return LOCATION_NONE; 231 232 Item item= (Item) event.item; 233 Point coordinates= fViewer.getControl().toControl(new Point(event.x, event.y)); 234 Rectangle bounds= getBounds(item); 235 if (bounds == null) { 236 return LOCATION_NONE; 237 } 238 if ((coordinates.y - bounds.y) < LOCATION_EPSILON) { 239 return LOCATION_BEFORE; 240 } 241 if ((bounds.y + bounds.height - coordinates.y) < LOCATION_EPSILON) { 242 return LOCATION_AFTER; 243 } 244 return LOCATION_ON; 245 } 246 247 251 private Rectangle getBounds(Item item) { 252 if (item instanceof TreeItem) 253 return ((TreeItem) item).getBounds(); 254 255 if (item instanceof TableItem) 256 return ((TableItem) item).getBounds(0); 257 258 return null; 259 } 260 261 265 protected void computeFeedback(DropTargetEvent event) { 266 if (!fShowInsertionFeedback && fLocation != LOCATION_NONE) { 267 event.feedback= DND.FEEDBACK_SELECT; 268 } else { 269 event.feedback= fLocation; 270 } 271 event.feedback|= fFeedback; 272 } 273 274 277 protected void clearDropOperation(DropTargetEvent event) { 278 event.detail= DND.DROP_NONE; 279 } 280 281 284 protected int getRequestedOperation() { 285 return fRequestedOperation; 286 } 287 288 protected void setDefaultFeedback(int feedback) { 289 fFeedback= feedback; 290 } 291 292 294 public void internalTestSetLocation(int location) { 295 fLocation= location; 296 } 297 } 298 | Popular Tags |