Home | History | Annotate | Download | only in ui
      1 /*******************************************************************************
      2  * Copyright (c) 2005, 2011 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 package org.eclipse.wb.internal.core.utils.ui;
     12 
     13 import org.eclipse.swt.graphics.Point;
     14 import org.eclipse.swt.layout.GridData;
     15 import org.eclipse.swt.widgets.Control;
     16 
     17 /**
     18  * This class provides a convienient shorthand for creating and initializing GridData. This offers
     19  * several benefits over creating GridData normal way:
     20  *
     21  * <ul>
     22  * <li>The same factory can be used many times to create several GridData instances</li>
     23  * <li>The setters on GridDataFactory all return "this", allowing them to be chained</li>
     24  * <li>GridDataFactory uses vector setters (it accepts Points), making it easy to set X and Y values
     25  * together</li>
     26  * </ul>
     27  *
     28  * <p>
     29  * GridDataFactory instances are created using one of the static methods on this class.
     30  * </p>
     31  *
     32  * <p>
     33  * Example usage:
     34  * </p>
     35  * <code>
     36  *
     37  * ////////////////////////////////////////////////////////////
     38  * // Example 1: Typical grid data for a non-wrapping label
     39  *
     40  *     // GridDataFactory version
     41  *     GridDataFactory.fillDefaults().applyTo(myLabel);
     42  *
     43  *     // Equivalent SWT version
     44  *     GridData labelData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
     45  *     myLabel.setLayoutData(labelData);
     46  *
     47  * ///////////////////////////////////////////////////////////
     48  * // Example 2: Typical grid data for a wrapping label
     49  *
     50  *     // GridDataFactory version
     51  *     GridDataFactory.fillDefaults()
     52  *          .align(SWT.FILL, SWT.CENTER)
     53  *    	    .hint(150, SWT.DEFAULT)
     54  *    	    .grab(true, false)
     55  *          .applyTo(wrappingLabel);
     56  *
     57  *     // Equivalent SWT version
     58  *     GridData wrappingLabelData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER);
     59  *     wrappingLabelData.minimumWidth = 1;
     60  *     wrappingLabelData.widthHint = 150;
     61  *     wrappingLabel.setLayoutData(wrappingLabelData);
     62  *
     63  * //////////////////////////////////////////////////////////////
     64  * // Example 3: Typical grid data for a scrollable control (a list box, tree, table, etc.)
     65  *
     66  *     // GridDataFactory version
     67  *     GridDataFactory.fillDefaults().grab(true, true).hint(150, 150).applyTo(listBox);
     68  *
     69  *     // Equivalent SWT version
     70  *     GridData listBoxData = new GridData(GridData.FILL_BOTH);
     71  *     listBoxData.widthHint = 150;
     72  *     listBoxData.heightHint = 150;
     73  *     listBoxData.minimumWidth = 1;
     74  *     listBoxData.minimumHeight = 1;
     75  *     listBox.setLayoutData(listBoxData);
     76  *
     77  * /////////////////////////////////////////////////////////////
     78  * // Example 4: Typical grid data for a button
     79  *
     80  *     // GridDataFactory version
     81  *     Point preferredSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
     82  *     Point hint = Geometry.max(LayoutConstants.getMinButtonSize(), preferredSize);
     83  *     GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).hint(hint).applyTo(button);
     84  *
     85  *     // Equivalent SWT version
     86  *     Point preferredSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
     87  *     Point hint = Geometry.max(LayoutConstants.getMinButtonSize(), preferredSize);
     88  *     GridData buttonData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER);
     89  *     buttonData.widthHint = hint.x;
     90  *     buttonData.heightHint = hint.y;
     91  *     button.setLayoutData(buttonData);
     92  * </code>
     93  *
     94  * <p>
     95  * IMPORTANT: WHEN ASSIGNING LAYOUT DATA TO A CONTROL, BE SURE TO USE
     96  * gridDataFactory.applyTo(control) AND NEVER control.setLayoutData(gridDataFactory).
     97  * </p>
     98  *
     99  * @since 3.2
    100  */
    101 public final class GridDataFactory {
    102   private final Control m_control;
    103   private final PixelConverter m_pixelConverter;
    104   private final GridData m_data;
    105 
    106   ////////////////////////////////////////////////////////////////////////////
    107   //
    108   // Constructor
    109   //
    110   ////////////////////////////////////////////////////////////////////////////
    111   private GridDataFactory(Control control, GridData gridData) {
    112     m_control = control;
    113     m_pixelConverter = new PixelConverter(m_control);
    114     //
    115     m_data = gridData;
    116     if (m_control.getLayoutData() != m_data) {
    117       m_control.setLayoutData(m_data);
    118     }
    119   }
    120 
    121   /**
    122    * Creates new {@link GridDataFactory} with new {@link GridData}.
    123    */
    124   public static GridDataFactory create(Control control) {
    125     return new GridDataFactory(control, new GridData());
    126   }
    127 
    128   /**
    129    * Creates new {@link GridDataFactory} for modifying {@link GridData} already installed in
    130    * control.
    131    */
    132   public static GridDataFactory modify(Control control) {
    133     GridData gridData;
    134     {
    135       Object existingLayoutData = control.getLayoutData();
    136       if (existingLayoutData instanceof GridData) {
    137         gridData = (GridData) existingLayoutData;
    138       } else {
    139         gridData = new GridData();
    140       }
    141     }
    142     return new GridDataFactory(control, gridData);
    143   }
    144 
    145   ////////////////////////////////////////////////////////////////////////////
    146   //
    147   // Span
    148   //
    149   ////////////////////////////////////////////////////////////////////////////
    150   /**
    151    * Sets the GridData span. The span controls how many cells are filled by the control.
    152    *
    153    * @param hSpan
    154    *          number of columns spanned by the control
    155    * @param vSpan
    156    *          number of rows spanned by the control
    157    * @return this
    158    */
    159   public GridDataFactory span(int hSpan, int vSpan) {
    160     m_data.horizontalSpan = hSpan;
    161     m_data.verticalSpan = vSpan;
    162     return this;
    163   }
    164 
    165   /**
    166    * Sets the GridData span. The span controls how many cells are filled by the control.
    167    *
    168    * @param hSpan
    169    *          number of columns spanned by the control
    170    * @return this
    171    */
    172   public GridDataFactory spanH(int hSpan) {
    173     m_data.horizontalSpan = hSpan;
    174     return this;
    175   }
    176 
    177   /**
    178    * Sets the GridData span. The span controls how many cells are filled by the control.
    179    *
    180    * @param vSpan
    181    *          number of rows spanned by the control
    182    * @return this
    183    */
    184   public GridDataFactory spanV(int vSpan) {
    185     m_data.verticalSpan = vSpan;
    186     return this;
    187   }
    188 
    189   ////////////////////////////////////////////////////////////////////////////
    190   //
    191   // Hint
    192   //
    193   ////////////////////////////////////////////////////////////////////////////
    194   /**
    195    * Sets the width and height hints. The width and height hints override the control's preferred
    196    * size. If either hint is set to SWT.DEFAULT, the control's preferred size is used.
    197    *
    198    * @param xHint
    199    *          horizontal hint (pixels), or SWT.DEFAULT to use the control's preferred size
    200    * @param yHint
    201    *          vertical hint (pixels), or SWT.DEFAULT to use the control's preferred size
    202    * @return this
    203    */
    204   public GridDataFactory hint(int xHint, int yHint) {
    205     m_data.widthHint = xHint;
    206     m_data.heightHint = yHint;
    207     return this;
    208   }
    209 
    210   /**
    211    * Sets hint in chars.
    212    */
    213   public GridDataFactory hintC(int xHintInChars, int yHintInChars) {
    214     hintHC(xHintInChars);
    215     hintVC(yHintInChars);
    216     return this;
    217   }
    218 
    219   /**
    220    * Sets the width hint.
    221    *
    222    * @return this
    223    */
    224   public GridDataFactory hintH(int xHint) {
    225     m_data.widthHint = xHint;
    226     return this;
    227   }
    228 
    229   /**
    230    * Sets the width hint to the minimum of current hint and given <code>otherHint</code>.
    231    *
    232    * @return this
    233    */
    234   public GridDataFactory hintHMin(int otherHint) {
    235     m_data.widthHint = Math.min(m_data.widthHint, otherHint);
    236     return this;
    237   }
    238 
    239   /**
    240    * Sets the width hint in chars.
    241    *
    242    * @return this
    243    */
    244   public GridDataFactory hintHC(int hintInChars) {
    245     return hintH(m_pixelConverter.convertWidthInCharsToPixels(hintInChars));
    246   }
    247 
    248   /**
    249    * Sets the width hint.
    250    *
    251    * @return this
    252    */
    253   public GridDataFactory hintHU(int hintInDLU) {
    254     return hintH(m_pixelConverter.convertHorizontalDLUsToPixels(hintInDLU));
    255   }
    256 
    257   /**
    258    * Sets the height hint.
    259    *
    260    * @return this
    261    */
    262   public GridDataFactory hintV(int yHint) {
    263     m_data.heightHint = yHint;
    264     return this;
    265   }
    266 
    267   /**
    268    * Sets the height hint in chars.
    269    *
    270    * @return this
    271    */
    272   public GridDataFactory hintVC(int hintInChars) {
    273     return hintV(m_pixelConverter.convertHeightInCharsToPixels(hintInChars));
    274   }
    275 
    276   /**
    277    * Increments horizontal hint on given value.
    278    *
    279    * @return this
    280    */
    281   public GridDataFactory hintHAdd(int increment) {
    282     return hintV(m_data.widthHint + increment);
    283   }
    284 
    285   /**
    286    * Increments vertical hint on given value.
    287    *
    288    * @return this
    289    */
    290   public GridDataFactory hintVAdd(int increment) {
    291     return hintV(m_data.heightHint + increment);
    292   }
    293 
    294   /**
    295    * Sets the width and height hints. The width and height hints override the control's preferred
    296    * size. If either hint is set to SWT.DEFAULT, the control's preferred size is used.
    297    *
    298    * @param hint
    299    *          size (pixels) to be used instead of the control's preferred size. If the x or y values
    300    *          are set to SWT.DEFAULT, the control's computeSize() method will be used to obtain that
    301    *          dimension of the preferred size.
    302    * @return this
    303    */
    304   public GridDataFactory hint(Point hint) {
    305     m_data.widthHint = hint.x;
    306     m_data.heightHint = hint.y;
    307     return this;
    308   }
    309 
    310   ////////////////////////////////////////////////////////////////////////////
    311   //
    312   // Minimum size
    313   //
    314   ////////////////////////////////////////////////////////////////////////////
    315   public GridDataFactory minH(int minimumWidth) {
    316     m_data.minimumWidth = minimumWidth;
    317     return this;
    318   }
    319 
    320   public GridDataFactory minHC(int widthInChars) {
    321     return minH(m_pixelConverter.convertWidthInCharsToPixels(widthInChars));
    322   }
    323 
    324   public GridDataFactory minV(int minimumHeight) {
    325     m_data.minimumHeight = minimumHeight;
    326     return this;
    327   }
    328 
    329   public GridDataFactory minVC(int heightInChars) {
    330     return minV(m_pixelConverter.convertHeightInCharsToPixels(heightInChars));
    331   }
    332 
    333   ////////////////////////////////////////////////////////////////////////////
    334   //
    335   // Alignment
    336   //
    337   ////////////////////////////////////////////////////////////////////////////
    338   /**
    339    * Sets the alignment of the control within its cell.
    340    *
    341    * @param hAlign
    342    *          horizontal alignment. One of SWT.BEGINNING, SWT.CENTER, SWT.END, or SWT.FILL.
    343    * @param vAlign
    344    *          vertical alignment. One of SWT.BEGINNING, SWT.CENTER, SWT.END, or SWT.FILL.
    345    * @return this
    346    */
    347   public GridDataFactory align(int hAlign, int vAlign) {
    348     m_data.horizontalAlignment = hAlign;
    349     m_data.verticalAlignment = vAlign;
    350     return this;
    351   }
    352 
    353   /**
    354    * Sets the horizontal and vertical alignment to GridData.FILL.
    355    */
    356   public GridDataFactory fill() {
    357     return align(GridData.FILL, GridData.FILL);
    358   }
    359 
    360   /**
    361    * Sets the horizontal alignment of the control within its cell.
    362    *
    363    * @param hAlign
    364    *          horizontal alignment. One of SWT.BEGINNING, SWT.CENTER, SWT.END, or SWT.FILL.
    365    * @return this
    366    */
    367   public GridDataFactory alignH(int hAlign) {
    368     m_data.horizontalAlignment = hAlign;
    369     return this;
    370   }
    371 
    372   /**
    373    * Sets the horizontal alignment of the control to GridData.BEGINNING
    374    *
    375    * @return this
    376    */
    377   public GridDataFactory alignHL() {
    378     return alignH(GridData.BEGINNING);
    379   }
    380 
    381   /**
    382    * Sets the horizontal alignment of the control to GridData.CENTER
    383    *
    384    * @return this
    385    */
    386   public GridDataFactory alignHC() {
    387     return alignH(GridData.CENTER);
    388   }
    389 
    390   /**
    391    * Sets the horizontal alignment of the control to GridData.FILL
    392    *
    393    * @return this
    394    */
    395   public GridDataFactory alignHF() {
    396     return alignH(GridData.FILL);
    397   }
    398 
    399   /**
    400    * Sets the horizontal alignment of the control to GridData.FILL
    401    *
    402    * @return this
    403    */
    404   public GridDataFactory fillH() {
    405     return alignHF();
    406   }
    407 
    408   /**
    409    * Sets the horizontal alignment of the control to GridData.END
    410    *
    411    * @return this
    412    */
    413   public GridDataFactory alignHR() {
    414     return alignH(GridData.END);
    415   }
    416 
    417   /**
    418    * Sets the vertical alignment of the control within its cell.
    419    *
    420    * @param vAlign
    421    *          vertical alignment. One of SWT.BEGINNING, SWT.CENTER, SWT.END, or SWT.FILL.
    422    * @return this
    423    */
    424   public GridDataFactory alignV(int vAlign) {
    425     m_data.verticalAlignment = vAlign;
    426     return this;
    427   }
    428 
    429   /**
    430    * Sets the vertical alignment of the control to GridData.BEGINNING
    431    *
    432    * @return this
    433    */
    434   public GridDataFactory alignVT() {
    435     return alignV(GridData.BEGINNING);
    436   }
    437 
    438   /**
    439    * Sets the vertical alignment of the control to GridData.CENTER
    440    *
    441    * @return this
    442    */
    443   public GridDataFactory alignVM() {
    444     return alignV(GridData.CENTER);
    445   }
    446 
    447   /**
    448    * Sets the vertical alignment of the control to GridData.FILL
    449    *
    450    * @return this
    451    */
    452   public GridDataFactory alignVF() {
    453     return alignV(GridData.FILL);
    454   }
    455 
    456   /**
    457    * Sets the vertical alignment of the control to GridData.FILL
    458    *
    459    * @return this
    460    */
    461   public GridDataFactory fillV() {
    462     return alignVF();
    463   }
    464 
    465   /**
    466    * Sets the vertical alignment of the control to GridData.END
    467    *
    468    * @return this
    469    */
    470   public GridDataFactory alignVB() {
    471     return alignV(GridData.END);
    472   }
    473 
    474   ////////////////////////////////////////////////////////////////////////////
    475   //
    476   // Indent
    477   //
    478   ////////////////////////////////////////////////////////////////////////////
    479   /**
    480    * Sets the indent of the control within the cell in pixels.
    481    */
    482   public GridDataFactory indentH(int hIndent) {
    483     m_data.horizontalIndent = hIndent;
    484     return this;
    485   }
    486 
    487   /**
    488    * Sets the indent of the control within the cell in characters.
    489    */
    490   public GridDataFactory indentHC(int hIndent) {
    491     m_data.horizontalIndent = m_pixelConverter.convertWidthInCharsToPixels(hIndent);
    492     return this;
    493   }
    494 
    495   ////////////////////////////////////////////////////////////////////////////
    496   //
    497   // Grab
    498   //
    499   ////////////////////////////////////////////////////////////////////////////
    500   /**
    501    * Determines whether extra horizontal or vertical space should be allocated to this control's
    502    * column when the layout resizes. If any control in the column is set to grab horizontal then the
    503    * whole column will grab horizontal space. If any control in the row is set to grab vertical then
    504    * the whole row will grab vertical space.
    505    *
    506    * @param horizontal
    507    *          true if the control's column should grow horizontally
    508    * @param vertical
    509    *          true if the control's row should grow vertically
    510    * @return this
    511    */
    512   public GridDataFactory grab(boolean horizontal, boolean vertical) {
    513     m_data.grabExcessHorizontalSpace = horizontal;
    514     m_data.grabExcessVerticalSpace = vertical;
    515     return this;
    516   }
    517 
    518   public GridDataFactory grabH() {
    519     m_data.grabExcessHorizontalSpace = true;
    520     return this;
    521   }
    522 
    523   public GridDataFactory grabV() {
    524     m_data.grabExcessVerticalSpace = true;
    525     return this;
    526   }
    527 
    528   public GridDataFactory grab() {
    529     return grab(true, true);
    530   }
    531 
    532   ////////////////////////////////////////////////////////////////////////////
    533   //
    534   // Exclude
    535   //
    536   ////////////////////////////////////////////////////////////////////////////
    537   public GridDataFactory exclude(boolean value) {
    538     m_data.exclude = value;
    539     return this;
    540   }
    541 }
    542