1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 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 moduleorg.eclipse.swt.dnd.TreeDragSourceEffect;
14 15 importjava.lang.all;
16 17 18 importorg.eclipse.swt.SWT;
19 importorg.eclipse.swt.graphics.Image;
20 importorg.eclipse.swt.internal.gtk.OS;
21 importorg.eclipse.swt.widgets.Display;
22 importorg.eclipse.swt.widgets.Tree;
23 importorg.eclipse.swt.dnd.DragSourceEffect;
24 importorg.eclipse.swt.dnd.DragSourceEvent;
25 26 27 /**
28 * This class provides default implementations to display a source image
29 * when a drag is initiated from a <code>Tree</code>.
30 *
31 * <p>Classes that wish to provide their own source image for a <code>Tree</code> can
32 * extend <code>TreeDragSourceEffect</code> class and override the <code>TreeDragSourceEffect.dragStart</code>
33 * method and set the field <code>DragSourceEvent.image</code> with their own image.</p>
34 *
35 * Subclasses that override any methods of this class must call the corresponding
36 * <code>super</code> method to get the default drag under effect implementation.
37 *
38 * @see DragSourceEffect
39 * @see DragSourceEvent
40 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
41 *
42 * @since 3.3
43 */44 publicclassTreeDragSourceEffect : DragSourceEffect {
45 ImagedragSourceImage = null;
46 47 /**
48 * Creates a new <code>TreeDragSourceEffect</code> to handle drag effect
49 * from the specified <code>Tree</code>.
50 *
51 * @param tree the <code>Tree</code> that the user clicks on to initiate the drag
52 */53 publicthis(Treetree) {
54 super(tree);
55 }
56 57 /**
58 * This implementation of <code>dragFinished</code> disposes the image
59 * that was created in <code>TreeDragSourceEffect.dragStart</code>.
60 *
61 * Subclasses that override this method should call <code>super.dragFinished(event)</code>
62 * to dispose the image in the default implementation.
63 *
64 * @param event the information associated with the drag finished event
65 */66 publicoverridevoiddragFinished(DragSourceEventevent) {
67 if (dragSourceImage !isnull) dragSourceImage.dispose();
68 dragSourceImage = null;
69 }
70 71 /**
72 * This implementation of <code>dragStart</code> will create a default
73 * image that will be used during the drag. The image should be disposed
74 * when the drag is completed in the <code>TreeDragSourceEffect.dragFinished</code>
75 * method.
76 *
77 * Subclasses that override this method should call <code>super.dragStart(event)</code>
78 * to use the image from the default implementation.
79 *
80 * @param event the information associated with the drag start event
81 */82 publicoverridevoiddragStart(DragSourceEventevent) {
83 event.image = getDragSourceImage(event);
84 }
85 86 ImagegetDragSourceImage(DragSourceEventevent) {
87 if (dragSourceImage !isnull) dragSourceImage.dispose();
88 dragSourceImage = null;
89 90 Treetree = cast(Tree) control;
91 if (OS.GTK_VERSION < OS.buildVERSION (2, 2, 0)) returnnull;
92 //TEMPORARY CODE93 if (tree.isListening(SWT.EraseItem) || tree.isListening (SWT.PaintItem)) returnnull;
94 /*
95 * Bug in GTK. gtk_tree_selection_get_selected_rows() segmentation faults
96 * in versions smaller than 2.2.4 if the model is NULL. The fix is
97 * to give a valid pointer instead.
98 */99 autohandle = tree.handle;
100 autoselection = OS.gtk_tree_view_get_selection (handle);
101 ptrdiff_tdummy;
102 void* model = OS.GTK_VERSION < OS.buildVERSION (2, 2, 4) ? &dummy : null;
103 autolist = OS.gtk_tree_selection_get_selected_rows (selection, &model);
104 if (listisnull) returnnull;
105 ptrdiff_tcount = Math.min(10, OS.g_list_length (list));
106 107 Displaydisplay = tree.getDisplay();
108 if (countis1) {
109 autopath = OS.g_list_nth_data (list, 0);
110 autopixmap = OS.gtk_tree_view_create_row_drag_icon(handle, path);
111 dragSourceImage = Image.gtk_new(display, SWT.ICON, pixmap, null);
112 } else {
113 intwidth = 0, height = 0;
114 intw , h;
115 int[] yy = newint[count], hh = newint[count];
116 GdkDrawable* [] pixmaps = newGdkDrawable*[count];
117 GdkRectanglerect;
118 for (inti=0; i<count; i++) {
119 autopath = OS.g_list_nth_data (list, i);
120 OS.gtk_tree_view_get_cell_area (handle, path, null, &rect);
121 pixmaps[i] = OS.gtk_tree_view_create_row_drag_icon(handle, path);
122 OS.gdk_drawable_get_size(pixmaps[i], &w, &h);
123 width = Math.max(width, w);
124 height = rect.y + h - yy[0];
125 yy[i] = rect.y;
126 hh[i] = h;
127 }
128 autosource = OS.gdk_pixmap_new(OS.GDK_ROOT_PARENT(), width, height, -1);
129 autogcSource = OS.gdk_gc_new(source);
130 automask = OS.gdk_pixmap_new(OS.GDK_ROOT_PARENT(), width, height, 1);
131 autogcMask = OS.gdk_gc_new(mask);
132 GdkColorcolor;
133 color.pixel = 0;
134 OS.gdk_gc_set_foreground(gcMask, &color);
135 OS.gdk_draw_rectangle(mask, gcMask, 1, 0, 0, width, height);
136 color.pixel = 1;
137 OS.gdk_gc_set_foreground(gcMask, &color);
138 for (inti=0; i<count; i++) {
139 OS.gdk_draw_drawable(source, gcSource, pixmaps[i], 0, 0, 0, yy[i] - yy[0], -1, -1);
140 OS.gdk_draw_rectangle(mask, gcMask, 1, 0, yy[i] - yy[0], width, hh[i]);
141 OS.g_object_unref(pixmaps[i]);
142 }
143 OS.g_object_unref(gcSource);
144 OS.g_object_unref(gcMask);
145 dragSourceImage = Image.gtk_new(display, SWT.ICON, source, mask);
146 }
147 OS.g_list_free (list);
148 149 returndragSourceImage;
150 }
151 }