From 6e30d6b7d6c918a7cf7e9b9367261c8f86b8259b Mon Sep 17 00:00:00 2001 From: Ansku Date: Thu, 17 Aug 2017 09:32:48 +0300 Subject: Resize should work within Grid details row (#9799) Fixes #7341 --- .../vaadin/client/connectors/GridConnector.java | 73 ++++++++++++++++++++-- .../main/java/com/vaadin/client/widgets/Grid.java | 13 ++++ 2 files changed, 82 insertions(+), 4 deletions(-) (limited to 'client/src') diff --git a/client/src/main/java/com/vaadin/client/connectors/GridConnector.java b/client/src/main/java/com/vaadin/client/connectors/GridConnector.java index 05f488a027..9cbafdbe21 100644 --- a/client/src/main/java/com/vaadin/client/connectors/GridConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/GridConnector.java @@ -52,6 +52,8 @@ import com.vaadin.client.ui.AbstractComponentConnector; import com.vaadin.client.ui.AbstractHasComponentsConnector; import com.vaadin.client.ui.ConnectorFocusAndBlurHandler; import com.vaadin.client.ui.SimpleManagedLayout; +import com.vaadin.client.ui.layout.ElementResizeEvent; +import com.vaadin.client.ui.layout.ElementResizeListener; import com.vaadin.client.widget.escalator.events.RowHeightChangedEvent; import com.vaadin.client.widget.escalator.events.RowHeightChangedHandler; import com.vaadin.client.widget.grid.CellReference; @@ -496,17 +498,67 @@ public class GridConnector extends AbstractHasComponentsConnector private final Map idToDetailsMap = new HashMap(); private final Map idToRowIndex = new HashMap(); + private final Map elementToResizeCommand = new HashMap(); + private final ElementResizeListener detailsRowResizeListener = new ElementResizeListener() { + + @Override + public void onElementResize(ElementResizeEvent e) { + if (elementToResizeCommand.containsKey(e.getElement())) { + Scheduler.get().scheduleFinally( + elementToResizeCommand.get(e.getElement())); + } + } + }; + + /* calculated when the first details row is opened */ + private Double spacerCellBorderHeights = null; @Override public Widget getDetails(int rowIndex) { String id = getId(rowIndex); - if (id == null) { + if (id == null || !hasDetailsOpen(rowIndex)) { return null; } ComponentConnector componentConnector = idToDetailsMap.get(id); idToRowIndex.put(id, rowIndex); - return componentConnector.getWidget(); + Widget widget = componentConnector.getWidget(); + getLayoutManager().addElementResizeListener(widget.getElement(), + detailsRowResizeListener); + elementToResizeCommand.put(widget.getElement(), + createResizeCommand(rowIndex, widget.getElement())); + + return widget; + } + + private ScheduledCommand createResizeCommand(final int rowIndex, + final Element element) { + return new ScheduledCommand() { + + @Override + public void execute() { + // It should not be possible to get here without calculating + // the spacerCellBorderHeights or without having the details + // row open, nor for this command to be triggered while + // layout is running, but it's safer to check anyway. + if (spacerCellBorderHeights != null + && !getLayoutManager().isLayoutRunning() + && hasDetailsOpen(rowIndex)) { + double height = getLayoutManager().getOuterHeightDouble( + element) + spacerCellBorderHeights; + getWidget().setDetailsHeight(rowIndex, height); + } + } + }; + } + + private boolean hasDetailsOpen(int rowIndex) { + JsonObject row = getWidget().getDataSource().getRow(rowIndex); + if (row.hasKey(GridState.JSONKEY_DETAILS_VISIBLE)) { + String id = row.getString(GridState.JSONKEY_DETAILS_VISIBLE); + return id != null && !id.isEmpty(); + } + return false; } @Override @@ -519,8 +571,16 @@ public class GridConnector extends AbstractHasComponentsConnector getLayoutManager().setNeedsMeasureRecursively(componentConnector); getLayoutManager().layoutNow(); - return getLayoutManager().getOuterHeightDouble( - componentConnector.getWidget().getElement()); + Element element = componentConnector.getWidget().getElement(); + if (spacerCellBorderHeights == null) { + // If theme is changed, new details generator is created from + // scratch, so this value doesn't need to be updated elsewhere. + spacerCellBorderHeights = WidgetUtil + .getBorderTopAndBottomThickness( + element.getParentElement()); + } + + return getLayoutManager().getOuterHeightDouble(element); } /** @@ -568,6 +628,11 @@ public class GridConnector extends AbstractHasComponentsConnector } for (String id : removedDetails) { + Element element = idToDetailsMap.get(id).getWidget() + .getElement(); + elementToResizeCommand.remove(element); + getLayoutManager().removeElementResizeListener(element, + detailsRowResizeListener); idToDetailsMap.remove(id); idToRowIndex.remove(id); } 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 c76ea3e436..21d7d0ae5d 100755 --- a/client/src/main/java/com/vaadin/client/widgets/Grid.java +++ b/client/src/main/java/com/vaadin/client/widgets/Grid.java @@ -9117,6 +9117,19 @@ public class Grid extends ResizeComposite implements HasSelectionHandlers, return visibleDetails.contains(Integer.valueOf(rowIndex)); } + /** + * Update details row height. + * + * @since + * @param rowIndex + * the index of the row for which to update details height + * @param height + * new height of the details row + */ + public void setDetailsHeight(int rowIndex, double height) { + escalator.getBody().setSpacer(rowIndex, height); + } + /** * Requests that the column widths should be recalculated. *

-- cgit v1.2.3