Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Xenos2016-03-26 17:14:49 +0000
committerStefan Xenos2017-05-04 20:02:40 +0000
commit1e645458b2ef61bd7d83b1f5c7fb28dcde7ace58 (patch)
tree9f48338f95f62689b1ee452f747db1522e163121
parente09eb0f702ecafa189017550bb8f1ca0edddd125 (diff)
downloadeclipse.platform.ui-1e645458b2ef61bd7d83b1f5c7fb28dcde7ace58.tar.gz
eclipse.platform.ui-1e645458b2ef61bd7d83b1f5c7fb28dcde7ace58.tar.xz
eclipse.platform.ui-1e645458b2ef61bd7d83b1f5c7fb28dcde7ace58.zip
Bug 196692 - Forms cannot handle most kinds of wrapping controlsI20170504-2000
Note that if this change is reverted or cherry-picked, you must also include the previous change elaskavaia.cdt@gmail.com as well. Change-Id: I781fab28ce427874f9d41662a98a1ebfa3840b18
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ColumnLayout.java168
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ExpandableComposite.java26
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/Form.java43
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/FormToolkit.java2
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ImageHyperlink.java19
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/LayoutComposite.java39
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ScrolledPageBook.java12
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/SharedScrolledComposite.java12
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/SizeCache.java66
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/TableWrapLayout.java27
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ToggleHyperlink.java13
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/ControlSegment.java11
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormHeading.java45
-rw-r--r--bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormUtil.java88
-rwxr-xr-xtests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/AllFormsTests.java4
-rwxr-xr-xtests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/AllLayoutTests.java6
-rw-r--r--tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/ControlFactory.java130
-rw-r--r--tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/TestColumnWrapLayout.java303
-rwxr-xr-xtests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/TestTableWrapLayout.java301
-rw-r--r--tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/ExpandableCompositeTest.java8
-rw-r--r--tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/HintAdjustmentTest.java247
-rw-r--r--tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/SizeCacheTest.java53
22 files changed, 1200 insertions, 423 deletions
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ColumnLayout.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ColumnLayout.java
index 6c7bd804be1..fa3642bf43d 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ColumnLayout.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ColumnLayout.java
@@ -18,6 +18,7 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.ui.internal.forms.widgets.ColumnLayoutUtils;
+import org.eclipse.ui.internal.forms.widgets.FormUtil;
/**
* This layout manager arranges children of the composite parent in vertical
* columns. All the columns are identical size and children are stretched
@@ -71,52 +72,101 @@ public final class ColumnLayout extends Layout implements ILayoutExtension {
*/
public int rightMargin = 5;
+ private LayoutCache cache = new LayoutCache();
+
+ private final static int MIN_SIZE = -2;
+
/**
* Creates a new instance of the column layout.
*/
public ColumnLayout() {
}
+ private void updateCache(Composite composite, boolean flushCache) {
+ Control[] children = composite.getChildren();
+ if (flushCache) {
+ cache.flush();
+ }
+ cache.setControls(children);
+ }
+
@Override
protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
- if (wHint == 0)
- return computeSize(composite, wHint, hHint, minNumColumns);
- else if (wHint == SWT.DEFAULT)
- return computeSize(composite, wHint, hHint, maxNumColumns);
- else
- return computeSize(composite, wHint, hHint, -1);
+ updateCache(composite, flushCache);
+ return computeSize(composite, wHint, hHint);
+ }
+
+ /**
+ * Given a desired number of columns, this returns a clamped result that falls
+ * within the range specified by the minimum and maximum number of columns.
+ */
+ private int clampNumColumns(Composite parent, int desiredNumColumns) {
+ int ncolumns = desiredNumColumns;
+ ncolumns = Math.min(ncolumns, parent.getChildren().length);
+ ncolumns = Math.min(ncolumns, maxNumColumns);
+ ncolumns = Math.max(ncolumns, minNumColumns);
+ ncolumns = Math.max(ncolumns, 1);
+ return ncolumns;
}
- private Point computeSize(Composite parent, int wHint, int hHint, int ncolumns) {
+ private int computeOptimalNumColumnsForWidth(Composite parent, int width) {
+ if (minNumColumns >= maxNumColumns || parent.getChildren().length <= minNumColumns) {
+ return clampNumColumns(parent, minNumColumns);
+ }
+
+ Control[] children = parent.getChildren();
+ int minColWidth = 0;
+
+ for (int i = 0; i < children.length; i++) {
+ // To maximize the number of columns:
+ int nextWidth = computeMinimumWidth(i);
+
+ // To minimize the number of columns:
+ // int nextWidth = computeControlSize(i, SWT.DEFAULT).x;
+
+ minColWidth = Math.max(minColWidth, nextWidth);
+ }
+
+ return clampNumColumns(parent,
+ (width - leftMargin - rightMargin + horizontalSpacing) / (minColWidth + horizontalSpacing));
+ }
+
+ private int computeColumnWidthForNumColumns(int layoutWidth, int numColumns) {
+ return ((layoutWidth - leftMargin - rightMargin) - (numColumns - 1) * horizontalSpacing) / numColumns;
+ }
+
+ private Point computeSize(Composite parent, int wHint, int hHint) {
Control[] children = parent.getChildren();
- int cwidth = 0;
int cheight = 0;
Point[] sizes = new Point[children.length];
- int cwHint = SWT.DEFAULT;
- if (ncolumns != -1) {
- cwHint = wHint - leftMargin - rightMargin - (ncolumns - 1) * horizontalSpacing;
- if (cwHint <= 0)
- cwHint = 0;
- else
- cwHint /= ncolumns;
+ int columnWidth = 0;
+ int nColumns;
+ if (wHint == SWT.DEFAULT) {
+ nColumns = clampNumColumns(parent, maxNumColumns);
+
+ for (int i = 0; i < children.length; i++) {
+ columnWidth = Math.max(columnWidth, computeControlSize(i, SWT.DEFAULT).x);
+ }
+ } else if (wHint == MIN_SIZE) {
+ nColumns = clampNumColumns(parent, 0);
+
+ for (int i = 0; i < children.length; i++) {
+ columnWidth = Math.max(columnWidth, computeMinimumWidth(i));
+ }
+ } else {
+ nColumns = computeOptimalNumColumnsForWidth(parent, wHint);
+ columnWidth = computeColumnWidthForNumColumns(wHint, nColumns);
}
for (int i = 0; i < children.length; i++) {
- sizes[i] = computeControlSize(children[i], cwHint);
- cwidth = Math.max(cwidth, sizes[i].x);
+ sizes[i] = computeControlSize(i, columnWidth);
cheight += sizes[i].y;
}
- if (ncolumns == -1) {
- // must compute
- ncolumns = (wHint - leftMargin - rightMargin - horizontalSpacing) / (cwidth + horizontalSpacing);
- ncolumns = Math.min(ncolumns, children.length);
- ncolumns = Math.max(ncolumns, minNumColumns);
- ncolumns = Math.min(ncolumns, maxNumColumns);
- }
- int perColHeight = ColumnLayoutUtils.computeColumnHeight(ncolumns, sizes, cheight, verticalSpacing);
+
+ int perColHeight = ColumnLayoutUtils.computeColumnHeight(nColumns, sizes, cheight, verticalSpacing);
int colHeight = 0;
- int[] heights = new int[ncolumns];
+ int[] heights = new int[nColumns];
int ncol = 0;
boolean fillIn = false;
@@ -126,7 +176,7 @@ public final class ColumnLayout extends Layout implements ILayoutExtension {
if (i>0 && colHeight + childHeight > perColHeight) {
heights[ncol] = colHeight;
ncol++;
- if (ncol == ncolumns || fillIn) {
+ if (ncol == nColumns || fillIn) {
// overflow - start filling in
fillIn = true;
ncol = findShortestColumn(heights);
@@ -140,21 +190,33 @@ public final class ColumnLayout extends Layout implements ILayoutExtension {
heights[ncol] = Math.max(heights[ncol],colHeight);
Point size = new Point(0, 0);
- for (int i = 0; i < ncolumns; i++) {
+ for (int i = 0; i < nColumns; i++) {
size.y = Math.max(size.y, heights[i]);
}
- size.x = cwidth * ncolumns + (ncolumns - 1) * horizontalSpacing;
+ size.x = columnWidth * nColumns + (nColumns - 1) * horizontalSpacing;
size.x += leftMargin + rightMargin;
- //System.out.println("ColumnLayout: whint="+wHint+", size.x="+size.x);
size.y += topMargin + bottomMargin;
+ if (hHint != SWT.DEFAULT) {
+ size.y = hHint;
+ }
return size;
}
- private Point computeControlSize(Control c, int wHint) {
+ private int computeMinimumWidth(int i) {
+ SizeCache sc = cache.getCache(i);
+ return sc.computeMinimumWidth();
+ }
+
+ private Point computeControlSize(int controlIndex, int wHint) {
+ SizeCache sizeCache = cache.getCache(controlIndex);
+ Control c = sizeCache.getControl();
ColumnLayoutData cd = (ColumnLayoutData) c.getLayoutData();
- int widthHint = cd != null ? cd.widthHint : wHint;
- int heightHint = cd != null ? cd.heightHint : SWT.DEFAULT;
- return c.computeSize(widthHint, heightHint);
+
+ if (cd != null) {
+ return FormUtil.computeControlSize(sizeCache, wHint, cd.widthHint, cd.heightHint,
+ cd.horizontalAlignment == ColumnLayoutData.FILL);
+ }
+ return FormUtil.computeControlSize(sizeCache, wHint, SWT.DEFAULT, SWT.DEFAULT, true);
}
private int findShortestColumn(int[] heights) {
@@ -171,32 +233,23 @@ public final class ColumnLayout extends Layout implements ILayoutExtension {
@Override
protected void layout(Composite parent, boolean flushCache) {
+ updateCache(parent, flushCache);
Control[] children = parent.getChildren();
Rectangle carea = parent.getClientArea();
- int cwidth = 0;
+ int nColumns = computeOptimalNumColumnsForWidth(parent, carea.width);
+ int columnWidth = computeColumnWidthForNumColumns(carea.width, nColumns);
+
int cheight = 0;
Point[] sizes = new Point[children.length];
for (int i = 0; i < children.length; i++) {
- sizes[i] = computeControlSize(children[i], SWT.DEFAULT);
- cwidth = Math.max(cwidth, sizes[i].x);
+ sizes[i] = computeControlSize(i, columnWidth);
cheight += sizes[i].y;
}
- int ncolumns = (carea.width - leftMargin - rightMargin + horizontalSpacing) / (cwidth + horizontalSpacing);
- ncolumns = Math.min(ncolumns, children.length);
- ncolumns = Math.max(ncolumns, minNumColumns);
- ncolumns = Math.min(ncolumns, maxNumColumns);
- int realWidth = (carea.width - leftMargin - rightMargin + horizontalSpacing) / ncolumns - horizontalSpacing;
-// int childrenPerColumn = children.length / ncolumns;
-// if (children.length % ncolumns != 0)
-// childrenPerColumn++;
-// int colWidth = 0;
-
- int fillWidth = Math.max(cwidth, realWidth);
- int perColHeight = ColumnLayoutUtils.computeColumnHeight(ncolumns, sizes, cheight, verticalSpacing);
+ int perColHeight = ColumnLayoutUtils.computeColumnHeight(nColumns, sizes, cheight, verticalSpacing);
int colHeight = 0;
- int[] heights = new int[ncolumns];
+ int[] heights = new int[nColumns];
int ncol = 0;
int x = leftMargin;
boolean fillIn = false;
@@ -206,21 +259,21 @@ public final class ColumnLayout extends Layout implements ILayoutExtension {
Point csize = sizes[i];
ColumnLayoutData cd = (ColumnLayoutData) child.getLayoutData();
int align = cd != null ? cd.horizontalAlignment : ColumnLayoutData.FILL;
- int childWidth = align == ColumnLayoutData.FILL ? fillWidth : csize.x;
+ int childWidth = csize.x;
if (i>0 && colHeight + csize.y > perColHeight) {
heights[ncol] = colHeight;
- if (fillIn || ncol == ncolumns-1) {
+ if (fillIn || ncol == nColumns - 1) {
// overflow - start filling in
fillIn = true;
ncol = findShortestColumn(heights);
- x = leftMargin + ncol * (fillWidth + horizontalSpacing);
+ x = leftMargin + ncol * (columnWidth + horizontalSpacing);
}
else {
ncol++;
- x += fillWidth + horizontalSpacing;
+ x += columnWidth + horizontalSpacing;
}
colHeight = heights[ncol];
}
@@ -234,10 +287,10 @@ public final class ColumnLayout extends Layout implements ILayoutExtension {
child.setBounds(x, topMargin+colHeight, childWidth, csize.y);
break;
case ColumnLayoutData.RIGHT :
- child.setBounds(x + fillWidth - childWidth, topMargin+colHeight, childWidth, csize.y);
+ child.setBounds(x + columnWidth - childWidth, topMargin + colHeight, childWidth, csize.y);
break;
case ColumnLayoutData.CENTER :
- child.setBounds(x + fillWidth / 2 - childWidth / 2, topMargin+colHeight, childWidth, csize.y);
+ child.setBounds(x + columnWidth / 2 - childWidth / 2, topMargin + colHeight, childWidth, csize.y);
break;
}
@@ -252,6 +305,7 @@ public final class ColumnLayout extends Layout implements ILayoutExtension {
@Override
public int computeMinimumWidth(Composite parent, boolean changed) {
- return computeSize(parent, 0, SWT.DEFAULT, changed).x;
+ updateCache(parent, changed);
+ return computeSize(parent, MIN_SIZE, SWT.DEFAULT).x;
}
}
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ExpandableComposite.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ExpandableComposite.java
index f732fa5562a..1cd4f385b5d 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ExpandableComposite.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ExpandableComposite.java
@@ -225,6 +225,8 @@ public class ExpandableComposite extends Canvas {
private class ExpandableLayout extends Layout implements ILayoutExtension {
+ private static final int MIN_WIDTH = -2;
+
private SizeCache toggleCache = new SizeCache();
private SizeCache textClientCache = new SizeCache();
@@ -318,10 +320,8 @@ public class ExpandableComposite extends Canvas {
boolean leftAlignment = textClient != null && (expansionStyle & LEFT_TEXT_CLIENT_ALIGNMENT) != 0;
if (toggle != null) {
- // if label control is absent we vcenter the toggle, because
- // text client is usually a lot thicker
- // before it was using leftAlignment flag for that which I think
- // is not related to this at all
+ // if label control is absent we vertically center the toggle,
+ // because the text client is usually a lot thicker
int ty = size.x == 0 ? (height - toggleSize.y) / 2 : 0;
ty = Math.max(ty, 0);
ty += marginHeight + tvmargin;
@@ -418,7 +418,7 @@ public class ExpandableComposite extends Canvas {
Point labelDefault = this.textLabelCache.computeSize(SWT.DEFAULT, SWT.DEFAULT);
int width = 0;
- if (wHint == SWT.DEFAULT) {
+ if (wHint == SWT.DEFAULT || wHint == MIN_WIDTH) {
width += toggleWidthPlusGap;
width += labelDefault.x;
width += gapBetweenTcAndLabel;
@@ -463,17 +463,23 @@ public class ExpandableComposite extends Canvas {
if ((expansionStyle & CLIENT_INDENT) != 0)
clientIndent = toggleWidthPlusGap;
- if (cwHint != SWT.DEFAULT) {
+ if (cwHint != SWT.DEFAULT && cwHint != MIN_WIDTH) {
cwHint -= marginWidth + marginWidth + thmargin + thmargin;
if ((expansionStyle & CLIENT_INDENT) != 0)
if (tcsize.x > 0)
cwHint -= toggleWidthPlusGap;
}
Point dsize = null;
- Point csize = clientCache.computeSize(cwHint, SWT.DEFAULT);
+ Point csize;
+ if (cwHint == MIN_WIDTH) {
+ int minWidth = clientCache.computeMinimumWidth();
+ csize = clientCache.computeSize(minWidth, SWT.DEFAULT);
+ } else {
+ csize = clientCache.computeSize(cwHint, SWT.DEFAULT);
+ }
if (getDescriptionControl() != null) {
int dwHint = cwHint;
- if (dwHint == SWT.DEFAULT) {
+ if (dwHint == SWT.DEFAULT || dwHint == MIN_WIDTH) {
dwHint = csize.x;
if ((expansionStyle & CLIENT_INDENT) != 0)
dwHint -= toggleWidthPlusGap;
@@ -496,7 +502,7 @@ public class ExpandableComposite extends Canvas {
int resultWidth = width + marginWidth + marginWidth + thmargin + thmargin;
- if (wHint != SWT.DEFAULT) {
+ if (wHint != SWT.DEFAULT && wHint != MIN_WIDTH) {
resultWidth = wHint;
}
@@ -512,7 +518,7 @@ public class ExpandableComposite extends Canvas {
@Override
public int computeMinimumWidth(Composite parent, boolean changed) {
- return computeSize(parent, 0, SWT.DEFAULT, changed).x;
+ return computeSize(parent, MIN_WIDTH, SWT.DEFAULT, changed).x;
}
@Override
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/Form.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/Form.java
index cb4c167ccc4..7caef61b7f1 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/Form.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/Form.java
@@ -108,7 +108,8 @@ public class Form extends Composite {
private class FormLayout extends Layout implements ILayoutExtension {
@Override
public int computeMinimumWidth(Composite composite, boolean flushCache) {
- return computeSize(composite, 5, SWT.DEFAULT, flushCache).x;
+ initCaches(flushCache);
+ return Math.max(headCache.computeMinimumWidth(), bodyCache.computeMinimumWidth());
}
@Override
@@ -119,18 +120,12 @@ public class Form extends Composite {
@Override
public Point computeSize(Composite composite, int wHint, int hHint,
boolean flushCache) {
- if (flushCache) {
- bodyCache.flush();
- headCache.flush();
- }
- bodyCache.setControl(body);
- headCache.setControl(head);
+ initCaches(flushCache);
int width = 0;
int height = 0;
- Point hsize = headCache.computeSize(FormUtil.getWidthHint(wHint,
- head), SWT.DEFAULT);
+ Point hsize = headCache.computeSize(wHint, SWT.DEFAULT);
width = Math.max(hsize.x, width);
height = hsize.y;
@@ -140,8 +135,7 @@ public class Form extends Composite {
if (ignoreBody)
bsize = new Point(0,0);
else
- bsize = bodyCache.computeSize(FormUtil.getWidthHint(wHint,
- body), SWT.DEFAULT);
+ bsize = bodyCache.computeSize(wHint, SWT.DEFAULT);
width = Math.max(bsize.x, width);
height += bsize.y;
return new Point(width, height);
@@ -149,12 +143,7 @@ public class Form extends Composite {
@Override
protected void layout(Composite composite, boolean flushCache) {
- if (flushCache) {
- bodyCache.flush();
- headCache.flush();
- }
- bodyCache.setControl(body);
- headCache.setControl(head);
+ initCaches(flushCache);
Rectangle carea = composite.getClientArea();
Point hsize = headCache.computeSize(carea.width, SWT.DEFAULT);
@@ -162,6 +151,15 @@ public class Form extends Composite {
bodyCache
.setBounds(0, hsize.y, carea.width, carea.height - hsize.y);
}
+
+ private void initCaches(boolean flushCache) {
+ if (flushCache) {
+ bodyCache.flush();
+ headCache.flush();
+ }
+ bodyCache.setControl(body);
+ headCache.setControl(head);
+ }
}
/**
@@ -175,7 +173,7 @@ public class Form extends Composite {
super.setLayout(new FormLayout());
head = new FormHeading(this, SWT.NULL);
head.setMenu(parent.getMenu());
- body = new LayoutComposite(this, SWT.NULL);
+ body = new Composite(this, SWT.NULL);
body.setMenu(parent.getMenu());
}
@@ -193,15 +191,6 @@ public class Form extends Composite {
}
/**
- * Fully delegates the size computation to the internal layout manager.
- */
- @Override
- public final Point computeSize(int wHint, int hHint, boolean changed) {
- return ((FormLayout) getLayout()).computeSize(this, wHint, hHint,
- changed);
- }
-
- /**
* Prevents from changing the custom control layout.
*/
@Override
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/FormToolkit.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/FormToolkit.java
index edeeada57ec..b3cacba24da 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/FormToolkit.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/FormToolkit.java
@@ -309,7 +309,7 @@ public class FormToolkit {
* @return the composite widget
*/
public Composite createComposite(Composite parent, int style) {
- Composite composite = new LayoutComposite(parent, style | orientation);
+ Composite composite = new Composite(parent, style | orientation);
adapt(composite);
return composite;
}
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ImageHyperlink.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ImageHyperlink.java
index 4b53e79ec61..2d6fa5d5b5d 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ImageHyperlink.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ImageHyperlink.java
@@ -156,15 +156,20 @@ public class ImageHyperlink extends Hyperlink {
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
checkWidget();
+ Rectangle trim = computeTrim(0, 0, 0, 0);
Point isize = computeMaxImageSize();
- int spacing = isize.x>0?textSpacing:0;
+ int spacing = isize.x > 0 ? textSpacing : 0;
Point textSize = null;
if (getText() != null) {
int innerWHint = wHint;
if (wHint != SWT.DEFAULT) {
- innerWHint = wHint - 2 * marginWidth - isize.x - spacing;
+ innerWHint = wHint - 2 * marginWidth - isize.x - spacing - trim.width;
}
- textSize = super.computeSize(innerWHint, hHint, changed);
+ int innerHHint = SWT.DEFAULT;
+ if (hHint != SWT.DEFAULT) {
+ innerHHint = hHint - trim.height;
+ }
+ textSize = super.computeSize(innerWHint, innerHHint, changed);
}
int width = isize.x;
int height = isize.y;
@@ -175,7 +180,13 @@ public class ImageHyperlink extends Hyperlink {
}
width += 2 * marginWidth;
height += 2 * marginHeight;
- return new Point(width, height);
+
+ if (wHint != SWT.DEFAULT)
+ width = wHint;
+ if (hHint != SWT.DEFAULT)
+ height = hHint;
+
+ return new Point(width + trim.width, height + trim.height);
}
@Override
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/LayoutComposite.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/LayoutComposite.java
deleted file mode 100644
index 7dbde00e0d7..00000000000
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/LayoutComposite.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2015 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
- *******************************************************************************/
-package org.eclipse.ui.forms.widgets;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Layout;
-/**
- * The class overrides default method for computing size in Composite by
- * accepting size returned from layout managers as-is. The default code accepts
- * width or height hint assuming it is correct. However, it is possible that
- * the computation using the provided width hint results in a real size that is
- * larger. This can result in wrapped text widgets being clipped, asking to
- * render in bounds narrower than the longest word.
- */
-/* package */class LayoutComposite extends Composite {
- public LayoutComposite(Composite parent, int style) {
- super(parent, style);
- setMenu(parent.getMenu());
- }
- @Override
- public Point computeSize(int wHint, int hHint, boolean changed) {
- Layout layout = getLayout();
- if (layout instanceof TableWrapLayout)
- return ((TableWrapLayout) layout).computeSize(this, wHint, hHint,
- changed);
- if (layout instanceof ColumnLayout)
- return ((ColumnLayout) layout).computeSize(this, wHint, hHint,
- changed);
- return super.computeSize(wHint, hHint, changed);
- }
-}
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ScrolledPageBook.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ScrolledPageBook.java
index 900786857ce..15f0850e8f1 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ScrolledPageBook.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ScrolledPageBook.java
@@ -78,7 +78,15 @@ public class ScrolledPageBook extends SharedScrolledComposite {
*/
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
- Rectangle trim = computeTrim(0, 0, 10, 10);
+ int width = 10;
+ int height = 10;
+ if (wHint != SWT.DEFAULT) {
+ width = wHint;
+ }
+ if (hHint != SWT.DEFAULT) {
+ height = hHint;
+ }
+ Rectangle trim = computeTrim(0, 0, width, height);
return new Point(trim.width, trim.height);
}
/**
@@ -209,7 +217,7 @@ public class ScrolledPageBook extends SharedScrolledComposite {
return currentPage;
}
private Composite createPage() {
- Composite page = new LayoutComposite(pageBook, SWT.NULL);
+ Composite page = new Composite(pageBook, SWT.NULL);
page.setBackground(getBackground());
page.setForeground(getForeground());
page.setMenu(pageBook.getMenu());
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/SharedScrolledComposite.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/SharedScrolledComposite.java
index b64b460b25e..349b63030f4 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/SharedScrolledComposite.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/SharedScrolledComposite.java
@@ -180,15 +180,17 @@ public abstract class SharedScrolledComposite extends ScrolledComposite {
if (flushCache) {
contentCache.flush();
}
- Point newSize = contentCache.computeSize(FormUtil.getWidthHint(
- clientArea.width, c), FormUtil.getHeightHint(clientArea.height,
- c));
+
+ int minWidth = contentCache.computeMinimumWidth();
+ int minHeight = contentCache.computeSize(minWidth, SWT.DEFAULT).y;
if (!(expandHorizontal && expandVertical)) {
- c.setSize(newSize);
+ Point preferredSize = contentCache.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+
+ c.setSize(preferredSize);
}
- setMinSize(newSize);
+ setMinSize(new Point(minWidth, minHeight));
FormUtil.updatePageIncrement(this);
// reduce vertical scroll increment if necessary
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/SizeCache.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/SizeCache.java
index 958e2e3abba..0ae267338c8 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/SizeCache.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/SizeCache.java
@@ -29,7 +29,6 @@ import org.eclipse.swt.widgets.Slider;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.Tree;
-import org.eclipse.ui.internal.forms.widgets.FormUtil;
/**
* Caches the preferred size of an SWT control
@@ -48,6 +47,7 @@ public class SizeCache {
private Point cachedHeight;
private int minimumWidth;
+ private int heightAtMinimumWidth;
private int maximumWidth;
/**
@@ -115,6 +115,8 @@ public class SizeCache {
independentDimensions = independentLengthAndWidth(control);
preferredWidthOrLargerIsMinimumHeight = isPreferredWidthMaximum(control);
computeHintOffset(control);
+ // TODO: We could probably speed things up quite a bit by using flush(false).
+ // Doing a recursive flush is probably not necessary here.
flush();
}
}
@@ -144,6 +146,7 @@ public class SizeCache {
minimumWidth = -1;
maximumWidth = -1;
minimumHeight = -1;
+ heightAtMinimumWidth = -1;
if (recursive || dirtySize != null) {
if (control == null || control.isDisposed()) {
@@ -183,7 +186,7 @@ public class SizeCache {
// This may not be what control returns but this means control won't
// fit in these dimensions and exactly how much it does not fit it
// probably not a concern of layout
- return new Point(widthHint + widthAdjustment, heightHint + heightAdjustment);
+ return new Point(widthHint, heightHint);
}
// No hints given -- find the preferred size
@@ -197,11 +200,11 @@ public class SizeCache {
Point result = Geometry.copy(getPreferredSize());
if (widthHint != SWT.DEFAULT) {
- result.x = widthHint + widthAdjustment;
+ result.x = widthHint;
}
if (heightHint != SWT.DEFAULT) {
- result.y = heightHint + heightAdjustment;
+ result.y = heightHint;
}
return result;
@@ -212,11 +215,15 @@ public class SizeCache {
// If we know the control's preferred size
if (preferredSize != null) {
// If the given width is the preferred width, then return the preferred size
- if (widthHint + widthAdjustment == preferredSize.x) {
+ if (widthHint == preferredSize.x) {
return Geometry.copy(preferredSize);
}
}
+ if (minimumWidth != -1 && heightAtMinimumWidth != -1 && widthHint == minimumWidth) {
+ return new Point(widthHint, heightAtMinimumWidth);
+ }
+
// If we have a cached height measurement
if (cachedHeightQuery != -1) {
// If this was measured with the same width hint
@@ -230,12 +237,12 @@ public class SizeCache {
// we can compute the result based on the preferred height
if (preferredWidthOrLargerIsMinimumHeight) {
// Computed the preferred size (if we don't already know it)
- getPreferredSize();
+ Point preferred = getPreferredSize();
// If the width hint is larger than the preferred width, then
// we can compute the result from the preferred width
- if (widthHint + widthAdjustment >= preferredSize.x) {
- return new Point(widthHint + widthAdjustment, preferredSize.y);
+ if (widthHint >= preferred.x) {
+ return new Point(widthHint, preferred.y);
}
}
@@ -243,6 +250,11 @@ public class SizeCache {
// it from scratch.
cachedHeight = controlComputeSize(widthHint, heightHint);
cachedHeightQuery = widthHint;
+
+ if (minimumWidth != -1 && widthHint == minimumWidth) {
+ heightAtMinimumWidth = cachedHeight.y;
+ }
+
return Geometry.copy(cachedHeight);
}
@@ -251,7 +263,7 @@ public class SizeCache {
// If we know the control's preferred size
if (preferredSize != null) {
// If the given height is the preferred height, then return the preferred size
- if (heightHint + heightAdjustment == preferredSize.y) {
+ if (heightHint == preferredSize.y) {
return Geometry.copy(preferredSize);
}
}
@@ -285,16 +297,29 @@ public class SizeCache {
* @return the control's size
*/
public Point computeAdjustedSize(int widthHint, int heightHint) {
+ return computeSize(widthHint, heightHint);
+ }
+
+ private Point controlComputeSize(int widthHint, int heightHint) {
int adjustedWidthHint = widthHint == SWT.DEFAULT ? SWT.DEFAULT : Math
.max(0, widthHint - widthAdjustment);
int adjustedHeightHint = heightHint == SWT.DEFAULT ? SWT.DEFAULT : Math
.max(0, heightHint - heightAdjustment);
- Point result = computeSize(adjustedWidthHint, adjustedHeightHint);
+ Point result = control.computeSize(adjustedWidthHint, adjustedHeightHint, flushChildren);
+ flushChildren = false;
// If the amounts we subtracted off the widthHint and heightHint didn't do the trick, then
// manually adjust the result to ensure that a non-default hint will return that result verbatim.
+ if (widthHint != SWT.DEFAULT) {
+ result.x = widthHint;
+ }
+
+ if (heightHint != SWT.DEFAULT) {
+ result.y = heightHint;
+ }
+
return result;
}
@@ -361,13 +386,6 @@ public class SizeCache {
}
}
- private Point controlComputeSize(int widthHint, int heightHint) {
- Point result = control.computeSize(widthHint, heightHint, flushChildren);
- flushChildren = false;
-
- return result;
- }
-
/**
* Returns true only if the control will return a constant height for any
* width hint larger than the preferred width. Returns false if there is any
@@ -400,9 +418,14 @@ public class SizeCache {
}
}
+ // TODO: Check for forms-specific control types that know how to compute
+ // their minimum width. Possibly allow
+ // the controls to implement ILayoutExtension directly.
+
if (minimumWidth == -1) {
- Point minWidth = controlComputeSize(FormUtil.getWidthHint(5, control), SWT.DEFAULT);
+ Point minWidth = computeSize(SWT.DEFAULT, SWT.DEFAULT);
minimumWidth = minWidth.x;
+ heightAtMinimumWidth = minWidth.y;
}
return minimumWidth;
@@ -419,6 +442,12 @@ public class SizeCache {
}
}
+ // TODO: Check for forms-specific control types that know how to compute
+ // their minimum width. Possibly allow
+ // the controls to implement ILayoutExtension directly.
+
+ // TODO: Fix the following branch.
+
if (maximumWidth == -1) {
maximumWidth = getPreferredSize().x;
}
@@ -427,6 +456,7 @@ public class SizeCache {
}
private int computeMinimumHeight() {
+ // TODO: Fix the following branch
if (minimumHeight == -1) {
Point sizeAtMinHeight = controlComputeSize(SWT.DEFAULT, 0);
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/TableWrapLayout.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/TableWrapLayout.java
index 352749aa33f..41e23e17736 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/TableWrapLayout.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/TableWrapLayout.java
@@ -20,6 +20,7 @@ import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;
+import org.eclipse.ui.internal.forms.widgets.FormUtil;
/**
* This implementation of the layout algorithm attempts to position controls in
@@ -318,7 +319,9 @@ public final class TableWrapLayout extends Layout implements ILayoutExtension {
if (k < j + span - 1)
cwidth += horizontalSpacing;
}
- Point size = computeSize(td.childIndex, cwidth, td.indent, td.maxWidth, td.maxHeight);
+ Point size = FormUtil.computeControlSize(cache.getCache(td.childIndex), cwidth - td.indent, td.maxWidth,
+ td.maxHeight, td.align == TableWrapData.FILL);
+ size.x += td.indent;
td.compWidth = cwidth;
if (td.heightHint != SWT.DEFAULT) {
size = new Point(size.x, td.heightHint);
@@ -392,20 +395,6 @@ public final class TableWrapLayout extends Layout implements ILayoutExtension {
return widths;
}
- Point computeSize(int childIndex, int width, int indent, int maxWidth, int maxHeight) {
- int widthArg = width - indent;
- SizeCache controlCache = cache.getCache(childIndex);
- if (!isWrap(controlCache.getControl()))
- widthArg = SWT.DEFAULT;
- Point size = controlCache.computeSize(widthArg, SWT.DEFAULT);
- if (maxWidth!=SWT.DEFAULT)
- size.x = Math.min(size.x, maxWidth);
- if (maxHeight!=SWT.DEFAULT)
- size.y = Math.min(size.y, maxHeight);
- size.x += indent;
- return size;
- }
-
void placeControl(Control control, TableWrapData td, int x, int y,
int[] rowHeights, int row) {
int xloc = x + td.indent;
@@ -426,7 +415,7 @@ public final class TableWrapLayout extends Layout implements ILayoutExtension {
}
// align horizontally
if (td.align == TableWrapData.CENTER) {
- xloc = x + colWidth / 2 - width / 2;
+ xloc = x + (colWidth - width) / 2;
} else if (td.align == TableWrapData.RIGHT) {
xloc = x + colWidth - width;
} else if (td.align == TableWrapData.FILL) {
@@ -434,7 +423,7 @@ public final class TableWrapLayout extends Layout implements ILayoutExtension {
}
// align vertically
if (td.valign == TableWrapData.MIDDLE) {
- yloc = y + slotHeight / 2 - height / 2;
+ yloc = y + (slotHeight - height) / 2;
} else if (td.valign == TableWrapData.BOTTOM) {
yloc = y + slotHeight - height;
} else if (td.valign == TableWrapData.FILL) {
@@ -669,7 +658,9 @@ public final class TableWrapLayout extends Layout implements ILayoutExtension {
}
int cy = td.heightHint;
if (cy == SWT.DEFAULT) {
- Point size = computeSize(td.childIndex, cwidth, td.indent, td.maxWidth, td.maxHeight);
+ SizeCache controlCache = cache.getCache(td.childIndex);
+ Point size = FormUtil.computeControlSize(controlCache, cwidth - td.indent, td.maxWidth,
+ td.maxHeight, td.align == TableWrapData.FILL);
cy = size.y;
}
RowSpan rowspan = rowspans.get(child);
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ToggleHyperlink.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ToggleHyperlink.java
index 966fa6debb8..850c5240fdb 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ToggleHyperlink.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/forms/widgets/ToggleHyperlink.java
@@ -141,18 +141,15 @@ public abstract class ToggleHyperlink extends AbstractHyperlink {
*/
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
- int width, height;
- /*
+ int width = innerWidth + 2 * marginWidth;
+ int height = innerHeight + 2 * marginHeight;
if (wHint != SWT.DEFAULT)
width = wHint;
- else */
- width = innerWidth + 2 * marginWidth;
- /*
if (hHint != SWT.DEFAULT)
height = hHint;
- else */
- height = innerHeight + 2 * marginHeight;
- return new Point(width, height);
+
+ Rectangle trim = computeTrim(0, 0, width, height);
+ return new Point(trim.width, trim.height);
}
/**
* Returns the expansion state of the toggle control. When toggle is in the
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/ControlSegment.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/ControlSegment.java
index ce9accfd4ae..133010ec9df 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/ControlSegment.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/ControlSegment.java
@@ -50,15 +50,14 @@ public class ControlSegment extends ObjectSegment implements IFocusSelectable {
}
@Override
- protected Point getObjectSize(Hashtable<String, Object> resourceTable, int wHint) {
+ protected Point getObjectSize(Hashtable<String, Object> resourceTable, int widthHint) {
Control control = getControl(resourceTable);
if (control==null)
return new Point(0,0);
- int realWhint = FormUtil.getWidthHint(wHint, control);
- Point size = control.computeSize(realWhint, SWT.DEFAULT);
- if (realWhint!=SWT.DEFAULT && fill)
- size.x = Math.max(size.x, realWhint);
- if (width !=SWT.DEFAULT)
+ Point size = control.computeSize(widthHint, SWT.DEFAULT);
+ if (widthHint!=SWT.DEFAULT && fill)
+ size.x = Math.max(size.x, widthHint);
+ if (width != SWT.DEFAULT)
size.x = width;
if (height != SWT.DEFAULT)
size.y = height;
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormHeading.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormHeading.java
index 85964d973a1..6d88f42db15 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormHeading.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormHeading.java
@@ -87,6 +87,8 @@ public class FormHeading extends Canvas {
private SizeCache messageCache = new SizeCache();
+ private SizeCache titleRegionCache = new SizeCache();
+
private TitleRegion titleRegion;
private MessageRegion messageRegion;
@@ -123,9 +125,11 @@ public class FormHeading extends Canvas {
}
private class FormHeadingLayout extends Layout implements ILayoutExtension {
+ private static final int MIN_WIDTH = -2;
+
@Override
public int computeMinimumWidth(Composite composite, boolean flushCache) {
- return computeSize(composite, 5, SWT.DEFAULT, flushCache).x;
+ return layout(composite, false, 0, 0, MIN_WIDTH, SWT.DEFAULT, flushCache).x;
}
@Override
@@ -148,6 +152,8 @@ public class FormHeading extends Canvas {
private Point layout(Composite composite, boolean move, int x, int y,
int width, int height, boolean flushCache) {
+ titleRegionCache.setControl(titleRegion);
+
Point tsize = null;
Point msize = null;
Point tbsize = null;
@@ -157,6 +163,7 @@ public class FormHeading extends Canvas {
clientCache.flush();
messageCache.flush();
toolbarCache.flush();
+ titleRegionCache.flush();
}
if (hasToolBar()) {
ToolBar tb = toolBarManager.getControl();
@@ -165,17 +172,17 @@ public class FormHeading extends Canvas {
}
if (headClient != null) {
clientCache.setControl(headClient);
- int cwhint = width;
- if (cwhint != SWT.DEFAULT) {
- cwhint -= HMARGIN * 2;
+ int clientWidthHint = width;
+ if (clientWidthHint != SWT.DEFAULT && clientWidthHint != MIN_WIDTH) {
+ clientWidthHint -= HMARGIN * 2;
if (tbsize != null && getToolBarAlignment() == SWT.BOTTOM)
- cwhint -= tbsize.x + SPACING;
+ clientWidthHint -= tbsize.x + SPACING;
}
- clsize = clientCache.computeSize(cwhint, SWT.DEFAULT);
+ clsize = computeSize(clientCache, clientWidthHint);
}
int totalFlexWidth = width;
int flexWidth = totalFlexWidth;
- if (totalFlexWidth != SWT.DEFAULT) {
+ if (totalFlexWidth != SWT.DEFAULT && totalFlexWidth != MIN_WIDTH) {
totalFlexWidth -= TITLE_HMARGIN * 2;
// complete right margin
if (hasToolBar() && getToolBarAlignment() == SWT.TOP
@@ -207,11 +214,11 @@ public class FormHeading extends Canvas {
* SWT.DEFAULT); } }
*/
if (!hasMessageRegion()) {
- tsize = titleRegion.computeSize(flexWidth, SWT.DEFAULT);
+ tsize = computeSize(titleRegionCache, flexWidth);
} else {
// Total flexible area in the first row is flexWidth.
// Try natural widths of title and
- Point tsizeNatural = titleRegion.computeSize(SWT.DEFAULT,
+ Point tsizeNatural = titleRegionCache.computeSize(SWT.DEFAULT,
SWT.DEFAULT);
messageCache.setControl(messageRegion.getMessageControl());
Point msizeNatural = messageCache.computeSize(SWT.DEFAULT,
@@ -219,7 +226,7 @@ public class FormHeading extends Canvas {
// try to fit all
tsize = tsizeNatural;
msize = msizeNatural;
- if (flexWidth != SWT.DEFAULT) {
+ if (flexWidth != SWT.DEFAULT && flexWidth != MIN_WIDTH) {
int needed = tsizeNatural.x + msizeNatural.x;
if (needed > flexWidth) {
// too big - try to limit the message
@@ -337,6 +344,24 @@ public class FormHeading extends Canvas {
}
return size;
}
+
+ /**
+ * Computes the preferred or minimum size of the given client cache.
+ *
+ * @param clientCache
+ * size cache for the control whose size is being computed
+ * @param wHint
+ * the width of the control, in pixels, or SWT.DEFAULT if the
+ * preferred size is being computed, or MIN_WIDTH if the minimum size
+ * is being computed
+ */
+ private Point computeSize(SizeCache clientCache, int wHint) {
+ if (wHint == MIN_WIDTH) {
+ int minWidth = clientCache.computeMinimumWidth();
+ return clientCache.computeSize(minWidth, SWT.DEFAULT);
+ }
+ return clientCache.computeSize(wHint, SWT.DEFAULT);
+ }
}
@Override
diff --git a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormUtil.java b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormUtil.java
index 3115ced00af..2b072647ab3 100644
--- a/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormUtil.java
+++ b/bundles/org.eclipse.ui.forms/src/org/eclipse/ui/internal/forms/widgets/FormUtil.java
@@ -33,7 +33,7 @@ import org.eclipse.ui.forms.widgets.ColumnLayout;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.FormToolkit;
-import org.eclipse.ui.forms.widgets.ILayoutExtension;
+import org.eclipse.ui.forms.widgets.SizeCache;
import com.ibm.icu.text.BreakIterator;
@@ -55,6 +55,58 @@ public class FormUtil {
public static final String IGNORE_BODY = "__ignore_body__"; //$NON-NLS-1$
+ /**
+ * Computes the preferred of a control, given the (optional) fixed width of the
+ * column it needs to fit within, the width and height hints from its layout
+ * data, and its horizontal alignment.
+ *
+ * @param cache
+ * the size cache for the control whose size is being computed
+ * @param constrainedWidth
+ * the width of the control's cell or SWT.DEFAULT if unconstrained
+ * @param widthHintFromLayoutData
+ * the width hint associated with the control's layout data or
+ * SWT.DEFAULT if none
+ * @param heightHintFromLayoutData
+ * the height hint associated with the control's layout data or
+ * SWT.DEFAULT if none
+ * @param isFillAligned
+ * true if and only if the control is horizontally fill-aligned
+ * within its cell
+ */
+ public static Point computeControlSize(SizeCache cache, int constrainedWidth, int widthHintFromLayoutData,
+ int heightHintFromLayoutData, boolean isFillAligned) {
+ int widthHint;
+ int heightHint = heightHintFromLayoutData;
+ // If using non-fill alignment and there is a width hint specified in both the
+ // argument and the layout data,
+ // use whichever one is smaller.
+ if (isFillAligned) {
+ // If width is unbounded, apply a width hint iff requested in the layout data
+ if (constrainedWidth == SWT.DEFAULT) {
+ widthHint = widthHintFromLayoutData;
+ } else {
+ widthHint = constrainedWidth;
+ }
+ } else {
+ // If not using fill alignment, make a first attempt at computing the size
+ // without considering the
+ // column width
+ widthHint = widthHintFromLayoutData;
+ }
+
+ Point result = cache.computeSize(widthHint, heightHint);
+
+ // If using non-fill alignment, it's possible that the result is larger than the
+ // column width. In that case,
+ // constrain the width and try again.
+ if (!isFillAligned && constrainedWidth != SWT.DEFAULT && result.x > constrainedWidth) {
+ result = cache.computeSize(constrainedWidth, heightHint);
+ }
+
+ return result;
+ }
+
public static Text createText(Composite parent, String label,
FormToolkit factory) {
return createText(parent, label, factory, 1);
@@ -406,20 +458,6 @@ public class FormUtil {
}
}
- public static boolean isWrapControl(Control c) {
- if ((c.getStyle() & SWT.WRAP) != 0)
- return true;
- if (c instanceof Composite) {
- return ((Composite) c).getLayout() instanceof ILayoutExtension;
- }
- return false;
- }
-
- public static int getWidthHint(int wHint, Control c) {
- boolean wrap = isWrapControl(c);
- return wrap ? wHint : SWT.DEFAULT;
- }
-
public static int getHeightHint(int hHint, Control c) {
if (c instanceof Composite) {
Layout layout = ((Composite) c).getLayout();
@@ -429,26 +467,6 @@ public class FormUtil {
return SWT.DEFAULT;
}
- public static int computeMinimumWidth(Control c, boolean changed) {
- if (c instanceof Composite) {
- Layout layout = ((Composite) c).getLayout();
- if (layout instanceof ILayoutExtension)
- return ((ILayoutExtension) layout).computeMinimumWidth(
- (Composite) c, changed);
- }
- return c.computeSize(FormUtil.getWidthHint(5, c), SWT.DEFAULT, changed).x;
- }
-
- public static int computeMaximumWidth(Control c, boolean changed) {
- if (c instanceof Composite) {
- Layout layout = ((Composite) c).getLayout();
- if (layout instanceof ILayoutExtension)
- return ((ILayoutExtension) layout).computeMaximumWidth(
- (Composite) c, changed);
- }
- return c.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed).x;
- }
-
public static Form getForm(Control c) {
Composite parent = c.getParent();
while (parent != null) {
diff --git a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/AllFormsTests.java b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/AllFormsTests.java
index c04fc122ea2..4fb9455f111 100755
--- a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/AllFormsTests.java
+++ b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/AllFormsTests.java
@@ -16,7 +16,6 @@ package org.eclipse.ui.tests.forms;
import org.eclipse.ui.tests.forms.layout.AllLayoutTests;
import org.eclipse.ui.tests.forms.util.AllUtilityTests;
import org.eclipse.ui.tests.forms.widgets.AllWidgetsTests;
-import org.eclipse.ui.tests.forms.widgets.SizeCacheTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -27,8 +26,7 @@ import org.junit.runners.Suite;
@Suite.SuiteClasses({
AllLayoutTests.class,
AllUtilityTests.class,
- AllWidgetsTests.class,
- SizeCacheTest.class
+ AllWidgetsTests.class
})
public class AllFormsTests {
diff --git a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/AllLayoutTests.java b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/AllLayoutTests.java
index 99a6a972542..c642c1fb5a9 100755
--- a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/AllLayoutTests.java
+++ b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/AllLayoutTests.java
@@ -12,6 +12,8 @@
package org.eclipse.ui.tests.forms.layout;
+import org.eclipse.ui.tests.forms.widgets.HintAdjustmentTest;
+import org.eclipse.ui.tests.forms.widgets.SizeCacheTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -20,8 +22,10 @@ import org.junit.runners.Suite;
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
+ HintAdjustmentTest.class,
+ SizeCacheTest.class,
TestColumnWrapLayout.class,
- TestTableWrapLayout.class
+ TestTableWrapLayout.class,
})
public class AllLayoutTests {
diff --git a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/ControlFactory.java b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/ControlFactory.java
new file mode 100644
index 00000000000..b3e87e79f29
--- /dev/null
+++ b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/ControlFactory.java
@@ -0,0 +1,130 @@
+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;
+ }
+}
diff --git a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/TestColumnWrapLayout.java b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/TestColumnWrapLayout.java
index ca22811d8ff..0dd299ab3dd 100644
--- a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/TestColumnWrapLayout.java
+++ b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/TestColumnWrapLayout.java
@@ -16,13 +16,18 @@ import static org.junit.Assert.assertEquals;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.ColumnLayout;
+import org.eclipse.ui.forms.widgets.ColumnLayoutData;
import org.eclipse.ui.internal.forms.widgets.ColumnLayoutUtils;
+import org.eclipse.ui.tests.forms.layout.ControlFactory.TestLayout;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
public class TestColumnWrapLayout {
@@ -33,6 +38,32 @@ public class TestColumnWrapLayout {
private final Point p100 = new Point(100, 100);
private final Point p200 = new Point(100, 200);
+ private Display display;
+ private Shell shell;
+ private Composite inner;
+ private ColumnLayout layout;
+
+ @Before
+ public void setUp() {
+ display = PlatformUI.getWorkbench().getDisplay();
+ shell = new Shell(display);
+ inner = new Composite(shell, SWT.NULL);
+ inner.setSize(100, 300);
+ layout = new ColumnLayout();
+ layout.leftMargin = 0;
+ layout.rightMargin = 0;
+ layout.topMargin = 0;
+ layout.bottomMargin = 0;
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ inner.setLayout(layout);
+ }
+
+ @After
+ public void tearDown() {
+ shell.dispose();
+ }
+
@Test
public void testEqualSizeColumns() {
Point[] sizes = { p20, p30, p30, p20, p20, p30 };
@@ -63,44 +94,258 @@ public class TestColumnWrapLayout {
assertEquals(260, ColumnLayoutUtils.computeColumnHeight(3, sizes, 100, 100));
}
- private class SizedComposite extends Composite {
-
- int height;
-
- public SizedComposite(Composite parent, int style, int height) {
- super(parent, style);
- this.height = height;
- }
-
- @Override
- public Point computeSize(int wHint, int hHint, boolean changed) {
- return new Point( 20, height);
- }
- }
-
/**
* Test that labels with the WRAP property set do indeed wrap.
*/
@Test
public void testColumnLayoutInShell() {
- Display display = PlatformUI.getWorkbench().getDisplay();
- Shell shell = new Shell(display);
- shell.setSize(100, 300);
- shell.setLayout(new GridLayout());
- Composite inner = new Composite(shell, SWT.NULL);
- ColumnLayout layout = new ColumnLayout();
layout.verticalSpacing = 5;
+ layout.horizontalSpacing = 5;
layout.minNumColumns = 2;
layout.maxNumColumns = 2;
layout.topMargin=2;
layout.bottomMargin=3;
- inner.setLayout(layout);
- new SizedComposite(inner, SWT.NULL, 30);
- new SizedComposite(inner, SWT.NULL, 40);
- new SizedComposite(inner, SWT.NULL, 20);
- shell.layout(true);
- assertEquals(70, inner.getSize().y);
- shell.dispose();
+ layout.leftMargin = 5;
+ layout.rightMargin = 5;
+ ControlFactory.create(inner, 20, 20, 30);
+ ControlFactory.create(inner, 20, 20, 40);
+ ControlFactory.create(inner, 20, 20, 20);
+ Point size = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ assertEquals(70, size.y);
+ inner.setSize(size);
+ inner.layout(true);
+ assertEquals(new Rectangle(5, 2, 20, 30), inner.getChildren()[0].getBounds());
+ assertEquals(new Rectangle(30, 2, 20, 40), inner.getChildren()[1].getBounds());
+ }
+
+ @Test
+ public void testHorizontalSpacingHasNoEffectWhenOnlyOneColumn() {
+ layout.horizontalSpacing = 1000;
+ Composite control = ControlFactory.create(inner, 20, 20, 30);
+ Point size = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ assertEquals(20, size.x);
+ inner.pack(true);
+ assertEquals(new Rectangle(0, 0, 20, 30), control.getBounds());
+ }
+
+ @Test
+ public void testHorizontalSpacing() {
+ layout.horizontalSpacing = 1000;
+ ControlFactory.create(inner, 20, 20, 30);
+ Composite secondControl = ControlFactory.create(inner, 20, 20, 30);
+ Point size = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ assertEquals(1040, size.x);
+ inner.pack(true);
+ assertEquals(new Rectangle(1020, 0, 20, 30), secondControl.getBounds());
+ }
+
+ @Test
+ public void testHorizontalMargins() {
+ layout.leftMargin = 100;
+ layout.rightMargin = 10;
+ Control leftControl = ControlFactory.create(inner, 20, 20, 30);
+ Control rightControl = ControlFactory.create(inner, 20, 20, 40);
+ Point size = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ assertEquals(150, size.x);
+ inner.pack(true);
+ assertEquals(new Rectangle(100, 0, 20, 30), leftControl.getBounds());
+ assertEquals(new Rectangle(120, 0, 20, 40), rightControl.getBounds());
+ assertEquals(new Rectangle(0, 0, 150, 40), inner.getBounds());
+ }
+
+ @Test
+ public void testVerticalSpacingHasNoEffectWhenOnlyOneColumn() {
+ layout.verticalSpacing = 1000;
+ Composite control = ControlFactory.create(inner, 20, 20, 30);
+ Point size = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ assertEquals(20, size.x);
+ inner.pack(true);
+ assertEquals(new Rectangle(0, 0, 20, 30), control.getBounds());
+ }
+
+ @Test
+ public void testVerticalSpacing() {
+ layout.verticalSpacing = 1000;
+ layout.maxNumColumns = 1;
+ ControlFactory.create(inner, 20, 20, 30);
+ Composite secondControl = ControlFactory.create(inner, 20, 20, 30);
+ Point size = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ assertEquals(1060, size.y);
+ inner.pack(true);
+ assertEquals(new Rectangle(0, 1030, 20, 30), secondControl.getBounds());
+ }
+
+ @Test
+ public void testVerticalMargins() {
+ layout.topMargin = 100;
+ layout.bottomMargin = 10;
+ layout.maxNumColumns = 1;
+ Control control1 = ControlFactory.create(inner, 20, 20, 30);
+ Control control2 = ControlFactory.create(inner, 20, 20, 40);
+ Point size = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ assertEquals(180, size.y);
+ inner.pack();
+ assertEquals(new Rectangle(0, 100, 20, 30), control1.getBounds());
+ assertEquals(new Rectangle(0, 130, 20, 40), control2.getBounds());
+ assertEquals(new Rectangle(0, 0, 20, 180), inner.getBounds());
+ }
+
+ @Test
+ public void testSelectsCorrectNumberOfColumns() {
+ layout.horizontalSpacing = 10;
+ layout.leftMargin = 10;
+ layout.rightMargin = 10;
+
+ ControlFactory.create(inner, 21, 30, 50);
+ ControlFactory.create(inner, 22, 40, 50);
+ // This last control will have a preferred height of 108 when compressed to its
+ // minimum width
+ ControlFactory.create(inner, 23, 50, 50);
+
+ // Should always use the maximum number of columns when the width is
+ // unconstrained, and the preferred size
+ // should be based on the maximum size of the children
+ Point size = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ assertEquals(190, size.x);
+ assertEquals(50, size.y);
+
+ // Should still use the maximum number of columns if the minimum size of the
+ // children will fit in the area
+ size = inner.computeSize(109, SWT.DEFAULT);
+ assertEquals(109, size.x);
+ assertEquals(108, size.y);
+
+ // Lay out with the default width
+ inner.pack(true);
+ assertAllChildrenHaveWidth(50);
+
+ for (Control next : inner.getChildren()) {
+ assertEquals(0, next.getBounds().y);
+ }
+
+ // If we're one pixel less than the minimum size for the children, the number of
+ // columns should be reduced
+ size = inner.computeSize(108, SWT.DEFAULT);
+ assertEquals(108, size.x);
+ assertEquals(89, size.y);
+
+ // Ensure that it falls back to the minimum number of columns when we're
+ // requesting the minimum width
+ int minWidth = layout.computeMinimumWidth(inner, false);
+ assertEquals(43, minWidth);
+ }
+
+ @Test
+ public void testFillAlignment() {
+ layout.maxNumColumns = 1;
+
+ // Control1 has a min size of 100, a default size of 800, and a width hint of
+ // 400. When computing the default size of the column, the width hint should be
+ // used rather than the control's preferred width and the control should end up
+ // with a size 400x100.
+ Composite control1 = ControlFactory.create(inner, 100, 800, 200);
+ ColumnLayoutData data1 = new ColumnLayoutData();
+ data1.widthHint = 400;
+ control1.setLayoutData(data1);
+
+ // Control2 is narrower than control1, but since it's fill-aligned it should be
+ // stretched to match the size of control1.
+ Composite control2 = ControlFactory.create(inner, 50, 100, 1200);
+ ColumnLayoutData data2 = new ColumnLayoutData();
+ data2.widthHint = 200;
+ control2.setLayoutData(data2);
+
+ Point size = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+
+ // Both control should be resized to match the first control's width hint since
+ // it's the widest and both are fill-aligned.
+ assertEquals(400, size.x);
+
+ // 400 pixels for the first control, 300 pixels for the second.
+ assertEquals(700, size.y);
+
+ inner.pack();
+
+ assertEquals(new Rectangle(0, 0, 400, 400), control1.getBounds());
+ assertEquals(new Rectangle(0, 400, 400, 300), control2.getBounds());
+ }
+
+ @Test
+ public void testLeftAlignment() {
+ layout.maxNumColumns = 1;
+
+ // Create a large control to dominate the width of the columns
+ Composite control1 = ControlFactory.create(inner, 200, 200, 200);
+
+ // Control2 is narrower than control1, but since it's fill-aligned it
+ // should be
+ // stretched to match the size of control1.
+ Composite control2 = ControlFactory.create(inner, 10, 100, 100);
+ ColumnLayoutData data2 = new ColumnLayoutData();
+ data2.horizontalAlignment = ColumnLayoutData.LEFT;
+ data2.widthHint = 50;
+ control2.setLayoutData(data2);
+
+ Composite control3 = ControlFactory.create(inner, 10, 50, 100);
+ ColumnLayoutData data3 = new ColumnLayoutData();
+ data3.widthHint = 10;
+ data3.horizontalAlignment = ColumnLayoutData.LEFT;
+ control3.setLayoutData(data3);
+
+ Point size = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+
+ assertEquals(200, size.x);
+ assertEquals(900, size.y);
+
+ inner.pack(true);
+
+ assertEquals(new Rectangle(0, 0, 200, 200), control1.getBounds());
+ assertEquals(new Rectangle(0, 200, 50, 200), control2.getBounds());
+ assertEquals(new Rectangle(0, 400, 10, 500), control3.getBounds());
+
+ // Verify that if we shrink a left-aligned wrapping control to a size
+ // smaller than its preferred width, it will still wrap correctly.
+
+ size = inner.computeSize(25, SWT.DEFAULT);
+
+ assertEquals(25, size.x);
+ assertEquals(2500, size.y);
+ }
+
+ @Test
+ public void testControlsFlushedCorrectly()
+ {
+ Composite composite = ControlFactory.create(inner, 200, 200, 200);
+ TestLayout layout = (TestLayout) composite.getLayout();
+
+ // Currently there is one unnecessary recursive flush on startup. Ignore it for
+ // now.
+ inner.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
+ layout.wasChanged = false;
+
+ // Verify that there is no redundant cache flush.
+ inner.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
+ assertEquals(false, layout.wasChanged);
+
+ inner.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+ assertEquals(true, layout.wasChanged);
+
+ layout.wasChanged = false;
+ inner.layout(false);
+ assertEquals(false, layout.wasChanged);
+
+ inner.layout(true);
+ assertEquals(true, layout.wasChanged);
}
+ private void assertAllChildrenHaveWidth(int desiredWidth) {
+ Control[] children = inner.getChildren();
+
+ for (int idx = 0; idx < children.length; idx++) {
+ Control next = children[idx];
+
+ Rectangle bounds = next.getBounds();
+ assertEquals("Child " + idx + " should have the correct width", desiredWidth, bounds.width);
+ }
+ }
}
diff --git a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/TestTableWrapLayout.java b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/TestTableWrapLayout.java
index b8edcd1019b..2a1e2c2a296 100755
--- a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/TestTableWrapLayout.java
+++ b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/layout/TestTableWrapLayout.java
@@ -16,102 +16,123 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
public class TestTableWrapLayout {
- private final String A1 = "A";
- private final String A10 = "A A A A A A A A A A";
- private final String A20 = A10 + " " + A10;
- private final String A40 = A20 + " " + A20;
- private final String A80 = A40 + " " + A40;
+ private Display display;
+ private Shell shell;
+ private Composite inner;
+ private TableWrapLayout layout;
// Returns the width + left
- private int rightEdge(Label lab) {
+ private int rightEdge(Control lab) {
Rectangle r = lab.getBounds();
return r.x + r.width;
}
+ @Before
+ public void setUp() {
+ display = PlatformUI.getWorkbench().getDisplay();
+ shell = new Shell(display);
+ shell.setLayout(new FillLayout());
+ inner = new Composite(shell, SWT.NONE);
+ inner.setSize(100, 300);
+ layout = new TableWrapLayout();
+ layout.leftMargin = 0;
+ layout.rightMargin = 0;
+ layout.topMargin = 0;
+ layout.bottomMargin = 0;
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ inner.setLayout(layout);
+ }
+
+ @After
+ public void tearDown() {
+ shell.dispose();
+ }
+
/**
- * Test that labels with the WRAP property set do indeed wrap.
+ * Test a simple two-cell layout.
*/
@Test
public void testTableWrapLayoutNonWrappingLabels() {
- Display display = PlatformUI.getWorkbench().getDisplay();
- Shell shell = new Shell(display);
- shell.setSize(100, 300);
- shell.setLayout(new FillLayout());
- Composite inner = new Composite(shell, SWT.V_SCROLL);
- inner.setLayout(new TableWrapLayout());
- Label l1 = new Label(inner, SWT.NULL);
- l1.setText(A10);
- Label l2 = new Label(inner, SWT.NULL);
- l2.setText(A80);
- shell.layout();
- assertEquals(l1.getSize().y, l2.getSize().y);
- assertTrue(l2.getSize().x > 100);
- shell.dispose();
+ Control l1 = ControlFactory.create(inner, 10, 100, 15);
+ Control l2 = ControlFactory.create(inner, 80, 800, 15);
+
+ Point preferredSize = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ int minimumWidth = layout.computeMinimumWidth(inner, false);
+ Point wrappedSize = inner.computeSize(400, SWT.DEFAULT);
+
+ inner.pack();
+ assertEquals(new Rectangle(0, 0, 100, 15), l1.getBounds());
+ assertEquals(new Rectangle(0, 15, 800, 15), l2.getBounds());
+ assertEquals(new Point(800, 30), preferredSize);
+ assertEquals(80, minimumWidth);
+ assertEquals(new Point(400, 45), wrappedSize);
}
/**
* Test that labels with the WRAP property set do indeed wrap.
*/
- // Test suppressed for now - does not pass but not sure if this is a bug
- public void suppressed_testWrappingPoint() {
- Display display = PlatformUI.getWorkbench().getDisplay();
- Shell shell = new Shell(display);
- shell.setSize(300, 300);
- shell.setLayout(new FillLayout());
- Composite inner = new Composite(shell, SWT.V_SCROLL);
- TableWrapLayout tableWrapLayout = new TableWrapLayout();
- tableWrapLayout.leftMargin = 0;
- tableWrapLayout.rightMargin = 0;
- inner.setLayout(tableWrapLayout);
- Label l1 = new Label(inner, SWT.WRAP);
- l1.setText(A10);
- shell.layout();
- int originalWidth = l1.getSize().x;
- int originalHeight = l1.getSize().y;
- shell.setSize(originalWidth, 300);
- shell.layout();
- assertEquals(l1.getSize().y, originalHeight);
- shell.setSize(originalWidth / 2, 300);
- shell.layout();
+ @Test
+ public void testWrappingPoint() {
+ Control l1 = ControlFactory.create(inner, 30, 100, 15);
+
+ // Validate the behavior of computeSize()
+ Point preferredSize = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
+ int preferredHeightWheneThereIsExtraHorizontalSpace = inner.computeSize(200, SWT.DEFAULT).y;
+ int preferredHeightWhenControlFillsSpace = inner.computeSize(100, SWT.DEFAULT).y;
+ int preferredHeightWhenControlCompressed = inner.computeSize(50, SWT.DEFAULT).y;
+ assertEquals(15, preferredHeightWheneThereIsExtraHorizontalSpace);
+ assertEquals(15, preferredHeightWhenControlFillsSpace);
+ assertEquals(30, preferredHeightWhenControlCompressed);
+ assertEquals(new Point(100, 15), preferredSize);
+
+ // Validate the behavior of layout()
+ inner.setSize(100, 15);
inner.layout();
- assertTrue(l1.getSize().y > originalHeight);
- shell.dispose();
+ assertEquals(15, l1.getSize().y);
+
+ inner.setSize(100, 300);
+ inner.layout();
+ assertEquals(15, l1.getSize().y);
+
+ inner.setSize(50, 300);
+ inner.layout();
+ assertEquals(30, l1.getSize().y);
+
+ // Validate the behavior of computeMinimumWidth
+ assertEquals(30, layout.computeMinimumWidth(inner, false));
+ assertEquals(100, layout.computeMaximumWidth(inner, false));
}
/**
* Test that labels with the WRAP property set do indeed wrap.
*/
- // Test suppressed for now, see Bug 196686
- public void suppressed_testTableWrapLayoutWrappingLabels() {
- Display display = PlatformUI.getWorkbench().getDisplay();
- Shell shell = new Shell(display);
- shell.setSize(100, 300);
- shell.setLayout(new FillLayout());
- Composite inner = new Composite(shell, SWT.V_SCROLL);
- inner.setLayout(new TableWrapLayout());
- Label l1 = new Label(inner, SWT.WRAP);
- l1.setText(A10);
- Label l2 = new Label(inner, SWT.WRAP);
- l2.setText(A80);
- shell.layout();
- assertTrue(l1.getSize().y < l2.getSize().y);
- assertTrue("Label is too wide for layout ", l1.getSize().x <= 100);
- assertTrue("Label is too wide for layout ", l2.getSize().x <= 100);
- assertTrue("Labels overlap", l2.getBounds().y >= l1.getBounds().y + l1.getBounds().height);
- shell.dispose();
+ @Test
+ public void testTableWrapLayoutWrappingLabels() {
+ Control l1 = ControlFactory.create(inner, 30, 100, 15);
+ Control l2 = ControlFactory.create(inner, 50, 800, 15);
+
+ inner.setSize(300, 1000);
+ inner.layout(false);
+
+ assertEquals("l1 had the wrong bounds", new Rectangle(0, 0, 100, 15), l1.getBounds());
+ assertEquals("l2 had the wrong bounds", new Rectangle(0, 15, 300, 40), l2.getBounds());
}
/**
@@ -119,97 +140,121 @@ public class TestTableWrapLayout {
*/
@Test
public void testTableWrapLayoutTwoColumnsWrappingLabels() {
- Display display = PlatformUI.getWorkbench().getDisplay();
- Shell shell = new Shell(display);
- shell.setSize(100, 300);
- shell.setLayout(new FillLayout());
- Composite inner = new Composite(shell, SWT.V_SCROLL);
- TableWrapLayout tableWrapLayout = new TableWrapLayout();
- tableWrapLayout.numColumns = 2;
- inner.setLayout(tableWrapLayout);
- Label l1 = new Label(inner, SWT.WRAP);
- l1.setText(A10);
- Label l2 = new Label(inner, SWT.WRAP);
- l2.setText(A20);
- Label l3 = new Label(inner, SWT.WRAP);
- l3.setText(A40);
- Label l4 = new Label(inner, SWT.WRAP);
- l4.setText(A80);
- shell.layout();
- assertTrue(l1.getSize().x < l2.getSize().x);
- assertTrue(l1.getSize().y < l3.getSize().y);
- assertTrue(l1.getSize().x < l4.getSize().x);
- assertTrue(l2.getSize().y < l3.getSize().y);
- assertTrue("Label is too wide for layout ", l1.getSize().x + l2.getSize().x <= 100);
- assertTrue("Labels overlap", l2.getBounds().x >= l1.getBounds().x + l1.getBounds().width);
- assertTrue("Labels overlap", l3.getBounds().y >= l1.getBounds().y + l1.getBounds().height);
- assertTrue("Labels overlap", l4.getBounds().x >= l3.getBounds().x + l3.getBounds().width);
- assertTrue("Labels overlap", l4.getBounds().y >= l2.getBounds().y + l2.getBounds().height);
- shell.dispose();
+ layout.numColumns = 2;
+ Control l1 = ControlFactory.create(inner, 31, 100, 15);
+ Control l2 = ControlFactory.create(inner, 32, 200, 15);
+ Control l3 = ControlFactory.create(inner, 33, 400, 15);
+ Control l4 = ControlFactory.create(inner, 34, 800, 15);
+
+ inner.setSize(300, 1000);
+ inner.layout(false);
+
+ assertEquals(300, l3.getBounds().width + l4.getBounds().width);
+ assertTrue(rightEdge(l1) <= l2.getBounds().x);
+ assertEquals(rightEdge(l3), l4.getBounds().x);
+ assertTrue(bottomEdge(l1) <= l3.getBounds().y);
+ assertTrue(bottomEdge(l1) <= l4.getBounds().y);
+
+ Point preferredSize = inner.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
+ assertEquals(new Point(1200, 30), preferredSize);
+
+ int minWidth = layout.computeMinimumWidth(inner, false);
+ assertEquals(67, minWidth);
+ }
+
+ /**
+ * Test what happens when the grid is compressed below its minimum size. It
+ * should remove pixels from the column that creates the least amount of
+ * truncation.
+ * <p>
+ * Test is currently suppressed because this layout cannot handle this case
+ * properly yet.
+ */
+ public void suppressed_testCompressedBelowMinimumSize() {
+ layout.numColumns = 2;
+ Control l1 = ControlFactory.create(inner, 50, 200, 50);
+ l1.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL));
+ Control l2 = ControlFactory.create(inner, 200, 200, 50);
+ l2.setLayoutData(new TableWrapData(TableWrapData.FILL, TableWrapData.FILL));
+ Control l3 = ControlFactory.create(inner, 400, 400, 50);
+ TableWrapData data = new TableWrapData(TableWrapData.FILL, TableWrapData.FILL);
+ data.colspan = 2;
+ l3.setLayoutData(data);
+
+ inner.setSize(300, 1000);
+ inner.layout(false);
+
+ assertEquals(new Rectangle(0, 0, 100, 50), l1.getBounds());
+ assertEquals(new Rectangle(100, 0, 200, 50), l1.getBounds());
+ assertEquals(new Rectangle(0, 50, 300, 50), l1.getBounds());
}
/**
* Test alignments and margins
*/
- // Suppressed for now - see Bug 196686
- public void suppressed_testTableWrapLayoutAlignment() {
- Display display = PlatformUI.getWorkbench().getDisplay();
- Shell shell = new Shell(display);
- shell.setSize(100, 300);
- shell.setLayout(new FillLayout());
- Composite inner = new Composite(shell, SWT.V_SCROLL);
- TableWrapLayout tableWrapLayout = new TableWrapLayout();
+ @Test
+ public void testTableWrapLayoutAlignment() {
final int LEFT_MARGIN = 1;
final int RIGHT_MARGIN = 2;
final int TOP_MARGIN = 3;
final int BOTTOM_MARGIN = 4;
- tableWrapLayout.leftMargin = LEFT_MARGIN;
- tableWrapLayout.rightMargin = RIGHT_MARGIN;
- tableWrapLayout.topMargin = TOP_MARGIN;
- tableWrapLayout.bottomMargin = BOTTOM_MARGIN;
- inner.setLayout(tableWrapLayout);
- Label lab0 = new Label(inner, SWT.WRAP);
- lab0.setText(A80);
- Label labLeft = new Label(inner, SWT.NULL);
- labLeft.setText(A1);
+ layout.leftMargin = LEFT_MARGIN;
+ layout.rightMargin = RIGHT_MARGIN;
+ layout.topMargin = TOP_MARGIN;
+ layout.bottomMargin = BOTTOM_MARGIN;
+ Control lab0 = ControlFactory.create(inner, 50, 800, 15);
+
+ Control labLeft = ControlFactory.create(inner, 50, 100, 15);
TableWrapData dataLeft = new TableWrapData();
dataLeft.align = TableWrapData.LEFT;
labLeft.setLayoutData(dataLeft);
- Label labRight = new Label(inner, SWT.NULL);
- labRight.setText(A1);
+
+ Control labRight = ControlFactory.create(inner, 50, 100, 15);
TableWrapData dataRight = new TableWrapData();
dataRight.align = TableWrapData.RIGHT;
labRight.setLayoutData(dataRight);
- Label labCenter = new Label(inner, SWT.NULL);
- labCenter.setText(A1);
+
+ Control labCenter = ControlFactory.create(inner, 50, 100, 15);
TableWrapData dataCenter = new TableWrapData();
dataCenter.align = TableWrapData.CENTER;
labCenter.setLayoutData(dataCenter);
- Label labFill = new Label(inner, SWT.NULL);
- labFill.setText(A1);
+
+ Control labFill = ControlFactory.create(inner, 50, 100, 15);
TableWrapData dataFill = new TableWrapData();
dataFill.align = TableWrapData.FILL;
labFill.setLayoutData(dataFill);
- shell.layout();
+
+ inner.setSize(300 + LEFT_MARGIN + RIGHT_MARGIN, 1000);
+ inner.layout(false);
+
// Check layout
- assertEquals(LEFT_MARGIN , labLeft.getBounds().x);
- assertTrue(rightEdge(lab0) > rightEdge(labLeft));
- assertTrue(rightEdge(labLeft) + tableWrapLayout.rightMargin < 100);
+ assertEquals(new Rectangle(LEFT_MARGIN, TOP_MARGIN, 300, 40), lab0.getBounds());
+ assertEquals(new Rectangle(LEFT_MARGIN, bottomEdge(lab0), 100, 15), labLeft.getBounds());
+ assertEquals(new Rectangle(rightEdge(lab0) - 100, bottomEdge(labLeft), 100, 15), labRight.getBounds());
- assertEquals(rightEdge(labRight), rightEdge(lab0));
- assertTrue(labRight.getBounds().x > LEFT_MARGIN);
+ int centerPoint = (leftEdge(labCenter) + rightEdge(labCenter)) / 2;
+ assertEquals(150, centerPoint - LEFT_MARGIN);
- assertTrue(labCenter.getBounds().x > LEFT_MARGIN);
- assertTrue(rightEdge(lab0) > rightEdge(labCenter));
+ assertEquals(new Rectangle(LEFT_MARGIN, bottomEdge(labCenter), 300, 5), labFill.getBounds());
+ }
- int offCenter = rightEdge(labCenter) + labCenter.getBounds().x
- - rightEdge(lab0) + lab0.getBounds().x;
- assertTrue(offCenter >= -2);
- assertTrue(offCenter <= 2);
+ private static void makeFilled(Control control) {
+ TableWrapData data = new TableWrapData();
+ data.align = TableWrapData.FILL;
+ data.valign = TableWrapData.FILL;
+ control.setLayoutData(data);
+ }
- assertEquals(LEFT_MARGIN , labFill.getBounds().x);
- assertEquals(rightEdge(labFill), rightEdge(lab0));
- shell.dispose();
+ private int leftEdge(Control control) {
+ Rectangle bounds = control.getBounds();
+
+ return bounds.x;
+ }
+
+ private int bottomEdge(Control control) {
+ Rectangle bounds = control.getBounds();
+
+ return bounds.y + bounds.height;
}
}
diff --git a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/ExpandableCompositeTest.java b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/ExpandableCompositeTest.java
index 55b4e0dcf4b..37ed74327fa 100644
--- a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/ExpandableCompositeTest.java
+++ b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/ExpandableCompositeTest.java
@@ -31,6 +31,7 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.events.IExpansionListener;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.tests.forms.layout.ControlFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -140,12 +141,7 @@ public class ExpandableCompositeTest {
}
private Composite rectangleComposite(final Composite parent, final int x, final int y) {
- return new Composite(parent, SWT.NONE) {
- @Override
- public Point computeSize(int wHint, int hHint, boolean changed) {
- return new Point(x, y);
- }
- };
+ return ControlFactory.create(parent, x, y);
}
private Composite createClient() {
diff --git a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/HintAdjustmentTest.java b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/HintAdjustmentTest.java
new file mode 100644
index 00000000000..73595aebd32
--- /dev/null
+++ b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/HintAdjustmentTest.java
@@ -0,0 +1,247 @@
+package org.eclipse.ui.tests.forms.widgets;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Scrollable;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.Form;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.Hyperlink;
+import org.eclipse.ui.forms.widgets.ImageHyperlink;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.ScrolledFormText;
+import org.eclipse.ui.forms.widgets.ScrolledPageBook;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.forms.widgets.TreeNode;
+import org.eclipse.ui.forms.widgets.Twistie;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * SWT controls have a complicated contract on
+ * {@link Control#computeSize(int, int)}. Specifically, if a non-SWT.DEFAULT
+ * width (or height) hint is passed as an argument, that argument is supposed to
+ * be a few pixels off from the constrained width being queried. That means you
+ * need to subtract a small adjustment to the hints prior to invoking
+ * computeSize. The implementation of computeSize is required to add these
+ * adjustments back on when it receives the arguments. The exact adjustment to
+ * use is well-defined (see the implementation of {@link #verifyComputeSize} for
+ * details).
+ * <p>
+ * This API contract is poorly documented and may seem a bit crazy, but since
+ * every layout depends on it and every control implements it, there's no good
+ * way to fix it without API breakage -- so libraries like forms need to
+ * implement it correctly.
+ * <p>
+ * The purpose of this test is to ensure that all the controls in the forms
+ * library add the correct adjustments to the hints they receive. One way to
+ * verify this is to invoke computeSize with constant hints and assert that the
+ * result differs by the hint by exactly the amount expected for the adjustment
+ * value.
+ */
+public class HintAdjustmentTest {
+ private static Display display;
+
+ static {
+ try {
+ display = PlatformUI.getWorkbench().getDisplay();
+ } catch (Throwable e) {
+ // this is to run without eclipse
+ display = new Display();
+ }
+ }
+
+ private Shell shell;
+
+ @Before
+ public void setUp() throws Exception {
+ shell = new Shell(display);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ shell.dispose();
+ }
+
+ void verifyComputeSize(Control control) {
+ int widthAdjustment;
+ int heightAdjustment;
+ if (control instanceof Scrollable) {
+ // For scrollables, subtract off the trim size
+ Scrollable scrollable = (Scrollable) control;
+ Rectangle trim = scrollable.computeTrim(0, 0, 0, 0);
+
+ widthAdjustment = trim.width;
+ heightAdjustment = trim.height;
+ } else {
+ // For non-composites, subtract off 2 * the border size
+ widthAdjustment = control.getBorderWidth() * 2;
+ heightAdjustment = widthAdjustment;
+ }
+
+ final int TEST_VALUE = 100;
+
+ Point computedSize = control.computeSize(TEST_VALUE, TEST_VALUE);
+
+ assertEquals("control is not applying the width adjustment correctly", TEST_VALUE + widthAdjustment,
+ computedSize.x);
+ assertEquals("control is not applying the height adjustment correctly", TEST_VALUE + heightAdjustment,
+ computedSize.y);
+ }
+
+ @Test
+ public void testScrollingHyperlink() {
+ Hyperlink link = new Hyperlink(shell, SWT.H_SCROLL | SWT.V_SCROLL);
+ link.setText("This is some sample text");
+ verifyComputeSize(link);
+ }
+
+ @Test
+ public void testHyperlink() {
+ Hyperlink link = new Hyperlink(shell, SWT.NONE);
+ link.setText("This is some sample text");
+ verifyComputeSize(link);
+ }
+
+ @Test
+ public void testScrollingExpandableComposite() {
+ ExpandableComposite ec = new ExpandableComposite(shell, SWT.H_SCROLL | SWT.V_SCROLL);
+ ec.setText("Foo bar baz zipp");
+ verifyComputeSize(ec);
+ }
+
+ @Test
+ public void testExpandableComposite() {
+ ExpandableComposite ec = new ExpandableComposite(shell, SWT.NONE);
+ ec.setText("Foo bar baz zipp");
+ verifyComputeSize(ec);
+ }
+
+ @Test
+ public void testScrollingForm() {
+ Form form = new Form(shell, SWT.H_SCROLL | SWT.V_SCROLL);
+ form.setMessage("Hello world");
+ verifyComputeSize(form);
+ }
+
+ @Test
+ public void testForm() {
+ Form form = new Form(shell, SWT.NONE);
+ form.setMessage("Hello world");
+ verifyComputeSize(form);
+ }
+
+ @Test
+ public void testScrollingFormText() {
+ FormText formText = new FormText(shell, SWT.H_SCROLL | SWT.V_SCROLL);
+ formText.setText("This izza test", false, false);
+ verifyComputeSize(formText);
+ }
+
+ @Test
+ public void testFormText() {
+ FormText formText = new FormText(shell, SWT.NONE);
+ formText.setText("This izza test", false, false);
+ verifyComputeSize(formText);
+ }
+
+ @Test
+ public void testScrollingImageHyperlink() {
+ ImageHyperlink hyperlink = new ImageHyperlink(shell, SWT.H_SCROLL | SWT.V_SCROLL);
+ hyperlink.setText("Foo, bar, baz");
+ verifyComputeSize(hyperlink);
+ }
+
+ @Test
+ public void testImageHyperlink() {
+ ImageHyperlink hyperlink = new ImageHyperlink(shell, SWT.NONE);
+ hyperlink.setText("Foo, bar, baz");
+ verifyComputeSize(hyperlink);
+ }
+
+ @Test
+ public void testScrolledForm() {
+ ScrolledForm scrolledForm = new ScrolledForm(shell, SWT.NONE);
+ scrolledForm.setText("Foo, bar, baz");
+ verifyComputeSize(scrolledForm);
+ }
+
+ @Test
+ public void testScrollingScrolledForm() {
+ ScrolledForm scrolledForm = new ScrolledForm(shell, SWT.H_SCROLL | SWT.V_SCROLL);
+ scrolledForm.setText("Foo, bar, baz");
+ verifyComputeSize(scrolledForm);
+ }
+
+ @Test
+ public void testScrolledFormText() {
+ ScrolledFormText scrolledForm = new ScrolledFormText(shell, SWT.NONE, true);
+ scrolledForm.setText("Foo, bar, baz");
+ verifyComputeSize(scrolledForm);
+ }
+
+ @Test
+ public void testScrollingScrolledFormText() {
+ ScrolledFormText scrolledForm = new ScrolledFormText(shell, SWT.H_SCROLL | SWT.V_SCROLL, true);
+ scrolledForm.setText("Foo, bar, baz");
+ verifyComputeSize(scrolledForm);
+ }
+
+ @Test
+ public void testScrolledPageBook() {
+ ScrolledPageBook scrolledPageBook = new ScrolledPageBook(shell, SWT.NONE);
+ verifyComputeSize(scrolledPageBook);
+ }
+
+ @Test
+ public void testScrollingScrolledPageBook() {
+ ScrolledPageBook scrolledPageBook = new ScrolledPageBook(shell, SWT.H_SCROLL | SWT.V_SCROLL);
+ verifyComputeSize(scrolledPageBook);
+ }
+
+ @Test
+ public void testSection() {
+ Section section = new Section(shell, SWT.NONE);
+ section.setText("Hi ho he hum de da doo dum");
+ verifyComputeSize(section);
+ }
+
+ @Test
+ public void testScrollingSection() {
+ Section section = new Section(shell, SWT.H_SCROLL | SWT.V_SCROLL);
+ section.setText("Hi ho he hum de da doo dum");
+ verifyComputeSize(section);
+ }
+
+ @Test
+ public void testTreeNode() {
+ TreeNode treeNode = new TreeNode(shell, SWT.NONE);
+ verifyComputeSize(treeNode);
+ }
+
+ @Test
+ public void testScrollingTreeNode() {
+ TreeNode treeNode = new TreeNode(shell, SWT.H_SCROLL | SWT.V_SCROLL);
+ verifyComputeSize(treeNode);
+ }
+
+ @Test
+ public void testTwistie() {
+ Twistie twistie = new Twistie(shell, SWT.NONE);
+ verifyComputeSize(twistie);
+ }
+
+ @Test
+ public void testScrollingTwistie() {
+ Twistie twistie = new Twistie(shell, SWT.H_SCROLL | SWT.V_SCROLL);
+ verifyComputeSize(twistie);
+ }
+}
diff --git a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/SizeCacheTest.java b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/SizeCacheTest.java
index d259d29dedf..044d61d8782 100644
--- a/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/SizeCacheTest.java
+++ b/tests/org.eclipse.ui.tests.forms/forms/org/eclipse/ui/tests/forms/widgets/SizeCacheTest.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.ui.tests.forms.widgets;
+import static org.junit.Assert.assertEquals;
+
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
@@ -27,11 +29,11 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.widgets.SizeCache;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
-import junit.framework.TestCase;
-
-public class SizeCacheTest extends TestCase {
+public class SizeCacheTest {
private static Display display;
private Shell shell;
private static final String SHORT_TEXT = "Hedgehog";
@@ -54,7 +56,7 @@ public class SizeCacheTest extends TestCase {
}
}
- @Override
+ @Before
public void setUp() throws Exception {
font = new Font(display, "Arial", 12, SWT.NORMAL);
shell = new Shell(display);
@@ -64,7 +66,7 @@ public class SizeCacheTest extends TestCase {
shell.open();
}
- @Override
+ @After
public void tearDown() throws Exception {
if (humanWatching)
dispatch(1000);
@@ -120,15 +122,41 @@ public class SizeCacheTest extends TestCase {
control.setSize(expectedSize);
dispatch();
- expectedSize = getAdjustedExpected(expectedSize, whint, hhint);
-
checkDoubleCall(whint, hhint);
checkPreferedThenOther(whint, hhint);
return expectedSize;
}
- private Point controlComputeSize(int whint, int hhint) {
- return control.computeSize(whint, hhint, true);
+ private Point controlComputeSize(int wHint, int hHint) {
+ Point adjusted = computeHintOffset();
+
+ int adjustedWidthHint = wHint;
+ if (adjustedWidthHint != SWT.DEFAULT) {
+ adjustedWidthHint = Math.max(0, wHint - adjusted.x);
+ }
+
+ int adjustedHeightHint = hHint;
+ if (adjustedHeightHint != SWT.DEFAULT) {
+ adjustedHeightHint = Math.max(0, hHint - adjusted.y);
+ }
+
+ Point result = control.computeSize(adjustedWidthHint, adjustedHeightHint, true);
+
+ // Ignore any component if the hint was something other than SWT.DEFAULT.
+ // There's no way to measure hints smaller than the adjustment value and
+ // somecontrols have buggy computeSize methods that don't return non-default
+ // hints verbatim. The purpose of this test is to verify SizeCache, not the
+ // controls, and we don't want such quirks to create failures, so we correct the
+ // result here if necessary.
+ if (wHint != SWT.DEFAULT) {
+ result.x = wHint;
+ }
+
+ if (hHint != SWT.DEFAULT) {
+ result.y = hHint;
+ }
+
+ return result;
}
private Point checkAlterate(int whint, int hhint) {
@@ -143,13 +171,6 @@ public class SizeCacheTest extends TestCase {
return expectedSize1;
}
- private Point getAdjustedExpected(Point calcSize, int whint, int hhint) {
- Point adjusted = computeHintOffset();
- int expectedHeight = hhint == SWT.DEFAULT ? calcSize.y : hhint + adjusted.y;
- int expectedWidth = whint == SWT.DEFAULT ? calcSize.x : whint + adjusted.x;
- return new Point(expectedWidth, expectedHeight);
- }
-
private Point computeHintOffset() {
Point size = new Point(0, 0);
if (control instanceof Scrollable) {

Back to the top