From 3e5c5bc10752ae011ee74c82530452ba26521833 Mon Sep 17 00:00:00 2001 From: Dmitrii Rogozin Date: Thu, 22 May 2014 14:04:48 +0300 Subject: [PATCH] Removes double spacing from gridLayout which has empty rows or columns (#8855) If row has no elements or only invisible elements, its size will be set to zero. When row expand ratio was set, its size will be assigned to the value according to an expand ratio. If component takes several rows of the gridLayout, these rows are considered as non-empty and won't be removed. Change-Id: I10ddd22a6c9535b9978769bab7b496e11a28b78a --- .../src/com/vaadin/client/ui/VGridLayout.java | 199 ++++++++++++++---- .../ui/gridlayout/GridLayoutConnector.java | 11 +- server/src/com/vaadin/ui/GridLayout.java | 141 +++++++------ .../shared/ui/gridlayout/GridLayoutState.java | 12 +- .../gridlayout/GridLayoutExpandRatio.java | 108 ++++++++++ .../gridlayout/GridLayoutExpandRatioTest.java | 53 +++++ .../gridlayout/GridLayoutHideMiddleCells.java | 146 +++++++++++++ .../GridLayoutHideMiddleCellsTest.java | 57 +++++ 8 files changed, 602 insertions(+), 125 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatio.java create mode 100644 uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatioTest.java create mode 100644 uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCells.java create mode 100644 uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCellsTest.java diff --git a/client/src/com/vaadin/client/ui/VGridLayout.java b/client/src/com/vaadin/client/ui/VGridLayout.java index 1c42243621..10e5c00a38 100644 --- a/client/src/com/vaadin/client/ui/VGridLayout.java +++ b/client/src/com/vaadin/client/ui/VGridLayout.java @@ -1,12 +1,12 @@ /* * 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 @@ -19,6 +19,7 @@ package com.vaadin.client.ui; import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Set; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Document; @@ -71,6 +72,8 @@ public class VGridLayout extends ComplexPanel { /** For internal use only. May be removed or replaced in the future. */ public DivElement spacingMeasureElement; + public Set explicitRowRatios; + public Set explicitColRatios; public VGridLayout() { super(); @@ -92,7 +95,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the column widths measured in pixels - * + * * @return */ protected int[] getColumnWidths() { @@ -101,7 +104,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the row heights measured in pixels - * + * * @return */ protected int[] getRowHeights() { @@ -110,7 +113,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the spacing between the cells horizontally in pixels - * + * * @return */ protected int getHorizontalSpacing() { @@ -119,7 +122,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the spacing between the cells vertically in pixels - * + * * @return */ protected int getVerticalSpacing() { @@ -136,18 +139,20 @@ public class VGridLayout extends ComplexPanel { void expandRows() { if (!isUndefinedHeight()) { - int usedSpace = minRowHeights[0]; - int verticalSpacing = getVerticalSpacing(); - for (int i = 1; i < minRowHeights.length; i++) { - usedSpace += verticalSpacing + minRowHeights[i]; - } + int usedSpace = calcRowUsedSpace(); + int[] actualExpandRatio = calcRowExpandRatio(); int availableSpace = LayoutManager.get(client).getInnerHeight( getElement()); int excessSpace = availableSpace - usedSpace; int distributed = 0; if (excessSpace > 0) { + int expandRatioSum = 0; + for (int i = 0; i < rowHeights.length; i++) { + expandRatioSum += actualExpandRatio[i]; + } for (int i = 0; i < rowHeights.length; i++) { - int ew = excessSpace * rowExpandRatioArray[i] / 1000; + int ew = excessSpace * actualExpandRatio[i] + / expandRatioSum; rowHeights[i] = minRowHeights[i] + ew; distributed += ew; } @@ -162,44 +167,52 @@ public class VGridLayout extends ComplexPanel { } } - /** For internal use only. May be removed or replaced in the future. */ - public void updateHeight() { - // Detect minimum heights & calculate spans - detectRowHeights(); - - // Expand - expandRows(); - - // Position - layoutCellsVertically(); + private int[] calcRowExpandRatio() { + int[] actualExpandRatio = new int[minRowHeights.length]; + for (int i = 0; i < minRowHeights.length; i++) { + if (rowHasComponentsOrRowSpan(i)) { + actualExpandRatio[i] = rowExpandRatioArray[i]; + } else { + // Should not do this if this has explicitly been + // expanded + if (explicitRowRatios.contains(i)) { + actualExpandRatio[i] = rowExpandRatioArray[i]; + } else { + actualExpandRatio[i] = 0; + } + } + } + return actualExpandRatio; } - /** For internal use only. May be removed or replaced in the future. */ - public void updateWidth() { - // Detect widths & calculate spans - detectColWidths(); - // Expand - expandColumns(); - // Position - layoutCellsHorizontally(); - + private int calcRowUsedSpace() { + int usedSpace = minRowHeights[0]; + int verticalSpacing = getVerticalSpacing(); + for (int i = 1; i < minRowHeights.length; i++) { + if (rowHasComponentsOrRowSpan(i) || minRowHeights[i] > 0 + || explicitRowRatios.contains(i)) { + usedSpace += verticalSpacing + minRowHeights[i]; + } + } + return usedSpace; } void expandColumns() { if (!isUndefinedWidth()) { - int usedSpace = minColumnWidths[0]; - int horizontalSpacing = getHorizontalSpacing(); - for (int i = 1; i < minColumnWidths.length; i++) { - usedSpace += horizontalSpacing + minColumnWidths[i]; - } - + int usedSpace = calcColumnUsedSpace(); + int[] actualExpandRatio = calcColumnExpandRatio(); int availableSpace = LayoutManager.get(client).getInnerWidth( getElement()); int excessSpace = availableSpace - usedSpace; int distributed = 0; if (excessSpace > 0) { + int expandRatioSum = 0; + for (int i = 0; i < columnWidths.length; i++) { + expandRatioSum += actualExpandRatio[i]; + } for (int i = 0; i < columnWidths.length; i++) { - int ew = excessSpace * colExpandRatioArray[i] / 1000; + int ew = excessSpace * actualExpandRatio[i] + / expandRatioSum; columnWidths[i] = minColumnWidths[i] + ew; distributed += ew; } @@ -214,6 +227,97 @@ public class VGridLayout extends ComplexPanel { } } + /** + * Calculates column expand ratio. + */ + private int[] calcColumnExpandRatio() { + int[] actualExpandRatio = new int[minColumnWidths.length]; + for (int i = 0; i < minColumnWidths.length; i++) { + if (colHasComponentsOrColSpan(i)) { + actualExpandRatio[i] = colExpandRatioArray[i]; + } else { + // Should not do this if this has explicitly been + // expanded + if (explicitColRatios.contains(i)) { + actualExpandRatio[i] = colExpandRatioArray[i]; + } else { + actualExpandRatio[i] = 0; + } + } + } + return actualExpandRatio; + } + + /** + * Calculates column used space + */ + private int calcColumnUsedSpace() { + int usedSpace = minColumnWidths[0]; + int horizontalSpacing = getHorizontalSpacing(); + for (int i = 1; i < minColumnWidths.length; i++) { + if (colHasComponentsOrColSpan(i) || minColumnWidths[i] > 0 + || explicitColRatios.contains(i)) { + usedSpace += horizontalSpacing + minColumnWidths[i]; + } + } + return usedSpace; + } + + private boolean rowHasComponentsOrRowSpan(int i) { + for (Cell cell : widgetToCell.values()) { + if (cell.row == i) { + return true; + } + } + for (SpanList l : rowSpans) { + for (Cell cell : l.cells) { + if (cell.row >= i && i < cell.row + cell.rowspan) { + return true; + } + } + } + return false; + } + + private boolean colHasComponentsOrColSpan(int i) { + for (Cell cell : widgetToCell.values()) { + if (cell.col == i) { + return true; + } + } + for (SpanList l : colSpans) { + for (Cell cell : l.cells) { + if (cell.col >= i && i < cell.col + cell.colspan) { + return true; + } + } + } + return false; + } + + /** For internal use only. May be removed or replaced in the future. */ + public void updateHeight() { + // Detect minimum heights & calculate spans + detectRowHeights(); + + // Expand + expandRows(); + + // Position + layoutCellsVertically(); + } + + /** For internal use only. May be removed or replaced in the future. */ + public void updateWidth() { + // Detect widths & calculate spans + detectColWidths(); + // Expand + expandColumns(); + // Position + layoutCellsHorizontally(); + + } + void layoutCellsVertically() { int verticalSpacing = getVerticalSpacing(); LayoutManager layoutManager = LayoutManager.get(client); @@ -241,7 +345,9 @@ public class VGridLayout extends ComplexPanel { cell.layoutVertically(y, reservedMargin); } - y += rowHeights[row] + verticalSpacing; + if (rowHasComponentsOrRowSpan(row) || rowHeights[row] > 0) { + y += rowHeights[row] + verticalSpacing; + } } } @@ -277,7 +383,9 @@ public class VGridLayout extends ComplexPanel { cell.layoutHorizontally(x, reservedMargin); } } - x += columnWidths[i] + horizontalSpacing; + if (colHasComponentsOrColSpan(i) || columnWidths[i] > 0) { + x += columnWidths[i] + horizontalSpacing; + } } if (isUndefinedWidth()) { @@ -602,7 +710,6 @@ public class VGridLayout extends ComplexPanel { - childComponentData.column1; // Set cell height rowspan = 1 + childComponentData.row2 - childComponentData.row1; - setAlignment(new AlignmentInfo(childComponentData.alignment)); } @@ -644,7 +751,7 @@ public class VGridLayout extends ComplexPanel { * Creates a new Cell with the given coordinates. *

* For internal use only. May be removed or replaced in the future. - * + * * @param row * @param col * @return @@ -660,7 +767,7 @@ public class VGridLayout extends ComplexPanel { * child component is also returned if "element" is part of its caption. *

* For internal use only. May be removed or replaced in the future. - * + * * @param element * An element that is a nested sub element of the root element in * this layout @@ -681,13 +788,13 @@ public class VGridLayout extends ComplexPanel { * child component is also returned if "element" is part of its caption. *

* For internal use only. May be removed or replaced in the future. - * + * * @param element * An element that is a nested sub element of the root element in * this layout * @return The Paintable which the element is a part of. Null if the element * belongs to the layout and not to a child. - * + * * @since 7.2 */ public ComponentConnector getComponent(Element element) { diff --git a/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java b/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java index 67220e5c36..786bd18bf9 100644 --- a/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java @@ -1,12 +1,12 @@ /* * 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 @@ -119,9 +119,7 @@ public class GridLayoutConnector extends AbstractComponentContainerConnector layout.rowExpandRatioArray = uidl.getIntArrayAttribute("rowExpand"); layout.updateMarginStyleNames(new MarginInfo(getState().marginsBitmask)); - layout.updateSpacingStyleName(getState().spacing); - getLayoutManager().setNeedsLayout(this); } @@ -171,7 +169,8 @@ public class GridLayoutConnector extends AbstractComponentContainerConnector layout.columnWidths = new int[cols]; layout.rowHeights = new int[rows]; - + layout.explicitRowRatios = getState().explicitRowRatios; + layout.explicitColRatios = getState().explicitColRatios; layout.setSize(rows, cols); } diff --git a/server/src/com/vaadin/ui/GridLayout.java b/server/src/com/vaadin/ui/GridLayout.java index 00e50aafc4..989f5efdea 100644 --- a/server/src/com/vaadin/ui/GridLayout.java +++ b/server/src/com/vaadin/ui/GridLayout.java @@ -1,12 +1,12 @@ /* * 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 @@ -39,12 +39,12 @@ import com.vaadin.shared.ui.gridlayout.GridLayoutState.ChildComponentData; /** * A layout where the components are laid out on a grid using cell coordinates. - * + * *

* The GridLayout also maintains a cursor for adding components in * left-to-right, top-to-bottom order. *

- * + * *

* Each component in a GridLayout uses a defined * {@link GridLayout.Area area} (column1,row1,column2,row2) from the grid. The @@ -52,12 +52,12 @@ import com.vaadin.shared.ui.gridlayout.GridLayoutState.ChildComponentData; * you will get an {@link OverlapsException}. Adding a component with cursor * automatically extends the grid by increasing the grid height. *

- * + * *

* The grid coordinates, which are specified by a row and column index, always * start from 0 for the topmost row and the leftmost column. *

- * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -96,10 +96,10 @@ public class GridLayout extends AbstractLayout implements /** * Constructor for a grid of given size (number of columns and rows). - * + * * The grid may grow or shrink later. Grid grows automatically if you add * components outside its area. - * + * * @param columns * Number of columns in the grid. * @param rows @@ -121,9 +121,9 @@ public class GridLayout extends AbstractLayout implements /** * Constructs a GridLayout of given size (number of columns and rows) and * adds the given components in order to the grid. - * + * * @see #addComponents(Component...) - * + * * @param columns * Number of columns in the grid. * @param rows @@ -147,13 +147,13 @@ public class GridLayout extends AbstractLayout implements * by specifying the upper left corner (column1, row1) and the lower right * corner (column2, row2) of the area. The coordinates are zero-based. *

- * + * *

* If the area overlaps with any of the existing components already present * in the grid, the operation will fail and an {@link OverlapsException} is * thrown. *

- * + * * @param component * the component to be added, not null. * @param column1 @@ -257,7 +257,7 @@ public class GridLayout extends AbstractLayout implements /** * Tests if the given area overlaps with any of the items already on the * grid. - * + * * @param area * the Area to be checked for overlapping. * @throws OverlapsException @@ -279,7 +279,7 @@ public class GridLayout extends AbstractLayout implements * the area.) End coordinates (SouthEast corner of the area) are the same as * column1,row1. The coordinates are zero-based. Component width and height * is 1. - * + * * @param component * the component to be added, not null. * @param column @@ -299,16 +299,16 @@ public class GridLayout extends AbstractLayout implements /** * Forces the next component to be added at the beginning of the next line. - * + * *

* Sets the cursor column to 0 and increments the cursor row by one. *

- * + * *

* By calling this function you can ensure that no more components are added * right of the previous component. *

- * + * * @see #space() */ public void newLine() { @@ -319,7 +319,7 @@ public class GridLayout extends AbstractLayout implements /** * Moves the cursor forward by one. If the cursor goes out of the right grid * border, it is moved to the first column of the next row. - * + * * @see #newLine() */ public void space() { @@ -335,7 +335,7 @@ public class GridLayout extends AbstractLayout implements * cursor position is already occupied, the cursor is moved forwards to find * free position. If the cursor goes out from the bottom of the grid, the * grid is automatically extended. - * + * * @param component * the component to be added, not null. */ @@ -371,7 +371,7 @@ public class GridLayout extends AbstractLayout implements /** * Removes the specified component from the layout. - * + * * @param component * the component to be removed. */ @@ -391,7 +391,7 @@ public class GridLayout extends AbstractLayout implements /** * Removes the component specified by its cell coordinates. - * + * * @param column * the component's column, starting from 0. * @param row @@ -414,7 +414,7 @@ public class GridLayout extends AbstractLayout implements /** * Gets an Iterator for the components contained in the layout. By using the * Iterator it is possible to step through the contents of the layout. - * + * * @return the Iterator of the components inside the layout. */ @Override @@ -425,7 +425,7 @@ public class GridLayout extends AbstractLayout implements /** * Gets the number of components contained in the layout. Consistent with * the iterator returned by {@link #getComponentIterator()}. - * + * * @return the number of contained components */ @Override @@ -440,7 +440,7 @@ public class GridLayout extends AbstractLayout implements /** * Paints the contents of this component. - * + * * @param target * the Paint Event. * @throws PaintException @@ -497,7 +497,6 @@ public class GridLayout extends AbstractLayout implements if (columnExpandRatioArray.length > 0) { columnExpandRatioArray[0] -= realColExpandRatioSum - 1000; } - target.addAttribute("colExpand", columnExpandRatioArray); target.addAttribute("rowExpand", rowExpandRatioArray); @@ -532,17 +531,17 @@ public class GridLayout extends AbstractLayout implements /** * Defines a rectangular area of cells in a GridLayout. - * + * *

* Also maintains a reference to the component contained in the area. *

- * + * *

* The area is specified by the cell coordinates of its upper left corner * (column1,row1) and lower right corner (column2,row2). As otherwise with * GridLayout, the column and row coordinates start from zero. *

- * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -554,7 +553,7 @@ public class GridLayout extends AbstractLayout implements *

* Construct a new area on a grid. *

- * + * * @param component * the component connected to the area. * @param column1 @@ -588,7 +587,7 @@ public class GridLayout extends AbstractLayout implements /** * Tests if this Area overlaps with another Area. - * + * * @param other * the other Area that is to be tested for overlap with this * area @@ -601,7 +600,7 @@ public class GridLayout extends AbstractLayout implements /** * Gets the component connected to the area. - * + * * @return the Component. */ public Component getComponent() { @@ -610,7 +609,7 @@ public class GridLayout extends AbstractLayout implements /** * Gets the column of the top-left corner cell. - * + * * @return the column of the top-left corner cell. */ public int getColumn1() { @@ -619,7 +618,7 @@ public class GridLayout extends AbstractLayout implements /** * Gets the column of the bottom-right corner cell. - * + * * @return the column of the bottom-right corner cell. */ public int getColumn2() { @@ -628,7 +627,7 @@ public class GridLayout extends AbstractLayout implements /** * Gets the row of the top-left corner cell. - * + * * @return the row of the top-left corner cell. */ public int getRow1() { @@ -637,7 +636,7 @@ public class GridLayout extends AbstractLayout implements /** * Gets the row of the bottom-right corner cell. - * + * * @return the row of the bottom-right corner cell. */ public int getRow2() { @@ -656,7 +655,7 @@ public class GridLayout extends AbstractLayout implements * Gridlayout does not support laying components on top of each other. An * OverlapsException is thrown when a component already exists * (even partly) at the same space on a grid with the new component. - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -666,7 +665,7 @@ public class GridLayout extends AbstractLayout implements /** * Constructs an OverlapsException. - * + * * @param existingArea */ public OverlapsException(Area existingArea) { @@ -701,7 +700,7 @@ public class GridLayout extends AbstractLayout implements /** * Gets the area . - * + * * @return the existing area. */ public Area getArea() { @@ -712,7 +711,7 @@ public class GridLayout extends AbstractLayout implements /** * An Exception object which is thrown when an area exceeds the * bounds of the grid. - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -723,7 +722,7 @@ public class GridLayout extends AbstractLayout implements /** * Constructs an OoutOfBoundsException with the specified * detail message. - * + * * @param areaOutOfBounds */ public OutOfBoundsException(Area areaOutOfBounds) { @@ -732,7 +731,7 @@ public class GridLayout extends AbstractLayout implements /** * Gets the area that is out of bounds. - * + * * @return the area out of Bound. */ public Area getArea() { @@ -743,7 +742,7 @@ public class GridLayout extends AbstractLayout implements /** * Sets the number of columns in the grid. The column count can not be * reduced if there are any areas that would be outside of the shrunk grid. - * + * * @param columns * the new number of columns in the grid. */ @@ -777,7 +776,7 @@ public class GridLayout extends AbstractLayout implements /** * Get the number of columns in the grid. - * + * * @return the number of columns in the grid. */ public int getColumns() { @@ -787,7 +786,7 @@ public class GridLayout extends AbstractLayout implements /** * Sets the number of rows in the grid. The number of rows can not be * reduced if there are any areas that would be outside of the shrunk grid. - * + * * @param rows * the new number of rows in the grid. */ @@ -821,7 +820,7 @@ public class GridLayout extends AbstractLayout implements /** * Get the number of rows in the grid. - * + * * @return the number of rows in the grid. */ public int getRows() { @@ -830,14 +829,14 @@ public class GridLayout extends AbstractLayout implements /** * Gets the current x-position (column) of the cursor. - * + * *

* The cursor position points the position for the next component that is * added without specifying its coordinates (grid cell). When the cursor * position is occupied, the next component will be added to first free * position after the cursor. *

- * + * * @return the grid column the cursor is on, starting from 0. */ public int getCursorX() { @@ -847,7 +846,7 @@ public class GridLayout extends AbstractLayout implements /** * Sets the current cursor x-position. This is usually handled automatically * by GridLayout. - * + * * @param cursorX */ public void setCursorX(int cursorX) { @@ -856,14 +855,14 @@ public class GridLayout extends AbstractLayout implements /** * Gets the current y-position (row) of the cursor. - * + * *

* The cursor position points the position for the next component that is * added without specifying its coordinates (grid cell). When the cursor * position is occupied, the next component will be added to the first free * position after the cursor. *

- * + * * @return the grid row the Cursor is on. */ public int getCursorY() { @@ -873,7 +872,7 @@ public class GridLayout extends AbstractLayout implements /** * Sets the current y-coordinate (row) of the cursor. This is usually * handled automatically by GridLayout. - * + * * @param cursorY * the row number, starting from 0 for the topmost row. */ @@ -957,7 +956,7 @@ public class GridLayout extends AbstractLayout implements /** * Inserts an empty row at the specified position in the grid. - * + * * @param row * Index of the row before which the new row will be inserted. * The leftmost row has index 0. @@ -991,18 +990,18 @@ public class GridLayout extends AbstractLayout implements /** * Removes a row and all the components in the row. - * + * *

* Components which span over several rows are removed if the selected row * is on the first row of such a component. *

- * + * *

* If the last row is removed then all remaining components will be removed * and the grid will be reduced to one row. The cursor will be moved to the * upper left cell of the grid. *

- * + * * @param row * Index of the row to remove. The leftmost row has index 0. */ @@ -1049,33 +1048,34 @@ public class GridLayout extends AbstractLayout implements /** * Sets the expand ratio of given column. - * + * *

* The expand ratio defines how excess space is distributed among columns. * Excess space means space that is left over from components that are not * sized relatively. By default, the excess space is distributed evenly. *

- * + * *

* Note that the component width of the GridLayout must be defined (fixed or * relative, as opposed to undefined) for this method to have any effect. *

- * + * * @see #setWidth(float, int) - * + * * @param columnIndex * @param ratio */ public void setColumnExpandRatio(int columnIndex, float ratio) { columnExpandRatio.put(columnIndex, ratio); + getState().explicitColRatios.add(columnIndex); markAsDirty(); } /** * Returns the expand ratio of given column - * + * * @see #setColumnExpandRatio(int, float) - * + * * @param columnIndex * @return the expand ratio, 0.0f by default */ @@ -1086,34 +1086,35 @@ public class GridLayout extends AbstractLayout implements /** * Sets the expand ratio of given row. - * + * *

* Expand ratio defines how excess space is distributed among rows. Excess * space means the space left over from components that are not sized * relatively. By default, the excess space is distributed evenly. *

- * + * *

* Note, that height needs to be defined (fixed or relative, as opposed to * undefined height) for this method to have any effect. *

- * + * * @see #setHeight(float, int) - * + * * @param rowIndex * The row index, starting from 0 for the topmost row. * @param ratio */ public void setRowExpandRatio(int rowIndex, float ratio) { rowExpandRatio.put(rowIndex, ratio); + getState().explicitRowRatios.add(rowIndex); markAsDirty(); } /** * Returns the expand ratio of given row. - * + * * @see #setRowExpandRatio(int, float) - * + * * @param rowIndex * The row index, starting from 0 for the topmost row. * @return the expand ratio, 0.0f by default @@ -1125,7 +1126,7 @@ public class GridLayout extends AbstractLayout implements /** * Gets the Component at given index. - * + * * @param x * The column index, starting from 0 for the leftmost column. * @param y @@ -1147,7 +1148,7 @@ public class GridLayout extends AbstractLayout implements /** * Returns information about the area where given component is laid in the * GridLayout. - * + * * @param component * the component whose area information is requested. * @return an Area object that contains information how component is laid in diff --git a/shared/src/com/vaadin/shared/ui/gridlayout/GridLayoutState.java b/shared/src/com/vaadin/shared/ui/gridlayout/GridLayoutState.java index ad0f34c862..768183cf73 100644 --- a/shared/src/com/vaadin/shared/ui/gridlayout/GridLayoutState.java +++ b/shared/src/com/vaadin/shared/ui/gridlayout/GridLayoutState.java @@ -1,12 +1,12 @@ /* * 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 @@ -17,7 +17,9 @@ package com.vaadin.shared.ui.gridlayout; import java.io.Serializable; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import com.vaadin.shared.Connector; import com.vaadin.shared.ui.AbstractLayoutState; @@ -33,6 +35,9 @@ public class GridLayoutState extends AbstractLayoutState { public int rows = 0; public int columns = 0; public int marginsBitmask = 0; + // Set of indexes of implicitly Ratios rows and columns + public Set explicitRowRatios = new HashSet();; + public Set explicitColRatios = new HashSet(); public Map childData = new HashMap(); public static class ChildComponentData implements Serializable { @@ -41,5 +46,6 @@ public class GridLayoutState extends AbstractLayoutState { public int column2; public int row2; public int alignment = ALIGNMENT_DEFAULT.getBitMask(); + } } diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatio.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatio.java new file mode 100644 index 0000000000..c20148743a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatio.java @@ -0,0 +1,108 @@ +/* + * Copyright 2000-2013 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.gridlayout; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; + +public class GridLayoutExpandRatio extends AbstractTestUI { + HorizontalLayout layout; + GridLayout gridLayout; + GridLayout gridLayout2; + private static final int ROWS = 5; + private static final int COLS = 5; + private Label[][] labels; + + @Override + protected void setup(VaadinRequest request) { + + labels = new Label[ROWS][COLS]; + layout = new HorizontalLayout(); + gridLayout = new GridLayout(ROWS, COLS); + layout.setImmediate(true); + gridLayout.setImmediate(true); + gridLayout2 = new GridLayout(4, 4); + for (int i = 0; i < ROWS; i++) { + for (int j = 0; j < COLS; j++) { + Label label = new Label("Slot " + i + " " + j); + label.setImmediate(true); + labels[i][j] = label; + gridLayout.addComponent(label, j, i); + if (!(i == 2 || j == 2)) { + Label label2 = new Label("Slot " + i + " " + j); + gridLayout2.addComponent(label2); + } + } + } + gridLayout.setHeight("500px"); + gridLayout.setWidth("500px"); + gridLayout.setSpacing(true); + + gridLayout2.setHeight("500px"); + gridLayout2.setWidth("500px"); + gridLayout2.setSpacing(true); + addComponent(layout); + HorizontalLayout space = new HorizontalLayout(); + space.setWidth("100px"); + layout.addComponent(gridLayout); + layout.addComponent(space); + layout.addComponent(gridLayout2); + + setExpandRatio(); + addComponent(new Button("Hide/show both middle Column and row", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + hideComponetns(); + } + })); + } + + private void hideComponetns() { + for (int i = 0; i < ROWS; i++) { + for (int j = 0; j < COLS; j++) { + if (i == 2 || j == 2) { + if (labels[i][j].isVisible()) { + labels[i][j].setVisible(false); + } else { + labels[i][j].setVisible(true); + } + } + } + } + } + + private void setExpandRatio() { + gridLayout.setRowExpandRatio(2, 5); + gridLayout2.setRowExpandRatio(1, 5); + } + + @Override + protected Integer getTicketNumber() { + return 8855; + } + + @Override + protected String getTestDescription() { + return "If row/column doesn't have elements but have an expand ratio set, it should be shown as a empty row/column"; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatioTest.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatioTest.java new file mode 100644 index 0000000000..7d5ad1fbc4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExpandRatioTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2013 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.gridlayout; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridLayoutElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridLayoutExpandRatioTest extends MultiBrowserTest { + @Test + public void gridLayoutExpandRatioTest() { + openTestURL(); + GridLayoutElement gridLayout5x5 = $(GridLayoutElement.class).get(0); + GridLayoutElement gridLayout4x4 = $(GridLayoutElement.class).get(1); + ButtonElement hidingButton = $(ButtonElement.class).get(0); + hidingButton.click(); + List slots5x5 = gridLayout5x5.findElements(By + .className("v-gridlayout-slot")); + List slots4x4 = gridLayout4x4.findElements(By + .className("v-gridlayout-slot")); + assertEquals("Different amount of slots", slots5x5.size(), + slots4x4.size()); + for (int i = 0; i < slots5x5.size(); i++) { + WebElement compared = slots5x5.get(i); + WebElement actual = slots4x4.get(i); + assertEquals("Different top coordinate for element " + i, + compared.getCssValue("top"), actual.getCssValue("top")); + assertEquals("Different left coordinate for element " + i, + compared.getCssValue("left"), actual.getCssValue("left")); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCells.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCells.java new file mode 100644 index 0000000000..16b3742c64 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCells.java @@ -0,0 +1,146 @@ +/* + * Copyright 2000-2013 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.gridlayout; + +import java.util.Random; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; + +public class GridLayoutHideMiddleCells extends AbstractTestUI { + GridLayout gridLayout; + GridLayout gridLayout2; + + @Override + protected void setup(VaadinRequest request) { + final int ROWS = 5; + final int COLS = 5; + + final Label[][] labels = new Label[ROWS][COLS]; + VerticalLayout mainLayout = new VerticalLayout(); + HorizontalLayout horLayout = new HorizontalLayout(); + gridLayout = new GridLayout(ROWS, COLS); + gridLayout2 = new GridLayout(4, 4); + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + Label label = new Label("Slot " + i + " " + j); + labels[i][j] = label; + gridLayout.addComponent(label); + if (!(i == 2 || j == 2)) { + Label label2 = new Label("Slot " + i + " " + j); + gridLayout2.addComponent(label2); + } + } + } + setContent(mainLayout); + gridLayout.setHeight("500px"); + gridLayout.setWidth("500px"); + gridLayout.setSpacing(true); + + addComponent(gridLayout); + addComponent(gridLayout2); + mainLayout.addComponent(horLayout); + gridLayout2.setHeight("500px"); + gridLayout2.setWidth("500px"); + gridLayout2.setSpacing(true); + horLayout.addComponent(gridLayout); + horLayout.addComponent(gridLayout2); + + mainLayout.addComponent(new Button( + "Hide/show both middle Column and row", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + for (int i = 0; i < ROWS; i++) { + for (int j = 0; j < COLS; j++) { + if (j == 2 || i == 2) { + if (labels[i][j].isVisible()) { + labels[i][j].setVisible(false); + } else { + labels[i][j].setVisible(true); + } + } + } + } + } + })); + mainLayout.addComponent(new Button("Hide/show middle Column", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + for (int i = 0; i < ROWS; i++) { + if (labels[i][2].isVisible()) { + labels[i][2].setVisible(false); + } else { + labels[i][2].setVisible(true); + } + } + } + })); + mainLayout.addComponent(new Button("Hide/show middle Row", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + for (int j = 0; j < COLS; j++) { + if (labels[2][j].isVisible()) { + labels[2][j].setVisible(false); + } else { + labels[2][j].setVisible(true); + } + } + } + + })); + mainLayout.addComponent(new Button("Hide Random button", + new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + // TODO Auto-generated method stub + Random rand = new Random(); + int i = rand.nextInt(ROWS); + int j = rand.nextInt(COLS); + if (labels[i][j].isVisible()) { + labels[i][j].setVisible(false); + } else { + labels[i][j].setVisible(true); + } + } + })); + } + + @Override + protected Integer getTicketNumber() { + return 8855; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Changing the number of visible fields a GridLayout with spacing should not cause additional empty space on the place of invisible fields"; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCellsTest.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCellsTest.java new file mode 100644 index 0000000000..d0225275f7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutHideMiddleCellsTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2013 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.gridlayout; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridLayoutElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridLayoutHideMiddleCellsTest extends MultiBrowserTest { + @Test + public void gridLayoutInvisibleElementsTest() { + openTestURL(); + GridLayoutElement gridLayout5x5 = $(GridLayoutElement.class).get(0); + GridLayoutElement gridLayout4x4 = $(GridLayoutElement.class).get(1); + ButtonElement hidingButton = $(ButtonElement.class).get(0); + hidingButton.click(); + List slots5x5 = gridLayout5x5.findElements(By + .className("v-gridlayout-slot")); + List slots4x4 = gridLayout4x4.findElements(By + .className("v-gridlayout-slot")); + assertEquals("Different amount of slots", slots5x5.size(), + slots4x4.size()); + + for (int i = 0; i < slots5x5.size(); i++) { + assertEquals("Different left coordinate for element " + i, slots5x5 + .get(i).getCssValue("left"), + slots4x4.get(i).getCssValue("left")); + } + for (int i = 0; i < slots5x5.size(); i++) { + assertEquals("Different top coordinate for element " + i, slots5x5 + .get(i).getCssValue("top"), + slots4x4.get(i).getCssValue("top")); + } + } + +} -- 2.39.5