]> source.dussan.org Git - vaadin-framework.git/commitdiff
Provide API for setting row heights in Grid for different sections (#9810)
authorTeemu Suo-Anttila <tsuoanttila@users.noreply.github.com>
Fri, 11 Aug 2017 12:27:27 +0000 (15:27 +0300)
committerHenri Sara <henri.sara@gmail.com>
Fri, 11 Aug 2017 12:27:27 +0000 (15:27 +0300)
Fixes #9425

all/src/main/templates/release-notes.html
client/src/main/java/com/vaadin/client/connectors/grid/GridConnector.java
server/src/main/java/com/vaadin/ui/Grid.java
shared/src/main/java/com/vaadin/shared/ui/grid/GridState.java
uitest/src/main/java/com/vaadin/tests/components/grid/basics/GridBasics.java
uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridRowHeightTest.java

index afc82cc67d5eb92ee65f6aebf186fee6788732ae..4aba9969f003d22096acde6b08ee8a9cb0d6c32d 100644 (file)
         <li><tt>TreeGrid.createColumn()</tt> has an additional parameter.</li>
         <li><tt>LocalDateTimeToDateConverter</tt> now uses <tt>ZoneId</tt> instead of <tt>ZoneOffset</tt>.</li>
         <li><tt>FontAwesome</tt> icon alignment in <tt>ComboBox</tt> has changed in the theme.</li>
+        <li><tt>GridState</tt> variable <tt>rowHeight</tt> has replaced by three variables.</li>
 
         <h2>For incompatible or behaviour-altering changes in 8.0, please see <a href="https://vaadin.com/download/release/8.0/8.0.0/release-notes.html#incompatible">8.0 release notes</a></h2>
         
index 61c0957d03d91b7e0725a12d245c60829953929a..41602fbcef6137f0cdf2dce3358fad6490089f37 100644 (file)
@@ -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<ComponentConnector> 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);
         }
     }
 
index 70e947ccd86d5334980f8c6310cb140b1f8b0cfb..1aca35d3ecd9f3742db9e1ccce97dcfe5510e1ca 100644 (file)
@@ -3012,27 +3012,113 @@ public class Grid<T> extends AbstractListing<T> 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.
      * <p>
      * 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;
     }
 
     /**
index 77744a9bb0c35eb5972ecd07ec2066043efd7f27..f2ebd903b27cb0d0ba6a5a18e8d2fffe14bae335 100644 (file)
@@ -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;
 }
index c5b6dbd490ad537ebdf22b5ce5fc44b0b3fb5d3a..21eb8b502ad9826a43f56a017cbf74c0f8e4a7ac 100644 (file)
@@ -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 */
index 73811bddc76c09f6d694720b6f8e45358e3c4788..c99c31d4f744ce07a3a1b7961ae5a7b4c72e80a5 100644 (file)
@@ -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");