View | Details | Raw Unified | Return to bug 73175
Collapse All | Expand All

(-)PerspectiveHelper.java (-4 / +211 lines)
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 {

Return to bug 73175