From 35d4a8fd0ec558b3a2a20bc6ffd0f1048ffc4c4d Mon Sep 17 00:00:00 2001 From: Henrik Paul Date: Thu, 2 Apr 2015 11:14:04 +0300 Subject: Escalator tries to hide out-of-sight spacers from the user (#17353) Change-Id: I807896e3cdd07f4a43a265ba720435f01778f7e1 --- .../src/com/vaadin/client/widgets/Escalator.java | 54 ++++++++++++++++++++-- 1 file changed, 50 insertions(+), 4 deletions(-) (limited to 'client/src') diff --git a/client/src/com/vaadin/client/widgets/Escalator.java b/client/src/com/vaadin/client/widgets/Escalator.java index fe8ba4f67e..01567143dd 100644 --- a/client/src/com/vaadin/client/widgets/Escalator.java +++ b/client/src/com/vaadin/client/widgets/Escalator.java @@ -3720,19 +3720,32 @@ public class Escalator extends Widget implements RequiresResize, List orderedBodyRows = new ArrayList( visualRowOrder); - for (int i = 0; i < visualRowOrder.size(); i++) { - SpacerContainer.SpacerImpl spacer = body.spacerContainer - .getSpacer(getTopRowLogicalIndex() + i); + Map spacers = body.spacerContainer + .getSpacers(); + + /* + * Start at -1 to include a spacer that is rendered above the + * viewport, but its parent row is still not shown + */ + for (int i = -1; i < visualRowOrder.size(); i++) { + SpacerContainer.SpacerImpl spacer = spacers.remove(Integer + .valueOf(getTopRowLogicalIndex() + i)); if (spacer != null) { orderedBodyRows.add(i + 1, spacer.getRootElement()); + spacer.show(); } } /* * At this point, invisible spacers aren't reordered, so their - * position in the DOM is undefined. + * position in the DOM will remain undefined. */ + // If a spacer was not reordered, it means that it's out of view. + for (SpacerContainer.SpacerImpl unmovedSpacer : spacers.values()) { + unmovedSpacer.hide(); + } + /* * If we have a focused row, start in the mode where we put * everything underneath that row. Otherwise, all rows are placed as @@ -4755,6 +4768,33 @@ public class Escalator extends Widget implements RequiresResize, root.setPropertyInt(SPACER_LOGICAL_ROW_PROPERTY, rowIndex); rowIndexToSpacer.put(this.rowIndex, this); } + + /** + * Updates the spacer's visibility parameters, based on whether it + * is being currently visible or not. + */ + public void updateVisibility() { + if (isInViewport()) { + show(); + } else { + hide(); + } + } + + private boolean isInViewport() { + int top = (int) Math.ceil(getTop()); + int height = (int) Math.floor(getHeight()); + Range location = Range.withLength(top, height); + return getViewportPixels().intersects(location); + } + + public void show() { + getRootElement().getStyle().clearDisplay(); + } + + public void hide() { + getRootElement().getStyle().setDisplay(Display.NONE); + } } private final TreeMap rowIndexToSpacer = new TreeMap(); @@ -4887,6 +4927,10 @@ public class Escalator extends Widget implements RequiresResize, } } + public Map getSpacers() { + return new HashMap(rowIndexToSpacer); + } + /** * Calculates the sum of all spacers. * @@ -5239,6 +5283,8 @@ public class Escalator extends Widget implements RequiresResize, spacerUpdater.init(spacer); assert getElement().isOrHasChild(spacer.getRootElement()) : "Spacer's root element somehow got detached from Escalator during attaching"; assert getElement().isOrHasChild(spacer.getElement()) : "Spacer element somehow got detached from Escalator during attaching"; + + spacer.updateVisibility(); } public String getSubPartName(Element subElement) { -- cgit v1.2.3