/** * Copyright (c) 2014 - 2017 Frank Appel * 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: * Frank Appel - initial API and implementation */ package com.codeaffine.eclipse.swt.widget.scrollable.context; import static com.codeaffine.eclipse.swt.test.util.ShellHelper.createShell; import static com.codeaffine.eclipse.swt.widget.scrollable.ScrolledCompositeHelper.createScrolledComposite; import static com.codeaffine.eclipse.swt.widget.scrollable.TreeHelper.createTree; import static com.codeaffine.eclipse.swt.widget.scrollable.TreeHelper.expandTopBranch; import static org.assertj.core.api.Assertions.assertThat; import java.util.stream.Stream; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.ScrollBar; import org.eclipse.swt.widgets.Scrollable; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import com.codeaffine.eclipse.swt.test.util.DisplayHelper; import com.codeaffine.eclipse.swt.test.util.SWTIgnoreConditions.CocoaPlatform; import com.codeaffine.eclipse.swt.util.ControlReflectionUtil; import com.codeaffine.test.util.junit.ConditionalIgnoreRule; import com.codeaffine.test.util.junit.ConditionalIgnoreRule.ConditionalIgnore; public class SizeComputerTest { @Rule public final DisplayHelper displayHelper = new DisplayHelper(); @Rule public final ConditionalIgnoreRule conditionalIgnoreRule = new ConditionalIgnoreRule(); private SizeComputer computer; private Composite adapter; private Tree scrollable; private Shell shell; @Before public void setUp() { shell = createShell( displayHelper ); adapter = createAdapter( shell ); scrollable = createTree( adapter, 6, 4 ); computer = createSizeComputer( scrollable, adapter ); shell.layout(); shell.open(); } @Test public void getPreferredSizeIfWidthIsSmallerThanAdapterAreaWidth() { Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( expectedSizeWithClientAreaWidth() ); } @Test @ConditionalIgnore( condition = CocoaPlatform.class ) public void getPreferredSizeIfWidthIsLargerThanAdapterAreaWidth() { expandTopBranch( scrollable ); Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( expectedSize() ); } @Test @ConditionalIgnore( condition = CocoaPlatform.class ) public void getPreferredSizeIfWidthIsLargerThanAdapterAreaWidthButHasOwnerDrawnItems() { expandTopBranch( scrollable ); shell.setSize( 200, 200 ); Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( expectedSize() ); } @Test @ConditionalIgnore( condition = CocoaPlatform.class ) public void getPreferredSizeIfWidthIsLargerThanAdapterAreaWidthButHasOwnerDrawnItemsAndIsVirtual() { createOwnderDrawnVirtualScrollable(); computer = createSizeComputer( scrollable, adapter ); shell.layout(); expandTopBranch( scrollable ); shell.setSize( 200, 200 ); Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( expectedSizeOnOwnerDrawnScrollable() ); assertThat( scrollable.getHorizontalBar().isVisible() ).isFalse(); } @Test public void getPreferredSizeOnIfWidthIsEqualsToScrollableContentWidth() { expandTopBranch( scrollable ); shell.setSize( 200, 200 ); Point expected = expectedSizeIfWidthIsEqualsToScrollableContentWidth(); scrollable.setSize( expected ); Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( expected ); } @Test public void getPreferredSizeForScrolledComposite() { Stream.of( adapter.getChildren() ).forEach( child -> child.dispose() ); ScrolledComposite scrolledComposite = createScrolledComposite( adapter ); computer = createSizeComputer( scrolledComposite, adapter ); Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( scrolledComposite.getContent().getSize() ); } @Test public void getPreferredSizeForScrolledCompositeThatHasNoContent() { Stream.of( adapter.getChildren() ).forEach( child -> child.dispose() ); ScrolledComposite scrolledComposite = new ScrolledComposite( adapter, SWT.H_SCROLL | SWT.V_SCROLL ); computer = createSizeComputer( scrolledComposite, adapter ); Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( scrolledComposite.computeSize( SWT.DEFAULT, SWT.DEFAULT, true ) ); } @Test public void preferredSizeGetsBuffered() { Point expected = computer.getPreferredSize(); expandTopBranch( scrollable ); Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( expected ); } @Test public void adjustPreferredWidthIfHorizontalBarIsNotVisible() { computer.adjustPreferredWidthIfHorizontalBarIsVisible(); Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( expectedSizeWithClientAreaWidth() ); } @Test @ConditionalIgnore( condition = CocoaPlatform.class ) public void adjustPreferredWidthIfHorizontalBarIsVisible() { expandTopBranch( scrollable ); computer.adjustPreferredWidthIfHorizontalBarIsVisible(); Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( expectedSize() ); } @Test @ConditionalIgnore( condition = CocoaPlatform.class ) public void adjustPreferredWidthIfHorizontalBarIsVisibleIfReparented() { reparentScrollable( shell, scrollable ); expandTopBranch( scrollable ); computer.adjustPreferredWidthIfHorizontalBarIsVisible(); Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( expectedSizeWithPreferredWidthAdjustment() ); } @Test @ConditionalIgnore( condition = CocoaPlatform.class ) public void updatePreferredSize() { Point preferredSize = computer.getPreferredSize(); expandTopBranch( scrollable ); computer.updatePreferredSize(); Point actual = computer.getPreferredSize(); assertThat( actual ).isNotEqualTo( preferredSize ); } @Test public void updatePreferredSizeBuffering() { expandTopBranch( scrollable ); shell.setSize( 400, 200 ); computer.updatePreferredSize(); Point buffered = computer.getPreferredSize(); shell.setSize( 200, 200 ); computer.updatePreferredSize(); Point actual = computer.getPreferredSize(); assertThat( actual ).isEqualTo( buffered ); } private static Composite createAdapter( Composite parent ) { Composite result = new Composite( parent, SWT.NONE ); result.setLayout( new FillLayout() ); return result; } private Point expectedSizeWithClientAreaWidth() { return new Point( adapter.getClientArea().width, computePreferredScrollableSize().y ); } private Point expectedSize() { ScrollBar horizontalBar = scrollable.getHorizontalBar(); return new Point( horizontalBar.getMaximum(), computePreferredScrollableSize().y ); } private Point expectedSizeWithPreferredWidthAdjustment() { ScrollBar horizontalBar = scrollable.getHorizontalBar(); return new Point( horizontalBar.getMaximum() * 2, computePreferredScrollableSize().y ); } private Point expectedSizeOnOwnerDrawnScrollable() { int height = scrollable.computeSize( SWT.DEFAULT, SWT.DEFAULT, true ).y; return new Point( adapter.getClientArea().width, height ); } private Point expectedSizeIfWidthIsEqualsToScrollableContentWidth() { Point size = scrollable.computeSize( SWT.DEFAULT, SWT.DEFAULT, true ); return new Point( size.x - scrollable.getVerticalBar().getSize().x, size.y ); } private Point computePreferredScrollableSize() { return scrollable.computeSize( SWT.DEFAULT, SWT.DEFAULT, true ); } private void createOwnderDrawnVirtualScrollable() { scrollable.dispose(); scrollable = createTree( adapter, 6, 4, SWT.VIRTUAL ); scrollable.addListener( SWT.MeasureItem, evt -> {} ); scrollable.getHorizontalBar().setVisible( true ); } private static void reparentScrollable( Composite parent, Scrollable scrollable ) { new ControlReflectionUtil().setField( scrollable, "parent", parent ); } private static SizeComputer createSizeComputer( Scrollable scrollable, Composite adapter ) { return new SizeComputer( new ScrollableControl<>( scrollable ), adapter ); } }