001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 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: * Stefan Xenos, IBM - initial implementation, bug 178888
011: *******************************************************************************/package org.eclipse.jface.layout;
012:
013: import org.eclipse.swt.SWT;
014: import org.eclipse.swt.graphics.Point;
015: import org.eclipse.swt.layout.GridData;
016: import org.eclipse.swt.widgets.Control;
017:
018: /**
019: * This class provides a convienient shorthand for creating and initializing
020: * GridData. This offers several benefits over creating GridData normal way:
021: *
022: * <ul>
023: * <li>The same factory can be used many times to create several GridData instances</li>
024: * <li>The setters on GridDataFactory all return "this", allowing them to be chained</li>
025: * <li>GridDataFactory uses vector setters (it accepts Points), making it easy to
026: * set X and Y values together</li>
027: * </ul>
028: *
029: * <p>
030: * GridDataFactory instances are created using one of the static methods on this class.
031: * </p>
032: *
033: * <p>
034: * Example usage:
035: * </p>
036: * <code><pre>
037: *
038: * ////////////////////////////////////////////////////////////
039: * // Example 1: Typical grid data for a non-wrapping label
040: *
041: * // GridDataFactory version
042: * GridDataFactory.fillDefaults().applyTo(myLabel);
043: *
044: * // Equivalent SWT version
045: * GridData labelData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
046: * myLabel.setLayoutData(labelData);
047: *
048: * ///////////////////////////////////////////////////////////
049: * // Example 2: Typical grid data for a wrapping label
050: *
051: * // GridDataFactory version
052: * GridDataFactory.fillDefaults()
053: * .align(SWT.FILL, SWT.CENTER)
054: * .hint(150, SWT.DEFAULT)
055: * .grab(true, false)
056: * .applyTo(wrappingLabel);
057: *
058: * // Equivalent SWT version
059: * GridData wrappingLabelData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER);
060: * wrappingLabelData.minimumWidth = 1;
061: * wrappingLabelData.widthHint = 150;
062: * wrappingLabel.setLayoutData(wrappingLabelData);
063: *
064: * //////////////////////////////////////////////////////////////
065: * // Example 3: Typical grid data for a scrollable control (a list box, tree, table, etc.)
066: *
067: * // GridDataFactory version
068: * GridDataFactory.fillDefaults().grab(true, true).hint(150, 150).applyTo(listBox);
069: *
070: * // Equivalent SWT version
071: * GridData listBoxData = new GridData(GridData.FILL_BOTH);
072: * listBoxData.widthHint = 150;
073: * listBoxData.heightHint = 150;
074: * listBoxData.minimumWidth = 1;
075: * listBoxData.minimumHeight = 1;
076: * listBox.setLayoutData(listBoxData);
077: *
078: * /////////////////////////////////////////////////////////////
079: * // Example 4: Typical grid data for a button
080: *
081: * // GridDataFactory version
082: * Point preferredSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
083: * Point hint = Geometry.max(LayoutConstants.getMinButtonSize(), preferredSize);
084: * GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).hint(hint).applyTo(button);
085: *
086: * // Equivalent SWT version
087: * Point preferredSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
088: * Point hint = Geometry.max(LayoutConstants.getMinButtonSize(), preferredSize);
089: * GridData buttonData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER);
090: * buttonData.widthHint = hint.x;
091: * buttonData.heightHint = hint.y;
092: * button.setLayoutData(buttonData);
093: *
094: * /////////////////////////////////////////////////////////////
095: * // Example 5: Generated GridData
096: *
097: * // Generates GridData a wrapping label that spans 2 columns
098: * GridDataFactory.generate(wrappingLabel, 2, 1);
099: *
100: * // Generates GridData for a listbox. and adjusts the preferred size to 300x400 pixels
101: * GridDataFactory.defaultsFor(listBox).hint(300, 400).applyTo(listBox);
102: *
103: * // Generates GridData equivalent to example 4
104: * GridDataFactory.generate(button, 1, 1);
105: *
106: * </pre></code>
107: *
108: * @since 3.2
109: */
110: public final class GridDataFactory {
111: private GridData data;
112:
113: /**
114: * Creates a GridDataFactory that creates copes of the given GridData.
115: *
116: * @param d template GridData to copy
117: */
118: private GridDataFactory(GridData d) {
119: this .data = d;
120: }
121:
122: /**
123: * Creates a new GridDataFactory initialized with the SWT defaults.
124: * This factory will generate GridData that is equivalent to
125: * "new GridData()".
126: *
127: * <p>
128: * Initial values are:
129: * </p>
130: *
131: * <ul>
132: * <li>align(SWT.BEGINNING, SWT.CENTER)</li>
133: * <li>exclude(false)</li>
134: * <li>grab(false, false)</li>
135: * <li>hint(SWT.DEFAULT, SWT.DEFAULT)</li>
136: * <li>indent(0,0)</li>
137: * <li>minSize(0,0)</li>
138: * <li>span(1,1)</li>
139: * </ul>
140: *
141: * @return a new GridDataFactory instance
142: * @see #fillDefaults()
143: */
144: public static GridDataFactory swtDefaults() {
145: return new GridDataFactory(new GridData());
146: }
147:
148: /**
149: * Creates a new GridDataFactory that creates copies of the given GridData
150: * by default.
151: *
152: * @param data GridData to copy
153: * @return a new GridDataFactory that creates copies of the argument by default
154: */
155: public static GridDataFactory createFrom(GridData data) {
156: return new GridDataFactory(copyData(data));
157: }
158:
159: /**
160: * Creates a GridDataFactory initialized with defaults that will cause
161: * the control to fill its cell. The minimum size is set to the smallest possible
162: * minimum size supported by SWT. Currently, the smallest supported minimum size
163: * is (1,1) so this is the default. If GridLayout ever adds support for grid data
164: * with no minimum size, this will be changed to 0,0 in the future.
165: *
166: * <p>
167: * Initial values are:
168: * </p>
169: *
170: * <ul>
171: * <li>align(SWT.FILL, SWT.FILL)</li>
172: * <li>exclude(false)</li>
173: * <li>grab(false, false)</li>
174: * <li>hint(SWT.DEFAULT, SWT.DEFAULT)</li>
175: * <li>indent(0,0)</li>
176: * <li>minSize(1,1)</li>
177: * <li>span(1,1)</li>
178: * </ul>
179: *
180: * @return a GridDataFactory that makes controls fill their grid by default
181: *
182: * @see #swtDefaults()
183: */
184: public static GridDataFactory fillDefaults() {
185: GridData data = new GridData();
186: data.minimumWidth = 1;
187: data.minimumHeight = 1;
188: data.horizontalAlignment = SWT.FILL;
189: data.verticalAlignment = SWT.FILL;
190:
191: return new GridDataFactory(data);
192: }
193:
194: /**
195: * Returns a GridDataFactory initialized with heuristicly generated defaults for the given control.
196: * To be precise, this method picks the default values that GridLayoutFactory.generateLayout
197: * would have assigned to the control. Does not attach GridData to the control. Callers must
198: * additionally call applyTo(theControl) if they wish to use the generated values.
199: *
200: * <p>
201: * This method is intended for situations where generateLayout is generating layout data
202: * for a particular control that is not quite right for the desired layout.
203: * This allows callers to start with the generated values and tweak one or two settings
204: * before applying the GridData to the control.
205: * </p>
206: *
207: * @see GridLayoutFactory#generateLayout(org.eclipse.swt.widgets.Composite)
208: * @param theControl
209: * @return a GridLayoutFactory initialized with defaults that GridLayoutFactory would have
210: * @since 3.3
211: */
212: public static GridDataFactory defaultsFor(Control theControl) {
213: return LayoutGenerator.defaultsFor(theControl);
214: }
215:
216: /**
217: * Generates layout data to the given control, given the number of cells
218: * spanned by the control. Attaches a GridData to the control. This method
219: * allows generated layout data to be used with controls that span multiple cells.
220: * <p>
221: * The generated layout data is the same as what would be generated by
222: * GridLayoutFactory.generateLayout, except that the span is configurable
223: * </p>
224: *
225: * @see GridLayoutFactory#generateLayout(org.eclipse.swt.widgets.Composite)
226: * @param theControl
227: * @param hSpan number of columns spanned by the control
228: * @param vSpan number of rows spanned by the control
229: * @since 3.3
230: */
231: public static void generate(Control theControl, int hSpan, int vSpan) {
232: defaultsFor(theControl).span(hSpan, vSpan).applyTo(theControl);
233: }
234:
235: /**
236: * Generates layout data to the given control, given the number of cells
237: * spanned by the control. Attaches GridData to the control. This method
238: * allows generated layout data to be used with controls that span multiple cells.
239: * <p>
240: * The generated layout data is the same as what would be generated by
241: * GridLayoutFactory.generateLayout, except that the span is configurable
242: * </p>
243: *
244: * @see GridLayoutFactory#generateLayout(org.eclipse.swt.widgets.Composite)
245: * @param theControl
246: * @param span The x coordinate indicates the number of
247: * columns spanned, and the y coordinate indicates the number of rows.
248: * @since 3.3
249: */
250: public static void generate(Control theControl, Point span) {
251: defaultsFor(theControl).span(span).applyTo(theControl);
252: }
253:
254: /**
255: * Sets the GridData span. The span controls how many cells
256: * are filled by the control.
257: *
258: * @param hSpan number of columns spanned by the control
259: * @param vSpan number of rows spanned by the control
260: * @return this
261: */
262: public GridDataFactory span(int hSpan, int vSpan) {
263: data.horizontalSpan = hSpan;
264: data.verticalSpan = vSpan;
265: return this ;
266: }
267:
268: /**
269: * Sets the GridData span. The span controls how many cells
270: * are filled by the control.
271: *
272: * @param span the new span. The x coordinate indicates the number of
273: * columns spanned, and the y coordinate indicates the number of rows.
274: * @return this
275: */
276: public GridDataFactory span(Point span) {
277: data.horizontalSpan = span.x;
278: data.verticalSpan = span.y;
279: return this ;
280: }
281:
282: /**
283: * Sets the width and height hints. The width and height hints override
284: * the control's preferred size. If either hint is set to SWT.DEFAULT,
285: * the control's preferred size is used.
286: *
287: * @param xHint horizontal hint (pixels), or SWT.DEFAULT to use the control's preferred size
288: * @param yHint vertical hint (pixels), or SWT.DEFAULT to use the control's preferred size
289: * @return this
290: */
291: public GridDataFactory hint(int xHint, int yHint) {
292: data.widthHint = xHint;
293: data.heightHint = yHint;
294: return this ;
295: }
296:
297: /**
298: * Sets the width and height hints. The width and height hints override
299: * the control's preferred size. If either hint is set to SWT.DEFAULT,
300: * the control's preferred size is used.
301: *
302: * @param hint size (pixels) to be used instead of the control's preferred size. If
303: * the x or y values are set to SWT.DEFAULT, the control's computeSize() method will
304: * be used to obtain that dimension of the preferred size.
305: * @return this
306: */
307: public GridDataFactory hint(Point hint) {
308: data.widthHint = hint.x;
309: data.heightHint = hint.y;
310: return this ;
311: }
312:
313: /**
314: * Sets the alignment of the control within its cell.
315: *
316: * @param hAlign horizontal alignment. One of SWT.BEGINNING, SWT.CENTER, SWT.END, or SWT.FILL.
317: * @param vAlign vertical alignment. One of SWT.BEGINNING, SWT.CENTER, SWT.END, or SWT.FILL.
318: * @return this
319: */
320: public GridDataFactory align(int hAlign, int vAlign) {
321: if (hAlign != SWT.BEGINNING && hAlign != SWT.CENTER
322: && hAlign != GridData.CENTER && hAlign != SWT.END
323: && hAlign != GridData.END && hAlign != SWT.FILL
324: && hAlign != SWT.LEFT && hAlign != SWT.RIGHT) {
325: throw new IllegalArgumentException();
326: }
327: if (vAlign != SWT.BEGINNING && vAlign != SWT.CENTER
328: && vAlign != GridData.CENTER && vAlign != SWT.END
329: && vAlign != GridData.END && vAlign != SWT.FILL
330: && vAlign != SWT.TOP && vAlign != SWT.BOTTOM) {
331: throw new IllegalArgumentException();
332: }
333: data.horizontalAlignment = hAlign;
334: data.verticalAlignment = vAlign;
335: return this ;
336: }
337:
338: /**
339: * Sets the indent of the control within the cell. Moves the position of the control
340: * by the given number of pixels. Positive values move toward the lower-right, negative
341: * values move toward the upper-left.
342: *
343: * @param hIndent distance to move to the right (negative values move left)
344: * @param vIndent distance to move down (negative values move up)
345: * @return this
346: */
347: public GridDataFactory indent(int hIndent, int vIndent) {
348: data.horizontalIndent = hIndent;
349: data.verticalIndent = vIndent;
350: return this ;
351: }
352:
353: /**
354: * Sets the indent of the control within the cell. Moves the position of the control
355: * by the given number of pixels. Positive values move toward the lower-right, negative
356: * values move toward the upper-left.
357: *
358: * @param indent offset to move the control
359: * @return this
360: */
361: public GridDataFactory indent(Point indent) {
362: data.horizontalIndent = indent.x;
363: data.verticalIndent = indent.y;
364: return this ;
365: }
366:
367: /**
368: * Determines whether extra horizontal or vertical space should be allocated to
369: * this control's column when the layout resizes. If any control in the column
370: * is set to grab horizontal then the whole column will grab horizontal space.
371: * If any control in the row is set to grab vertical then the whole row will grab
372: * vertical space.
373: *
374: * @param horizontal true if the control's column should grow horizontally
375: * @param vertical true if the control's row should grow vertically
376: * @return this
377: */
378: public GridDataFactory grab(boolean horizontal, boolean vertical) {
379: data.grabExcessHorizontalSpace = horizontal;
380: data.grabExcessVerticalSpace = vertical;
381: return this ;
382: }
383:
384: /**
385: * Sets the minimum size for the control. The control will not be permitted
386: * to shrink below this size. Note: GridLayout treats a minimum size of 0
387: * as an undocumented special value, so the smallest possible minimum size
388: * is a size of 1. A minimum size of SWT.DEFAULT indicates that the result
389: * of computeSize(int, int, boolean) should be used as the control's minimum
390: * size.
391: *
392: *
393: * @param minX minimum a value of 1 or more is a horizontal size of the control (pixels).
394: * SWT.DEFAULT indicates that the control's preferred size should be used. A size
395: * of 0 has special semantics defined by GridLayout.
396: * @param minY minimum a value of 1 or more is a vertical size of the control (pixels). SWT.DEFAULT
397: * indicates that the control's preferred size should be used. A size
398: * of 0 has special semantics defined by GridLayout.
399: * @return this
400: */
401: public GridDataFactory minSize(int minX, int minY) {
402: data.minimumWidth = minX;
403: data.minimumHeight = minY;
404: return this ;
405: }
406:
407: /**
408: * Sets the minimum size for the control. The control will not be permitted
409: * to shrink below this size. Note: GridLayout treats a minimum size of 0
410: * as an undocumented special value, so the smallest possible minimum size
411: * is a size of 1. A minimum size of SWT.DEFAULT indicates that the result
412: * of computeSize(int, int, boolean) should be used as the control's minimum
413: * size.
414: *
415: * @param min minimum size of the control
416: * @return this
417: */
418: public GridDataFactory minSize(Point min) {
419: data.minimumWidth = min.x;
420: data.minimumHeight = min.y;
421: return this ;
422: }
423:
424: /**
425: * Instructs the GridLayout to ignore this control when performing layouts.
426: *
427: * @param shouldExclude true iff the control should be excluded from layouts
428: * @return this
429: */
430: public GridDataFactory exclude(boolean shouldExclude) {
431: data.exclude = shouldExclude;
432: return this ;
433: }
434:
435: /**
436: * Creates a new GridData instance. All attributes of the GridData instance
437: * will be initialized by the factory.
438: *
439: * @return a new GridData instance
440: */
441: public GridData create() {
442: return copyData(data);
443: }
444:
445: /**
446: * Creates a copy of the reciever.
447: *
448: * @return a copy of the reciever
449: */
450: public GridDataFactory copy() {
451: return new GridDataFactory(create());
452: }
453:
454: /**
455: * Returns a copy of the given GridData
456: *
457: * @param data GridData to copy
458: * @return a copy of the argument
459: */
460: public static GridData copyData(GridData data) {
461: GridData newData = new GridData(data.horizontalAlignment,
462: data.verticalAlignment, data.grabExcessHorizontalSpace,
463: data.grabExcessVerticalSpace, data.horizontalSpan,
464: data.verticalSpan);
465: newData.exclude = data.exclude;
466: newData.heightHint = data.heightHint;
467: newData.horizontalIndent = data.horizontalIndent;
468: newData.minimumHeight = data.minimumHeight;
469: newData.minimumWidth = data.minimumWidth;
470: newData.verticalIndent = data.verticalIndent;
471: newData.widthHint = data.widthHint;
472:
473: return newData;
474: }
475:
476: /**
477: * Sets the layout data on the given control. Creates a new GridData instance and
478: * assigns it to the control by calling control.setLayoutData.
479: *
480: * @param control control whose layout data will be initialized
481: */
482: public void applyTo(Control control) {
483: control.setLayoutData(create());
484: }
485:
486: }
|