Project

General

Profile

Download (23.6 KB) Statistics
| Branch: | Tag: | Revision:
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 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
 *     Asim Ullah - Ported for use in draw2d (c.f Bugzilla 71684). [Sep 10, 2004]
11
 *******************************************************************************/
12
package org.eclipse.draw2d;
13

    
14
import java.util.HashMap;
15
import java.util.List;
16
import java.util.Map;
17

    
18

    
19
import org.eclipse.draw2d.geometry.Dimension;
20
import org.eclipse.draw2d.geometry.Rectangle;
21
import org.eclipse.draw2d.rap.swt.SWT;
22

    
23
/**
24
 * Lays out children into a Grid arrangement in which overall aligment and
25
 * spacing can be configured, as well as specfic layout requirements for the
26
 * each individual member of the GridLayout. This layout is a Draw2D port of the
27
 * swt GridLayout.
28
 * 
29
 * <code>GridLayout</code> has a number of configuration fields, and the Figures
30
 * it lays out can have an associated layout data object, called
31
 * <code>GridData</code> (similar to the swt GridData object). The power of
32
 * <code>GridLayout</code> lies in the ability to configure
33
 * <code>GridData</code> for each Figure in the layout.
34
 * <p>
35
 * The following code creates a container Figure managed by a
36
 * <code>GridLayout</code> with 2 columns, containing 3 RectangleFigure shapes,
37
 * the last of which has been given further layout instructions. Note that it is
38
 * the <code>GridLayout</code> method <code>setConstraint</code> that binds the
39
 * child <code>Figure</code> to its layout <code>GridData</code> object.
40
 * 
41
 * <pre>
42
 * Figure container = new Figure();
43
 * GridLayout gridLayout = new GridLayout();
44
 * gridLayout.numColumns = 2;
45
 * container.setLayout(gridLayout);
46
 * 
47
 * Shape rect;
48
 * rect = new RectangleFigure();
49
 * container.add(rect);
50
 * 
51
 * rect = new RectangleFigure();
52
 * container.add(rect);
53
 * 
54
 * rect = new RectangleFigure();
55
 * GridData gridData = new GridData();
56
 * gridData.widthHint = 150;
57
 * layout.setConstraint(rect, gridData);
58
 * 
59
 * container.add(rect);
60
 * </pre>
61
 * 
62
 * <p>
63
 * The <code>numColumns</code> field is the most important field in a
64
 * <code>GridLayout</code>. Widgets are laid out in columns from left to right,
65
 * and a new row is created when <code>numColumns</code>+ 1 figures are added to
66
 * the <code>Figure<code> parent container.
67
 * 
68
 * @see GridData
69
 * 
70
 */
71
public class GridLayout extends AbstractLayout {
72

    
73
	/**
74
	 * numColumns specifies the number of cell columns in the layout.
75
	 * 
76
	 * The default value is 1.
77
	 */
78
	public int numColumns = 1;
79

    
80
	/**
81
	 * makeColumnsEqualWidth specifies whether all columns in the layout will be
82
	 * forced to have the same width.
83
	 * 
84
	 * The default value is false.
85
	 */
86
	public boolean makeColumnsEqualWidth = false;
87

    
88
	/**
89
	 * marginWidth specifies the number of pixels of horizontal margin that will
90
	 * be placed along the left and right edges of the layout.
91
	 * 
92
	 * The default value is 5.
93
	 */
94
	public int marginWidth = 5;
95

    
96
	/**
97
	 * marginHeight specifies the number of pixels of vertical margin that will
98
	 * be placed along the top and bottom edges of the layout.
99
	 * 
100
	 * The default value is 5.
101
	 */
102
	public int marginHeight = 5;
103

    
104
	/**
105
	 * horizontalSpacing specifies the number of pixels between the right edge
106
	 * of one cell and the left edge of its neighbouring cell to the right.
107
	 * 
108
	 * The default value is 5.
109
	 */
110
	public int horizontalSpacing = 5;
111

    
112
	/**
113
	 * verticalSpacing specifies the number of pixels between the bottom edge of
114
	 * one cell and the top edge of its neighbouring cell underneath.
115
	 * 
116
	 * The default value is 5.
117
	 */
118
	public int verticalSpacing = 5;
119

    
120
	/** The layout contraints */
121
	protected Map constraints = new HashMap();
122

    
123
	/**
124
	 * Default Constructor
125
	 */
126
	public GridLayout() {
127
		super();
128
	}
129

    
130
	/**
131
	 * Constructs a new instance of this class given the number of columns, and
132
	 * whether or not the columns should be forced to have the same width.
133
	 * 
134
	 * @param numColumns
135
	 *            the number of columns in the grid
136
	 * @param makeColumnsEqualWidth
137
	 *            whether or not the columns will have equal width
138
	 * 
139
	 */
140
	public GridLayout(int numColumns, boolean makeColumnsEqualWidth) {
141
		this.numColumns = numColumns;
142
		this.makeColumnsEqualWidth = makeColumnsEqualWidth;
143
	}
144

    
145
	/**
146
	 * @param child
147
	 * @param wHint
148
	 * @param hHint
149
	 * @return the child size.
150
	 */
151
	protected Dimension getChildSize(IFigure child, int wHint, int hHint) {
152
		return child.getPreferredSize(wHint, hHint);
153
	}
154

    
155
	GridData getData(IFigure[][] grid, int row, int column, int rowCount,
156
			int columnCount, boolean first) {
157
		IFigure figure = grid[row][column];
158
		if (figure != null) {
159
			GridData data = (GridData) getConstraint(figure);
160
			int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount));
161
			int vSpan = Math.max(1, data.verticalSpan);
162
			int i = first ? row + vSpan - 1 : row - vSpan + 1;
163
			int j = first ? column + hSpan - 1 : column - hSpan + 1;
164
			if (0 <= i && i < rowCount) {
165
				if (0 <= j && j < columnCount) {
166
					if (figure == grid[i][j])
167
						return data;
168
				}
169
			}
170
		}
171
		return null;
172
	}
173

    
174
	void initChildren(IFigure container) {
175
		List children = container.getChildren();
176
		for (int i = 0; i < children.size(); i++) {
177
			IFigure child = (IFigure) children.get(i);
178
			if (child.getLayoutManager() == null)
179
				child.setLayoutManager(this);
180
		}
181
	}
182

    
183
	/*
184
	 * (non-Javadoc)
185
	 * 
186
	 * @see
187
	 * org.eclipse.draw2d.AbstractLayout#calculatePreferredSize(org.eclipse.
188
	 * draw2d.IFigure, int, int)
189
	 */
190
	protected Dimension calculatePreferredSize(IFigure container, int wHint,
191
			int hHint) {
192
		Dimension size = layout(container, false, 0, 0, wHint, hHint, /* flushCache */
193
		true);
194
		if (wHint != SWT.DEFAULT)
195
			size.width = wHint;
196
		if (hHint != SWT.DEFAULT)
197
			size.height = hHint;
198

    
199
		/*
200
		 * Adjust for the size of the border
201
		 */
202
		size.expand(container.getInsets().getWidth(), container.getInsets()
203
				.getHeight());
204
		size.union(getBorderPreferredSize(container));
205

    
206
		return size;
207
	}
208

    
209
	/*
210
	 * (non-Javadoc)
211
	 * 
212
	 * @see org.eclipse.draw2d.LayoutManager#layout(org.eclipse.draw2d.IFigure)
213
	 */
214
	public void layout(IFigure container) {
215
		// initChildren( container);
216
		Rectangle rect = container.getClientArea();
217
		layout(container, true, rect.x, rect.y, rect.width, rect.height, /* flushCache */
218
		true);
219

    
220
	}
221

    
222
	Dimension layout(IFigure container, boolean move, int x, int y, int width,
223
			int height, boolean flushCache) {
224
		if (numColumns < 1)
225
			return new Dimension(marginWidth * 2, marginHeight * 2);
226
		List children = container.getChildren();
227
		for (int i = 0; i < children.size(); i++) {
228
			IFigure child = (IFigure) children.get(i);
229

    
230
			GridData data = (GridData) getConstraint(child);
231
			if (data == null)
232
				setConstraint(child, data = new GridData());
233
			if (flushCache)
234
				data.flushCache();
235
			data.computeSize(child, flushCache);
236
		}
237

    
238
		/* Build the grid */
239
		int row = 0, column = 0, rowCount = 0, columnCount = numColumns;
240
		IFigure[][] grid = new IFigure[4][columnCount];
241
		for (int i = 0; i < children.size(); i++) {
242
			IFigure child = (IFigure) children.get(i);
243
			GridData data = (GridData) getConstraint(child);
244
			int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount));
245
			int vSpan = Math.max(1, data.verticalSpan);
246
			while (true) {
247
				int lastRow = row + vSpan;
248
				if (lastRow >= grid.length) {
249
					IFigure[][] newGrid = new IFigure[lastRow + 4][columnCount];
250
					System.arraycopy(grid, 0, newGrid, 0, grid.length);
251
					grid = newGrid;
252
				}
253
				if (grid[row] == null) {
254
					grid[row] = new IFigure[columnCount];
255
				}
256
				while (column < columnCount && grid[row][column] != null) {
257
					column++;
258
				}
259
				int endCount = column + hSpan;
260
				if (endCount <= columnCount) {
261
					int index = column;
262
					while (index < endCount && grid[row][index] == null) {
263
						index++;
264
					}
265
					if (index == endCount)
266
						break;
267
					column = index;
268
				}
269
				if (column + hSpan >= columnCount) {
270
					column = 0;
271
					row++;
272
				}
273
			}
274
			for (int j = 0; j < vSpan; j++) {
275
				if (grid[row + j] == null) {
276
					grid[row + j] = new IFigure[columnCount];
277
				}
278
				for (int k = 0; k < hSpan; k++) {
279
					grid[row + j][column + k] = child;
280
				}
281
			}
282
			rowCount = Math.max(rowCount, row + vSpan);
283
			column += hSpan;
284
		}
285

    
286
		/* Column widths */
287
		int availableWidth = width - horizontalSpacing * (columnCount - 1)
288
				- marginWidth * 2;
289
		int expandCount = 0;
290
		int[] widths = new int[columnCount];
291
		int[] minWidths = new int[columnCount];
292
		boolean[] expandColumn = new boolean[columnCount];
293
		for (int j = 0; j < columnCount; j++) {
294
			for (int i = 0; i < rowCount; i++) {
295
				GridData data = getData(grid, i, j, rowCount, columnCount, true);
296
				if (data != null) {
297
					int hSpan = Math.max(1,
298
							Math.min(data.horizontalSpan, columnCount));
299
					if (hSpan == 1) {
300
						int w = data.cacheWidth + data.horizontalIndent;
301
						widths[j] = Math.max(widths[j], w);
302
						if (data.grabExcessHorizontalSpace) {
303
							if (!expandColumn[j])
304
								expandCount++;
305
							expandColumn[j] = true;
306
						}
307
						if (data.widthHint != SWT.DEFAULT
308
								|| !data.grabExcessHorizontalSpace) {
309
							minWidths[j] = Math.max(minWidths[j], w);
310
						}
311
					}
312
				}
313
			}
314
			for (int i = 0; i < rowCount; i++) {
315
				GridData data = getData(grid, i, j, rowCount, columnCount,
316
						false);
317
				if (data != null) {
318
					int hSpan = Math.max(1,
319
							Math.min(data.horizontalSpan, columnCount));
320
					if (hSpan > 1) {
321
						int spanWidth = 0, spanMinWidth = 0, spanExpandCount = 0;
322
						for (int k = 0; k < hSpan; k++) {
323
							spanWidth += widths[j - k];
324
							spanMinWidth += minWidths[j - k];
325
							if (expandColumn[j - k])
326
								spanExpandCount++;
327
						}
328
						if (data.grabExcessHorizontalSpace
329
								&& spanExpandCount == 0) {
330
							expandCount++;
331
							expandColumn[j] = true;
332
						}
333
						int w = data.cacheWidth + data.horizontalIndent
334
								- spanWidth - (hSpan - 1) * horizontalSpacing;
335
						if (w > 0) {
336
							if (spanExpandCount == 0) {
337
								widths[j] += w;
338
							} else {
339
								int delta = w / spanExpandCount;
340
								int remainder = w % spanExpandCount, last = -1;
341
								for (int k = 0; k < hSpan; k++) {
342
									if (expandColumn[j - k]) {
343
										widths[last = j - k] += delta;
344
									}
345
								}
346
								if (last > -1)
347
									widths[last] += remainder;
348
							}
349
						}
350
						if (data.widthHint != SWT.DEFAULT
351
								|| !data.grabExcessHorizontalSpace) {
352
							w = data.cacheWidth + data.horizontalIndent
353
									- spanMinWidth - (hSpan - 1)
354
									* horizontalSpacing;
355
							if (w > 0) {
356
								if (spanExpandCount == 0) {
357
									minWidths[j] += w;
358
								} else {
359
									int delta = w / spanExpandCount;
360
									int remainder = w % spanExpandCount, last = -1;
361
									for (int k = 0; k < hSpan; k++) {
362
										if (expandColumn[j - k]) {
363
											minWidths[last = j - k] += delta;
364
										}
365
									}
366
									if (last > -1)
367
										minWidths[last] += remainder;
368
								}
369
							}
370
						}
371
					}
372
				}
373
			}
374
		}
375
		if (makeColumnsEqualWidth) {
376
			int minColumnWidth = 0;
377
			int columnWidth = 0;
378
			for (int i = 0; i < columnCount; i++) {
379
				minColumnWidth = Math.max(minColumnWidth, minWidths[i]);
380
				columnWidth = Math.max(columnWidth, widths[i]);
381
			}
382
			columnWidth = width == SWT.DEFAULT || expandCount == 0 ? columnWidth
383
					: Math.max(minColumnWidth, availableWidth / columnCount);
384
			for (int i = 0; i < columnCount; i++) {
385
				expandColumn[i] = expandCount > 0;
386
				widths[i] = columnWidth;
387
			}
388
		} else {
389
			if (width != SWT.DEFAULT && expandCount > 0) {
390
				int totalWidth = 0;
391
				for (int i = 0; i < columnCount; i++) {
392
					totalWidth += widths[i];
393
				}
394
				int count = expandCount;
395
				int delta = (availableWidth - totalWidth) / count;
396
				int remainder = (availableWidth - totalWidth) % count;
397
				int last = -1;
398
				while (totalWidth != availableWidth) {
399
					for (int j = 0; j < columnCount; j++) {
400
						if (expandColumn[j]) {
401
							if (widths[j] + delta > minWidths[j]) {
402
								widths[last = j] = widths[j] + delta;
403
							} else {
404
								widths[j] = minWidths[j];
405
								expandColumn[j] = false;
406
								count--;
407
							}
408
						}
409
					}
410
					if (last > -1)
411
						widths[last] += remainder;
412

    
413
					for (int j = 0; j < columnCount; j++) {
414
						for (int i = 0; i < rowCount; i++) {
415
							GridData data = getData(grid, i, j, rowCount,
416
									columnCount, false);
417
							if (data != null) {
418
								int hSpan = Math.max(1, Math.min(
419
										data.horizontalSpan, columnCount));
420
								if (hSpan > 1) {
421
									if (data.widthHint != SWT.DEFAULT
422
											|| !data.grabExcessHorizontalSpace) {
423
										int spanWidth = 0, spanExpandCount = 0;
424
										for (int k = 0; k < hSpan; k++) {
425
											spanWidth += widths[j - k];
426
											if (expandColumn[j - k])
427
												spanExpandCount++;
428
										}
429
										int w = data.cacheWidth
430
												+ data.horizontalIndent
431
												- spanWidth - (hSpan - 1)
432
												* horizontalSpacing;
433
										if (w > 0) {
434
											if (spanExpandCount == 0) {
435
												widths[j] += w;
436
											} else {
437
												int delta2 = w
438
														/ spanExpandCount;
439
												int remainder2 = w
440
														% spanExpandCount, last2 = -1;
441
												for (int k = 0; k < hSpan; k++) {
442
													if (expandColumn[j - k]) {
443
														widths[last2 = j - k] += delta2;
444
													}
445
												}
446
												if (last2 > -1)
447
													widths[last2] += remainder2;
448
											}
449
										}
450
									}
451
								}
452
							}
453
						}
454
					}
455
					if (count == 0)
456
						break;
457
					totalWidth = 0;
458
					for (int i = 0; i < columnCount; i++) {
459
						totalWidth += widths[i];
460
					}
461
					delta = (availableWidth - totalWidth) / count;
462
					remainder = (availableWidth - totalWidth) % count;
463
					last = -1;
464
				}
465
			}
466
		}
467

    
468
		/* Wrapping */
469
		GridData[] flush = null;
470
		int flushLength = 0;
471
		if (width != SWT.DEFAULT) {
472
			for (int j = 0; j < columnCount; j++) {
473
				for (int i = 0; i < rowCount; i++) {
474
					GridData data = getData(grid, i, j, rowCount, columnCount,
475
							false);
476
					if (data != null) {
477
						if (data.heightHint == SWT.DEFAULT) {
478
							IFigure child = grid[i][j];
479
							// TEMPORARY CODE
480
							int hSpan = Math.max(1,
481
									Math.min(data.horizontalSpan, columnCount));
482
							int currentWidth = 0;
483
							for (int k = 0; k < hSpan; k++) {
484
								currentWidth += widths[j - k];
485
							}
486
							currentWidth += (hSpan - 1) * horizontalSpacing
487
									- data.horizontalIndent;
488
							if ((currentWidth != data.cacheWidth && data.horizontalAlignment == SWT.FILL)
489
									|| (data.cacheWidth > currentWidth)) {
490
								int trim = 0;
491
								/*
492
								 * // *Note*: Left this in place from SWT //
493
								 * GridLayout. Not sure if Draw2D Borders or //
494
								 * Scrollbars 'trim' will need to be takeninto
495
								 * account.
496
								 * 
497
								 * if (child instanceof Group) { Group g
498
								 * =(Group)child; trim = g.getSize ().x -
499
								 * g.getClientArea ().width; } else if (child
500
								 * instanceof Scrollable) { Rectangle rect =
501
								 * ((Scrollable) child).computeTrim (0, 0, 0,0);
502
								 * trim = rect.width; } else { trim =
503
								 * child.getBorderWidth () * 2; }
504
								 */
505
								int oldWidthHint = data.widthHint;
506
								data.widthHint = Math.max(0, currentWidth
507
										- trim);
508
								data.cacheWidth = data.cacheHeight = SWT.DEFAULT;
509
								data.computeSize(child, false);
510
								data.widthHint = oldWidthHint;
511
								if (flush == null)
512
									flush = new GridData[children.size()];
513
								flush[flushLength++] = data;
514
							}
515
						}
516
					}
517
				}
518
			}
519
		}
520

    
521
		/* Row heights */
522
		int availableHeight = height - verticalSpacing * (rowCount - 1)
523
				- marginHeight * 2;
524
		expandCount = 0;
525
		int[] heights = new int[rowCount];
526
		int[] minHeights = new int[rowCount];
527
		boolean[] expandRow = new boolean[rowCount];
528
		for (int i = 0; i < rowCount; i++) {
529
			for (int j = 0; j < columnCount; j++) {
530
				GridData data = getData(grid, i, j, rowCount, columnCount, true);
531
				if (data != null) {
532
					int vSpan = Math.max(1,
533
							Math.min(data.verticalSpan, rowCount));
534
					if (vSpan == 1) {
535
						int h = data.cacheHeight; // + data.verticalIndent;
536
						heights[i] = Math.max(heights[i], h);
537
						if (data.grabExcessVerticalSpace) {
538
							if (!expandRow[i])
539
								expandCount++;
540
							expandRow[i] = true;
541
						}
542
						if (data.heightHint != SWT.DEFAULT
543
								|| !data.grabExcessVerticalSpace) {
544
							minHeights[i] = Math.max(minHeights[i], h);
545
						}
546
					}
547
				}
548
			}
549
			for (int j = 0; j < columnCount; j++) {
550
				GridData data = getData(grid, i, j, rowCount, columnCount,
551
						false);
552
				if (data != null) {
553
					int vSpan = Math.max(1,
554
							Math.min(data.verticalSpan, rowCount));
555
					if (vSpan > 1) {
556
						int spanHeight = 0, spanMinHeight = 0, spanExpandCount = 0;
557
						for (int k = 0; k < vSpan; k++) {
558
							spanHeight += heights[i - k];
559
							spanMinHeight += minHeights[i - k];
560
							if (expandRow[i - k])
561
								spanExpandCount++;
562
						}
563
						if (data.grabExcessVerticalSpace
564
								&& spanExpandCount == 0) {
565
							expandCount++;
566
							expandRow[i] = true;
567
						}
568
						int h = data.cacheHeight - spanHeight - (vSpan - 1)
569
								* verticalSpacing; // + data.verticalalIndent
570
						if (h > 0) {
571
							if (spanExpandCount == 0) {
572
								heights[i] += h;
573
							} else {
574
								int delta = h / spanExpandCount;
575
								int remainder = h % spanExpandCount, last = -1;
576
								for (int k = 0; k < vSpan; k++) {
577
									if (expandRow[i - k]) {
578
										heights[last = i - k] += delta;
579
									}
580
								}
581
								if (last > -1)
582
									heights[last] += remainder;
583
							}
584
						}
585
						if (data.heightHint != SWT.DEFAULT
586
								|| !data.grabExcessVerticalSpace) {
587
							h = data.cacheHeight - spanMinHeight - (vSpan - 1)
588
									* verticalSpacing; // + data.verticalIndent
589
							if (h > 0) {
590
								if (spanExpandCount == 0) {
591
									minHeights[i] += h;
592
								} else {
593
									int delta = h / spanExpandCount;
594
									int remainder = h % spanExpandCount, last = -1;
595
									for (int k = 0; k < vSpan; k++) {
596
										if (expandRow[i - k]) {
597
											minHeights[last = i - k] += delta;
598
										}
599
									}
600
									if (last > -1)
601
										minHeights[last] += remainder;
602
								}
603
							}
604
						}
605
					}
606
				}
607
			}
608
		}
609
		if (height != SWT.DEFAULT && expandCount > 0) {
610
			int totalHeight = 0;
611
			for (int i = 0; i < rowCount; i++) {
612
				totalHeight += heights[i];
613
			}
614
			int count = expandCount;
615
			int delta = (availableHeight - totalHeight) / count;
616
			int remainder = (availableHeight - totalHeight) % count;
617
			int last = -1;
618
			while (totalHeight != availableHeight) {
619
				for (int i = 0; i < rowCount; i++) {
620
					if (expandRow[i]) {
621
						if (heights[i] + delta > minHeights[i]) {
622
							heights[last = i] = heights[i] + delta;
623
						} else {
624
							heights[i] = minHeights[i];
625
							expandRow[i] = false;
626
							count--;
627
						}
628
					}
629
				}
630
				if (last > -1)
631
					heights[last] += remainder;
632

    
633
				for (int i = 0; i < rowCount; i++) {
634
					for (int j = 0; j < columnCount; j++) {
635
						GridData data = getData(grid, i, j, rowCount,
636
								columnCount, false);
637
						if (data != null) {
638
							int vSpan = Math.max(1,
639
									Math.min(data.verticalSpan, rowCount));
640
							if (vSpan > 1) {
641
								if (data.heightHint != SWT.DEFAULT
642
										|| !data.grabExcessVerticalSpace) {
643
									int spanHeight = 0, spanExpandCount = 0;
644
									for (int k = 0; k < vSpan; k++) {
645
										spanHeight += heights[i - k];
646
										if (expandRow[i - k])
647
											spanExpandCount++;
648
									}
649
									int h = data.cacheHeight - spanHeight
650
											- (vSpan - 1) * verticalSpacing; // +
651
									// data.verticalIndent
652
									if (h > 0) {
653
										if (spanExpandCount == 0) {
654
											heights[i] += h;
655
										} else {
656
											int delta2 = h / spanExpandCount;
657
											int remainder2 = h
658
													% spanExpandCount, last2 = -1;
659
											for (int k = 0; k < vSpan; k++) {
660
												if (expandRow[i - k]) {
661
													heights[last2 = i - k] += delta2;
662
												}
663
											}
664
											if (last2 > -1)
665
												heights[last2] += remainder2;
666
										}
667
									}
668
								}
669
							}
670
						}
671
					}
672
				}
673
				if (count == 0)
674
					break;
675
				totalHeight = 0;
676
				for (int i = 0; i < rowCount; i++) {
677
					totalHeight += heights[i];
678
				}
679
				delta = (availableHeight - totalHeight) / count;
680
				remainder = (availableHeight - totalHeight) % count;
681
				last = -1;
682
			}
683
		}
684

    
685
		/* Position the IFigures */
686
		if (move) {
687
			int gridY = y + marginHeight;
688
			for (int i = 0; i < rowCount; i++) {
689
				int gridX = x + marginWidth;
690
				for (int j = 0; j < columnCount; j++) {
691
					GridData data = getData(grid, i, j, rowCount, columnCount,
692
							true);
693
					if (data != null) {
694
						int hSpan = Math.max(1,
695
								Math.min(data.horizontalSpan, columnCount));
696
						int vSpan = Math.max(1, data.verticalSpan);
697
						int cellWidth = 0, cellHeight = 0;
698
						for (int k = 0; k < hSpan; k++) {
699
							cellWidth += widths[j + k];
700
						}
701
						for (int k = 0; k < vSpan; k++) {
702
							cellHeight += heights[i + k];
703
						}
704
						cellWidth += horizontalSpacing * (hSpan - 1);
705
						int childX = gridX + data.horizontalIndent;
706
						int childWidth = Math.min(data.cacheWidth, cellWidth);
707
						switch (data.horizontalAlignment) {
708
						case SWT.CENTER:
709
						case GridData.CENTER:
710
							childX = gridX
711
									+ Math.max(0, (cellWidth - childWidth) / 2);
712
							break;
713
						case SWT.RIGHT:
714
						case SWT.END:
715
						case GridData.END:
716
							childX = gridX
717
									+ Math.max(0, cellWidth - childWidth);
718
							break;
719
						case SWT.FILL:
720
							childWidth = cellWidth - data.horizontalIndent;
721
							break;
722
						}
723
						cellHeight += verticalSpacing * (vSpan - 1);
724
						int childY = gridY; // + data.verticalIndent;
725
						int childHeight = Math
726
								.min(data.cacheHeight, cellHeight);
727
						switch (data.verticalAlignment) {
728
						case SWT.CENTER:
729
						case GridData.CENTER:
730
							childY = gridY
731
									+ Math.max(0,
732
											(cellHeight - childHeight) / 2);
733
							break;
734
						case SWT.BOTTOM:
735
						case SWT.END:
736
						case GridData.END:
737
							childY = gridY
738
									+ Math.max(0, cellHeight - childHeight);
739
							break;
740
						case SWT.FILL:
741
							childHeight = cellHeight; // -
742
							// data.verticalIndent;
743
							break;
744
						}
745
						IFigure child = grid[i][j];
746
						if (child != null) {
747
							// following param could be replaced by
748
							// Rectangle.SINGLETON
749
							child.setBounds(new Rectangle(childX, childY,
750
									childWidth, childHeight));
751
						}
752
					}
753
					gridX += widths[j] + horizontalSpacing;
754
				}
755
				gridY += heights[i] + verticalSpacing;
756
			}
757
		}
758

    
759
		// clean up cache
760
		for (int i = 0; i < flushLength; i++) {
761
			flush[i].cacheWidth = flush[i].cacheHeight = -1;
762
		}
763

    
764
		int totalDefaultWidth = 0;
765
		int totalDefaultHeight = 0;
766
		for (int i = 0; i < columnCount; i++) {
767
			totalDefaultWidth += widths[i];
768
		}
769
		for (int i = 0; i < rowCount; i++) {
770
			totalDefaultHeight += heights[i];
771
		}
772
		totalDefaultWidth += horizontalSpacing * (columnCount - 1)
773
				+ marginWidth * 2;
774
		totalDefaultHeight += verticalSpacing * (rowCount - 1) + marginHeight
775
				* 2;
776
		return new Dimension(totalDefaultWidth, totalDefaultHeight);
777
	}
778

    
779
	/*
780
	 * (non-Javadoc)
781
	 * 
782
	 * @see
783
	 * org.eclipse.draw2d.LayoutManager#getConstraint(org.eclipse.draw2d.IFigure
784
	 * )
785
	 */
786
	public Object getConstraint(IFigure child) {
787
		return constraints.get(child);
788
	}
789

    
790
	/**
791
	 * Sets the layout constraint of the given figure. The constraints can only
792
	 * be of type {@link GridData}.
793
	 * 
794
	 * @see LayoutManager#setConstraint(IFigure, Object)
795
	 */
796
	public void setConstraint(IFigure figure, Object newConstraint) {
797
		super.setConstraint(figure, newConstraint);
798
		if (newConstraint != null) {
799
			constraints.put(figure, newConstraint);
800

    
801
		}
802
	}
803

    
804
}
(81-81/171)