package org.eclipse.swt.tests;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StyledTextMarginsBugTest {
private Display display;
private Shell shell;
private StyledText textBoxWithMargins;
private Composite containerWithMargins;
private StyledText textBoxWithoutMargins;
private static final String TEXT = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, " +
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
private Point textPrefSize;
private int margin;
private int lineHeight;
private int twoLineHeight;
/**
*
* SHELL
* - root (pref width)
* - 1) container (right margin)
* - text
* - 2) text (right margin)
*
*
* - the first text control inside container with margin displays correctly
* - the second text control is not laid-out correctly
* (second line is correctly wrapped, but is not visible because {@linkplain StyledText#computeSize(int,int)} does not return correct values.
*
*/
@Before
public void setUp () {
display = Display.getDefault ();
shell = new Shell (display, SWT.SHELL_TRIM);
shell.setText ("StyledText Margins Layout Bug Tester");
final GridLayout shellLayout = new GridLayout ();
shellLayout.marginWidth = 12;
shellLayout.marginHeight = 9;
shell.setLayout (shellLayout);
final Composite root = new Composite(shell, SWT.NONE);
final GridLayout rootLayout = new GridLayout ();
rootLayout.marginWidth = 0;
rootLayout.marginHeight = 0;
root.setLayout (rootLayout);
containerWithMargins = new Composite (root, SWT.NONE);
final GridLayout layoutWithMargin = new GridLayout ();
layoutWithMargin.marginWidth = 0;
layoutWithMargin.marginHeight = 0;
containerWithMargins.setLayout (layoutWithMargin);
textBoxWithoutMargins = new StyledText (containerWithMargins, SWT.MULTI | SWT.WRAP);
textBoxWithoutMargins.setText (TEXT);
textBoxWithMargins = new StyledText (root, SWT.MULTI | SWT.WRAP);
textBoxWithMargins.setText (TEXT);
textPrefSize = textBoxWithMargins.computeSize (SWT.DEFAULT, SWT.DEFAULT);
// Lets set the margin to the third of the preferred width of the text control
margin = textPrefSize.x / 3;
layoutWithMargin.marginRight = margin;
textBoxWithMargins.setRightMargin (margin);
// set the root width hint to the text preferred width
final GridData rootLD = new GridData (SWT.FILL, SWT.FILL, true, true);
rootLD.widthHint = textPrefSize.x;
root.setLayoutData (rootLD);
// finish the initialization with some common layout data setting...
containerWithMargins.setLayoutData (new GridData (SWT.FILL, SWT.TOP, true, false));
textBoxWithMargins.setLayoutData (new GridData (SWT.FILL, SWT.TOP, true, false));
textBoxWithoutMargins.setLayoutData (new GridData (SWT.FILL, SWT.FILL, true, true));
// and debugging colors
containerWithMargins.setBackground (display.getSystemColor (SWT.COLOR_GREEN));
textBoxWithoutMargins.setBackground (display.getSystemColor (SWT.COLOR_BLUE));
textBoxWithMargins.setBackground (display.getSystemColor (SWT.COLOR_RED));
// pack shell (to the size where the bug is most visible -- to the pref. width of the text
// (=previous preferred width of the text control without margins)
shell.pack ();
// shell.setSize (shell.computeSize (textPrefSize.x, SWT.DEFAULT));
// Prepare line height values against which the assertions will be performed
final int lineSpacing = textBoxWithoutMargins.getLineSpacing ();
lineHeight = textBoxWithoutMargins.getLineHeight ();
twoLineHeight = (lineHeight * 2) + lineSpacing;
}
@After
public void tearDown () {
if (shell != null && !shell.isDisposed ()) {
shell.dispose ();
}
shell = null;
}
/**
* This is of course ok :)
*/
@Test
public void testComputeSizePreferred () {
// PREFERRED SIZE... that is ok :)
assertEquals (textPrefSize, textBoxWithoutMargins.computeSize (SWT.DEFAULT, SWT.DEFAULT));
assertEquals (textPrefSize.x + margin, containerWithMargins.computeSize (SWT.DEFAULT, SWT.DEFAULT).x);
assertEquals (textPrefSize.x + margin, textBoxWithMargins.computeSize (SWT.DEFAULT, SWT.DEFAULT).x);
}
@Test
public void testMyAssumptions() {
// tests my assumption that the pref height of a one line StyledText control is equal to the line height.
assertEquals (lineHeight, textPrefSize.y);
assertEquals (textPrefSize, textBoxWithoutMargins.computeSize (SWT.DEFAULT, SWT.DEFAULT));
assertEquals (twoLineHeight, textBoxWithoutMargins.computeSize (textPrefSize.x - margin, SWT.DEFAULT).y);
// StyledText.getLineCound() currently does not return 2, but if main method is run,
// there will be two lines rendered in the correct (blue) StyledText.
// assertEquals (2, textBoxWithMargins.getLineCount ());
}
/**
* Shows how the bug in the {@linkplain StyledText#computeSize(int, int, boolean)} represents itself.
*/
@Test
public void testComputeSizeWithWidthConstraint () {
// On my Mac, there is some 1px addition to the calculated width that I can't pinpoint...
// so change this small value if it doesn't match exactly.
// (the bug will present itself with much greater difference)
final int textBoxCalculatedWidthAdditon = 1;
// no margin StyledText test
assertEquals ("reference test... this is how it looks when no margin is set\n",
new Point(textPrefSize.x + textBoxCalculatedWidthAdditon, textPrefSize.y),
textBoxWithoutMargins.computeSize (textPrefSize.x, SWT.DEFAULT)
);
assertEquals ("reference test... this is how it half width StyledText looks when no margin is set\n",
new Point(textPrefSize.x - margin + textBoxCalculatedWidthAdditon, twoLineHeight),
textBoxWithoutMargins.computeSize (textPrefSize.x - margin, SWT.DEFAULT)
);
// margined Composite test
assertEquals ("composite with margins... calculates the size correctly\n",
new Point(
textPrefSize.x, // the margin is incorporated inside the composite
twoLineHeight
),
containerWithMargins.computeSize (textPrefSize.x, SWT.DEFAULT)
);
// margined StyledText test – will fail if the bug this test describes is still in place
assertEquals ("TextBox with margins... calculates the size incorrectly because of this bug!\n",
new Point(
textPrefSize.x + textBoxCalculatedWidthAdditon, // the margin should be incorporated inside the StyledText
twoLineHeight // the text should be 2 lines high, but as this failed test shows, it is only 1 line high!
),
textBoxWithMargins.computeSize (textPrefSize.x, SWT.DEFAULT, true)
);
/*
* We see that the margin is calculated into the size AFTER the dimensions based on the text were done.
* But it has to be done in the reverse order:
* -- the available space has to be cropped BEFORE the size of the text is calculated.
*
* Solution is in repairing the {@linkplain StyledText#computeSize(int, int, boolean)} method ;)
* (if i knew how to compile the swt library, I would correct it myself)
*/
}
/**
* Main
*/
static public void main(final String... args) {
final StyledTextMarginsBugTest test = new StyledTextMarginsBugTest();
test.setUp ();
test.shell.open ();
while (!test.shell.isDisposed ()) {
if (!test.display.readAndDispatch ()) {
test.display.sleep ();
}
}
test.tearDown ();
}
}