KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > layout > CellData


1 /*******************************************************************************
2  * Copyright (c) 2004, 2006 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  *******************************************************************************/

11
12 package org.eclipse.ui.internal.layout;
13
14 import org.eclipse.swt.SWT;
15 import org.eclipse.swt.graphics.Point;
16 import org.eclipse.swt.graphics.Rectangle;
17 import org.eclipse.swt.layout.GridData;
18
19 /**
20  * <code>CellData</code> is the layout data object associated with
21  * <code>CellLayout</code>. You can attach a CellData object to a
22  * control by using the <code>setLayoutData</code> method. CellData
23  * objects are optional. If you do not attach any layout data to a control,
24  * it will behave just like attaching a CellData created using its default
25  * constructor.
26  *
27  * @since 3.0
28  **/

29 public final class CellData {
30
31     /**
32      * hintType flag (value = 0) indicating that the control's computeSize method should be used
33      * to determine the control size. If modifierType is set to NONE, then the widthHint
34      * and heightHint fields will be ignored.
35      */

36     public final static int NONE = 0;
37
38     /**
39      * hintType flag (value = 1) indicating that the widthHint and heightHint should be used
40      * as the control's size instead of the result of computeSize
41      * <p>
42      * This flag is useful for list boxes, text boxes, tree controls, and other controls
43      * whose contents can change dynamically. For example, create a tree control and set
44      * its width and height hints to the default size for that control. This will cause
45      * the hints to be used instead of the preferred size of the tree control.</p>
46      */

47     public final static int OVERRIDE = 1;
48
49     /**
50      * hintType(value = 2) indicating that the width of the control should be no less than
51      * widthHint (if provided) and the height of the control should be no less
52      * than heightHint (if provided).
53      * <p>
54      * This flag is useful for buttons. For example, set the width and height hints to
55      * the default button size. This will use the default button size unless the button
56      * label is too large to fit on the button.
57      * </p>
58      */

59     public final static int MINIMUM = 2;
60
61     /**
62      * hintType flag (value = 3) indicating that the width of the control should be no more than
63      * widthHint (if provided) and the height of the control should be no more
64      * than heightHint (if provided).
65      * <p>
66      * This flag is useful for wrapping text. For example, set heightHint to SWT.DEFAULT
67      * and set widthHint to the desired number of pixels after which text should wrap. This
68      * will cause the text to wrap after the given number of pixels, but will not allocate
69      * extra space in the column if the text widget does not fill an entire line.
70      * </p>
71      */

72     public final static int MAXIMUM = 3;
73
74     /**
75      * This flag controls how the width and height hints are to be treated. See the constants
76      * above.
77      */

78     public int hintType = OVERRIDE;
79
80     /**
81      * Width hint. This modifies the width of the control, in pixels. If set to SWT.DEFAULT,
82      * this dimension will not be constrained. Depending on the value of modifierType,
83      * this may be a minimum size, a maximum size, or simply replace the preferred control
84      * size.
85      */

86     public int widthHint = SWT.DEFAULT;
87
88     /**
89      * Height hint. This modifies the height of the control, in pixels. If set to SWT.DEFAULT,
90      * this dimension will not be constrained. Depending on the value of modifierType,
91      * this will be a minimum size, a maximum size, or a replacement for the control's preferred
92      * size.
93      */

94     public int heightHint = SWT.DEFAULT;
95
96     /**
97      * Number of rows spanned by this cell (default = 1)
98      */

99     public int verticalSpan = 1;
100
101     /**
102      * Number of columns spanned by this cell (default = 1)
103      */

104     public int horizontalSpan = 1;
105
106     /**
107      * Horizontal alignment of the control within the cell. May be one
108      * of SWT.LEFT, SWT.RIGHT, SWT.CENTER, or SWT.NORMAL. SWT.NORMAL indicates
109      * that the control should be made as wide as the cell.
110      */

111     public int horizontalAlignment = SWT.FILL;
112
113     /**
114      * Vertical alignment of the control within the cell. May be one of
115      * SWT.TOP, SWT.BOTTOM, SWT.CENTER, or SWT.NORMAL. SWT.NORMAL indicates
116      * that the control should be made as wide as the cell.
117      */

118     public int verticalAlignment = SWT.FILL;
119
120     /**
121      * Horizontal indentation (pixels). Positive values move the control
122      * to the right, negative to the left.
123      */

124     public int horizontalIndent = 0;
125
126     /**
127      * Vertical indentation (pixels). Positive values move the control
128      * down, negative values move the control up.
129      */

130     public int verticalIndent = 0;
131
132     /**
133      * Constructs a CellData with default properties
134      */

135     public CellData() {
136         // Use the default values for all fields.
137
}
138
139     /**
140      * Creates a new CellData that with properties that are as close as possible to
141      * the given GridData. This is used for converting GridLayouts into CellLayouts.
142      *
143      * @param data
144      */

145     public CellData(GridData data) {
146         verticalSpan = data.verticalSpan;
147         horizontalSpan = data.horizontalSpan;
148
149         switch (data.horizontalAlignment) {
150         case GridData.BEGINNING:
151             horizontalAlignment = SWT.LEFT;
152             break;
153         case GridData.CENTER:
154             horizontalAlignment = SWT.CENTER;
155             break;
156         case GridData.END:
157             horizontalAlignment = SWT.RIGHT;
158             break;
159         case GridData.FILL:
160             horizontalAlignment = SWT.FILL;
161             break;
162         }
163
164         switch (data.verticalAlignment) {
165         case GridData.BEGINNING:
166             verticalAlignment = SWT.LEFT;
167             break;
168         case GridData.CENTER:
169             verticalAlignment = SWT.CENTER;
170             break;
171         case GridData.END:
172             verticalAlignment = SWT.RIGHT;
173             break;
174         case GridData.FILL:
175             verticalAlignment = SWT.FILL;
176             break;
177         }
178
179         widthHint = data.widthHint;
180         heightHint = data.heightHint;
181         horizontalIndent = data.horizontalIndent;
182         hintType = OVERRIDE;
183     }
184
185     /**
186      * Copies the given CellData
187      *
188      * @param newData
189      */

190     public CellData(CellData newData) {
191         hintType = newData.hintType;
192         widthHint = newData.widthHint;
193         heightHint = newData.heightHint;
194         horizontalAlignment = newData.horizontalAlignment;
195         verticalAlignment = newData.verticalAlignment;
196         horizontalSpan = newData.horizontalSpan;
197         verticalSpan = newData.verticalSpan;
198     }
199
200     /**
201      * Sets the size hint for this control. This is used to modify the control's
202      * preferred size. If one dimension should remain unmodified, that hint can be
203      * set to SWT.DEFAULT. Using a size hint of CellData.MINIMUM ensures that the preferred
204      * control size is larger than the hint. Using a size hint of CellData.MAXIMUM ensures
205      * that the preferred size is smaller than the hint. Using a size hint of CellData.OVERRIDE
206      * ensures that the preferred size is always equal to the hint.
207      *
208      * @param hintType one of CellData.MINIMUM, CellData.MAXIMUM, or CellData.OVERRIDE
209      * @param hint size hint (in pixels). If either dimension is set to SWT.DEFAULT, the
210      * hint will not affect that dimension
211      * @return this
212      */

213     public CellData setHint(int hintType, Point hint) {
214         return setHint(hintType, hint.x, hint.y);
215     }
216
217     /**
218      * Sets the size hint for this control. This is used to modify the control's
219      * preferred size. If one dimension should remain unmodified, that hint can be
220      * set to SWT.DEFAULT. Using a size hint of CellData.MINIMUM ensures that the preferred
221      * control size is larger than the hint. Using a size hint of CellData.MAXIMUM ensures
222      * that the preferred size is smaller than the hint. Using a size hint of CellData.OVERRIDE
223      * ensures that the preferred size is always equal to the hint. If both hints are equal
224      * to SWT.DEFAULT, then the control's preferred size is unmodified.
225      *
226      * @param hintType one of CellData.MINIMUM, CellData.MAXIMUM, or CellData.OVERRIDE
227      * @param horizontal horizontal hint (pixels). A value of SWT.DEFAULT will leave the result
228      * of the control's computeSize method unmodified.
229      * @param vertical vertical hint (pixels). A value of SWT.DEFAULT will leave the result of
230      * the control's computeSize method unmodified.
231      * @return this
232      */

233     public CellData setHint(int hintType, int horizontal, int vertical) {
234         this.hintType = hintType;
235         this.heightHint = vertical;
236         this.widthHint = horizontal;
237
238         return this;
239     }
240
241     /**
242      * Sets the alignment for this control
243      *
244      * @param horizontalAlignment one of SWT.LEFT, SWT.RIGHT, SWT.FILL, or SWT.CENTER
245      * @param verticalAlignment one of SWT.TOP, SWT.BOTTOM, SWT.FILL, or SWT.CENTER
246      * @return this
247      */

248     public CellData align(int horizontalAlignment, int verticalAlignment) {
249         this.horizontalAlignment = horizontalAlignment;
250         this.verticalAlignment = verticalAlignment;
251
252         return this;
253     }
254
255     /**
256      * Sets the number of rows and columns spanned by this control.
257      *
258      * @param horizontalSpan number of columns spanned by the control (> 0)
259      * @param verticalSpan number of rows spanned by the control (> 0)
260      * @return this
261      */

262     public CellData span(int horizontalSpan, int verticalSpan) {
263         this.horizontalSpan = horizontalSpan;
264         this.verticalSpan = verticalSpan;
265
266         return this;
267     }
268
269     /**
270      * Sets the indentation for this control. The indentation is added to
271      * the control's position within the cell. For example, indentation of
272      * (10,4) will move the control right by 10 pixels and down by 4 pixels.
273      *
274      * @param indent indentation (pixels)
275      * @return this
276      */

277     public CellData indent(Point indent) {
278         return this.indent(indent.x, indent.y);
279     }
280
281     /**
282      * Sets the indentation for this cell
283      *
284      * @param horizontalIndent distance (pixels) to move the control to the right
285      * @param verticalIndent distance (pixels) to move the control down
286      * @return this
287      */

288     public CellData indent(int horizontalIndent, int verticalIndent) {
289         this.horizontalIndent = horizontalIndent;
290         this.verticalIndent = verticalIndent;
291
292         return this;
293     }
294
295     /**
296      * Returns the preferred size of the given control, given the known dimensions of
297      * its cell.
298      *
299      * @param toCompute the control whose size is to be computed
300      * @param cellWidth width of the cell, in pixels (or SWT.DEFAULT if unknown)
301      * @param cellHeight height of the cell, in pixels (or SWT.DEFAULT if unknown)
302      * @return the preferred size of the given control, in pixels
303      */

304     public Point computeSize(SizeCache toCompute, int cellWidth, int cellHeight) {
305
306         int absHorizontalIndent = Math.abs(horizontalIndent);
307         int absVerticalIndent = Math.abs(verticalIndent);
308
309         // If we're going to indent, subtract off the space that will be required for indentation from
310
// the available space
311
if (cellWidth != SWT.DEFAULT) {
312             cellWidth -= absHorizontalIndent;
313         }
314
315         if (cellHeight != SWT.DEFAULT) {
316             cellHeight -= absVerticalIndent;
317         }
318
319         int controlWidth = horizontalAlignment == SWT.FILL ? cellWidth
320                 : SWT.DEFAULT;
321         int controlHeight = verticalAlignment == SWT.FILL ? cellHeight
322                 : SWT.DEFAULT;
323
324         // Note: this could be optimized further. If we're using a MAXIMUM hint and
325
// non-FILL alignment, we could simply call computeMaximumBoundedSize using the
326
// minimum of the cell size and the hint as the boundary -- basically, rather
327
// than applying two limits for the hint and the cell boundary, we can do it in
328
// one step and reduce the size computations by half (for this specific case).
329
Point controlSize = computeControlSize(toCompute, controlWidth,
330                 controlHeight);
331
332         if (cellWidth != SWT.DEFAULT && controlSize.x > cellWidth) {
333             controlSize = computeControlSize(toCompute, cellWidth,
334                     controlHeight);
335             if (cellHeight != SWT.DEFAULT && controlSize.y > cellHeight) {
336                 controlSize.y = cellHeight;
337             }
338         } else if (cellHeight != SWT.DEFAULT && controlSize.y > cellHeight) {
339             controlSize = computeControlSize(toCompute, controlWidth,
340                     cellHeight);
341             if (cellWidth != SWT.DEFAULT && controlSize.x > cellWidth) {
342                 controlSize.x = cellWidth;
343             }
344         }
345
346         // If we're going to indent, add the indentation to the required space
347
controlSize.x += absHorizontalIndent;
348         controlSize.y += absVerticalIndent;
349
350         return controlSize;
351     }
352
353     /**
354      * Arranges the given control within the given rectangle using the
355      * criteria described by this CellData.
356      *
357      * @param control
358      * @param cellBounds
359      * @since 3.0
360      */

361     public void positionControl(SizeCache cache, Rectangle cellBounds) {
362
363         int startx = cellBounds.x;
364         int starty = cellBounds.y;
365         int availableWidth = cellBounds.width - horizontalIndent;
366         int availableHeight = cellBounds.height - verticalIndent;
367
368         Point size = computeSize(cache, availableWidth, availableHeight);
369
370         // Horizontal justification
371
switch (horizontalAlignment) {
372         case SWT.RIGHT:
373             startx = cellBounds.x + availableWidth - size.x;
374             break;
375         case SWT.CENTER:
376             startx = cellBounds.x + (availableWidth - size.x) / 2;
377             break;
378         }
379
380         // Vertical justification
381
switch (verticalAlignment) {
382         case SWT.BOTTOM:
383             starty = cellBounds.y + availableHeight - size.y;
384             break;
385         case SWT.CENTER:
386             starty = cellBounds.y + (availableHeight - size.y) / 2;
387             break;
388         }
389
390         // Position the control
391
cache.getControl().setBounds(startx + horizontalIndent,
392                 starty + verticalIndent, size.x, size.y);
393     }
394
395     /**
396      * Returns the preferred size of the given control in this cell, given one or both
397      * known dimensions of the control. This differs from computeSize, which takes known
398      * dimensions of the <b>cell</b> as arguments.
399      *
400      * @param toCompute
401      * @param controlWidth
402      * @param controlHeight
403      * @return
404      * @since 3.0
405      */

406     private Point computeControlSize(SizeCache toCompute, int controlWidth,
407             int controlHeight) {
408         switch (hintType) {
409         case OVERRIDE:
410             return computeOverrideSize(toCompute, controlWidth, controlHeight,
411                     widthHint, heightHint);
412         case MINIMUM:
413             return computeMinimumBoundedSize(toCompute, controlWidth,
414                     controlHeight, widthHint, heightHint);
415         case MAXIMUM:
416             return computeMaximumBoundedSize(toCompute, controlWidth,
417                     controlHeight, widthHint, heightHint);
418         }
419
420         return computeRawSize(toCompute, controlWidth, controlHeight);
421     }
422
423     /**
424      * Computes the size of the control, given its outer dimensions. This should be used in
425      * place of calling Control.computeSize, since Control.computeSize takes control-specific
426      * inner dimensions as hints.
427      *
428      * @param toCompute Control whose size will be computed
429      * @param controlWidth width of the control (pixels or SWT.DEFAULT if unknown)
430      * @param controlHeight height of the control (pixels or SWT.DEFAULT if unknown)
431      * @return preferred dimensions of the control
432      */

433     private static Point computeRawSize(SizeCache toCompute, int controlWidth,
434             int controlHeight) {
435         if (controlWidth != SWT.DEFAULT && controlHeight != SWT.DEFAULT) {
436             return new Point(controlWidth, controlHeight);
437         }
438
439         // Known bug: we pass the OUTER dimension of the control into computeSize, even though
440
// SWT expects a control-specific inner dimension as width and height hints. Currently,
441
// SWT does not provide any means to convert outer dimensions into inner dimensions.
442
// Fortunately, the outer and inner dimensions tend to be quite close so we
443
// pass in the outer dimension and adjust the result if it differs from one of the
444
// hints. This may cause incorrect text wrapping in rare cases, and should be fixed
445
// once SWT provides a way to convert the outer dimension of a control into a valid
446
// width or height hint for Control.computeSize. Note that the distinction between outer
447
// and inner dimensions is undocumented in SWT, and most examples also contain this
448
// bug.
449
Point result = toCompute.computeSize(controlWidth, controlHeight);
450
451         // Hack: If the result of computeSize differs from the width or height-hints, adjust it.
452
// See above. Don't remove this hack until SWT provides some way to pass correct width
453
// and height hints into computeSize. Once this happens, these conditions should always
454
// return false and the hack will have no effect.
455
if (controlWidth != SWT.DEFAULT) {
456             result.x = controlWidth;
457         } else if (controlHeight != SWT.DEFAULT) {
458             result.y = controlHeight;
459         }
460
461         return result;
462     }
463
464     /**
465      * Computes the preferred size of the control. Optionally, one or both dimensions
466      * may be fixed to a given size.
467      *
468      * @param control object that can compute the size of the control of interest
469      * @param wHint known width (or SWT.DEFAULT if the width needs to be computed)
470      * @param hHint known height (or SWT.DEFAULT if the height needs to be computed)
471      * @param overrideW width that should always be returned by the control,
472      * or SWT.DEFAULT if the width is not being constrained
473      * @param overrideH height that should always be returned by the control,
474      * or SWT.DEFAULT if the height is not being constrained
475      * @return
476      */

477     private static Point computeOverrideSize(SizeCache control, int wHint,
478             int hHint, int overrideW, int overrideH) {
479         int resultWidth = overrideW;
480         int resultHeight = overrideH;
481
482         if (wHint != SWT.DEFAULT) {
483             resultWidth = wHint;
484         }
485
486         if (hHint != SWT.DEFAULT) {
487             resultHeight = hHint;
488         }
489
490         if (resultWidth == SWT.DEFAULT || resultHeight == SWT.DEFAULT) {
491             Point result = computeRawSize(control, resultWidth, resultHeight);
492
493             return result;
494         }
495
496         return new Point(resultWidth, resultHeight);
497     }
498
499     /**
500      * Computes the size for the control, optionally bounding the size in the x and
501      * y directions. The various hints are used to determine which dimensions are
502      * already known and which dimensions need to be computed.
503      *
504      * @param control The control whose size should be computed
505      * @param wHint known width (or SWT.DEFAULT if the width needs to be computed)
506      * @param hHint known height (or SWT.DEFAULT if the height needs to be computed)
507      * @param boundedWidth maximum width for the control (or SWT.DEFAULT if the width is unbounded)
508      * @param boundedHeight maximum height for the control (or SWT.DEFAULT if the height is unbounded)
509      * @return the preferred size of the control, given that it cannot exceed the given bounds
510      */

511     private static Point computeMaximumBoundedSize(SizeCache control,
512             int wHint, int hHint, int boundedWidth, int boundedHeight) {
513         Point controlSize = computeRawSize(control, wHint, hHint);
514
515         if (wHint == SWT.DEFAULT && boundedWidth != SWT.DEFAULT
516                 && controlSize.x > boundedWidth) {
517             return computeMaximumBoundedSize(control, boundedWidth, hHint,
518                     boundedWidth, boundedHeight);
519         }
520
521         if (hHint == SWT.DEFAULT && boundedHeight != SWT.DEFAULT
522                 && controlSize.y > boundedHeight) {
523             return computeMaximumBoundedSize(control, wHint, boundedHeight,
524                     boundedWidth, boundedHeight);
525         }
526
527         return controlSize;
528     }
529
530     private static Point computeMinimumBoundedSize(SizeCache control,
531             int wHint, int hHint, int minimumWidth, int minimumHeight) {
532
533         Point controlSize = computeRawSize(control, wHint, hHint);
534
535         if (minimumWidth != SWT.DEFAULT && wHint == SWT.DEFAULT
536                 && controlSize.x < minimumWidth) {
537             return computeMinimumBoundedSize(control, minimumWidth, hHint,
538                     minimumWidth, minimumHeight);
539         }
540
541         if (minimumHeight != SWT.DEFAULT && hHint == SWT.DEFAULT
542                 && controlSize.y < minimumHeight) {
543             return computeMinimumBoundedSize(control, wHint, minimumHeight,
544                     minimumWidth, minimumHeight);
545         }
546
547         return controlSize;
548     }
549
550 }
551
Popular Tags