package org.eclipse.ui.tests.forms.layout;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.ui.forms.widgets.ILayoutExtension;
/**
* Factory for creating test controls which try to maintain a constant area when
* their width changes.
*/
public final class ControlFactory {
/**
* Implements a layout intended for use within unit tests. The layout simulates
* a wrapping control by attempting to maintain a constant area. When the layout
* is compressed or stretched, its preferred height will increase or decrease in
* order to preserve the layout's area.
* <p>
* This layout also records whether or not its cache was ever flushed, allowing
* unit tests to test that the flush flags propagate correctly.
* <p>
* This layout does not reposition its children. It is meant to be used with
* Composites that have no children.
*/
public static class TestLayout extends Layout {
final int maxWidth;
final int desiredArea;
public boolean wasChanged = false;
public Rectangle bounds = new Rectangle(0, 0, 0, 0);
public TestLayout(int maxWidth, int desiredArea) {
super();
this.maxWidth = maxWidth;
this.desiredArea = desiredArea;
}
protected void recordChanged(boolean changed) {
if (changed) {
this.wasChanged = changed;
}
}
@Override
protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
recordChanged(flushCache);
if (wHint == SWT.DEFAULT) {
wHint = maxWidth;
}
if (hHint == SWT.DEFAULT) {
hHint = wHint <= 0 ? desiredArea : (desiredArea / wHint);
}
return new Point(wHint, hHint);
}
@Override
protected void layout(Composite composite, boolean flushCache) {
recordChanged(flushCache);
bounds = composite.getBounds();
}
}
private static class TestLayoutWithExtension extends TestLayout implements ILayoutExtension {
final int minWidth;
public TestLayoutWithExtension(int minWidth, int maxWidth, int desiredArea) {
super(maxWidth, desiredArea);
this.minWidth = minWidth;
}
@Override
public int computeMinimumWidth(Composite parent, boolean changed) {
recordChanged(changed);
return minWidth;
}
@Override
public int computeMaximumWidth(Composite parent, boolean changed) {
recordChanged(changed);
return maxWidth;
}
}
/**
* Creates a wrapping layout that does not implement ILayoutExtension and
* attempts to maintain a constant area.
*/
public static TestLayout createLayout(int maxWidth, int heightAtMaxWidth) {
int area = heightAtMaxWidth * maxWidth;
return new TestLayout(maxWidth, area);
}
/**
* Creates a wrapping layout that implements ILayoutExtension and attempts to maintain a constant area.
*/
public static TestLayout createLayout(int minWidth, int maxWidth, int heightAtMaxWidth) {
int area = heightAtMaxWidth * maxWidth;
return new TestLayoutWithExtension(minWidth, maxWidth, area);
}
/**
* Creates a new composite that attempts to maintain a constant area. The
* composite's layout implements ILayoutExtension. It will not lay out its
* children.
*/
public static Composite create(Composite parent, int minWidth, int maxWidth, int heightAtMaxWidth) {
Composite newControl = new Composite(parent, SWT.NONE);
newControl.setLayout(createLayout(minWidth, maxWidth, heightAtMaxWidth));
return newControl;
}
/**
* Creates a new composite that attempts to maintain a constant area. The
* composite's layout does not implement ILayoutExtension. It will not lay
* out its children.
*/
public static Composite create(Composite parent, int maxWidth, int heightAtMaxWidth) {
Composite newControl = new Composite(parent, SWT.NONE);
newControl.setLayout(createLayout(maxWidth, heightAtMaxWidth));
return newControl;
}
}