comparison org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/layout/RowLayout.d @ 0:6dd524f61e62

add dwt win and basic java stuff
author Frank Benoit <benoit@tionex.de>
date Mon, 02 Mar 2009 14:44:16 +0100
parents
children 6bf2837c50fe
comparison
equal deleted inserted replaced
-1:000000000000 0:6dd524f61e62
1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 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 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module org.eclipse.swt.layout.RowLayout;
14
15 import org.eclipse.swt.SWT;
16 import org.eclipse.swt.graphics.Point;
17 import org.eclipse.swt.graphics.Rectangle;
18 import org.eclipse.swt.widgets.Control;
19 import org.eclipse.swt.widgets.Layout;
20 import org.eclipse.swt.widgets.Composite;
21 import org.eclipse.swt.layout.RowData;
22 import tango.util.Convert;
23 import Math = tango.math.Math;
24 import java.lang.all;
25
26
27 /**
28 * Instances of this class determine the size and position of the
29 * children of a <code>Composite</code> by placing them either in
30 * horizontal rows or vertical columns within the parent <code>Composite</code>.
31 * <p>
32 * <code>RowLayout</code> aligns all controls in one row if the
33 * <code>type</code> is set to horizontal, and one column if it is
34 * set to vertical. It has the ability to wrap, and provides configurable
35 * margins and spacing. <code>RowLayout</code> has a number of configuration
36 * fields. In addition, the height and width of each control in a
37 * <code>RowLayout</code> can be specified by setting a <code>RowData</code>
38 * object into the control using <code>setLayoutData ()</code>.
39 * </p>
40 * <p>
41 * The following example code creates a <code>RowLayout</code>, sets all
42 * of its fields to non-default values, and then sets it into a
43 * <code>Shell</code>.
44 * <pre>
45 * RowLayout rowLayout = new RowLayout();
46 * rowLayout.wrap = false;
47 * rowLayout.pack = false;
48 * rowLayout.justify = true;
49 * rowLayout.type = SWT.VERTICAL;
50 * rowLayout.marginLeft = 5;
51 * rowLayout.marginTop = 5;
52 * rowLayout.marginRight = 5;
53 * rowLayout.marginBottom = 5;
54 * rowLayout.spacing = 0;
55 * shell.setLayout(rowLayout);
56 * </pre>
57 * If you are using the default field values, you only need one line of code:
58 * <pre>
59 * shell.setLayout(new RowLayout());
60 * </pre>
61 * </p>
62 *
63 * @see RowData
64 * @see <a href="http://www.eclipse.org/swt/snippets/#rowlayout">RowLayout snippets</a>
65 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: LayoutExample</a>
66 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
67 */
68 public final class RowLayout : Layout {
69
70 /**
71 * type specifies whether the layout places controls in rows or
72 * columns.
73 *
74 * The default value is HORIZONTAL.
75 *
76 * Possible values are: <ul>
77 * <li>HORIZONTAL: Position the controls horizontally from left to right</li>
78 * <li>VERTICAL: Position the controls vertically from top to bottom</li>
79 * </ul>
80 *
81 * @since 2.0
82 */
83 public int type = SWT.HORIZONTAL;
84
85 /**
86 * marginWidth specifies the number of pixels of horizontal margin
87 * that will be placed along the left and right edges of the layout.
88 *
89 * The default value is 0.
90 *
91 * @since 3.0
92 */
93 public int marginWidth = 0;
94
95 /**
96 * marginHeight specifies the number of pixels of vertical margin
97 * that will be placed along the top and bottom edges of the layout.
98 *
99 * The default value is 0.
100 *
101 * @since 3.0
102 */
103 public int marginHeight = 0;
104
105 /**
106 * spacing specifies the number of pixels between the edge of one cell
107 * and the edge of its neighbouring cell.
108 *
109 * The default value is 3.
110 */
111 public int spacing = 3;
112
113 /**
114 * wrap specifies whether a control will be wrapped to the next
115 * row if there is insufficient space on the current row.
116 *
117 * The default value is true.
118 */
119 public bool wrap = true;
120
121 /**
122 * pack specifies whether all controls in the layout take
123 * their preferred size. If pack is false, all controls will
124 * have the same size which is the size required to accommodate the
125 * largest preferred height and the largest preferred width of all
126 * the controls in the layout.
127 *
128 * The default value is true.
129 */
130 public bool pack = true;
131
132 /**
133 * fill specifies whether the controls in a row should be
134 * all the same height for horizontal layouts, or the same
135 * width for vertical layouts.
136 *
137 * The default value is false.
138 *
139 * @since 3.0
140 */
141 public bool fill = false;
142
143 /**
144 * center specifies whether the controls in a row should be
145 * centered vertically in each cell for horizontal layouts,
146 * or centered horizontally in each cell for vertical layouts.
147 *
148 * The default value is false.
149 *
150 * @since 3.4
151 */
152 public bool center = false;
153
154 /**
155 * justify specifies whether the controls in a row should be
156 * fully justified, with any extra space placed between the controls.
157 *
158 * The default value is false.
159 */
160 public bool justify = false;
161
162 /**
163 * marginLeft specifies the number of pixels of horizontal margin
164 * that will be placed along the left edge of the layout.
165 *
166 * The default value is 3.
167 */
168 public int marginLeft = 3;
169
170 /**
171 * marginTop specifies the number of pixels of vertical margin
172 * that will be placed along the top edge of the layout.
173 *
174 * The default value is 3.
175 */
176 public int marginTop = 3;
177
178 /**
179 * marginRight specifies the number of pixels of horizontal margin
180 * that will be placed along the right edge of the layout.
181 *
182 * The default value is 3.
183 */
184 public int marginRight = 3;
185
186 /**
187 * marginBottom specifies the number of pixels of vertical margin
188 * that will be placed along the bottom edge of the layout.
189 *
190 * The default value is 3.
191 */
192 public int marginBottom = 3;
193
194 /**
195 * Constructs a new instance of this class.
196 */
197 public this () {
198 }
199
200 /**
201 * Constructs a new instance of this class given the type.
202 *
203 * @param type the type of row layout
204 *
205 * @since 2.0
206 */
207 public this (int type) {
208 this.type = type;
209 }
210
211 override protected Point computeSize (Composite composite, int wHint, int hHint, bool flushCache_) {
212 Point extent;
213 if (type is SWT.HORIZONTAL) {
214 extent = layoutHorizontal (composite, false, (wHint !is SWT.DEFAULT) && wrap, wHint, flushCache_);
215 } else {
216 extent = layoutVertical (composite, false, (hHint !is SWT.DEFAULT) && wrap, hHint, flushCache_);
217 }
218 if (wHint !is SWT.DEFAULT) extent.x = wHint;
219 if (hHint !is SWT.DEFAULT) extent.y = hHint;
220 return extent;
221 }
222
223 Point computeSize (Control control, bool flushCache_) {
224 int wHint = SWT.DEFAULT, hHint = SWT.DEFAULT;
225 RowData data = cast(RowData) control.getLayoutData ();
226 if (data !is null) {
227 wHint = data.width;
228 hHint = data.height;
229 }
230 return control.computeSize (wHint, hHint, flushCache_);
231 }
232
233 override protected bool flushCache (Control control) {
234 return true;
235 }
236
237 String getName () {
238 String string = this.classinfo.name;
239 int index = string.lastIndexOf('.');
240 if (index is -1 ) return string;
241 return string[ index + 1 .. string.length ];
242 }
243
244 override protected void layout (Composite composite, bool flushCache_) {
245 Rectangle clientArea = composite.getClientArea ();
246 if (type is SWT.HORIZONTAL) {
247 layoutHorizontal (composite, true, wrap, clientArea.width, flushCache_);
248 } else {
249 layoutVertical (composite, true, wrap, clientArea.height, flushCache_);
250 }
251 }
252
253 Point layoutHorizontal (Composite composite, bool move, bool wrap, int width, bool flushCache_) {
254 Control [] children = composite.getChildren ();
255 int count = 0;
256 for (int i=0; i<children.length; i++) {
257 Control control = children [i];
258 RowData data = cast(RowData) control.getLayoutData ();
259 if (data is null || !data.exclude) {
260 children [count++] = children [i];
261 }
262 }
263 if (count is 0) {
264 return new Point (marginLeft + marginWidth * 2 + marginRight, marginTop + marginHeight * 2 + marginBottom);
265 }
266 int childWidth = 0, childHeight = 0, maxHeight = 0;
267 if (!pack) {
268 for (int i=0; i<count; i++) {
269 Control child = children [i];
270 Point size = computeSize (child, flushCache_);
271 childWidth = Math.max (childWidth, size.x);
272 childHeight = Math.max (childHeight, size.y);
273 }
274 maxHeight = childHeight;
275 }
276 int clientX = 0, clientY = 0;
277 if (move) {
278 Rectangle rect = composite.getClientArea ();
279 clientX = rect.x;
280 clientY = rect.y;
281 }
282 int [] wraps = null;
283 bool wrapped = false;
284 Rectangle [] bounds = null;
285 if (move && (justify || fill || center)) {
286 bounds = new Rectangle [count];
287 wraps = new int [count];
288 }
289 int maxX = 0, x = marginLeft + marginWidth, y = marginTop + marginHeight;
290 for (int i=0; i<count; i++) {
291 Control child = children [i];
292 if (pack) {
293 Point size = computeSize (child, flushCache_);
294 childWidth = size.x;
295 childHeight = size.y;
296 }
297 if (wrap && (i !is 0) && (x + childWidth > width)) {
298 wrapped = true;
299 if (move && (justify || fill || center)) wraps [i - 1] = maxHeight;
300 x = marginLeft + marginWidth;
301 y += spacing + maxHeight;
302 if (pack) maxHeight = 0;
303 }
304 if (pack || fill || center) {
305 maxHeight = Math.max (maxHeight, childHeight);
306 }
307 if (move) {
308 int childX = x + clientX, childY = y + clientY;
309 if (justify || fill || center) {
310 bounds [i] = new Rectangle (childX, childY, childWidth, childHeight);
311 } else {
312 child.setBounds (childX, childY, childWidth, childHeight);
313 }
314 }
315 x += spacing + childWidth;
316 maxX = Math.max (maxX, x);
317 }
318 maxX = Math.max (clientX + marginLeft + marginWidth, maxX - spacing);
319 if (!wrapped) maxX += marginRight + marginWidth;
320 if (move && (justify || fill || center)) {
321 int space = 0, margin = 0;
322 if (!wrapped) {
323 space = Math.max (0, (width - maxX) / (count + 1));
324 margin = Math.max (0, ((width - maxX) % (count + 1)) / 2);
325 } else {
326 if (fill || justify || center) {
327 int last = 0;
328 if (count > 0) wraps [count - 1] = maxHeight;
329 for (int i=0; i<count; i++) {
330 if (wraps [i] !is 0) {
331 int wrapCount = i - last + 1;
332 if (justify) {
333 int wrapX = 0;
334 for (int j=last; j<=i; j++) {
335 wrapX += bounds [j].width + spacing;
336 }
337 space = Math.max (0, (width - wrapX) / (wrapCount + 1));
338 margin = Math.max (0, ((width - wrapX) % (wrapCount + 1)) / 2);
339 }
340 for (int j=last; j<=i; j++) {
341 if (justify) bounds [j].x += (space * (j - last + 1)) + margin;
342 if (fill) {
343 bounds [j].height = wraps [i];
344 } else {
345 if (center) {
346 bounds [j].y += Math.max (0, (wraps [i] - bounds [j].height) / 2);
347 }
348 }
349 }
350 last = i + 1;
351 }
352 }
353 }
354 }
355 for (int i=0; i<count; i++) {
356 if (!wrapped) {
357 if (justify) bounds [i].x += (space * (i + 1)) + margin;
358 if (fill) {
359 bounds [i].height = maxHeight;
360 } else {
361 if (center) {
362 bounds [i].y += Math.max (0, (maxHeight - bounds [i].height) / 2);
363 }
364 }
365 }
366 children [i].setBounds (bounds [i]);
367 }
368 }
369 return new Point (maxX, y + maxHeight + marginBottom + marginHeight);
370 }
371
372 Point layoutVertical (Composite composite, bool move, bool wrap, int height, bool flushCache_) {
373 Control [] children = composite.getChildren ();
374 int count = 0;
375 for (int i=0; i<children.length; i++) {
376 Control control = children [i];
377 RowData data = cast(RowData) control.getLayoutData ();
378 if (data is null || !data.exclude) {
379 children [count++] = children [i];
380 }
381 }
382 if (count is 0) {
383 return new Point (marginLeft + marginWidth * 2 + marginRight, marginTop + marginHeight * 2 + marginBottom);
384 }
385 int childWidth = 0, childHeight = 0, maxWidth = 0;
386 if (!pack) {
387 for (int i=0; i<count; i++) {
388 Control child = children [i];
389 Point size = computeSize (child, flushCache_);
390 childWidth = Math.max (childWidth, size.x);
391 childHeight = Math.max (childHeight, size.y);
392 }
393 maxWidth = childWidth;
394 }
395 int clientX = 0, clientY = 0;
396 if (move) {
397 Rectangle rect = composite.getClientArea ();
398 clientX = rect.x;
399 clientY = rect.y;
400 }
401 int [] wraps = null;
402 bool wrapped = false;
403 Rectangle [] bounds = null;
404 if (move && (justify || fill || center)) {
405 bounds = new Rectangle [count];
406 wraps = new int [count];
407 }
408 int maxY = 0, x = marginLeft + marginWidth, y = marginTop + marginHeight;
409 for (int i=0; i<count; i++) {
410 Control child = children [i];
411 if (pack) {
412 Point size = computeSize (child, flushCache_);
413 childWidth = size.x;
414 childHeight = size.y;
415 }
416 if (wrap && (i !is 0) && (y + childHeight > height)) {
417 wrapped = true;
418 if (move && (justify || fill || center)) wraps [i - 1] = maxWidth;
419 x += spacing + maxWidth;
420 y = marginTop + marginHeight;
421 if (pack) maxWidth = 0;
422 }
423 if (pack || fill || center) {
424 maxWidth = Math.max (maxWidth, childWidth);
425 }
426 if (move) {
427 int childX = x + clientX, childY = y + clientY;
428 if (justify || fill || center) {
429 bounds [i] = new Rectangle (childX, childY, childWidth, childHeight);
430 } else {
431 child.setBounds (childX, childY, childWidth, childHeight);
432 }
433 }
434 y += spacing + childHeight;
435 maxY = Math.max (maxY, y);
436 }
437 maxY = Math.max (clientY + marginTop + marginHeight, maxY - spacing);
438 if (!wrapped) maxY += marginBottom + marginHeight;
439 if (move && (justify || fill || center)) {
440 int space = 0, margin = 0;
441 if (!wrapped) {
442 space = Math.max (0, (height - maxY) / (count + 1));
443 margin = Math.max (0, ((height - maxY) % (count + 1)) / 2);
444 } else {
445 if (fill || justify || center) {
446 int last = 0;
447 if (count > 0) wraps [count - 1] = maxWidth;
448 for (int i=0; i<count; i++) {
449 if (wraps [i] !is 0) {
450 int wrapCount = i - last + 1;
451 if (justify) {
452 int wrapY = 0;
453 for (int j=last; j<=i; j++) {
454 wrapY += bounds [j].height + spacing;
455 }
456 space = Math.max (0, (height - wrapY) / (wrapCount + 1));
457 margin = Math.max (0, ((height - wrapY) % (wrapCount + 1)) / 2);
458 }
459 for (int j=last; j<=i; j++) {
460 if (justify) bounds [j].y += (space * (j - last + 1)) + margin;
461 if (fill) {
462 bounds [j].width = wraps [i];
463 } else {
464 if (center) {
465 bounds [j].x += Math.max (0, (wraps [i] - bounds [j].width) / 2);
466 }
467 }
468 }
469 last = i + 1;
470 }
471 }
472 }
473 }
474 for (int i=0; i<count; i++) {
475 if (!wrapped) {
476 if (justify) bounds [i].y += (space * (i + 1)) + margin;
477 if (fill) {
478 bounds [i].width = maxWidth;
479 } else {
480 if (center) {
481 bounds [i].x += Math.max (0, (maxWidth - bounds [i].width) / 2);
482 }
483 }
484
485 }
486 children [i].setBounds (bounds [i]);
487 }
488 }
489 return new Point (x + maxWidth + marginRight + marginWidth, maxY);
490 }
491
492 /**
493 * Returns a string containing a concise, human-readable
494 * description of the receiver.
495 *
496 * @return a string representation of the layout
497 */
498 override public String toString () {
499 String string = getName ()~" {";
500 string ~= "type="~((type !is SWT.HORIZONTAL) ? "SWT.VERTICAL" : "SWT.HORIZONTAL")~" ";
501 if (marginWidth !is 0) string ~= "marginWidth="~to!(String)(marginWidth)~" ";
502 if (marginHeight !is 0) string ~= "marginHeight="~to!(String)(marginHeight)~" ";
503 if (marginLeft !is 0) string ~= "marginLeft="~to!(String)(marginLeft)~" ";
504 if (marginTop !is 0) string ~= "marginTop="~to!(String)(marginTop)~" ";
505 if (marginRight !is 0) string ~= "marginRight="~to!(String)(marginRight)~" ";
506 if (marginBottom !is 0) string ~= "marginBottom="~to!(String)(marginBottom)~" ";
507 if (spacing !is 0) string ~= "spacing="~to!(String)(spacing)~" ";
508 string ~= "wrap="~to!(String)(wrap)~" ";
509 string ~= "pack="~to!(String)(pack)~" ";
510 string ~= "fill="~to!(String)(fill)~" ";
511 string ~= "justify="~to!(String)(justify)~" ";
512 string = string.trim();
513 string ~= "}";
514 return string;
515 }
516 }