001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.layout;
011:
012: import org.eclipse.swt.*;
013: import org.eclipse.swt.graphics.*;
014: import org.eclipse.swt.widgets.*;
015:
016: /**
017: * <code>GridData</code> is the layout data object associated with
018: * <code>GridLayout</code>. To set a <code>GridData</code> object into a
019: * control, you use the <code>Control.setLayoutData(Object)</code> method.
020: * <p>
021: * There are two ways to create a <code>GridData</code> object with certain
022: * fields set. The first is to set the fields directly, like this:
023: * <pre>
024: * GridData gridData = new GridData();
025: * gridData.horizontalAlignment = GridData.FILL;
026: * gridData.grabExcessHorizontalSpace = true;
027: * button1.setLayoutData(gridData);
028: * </pre>
029: * The second is to take advantage of convenience style bits defined
030: * by <code>GridData</code>:
031: * <pre>
032: * button1.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
033: * </pre>
034: * </p>
035: * <p>
036: * NOTE: Do not reuse <code>GridData</code> objects. Every control in a
037: * <code>Composite</code> that is managed by a <code>GridLayout</code>
038: * must have a unique <code>GridData</code> object. If the layout data
039: * for a control in a <code>GridLayout</code> is null at layout time,
040: * a unique <code>GridData</code> object is created for it.
041: * </p>
042: *
043: * @see GridLayout
044: * @see Control#setLayoutData
045: */
046: public final class GridData {
047: /**
048: * verticalAlignment specifies how controls will be positioned
049: * vertically within a cell.
050: *
051: * The default value is CENTER.
052: *
053: * Possible values are: <ul>
054: * <li>SWT.BEGINNING (or SWT.TOP): Position the control at the top of the cell</li>
055: * <li>SWT.CENTER: Position the control in the vertical center of the cell</li>
056: * <li>SWT.END (or SWT.BOTTOM): Position the control at the bottom of the cell</li>
057: * <li>SWT.FILL: Resize the control to fill the cell vertically</li>
058: * </ul>
059: */
060: public int verticalAlignment = CENTER;
061:
062: /**
063: * horizontalAlignment specifies how controls will be positioned
064: * horizontally within a cell.
065: *
066: * The default value is BEGINNING.
067: *
068: * Possible values are: <ul>
069: * <li>SWT.BEGINNING (or SWT.LEFT): Position the control at the left of the cell</li>
070: * <li>SWT.CENTER: Position the control in the horizontal center of the cell</li>
071: * <li>SWT.END (or SWT.RIGHT): Position the control at the right of the cell</li>
072: * <li>SWT.FILL: Resize the control to fill the cell horizontally</li>
073: * </ul>
074: */
075: public int horizontalAlignment = BEGINNING;
076:
077: /**
078: * widthHint specifies the preferred width in pixels. This value
079: * is the wHint passed into Control.computeSize(int, int, boolean)
080: * to determine the preferred size of the control.
081: *
082: * The default value is SWT.DEFAULT.
083: *
084: * @see Control#computeSize(int, int, boolean)
085: */
086: public int widthHint = SWT.DEFAULT;
087:
088: /**
089: * heightHint specifies the preferred height in pixels. This value
090: * is the hHint passed into Control.computeSize(int, int, boolean)
091: * to determine the preferred size of the control.
092: *
093: * The default value is SWT.DEFAULT.
094: *
095: * @see Control#computeSize(int, int, boolean)
096: */
097: public int heightHint = SWT.DEFAULT;
098:
099: /**
100: * horizontalIndent specifies the number of pixels of indentation
101: * that will be placed along the left side of the cell.
102: *
103: * The default value is 0.
104: */
105: public int horizontalIndent = 0;
106:
107: /**
108: * verticalIndent specifies the number of pixels of indentation
109: * that will be placed along the top side of the cell.
110: *
111: * The default value is 0.
112: *
113: * @since 3.1
114: */
115: public int verticalIndent = 0;
116:
117: /**
118: * horizontalSpan specifies the number of column cells that the control
119: * will take up.
120: *
121: * The default value is 1.
122: */
123: public int horizontalSpan = 1;
124:
125: /**
126: * verticalSpan specifies the number of row cells that the control
127: * will take up.
128: *
129: * The default value is 1.
130: */
131: public int verticalSpan = 1;
132:
133: /**
134: * <p>grabExcessHorizontalSpace specifies whether the width of the cell
135: * changes depending on the size of the parent Composite. If
136: * grabExcessHorizontalSpace is <code>true</code>, the following rules
137: * apply to the width of the cell:</p>
138: * <ul>
139: * <li>If extra horizontal space is available in the parent, the cell will
140: * grow to be wider than its preferred width. The new width
141: * will be "preferred width + delta" where delta is the extra
142: * horizontal space divided by the number of grabbing columns.</li>
143: * <li>If there is not enough horizontal space available in the parent, the
144: * cell will shrink until it reaches its minimum width as specified by
145: * GridData.minimumWidth. The new width will be the maximum of
146: * "minimumWidth" and "preferred width - delta", where delta is
147: * the amount of space missing divided by the number of grabbing columns.</li>
148: * <li>If the parent is packed, the cell will be its preferred width
149: * as specified by GridData.widthHint.</li>
150: * <li>If the control spans multiple columns and there are no other grabbing
151: * controls in any of the spanned columns, the last column in the span will
152: * grab the extra space. If there is at least one other grabbing control
153: * in the span, the grabbing will be spread over the columns already
154: * marked as grabExcessHorizontalSpace.</li>
155: * </ul>
156: *
157: * <p>The default value is false.</p>
158: *
159: * @see GridData#minimumWidth
160: * @see GridData#widthHint
161: */
162: public boolean grabExcessHorizontalSpace = false;
163:
164: /**
165: * <p>grabExcessVerticalSpace specifies whether the height of the cell
166: * changes depending on the size of the parent Composite. If
167: * grabExcessVerticalSpace is <code>true</code>, the following rules
168: * apply to the height of the cell:</p>
169: * <ul>
170: * <li>If extra vertical space is available in the parent, the cell will
171: * grow to be taller than its preferred height. The new height
172: * will be "preferred height + delta" where delta is the extra
173: * vertical space divided by the number of grabbing rows.</li>
174: * <li>If there is not enough vertical space available in the parent, the
175: * cell will shrink until it reaches its minimum height as specified by
176: * GridData.minimumHeight. The new height will be the maximum of
177: * "minimumHeight" and "preferred height - delta", where delta is
178: * the amount of space missing divided by the number of grabbing rows.</li>
179: * <li>If the parent is packed, the cell will be its preferred height
180: * as specified by GridData.heightHint.</li>
181: * <li>If the control spans multiple rows and there are no other grabbing
182: * controls in any of the spanned rows, the last row in the span will
183: * grab the extra space. If there is at least one other grabbing control
184: * in the span, the grabbing will be spread over the rows already
185: * marked as grabExcessVerticalSpace.</li>
186: * </ul>
187: *
188: * <p>The default value is false.</p>
189: *
190: * @see GridData#minimumHeight
191: * @see GridData#heightHint
192: */
193: public boolean grabExcessVerticalSpace = false;
194:
195: /**
196: * minimumWidth specifies the minimum width in pixels. This value
197: * applies only if grabExcessHorizontalSpace is true. A value of
198: * SWT.DEFAULT means that the minimum width will be the result
199: * of Control.computeSize(int, int, boolean) where wHint is
200: * determined by GridData.widthHint.
201: *
202: * The default value is 0.
203: *
204: * @since 3.1
205: * @see Control#computeSize(int, int, boolean)
206: * @see GridData#widthHint
207: */
208: public int minimumWidth = 0;
209:
210: /**
211: * minimumHeight specifies the minimum height in pixels. This value
212: * applies only if grabExcessVerticalSpace is true. A value of
213: * SWT.DEFAULT means that the minimum height will be the result
214: * of Control.computeSize(int, int, boolean) where hHint is
215: * determined by GridData.heightHint.
216: *
217: * The default value is 0.
218: *
219: * @since 3.1
220: * @see Control#computeSize(int, int, boolean)
221: * @see GridData#heightHint
222: */
223: public int minimumHeight = 0;
224:
225: /**
226: * exclude informs the layout to ignore this control when sizing
227: * and positioning controls. If this value is <code>true</code>,
228: * the size and position of the control will not be managed by the
229: * layout. If this value is <code>false</code>, the size and
230: * position of the control will be computed and assigned.
231: *
232: * The default value is <code>false</code>.
233: *
234: * @since 3.1
235: */
236: public boolean exclude = false;
237:
238: /**
239: * Value for horizontalAlignment or verticalAlignment.
240: * Position the control at the top or left of the cell.
241: * Not recommended. Use SWT.BEGINNING, SWT.TOP or SWT.LEFT instead.
242: */
243: public static final int BEGINNING = SWT.BEGINNING;
244:
245: /**
246: * Value for horizontalAlignment or verticalAlignment.
247: * Position the control in the vertical or horizontal center of the cell
248: * Not recommended. Use SWT.CENTER instead.
249: */
250: public static final int CENTER = 2;
251:
252: /**
253: * Value for horizontalAlignment or verticalAlignment.
254: * Position the control at the bottom or right of the cell
255: * Not recommended. Use SWT.END, SWT.BOTTOM or SWT.RIGHT instead.
256: */
257: public static final int END = 3;
258:
259: /**
260: * Value for horizontalAlignment or verticalAlignment.
261: * Resize the control to fill the cell horizontally or vertically.
262: * Not recommended. Use SWT.FILL instead.
263: */
264: public static final int FILL = SWT.FILL;
265:
266: /**
267: * Style bit for <code>new GridData(int)</code>.
268: * Position the control at the top of the cell.
269: * Not recommended. Use
270: * <code>new GridData(int, SWT.BEGINNING, boolean, boolean)</code>
271: * instead.
272: */
273: public static final int VERTICAL_ALIGN_BEGINNING = 1 << 1;
274:
275: /**
276: * Style bit for <code>new GridData(int)</code> to position the
277: * control in the vertical center of the cell.
278: * Not recommended. Use
279: * <code>new GridData(int, SWT.CENTER, boolean, boolean)</code>
280: * instead.
281: */
282: public static final int VERTICAL_ALIGN_CENTER = 1 << 2;
283:
284: /**
285: * Style bit for <code>new GridData(int)</code> to position the
286: * control at the bottom of the cell.
287: * Not recommended. Use
288: * <code>new GridData(int, SWT.END, boolean, boolean)</code>
289: * instead.
290: */
291: public static final int VERTICAL_ALIGN_END = 1 << 3;
292:
293: /**
294: * Style bit for <code>new GridData(int)</code> to resize the
295: * control to fill the cell vertically.
296: * Not recommended. Use
297: * <code>new GridData(int, SWT.FILL, boolean, boolean)</code>
298: * instead
299: */
300: public static final int VERTICAL_ALIGN_FILL = 1 << 4;
301:
302: /**
303: * Style bit for <code>new GridData(int)</code> to position the
304: * control at the left of the cell.
305: * Not recommended. Use
306: * <code>new GridData(SWT.BEGINNING, int, boolean, boolean)</code>
307: * instead.
308: */
309: public static final int HORIZONTAL_ALIGN_BEGINNING = 1 << 5;
310:
311: /**
312: * Style bit for <code>new GridData(int)</code> to position the
313: * control in the horizontal center of the cell.
314: * Not recommended. Use
315: * <code>new GridData(SWT.CENTER, int, boolean, boolean)</code>
316: * instead.
317: */
318: public static final int HORIZONTAL_ALIGN_CENTER = 1 << 6;
319:
320: /**
321: * Style bit for <code>new GridData(int)</code> to position the
322: * control at the right of the cell.
323: * Not recommended. Use
324: * <code>new GridData(SWT.END, int, boolean, boolean)</code>
325: * instead.
326: */
327: public static final int HORIZONTAL_ALIGN_END = 1 << 7;
328:
329: /**
330: * Style bit for <code>new GridData(int)</code> to resize the
331: * control to fill the cell horizontally.
332: * Not recommended. Use
333: * <code>new GridData(SWT.FILL, int, boolean, boolean)</code>
334: * instead.
335: */
336: public static final int HORIZONTAL_ALIGN_FILL = 1 << 8;
337:
338: /**
339: * Style bit for <code>new GridData(int)</code> to resize the
340: * control to fit the remaining horizontal space.
341: * Not recommended. Use
342: * <code>new GridData(int, int, true, boolean)</code>
343: * instead.
344: */
345: public static final int GRAB_HORIZONTAL = 1 << 9;
346:
347: /**
348: * Style bit for <code>new GridData(int)</code> to resize the
349: * control to fit the remaining vertical space.
350: * Not recommended. Use
351: * <code>new GridData(int, int, boolean, true)</code>
352: * instead.
353: */
354: public static final int GRAB_VERTICAL = 1 << 10;
355:
356: /**
357: * Style bit for <code>new GridData(int)</code> to resize the
358: * control to fill the cell vertically and to fit the remaining
359: * vertical space.
360: * FILL_VERTICAL = VERTICAL_ALIGN_FILL | GRAB_VERTICAL
361: * Not recommended. Use
362: * <code>new GridData(int, SWT.FILL, boolean, true)</code>
363: * instead.
364: */
365: public static final int FILL_VERTICAL = VERTICAL_ALIGN_FILL
366: | GRAB_VERTICAL;
367:
368: /**
369: * Style bit for <code>new GridData(int)</code> to resize the
370: * control to fill the cell horizontally and to fit the remaining
371: * horizontal space.
372: * FILL_HORIZONTAL = HORIZONTAL_ALIGN_FILL | GRAB_HORIZONTAL
373: * Not recommended. Use
374: * <code>new GridData(SWT.FILL, int, true, boolean)</code>
375: * instead.
376: */
377: public static final int FILL_HORIZONTAL = HORIZONTAL_ALIGN_FILL
378: | GRAB_HORIZONTAL;
379:
380: /**
381: * Style bit for <code>new GridData(int)</code> to resize the
382: * control to fill the cell horizontally and vertically and
383: * to fit the remaining horizontal and vertical space.
384: * FILL_BOTH = FILL_VERTICAL | FILL_HORIZONTAL
385: * Not recommended. Use
386: * <code>new GridData(SWT.FILL, SWT.FILL, true, true)</code>
387: * instead.
388: */
389: public static final int FILL_BOTH = FILL_VERTICAL | FILL_HORIZONTAL;
390:
391: int cacheWidth = -1, cacheHeight = -1;
392: int defaultWhint, defaultHhint, defaultWidth = -1,
393: defaultHeight = -1;
394: int currentWhint, currentHhint, currentWidth = -1,
395: currentHeight = -1;
396:
397: /**
398: * Constructs a new instance of GridData using
399: * default values.
400: */
401: public GridData() {
402: super ();
403: }
404:
405: /**
406: * Constructs a new instance based on the GridData style.
407: * This constructor is not recommended.
408: *
409: * @param style the GridData style
410: */
411: public GridData(int style) {
412: super ();
413: if ((style & VERTICAL_ALIGN_BEGINNING) != 0)
414: verticalAlignment = BEGINNING;
415: if ((style & VERTICAL_ALIGN_CENTER) != 0)
416: verticalAlignment = CENTER;
417: if ((style & VERTICAL_ALIGN_FILL) != 0)
418: verticalAlignment = FILL;
419: if ((style & VERTICAL_ALIGN_END) != 0)
420: verticalAlignment = END;
421: if ((style & HORIZONTAL_ALIGN_BEGINNING) != 0)
422: horizontalAlignment = BEGINNING;
423: if ((style & HORIZONTAL_ALIGN_CENTER) != 0)
424: horizontalAlignment = CENTER;
425: if ((style & HORIZONTAL_ALIGN_FILL) != 0)
426: horizontalAlignment = FILL;
427: if ((style & HORIZONTAL_ALIGN_END) != 0)
428: horizontalAlignment = END;
429: grabExcessHorizontalSpace = (style & GRAB_HORIZONTAL) != 0;
430: grabExcessVerticalSpace = (style & GRAB_VERTICAL) != 0;
431: }
432:
433: /**
434: * Constructs a new instance of GridData according to the parameters.
435: *
436: * @param horizontalAlignment how control will be positioned horizontally within a cell
437: * @param verticalAlignment how control will be positioned vertically within a cell
438: * @param grabExcessHorizontalSpace whether cell will be made wide enough to fit the remaining horizontal space
439: * @param grabExcessVerticalSpace whether cell will be made high enough to fit the remaining vertical space
440: *
441: * @since 3.0
442: */
443: public GridData(int horizontalAlignment, int verticalAlignment,
444: boolean grabExcessHorizontalSpace,
445: boolean grabExcessVerticalSpace) {
446: this (horizontalAlignment, verticalAlignment,
447: grabExcessHorizontalSpace, grabExcessVerticalSpace, 1,
448: 1);
449: }
450:
451: /**
452: * Constructs a new instance of GridData according to the parameters.
453: *
454: * @param horizontalAlignment how control will be positioned horizontally within a cell
455: * @param verticalAlignment how control will be positioned vertically within a cell
456: * @param grabExcessHorizontalSpace whether cell will be made wide enough to fit the remaining horizontal space
457: * @param grabExcessVerticalSpace whether cell will be made high enough to fit the remaining vertical space
458: * @param horizontalSpan the number of column cells that the control will take up
459: * @param verticalSpan the number of row cells that the control will take up
460: *
461: * @since 3.0
462: */
463: public GridData(int horizontalAlignment, int verticalAlignment,
464: boolean grabExcessHorizontalSpace,
465: boolean grabExcessVerticalSpace, int horizontalSpan,
466: int verticalSpan) {
467: super ();
468: this .horizontalAlignment = horizontalAlignment;
469: this .verticalAlignment = verticalAlignment;
470: this .grabExcessHorizontalSpace = grabExcessHorizontalSpace;
471: this .grabExcessVerticalSpace = grabExcessVerticalSpace;
472: this .horizontalSpan = horizontalSpan;
473: this .verticalSpan = verticalSpan;
474: }
475:
476: /**
477: * Constructs a new instance of GridData according to the parameters.
478: * A value of SWT.DEFAULT indicates that no minimum width or
479: * no minimum height is specified.
480: *
481: * @param width a minimum width for the column
482: * @param height a minimum height for the row
483: *
484: * @since 3.0
485: */
486: public GridData(int width, int height) {
487: super ();
488: this .widthHint = width;
489: this .heightHint = height;
490: }
491:
492: void computeSize(Control control, int wHint, int hHint,
493: boolean flushCache) {
494: if (cacheWidth != -1 && cacheHeight != -1)
495: return;
496: if (wHint == this .widthHint && hHint == this .heightHint) {
497: if (defaultWidth == -1 || defaultHeight == -1
498: || wHint != defaultWhint || hHint != defaultHhint) {
499: Point size = control.computeSize(wHint, hHint,
500: flushCache);
501: defaultWhint = wHint;
502: defaultHhint = hHint;
503: defaultWidth = size.x;
504: defaultHeight = size.y;
505: }
506: cacheWidth = defaultWidth;
507: cacheHeight = defaultHeight;
508: return;
509: }
510: if (currentWidth == -1 || currentHeight == -1
511: || wHint != currentWhint || hHint != currentHhint) {
512: Point size = control.computeSize(wHint, hHint, flushCache);
513: currentWhint = wHint;
514: currentHhint = hHint;
515: currentWidth = size.x;
516: currentHeight = size.y;
517: }
518: cacheWidth = currentWidth;
519: cacheHeight = currentHeight;
520: }
521:
522: void flushCache() {
523: cacheWidth = cacheHeight = -1;
524: defaultWidth = defaultHeight = -1;
525: currentWidth = currentHeight = -1;
526: }
527:
528: String getName() {
529: String string = getClass().getName();
530: int index = string.lastIndexOf('.');
531: if (index == -1)
532: return string;
533: return string.substring(index + 1, string.length());
534: }
535:
536: /**
537: * Returns a string containing a concise, human-readable
538: * description of the receiver.
539: *
540: * @return a string representation of the GridData object
541: */
542: public String toString() {
543: String hAlign = "";
544: switch (horizontalAlignment) {
545: case SWT.FILL:
546: hAlign = "SWT.FILL";
547: break;
548: case SWT.BEGINNING:
549: hAlign = "SWT.BEGINNING";
550: break;
551: case SWT.LEFT:
552: hAlign = "SWT.LEFT";
553: break;
554: case SWT.END:
555: hAlign = "SWT.END";
556: break;
557: case END:
558: hAlign = "GridData.END";
559: break;
560: case SWT.RIGHT:
561: hAlign = "SWT.RIGHT";
562: break;
563: case SWT.CENTER:
564: hAlign = "SWT.CENTER";
565: break;
566: case CENTER:
567: hAlign = "GridData.CENTER";
568: break;
569: default:
570: hAlign = "Undefined " + horizontalAlignment;
571: break;
572: }
573: String vAlign = "";
574: switch (verticalAlignment) {
575: case SWT.FILL:
576: vAlign = "SWT.FILL";
577: break;
578: case SWT.BEGINNING:
579: vAlign = "SWT.BEGINNING";
580: break;
581: case SWT.TOP:
582: vAlign = "SWT.TOP";
583: break;
584: case SWT.END:
585: vAlign = "SWT.END";
586: break;
587: case END:
588: vAlign = "GridData.END";
589: break;
590: case SWT.BOTTOM:
591: vAlign = "SWT.BOTTOM";
592: break;
593: case SWT.CENTER:
594: vAlign = "SWT.CENTER";
595: break;
596: case CENTER:
597: vAlign = "GridData.CENTER";
598: break;
599: default:
600: vAlign = "Undefined " + verticalAlignment;
601: break;
602: }
603: String string = getName() + " {";
604: string += "horizontalAlignment=" + hAlign + " ";
605: if (horizontalIndent != 0)
606: string += "horizontalIndent=" + horizontalIndent + " ";
607: if (horizontalSpan != 1)
608: string += "horizontalSpan=" + horizontalSpan + " ";
609: if (grabExcessHorizontalSpace)
610: string += "grabExcessHorizontalSpace="
611: + grabExcessHorizontalSpace + " ";
612: if (widthHint != SWT.DEFAULT)
613: string += "widthHint=" + widthHint + " ";
614: if (minimumWidth != 0)
615: string += "minimumWidth=" + minimumWidth + " ";
616: string += "verticalAlignment=" + vAlign + " ";
617: if (verticalIndent != 0)
618: string += "verticalIndent=" + verticalIndent + " ";
619: if (verticalSpan != 1)
620: string += "verticalSpan=" + verticalSpan + " ";
621: if (grabExcessVerticalSpace)
622: string += "grabExcessVerticalSpace="
623: + grabExcessVerticalSpace + " ";
624: if (heightHint != SWT.DEFAULT)
625: string += "heightHint=" + heightHint + " ";
626: if (minimumHeight != 0)
627: string += "minimumHeight=" + minimumHeight + " ";
628: if (exclude)
629: string += "exclude=" + exclude + " ";
630: string = string.trim();
631: string += "}";
632: return string;
633: }
634: }
|