Mercurial > projects > dwt-addons
annotate dwtx/jface/viewers/ViewerDropAdapter.d @ 70:46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 22 May 2008 01:36:46 +0200 |
parents | ea8ff534f622 |
children |
rev | line source |
---|---|
10 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwtx.jface.viewers.ViewerDropAdapter; | |
14 | |
15 import dwtx.jface.viewers.Viewer; | |
16 import dwtx.jface.viewers.IStructuredSelection; | |
17 import dwtx.jface.viewers.ISelection; | |
18 | |
19 import dwt.dnd.DND; | |
20 import dwt.dnd.DropTargetAdapter; | |
21 import dwt.dnd.DropTargetEvent; | |
22 import dwt.dnd.TransferData; | |
23 import dwt.graphics.Point; | |
24 import dwt.graphics.Rectangle; | |
25 import dwt.widgets.Item; | |
26 import dwt.widgets.TableItem; | |
27 import dwt.widgets.TreeItem; | |
28 | |
29 import dwt.dwthelper.utils; | |
30 | |
31 /** | |
32 * This adapter class provides generic drag-and-drop support for a viewer. | |
33 * <p> | |
34 * Subclasses must implement the following methods: | |
35 * <ul> | |
36 * <li><code>validateDrop</code> - identifies valid drop targets in viewer</li> | |
37 * <li><code>performDrop</code> - carries out a drop into a viewer</li> | |
38 * </ul> | |
39 * The <code>setFeedbackEnabled</code> method can be called to turn on and off | |
40 * visual insertion feedback (on by default). | |
41 * </p> | |
42 */ | |
43 public abstract class ViewerDropAdapter : DropTargetAdapter { | |
44 | |
45 /** | |
46 * Constant describing the position of the cursor relative | |
47 * to the target object. This means the mouse is positioned | |
48 * slightly before the target. | |
49 * @see #getCurrentLocation() | |
50 */ | |
51 public static const int LOCATION_BEFORE = 1; | |
52 | |
53 /** | |
54 * Constant describing the position of the cursor relative | |
55 * to the target object. This means the mouse is positioned | |
56 * slightly after the target. | |
57 * @see #getCurrentLocation() | |
58 */ | |
59 public static const int LOCATION_AFTER = 2; | |
60 | |
61 /** | |
62 * Constant describing the position of the cursor relative | |
63 * to the target object. This means the mouse is positioned | |
64 * directly on the target. | |
65 * @see #getCurrentLocation() | |
66 */ | |
67 public static const int LOCATION_ON = 3; | |
68 | |
69 /** | |
70 * Constant describing the position of the cursor relative | |
71 * to the target object. This means the mouse is not positioned | |
72 * over or near any valid target. | |
73 * @see #getCurrentLocation() | |
74 */ | |
75 public static const int LOCATION_NONE = 4; | |
76 | |
77 /** | |
78 * The viewer to which this drop support has been added. | |
79 */ | |
80 private Viewer viewer; | |
81 | |
82 /** | |
83 * The current operation. | |
84 */ | |
85 private int currentOperation = DND.DROP_NONE; | |
86 | |
87 /** | |
88 * The last valid operation. | |
89 */ | |
90 private int lastValidOperation = DND.DROP_NONE; | |
91 | |
92 /** | |
93 * The data item currently under the mouse. | |
94 */ | |
95 private Object currentTarget; | |
96 | |
97 /** | |
98 * Information about the position of the mouse relative to the | |
99 * target (before, on, or after the target. Location is one of | |
100 * the <code>LOCATION_* </code> constants defined in this type. | |
101 */ | |
102 private int currentLocation; | |
103 | |
104 /** | |
105 * A flag that allows adapter users to turn the insertion | |
106 * feedback on or off. Default is <code>true</code>. | |
107 */ | |
108 private bool feedbackEnabled = true; | |
109 | |
110 /** | |
111 * A flag that allows adapter users to turn auto scrolling | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
112 * on or off. Default is <code>true</code>. |
10 | 113 */ |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
114 private bool scrollEnabled = true; |
10 | 115 |
116 /** | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
117 * A flag that allows adapter users to turn auto |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
118 * expanding on or off. Default is <code>true</code>. |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
119 */ |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
120 private bool expandEnabled = true; |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
121 |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
122 /** |
10 | 123 * A flag that allows adapter users to turn selection feedback |
124 * on or off. Default is <code>true</code>. | |
125 */ | |
126 private bool selectFeedbackEnabled = true; | |
127 | |
128 /** | |
129 * Creates a new drop adapter for the given viewer. | |
130 * | |
131 * @param viewer the viewer | |
132 */ | |
133 protected this(Viewer viewer) { | |
134 this.viewer = viewer; | |
135 } | |
136 | |
137 /** | |
138 * Returns the position of the given event's coordinates relative to its target. | |
139 * The position is determined to be before, after, or on the item, based on | |
140 * some threshold value. | |
141 * | |
142 * @param event the event | |
143 * @return one of the <code>LOCATION_* </code>constants defined in this class | |
144 */ | |
145 protected int determineLocation(DropTargetEvent event) { | |
146 if (!( cast(Item)event.item )) { | |
147 return LOCATION_NONE; | |
148 } | |
149 Item item = cast(Item) event.item; | |
150 Point coordinates = new Point(event.x, event.y); | |
151 coordinates = viewer.getControl().toControl(coordinates); | |
152 if (item !is null) { | |
153 Rectangle bounds = getBounds(item); | |
154 if (bounds is null) { | |
155 return LOCATION_NONE; | |
156 } | |
157 if ((coordinates.y - bounds.y) < 5) { | |
158 return LOCATION_BEFORE; | |
159 } | |
160 if ((bounds.y + bounds.height - coordinates.y) < 5) { | |
161 return LOCATION_AFTER; | |
162 } | |
163 } | |
164 return LOCATION_ON; | |
165 } | |
166 | |
167 /** | |
168 * Returns the target item of the given drop event. | |
169 * | |
170 * @param event the event | |
171 * @return The target of the drop, may be <code>null</code>. | |
172 */ | |
173 protected Object determineTarget(DropTargetEvent event) { | |
174 return event.item is null ? null : event.item.getData(); | |
175 } | |
176 | |
177 /* (non-Javadoc) | |
178 * Method declared on DropTargetAdapter. | |
179 * The mouse has moved over the drop target. If the | |
180 * target item has changed, notify the action and check | |
181 * that it is still enabled. | |
182 */ | |
183 private void doDropValidation(DropTargetEvent event) { | |
184 //update last valid operation | |
185 if (event.detail !is DND.DROP_NONE) { | |
186 lastValidOperation = event.detail; | |
187 } | |
188 //valid drop and set event detail accordingly | |
189 if (validateDrop(currentTarget, event.detail, event.currentDataType)) { | |
190 currentOperation = lastValidOperation; | |
191 } else { | |
192 currentOperation = DND.DROP_NONE; | |
193 } | |
194 event.detail = currentOperation; | |
195 } | |
196 | |
197 /* (non-Javadoc) | |
198 * Method declared on DropTargetAdapter. | |
199 * The drag has entered this widget's region. See | |
200 * if the drop should be allowed. | |
201 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
10
diff
changeset
|
202 public override void dragEnter(DropTargetEvent event) { |
10 | 203 currentTarget = determineTarget(event); |
204 doDropValidation(event); | |
205 } | |
206 | |
207 /* (non-Javadoc) | |
208 * Method declared on DropTargetAdapter. | |
209 * The drop operation has changed, see if the action | |
210 * should still be enabled. | |
211 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
10
diff
changeset
|
212 public override void dragOperationChanged(DropTargetEvent event) { |
10 | 213 currentTarget = determineTarget(event); |
214 doDropValidation(event); | |
215 } | |
216 | |
217 /* (non-Javadoc) | |
218 * Method declared on DropTargetAdapter. | |
219 * The mouse has moved over the drop target. If the | |
220 * target item has changed, notify the action and check | |
221 * that it is still enabled. | |
222 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
10
diff
changeset
|
223 public override void dragOver(DropTargetEvent event) { |
10 | 224 //use newly revealed item as target if scrolling occurs |
225 Object target = determineTarget(event); | |
226 | |
227 //set the location feedback | |
228 int oldLocation = currentLocation; | |
229 currentLocation = determineLocation(event); | |
230 setFeedback(event, currentLocation); | |
231 | |
232 //see if anything has really changed before doing validation. | |
233 if (target !is currentTarget || currentLocation !is oldLocation) { | |
234 currentTarget = target; | |
235 doDropValidation(event); | |
236 } | |
237 } | |
238 | |
239 /* (non-Javadoc) | |
240 * Method declared on DropTargetAdapter. | |
241 * The user has dropped something on the desktop viewer. | |
242 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
10
diff
changeset
|
243 public override void drop(DropTargetEvent event) { |
10 | 244 currentLocation = determineLocation(event); |
245 | |
246 //perform the drop behavior | |
247 if (!performDrop(event.data)) { | |
248 event.detail = DND.DROP_NONE; | |
249 } | |
250 currentOperation = event.detail; | |
251 } | |
252 | |
253 /* (non-Javadoc) | |
254 * Method declared on DropTargetAdapter. | |
255 * Last chance for the action to disable itself | |
256 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
10
diff
changeset
|
257 public override void dropAccept(DropTargetEvent event) { |
10 | 258 if (!validateDrop(currentTarget, event.detail, event.currentDataType)) { |
259 event.detail = DND.DROP_NONE; | |
260 } | |
261 } | |
262 | |
263 /** | |
264 * Returns the bounds of the given DWT tree or table item. | |
265 * | |
266 * @param item the DWT Item | |
267 * @return the bounds, or <code>null</code> if it is not a known type of item | |
268 */ | |
269 protected Rectangle getBounds(Item item) { | |
270 if ( auto i = cast(TreeItem)item ) { | |
271 return i.getBounds(); | |
272 } | |
273 if (auto i = cast(TableItem)item ) { | |
274 return i.getBounds(0); | |
275 } | |
276 return null; | |
277 } | |
278 | |
279 /** | |
280 * Returns a constant describing the position of the mouse relative to the | |
281 * target (before, on, or after the target. | |
282 * | |
283 * @return one of the <code>LOCATION_* </code> constants defined in this type | |
284 */ | |
285 protected int getCurrentLocation() { | |
286 return currentLocation; | |
287 } | |
288 | |
289 /** | |
290 * Returns the current operation. | |
291 * | |
292 * @return a <code>DROP_*</code> constant from class <code>DND</code> | |
293 * | |
294 * @see DND#DROP_COPY | |
295 * @see DND#DROP_MOVE | |
296 * @see DND#DROP_LINK | |
297 * @see DND#DROP_NONE | |
298 */ | |
299 protected int getCurrentOperation() { | |
300 return currentOperation; | |
301 } | |
302 | |
303 /** | |
304 * Returns the target object currently under the mouse. | |
305 * | |
306 * @return the current target object | |
307 */ | |
308 protected Object getCurrentTarget() { | |
309 return currentTarget; | |
310 } | |
311 | |
312 /** | |
313 * Returns whether visible insertion feedback should be presented to the user. | |
314 * <p> | |
315 * Typical insertion feedback is the horizontal insertion bars that appear | |
316 * between adjacent items while dragging. | |
317 * </p> | |
318 * | |
319 * @return <code>true</code> if visual feedback is desired, and <code>false</code> if not | |
320 */ | |
321 public bool getFeedbackEnabled() { | |
322 return feedbackEnabled; | |
323 } | |
324 | |
325 /** | |
326 * Returns the object currently selected by the viewer. | |
327 * | |
328 * @return the selected object, or <code>null</code> if either no object or | |
329 * multiple objects are selected | |
330 */ | |
331 protected Object getSelectedObject() { | |
332 ISelection selection = viewer.getSelection(); | |
333 if ( null !is cast(IStructuredSelection) selection && !selection.isEmpty()) { | |
334 IStructuredSelection structured = cast(IStructuredSelection) selection; | |
335 return structured.getFirstElement(); | |
336 } | |
337 return null; | |
338 } | |
339 | |
340 /** | |
341 * @return the viewer to which this drop support has been added. | |
342 */ | |
343 protected Viewer getViewer() { | |
344 return viewer; | |
345 } | |
346 | |
347 /** | |
348 * @deprecated this method should not be used. Exception handling has been | |
349 * removed from DropTargetAdapter methods overridden by this class. | |
350 * Handles any exception that occurs during callback, including | |
351 * rethrowing behavior. | |
352 * <p> | |
353 * [Issue: Implementation prints stack trace and eats exception to avoid | |
354 * crashing VA/J. | |
355 * Consider conditionalizing the implementation to do one thing in VAJ | |
356 * and something more reasonable in other operating environments. | |
357 * ] | |
358 * </p> | |
359 * | |
360 * @param exception the exception | |
361 * @param event the event | |
362 */ | |
363 protected void handleException(Exception exception, DropTargetEvent event) { | |
364 // Currently we never rethrow because VA/Java crashes if an DWT | |
365 // callback throws anything. Generally catching Throwable is bad, but in | |
366 // this cases it's better than hanging the image. | |
367 ExceptionPrintStackTrace( exception ); | |
368 event.detail = DND.DROP_NONE; | |
369 } | |
370 | |
371 /** | |
372 * Performs any work associated with the drop. | |
373 * <p> | |
374 * Subclasses must implement this method to provide drop behavior. | |
375 * </p> | |
376 * | |
377 * @param data the drop data | |
378 * @return <code>true</code> if the drop was successful, and | |
379 * <code>false</code> otherwise | |
380 */ | |
381 public abstract bool performDrop(Object data); | |
382 | |
383 /* (non-Javadoc) | |
384 * Method declared on DropTargetAdapter. | |
385 * The mouse has moved over the drop target. If the | |
386 * target item has changed, notify the action and check | |
387 * that it is still enabled. | |
388 */ | |
389 private void setFeedback(DropTargetEvent event, int location) { | |
390 if (feedbackEnabled) { | |
391 switch (location) { | |
392 case LOCATION_BEFORE: | |
393 event.feedback = DND.FEEDBACK_INSERT_BEFORE; | |
394 break; | |
395 case LOCATION_AFTER: | |
396 event.feedback = DND.FEEDBACK_INSERT_AFTER; | |
397 break; | |
398 case LOCATION_ON: | |
399 default: | |
400 event.feedback = DND.FEEDBACK_SELECT; | |
401 break; | |
402 } | |
403 } | |
404 | |
405 // Explicitly inhibit SELECT feedback if desired | |
406 if (!selectFeedbackEnabled) { | |
407 event.feedback &= ~DND.FEEDBACK_SELECT; | |
408 } | |
409 | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
410 if (expandEnabled) { |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
411 event.feedback |= DND.FEEDBACK_EXPAND; |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
412 } |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
413 if (scrollEnabled) { |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
414 event.feedback |= DND.FEEDBACK_SCROLL; |
10 | 415 } |
416 } | |
417 | |
418 /** | |
419 * Sets whether visible insertion feedback should be presented to the user. | |
420 * <p> | |
421 * Typical insertion feedback is the horizontal insertion bars that appear | |
422 * between adjacent items while dragging. | |
423 * </p> | |
424 * | |
425 * @param value | |
426 * <code>true</code> if visual feedback is desired, and | |
427 * <code>false</code> if not | |
428 */ | |
429 public void setFeedbackEnabled(bool value) { | |
430 feedbackEnabled = value; | |
431 } | |
432 | |
433 /** | |
434 * Sets whether selection feedback should be provided during dragging. | |
435 * | |
436 * @param value <code>true</code> if selection feedback is desired, and | |
437 * <code>false</code> if not | |
438 * | |
439 * @since 3.2 | |
440 */ | |
441 public void setSelectionFeedbackEnabled(bool value) { | |
442 selectFeedbackEnabled = value; | |
443 } | |
444 | |
445 /** | |
446 * Sets whether auto scrolling and expanding should be provided during dragging. | |
447 * | |
448 * @param value <code>true</code> if scrolling and expanding is desired, and | |
449 * <code>false</code> if not | |
450 * @since 2.0 | |
451 */ | |
452 public void setScrollExpandEnabled(bool value) { | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
453 expandEnabled = value; |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
454 scrollEnabled = value; |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
455 } |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
456 |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
457 /** |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
458 * Sets whether auto expanding should be provided during dragging. |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
459 * |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
460 * @param value <code>true</code> if expanding is desired, and |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
461 * <code>false</code> if not |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
462 * @since 3.4 |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
463 */ |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
464 public void setExpandEnabled(bool value) { |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
465 expandEnabled = value; |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
466 } |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
467 |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
468 /** |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
469 * Sets whether auto scrolling should be provided during dragging. |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
470 * |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
471 * @param value <code>true</code> if scrolling is desired, and |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
472 * <code>false</code> if not |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
473 * @since 3.4 |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
474 */ |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
475 public void setScrollEnabled(bool value) { |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
43
diff
changeset
|
476 scrollEnabled = value; |
10 | 477 } |
478 | |
479 /** | |
480 * Validates dropping on the given object. This method is called whenever some | |
481 * aspect of the drop operation changes. | |
482 * <p> | |
483 * Subclasses must implement this method to define which drops make sense. | |
484 * </p> | |
485 * | |
486 * @param target the object that the mouse is currently hovering over, or | |
487 * <code>null</code> if the mouse is hovering over empty space | |
488 * @param operation the current drag operation (copy, move, etc.) | |
489 * @param transferType the current transfer type | |
490 * @return <code>true</code> if the drop is valid, and <code>false</code> | |
491 * otherwise | |
492 */ | |
493 public abstract bool validateDrop(Object target, int operation, | |
494 TransferData transferType); | |
495 } |