Home | History | Annotate | Download | only in controls
      1 /*******************************************************************************
      2  * Copyright (c) 2011 Google, Inc.
      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  *    Google, Inc. - initial API and implementation
     10  *******************************************************************************/
     11 package org.eclipse.wb.core.controls;
     12 
     13 import org.eclipse.swt.SWT;
     14 import org.eclipse.swt.SWTException;
     15 import org.eclipse.swt.custom.SashForm;
     16 import org.eclipse.swt.graphics.Rectangle;
     17 import org.eclipse.swt.widgets.Composite;
     18 
     19 /**
     20  * Instances of the class <code>SelfOrientingSashForm</code> implement a sash form that will
     21  * automatically reset its orientation based on the relationship between the width and height of the
     22  * client area. This is done so that the sash form can be placed in a view that will sometimes be
     23  * tall and narrow and sometimes be short and wide and still lay out its children in a pleasing way.
     24  * <p>
     25  *
     26  * @author unknown
     27  * @author Brian Wilkerson
     28  * @version $Revision: 1.2 $
     29  * @coverage core.control
     30  */
     31 public class SelfOrientingSashForm extends SashForm {
     32   ////////////////////////////////////////////////////////////////////////////
     33   //
     34   // Constructors
     35   //
     36   ////////////////////////////////////////////////////////////////////////////
     37   /**
     38    * Initialize a newly created control to have the given parent and style. The style describes the
     39    * behavior and appearance of this control.
     40    * <p>
     41    * The style value is either one of the style constants defined in the class <code>SWT</code>
     42    * which is applicable to instances of this class, or must be built by <em>bitwise OR</em>'ing
     43    * together (that is, using the <code>int</code> "|" operator) two or more of those
     44    * <code>SWT</code> style constants. The class description for all SWT widget classes should
     45    * include a comment which describes the style constants which are applicable to the class.
     46    * </p>
     47    *
     48    * @param parent
     49    *          a widget which will be the parent of the new instance (not null)
     50    * @param style
     51    *          the style of widget to construct
     52    *
     53    * @exception IllegalArgumentException
     54    *              <ul>
     55    *              <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
     56    *              </ul>
     57    * @exception SWTException
     58    *              <ul>
     59    *              <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the
     60    *              parent</li>
     61    *              <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
     62    *              </ul>
     63    */
     64   public SelfOrientingSashForm(Composite parent, int style) {
     65     super(parent, style);
     66   }
     67 
     68   ////////////////////////////////////////////////////////////////////////////
     69   //
     70   // Layout
     71   //
     72   ////////////////////////////////////////////////////////////////////////////
     73   /**
     74    * Returns SWT.HORIZONTAL if the controls in the SashForm are laid out side by side or
     75    * SWT.VERTICAL if the controls in the SashForm are laid out top to bottom.
     76    *
     77    * @return SWT.HORIZONTAL or SWT.VERTICAL
     78    */
     79   @Override
     80   public int getOrientation() {
     81     int currentOrientation = super.getOrientation();
     82     if (inSetOrientation) {
     83       return currentOrientation;
     84     }
     85     int preferredOrientation = isDisposed() ? currentOrientation : getPreferredOrientation();
     86     if (currentOrientation != preferredOrientation) {
     87       setOrientation(preferredOrientation);
     88     }
     89     return preferredOrientation;
     90   }
     91 
     92   boolean inSetOrientation = false;
     93 
     94   @Override
     95   public void setOrientation(int orientation) {
     96     if (inSetOrientation) {
     97       return;
     98     }
     99     inSetOrientation = true;
    100     super.setOrientation(orientation);
    101     inSetOrientation = false;
    102   }
    103 
    104   /**
    105    * If the receiver has a layout, ask the layout to <em>lay out</em> (that is, set the size and
    106    * location of) the receiver's children. If the argument is <code>true</code> the layout must not
    107    * rely on any cached information it is keeping about the children. If it is <code>false</code>
    108    * the layout may (potentially) simplify the work it is doing by assuming that the state of the
    109    * none of the receiver's children has changed since the last layout. If the receiver does not
    110    * have a layout, do nothing.
    111    *
    112    * @param changed
    113    *          <code>true</code> if the layout must flush its caches, and <code>false</code>
    114    *          otherwise
    115    *
    116    * @exception SWTException
    117    *              <ul>
    118    *              <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
    119    *              <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the
    120    *              receiver</li>
    121    *              </ul>
    122    */
    123   @Override
    124   public void layout(boolean changed) {
    125     Rectangle area;
    126     int oldOrientation, newOrientation;
    127     area = getClientArea();
    128     if (area.width > 0 && area.height > 0) {
    129       oldOrientation = super.getOrientation();
    130       newOrientation = SWT.HORIZONTAL;
    131       if (area.width < area.height) {
    132         newOrientation = SWT.VERTICAL;
    133       }
    134       if (newOrientation != oldOrientation) {
    135         setOrientation(newOrientation);
    136         changed = true;
    137       }
    138     }
    139     super.layout(changed);
    140   }
    141 
    142   private int getPreferredOrientation() {
    143     Rectangle area = getClientArea();
    144     if (area.width > 0 && area.height > 0 && area.width < area.height) {
    145       return SWT.VERTICAL;
    146     }
    147     return SWT.HORIZONTAL;
    148   }
    149 }