Added
Link Here
|
1 |
package org.eclipse.gmf.internal.codegen.draw2d; |
2 |
|
3 |
import java.util.HashMap; |
4 |
import java.util.List; |
5 |
import java.util.Map; |
6 |
|
7 |
import org.eclipse.draw2d.AbstractLayout; |
8 |
import org.eclipse.draw2d.IFigure; |
9 |
import org.eclipse.draw2d.LayoutManager; |
10 |
import org.eclipse.draw2d.geometry.Dimension; |
11 |
import org.eclipse.draw2d.geometry.Rectangle; |
12 |
import org.eclipse.swt.SWT; |
13 |
|
14 |
|
15 |
/** |
16 |
* Lays out children into a Grid arrangement in which overall aligment and |
17 |
* spacing can be configured, as well as specfic layout requirements for the |
18 |
* each individual member of the GridLayout. This layout is a Draw2D port of the |
19 |
* swt GridLayout. |
20 |
* |
21 |
* <code>GridLayout</code> has a number of configuration fields, and the |
22 |
* Figures it lays out can have an associated layout data object, called |
23 |
* <code>GridLayoutData</code> (similar to the swt GridLayoutData object). The power of |
24 |
* <code>GridLayout</code> lies in the ability to configure |
25 |
* <code>GridLayoutData</code> for each Figure in the layout. |
26 |
* <p> |
27 |
* The following code creates a container Figure managed by a |
28 |
* <code>GridLayout</code> with 2 columns, containing 3 RectangleFigure |
29 |
* shapes, the last of which has been given further layout instructions. |
30 |
* Note that it is the <code>GridLayout</code> method <code>setConstraint</code> |
31 |
* that binds the child <code>Figure</code> to its layout <code>GridLayoutData</code> object. |
32 |
* |
33 |
* <pre> |
34 |
* Figure container = new Figure(); |
35 |
* GridLayout gridLayout = new GridLayout(); |
36 |
* gridLayout.numColumns = 2; |
37 |
* container.setLayout(gridLayout); |
38 |
* |
39 |
* Shape rect; |
40 |
* rect = new RectangleFigure(); |
41 |
* container.add(rect); |
42 |
* |
43 |
* rect = new RectangleFigure(); |
44 |
* container.add(rect); |
45 |
* |
46 |
* rect = new RectangleFigure(); |
47 |
* GridLayoutData GridLayoutData = new GridLayoutData(); |
48 |
* GridLayoutData.widthHint = 150; |
49 |
* layout.setConstraint(rect, GridLayoutData); |
50 |
* |
51 |
* container.add(rect); |
52 |
* </pre> |
53 |
* |
54 |
* <p> |
55 |
* The <code>numColumns</code> field is the most important field in a |
56 |
* <code>GridLayout</code>. Widgets are laid out in columns from left to |
57 |
* right, and a new row is created when <code>numColumns</code>+ 1 figures |
58 |
* are added to the <code>Figure<code> parent container. |
59 |
* |
60 |
* @see GridLayoutData |
61 |
* |
62 |
* @author Asim Ullah |
63 |
* created: Sep 10, 2004 |
64 |
*/ |
65 |
public class GridLayout extends AbstractLayout { |
66 |
|
67 |
/** |
68 |
* numColumns specifies the number of cell columns in the layout. |
69 |
* |
70 |
* The default value is 1. |
71 |
*/ |
72 |
public int numColumns = 1; |
73 |
|
74 |
/** |
75 |
* makeColumnsEqualWidth specifies whether all columns in the layout will be |
76 |
* forced to have the same width. |
77 |
* |
78 |
* The default value is false. |
79 |
*/ |
80 |
public boolean makeColumnsEqualWidth = false; |
81 |
|
82 |
/** |
83 |
* marginWidth specifies the number of pixels of horizontal margin that will |
84 |
* be placed along the left and right edges of the layout. |
85 |
* |
86 |
* The default value is 5. |
87 |
*/ |
88 |
public int marginWidth = 5; |
89 |
|
90 |
/** |
91 |
* marginHeight specifies the number of pixels of vertical margin that will |
92 |
* be placed along the top and bottom edges of the layout. |
93 |
* |
94 |
* The default value is 5. |
95 |
*/ |
96 |
public int marginHeight = 5; |
97 |
|
98 |
/** |
99 |
* horizontalSpacing specifies the number of pixels between the right edge |
100 |
* of one cell and the left edge of its neighbouring cell to the right. |
101 |
* |
102 |
* The default value is 5. |
103 |
*/ |
104 |
public int horizontalSpacing = 5; |
105 |
|
106 |
/** |
107 |
* verticalSpacing specifies the number of pixels between the bottom edge of |
108 |
* one cell and the top edge of its neighbouring cell underneath. |
109 |
* |
110 |
* The default value is 5. |
111 |
*/ |
112 |
public int verticalSpacing = 5; |
113 |
|
114 |
/** The layout contraints */ |
115 |
protected Map constraints = new HashMap(); |
116 |
|
117 |
/** |
118 |
* Default Constructor |
119 |
*/ |
120 |
public GridLayout() { |
121 |
super(); |
122 |
} |
123 |
|
124 |
/** |
125 |
* Constructs a new instance of this class given the number of columns, and |
126 |
* whether or not the columns should be forced to have the same width. |
127 |
* |
128 |
* @param numColumns |
129 |
* the number of columns in the grid |
130 |
* @param makeColumnsEqualWidth |
131 |
* whether or not the columns will have equal width |
132 |
* |
133 |
*/ |
134 |
public GridLayout(int numColumns, boolean makeColumnsEqualWidth) { |
135 |
this.numColumns = numColumns; |
136 |
this.makeColumnsEqualWidth = makeColumnsEqualWidth; |
137 |
} |
138 |
|
139 |
/** |
140 |
* @param child |
141 |
* @param wHint |
142 |
* @param hHint |
143 |
* @return |
144 |
*/ |
145 |
protected Dimension getChildSize(IFigure child, int wHint, int hHint) { |
146 |
return child.getPreferredSize(wHint, hHint); |
147 |
} |
148 |
|
149 |
GridLayoutData getData(IFigure[][] grid, int row, int column, int rowCount, |
150 |
int columnCount, boolean first) { |
151 |
IFigure figure = grid[row][column]; |
152 |
if (figure != null) { |
153 |
GridLayoutData data = (GridLayoutData) getConstraint(figure); |
154 |
int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount)); |
155 |
int vSpan = Math.max(1, data.verticalSpan); |
156 |
int i = first ? row + vSpan - 1 : row - vSpan + 1; |
157 |
int j = first ? column + hSpan - 1 : column - hSpan + 1; |
158 |
if (0 <= i && i < rowCount) { |
159 |
if (0 <= j && j < columnCount) { |
160 |
if (figure == grid[i][j]) |
161 |
return data; |
162 |
} |
163 |
} |
164 |
} |
165 |
return null; |
166 |
} |
167 |
|
168 |
void initChildren(IFigure container) |
169 |
{ |
170 |
List children = container.getChildren(); |
171 |
for (int i = 0; i < children.size(); i++) { |
172 |
IFigure child = (IFigure) children.get(i); |
173 |
if (child.getLayoutManager()==null) |
174 |
child.setLayoutManager(this); |
175 |
} |
176 |
} |
177 |
|
178 |
/* |
179 |
* (non-Javadoc) |
180 |
* |
181 |
* @see org.eclipse.draw2d.AbstractLayout#calculatePreferredSize(org.eclipse.draw2d.IFigure, |
182 |
* int, int) |
183 |
*/ |
184 |
protected Dimension calculatePreferredSize(IFigure container, int wHint, |
185 |
int hHint) { |
186 |
Dimension size = layout(container, false, 0, 0, wHint, hHint, /* flushCache */ |
187 |
true); |
188 |
if (wHint != SWT.DEFAULT) |
189 |
size.width = wHint; |
190 |
if (hHint != SWT.DEFAULT) |
191 |
size.height = hHint; |
192 |
|
193 |
return size; |
194 |
} |
195 |
|
196 |
/* |
197 |
* (non-Javadoc) |
198 |
* |
199 |
* @see org.eclipse.draw2d.LayoutManager#layout(org.eclipse.draw2d.IFigure) |
200 |
*/ |
201 |
public void layout(IFigure container) { |
202 |
//initChildren( container); |
203 |
Rectangle rect = container.getClientArea(); |
204 |
layout(container, true, rect.x, rect.y, rect.width, rect.height, /* flushCache */ |
205 |
true); |
206 |
|
207 |
} |
208 |
|
209 |
Dimension layout(IFigure container, boolean move, int x, int y, int width, |
210 |
int height, boolean flushCache) { |
211 |
if (numColumns < 1) |
212 |
return new Dimension(marginWidth * 2, marginHeight * 2); |
213 |
List children = container.getChildren(); |
214 |
for (int i = 0; i < children.size(); i++) { |
215 |
IFigure child = (IFigure) children.get(i); |
216 |
|
217 |
GridLayoutData data = (GridLayoutData) getConstraint(child); |
218 |
if (data == null) |
219 |
setConstraint(child, data = new GridLayoutData()); |
220 |
if (flushCache) |
221 |
data.flushCache(); |
222 |
data.computeSize(child, flushCache); |
223 |
} |
224 |
|
225 |
/* Build the grid */ |
226 |
int row = 0, column = 0, rowCount = 0, columnCount = numColumns; |
227 |
IFigure[][] grid = new IFigure[4][columnCount]; |
228 |
for (int i = 0; i < children.size(); i++) { |
229 |
IFigure child = (IFigure) children.get(i); |
230 |
GridLayoutData data = (GridLayoutData) getConstraint(child); |
231 |
int hSpan = Math.max(1, Math.min(data.horizontalSpan, columnCount)); |
232 |
int vSpan = Math.max(1, data.verticalSpan); |
233 |
while (true) { |
234 |
int lastRow = row + vSpan; |
235 |
if (lastRow >= grid.length) { |
236 |
IFigure[][] newGrid = new IFigure[lastRow + 4][columnCount]; |
237 |
System.arraycopy(grid, 0, newGrid, 0, grid.length); |
238 |
grid = newGrid; |
239 |
} |
240 |
if (grid[row] == null) { |
241 |
grid[row] = new IFigure[columnCount]; |
242 |
} |
243 |
while (column < columnCount && grid[row][column] != null) { |
244 |
column++; |
245 |
} |
246 |
int endCount = column + hSpan; |
247 |
if (endCount <= columnCount) { |
248 |
int index = column; |
249 |
while (index < endCount && grid[row][index] == null) { |
250 |
index++; |
251 |
} |
252 |
if (index == endCount) |
253 |
break; |
254 |
column = index; |
255 |
} |
256 |
if (column + hSpan >= columnCount) { |
257 |
column = 0; |
258 |
row++; |
259 |
} |
260 |
} |
261 |
for (int j = 0; j < vSpan; j++) { |
262 |
if (grid[row + j] == null) { |
263 |
grid[row + j] = new IFigure[columnCount]; |
264 |
} |
265 |
for (int k = 0; k < hSpan; k++) { |
266 |
grid[row + j][column + k] = child; |
267 |
} |
268 |
} |
269 |
rowCount = Math.max(rowCount, row + vSpan); |
270 |
column += hSpan; |
271 |
} |
272 |
|
273 |
/* Column widths */ |
274 |
int availableWidth = width - horizontalSpacing * (columnCount - 1) |
275 |
- marginWidth * 2; |
276 |
int expandCount = 0; |
277 |
int[] widths = new int[columnCount]; |
278 |
int[] minWidths = new int[columnCount]; |
279 |
boolean[] expandColumn = new boolean[columnCount]; |
280 |
for (int j = 0; j < columnCount; j++) { |
281 |
for (int i = 0; i < rowCount; i++) { |
282 |
GridLayoutData data = getData(grid, i, j, rowCount, columnCount, true); |
283 |
if (data != null) { |
284 |
int hSpan = Math.max(1, Math.min(data.horizontalSpan, |
285 |
columnCount)); |
286 |
if (hSpan == 1) { |
287 |
int w = data.cacheWidth + data.horizontalIndent; |
288 |
widths[j] = Math.max(widths[j], w); |
289 |
if (data.grabExcessHorizontalSpace) { |
290 |
if (!expandColumn[j]) |
291 |
expandCount++; |
292 |
expandColumn[j] = true; |
293 |
} |
294 |
if (data.widthHint != SWT.DEFAULT |
295 |
|| !data.grabExcessHorizontalSpace) { |
296 |
minWidths[j] = Math.max(minWidths[j], w); |
297 |
} |
298 |
} |
299 |
} |
300 |
} |
301 |
for (int i = 0; i < rowCount; i++) { |
302 |
GridLayoutData data = getData(grid, i, j, rowCount, columnCount, |
303 |
false); |
304 |
if (data != null) { |
305 |
int hSpan = Math.max(1, Math.min(data.horizontalSpan, |
306 |
columnCount)); |
307 |
if (hSpan > 1) { |
308 |
int spanWidth = 0, spanMinWidth = 0, spanExpandCount = 0; |
309 |
for (int k = 0; k < hSpan; k++) { |
310 |
spanWidth += widths[j - k]; |
311 |
spanMinWidth += minWidths[j - k]; |
312 |
if (expandColumn[j - k]) |
313 |
spanExpandCount++; |
314 |
} |
315 |
if (data.grabExcessHorizontalSpace |
316 |
&& spanExpandCount == 0) { |
317 |
expandCount++; |
318 |
expandColumn[j] = true; |
319 |
} |
320 |
int w = data.cacheWidth + data.horizontalIndent |
321 |
- spanWidth - (hSpan - 1) * horizontalSpacing; |
322 |
if (w > 0) { |
323 |
if (spanExpandCount == 0) { |
324 |
widths[j] += w; |
325 |
} else { |
326 |
int delta = w / spanExpandCount; |
327 |
int remainder = w % spanExpandCount, last = -1; |
328 |
for (int k = 0; k < hSpan; k++) { |
329 |
if (expandColumn[j - k]) { |
330 |
widths[last = j - k] += delta; |
331 |
} |
332 |
} |
333 |
if (last > -1) |
334 |
widths[last] += remainder; |
335 |
} |
336 |
} |
337 |
if (data.widthHint != SWT.DEFAULT |
338 |
|| !data.grabExcessHorizontalSpace) { |
339 |
w = data.cacheWidth + data.horizontalIndent |
340 |
- spanMinWidth - (hSpan - 1) |
341 |
* horizontalSpacing; |
342 |
if (w > 0) { |
343 |
if (spanExpandCount == 0) { |
344 |
minWidths[j] += w; |
345 |
} else { |
346 |
int delta = w / spanExpandCount; |
347 |
int remainder = w % spanExpandCount, last = -1; |
348 |
for (int k = 0; k < hSpan; k++) { |
349 |
if (expandColumn[j - k]) { |
350 |
minWidths[last = j - k] += delta; |
351 |
} |
352 |
} |
353 |
if (last > -1) |
354 |
minWidths[last] += remainder; |
355 |
} |
356 |
} |
357 |
} |
358 |
} |
359 |
} |
360 |
} |
361 |
} |
362 |
if (makeColumnsEqualWidth) { |
363 |
int minColumnWidth = 0; |
364 |
int columnWidth = 0; |
365 |
for (int i = 0; i < columnCount; i++) { |
366 |
minColumnWidth = Math.max(minColumnWidth, minWidths[i]); |
367 |
columnWidth = Math.max(columnWidth, widths[i]); |
368 |
} |
369 |
columnWidth = width == SWT.DEFAULT || expandCount == 0 |
370 |
? columnWidth |
371 |
: Math.max(minColumnWidth, availableWidth / columnCount); |
372 |
for (int i = 0; i < columnCount; i++) { |
373 |
expandColumn[i] = expandCount > 0; |
374 |
widths[i] = columnWidth; |
375 |
} |
376 |
} else { |
377 |
if (width != SWT.DEFAULT && expandCount > 0) { |
378 |
int totalWidth = 0; |
379 |
for (int i = 0; i < columnCount; i++) { |
380 |
totalWidth += widths[i]; |
381 |
} |
382 |
int count = expandCount; |
383 |
int delta = (availableWidth - totalWidth) / count; |
384 |
int remainder = (availableWidth - totalWidth) % count; |
385 |
int last = -1; |
386 |
while (totalWidth != availableWidth) { |
387 |
for (int j = 0; j < columnCount; j++) { |
388 |
if (expandColumn[j]) { |
389 |
if (widths[j] + delta > minWidths[j]) { |
390 |
widths[last = j] = widths[j] + delta; |
391 |
} else { |
392 |
widths[j] = minWidths[j]; |
393 |
expandColumn[j] = false; |
394 |
count--; |
395 |
} |
396 |
} |
397 |
} |
398 |
if (last > -1) |
399 |
widths[last] += remainder; |
400 |
|
401 |
for (int j = 0; j < columnCount; j++) { |
402 |
for (int i = 0; i < rowCount; i++) { |
403 |
GridLayoutData data = getData(grid, i, j, rowCount, |
404 |
columnCount, false); |
405 |
if (data != null) { |
406 |
int hSpan = Math.max(1, Math.min( |
407 |
data.horizontalSpan, columnCount)); |
408 |
if (hSpan > 1) { |
409 |
if (data.widthHint != SWT.DEFAULT |
410 |
|| !data.grabExcessHorizontalSpace) { |
411 |
int spanWidth = 0, spanExpandCount = 0; |
412 |
for (int k = 0; k < hSpan; k++) { |
413 |
spanWidth += widths[j - k]; |
414 |
if (expandColumn[j - k]) |
415 |
spanExpandCount++; |
416 |
} |
417 |
int w = data.cacheWidth |
418 |
+ data.horizontalIndent |
419 |
- spanWidth - (hSpan - 1) |
420 |
* horizontalSpacing; |
421 |
if (w > 0) { |
422 |
if (spanExpandCount == 0) { |
423 |
widths[j] += w; |
424 |
} else { |
425 |
int delta2 = w |
426 |
/ spanExpandCount; |
427 |
int remainder2 = w |
428 |
% spanExpandCount, last2 = -1; |
429 |
for (int k = 0; k < hSpan; k++) { |
430 |
if (expandColumn[j - k]) { |
431 |
widths[last2 = j - k] += delta2; |
432 |
} |
433 |
} |
434 |
if (last2 > -1) |
435 |
widths[last2] += remainder2; |
436 |
} |
437 |
} |
438 |
} |
439 |
} |
440 |
} |
441 |
} |
442 |
} |
443 |
if (count == 0) |
444 |
break; |
445 |
totalWidth = 0; |
446 |
for (int i = 0; i < columnCount; i++) { |
447 |
totalWidth += widths[i]; |
448 |
} |
449 |
delta = (availableWidth - totalWidth) / count; |
450 |
remainder = (availableWidth - totalWidth) % count; |
451 |
last = -1; |
452 |
} |
453 |
} |
454 |
} |
455 |
|
456 |
/* Wrapping */ |
457 |
GridLayoutData[] flush = null; |
458 |
int flushLength = 0; |
459 |
if (width != SWT.DEFAULT) { |
460 |
for (int j = 0; j < columnCount; j++) { |
461 |
for (int i = 0; i < rowCount; i++) { |
462 |
GridLayoutData data = getData(grid, i, j, rowCount, columnCount, |
463 |
false); |
464 |
if (data != null) { |
465 |
if (data.heightHint == SWT.DEFAULT) { |
466 |
IFigure child = grid[i][j]; |
467 |
//TEMPORARY CODE |
468 |
int hSpan = Math.max(1, Math.min( |
469 |
data.horizontalSpan, columnCount)); |
470 |
int currentWidth = 0; |
471 |
for (int k = 0; k < hSpan; k++) { |
472 |
currentWidth += widths[j - k]; |
473 |
} |
474 |
currentWidth += (hSpan - 1) * horizontalSpacing |
475 |
- data.horizontalIndent; |
476 |
if ((currentWidth != data.cacheWidth && data.horizontalAlignment == SWT.FILL) |
477 |
|| (data.cacheWidth > currentWidth)) { |
478 |
int trim = 0; |
479 |
/* |
480 |
// *Note*: Left this in place from SWT |
481 |
// GridLayout. Not sure if Draw2D Borders or |
482 |
// Scrollbars 'trim' will need to be takeninto account. |
483 |
|
484 |
if (child instanceof Group) { |
485 |
Group g =(Group)child; trim = g.getSize ().x - |
486 |
g.getClientArea ().width; |
487 |
} else if (child instanceof Scrollable) { |
488 |
Rectangle rect = |
489 |
((Scrollable) child).computeTrim (0, 0, 0,0); |
490 |
trim = rect.width; } |
491 |
else { |
492 |
trim = child.getBorderWidth () * 2; |
493 |
} |
494 |
*/ |
495 |
int oldWidthHint = data.widthHint; |
496 |
data.widthHint = Math.max(0, currentWidth |
497 |
- trim); |
498 |
data.cacheWidth = data.cacheHeight = SWT.DEFAULT; |
499 |
data.computeSize(child, false); |
500 |
data.widthHint = oldWidthHint; |
501 |
if (flush == null) |
502 |
flush = new GridLayoutData[children.size()]; |
503 |
flush[flushLength++] = data; |
504 |
} |
505 |
} |
506 |
} |
507 |
} |
508 |
} |
509 |
} |
510 |
|
511 |
/* Row heights */ |
512 |
int availableHeight = height - verticalSpacing * (rowCount - 1) |
513 |
- marginHeight * 2; |
514 |
expandCount = 0; |
515 |
int[] heights = new int[rowCount]; |
516 |
int[] minHeights = new int[rowCount]; |
517 |
boolean[] expandRow = new boolean[rowCount]; |
518 |
for (int i = 0; i < rowCount; i++) { |
519 |
for (int j = 0; j < columnCount; j++) { |
520 |
GridLayoutData data = getData(grid, i, j, rowCount, columnCount, true); |
521 |
if (data != null) { |
522 |
int vSpan = Math.max(1, Math.min(data.verticalSpan, |
523 |
rowCount)); |
524 |
if (vSpan == 1) { |
525 |
int h = data.cacheHeight; // + data.verticalIndent; |
526 |
heights[i] = Math.max(heights[i], h); |
527 |
if (data.grabExcessVerticalSpace) { |
528 |
if (!expandRow[i]) |
529 |
expandCount++; |
530 |
expandRow[i] = true; |
531 |
} |
532 |
if (data.heightHint != SWT.DEFAULT |
533 |
|| !data.grabExcessVerticalSpace) { |
534 |
minHeights[i] = Math.max(minHeights[i], h); |
535 |
} |
536 |
} |
537 |
} |
538 |
} |
539 |
for (int j = 0; j < columnCount; j++) { |
540 |
GridLayoutData data = getData(grid, i, j, rowCount, columnCount, |
541 |
false); |
542 |
if (data != null) { |
543 |
int vSpan = Math.max(1, Math.min(data.verticalSpan, |
544 |
rowCount)); |
545 |
if (vSpan > 1) { |
546 |
int spanHeight = 0, spanMinHeight = 0, spanExpandCount = 0; |
547 |
for (int k = 0; k < vSpan; k++) { |
548 |
spanHeight += heights[i - k]; |
549 |
spanMinHeight += minHeights[i - k]; |
550 |
if (expandRow[i - k]) |
551 |
spanExpandCount++; |
552 |
} |
553 |
if (data.grabExcessVerticalSpace |
554 |
&& spanExpandCount == 0) { |
555 |
expandCount++; |
556 |
expandRow[i] = true; |
557 |
} |
558 |
int h = data.cacheHeight - spanHeight - (vSpan - 1) |
559 |
* verticalSpacing; // + data.verticalalIndent |
560 |
if (h > 0) { |
561 |
if (spanExpandCount == 0) { |
562 |
heights[i] += h; |
563 |
} else { |
564 |
int delta = h / spanExpandCount; |
565 |
int remainder = h % spanExpandCount, last = -1; |
566 |
for (int k = 0; k < vSpan; k++) { |
567 |
if (expandRow[i - k]) { |
568 |
heights[last = i - k] += delta; |
569 |
} |
570 |
} |
571 |
if (last > -1) |
572 |
heights[last] += remainder; |
573 |
} |
574 |
} |
575 |
if (data.heightHint != SWT.DEFAULT |
576 |
|| !data.grabExcessVerticalSpace) { |
577 |
h = data.cacheHeight - spanMinHeight - (vSpan - 1) |
578 |
* verticalSpacing; // + data.verticalIndent |
579 |
if (h > 0) { |
580 |
if (spanExpandCount == 0) { |
581 |
minHeights[i] += h; |
582 |
} else { |
583 |
int delta = h / spanExpandCount; |
584 |
int remainder = h % spanExpandCount, last = -1; |
585 |
for (int k = 0; k < vSpan; k++) { |
586 |
if (expandRow[i - k]) { |
587 |
minHeights[last = i - k] += delta; |
588 |
} |
589 |
} |
590 |
if (last > -1) |
591 |
minHeights[last] += remainder; |
592 |
} |
593 |
} |
594 |
} |
595 |
} |
596 |
} |
597 |
} |
598 |
} |
599 |
if (height != SWT.DEFAULT && expandCount > 0) { |
600 |
int totalHeight = 0; |
601 |
for (int i = 0; i < rowCount; i++) { |
602 |
totalHeight += heights[i]; |
603 |
} |
604 |
int count = expandCount; |
605 |
int delta = (availableHeight - totalHeight) / count; |
606 |
int remainder = (availableHeight - totalHeight) % count; |
607 |
int last = -1; |
608 |
while (totalHeight != availableHeight) { |
609 |
for (int i = 0; i < rowCount; i++) { |
610 |
if (expandRow[i]) { |
611 |
if (heights[i] + delta > minHeights[i]) { |
612 |
heights[last = i] = heights[i] + delta; |
613 |
} else { |
614 |
heights[i] = minHeights[i]; |
615 |
expandRow[i] = false; |
616 |
count--; |
617 |
} |
618 |
} |
619 |
} |
620 |
if (last > -1) |
621 |
heights[last] += remainder; |
622 |
|
623 |
for (int i = 0; i < rowCount; i++) { |
624 |
for (int j = 0; j < columnCount; j++) { |
625 |
GridLayoutData data = getData(grid, i, j, rowCount, |
626 |
columnCount, false); |
627 |
if (data != null) { |
628 |
int vSpan = Math.max(1, Math.min(data.verticalSpan, |
629 |
rowCount)); |
630 |
if (vSpan > 1) { |
631 |
if (data.heightHint != SWT.DEFAULT |
632 |
|| !data.grabExcessVerticalSpace) { |
633 |
int spanHeight = 0, spanExpandCount = 0; |
634 |
for (int k = 0; k < vSpan; k++) { |
635 |
spanHeight += heights[i - k]; |
636 |
if (expandRow[i - k]) |
637 |
spanExpandCount++; |
638 |
} |
639 |
int h = data.cacheHeight - spanHeight |
640 |
- (vSpan - 1) * verticalSpacing; // + |
641 |
// data.verticalIndent |
642 |
if (h > 0) { |
643 |
if (spanExpandCount == 0) { |
644 |
heights[i] += h; |
645 |
} else { |
646 |
int delta2 = h / spanExpandCount; |
647 |
int remainder2 = h |
648 |
% spanExpandCount, last2 = -1; |
649 |
for (int k = 0; k < vSpan; k++) { |
650 |
if (expandRow[i - k]) { |
651 |
heights[last2 = i - k] += delta2; |
652 |
} |
653 |
} |
654 |
if (last2 > -1) |
655 |
heights[last2] += remainder2; |
656 |
} |
657 |
} |
658 |
} |
659 |
} |
660 |
} |
661 |
} |
662 |
} |
663 |
if (count == 0) |
664 |
break; |
665 |
totalHeight = 0; |
666 |
for (int i = 0; i < rowCount; i++) { |
667 |
totalHeight += heights[i]; |
668 |
} |
669 |
delta = (availableHeight - totalHeight) / count; |
670 |
remainder = (availableHeight - totalHeight) % count; |
671 |
last = -1; |
672 |
} |
673 |
} |
674 |
|
675 |
/* Position the IFigures */ |
676 |
if (move) { |
677 |
int gridY = y + marginHeight; |
678 |
for (int i = 0; i < rowCount; i++) { |
679 |
int gridX = x + marginWidth; |
680 |
for (int j = 0; j < columnCount; j++) { |
681 |
GridLayoutData data = getData(grid, i, j, rowCount, columnCount, |
682 |
true); |
683 |
if (data != null) { |
684 |
int hSpan = Math.max(1, Math.min(data.horizontalSpan, |
685 |
columnCount)); |
686 |
int vSpan = Math.max(1, data.verticalSpan); |
687 |
int cellWidth = 0, cellHeight = 0; |
688 |
for (int k = 0; k < hSpan; k++) { |
689 |
cellWidth += widths[j + k]; |
690 |
} |
691 |
for (int k = 0; k < vSpan; k++) { |
692 |
cellHeight += heights[i + k]; |
693 |
} |
694 |
cellWidth += horizontalSpacing * (hSpan - 1); |
695 |
int childX = gridX + data.horizontalIndent; |
696 |
int childWidth = Math.min(data.cacheWidth, cellWidth); |
697 |
switch (data.horizontalAlignment) { |
698 |
case SWT.CENTER : |
699 |
case GridLayoutData.CENTER : |
700 |
childX = gridX |
701 |
+ Math.max(0, |
702 |
(cellWidth - childWidth) / 2); |
703 |
break; |
704 |
case SWT.RIGHT : |
705 |
case SWT.END : |
706 |
case GridLayoutData.END : |
707 |
childX = gridX |
708 |
+ Math.max(0, cellWidth - childWidth); |
709 |
break; |
710 |
case SWT.FILL : |
711 |
childWidth = cellWidth - data.horizontalIndent; |
712 |
break; |
713 |
} |
714 |
cellHeight += verticalSpacing * (vSpan - 1); |
715 |
int childY = gridY; // + data.verticalIndent; |
716 |
int childHeight = Math |
717 |
.min(data.cacheHeight, cellHeight); |
718 |
switch (data.verticalAlignment) { |
719 |
case SWT.CENTER : |
720 |
case GridLayoutData.CENTER : |
721 |
childY = gridY |
722 |
+ Math.max(0, |
723 |
(cellHeight - childHeight) / 2); |
724 |
break; |
725 |
case SWT.BOTTOM : |
726 |
case SWT.END : |
727 |
case GridLayoutData.END : |
728 |
childY = gridY |
729 |
+ Math.max(0, cellHeight - childHeight); |
730 |
break; |
731 |
case SWT.FILL : |
732 |
childHeight = cellHeight; // - |
733 |
// data.verticalIndent; |
734 |
break; |
735 |
} |
736 |
IFigure child = grid[i][j]; |
737 |
if (child != null) { |
738 |
// following param could be replaced by |
739 |
// Rectangle.SINGLETON |
740 |
child.setBounds(new Rectangle(childX, childY, |
741 |
childWidth, childHeight)); |
742 |
} |
743 |
} |
744 |
gridX += widths[j] + horizontalSpacing; |
745 |
} |
746 |
gridY += heights[i] + verticalSpacing; |
747 |
} |
748 |
} |
749 |
|
750 |
// clean up cache |
751 |
for (int i = 0; i < flushLength; i++) { |
752 |
flush[i].cacheWidth = flush[i].cacheHeight = -1; |
753 |
} |
754 |
|
755 |
int totalDefaultWidth = 0; |
756 |
int totalDefaultHeight = 0; |
757 |
for (int i = 0; i < columnCount; i++) { |
758 |
totalDefaultWidth += widths[i]; |
759 |
} |
760 |
for (int i = 0; i < rowCount; i++) { |
761 |
totalDefaultHeight += heights[i]; |
762 |
} |
763 |
totalDefaultWidth += horizontalSpacing * (columnCount - 1) |
764 |
+ marginWidth * 2; |
765 |
totalDefaultHeight += verticalSpacing * (rowCount - 1) + marginHeight |
766 |
* 2; |
767 |
return new Dimension(totalDefaultWidth, totalDefaultHeight); |
768 |
} |
769 |
|
770 |
/* |
771 |
* (non-Javadoc) |
772 |
* |
773 |
* @see org.eclipse.draw2d.LayoutManager#getConstraint(org.eclipse.draw2d.IFigure) |
774 |
*/ |
775 |
public Object getConstraint(IFigure child) { |
776 |
return constraints.get(child); |
777 |
} |
778 |
|
779 |
/** |
780 |
* Sets the layout constraint of the given figure. The constraints can only |
781 |
* be of type {@link GridLayoutData}. |
782 |
* |
783 |
* @see LayoutManager#setConstraint(IFigure, Object) |
784 |
*/ |
785 |
public void setConstraint(IFigure figure, Object newConstraint) { |
786 |
super.setConstraint(figure, newConstraint); |
787 |
if (newConstraint != null) |
788 |
{ |
789 |
constraints.put(figure, newConstraint); |
790 |
|
791 |
} |
792 |
} |
793 |
|
794 |
} |