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 }