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
|
}
|