KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > dnd > TreeDragAndDropEffect


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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  *******************************************************************************/

11 package org.eclipse.swt.dnd;
12
13 import org.eclipse.swt.*;
14 import org.eclipse.swt.graphics.*;
15 import org.eclipse.swt.internal.win32.*;
16 import org.eclipse.swt.widgets.*;
17
18 class TreeDragAndDropEffect extends DragAndDropEffect {
19     Tree tree;
20     int dropIndex;
21     int scrollIndex;
22     long scrollBeginTime;
23     int expandIndex;
24     long expandBeginTime;
25     TreeItem insertItem;
26     boolean insertBefore;
27     
28     static final int SCROLL_HYSTERESIS = 200; // milli seconds
29
static final int EXPAND_HYSTERESIS = 300; // milli seconds
30

31
32 TreeDragAndDropEffect(Tree tree) {
33     this.tree = tree;
34 }
35
36 int checkEffect(int effect) {
37     // Some effects are mutually exclusive. Make sure that only one of the mutually exclusive effects has been specified.
38
if ((effect & DND.FEEDBACK_SELECT) != 0) effect = effect & ~DND.FEEDBACK_INSERT_AFTER & ~DND.FEEDBACK_INSERT_BEFORE;
39     if ((effect & DND.FEEDBACK_INSERT_BEFORE) != 0) effect = effect & ~DND.FEEDBACK_INSERT_AFTER;
40     return effect;
41 }
42
43 Widget getItem(int x, int y) {
44     Point coordinates = new Point(x, y);
45     coordinates = tree.toControl(coordinates);
46     TreeItem item = tree.getItem(coordinates);
47     if (item == null) {
48         Rectangle area = tree.getClientArea();
49         if (area.contains(coordinates)) {
50             // Scan across the width of the tree.
51
for (int x1 = area.x; x1 < area.x + area.width; x1++) {
52                 Point pt = new Point(x1, coordinates.y);
53                 item = tree.getItem(pt);
54                 if (item != null) {
55                     break;
56                 }
57             }
58         }
59     }
60     return item;
61 }
62
63 ImageData getDragSourceImage(int x, int y) {
64     TreeItem[] selection = tree.getSelection();
65     if (selection.length == 0) return null;
66     int treeImageList = OS.SendMessage (tree.handle, OS.TVM_GETIMAGELIST, OS.TVSIL_NORMAL, 0);
67     if (treeImageList != 0) {
68         int count = Math.min(selection.length, 10);
69         Rectangle bounds = selection[0].getBounds(0);
70         for (int i = 1; i < count; i++) {
71             bounds = bounds.union(selection[i].getBounds(0));
72         }
73         int hDC = OS.GetDC(0);
74         int hDC1 = OS.CreateCompatibleDC(hDC);
75         int bitmap = OS.CreateCompatibleBitmap(hDC, bounds.width, bounds.height);
76         int hOldBitmap = OS.SelectObject(hDC1, bitmap);
77         RECT rect = new RECT();
78         rect.right = bounds.width;
79         rect.bottom = bounds.height;
80         int hBrush = OS.GetStockObject(OS.WHITE_BRUSH);
81         OS.FillRect(hDC1, rect, hBrush);
82         for (int i = 0; i < count; i++) {
83             TreeItem selected = selection[i];
84             Rectangle cell = selected.getBounds(0);
85             int imageList = OS.SendMessage(tree.handle, OS.TVM_CREATEDRAGIMAGE, 0, selected.handle);
86             OS.ImageList_Draw(imageList, 0, hDC1, cell.x - bounds.x, cell.y - bounds.y, OS.ILD_SELECTED);
87             OS.ImageList_Destroy(imageList);
88         }
89         OS.SelectObject(hDC1, hOldBitmap);
90         OS.DeleteDC (hDC1);
91         OS.ReleaseDC (0, hDC);
92         Display display = tree.getDisplay();
93         Image image = Image.win32_new(display, SWT.BITMAP, bitmap);
94         ImageData imageData = image.getImageData();
95         image.dispose();
96         return imageData;
97     }
98     return null;
99 }
100
101 void showDropTargetEffect(int effect, int x, int y) {
102     effect = checkEffect(effect);
103     int handle = tree.handle;
104     Point coordinates = new Point(x, y);
105     coordinates = tree.toControl(coordinates);
106     TVHITTESTINFO lpht = new TVHITTESTINFO ();
107     lpht.x = coordinates.x;
108     lpht.y = coordinates.y;
109     OS.SendMessage (handle, OS.TVM_HITTEST, 0, lpht);
110     int hItem = lpht.hItem;
111     if ((effect & DND.FEEDBACK_SCROLL) == 0) {
112         scrollBeginTime = 0;
113         scrollIndex = -1;
114     } else {
115         if (hItem != -1 && scrollIndex == hItem && scrollBeginTime != 0) {
116             if (System.currentTimeMillis() >= scrollBeginTime) {
117                 int topItem = OS.SendMessage(handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0);
118                 int nextItem = OS.SendMessage(handle, OS.TVM_GETNEXTITEM, hItem == topItem ? OS.TVGN_PREVIOUSVISIBLE : OS.TVGN_NEXTVISIBLE, hItem);
119                 boolean scroll = true;
120                 if (hItem == topItem) {
121                     scroll = nextItem != 0;
122                 } else {
123                     RECT itemRect = new RECT ();
124                     itemRect.left = nextItem;
125                     if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, itemRect) != 0) {
126                         RECT rect = new RECT ();
127                         OS.GetClientRect (handle, rect);
128                         POINT pt = new POINT ();
129                         pt.x = itemRect.left;
130                         pt.y = itemRect.top;
131                         if (OS.PtInRect (rect, pt)) {
132                             pt.y = itemRect.bottom;
133                             if (OS.PtInRect (rect, pt)) scroll = false;
134                         }
135                     }
136                 }
137                 if (scroll) {
138                     OS.SendMessage (handle, OS.TVM_ENSUREVISIBLE, 0, nextItem);
139                     tree.redraw();
140                 }
141                 scrollBeginTime = 0;
142                 scrollIndex = -1;
143             }
144         } else {
145             scrollBeginTime = System.currentTimeMillis() + SCROLL_HYSTERESIS;
146             scrollIndex = hItem;
147         }
148     }
149     if ((effect & DND.FEEDBACK_EXPAND) == 0) {
150         expandBeginTime = 0;
151         expandIndex = -1;
152     } else {
153         if (hItem != -1 && expandIndex == hItem && expandBeginTime != 0) {
154             if (System.currentTimeMillis() >= expandBeginTime) {
155                 if (OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hItem) != 0) {
156                     TVITEM tvItem = new TVITEM ();
157                     tvItem.hItem = hItem;
158                     tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE;
159                     OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem);
160                     if ((tvItem.state & OS.TVIS_EXPANDED) == 0) {
161                         OS.SendMessage (handle, OS.TVM_EXPAND, OS.TVE_EXPAND, hItem);
162                         tree.redraw();
163                     }
164                 }
165                 expandBeginTime = 0;
166                 expandIndex = -1;
167             }
168         } else {
169             expandBeginTime = System.currentTimeMillis() + EXPAND_HYSTERESIS;
170             expandIndex = hItem;
171         }
172     }
173     if (dropIndex != -1 && (dropIndex != hItem || (effect & DND.FEEDBACK_SELECT) == 0)) {
174         TVITEM tvItem = new TVITEM ();
175         tvItem.hItem = dropIndex;
176         tvItem.mask = OS.TVIF_STATE;
177         tvItem.stateMask = OS.TVIS_DROPHILITED;
178         tvItem.state = 0;
179         OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem);
180         dropIndex = -1;
181     }
182     if (hItem != -1 && hItem != dropIndex && (effect & DND.FEEDBACK_SELECT) != 0) {
183         TVITEM tvItem = new TVITEM ();
184         tvItem.hItem = hItem;
185         tvItem.mask = OS.TVIF_STATE;
186         tvItem.stateMask = OS.TVIS_DROPHILITED;
187         tvItem.state = OS.TVIS_DROPHILITED;
188         OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem);
189         dropIndex = hItem;
190     }
191     if ((effect & DND.FEEDBACK_INSERT_BEFORE) != 0 || (effect & DND.FEEDBACK_INSERT_AFTER) != 0) {
192         boolean before = (effect & DND.FEEDBACK_INSERT_BEFORE) != 0;
193         /*
194         * Bug in Windows. When TVM_SETINSERTMARK is used to set
195         * an insert mark for a tree and an item is expanded or
196         * collapsed near the insert mark, the tree does not redraw
197         * the insert mark properly. The fix is to hide and show
198         * the insert mark whenever an item is expanded or collapsed.
199         * Since the insert mark can not be queried from the tree,
200         * use the Tree API rather than calling the OS directly.
201         */

202         TreeItem item = (TreeItem)tree.getDisplay().findWidget(tree.handle, hItem);
203         if (item != null) {
204             if (item != insertItem || before != insertBefore) {
205                 tree.setInsertMark(item, before);
206             }
207             insertItem = item;
208             insertBefore = before;
209         } else {
210             if (insertItem != null) {
211                 tree.setInsertMark(null, false);
212             }
213             insertItem = null;
214         }
215     } else {
216         if (insertItem != null) {
217             tree.setInsertMark(null, false);
218         }
219         insertItem = null;
220     }
221     return;
222 }
223 }
224
Popular Tags