diff --git a/client/src/main/java/com/vaadin/client/widgets/Escalator.java b/client/src/main/java/com/vaadin/client/widgets/Escalator.java index 34cdb70b2b3..8f79483eb81 100644 --- a/client/src/main/java/com/vaadin/client/widgets/Escalator.java +++ b/client/src/main/java/com/vaadin/client/widgets/Escalator.java @@ -2970,7 +2970,7 @@ public void moveViewportAndContent(final double yDelta) { private List fillAndPopulateEscalatorRowsIfNeeded( final int index, final int numberOfRows) { - final int escalatorRowsStillFit = getMaxEscalatorRowCapacity() + final int escalatorRowsStillFit = getMaxVisibleRowCount() - getDomRowCount(); final int escalatorRowsNeeded = Math.min(numberOfRows, escalatorRowsStillFit); @@ -3003,16 +3003,22 @@ private List fillAndPopulateEscalatorRowsIfNeeded( } } - private int getMaxEscalatorRowCapacity() { - final int maxEscalatorRowCapacity = (int) Math - .ceil(getHeightOfSection() / getDefaultRowHeight()) + 1; + private int getMaxVisibleRowCount() { + double heightOfSection = getHeightOfSection(); + // By including the possibly shown scrollbar height, we get a + // consistent count and do not add/remove rows whenever a scrollbar + // is shown + heightOfSection += horizontalScrollbarDeco.getOffsetHeight(); + double defaultRowHeight = getDefaultRowHeight(); + final int maxVisibleRowCount = (int) Math + .ceil(heightOfSection / defaultRowHeight) + 1; /* - * maxEscalatorRowCapacity can become negative if the headers and - * footers start to overlap. This is a crazy situation, but Vaadin - * blinks the components a lot, so it's feasible. + * maxVisibleRowCount can become negative if the headers and footers + * start to overlap. This is a crazy situation, but Vaadin blinks + * the components a lot, so it's feasible. */ - return Math.max(0, maxEscalatorRowCapacity); + return Math.max(0, maxVisibleRowCount); } @Override @@ -3489,12 +3495,12 @@ private Range convertToVisual(final Range logicalRange) { * TODO [[spacer]]: these assumptions will be totally broken with * spacers. */ - final int maxEscalatorRows = getMaxEscalatorRowCapacity(); + final int maxVisibleRowCount = getMaxVisibleRowCount(); final int currentTopRowIndex = getLogicalRowIndex( visualRowOrder.getFirst()); final Range[] partitions = logicalRange.partitionWith( - Range.withLength(currentTopRowIndex, maxEscalatorRows)); + Range.withLength(currentTopRowIndex, maxVisibleRowCount)); final Range insideRange = partitions[1]; return insideRange.offsetBy(-currentTopRowIndex); } @@ -3606,8 +3612,8 @@ public void verifyEscalatorCount() { return; } - final int maxEscalatorRows = getMaxEscalatorRowCapacity(); - final int neededEscalatorRows = Math.min(maxEscalatorRows, + final int maxVisibleRowCount = getMaxVisibleRowCount(); + final int neededEscalatorRows = Math.min(maxVisibleRowCount, body.getRowCount()); final int neededEscalatorRowsDiff = neededEscalatorRows - visualRowOrder.size(); @@ -6646,7 +6652,7 @@ public void onResize() { * @return the maximum capacity */ public int getMaxVisibleRowCount() { - return body.getMaxEscalatorRowCapacity(); + return body.getMaxVisibleRowCount(); } /** diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java index 04fcdbe766b..f022d691b7f 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Escalator.java @@ -2982,7 +2982,7 @@ public void moveViewportAndContent(final double yDelta) { private List fillAndPopulateEscalatorRowsIfNeeded( final int index, final int numberOfRows) { - final int escalatorRowsStillFit = getMaxEscalatorRowCapacity() + final int escalatorRowsStillFit = getMaxVisibleRowCount() - getDomRowCount(); final int escalatorRowsNeeded = Math.min(numberOfRows, escalatorRowsStillFit); @@ -3015,16 +3015,22 @@ private List fillAndPopulateEscalatorRowsIfNeeded( } } - private int getMaxEscalatorRowCapacity() { - final int maxEscalatorRowCapacity = (int) Math - .ceil(getHeightOfSection() / getDefaultRowHeight()) + 1; + private int getMaxVisibleRowCount() { + double heightOfSection = getHeightOfSection(); + // By including the possibly shown scrollbar height, we get a + // consistent count and do not add/remove rows whenever a scrollbar + // is shown + heightOfSection += horizontalScrollbarDeco.getOffsetHeight(); + double defaultRowHeight = getDefaultRowHeight(); + final int maxVisibleRowCount = (int) Math + .ceil(heightOfSection / defaultRowHeight) + 1; /* - * maxEscalatorRowCapacity can become negative if the headers and - * footers start to overlap. This is a crazy situation, but Vaadin - * blinks the components a lot, so it's feasible. + * maxVisibleRowCount can become negative if the headers and footers + * start to overlap. This is a crazy situation, but Vaadin blinks + * the components a lot, so it's feasible. */ - return Math.max(0, maxEscalatorRowCapacity); + return Math.max(0, maxVisibleRowCount); } @Override @@ -3507,12 +3513,12 @@ private Range convertToVisual(final Range logicalRange) { * TODO [[spacer]]: these assumptions will be totally broken with * spacers. */ - final int maxEscalatorRows = getMaxEscalatorRowCapacity(); + final int maxVisibleRowCount = getMaxVisibleRowCount(); final int currentTopRowIndex = getLogicalRowIndex( visualRowOrder.getFirst()); final Range[] partitions = logicalRange.partitionWith( - Range.withLength(currentTopRowIndex, maxEscalatorRows)); + Range.withLength(currentTopRowIndex, maxVisibleRowCount)); final Range insideRange = partitions[1]; return insideRange.offsetBy(-currentTopRowIndex); } @@ -3624,8 +3630,8 @@ public void verifyEscalatorCount() { return; } - final int maxEscalatorRows = getMaxEscalatorRowCapacity(); - final int neededEscalatorRows = Math.min(maxEscalatorRows, + final int maxVisibleRowCount = getMaxVisibleRowCount(); + final int neededEscalatorRows = Math.min(maxVisibleRowCount, body.getRowCount()); final int neededEscalatorRowsDiff = neededEscalatorRows - visualRowOrder.size(); @@ -6673,7 +6679,7 @@ public void onResize() { * @return the maximum capacity */ public int getMaxVisibleRowCount() { - return body.getMaxEscalatorRowCapacity(); + return body.getMaxVisibleRowCount(); } /** diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/grid/HideGridColumnWhenHavingUnsuitableHeight.java b/uitest/src/main/java/com/vaadin/v7/tests/components/grid/HideGridColumnWhenHavingUnsuitableHeight.java new file mode 100644 index 00000000000..d5e6c410639 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/grid/HideGridColumnWhenHavingUnsuitableHeight.java @@ -0,0 +1,92 @@ +package com.vaadin.v7.tests.components.grid; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.v7.data.Item; +import com.vaadin.v7.data.util.BeanItemContainer; +import com.vaadin.v7.data.util.GeneratedPropertyContainer; +import com.vaadin.v7.data.util.PropertyValueGenerator; +import com.vaadin.v7.ui.Grid; +import com.vaadin.v7.ui.Grid.Column; +import com.vaadin.v7.ui.renderers.ButtonRenderer; + +@Theme("valo") +public class HideGridColumnWhenHavingUnsuitableHeight extends AbstractTestUI { + + private Grid grid; + + public static class SampleBean { + + private String col1; + private String col2; + + public SampleBean() { + } + + public String getCol1() { + return col1; + } + + public void setCol1(String col1) { + this.col1 = col1; + } + + public String getCol2() { + return col2; + } + + public void setCol2(String col2) { + this.col2 = col2; + } + } + + @SuppressWarnings("serial") + @Override + protected void setup(VaadinRequest vaadinRequest) { + grid = new Grid(); + + BeanItemContainer container = generateData(50); + GeneratedPropertyContainer gpc = new GeneratedPropertyContainer( + container); + grid.setContainerDataSource(gpc); + + gpc.addGeneratedProperty("Button1", + new PropertyValueGenerator() { + @Override + public String getValue(Item item, Object itemId, + Object propertyId) { + return "Button 1"; + } + + @Override + public Class getType() { + return String.class; + } + }); + grid.getColumn("Button1").setRenderer(new ButtonRenderer()); + grid.getColumn("col1").setWidth(1600); + for (Column gridCol : grid.getColumns()) { + gridCol.setHidable(true); + } + grid.setWidth("100%"); + grid.setHeight("425px"); + + grid.setColumns("col1", "col2", "Button1"); + + addComponent(grid); + } + + private BeanItemContainer generateData(int rows) { + BeanItemContainer container = new BeanItemContainer( + SampleBean.class); + for (int y = 0; y < rows; ++y) { + SampleBean sampleBean = new SampleBean(); + sampleBean.setCol1("Row " + y + " Column 1"); + sampleBean.setCol2("Row " + y + " Column 2"); + container.addBean(sampleBean); + } + return container; + } + +} diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorSpacerTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorSpacerTest.java index 12f55b88644..f3c97cfeea8 100644 --- a/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorSpacerTest.java +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorSpacerTest.java @@ -290,12 +290,12 @@ public void scrollToRowWorksProperlyWithSpacers() throws Exception { selectMenuPath(FEATURES, SPACERS, ROW_1, SET_100PX); /* - * we check for row -2 instead of -1, because escalator has the one row + * we check for row -3 instead of -1, because escalator has two rows * buffered underneath the footer */ selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, SCROLL_TO, ROW_75); Thread.sleep(500); - assertEquals("Row 75: 0,75", getBodyCell(-2, 0).getText()); + assertEquals("Row 75: 0,75", getBodyCell(-3, 0).getText()); selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, SCROLL_TO, ROW_25); Thread.sleep(500); diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridScrollTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridScrollTest.java new file mode 100644 index 00000000000..9bb35bc3113 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/basics/GridScrollTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2014 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.basics; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; + +public class GridScrollTest extends GridBasicsTest { + + @Test + public void workPendingWhileScrolling() { + openTestURL("theme=valo"); + String script = "var c = window.vaadin.clients.runcomvaadintestscomponentsgridbasicsGridBasics;\n" + // Scroll down and cause lazy loading + + "c.getElementByPath(\"//Grid[0]#cell[21]\"); \n" + + "return c.isActive();"; + + Boolean active = (Boolean) executeScript(script); + assertTrue("Grid should be marked to have workPending while scrolling", + active); + } + + @Test + public void scrollIntoViewThroughSubPart() { + openTestURL("theme=valo"); + GridElement grid = $(GridElement.class).first(); + assertEquals("(10, 0)", grid.getCell(10, 0).getText()); + } +} diff --git a/uitest/src/test/java/com/vaadin/v7/tests/components/grid/HideGridColumnWhenHavingUnsuitableHeightTest.java b/uitest/src/test/java/com/vaadin/v7/tests/components/grid/HideGridColumnWhenHavingUnsuitableHeightTest.java new file mode 100644 index 00000000000..30189860907 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/v7/tests/components/grid/HideGridColumnWhenHavingUnsuitableHeightTest.java @@ -0,0 +1,40 @@ +package com.vaadin.v7.tests.components.grid; + +import java.util.List; +import java.util.logging.Level; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class HideGridColumnWhenHavingUnsuitableHeightTest + extends SingleBrowserTest { + + @Test + public void hideAndScroll() { + openTestURL("debug"); + GridElement grid = $(GridElement.class).first(); + + getSidebarOpenButton(grid).click(); + // Hide first column + getSidebarPopup().findElements(By.tagName("td")).get(0).click(); + + grid.scrollToRow(25); + assertNoDebugMessage(Level.SEVERE); + } + + protected WebElement getSidebarOpenButton(GridElement grid) { + List elements = grid + .findElements(By.className("v-grid-sidebar-button")); + return elements.isEmpty() ? null : elements.get(0); + } + + protected WebElement getSidebarPopup() { + List elements = findElements( + By.className("v-grid-sidebar-popup")); + return elements.isEmpty() ? null : elements.get(0); + } +}