diff options
author | Artur <artur@vaadin.com> | 2017-05-30 16:24:58 +0300 |
---|---|---|
committer | Ilia Motornyi <elmot@vaadin.com> | 2017-05-30 16:24:58 +0300 |
commit | 39846ae08337d55a24d3d90a6350f8e565a5c27f (patch) | |
tree | 5b77ba5236e440f7f79990b5e1372188681338a8 | |
parent | 2b9bcc62cfa0ee1d4f5da915190a8f03f076037c (diff) | |
download | vaadin-framework-39846ae08337d55a24d3d90a6350f8e565a5c27f.tar.gz vaadin-framework-39846ae08337d55a24d3d90a6350f8e565a5c27f.zip |
Allow grid columns to optionally shrink to be narrower than contents
Fixes #8548
8 files changed, 212 insertions, 10 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java index bfc605ee2e..89914ea664 100644 --- a/client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/grid/ColumnConnector.java @@ -131,6 +131,11 @@ public class ColumnConnector extends AbstractExtensionConnector { column.setMinimumWidth(getState().minWidth); } + @OnStateChange("minimumWidthFromContent") + void updateMinimumWidthFromContent() { + column.setMinimumWidthFromContent(getState().minimumWidthFromContent); + } + @OnStateChange("maxWidth") void updateMaxWidth() { column.setMaximumWidth(getState().maxWidth); diff --git a/client/src/main/java/com/vaadin/client/widgets/Grid.java b/client/src/main/java/com/vaadin/client/widgets/Grid.java index fb59329883..1d4abddf54 100755 --- a/client/src/main/java/com/vaadin/client/widgets/Grid.java +++ b/client/src/main/java/com/vaadin/client/widgets/Grid.java @@ -3393,8 +3393,13 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, final int expandRatio = defaultExpandRatios ? 1 : column.getExpandRatio(); final double maxWidth = getMaxWidth(column); - final double newWidth = Math.min(maxWidth, - column.getWidthActual()); + double newWidth; + if (column.isMinimumWidthFromContent()) { + newWidth = Math.min(maxWidth, column.getWidthActual()); + } else { + newWidth = 0; + } + boolean shouldExpand = newWidth < maxWidth && expandRatio > 0 && column != selectionColumn; if (shouldExpand) { @@ -4673,7 +4678,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * @param <T> * the row type */ - public static abstract class Column<C, T> { + public abstract static class Column<C, T> { /** * Default renderer for GridColumns. Renders everything into text @@ -4736,6 +4741,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private double minimumWidthPx = GridConstants.DEFAULT_MIN_WIDTH; private double maximumWidthPx = GridConstants.DEFAULT_MAX_WIDTH; private int expandRatio = GridConstants.DEFAULT_EXPAND_RATIO; + private boolean minimumWidthFromContent = true; /** * Constructs a new column with a simple TextRenderer. @@ -5265,6 +5271,43 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } /** + * Sets whether the width of the contents in the column should be + * considered minimum width for this column. + * <p> + * If this is set to <code>true</code> (default for backwards + * compatibility), then a column will not shrink to smaller than the + * width required to show the contents available when calculating the + * widths (first N rows). + * <p> + * If this is set to <code>false</code>, then a column will shrink if + * necessary to the minimum width defined by + * {@link #setMinimumWidth(double)} <em>when it is set to expand</em>. + * + * @param minimumWidthFromContent + * <code>true</code> to reserve space for all contents, + * <code>false</code> to allow the column to shrink smaller + * than the contents + * @since + */ + public void setMinimumWidthFromContent( + boolean minimumWidthFromContent) { + this.minimumWidthFromContent = minimumWidthFromContent; + } + + /** + * Gets whether the width of the contents in the column should be + * considered minimum width for this column. + * + * @return <code>true</code> to reserve space for all contents, + * <code>false</code> to allow the column to shrink smaller than + * the contents + * @since + */ + public boolean isMinimumWidthFromContent() { + return minimumWidthFromContent; + } + + /** * Sets the maximum width for this column. * <p> * This defines the maximum allowed pixel width of the column <em>when @@ -5435,6 +5478,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, protected void setDefaultHeaderContent(HeaderCell cell) { cell.setText(headerCaption); } + } protected class BodyUpdater implements EscalatorUpdater { diff --git a/documentation/components/components-grid.asciidoc b/documentation/components/components-grid.asciidoc index 160b97f077..5a9cef230b 100644 --- a/documentation/components/components-grid.asciidoc +++ b/documentation/components/components-grid.asciidoc @@ -344,7 +344,11 @@ value with [methodname]#setWidth()#, or relatively using expand ratios with [methodname]#setExpandRatio()#. When using expand ratios, the columns with a non-zero expand ratio use the extra -space remaining from other columns, in proportion to the defined ratios. +space remaining from other columns, in proportion to the defined ratios. Do note +that the minimum width of an expanded column by default is based on the contents +of the column (the initially rendered rows). To allow the column to become +narrower than this, use [methodname]#setMinimumWidthFromContent(false)# +(introduced in 8.1). You can specify minimum and maximum widths for the expanding columns with [methodname]#setMinimumWidth()# and [methodname]#setMaximumWidth()#, diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java index d5bdfe45e8..3ae03679cf 100644 --- a/server/src/main/java/com/vaadin/ui/Grid.java +++ b/server/src/main/java/com/vaadin/ui/Grid.java @@ -1472,9 +1472,12 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents, * This defines the minimum guaranteed pixel width of the column * <em>when it is set to expand</em>. * + * @param pixels + * the minimum width for the column * @throws IllegalStateException * if the column is no longer attached to any grid * @see #setExpandRatio(int) + * @return the column itself */ public Column<T, V> setMinimumWidth(double pixels) throws IllegalStateException { @@ -1502,6 +1505,57 @@ public class Grid<T> extends AbstractListing<T> implements HasComponents, } /** + * Sets whether the width of the contents in the column should be + * considered minimum width for this column. + * <p> + * If this is set to <code>true</code> (default for backwards + * compatibility), then a column will not shrink to smaller than the + * width required to show the contents available when calculating the + * widths (only the widths of the initially rendered rows are + * considered). + * <p> + * If this is set to <code>false</code> and the column has been set to + * expand using #setExpandRatio(int), then the contents of the column + * will be ignored when calculating the width, and the column will thus + * shrink down to the minimum width defined by #setMinimumWidth(double) + * if necessary. + * + * @param minimumWidthFromContent + * <code>true</code> to reserve space for all contents, + * <code>false</code> to allow the column to shrink smaller + * than the contents + * @return the column itself + * @throws IllegalStateException + * if the column is no longer attached to any grid + * @see #setMinimumWidth(double) + * @since + */ + public Column<T, V> setMinimumWidthFromContent( + boolean minimumWidthFromContent) throws IllegalStateException { + checkColumnIsAttached(); + + if (isMinimumWidthFromContent() != minimumWidthFromContent) { + getState().minimumWidthFromContent = minimumWidthFromContent; + getGrid().markAsDirty(); + } + return this; + } + + /** + * Gets whether the width of the contents in the column should be + * considered minimum width for this column. + * + * @return <code>true</code> to reserve space for all contents, + * <code>false</code> to allow the column to shrink smaller than + * the contents + * @see #setMinimumWidthFromContent(boolean) + * @since + */ + public boolean isMinimumWidthFromContent() { + return getState(false).minimumWidthFromContent; + } + + /** * Sets the maximum width for this column. * <p> * This defines the maximum allowed pixel width of the column <em>when diff --git a/shared/src/main/java/com/vaadin/shared/ui/grid/ColumnState.java b/shared/src/main/java/com/vaadin/shared/ui/grid/ColumnState.java index 40167ea061..230db387ff 100644 --- a/shared/src/main/java/com/vaadin/shared/ui/grid/ColumnState.java +++ b/shared/src/main/java/com/vaadin/shared/ui/grid/ColumnState.java @@ -64,5 +64,9 @@ public class ColumnState extends AbstractGridExtensionState { public boolean resizable = true; public Connector renderer; + /** + * Whether the contents define the minimum width for this column. + */ + public boolean minimumWidthFromContent = true; } diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnShrinkSmallerThanContents.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnShrinkSmallerThanContents.java new file mode 100644 index 0000000000..e008adbf19 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnShrinkSmallerThanContents.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Component; +import com.vaadin.ui.Grid; + +@Widgetset("com.vaadin.DefaultWidgetSet") +public class GridColumnShrinkSmallerThanContents extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + addComponent(createGrid(true)); + addComponent(createGrid(false)); + } + + private Component createGrid(boolean minimumWidthFromContent) { + Grid<Object> grid = new Grid<>(); + grid.addColumn(item -> "Contents in column 1"); + grid.addColumn( + item -> "Contents in column 2. Contents in column 2. Contents in column 2. Contents in column 2. Contents in column 2.") + .setExpandRatio(1) + .setMinimumWidthFromContent(minimumWidthFromContent); + grid.setItems(new Object(), new Object()); + grid.setWidth("500px"); + return grid; + } + +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/GridColumnShrinkSmallerThanContentsTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/GridColumnShrinkSmallerThanContentsTest.java new file mode 100644 index 0000000000..94fe348bff --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/GridColumnShrinkSmallerThanContentsTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class GridColumnShrinkSmallerThanContentsTest extends SingleBrowserTest { + + @Test + public void scrollbarAndNoScrollbar() { + openTestURL(); + GridElement noshrinkColumnGrid = $(GridElement.class).get(0); + GridElement shrinkColumnGrid = $(GridElement.class).get(1); + assertHorizontalScrollbar(noshrinkColumnGrid.getHorizontalScroller(), + "Should have a horizontal scrollbar as column 2 should be wide"); + assertNoHorizontalScrollbar(shrinkColumnGrid.getHorizontalScroller(), + "Should not have a horizontal scrollbar as column 2 should be narrow"); + } +} diff --git a/uitest/src/test/java/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/test/java/com/vaadin/tests/tb3/AbstractTB3Test.java index 8447e1e4d5..5f02282a51 100644 --- a/uitest/src/test/java/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/test/java/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -1171,18 +1171,29 @@ public abstract class AbstractTB3Test extends ParallelTest { protected void assertNoHorizontalScrollbar(WebElement element, String errorMessage) { + assertHasHorizontalScrollbar(element, errorMessage, false); + } + + protected void assertHorizontalScrollbar(WebElement element, + String errorMessage) { + assertHasHorizontalScrollbar(element, errorMessage, true); + } + + private void assertHasHorizontalScrollbar(WebElement element, + String errorMessage, boolean expected) { // IE rounds clientWidth/clientHeight down and scrollHeight/scrollWidth // up, so using clientWidth/clientHeight will fail if the element height // is not an integer int clientWidth = getClientWidth(element); int scrollWidth = getScrollWidth(element); boolean hasScrollbar = scrollWidth > clientWidth; - - Assert.assertFalse( - "The element should not have a horizontal scrollbar (scrollWidth: " - + scrollWidth + ", clientWidth: " + clientWidth + "): " - + errorMessage, - hasScrollbar); + String message = "The element should"; + if (!expected) { + message += " not"; + } + message += " have a horizontal scrollbar (scrollWidth: " + scrollWidth + + ", clientWidth: " + clientWidth + "): " + errorMessage; + Assert.assertEquals(message, expected, hasScrollbar); } protected void assertNoVerticalScrollbar(WebElement element, |