/* * This software is Copyright 2005,2006,2007,2008 Langdale Consultants. * Langdale Consultants can be contacted at: http://www.langdale.com.au */ package au.com.langdale.ui.builder; /******************************************************************************* * Copyright (c) 2005, 2006 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.LayoutConstants; import org.eclipse.jface.util.Geometry; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Layout; import org.eclipse.ui.forms.widgets.FormText; /** * Public version of a private jface class. * The logic has been reworked to suit Templates and Assembly. * */ public class LayoutGenerator { private static final Point defaultSize = new Point(150, 150); private static final int wrapSize = 350; private static final GridDataFactory nonWrappingLabelData = GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).grab(false, false); private static boolean hasStyle(Control c, int style) { return (c.getStyle() & style) != 0; } private static boolean hasMethod(Control control, String name, Class[] parameterTypes) { Class c = control.getClass(); try { return c.getMethod(name, parameterTypes) != null; } catch (SecurityException e) { return false; } catch (NoSuchMethodException e) { return false; } } /** * Determine how to layout the given control within a Grid. * The layout information is returned indirectly in the form * of an object that sets layout on a control. */ public static GridDataFactory defaultsFor(Control control) { if (control instanceof Button) { Button button = (Button) control; if (hasStyle(button, SWT.CHECK)) { return nonWrappingLabelData.copy(); } else { return GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).hint(Geometry.max(button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true), LayoutConstants.getMinButtonSize())); } } if (control instanceof Composite) { Composite composite = (Composite) control; Layout theLayout = composite.getLayout(); if (theLayout instanceof GridLayout) { boolean growsHorizontally = false; boolean growsVertically = false; Control[] children = composite.getChildren(); for (int i = 0; i < children.length; i++) { Control child = children[i]; GridData data = (GridData) child.getLayoutData(); if (data != null) { if (data.grabExcessHorizontalSpace) { growsHorizontally = true; } if (data.grabExcessVerticalSpace) { growsVertically = true; } } } return GridDataFactory.fillDefaults().grab(growsHorizontally, growsVertically); } } Point size = control.getSize(); boolean wrapping = hasStyle(control, SWT.WRAP); boolean containsText = hasMethod(control, "setText", new Class[] { String.class }) || (control instanceof FormText); boolean variable = ! (control instanceof Label); boolean variableText = containsText && variable; boolean hScroll = hasStyle(control, SWT.H_SCROLL); boolean vScroll = hasStyle(control, SWT.V_SCROLL); boolean multiLine = hasStyle(control, SWT.MULTI); boolean grabHorizontal = hScroll || variableText && !wrapping || containsText && wrapping; boolean grabVertical = (vScroll || variableText && multiLine) && size.y <= 0; int hHint, vHint, vAlign; if (grabHorizontal) { // For horizontally-scrollable controls, override their horizontal // preferred size with a constant if(wrapping) { // For wrapping controls, there are two cases. if(containsText) // 1. For controls that contain text (like wrapping labels, // read-only text boxes, // etc.) override their preferred size with the preferred wrapping // point and // make them grab horizontal space. hHint = wrapSize; else // 2. For non-text controls (like wrapping toolbars), assume that // their non-wrapped // size is best. hHint = SWT.DEFAULT; } else { hHint = defaultSize.x; } } else { hHint = SWT.DEFAULT; } if( size.y > 0) { vHint = size.y; } else if(grabVertical) { vHint = defaultSize.y; } else { vHint = SWT.DEFAULT; } if (containsText && ! variableText) { // Heuristic for labels: Controls that contain non-wrapping read-only // text should be // center-aligned rather than fill-aligned vAlign = SWT.CENTER; } else { vAlign = SWT.FILL; } return GridDataFactory.fillDefaults().grab(grabHorizontal, grabVertical).align(SWT.FILL, vAlign).hint(hHint, vHint); } }