From bda7e54cb6eadddf07fb19d88479c642c4831a66 Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Fri, 11 Aug 2017 15:27:27 +0300 Subject: [PATCH] Provide API for setting row heights in Grid for different sections (#9810) Fixes #9425 --- all/src/main/templates/release-notes.html | 1 + .../client/connectors/grid/GridConnector.java | 60 +++++++++--- server/src/main/java/com/vaadin/ui/Grid.java | 98 +++++++++++++++++-- .../com/vaadin/shared/ui/grid/GridState.java | 21 +++- .../components/grid/basics/GridBasics.java | 12 +++ .../grid/basics/GridRowHeightTest.java | 20 ++++ 6 files changed, 191 insertions(+), 21 deletions(-) diff --git a/all/src/main/templates/release-notes.html b/all/src/main/templates/release-notes.html index afc82cc67d..4aba9969f0 100644 --- a/all/src/main/templates/release-notes.html +++ b/all/src/main/templates/release-notes.html @@ -116,6 +116,7 @@
  • TreeGrid.createColumn() has an additional parameter.
  • LocalDateTimeToDateConverter now uses ZoneId instead of ZoneOffset.
  • FontAwesome icon alignment in ComboBox has changed in the theme.
  • +
  • GridState variable rowHeight has replaced by three variables.
  • For incompatible or behaviour-altering changes in 8.0, please see 8.0 release notes

    diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java index 61c0957d03..41602fbcef 100644 --- a/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java @@ -44,6 +44,7 @@ import com.vaadin.client.connectors.AbstractListingConnector; import com.vaadin.client.connectors.grid.ColumnConnector.CustomColumn; import com.vaadin.client.data.DataSource; import com.vaadin.client.ui.SimpleManagedLayout; +import com.vaadin.client.widget.escalator.RowContainer; import com.vaadin.client.widget.grid.CellReference; import com.vaadin.client.widget.grid.EventCellReference; import com.vaadin.client.widget.grid.events.BodyClickHandler; @@ -117,6 +118,7 @@ public class GridConnector extends AbstractListingConnector /* Child component list for HasComponentsConnector */ private List childComponents; private ItemClickHandler itemClickHandler = new ItemClickHandler(); + private boolean rowHeightScheduled = false; /** * Gets the string identifier of the given column in this grid. @@ -347,19 +349,53 @@ public class GridConnector extends AbstractListingConnector grid.setHeaderVisible(state.visible); } - @OnStateChange("rowHeight") + @OnStateChange({ "bodyRowHeight", "headerRowHeight", "footerRowHeight" }) void updateRowHeight() { - double rowHeight = getState().rowHeight; - if (rowHeight >= 0) { - getWidget().getEscalator().getHeader() - .setDefaultRowHeight(rowHeight); - getWidget().getEscalator().getBody().setDefaultRowHeight(rowHeight); - getWidget().getEscalator().getFooter() - .setDefaultRowHeight(rowHeight); - } else if (getWidget().isAttached()) { - // finally to make sure column sizes have been set before this - Scheduler.get() - .scheduleFinally(() -> getWidget().resetSizesFromDom()); + if (rowHeightScheduled) { + return; + } + + Scheduler.get().scheduleFinally(() -> { + GridState state = getState(); + if (getWidget().isAttached() && rowHeightNeedsReset()) { + getWidget().resetSizesFromDom(); + } + updateContainerRowHeigth(getWidget().getEscalator().getBody(), + state.bodyRowHeight); + updateContainerRowHeigth(getWidget().getEscalator().getHeader(), + state.headerRowHeight); + updateContainerRowHeigth(getWidget().getEscalator().getFooter(), + state.footerRowHeight); + rowHeightScheduled = false; + }); + + rowHeightScheduled = true; + } + + private boolean rowHeightNeedsReset() { + GridState state = getState(); + // Body + boolean bodyAutoCalc = state.bodyRowHeight < 0; + + // Header + boolean headerAutoCalc = state.headerRowHeight < 0; + boolean headerReset = headerAutoCalc && hasVisibleContent(state.header); + + // Footer + boolean footerAutoCalc = state.footerRowHeight < 0; + boolean footerReset = footerAutoCalc && hasVisibleContent(state.footer); + + return bodyAutoCalc || headerReset || footerReset; + } + + private boolean hasVisibleContent(SectionState state) { + return state.visible && !state.rows.isEmpty(); + } + + private void updateContainerRowHeigth(RowContainer container, + double height) { + if (height >= 0) { + container.setDefaultRowHeight(height); } } diff --git a/server/src/main/java/com/vaadin/ui/Grid.java b/server/src/main/java/com/vaadin/ui/Grid.java index 70e947ccd8..1aca35d3ec 100644 --- a/server/src/main/java/com/vaadin/ui/Grid.java +++ b/server/src/main/java/com/vaadin/ui/Grid.java @@ -3012,27 +3012,113 @@ public class Grid extends AbstractListing implements HasComponents, } /** - * Sets the height of a row. If -1 (default), the row height is calculated - * based on the theme for an empty row before the Grid is displayed. + * Sets the height of body, header and footer rows. If -1 (default), the row + * height is calculated based on the theme for an empty row before the Grid + * is displayed. *

    * Note that all header, body and footer rows get the same height if * explicitly set. In automatic mode, each section is calculated separately * based on an empty row of that type. + * + * @see #setBodyRowHeight(double) + * @see #setHeaderRowHeight(double) + * @see #setFooterRowHeight(double) * * @param rowHeight * The height of a row in pixels or -1 for automatic calculation */ public void setRowHeight(double rowHeight) { - getState().rowHeight = rowHeight; + setBodyRowHeight(rowHeight); + setHeaderRowHeight(rowHeight); + setFooterRowHeight(rowHeight); + } + + /** + * Sets the height of a body row. If -1 (default), the row height is + * calculated based on the theme for an empty row before the Grid is + * displayed. + * + * @param rowHeight + * The height of a row in pixels or -1 for automatic calculation + * @since 8.1.2 + */ + public void setBodyRowHeight(double rowHeight) { + getState().bodyRowHeight = rowHeight; + } + + /** + * Sets the height of a header row. If -1 (default), the row height is + * calculated based on the theme for an empty row before the Grid is + * displayed. + * + * @param rowHeight + * The height of a row in pixels or -1 for automatic calculation + * @since 8.1.2 + */ + public void setHeaderRowHeight(double rowHeight) { + getState().headerRowHeight = rowHeight; } /** - * Returns the currently explicitly set row height or -1 if automatic. + * Sets the height of a footer row. If -1 (default), the row height is + * calculated based on the theme for an empty row before the Grid is + * displayed. * - * @return explicitly set row height in pixels or -1 if in automatic mode + * @param rowHeight + * The height of a row in pixels or -1 for automatic calculation + * @since 8.1.2 */ + public void setFooterRowHeight(double rowHeight) { + getState().footerRowHeight = rowHeight; + } + + /** + * Returns the current body row height.-1 if row height is in automatic + * calculation mode. + * + * @see #getBodyRowHeight() + * @see #getHeaderRowHeight() + * @see #getFooterRowHeight() + * + * @return body row height + * @deprecated replaced by three separate row height controls + */ + @Deprecated public double getRowHeight() { - return getState(false).rowHeight; + return getBodyRowHeight(); + } + + /** + * Returns the current body row height. -1 if row height is in automatic + * calculation mode. + * + * @return body row height + * @since 8.1.2 + */ + public double getBodyRowHeight() { + return getState(false).bodyRowHeight; + } + + /** + * Returns the current header row height. -1 if row height is in automatic + * calculation mode. + * + * @return header row height + * @since 8.1.2 + */ + public double getHeaderRowHeight() { + return getState(false).headerRowHeight; + } + + /** + * Returns the current footer row height. -1 if row height is in automatic + * calculation mode. + * + * @return footer row height + * @since 8.1.2 + */ + public double getFooterRowHeight() { + return getState(false).footerRowHeight; } /** diff --git a/shared/src/main/java/com/vaadin/shared/ui/grid/GridState.java b/shared/src/main/java/com/vaadin/shared/ui/grid/GridState.java index 77744a9bb0..f2ebd903b2 100644 --- a/shared/src/main/java/com/vaadin/shared/ui/grid/GridState.java +++ b/shared/src/main/java/com/vaadin/shared/ui/grid/GridState.java @@ -147,11 +147,26 @@ public class GridState extends AbstractSingleSelectState { public boolean columnReorderingAllowed; /** - * Explicit row height in pixels for grid rows, or -1 to calculate + * Explicit body row height in pixels for grid rows, or -1 to calculate * automatically based on the theme. * - * @since 8.1 + * @since 8.1.2 */ - public double rowHeight = -1; + public double bodyRowHeight = -1; + /** + * Explicit body row height in pixels for grid rows, or -1 to calculate + * automatically based on the theme. + * + * @since 8.1.2 + */ + public double headerRowHeight = -1; + + /** + * Explicit body row height in pixels for grid rows, or -1 to calculate + * automatically based on the theme. + * + * @since 8.1.2 + */ + public double footerRowHeight = -1; } diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java b/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java index c5b6dbd490..21eb8b502a 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java @@ -539,6 +539,10 @@ public class GridBasics extends AbstractTestUIWithLog { rowMenu.addItem("Deselect all", menuItem -> { grid.getSelectionModel().deselectAll(); }); + + MenuItem rowHeight = rowMenu.addItem("Body Row Height", null); + Stream.of(-1, 20, 50, 100).forEach(i -> rowHeight.addItem("" + i, + menuItem -> grid.setBodyRowHeight(i))); } private void createSelectionMenu(MenuItem stateItem) { @@ -640,6 +644,10 @@ public class GridBasics extends AbstractTestUIWithLog { headerMenu.addItem("Merge Header Cells [0,6..7]", menuItem -> { mergeHeaderСells(0, "6+7", 6, 7); }); + + MenuItem rowHeight = headerMenu.addItem("Header Row Height", null); + Stream.of(-1, 20, 50, 100).forEach(i -> rowHeight.addItem("" + i, + menuItem -> grid.setHeaderRowHeight(i))); } private void mergeHeaderСells(int rowIndex, String jointCellText, @@ -703,6 +711,10 @@ public class GridBasics extends AbstractTestUIWithLog { footerMenu.addItem("Merge Footer Cells [0,6..7]", menuItem -> { mergeFooterСells(0, "6+7", 6, 7); }); + + MenuItem rowHeight = footerMenu.addItem("Footer Row Height", null); + Stream.of(-1, 20, 50, 100).forEach(i -> rowHeight.addItem("" + i, + menuItem -> grid.setFooterRowHeight(i))); } /* DetailsGenerator related things */ diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridRowHeightTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridRowHeightTest.java index 73811bddc7..c99c31d4f7 100644 --- a/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridRowHeightTest.java +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridRowHeightTest.java @@ -5,6 +5,26 @@ import org.junit.Test; public class GridRowHeightTest extends GridBasicsTest { + @Test + public void testSeparateRowHeights() { + selectMenuPath("Component", "Footer", "Add default footer row"); + + int initialHeaderHeight = getHeaderHeight(); + + Assert.assertNotEquals("Header height should not be 50px initially", 50, + initialHeaderHeight); + + selectMenuPath("Component", "Body rows", "Body Row Height", "" + 100); + selectMenuPath("Component", "Header", "Header Row Height", "" + 20); + selectMenuPath("Component", "Footer", "Footer Row Height", "" + 50); + + checkRowHeights(20, 100, 50); + + selectMenuPath("Component", "Header", "Header Row Height", "" + -1); + + checkRowHeights(initialHeaderHeight, 100, 50); + } + @Test public void testRowHeights() { selectMenuPath("Component", "Footer", "Add default footer row"); -- 2.39.5