Lines 14-23
Link Here
|
14 |
import java.util.ArrayList; |
14 |
import java.util.ArrayList; |
15 |
import java.util.Collections; |
15 |
import java.util.Collections; |
16 |
import java.util.Enumeration; |
16 |
import java.util.Enumeration; |
|
|
17 |
import java.util.HashMap; |
18 |
import java.util.Iterator; |
17 |
import java.util.List; |
19 |
import java.util.List; |
|
|
20 |
import java.util.Map; |
18 |
import java.util.Vector; |
21 |
import java.util.Vector; |
19 |
|
22 |
|
20 |
import org.eclipse.core.runtime.IStatus; |
23 |
import org.eclipse.core.runtime.IStatus; |
|
|
24 |
import org.eclipse.jface.util.Geometry; |
21 |
import org.eclipse.jface.window.Window; |
25 |
import org.eclipse.jface.window.Window; |
22 |
import org.eclipse.swt.SWT; |
26 |
import org.eclipse.swt.SWT; |
23 |
import org.eclipse.swt.graphics.Cursor; |
27 |
import org.eclipse.swt.graphics.Cursor; |
Lines 25-30
Link Here
|
25 |
import org.eclipse.swt.graphics.Rectangle; |
29 |
import org.eclipse.swt.graphics.Rectangle; |
26 |
import org.eclipse.swt.widgets.Composite; |
30 |
import org.eclipse.swt.widgets.Composite; |
27 |
import org.eclipse.swt.widgets.Control; |
31 |
import org.eclipse.swt.widgets.Control; |
|
|
32 |
import org.eclipse.swt.widgets.Display; |
33 |
import org.eclipse.swt.widgets.Monitor; |
34 |
import org.eclipse.swt.widgets.Shell; |
28 |
import org.eclipse.ui.IMemento; |
35 |
import org.eclipse.ui.IMemento; |
29 |
import org.eclipse.ui.IViewReference; |
36 |
import org.eclipse.ui.IViewReference; |
30 |
import org.eclipse.ui.IWorkbenchPartReference; |
37 |
import org.eclipse.ui.IWorkbenchPartReference; |
Lines 116-125
Link Here
|
116 |
private LayoutPart part; |
123 |
private LayoutPart part; |
117 |
|
124 |
|
118 |
private Rectangle dragRectangle; |
125 |
private Rectangle dragRectangle; |
|
|
126 |
|
127 |
private Window window; |
128 |
|
129 |
private int MAXIMUM_SNAP_DISTANCE = 40; |
130 |
|
131 |
private List distances = new ArrayList(5); |
132 |
private Map distancesToPoints = new HashMap(5); |
133 |
private Map pointsToRectangles = new HashMap(5); |
119 |
|
134 |
|
120 |
private ActualDropTarget(LayoutPart part, Rectangle dragRectangle) { |
135 |
private ActualDropTarget(LayoutPart part, Rectangle dragRectangle) { |
121 |
super(); |
136 |
super(); |
122 |
setTarget(part, dragRectangle); |
137 |
setTarget(part, dragRectangle); |
123 |
} |
138 |
} |
124 |
|
139 |
|
125 |
/** |
140 |
/** |
Lines 129-140
Link Here
|
129 |
*/ |
144 |
*/ |
130 |
private void setTarget(LayoutPart part, Rectangle dragRectangle) { |
145 |
private void setTarget(LayoutPart part, Rectangle dragRectangle) { |
131 |
this.part = part; |
146 |
this.part = part; |
132 |
this.dragRectangle = dragRectangle; |
147 |
this.dragRectangle = dragRectangle; |
|
|
148 |
this.window = part.getWindow(); |
133 |
} |
149 |
} |
134 |
|
150 |
|
135 |
public void drop() { |
151 |
public void drop() { |
136 |
|
|
|
137 |
Window window = part.getWindow(); |
138 |
if (window instanceof DetachedWindow) { |
152 |
if (window instanceof DetachedWindow) { |
139 |
// only one tab folder in a detach window, so do window |
153 |
// only one tab folder in a detach window, so do window |
140 |
// move |
154 |
// move |
Lines 164-169
Link Here
|
164 |
public Cursor getCursor() { |
178 |
public Cursor getCursor() { |
165 |
return DragCursors.getCursor(DragCursors.OFFSCREEN); |
179 |
return DragCursors.getCursor(DragCursors.OFFSCREEN); |
166 |
} |
180 |
} |
|
|
181 |
|
182 |
public Rectangle getSnapRectangle() { |
183 |
Rectangle snapRect = null; |
184 |
Point initial = window.getShell().getDisplay().getCursorLocation(); |
185 |
Rectangle sourceRect = dragRectangle; |
186 |
|
187 |
Rectangle offScreen = null; |
188 |
|
189 |
if(window instanceof WorkbenchWindow) { |
190 |
ILayoutContainer cont = part.getContainer(); |
191 |
if(cont != null && cont instanceof PartStack) |
192 |
Geometry.setSize(sourceRect, ((PartStack)part.getContainer()).getSize()); |
193 |
else |
194 |
Geometry.setSize(sourceRect, part.getControl().getSize()); |
195 |
} |
196 |
else { |
197 |
Geometry.setSize(sourceRect, window.getShell().getSize()); |
198 |
} |
199 |
|
200 |
int[] sides = { SWT.TOP, SWT.BOTTOM, SWT.RIGHT, SWT.LEFT }; |
201 |
|
202 |
|
203 |
for (int i = 0; i < sides.length; i++) { |
204 |
getEdges(sourceRect, sides[i]); |
205 |
Collections.sort(distances); |
206 |
for (Iterator iter = distances.iterator(); iter.hasNext();) { |
207 |
Point found = (Point)distancesToPoints.get((Double) iter.next()); |
208 |
if(found != null) { |
209 |
boolean finished = false; |
210 |
switch (sides[i]) { |
211 |
case SWT.TOP: |
212 |
if((found.y + MAXIMUM_SNAP_DISTANCE) > initial.y && |
213 |
(found.y) < initial.y) { |
214 |
offScreen = sourceRect; |
215 |
offScreen.y = found.y; |
216 |
if(willBeTouching(offScreen, found, SWT.BOTTOM)) { |
217 |
snapRect = offScreen; |
218 |
finished = true; |
219 |
} |
220 |
} |
221 |
else if((found.y) > initial.y && |
222 |
(found.y- MAXIMUM_SNAP_DISTANCE) < initial.y) { |
223 |
offScreen = sourceRect; |
224 |
offScreen.y = (found.y - sourceRect.height); |
225 |
if(willBeTouching(offScreen, found, SWT.BOTTOM)) { |
226 |
snapRect = offScreen; |
227 |
finished = true; |
228 |
} |
229 |
} |
230 |
break; |
231 |
case SWT.BOTTOM: |
232 |
if((found.y + MAXIMUM_SNAP_DISTANCE) > initial.y && |
233 |
(found.y) < initial.y) { |
234 |
offScreen = sourceRect; |
235 |
offScreen.y = found.y; |
236 |
if(willBeTouching(offScreen, found, SWT.TOP)) { |
237 |
snapRect = offScreen; |
238 |
finished = true; |
239 |
} |
240 |
} |
241 |
else if((found.y) > initial.y && |
242 |
(found.y - MAXIMUM_SNAP_DISTANCE) < initial.y) { |
243 |
offScreen = sourceRect; |
244 |
offScreen.y = (found.y - sourceRect.height); |
245 |
if(willBeTouching(offScreen, found, SWT.TOP)) { |
246 |
snapRect = offScreen; |
247 |
finished = true; |
248 |
} |
249 |
} |
250 |
break; |
251 |
case SWT.RIGHT: |
252 |
if((found.x + MAXIMUM_SNAP_DISTANCE) > initial.x && |
253 |
(found.x) < initial.x) { |
254 |
offScreen = sourceRect; |
255 |
offScreen.x = found.x; |
256 |
if(willBeTouching(offScreen, found, SWT.LEFT)) { |
257 |
snapRect = offScreen; |
258 |
finished = true; |
259 |
} |
260 |
} |
261 |
else if((found.x) > initial.x && |
262 |
(found.x - MAXIMUM_SNAP_DISTANCE) < initial.x) { |
263 |
offScreen = sourceRect; |
264 |
offScreen.x = (found.x - sourceRect.width); |
265 |
if(willBeTouching(offScreen, found, SWT.LEFT)) { |
266 |
snapRect = offScreen; |
267 |
finished = true; |
268 |
} |
269 |
} |
270 |
break; |
271 |
case SWT.LEFT: |
272 |
if((found.x + MAXIMUM_SNAP_DISTANCE) > initial.x && |
273 |
(found.x) < initial.x) { |
274 |
offScreen = sourceRect; |
275 |
offScreen.x = found.x; |
276 |
if(willBeTouching(offScreen, found, SWT.RIGHT)) { |
277 |
snapRect = offScreen; |
278 |
finished = true; |
279 |
} |
280 |
} |
281 |
if((found.x > initial.x) && |
282 |
(found.x - MAXIMUM_SNAP_DISTANCE) < initial.x) { |
283 |
offScreen = sourceRect; |
284 |
offScreen.x = (found.x - sourceRect.width); |
285 |
if(willBeTouching(offScreen, found, SWT.RIGHT)) { |
286 |
snapRect = offScreen; |
287 |
finished = true; |
288 |
} |
289 |
} |
290 |
break; |
291 |
} |
292 |
if(finished) { |
293 |
break; |
294 |
} |
295 |
} |
296 |
} |
297 |
} |
298 |
return snapRect; |
299 |
} |
300 |
|
301 |
private void getEdges(Rectangle source, int side) { |
302 |
Shell shell = window.getShell(); |
303 |
Point closest = null; |
304 |
distances.clear(); |
305 |
distancesToPoints.clear(); |
306 |
pointsToRectangles.clear(); |
307 |
Rectangle clientArea; |
308 |
if (shell != null) { |
309 |
Point sourceSide = createCenterPoint(source, side); |
310 |
Vector pointsToSearch = new Vector(11); |
311 |
|
312 |
// first we check the edges of monitors |
313 |
Display display = shell.getDisplay(); |
314 |
Monitor[] monitors = display.getMonitors(); |
315 |
|
316 |
for (int idx = 0; idx < monitors.length; idx++) { |
317 |
Monitor mon = monitors[idx]; |
318 |
clientArea = mon.getClientArea(); |
319 |
Point p = createCenterPoint(clientArea, side); |
320 |
pointsToSearch.add(p); |
321 |
pointsToRectangles.put(p, clientArea); |
322 |
} |
323 |
|
324 |
// now search the shells |
325 |
// shells that do not have the data field set do not have a window |
326 |
// associated with them, therefore we do not search them |
327 |
|
328 |
// we also don't search for the shell we're moving |
329 |
Shell[] shells = display.getShells(); |
330 |
for (int i = 0; i < shells.length; i++) { |
331 |
if(shells[i].getData() != null) { |
332 |
if(shells[i] == shell && !(shells[i].getData() instanceof WorkbenchWindow)) { |
333 |
continue; |
334 |
} |
335 |
clientArea = shells[i].getBounds(); |
336 |
Point p = createCenterPoint(clientArea, side); |
337 |
pointsToSearch.add(p); |
338 |
pointsToRectangles.put(p, clientArea); |
339 |
} |
340 |
} |
341 |
|
342 |
// real work |
343 |
for (Iterator iter = pointsToSearch.iterator(); iter.hasNext();) { |
344 |
Point toSearch = (Point) iter.next(); |
345 |
double dSquared = Geometry.distanceSquared(sourceSide, toSearch); |
346 |
distances.add(new Double(dSquared)); |
347 |
distancesToPoints.put(new Double(dSquared), toSearch); |
348 |
|
349 |
} |
350 |
} |
351 |
|
352 |
} |
353 |
|
354 |
private boolean willBeTouching(Rectangle toTest, Point p, int side) { |
355 |
Rectangle source = (Rectangle)pointsToRectangles.get(p); |
356 |
Geometry.expand(source, 15, 15, 15, 15); |
357 |
return source.intersects(toTest); |
358 |
} |
359 |
|
360 |
private Point createCenterPoint(Rectangle toSearch, int side) { |
361 |
switch (side){ |
362 |
case SWT.TOP: |
363 |
return new Point((int)((double)toSearch.width/(double)2) + toSearch.x, toSearch.y); |
364 |
case SWT.BOTTOM: |
365 |
return new Point((int)((double)toSearch.width/(double)2) + toSearch.x, toSearch.height + toSearch.y); |
366 |
case SWT.LEFT: |
367 |
return new Point(toSearch.x, (int)((double)toSearch.height/(double)2) + toSearch.y); |
368 |
case SWT.RIGHT: |
369 |
return new Point(toSearch.width + toSearch.x, (int)((double)toSearch.height/(double)2) + toSearch.y); |
370 |
} |
371 |
return new Point(0, 0); |
372 |
} |
373 |
|
167 |
} |
374 |
} |
168 |
|
375 |
|
169 |
private class MatchingPart implements Comparable { |
376 |
private class MatchingPart implements Comparable { |