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 module org.eclipse.swt.dnd.TableDropTargetEffect; 14 15 import java.lang.all; 16 17 18 import org.eclipse.swt.graphics.Point; 19 import org.eclipse.swt.internal.gtk.OS; 20 import org.eclipse.swt.widgets.Table; 21 import org.eclipse.swt.dnd.DropTargetEffect; 22 import org.eclipse.swt.dnd.DropTargetEvent; 23 import org.eclipse.swt.dnd.DND; 24 25 26 /** 27 * This class provides a default drag under effect (eg. select, insert and scroll) 28 * when a drag occurs over a <code>Table</code>. 29 * 30 * <p>Classes that wish to provide their own drag under effect for a <code>Table</code> 31 * can extend the <code>TableDropTargetEffect</code> and override any applicable methods 32 * in <code>TableDropTargetEffect</code> to display their own drag under effect.</p> 33 * 34 * Subclasses that override any methods of this class must call the corresponding 35 * <code>super</code> method to get the default drag under effect implementation. 36 * 37 * <p>The feedback value is either one of the FEEDBACK constants defined in 38 * class <code>DND</code> which is applicable to instances of this class, 39 * or it must be built by <em>bitwise OR</em>'ing together 40 * (that is, using the <code>int</code> "|" operator) two or more 41 * of those <code>DND</code> effect constants. 42 * </p> 43 * <p> 44 * <dl> 45 * <dt><b>Feedback:</b></dt> 46 * <dd>FEEDBACK_SELECT, FEEDBACK_SCROLL</dd> 47 * </dl> 48 * </p> 49 * 50 * @see DropTargetAdapter 51 * @see DropTargetEvent 52 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> 53 * 54 * @since 3.3 55 */ 56 public class TableDropTargetEffect : DropTargetEffect { 57 static const int SCROLL_HYSTERESIS = 150; // milli seconds 58 59 int scrollIndex; 60 long scrollBeginTime; 61 62 /** 63 * Creates a new <code>TableDropTargetEffect</code> to handle the drag under effect on the specified 64 * <code>Table</code>. 65 * 66 * @param table the <code>Table</code> over which the user positions the cursor to drop the data 67 */ 68 public this(Table table) { 69 super(table); 70 } 71 72 int checkEffect(int effect) { 73 // Some effects are mutually exclusive. Make sure that only one of the mutually exclusive effects has been specified. 74 if ((effect & DND.FEEDBACK_SELECT) !is 0) effect = effect & ~DND.FEEDBACK_INSERT_AFTER & ~DND.FEEDBACK_INSERT_BEFORE; 75 if ((effect & DND.FEEDBACK_INSERT_BEFORE) !is 0) effect = effect & ~DND.FEEDBACK_INSERT_AFTER; 76 return effect; 77 } 78 79 /** 80 * This implementation of <code>dragEnter</code> provides a default drag under effect 81 * for the feedback specified in <code>event.feedback</code>. 82 * 83 * For additional information see <code>DropTargetAdapter.dragEnter</code>. 84 * 85 * Subclasses that override this method should call <code>super.dragEnter(event)</code> 86 * to get the default drag under effect implementation. 87 * 88 * @param event the information associated with the drag enter event 89 * 90 * @see DropTargetAdapter 91 * @see DropTargetEvent 92 */ 93 public override void dragEnter(DropTargetEvent event) { 94 scrollBeginTime = 0; 95 scrollIndex = -1; 96 } 97 98 /** 99 * This implementation of <code>dragLeave</code> provides a default drag under effect 100 * for the feedback specified in <code>event.feedback</code>. 101 * 102 * For additional information see <code>DropTargetAdapter.dragLeave</code>. 103 * 104 * Subclasses that override this method should call <code>super.dragLeave(event)</code> 105 * to get the default drag under effect implementation. 106 * 107 * @param event the information associated with the drag leave event 108 * 109 * @see DropTargetAdapter 110 * @see DropTargetEvent 111 */ 112 public override void dragLeave(DropTargetEvent event) { 113 Table table = cast(Table) control; 114 auto handle = table.handle; 115 OS.gtk_tree_view_set_drag_dest_row(handle, null, OS.GTK_TREE_VIEW_DROP_BEFORE); 116 117 scrollBeginTime = 0; 118 scrollIndex = -1; 119 } 120 121 /** 122 * This implementation of <code>dragOver</code> provides a default drag under effect 123 * for the feedback specified in <code>event.feedback</code>. The class description 124 * lists the FEEDBACK constants that are applicable to the class. 125 * 126 * For additional information see <code>DropTargetAdapter.dragOver</code>. 127 * 128 * Subclasses that override this method should call <code>super.dragOver(event)</code> 129 * to get the default drag under effect implementation. 130 * 131 * @param event the information associated with the drag over event 132 * 133 * @see DropTargetAdapter 134 * @see DropTargetEvent 135 * @see DND#FEEDBACK_SELECT 136 * @see DND#FEEDBACK_SCROLL 137 */ 138 public override void dragOver(DropTargetEvent event) { 139 Table table = cast(Table) control; 140 auto handle = table.handle; 141 int effect = checkEffect(event.feedback); 142 Point coordinates = new Point(event.x, event.y); 143 coordinates = table.toControl(coordinates); 144 void* path; 145 OS.gtk_tree_view_get_path_at_pos (handle, coordinates.x, coordinates.y, &path, null, null, null); 146 int index = -1; 147 if (path !is null) { 148 auto indices = OS.gtk_tree_path_get_indices (path); 149 if (indices !is null) { 150 index = indices[0]; 151 } 152 } 153 if ((effect & DND.FEEDBACK_SCROLL) is 0) { 154 scrollBeginTime = 0; 155 scrollIndex = -1; 156 } else { 157 if (index !is -1 && scrollIndex is index && scrollBeginTime !is 0) { 158 if (System.currentTimeMillis() >= scrollBeginTime) { 159 if (coordinates.y < table.getItemHeight()) { 160 OS.gtk_tree_path_prev(path); 161 } else { 162 OS.gtk_tree_path_next(path); 163 } 164 if (path !is null) { 165 OS.gtk_tree_view_scroll_to_cell(handle, path, null, false, 0, 0); 166 OS.gtk_tree_path_free(path); 167 path = null; 168 OS.gtk_tree_view_get_path_at_pos (handle, coordinates.x, coordinates.y, &path, null, null, null); 169 } 170 scrollBeginTime = 0; 171 scrollIndex = -1; 172 } 173 } else { 174 scrollBeginTime = System.currentTimeMillis() + SCROLL_HYSTERESIS; 175 scrollIndex = index; 176 } 177 } 178 if (path !is null) { 179 ptrdiff_t position = 0; 180 if ((effect & DND.FEEDBACK_SELECT) !is 0) position = OS.GTK_TREE_VIEW_DROP_INTO_OR_BEFORE; 181 //if ((effect & DND.FEEDBACK_INSERT_BEFORE) !is 0) position = OS.GTK_TREE_VIEW_DROP_BEFORE; 182 //if ((effect & DND.FEEDBACK_INSERT_AFTER) !is 0) position = OS.GTK_TREE_VIEW_DROP_AFTER; 183 if (position !is 0) { 184 OS.gtk_tree_view_set_drag_dest_row(handle, path, OS.GTK_TREE_VIEW_DROP_INTO_OR_BEFORE); 185 } else { 186 OS.gtk_tree_view_set_drag_dest_row(handle, null, OS.GTK_TREE_VIEW_DROP_BEFORE); 187 } 188 } else { 189 OS.gtk_tree_view_set_drag_dest_row(handle, null, OS.GTK_TREE_VIEW_DROP_BEFORE); 190 } 191 if (path !is null) OS.gtk_tree_path_free (path ); 192 } 193 }