summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrik Paul <henrik@vaadin.com>2014-12-08 01:02:29 +0200
committerHenrik Paul <henrik@vaadin.com>2014-12-12 09:44:00 +0200
commitb3e6edc9634f444ccece00e200cb51eee7994d75 (patch)
treecec9735edc99ec2d0454914ff16fb0f68fa97aa9
parent9927297a94edcc96ac7a653dcdc1cd4fb91951e2 (diff)
downloadvaadin-framework-b3e6edc9634f444ccece00e200cb51eee7994d75.tar.gz
vaadin-framework-b3e6edc9634f444ccece00e200cb51eee7994d75.zip
Columns can now have subpixel accuracy widths (#13334)
Change-Id: I1d16260be7b15c9fbdbfdd8f51e50e9f34e96272
-rw-r--r--client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java7
-rw-r--r--client/src/com/vaadin/client/ui/grid/Escalator.java88
-rw-r--r--client/src/com/vaadin/client/ui/grid/FlyweightCell.java4
-rw-r--r--client/src/com/vaadin/client/ui/grid/FlyweightRow.java6
-rw-r--r--client/src/com/vaadin/client/ui/grid/Grid.java23
-rw-r--r--client/src/com/vaadin/client/ui/grid/GridUtil.java25
-rw-r--r--client/src/com/vaadin/client/ui/grid/ScrollbarBundle.java32
-rw-r--r--server/src/com/vaadin/ui/Grid.java7
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java10
-rw-r--r--shared/src/com/vaadin/shared/ui/grid/GridColumnState.java4
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java11
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java.orig922
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java6
13 files changed, 1040 insertions, 105 deletions
diff --git a/client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java b/client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java
index 6c304ddaea..88f07e023f 100644
--- a/client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java
+++ b/client/src/com/vaadin/client/ui/grid/ColumnConfiguration.java
@@ -123,7 +123,7 @@ public interface ColumnConfiguration {
* @throws IllegalArgumentException
* if <code>index</code> is not a valid column index
*/
- public void setColumnWidth(int index, int px)
+ public void setColumnWidth(int index, double px)
throws IllegalArgumentException;
/**
@@ -136,7 +136,7 @@ public interface ColumnConfiguration {
* @throws IllegalArgumentException
* if <code>index</code> is not a valid column index
*/
- public int getColumnWidth(int index) throws IllegalArgumentException;
+ public double getColumnWidth(int index) throws IllegalArgumentException;
/**
* Returns the actual width of a column.
@@ -147,7 +147,8 @@ public interface ColumnConfiguration {
* @throws IllegalArgumentException
* if <code>index</code> is not a valid column index
*/
- public int getColumnWidthActual(int index) throws IllegalArgumentException;
+ public double getColumnWidthActual(int index)
+ throws IllegalArgumentException;
/**
* Refreshes a range of rows in the current row containers in each Escalator
diff --git a/client/src/com/vaadin/client/ui/grid/Escalator.java b/client/src/com/vaadin/client/ui/grid/Escalator.java
index 1bbcaaf166..3ea7d94282 100644
--- a/client/src/com/vaadin/client/ui/grid/Escalator.java
+++ b/client/src/com/vaadin/client/ui/grid/Escalator.java
@@ -744,7 +744,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
*/
public void recalculateScrollbarsForVirtualViewport() {
int scrollContentHeight = body.calculateEstimatedTotalRowHeight();
- int scrollContentWidth = columnConfiguration.calculateRowWidth();
+ double scrollContentWidth = columnConfiguration.calculateRowWidth();
double tableWrapperHeight = heightOfEscalator;
double tableWrapperWidth = widthOfEscalator;
@@ -789,11 +789,11 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
*/
double prevScrollPos = horizontalScrollbar.getScrollPos();
- int unfrozenPixels = columnConfiguration
+ double unfrozenPixels = columnConfiguration
.getCalculatedColumnsWidth(Range.between(
columnConfiguration.getFrozenColumnCount(),
columnConfiguration.getColumnCount()));
- int frozenPixels = scrollContentWidth - unfrozenPixels;
+ double frozenPixels = scrollContentWidth - unfrozenPixels;
double hScrollOffsetWidth = tableWrapperWidth - frozenPixels;
horizontalScrollbar.setOffsetSize(hScrollOffsetWidth);
horizontalScrollbar.setScrollSize(unfrozenPixels);
@@ -1034,19 +1034,19 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
* structure effectively means that scrollLeft also ignores the
* frozen columns.
*/
- final int frozenPixels = columnConfiguration
+ final double frozenPixels = columnConfiguration
.getCalculatedColumnsWidth(Range.withLength(0,
columnConfiguration.frozenColumns));
- final int targetStartPx = columnConfiguration
+ final double targetStartPx = columnConfiguration
.getCalculatedColumnsWidth(Range.withLength(0, columnIndex))
- frozenPixels;
- final int targetEndPx = targetStartPx
+ final double targetEndPx = targetStartPx
+ columnConfiguration.getColumnWidthActual(columnIndex);
final double viewportStartPx = getScrollLeft();
double viewportEndPx = viewportStartPx
- + getElement().getOffsetWidth() - frozenPixels;
+ + getPreciseWidth(getElement()) - frozenPixels;
if (verticalScrollbar.showsScrollHandle()) {
viewportEndPx -= Util.getNativeScrollbarSize();
}
@@ -1399,7 +1399,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
tr.addClassName(getStylePrimaryName() + "-row");
for (int col = 0; col < columnConfiguration.getColumnCount(); col++) {
- final int colWidth = columnConfiguration
+ final double colWidth = columnConfiguration
.getColumnWidthActual(col);
final TableCellElement cellElem = createCellElement(
rowHeight, colWidth);
@@ -1542,11 +1542,11 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
* @return a set-up empty cell element
*/
public TableCellElement createCellElement(final int height,
- final int width) {
+ final double colWidth) {
final TableCellElement cellElem = TableCellElement.as(DOM
.createElement(getCellElementTagName()));
cellElem.getStyle().setHeight(height, Unit.PX);
- cellElem.getStyle().setWidth(width, Unit.PX);
+ cellElem.getStyle().setWidth(colWidth, Unit.PX);
cellElem.addClassName(getStylePrimaryName() + "-cell");
return cellElem;
}
@@ -1640,7 +1640,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
final int rowHeight = getDefaultRowHeight();
for (FlyweightCell cell : cells) {
- final int colWidth = columnConfiguration
+ final double colWidth = columnConfiguration
.getColumnWidthActual(cell.getColumn());
final TableCellElement cellElem = createCellElement(rowHeight,
colWidth);
@@ -1706,16 +1706,16 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
* the index of the column to inspect
* @return the pixel width of the widest element in the indicated column
*/
- public int calculateMaxColWidth(int index) {
+ public double calculateMaxColWidth(int index) {
TableRowElement row = TableRowElement.as(root
.getFirstChildElement());
- int maxWidth = 0;
+ double maxWidth = 0;
while (row != null) {
final TableCellElement cell = row.getCells().getItem(index);
final boolean isVisible = !cell.getStyle().getDisplay()
.equals(Display.NONE.getCssName());
if (isVisible) {
- maxWidth = Math.max(maxWidth, cell.getScrollWidth());
+ maxWidth = Math.max(maxWidth, getPreciseWidth(cell));
}
row = TableRowElement.as(row.getNextSiblingElement());
}
@@ -1732,8 +1732,8 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
Element cell = row.getFirstChildElement();
int columnIndex = 0;
while (cell != null) {
- final int width = getCalculatedColumnWidthWithColspan(cell,
- columnIndex);
+ final double width = getCalculatedColumnWidthWithColspan(
+ cell, columnIndex);
/*
* TODO Should Escalator implement ProvidesResize at some
@@ -1750,7 +1750,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
reapplyRowWidths();
}
- private int getCalculatedColumnWidthWithColspan(final Element cell,
+ private double getCalculatedColumnWidthWithColspan(final Element cell,
final int columnIndex) {
final int colspan = cell.getPropertyInt(FlyweightCell.COLSPAN_ATTR);
Range spannedColumns = Range.withLength(columnIndex, colspan);
@@ -1775,7 +1775,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
* cells within.
*/
protected void reapplyRowWidths() {
- int rowWidth = columnConfiguration.calculateRowWidth();
+ double rowWidth = columnConfiguration.calculateRowWidth();
com.google.gwt.dom.client.Element row = root.getFirstChildElement();
while (row != null) {
@@ -1957,8 +1957,8 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
return new Cell(domRowIndex, domColumnIndex, cellElement);
}
- int getMaxCellWidth(int colIndex) throws IllegalArgumentException {
- int maxCellWidth = -1;
+ double getMaxCellWidth(int colIndex) throws IllegalArgumentException {
+ double maxCellWidth = -1;
assert isAttached() : "Can't measure max width of cell, since Escalator is not attached to the DOM.";
@@ -1988,7 +1988,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
cellClone.getStyle().clearWidth();
rowElement.insertBefore(cellClone, cellOriginal);
- maxCellWidth = Math.max(cellClone.getOffsetWidth(),
+ maxCellWidth = Math.max(getPreciseWidth(cellClone),
maxCellWidth);
cellClone.removeFromParent();
}
@@ -3684,8 +3684,8 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
public class Column {
private static final int DEFAULT_COLUMN_WIDTH_PX = 100;
- private int definedWidth = -1;
- private int calculatedWidth = DEFAULT_COLUMN_WIDTH_PX;
+ private double definedWidth = -1;
+ private double calculatedWidth = DEFAULT_COLUMN_WIDTH_PX;
private boolean measuringRequested = false;
/**
@@ -3695,7 +3695,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
*/
private boolean widthHasBeenFinalized = false;
- public void setWidth(int px) {
+ public void setWidth(double px) {
definedWidth = px;
if (px < 0) {
@@ -3713,7 +3713,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
}
}
- public int getDefinedWidth() {
+ public double getDefinedWidth() {
return definedWidth;
}
@@ -3723,7 +3723,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
* @return the width in pixels in the DOM. Returns -1 if the column
* needs measuring, but has not been yet measured
*/
- public int getCalculatedWidth() {
+ public double getCalculatedWidth() {
/*
* This might return an untrue value (e.g. during init/onload),
* since we haven't had a proper chance to actually calculate
@@ -3777,7 +3777,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
*
* @see #getCalculatedColumnWidths()
*/
- private int[] widthsArray = null;
+ private double[] widthsArray = null;
/**
* {@inheritDoc}
@@ -3884,7 +3884,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
*
* @return the width of a row, in pixels
*/
- public int calculateRowWidth() {
+ public double calculateRowWidth() {
return getCalculatedColumnsWidth(Range.between(0, getColumnCount()));
}
@@ -3966,12 +3966,12 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
}
// Adjust scrollbar
- int pixelsToInsertedColumn = columnConfiguration
+ double pixelsToInsertedColumn = columnConfiguration
.getCalculatedColumnsWidth(Range.withLength(0, index));
final boolean columnsWereAddedToTheLeftOfViewport = scroller.lastScrollLeft > pixelsToInsertedColumn;
if (columnsWereAddedToTheLeftOfViewport) {
- int insertedColumnsWidth = columnConfiguration
+ double insertedColumnsWidth = columnConfiguration
.getCalculatedColumnsWidth(Range.withLength(index,
numberOfColumns));
horizontalScrollbar.setScrollPos(scroller.lastScrollLeft
@@ -4042,7 +4042,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
}
@Override
- public void setColumnWidth(int index, int px)
+ public void setColumnWidth(int index, double px)
throws IllegalArgumentException {
checkValidColumnIndex(index);
@@ -4069,25 +4069,25 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
}
@Override
- public int getColumnWidth(int index) throws IllegalArgumentException {
+ public double getColumnWidth(int index) throws IllegalArgumentException {
checkValidColumnIndex(index);
return columns.get(index).getDefinedWidth();
}
@Override
- public int getColumnWidthActual(int index) {
+ public double getColumnWidthActual(int index) {
return columns.get(index).getCalculatedWidth();
}
- private int getMaxCellWidth(int colIndex)
+ private double getMaxCellWidth(int colIndex)
throws IllegalArgumentException {
- int headerWidth = header.getMaxCellWidth(colIndex);
- int bodyWidth = body.getMaxCellWidth(colIndex);
- int footerWidth = footer.getMaxCellWidth(colIndex);
+ double headerWidth = header.getMaxCellWidth(colIndex);
+ double bodyWidth = body.getMaxCellWidth(colIndex);
+ double footerWidth = footer.getMaxCellWidth(colIndex);
- int maxWidth = Math.max(headerWidth,
+ double maxWidth = Math.max(headerWidth,
Math.max(bodyWidth, footerWidth));
- assert maxWidth > 0 : "Got a negative max width for a column, which should be impossible.";
+ assert maxWidth >= 0 : "Got a negative max width for a column, which should be impossible.";
return maxWidth;
}
@@ -4099,7 +4099,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
* @return the total width of the columns in the given
* <code>columns</code>
*/
- int getCalculatedColumnsWidth(final Range columns) {
+ double getCalculatedColumnsWidth(final Range columns) {
/*
* This is an assert instead of an exception, since this is an
* internal method.
@@ -4110,17 +4110,17 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker
+ ", but was given :"
+ columns;
- int sum = 0;
+ double sum = 0;
for (int i = columns.getStart(); i < columns.getEnd(); i++) {
- int columnWidthActual = getColumnWidthActual(i);
+ double columnWidthActual = getColumnWidthActual(i);
sum += columnWidthActual;
}
return sum;
}
- int[] getCalculatedColumnWidths() {
+ double[] getCalculatedColumnWidths() {
if (widthsArray == null || widthsArray.length != getColumnCount()) {
- widthsArray = new int[getColumnCount()];
+ widthsArray = new double[getColumnCount()];
for (int i = 0; i < columns.size(); i++) {
widthsArray[i] = columns.get(i).getCalculatedWidth();
}
diff --git a/client/src/com/vaadin/client/ui/grid/FlyweightCell.java b/client/src/com/vaadin/client/ui/grid/FlyweightCell.java
index adcca1b630..fe826b16c3 100644
--- a/client/src/com/vaadin/client/ui/grid/FlyweightCell.java
+++ b/client/src/com/vaadin/client/ui/grid/FlyweightCell.java
@@ -169,8 +169,8 @@ public class FlyweightCell {
final int cellsToTheRight = currentIterator.rawPeekNext(
numberOfCells - 1).size();
- final int selfWidth = row.getColumnWidth(column);
- int widthsOfColumnsToTheRight = 0;
+ final double selfWidth = row.getColumnWidth(column);
+ double widthsOfColumnsToTheRight = 0;
for (int i = 0; i < cellsToTheRight; i++) {
widthsOfColumnsToTheRight += row.getColumnWidth(column + i + 1);
}
diff --git a/client/src/com/vaadin/client/ui/grid/FlyweightRow.java b/client/src/com/vaadin/client/ui/grid/FlyweightRow.java
index 0e9c6ad955..9f913f5cd1 100644
--- a/client/src/com/vaadin/client/ui/grid/FlyweightRow.java
+++ b/client/src/com/vaadin/client/ui/grid/FlyweightRow.java
@@ -140,10 +140,10 @@ class FlyweightRow implements Row {
private int row;
private TableRowElement element;
- private int[] columnWidths = null;
+ private double[] columnWidths = null;
private final List<FlyweightCell> cells = new ArrayList<FlyweightCell>();
- void setup(final TableRowElement e, final int row, int[] columnWidths) {
+ void setup(final TableRowElement e, final int row, double[] columnWidths) {
element = e;
this.row = row;
this.columnWidths = columnWidths;
@@ -285,7 +285,7 @@ class FlyweightRow implements Row {
+ "has been stored and accessed.";
}
- int getColumnWidth(int column) {
+ double getColumnWidth(int column) {
assertSetup();
return columnWidths[column];
}
diff --git a/client/src/com/vaadin/client/ui/grid/Grid.java b/client/src/com/vaadin/client/ui/grid/Grid.java
index c6d7e22d3b..80ecc9a9e9 100644
--- a/client/src/com/vaadin/client/ui/grid/Grid.java
+++ b/client/src/com/vaadin/client/ui/grid/Grid.java
@@ -1875,7 +1875,7 @@ public class Grid<T> extends ResizeComposite implements
}
@Override
- public GridColumn<Boolean, T> setWidth(int pixels) {
+ public GridColumn<Boolean, T> setWidth(double pixels) {
if (pixels != getWidth() && initDone) {
throw new UnsupportedOperationException("The selection "
+ "column cannot be modified after init");
@@ -2208,8 +2208,11 @@ public class Grid<T> extends ResizeComposite implements
*/
private boolean visible = true;
- /** Width of column in pixels as {@link #setWidth(int)} has been called */
- private int widthUser = GridColumnState.DEFAULT_COLUMN_WIDTH_PX;
+ /**
+ * Width of column in pixels as {@link #setWidth(double)} has been
+ * called
+ */
+ private double widthUser = GridColumnState.DEFAULT_COLUMN_WIDTH_PX;
/**
* Renderer for rendering a value into the cell
@@ -2387,7 +2390,7 @@ public class Grid<T> extends ResizeComposite implements
* the width in pixels or negative for auto sizing
* @return the column itself
*/
- public GridColumn<C, T> setWidth(int pixels) {
+ public GridColumn<C, T> setWidth(double pixels) {
widthUser = pixels;
if (pixels < 0) {
setWidthAutodetect();
@@ -2409,14 +2412,14 @@ public class Grid<T> extends ResizeComposite implements
*/
}
- private void setWidthAbsolute(int pixels) {
+ private void setWidthAbsolute(double pixels) {
asyncAutodetectWidth.stop();
if (grid != null) {
setWidthForce(pixels);
}
}
- private void setWidthForce(int pixels) {
+ private void setWidthForce(double pixels) {
int index = grid.columns.indexOf(this);
ColumnConfiguration conf = grid.escalator.getColumnConfiguration();
conf.setColumnWidth(index, pixels);
@@ -2426,14 +2429,14 @@ public class Grid<T> extends ResizeComposite implements
* Returns the pixel width of the column as given by the user.
* <p>
* <em>Note:</em> If a negative value was given to
- * {@link #setWidth(int)}, that same negative value is returned here.
+ * {@link #setWidth(double)}, that same negative value is returned here.
*
* @return pixel width of the column, or a negative number if the column
* width has been automatically calculated.
- * @see #setWidth(int)
+ * @see #setWidth(double)
* @see #getWidthActual()
*/
- public int getWidth() {
+ public double getWidth() {
return widthUser;
}
@@ -2445,7 +2448,7 @@ public class Grid<T> extends ResizeComposite implements
*
* @return pixel width of the column.
*/
- public int getWidthActual() {
+ public double getWidthActual() {
return grid.escalator.getColumnConfiguration()
.getColumnWidthActual(grid.columns.indexOf(this));
}
diff --git a/client/src/com/vaadin/client/ui/grid/GridUtil.java b/client/src/com/vaadin/client/ui/grid/GridUtil.java
index 0eed0e98b5..8dc0822d9d 100644
--- a/client/src/com/vaadin/client/ui/grid/GridUtil.java
+++ b/client/src/com/vaadin/client/ui/grid/GridUtil.java
@@ -16,7 +16,6 @@
package com.vaadin.client.ui.grid;
import com.google.gwt.dom.client.Element;
-import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.Util;
@@ -29,8 +28,17 @@ import com.vaadin.client.Util;
public class GridUtil {
/**
+ * The allowed value inaccuracy when comparing two double-typed pixel
+ * values.
+ * <p>
+ * Since we're comparing pixels on a screen, epsilon must be less than 1.
+ * 0.49 was deemed a perfectly fine and beautifully round number.
+ */
+ public static final double PIXEL_EPSILON = 0.49d;
+
+ /**
* Returns the cell the given element belongs to.
- *
+ *
* @param grid
* the grid instance that is queried
* @param e
@@ -78,4 +86,17 @@ public class GridUtil {
widget.@com.google.gwt.user.client.ui.Widget::setParent(Lcom/google/gwt/user/client/ui/Widget;)(parent);
}-*/;
+ /**
+ * Compares two double values with the error margin of
+ * {@link #PIXEL_EPSILON} (i.e. {@value #PIXEL_EPSILON})
+ *
+ * @param num1
+ * the first value for which to compare equality
+ * @param num2
+ * the second value for which to compare equality
+ */
+ public static boolean pixelValuesEqual(final double num1, final double num2) {
+ return Math.abs(num1 - num2) <= PIXEL_EPSILON;
+ }
+
}
diff --git a/client/src/com/vaadin/client/ui/grid/ScrollbarBundle.java b/client/src/com/vaadin/client/ui/grid/ScrollbarBundle.java
index a2df48e6c6..7d6d050e64 100644
--- a/client/src/com/vaadin/client/ui/grid/ScrollbarBundle.java
+++ b/client/src/com/vaadin/client/ui/grid/ScrollbarBundle.java
@@ -179,15 +179,6 @@ abstract class ScrollbarBundle {
private static final int OSX_INVISIBLE_SCROLLBAR_FAKE_SIZE_PX = 13;
/**
- * The allowed value inaccuracy when comparing two double-typed pixel
- * values.
- * <p>
- * Since we're comparing pixels on a screen, epsilon must be less than 1.
- * 0.49 was deemed a perfectly fine and beautifully round number.
- */
- private static final double PIXEL_EPSILON = 0.49d;
-
- /**
* A representation of a single vertical scrollbar.
*
* @see VerticalScrollbarBundle#getElement()
@@ -211,7 +202,7 @@ abstract class ScrollbarBundle {
}
@Override
- protected void internalSetScrollSize(int px) {
+ protected void internalSetScrollSize(double px) {
scrollSizeElement.getStyle().setHeight(px, Unit.PX);
}
@@ -280,7 +271,7 @@ abstract class ScrollbarBundle {
}
@Override
- protected void internalSetScrollSize(int px) {
+ protected void internalSetScrollSize(double px) {
scrollSizeElement.getStyle().setWidth(px, Unit.PX);
}
@@ -451,7 +442,7 @@ abstract class ScrollbarBundle {
double oldScrollPos = scrollPos;
scrollPos = Math.max(0, Math.min(maxScrollPos, truncate(px)));
- if (!pixelValuesEqual(oldScrollPos, scrollPos)) {
+ if (!GridUtil.pixelValuesEqual(oldScrollPos, scrollPos)) {
if (isInvisibleScrollbar) {
invisibleScrollbarTemporaryResizer.show();
}
@@ -533,7 +524,7 @@ abstract class ScrollbarBundle {
* the new size of {@link #scrollSizeElement} in the dimension
* this scrollbar is representing
*/
- protected abstract void internalSetScrollSize(int px);
+ protected abstract void internalSetScrollSize(double px);
/**
* Sets the amount of pixels the scrollbar needs to be able to scroll
@@ -549,7 +540,7 @@ abstract class ScrollbarBundle {
* through
*/
public final void setScrollSize(double px) {
- internalSetScrollSize(toInt32(Math.max(0, truncate(px))));
+ internalSetScrollSize(Math.max(0, px));
forceScrollbar(showsScrollHandle());
recalculateMaxScrollPos();
fireVisibilityChangeIfNeeded();
@@ -719,19 +710,6 @@ abstract class ScrollbarBundle {
}-*/;
/**
- * Compares two double values with the error margin of
- * {@link #PIXEL_EPSILON} (i.e. {@value #PIXEL_EPSILON})
- *
- * @param num1
- * the first value for which to compare equality
- * @param num2
- * the second value for which to compare equality
- */
- private static boolean pixelValuesEqual(final double num1, final double num2) {
- return Math.abs(num1 - num2) <= PIXEL_EPSILON;
- }
-
- /**
* Locks or unlocks the scrollbar bundle.
* <p>
* A locked scrollbar bundle will refuse to scroll, both programmatically
diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java
index 838829b9cc..d0485c3d68 100644
--- a/server/src/com/vaadin/ui/Grid.java
+++ b/server/src/com/vaadin/ui/Grid.java
@@ -64,7 +64,6 @@ import com.vaadin.event.SortOrderChangeEvent.SortOrderChangeListener;
import com.vaadin.event.SortOrderChangeEvent.SortOrderChangeNotifier;
import com.vaadin.server.AbstractClientConnector;
import com.vaadin.server.AbstractExtension;
-import com.vaadin.server.ClientConnector;
import com.vaadin.server.ErrorHandler;
import com.vaadin.server.ErrorMessage;
import com.vaadin.server.JsonCodec;
@@ -1643,7 +1642,7 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier,
* @throws IllegalStateException
* if the column is no longer attached to any grid
*/
- public int getWidth() throws IllegalStateException {
+ public double getWidth() throws IllegalStateException {
checkColumnIsAttached();
return state.width;
}
@@ -1660,7 +1659,7 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier,
* @throws IllegalArgumentException
* thrown if pixel width is less than zero
*/
- public Column setWidth(int pixelWidth) throws IllegalStateException,
+ public Column setWidth(double pixelWidth) throws IllegalStateException,
IllegalArgumentException {
checkColumnIsAttached();
if (pixelWidth < 0) {
@@ -2518,7 +2517,7 @@ public class Grid extends AbstractComponent implements SelectionChangeNotifier,
*
* @return unmodifiable copy of current columns in visual order
*/
- public Collection<Column> getColumns() {
+ public List<Column> getColumns() {
List<Column> columns = new ArrayList<Grid.Column>();
for (String columnId : getState(false).columnOrder) {
columns.add(getColumnByColumnId(columnId));
diff --git a/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java b/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java
index 366176c3fa..1204b1e396 100644
--- a/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java
+++ b/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java
@@ -100,18 +100,18 @@ public class GridColumns {
.getCell("column1").getText());
column.setWidth(100);
- assertEquals(100, column.getWidth());
- assertEquals(column.getWidth(), getColumnState("column1").width);
+ assertEquals(100, column.getWidth(), 0.49d);
+ assertEquals(column.getWidth(), getColumnState("column1").width, 0.49d);
try {
column.setWidth(-1);
fail("Setting width to -1 should throw exception");
} catch (IllegalArgumentException iae) {
-
+ // expected
}
- assertEquals(100, column.getWidth());
- assertEquals(100, getColumnState("column1").width);
+ assertEquals(100, column.getWidth(), 0.49d);
+ assertEquals(100, getColumnState("column1").width, 0.49d);
}
@Test
diff --git a/shared/src/com/vaadin/shared/ui/grid/GridColumnState.java b/shared/src/com/vaadin/shared/ui/grid/GridColumnState.java
index 751b262570..65a5ed625d 100644
--- a/shared/src/com/vaadin/shared/ui/grid/GridColumnState.java
+++ b/shared/src/com/vaadin/shared/ui/grid/GridColumnState.java
@@ -28,7 +28,7 @@ import com.vaadin.shared.Connector;
*/
public class GridColumnState implements Serializable {
- public static final int DEFAULT_COLUMN_WIDTH_PX = -1;
+ public static final double DEFAULT_COLUMN_WIDTH_PX = -1;
/**
* Id used by grid connector to map server side column with client side
@@ -40,7 +40,7 @@ public class GridColumnState implements Serializable {
* Column width in pixels. Default column width is
* {@value #DEFAULT_COLUMN_WIDTH_PX}.
*/
- public int width = DEFAULT_COLUMN_WIDTH_PX;
+ public double width = DEFAULT_COLUMN_WIDTH_PX;
/**
* The connector for the renderer used to render the cells in this column.
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java
index 043ff2e2e0..e61edb4e65 100644
--- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java
+++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java
@@ -538,6 +538,17 @@ public class GridBasicFeatures extends AbstractComponentTest<Grid> {
}
}, -1, c);
+ createClickAction("25.5px", "Column " + c + " Width",
+ new Command<Grid, Void>() {
+ @Override
+ @SuppressWarnings("boxing")
+ public void execute(Grid grid, Void value,
+ Object columnIndex) {
+ grid.getColumns().get((Integer) columnIndex)
+ .setWidth(25.5);
+ }
+ }, null, c);
+
for (int w = 50; w < 300; w += 50) {
createClickAction(w + "px", "Column " + c + " Width",
new Command<Grid, Integer>() {
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java.orig b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java.orig
new file mode 100644
index 0000000000..5d7fa04e94
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java.orig
@@ -0,0 +1,922 @@
+/*
+ * 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.basicfeatures;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Random;
+
+import com.vaadin.data.Container.Filter;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
+import com.vaadin.data.sort.Sort;
+import com.vaadin.data.sort.SortOrder;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.event.SortOrderChangeEvent;
+import com.vaadin.event.SortOrderChangeEvent.SortOrderChangeListener;
+import com.vaadin.shared.ui.grid.GridStaticCellType;
+import com.vaadin.shared.ui.grid.HeightMode;
+import com.vaadin.shared.ui.grid.SortDirection;
+import com.vaadin.tests.components.AbstractComponentTest;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Grid.CellStyleGenerator;
+import com.vaadin.ui.Grid.Column;
+import com.vaadin.ui.Grid.FooterCell;
+import com.vaadin.ui.Grid.HeaderCell;
+import com.vaadin.ui.Grid.HeaderRow;
+import com.vaadin.ui.Grid.MultiSelectionModel;
+import com.vaadin.ui.Grid.SelectionMode;
+<<<<<<< HEAD
+import com.vaadin.ui.renderer.DateRenderer;
+import com.vaadin.ui.renderer.HtmlRenderer;
+import com.vaadin.ui.renderer.NumberRenderer;
+=======
+import com.vaadin.ui.components.grid.SortOrderChangeEvent;
+import com.vaadin.ui.components.grid.SortOrderChangeListener;
+import com.vaadin.ui.components.grid.renderers.DateRenderer;
+import com.vaadin.ui.components.grid.renderers.HtmlRenderer;
+import com.vaadin.ui.components.grid.renderers.NumberRenderer;
+import com.vaadin.ui.components.grid.selection.MultiSelectionModel;
+import com.vaadin.ui.components.grid.sort.Sort;
+import com.vaadin.ui.components.grid.sort.SortOrder;
+>>>>>>> Columns can now have subpixel accuracy widths (#13334)
+
+/**
+ * Tests the basic features like columns, footers and headers
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class GridBasicFeatures extends AbstractComponentTest<Grid> {
+
+ private static final int MANUALLY_FORMATTED_COLUMNS = 5;
+ public static final int COLUMNS = 12;
+ public static final int ROWS = 1000;
+
+ private int columnGroupRows = 0;
+ private IndexedContainer ds;
+ private Grid grid;
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected Grid constructComponent() {
+
+ // Build data source
+ ds = new IndexedContainer() {
+ @Override
+ public List<Object> getItemIds(int startIndex, int numberOfIds) {
+ log("Requested items " + startIndex + " - "
+ + (startIndex + numberOfIds));
+ return super.getItemIds(startIndex, numberOfIds);
+ }
+ };
+
+ {
+ int col = 0;
+ for (; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; col++) {
+ ds.addContainerProperty(getColumnProperty(col), String.class,
+ "");
+ }
+
+ ds.addContainerProperty(getColumnProperty(col++), Integer.class,
+ Integer.valueOf(0));
+ ds.addContainerProperty(getColumnProperty(col++), Date.class,
+ new Date());
+ ds.addContainerProperty(getColumnProperty(col++), String.class, "");
+
+ // Random numbers
+ ds.addContainerProperty(getColumnProperty(col++), Integer.class, 0);
+ ds.addContainerProperty(getColumnProperty(col++), Integer.class, 0);
+
+ }
+
+ {
+ Random rand = new Random();
+ rand.setSeed(13334);
+ long timestamp = 0;
+ for (int row = 0; row < ROWS; row++) {
+ Item item = ds.addItem(Integer.valueOf(row));
+ int col = 0;
+ for (; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; col++) {
+ item.getItemProperty(getColumnProperty(col)).setValue(
+ "(" + row + ", " + col + ")");
+ }
+ item.getItemProperty(getColumnProperty(1)).setReadOnly(true);
+
+ item.getItemProperty(getColumnProperty(col++)).setValue(
+ Integer.valueOf(row));
+ item.getItemProperty(getColumnProperty(col++)).setValue(
+ new Date(timestamp));
+ timestamp += 91250000; // a bit over a day, just to get
+ // variation
+ item.getItemProperty(getColumnProperty(col++)).setValue(
+ "<b>" + row + "</b>");
+
+ // Random numbers
+ item.getItemProperty(getColumnProperty(col++)).setValue(
+ rand.nextInt());
+ // Random between 0 - 5 to test multisorting
+ item.getItemProperty(getColumnProperty(col++)).setValue(
+ rand.nextInt(5));
+ }
+ }
+
+ // Create grid
+ Grid grid = new Grid(ds);
+
+ {
+ int col = grid.getContainerDataSource().getContainerPropertyIds()
+ .size()
+ - MANUALLY_FORMATTED_COLUMNS;
+ grid.getColumn(getColumnProperty(col++)).setRenderer(
+ new NumberRenderer(new DecimalFormat("0,000.00",
+ DecimalFormatSymbols.getInstance(new Locale("fi",
+ "FI")))));
+ grid.getColumn(getColumnProperty(col++)).setRenderer(
+ new DateRenderer(new SimpleDateFormat("dd.MM.yy HH:mm")));
+ grid.getColumn(getColumnProperty(col++)).setRenderer(
+ new HtmlRenderer());
+ grid.getColumn(getColumnProperty(col++)).setRenderer(
+ new NumberRenderer());
+ grid.getColumn(getColumnProperty(col++)).setRenderer(
+ new NumberRenderer());
+ }
+
+ // Create footer
+ grid.appendFooterRow();
+ grid.setFooterVisible(false);
+
+ // Add footer values (header values are automatically created)
+ for (int col = 0; col < COLUMNS; col++) {
+ grid.getFooterRow(0).getCell(getColumnProperty(col))
+ .setText("Footer " + col);
+ }
+
+ // Set varying column widths
+ for (int col = 0; col < COLUMNS; col++) {
+ grid.getColumn(getColumnProperty(col)).setWidth(100 + col * 50);
+ }
+
+ grid.addSortOrderChangeListener(new SortOrderChangeListener() {
+ @Override
+ public void sortOrderChange(SortOrderChangeEvent event) {
+
+ log("SortOrderChangeEvent: isUserOriginated? "
+ + event.isUserOriginated());
+ }
+ });
+
+ grid.setSelectionMode(SelectionMode.NONE);
+
+ grid.setPropertyEditable(getColumnProperty(3), false);
+
+ createGridActions();
+
+ createColumnActions();
+
+ createPropertyActions();
+
+ createHeaderActions();
+
+ createFooterActions();
+
+ createRowActions();
+
+ createEditorRowActions();
+
+ addHeightActions();
+
+ createClickAction("Column 1 starts with \"(23\"", "Filter",
+ new Command<Grid, Void>() {
+ @Override
+ public void execute(Grid grid, Void value, Object data) {
+ ds.addContainerFilter(new Filter() {
+
+ @Override
+ public boolean passesFilter(Object itemId, Item item)
+ throws UnsupportedOperationException {
+ return item.getItemProperty("Column 1")
+ .getValue().toString()
+ .startsWith("(23");
+ }
+
+ @Override
+ public boolean appliesToProperty(Object propertyId) {
+ return propertyId.equals("Column 1");
+ }
+ });
+ }
+ }, null);
+
+ this.grid = grid;
+ return grid;
+ }
+
+ protected void createGridActions() {
+ LinkedHashMap<String, String> primaryStyleNames = new LinkedHashMap<String, String>();
+ primaryStyleNames.put("v-grid", "v-grid");
+ primaryStyleNames.put("v-escalator", "v-escalator");
+ primaryStyleNames.put("my-grid", "my-grid");
+
+ createMultiClickAction("Primary style name", "State",
+ primaryStyleNames, new Command<Grid, String>() {
+
+ @Override
+ public void execute(Grid grid, String value, Object data) {
+ grid.setPrimaryStyleName(value);
+
+ }
+ }, primaryStyleNames.get("v-grid"));
+
+ LinkedHashMap<String, SelectionMode> selectionModes = new LinkedHashMap<String, Grid.SelectionMode>();
+ selectionModes.put("single", SelectionMode.SINGLE);
+ selectionModes.put("multi", SelectionMode.MULTI);
+ selectionModes.put("none", SelectionMode.NONE);
+ createSelectAction("Selection mode", "State", selectionModes, "none",
+ new Command<Grid, Grid.SelectionMode>() {
+ @Override
+ public void execute(Grid grid, SelectionMode selectionMode,
+ Object data) {
+ grid.setSelectionMode(selectionMode);
+ }
+ });
+
+ LinkedHashMap<String, Integer> selectionLimits = new LinkedHashMap<String, Integer>();
+ selectionLimits.put("2", Integer.valueOf(2));
+ selectionLimits.put("1000", Integer.valueOf(1000));
+ selectionLimits.put("Integer.MAX_VALUE",
+ Integer.valueOf(Integer.MAX_VALUE));
+ createSelectAction("Selection limit", "State", selectionLimits, "1000",
+ new Command<Grid, Integer>() {
+ @Override
+ public void execute(Grid grid, Integer limit, Object data) {
+ if (!(grid.getSelectionModel() instanceof MultiSelectionModel)) {
+ grid.setSelectionMode(SelectionMode.MULTI);
+ }
+
+ ((MultiSelectionModel) grid.getSelectionModel())
+ .setSelectionLimit(limit.intValue());
+ }
+ });
+
+ LinkedHashMap<String, List<SortOrder>> sortableProperties = new LinkedHashMap<String, List<SortOrder>>();
+ for (Object propertyId : ds.getSortableContainerPropertyIds()) {
+ sortableProperties.put(propertyId + ", ASC", Sort.by(propertyId)
+ .build());
+ sortableProperties.put(propertyId + ", DESC",
+ Sort.by(propertyId, SortDirection.DESCENDING).build());
+ }
+ createSelectAction("Sort by column", "State", sortableProperties,
+ "Column 9, ascending", new Command<Grid, List<SortOrder>>() {
+ @Override
+ public void execute(Grid grid, List<SortOrder> sortOrder,
+ Object data) {
+ grid.setSortOrder(sortOrder);
+ }
+ });
+
+ createBooleanAction("Reverse Grid Columns", "State", false,
+ new Command<Grid, Boolean>() {
+
+ @Override
+ public void execute(Grid c, Boolean value, Object data) {
+ List<Object> ids = new ArrayList<Object>();
+ ids.addAll(ds.getContainerPropertyIds());
+ if (!value) {
+ c.setColumnOrder(ids.toArray());
+ } else {
+ Object[] idsArray = new Object[ids.size()];
+ for (int i = 0; i < ids.size(); ++i) {
+ idsArray[i] = ids.get((ids.size() - 1) - i);
+ }
+ c.setColumnOrder(idsArray);
+ }
+ }
+ });
+
+ LinkedHashMap<String, CellStyleGenerator> styleGenerators = new LinkedHashMap<String, CellStyleGenerator>();
+ styleGenerators.put("None", null);
+ styleGenerators.put("Row only", new CellStyleGenerator() {
+ @Override
+ public String getStyle(Grid grid, Object itemId, Object propertyId) {
+ if (propertyId == null) {
+ return "row" + itemId;
+ } else {
+ return null;
+ }
+ }
+ });
+ styleGenerators.put("Cell only", new CellStyleGenerator() {
+ @Override
+ public String getStyle(Grid grid, Object itemId, Object propertyId) {
+ if (propertyId == null) {
+ return null;
+ } else {
+ return propertyId.toString().replace(' ', '-');
+ }
+ }
+ });
+ styleGenerators.put("Combined", new CellStyleGenerator() {
+ @Override
+ public String getStyle(Grid grid, Object itemId, Object propertyId) {
+ int rowIndex = ((Integer) itemId).intValue();
+ if (propertyId == null) {
+ if (rowIndex % 4 == 0) {
+ return null;
+ } else {
+ return "row" + itemId;
+ }
+ } else {
+ if (rowIndex % 4 == 1) {
+ return null;
+ } else if (rowIndex % 4 == 3
+ && "Column 1".equals(propertyId)) {
+ return null;
+ }
+ return propertyId.toString().replace(' ', '_');
+ }
+ }
+ });
+ createSelectAction("Style generator", "State", styleGenerators, "None",
+ new Command<Grid, CellStyleGenerator>() {
+ @Override
+ public void execute(Grid grid,
+ CellStyleGenerator generator, Object data) {
+ grid.setCellStyleGenerator(generator);
+ }
+ });
+
+ LinkedHashMap<String, Integer> frozenOptions = new LinkedHashMap<String, Integer>();
+ for (int i = -1; i <= COLUMNS; i++) {
+ frozenOptions.put(String.valueOf(i), Integer.valueOf(i));
+ }
+ createSelectAction("Frozen column count", "State", frozenOptions, "0",
+ new Command<Grid, Integer>() {
+ @Override
+ public void execute(Grid c, Integer value, Object data) {
+ c.setFrozenColumnCount(value.intValue());
+ }
+ });
+ }
+
+ protected void createHeaderActions() {
+ createCategory("Header", null);
+
+ createBooleanAction("Visible", "Header", true,
+ new Command<Grid, Boolean>() {
+
+ @Override
+ public void execute(Grid grid, Boolean value, Object data) {
+ grid.setHeaderVisible(value);
+ }
+ });
+
+ LinkedHashMap<String, String> defaultRows = new LinkedHashMap<String, String>();
+ defaultRows.put("Top", "Top");
+ defaultRows.put("Bottom", "Bottom");
+ defaultRows.put("Unset", "Unset");
+
+ createMultiClickAction("Default row", "Header", defaultRows,
+ new Command<Grid, String>() {
+
+ @Override
+ public void execute(Grid grid, String value, Object data) {
+ HeaderRow defaultRow = null;
+ if (value.equals("Top")) {
+ defaultRow = grid.getHeaderRow(0);
+ } else if (value.equals("Bottom")) {
+ defaultRow = grid.getHeaderRow(grid
+ .getHeaderRowCount() - 1);
+ }
+ grid.setDefaultHeaderRow(defaultRow);
+ }
+
+ }, defaultRows.get("Top"));
+
+ createClickAction("Prepend row", "Header", new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.prependHeaderRow();
+ }
+
+ }, null);
+ createClickAction("Append row", "Header", new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.appendHeaderRow();
+ }
+
+ }, null);
+
+ createClickAction("Remove top row", "Header",
+ new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.removeHeaderRow(0);
+ }
+
+ }, null);
+ createClickAction("Remove bottom row", "Header",
+ new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.removeHeaderRow(grid.getHeaderRowCount() - 1);
+ }
+
+ }, null);
+ }
+
+ protected void createFooterActions() {
+ createCategory("Footer", null);
+
+ createBooleanAction("Visible", "Footer", false,
+ new Command<Grid, Boolean>() {
+
+ @Override
+ public void execute(Grid grid, Boolean value, Object data) {
+ grid.setFooterVisible(value);
+ }
+ });
+
+ createClickAction("Prepend row", "Footer", new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.prependFooterRow();
+ }
+
+ }, null);
+ createClickAction("Append row", "Footer", new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.appendFooterRow();
+ }
+
+ }, null);
+
+ createClickAction("Remove top row", "Footer",
+ new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.removeFooterRow(0);
+ }
+
+ }, null);
+ createClickAction("Remove bottom row", "Footer",
+ new Command<Grid, Object>() {
+
+ @Override
+ public void execute(Grid grid, Object value, Object data) {
+ grid.removeFooterRow(grid.getFooterRowCount() - 1);
+ }
+
+ }, null);
+ }
+
+ protected void createColumnActions() {
+ createCategory("Columns", null);
+
+ for (int c = 0; c < COLUMNS; c++) {
+ final int index = c;
+ createCategory(getColumnProperty(c), "Columns");
+
+ createClickAction("Add / Remove", getColumnProperty(c),
+ new Command<Grid, String>() {
+
+ @Override
+ public void execute(Grid grid, String value, Object data) {
+ String columnProperty = getColumnProperty((Integer) data);
+ if (grid.getColumn(columnProperty) == null) {
+ grid.addColumn(columnProperty);
+ } else {
+ grid.removeColumn(columnProperty);
+ }
+ }
+ }, null, c);
+
+ createBooleanAction("Sortable", getColumnProperty(c), true,
+ new Command<Grid, Boolean>() {
+
+ @Override
+ public void execute(Grid grid, Boolean value,
+ Object columnIndex) {
+ Object propertyId = getColumnProperty((Integer) columnIndex);
+ Column column = grid.getColumn(propertyId);
+ column.setSortable(value);
+ }
+ }, c);
+
+ createCategory("Column " + c + " Width", getColumnProperty(c));
+
+ createClickAction("Auto", "Column " + c + " Width",
+ new Command<Grid, Integer>() {
+
+ @Override
+ public void execute(Grid grid, Integer value,
+ Object columnIndex) {
+ Object propertyId = getColumnProperty((Integer) columnIndex);
+ Column column = grid.getColumn(propertyId);
+ column.setWidthUndefined();
+ }
+ }, -1, c);
+
+ createClickAction("25.5px", "Column " + c + " Width",
+ new Command<Grid, Void>() {
+ @Override
+ @SuppressWarnings("boxing")
+ public void execute(Grid grid, Void value,
+ Object columnIndex) {
+ grid.getColumns().get((Integer) columnIndex)
+ .setWidth(25.5);
+ }
+ }, null, c);
+
+ for (int w = 50; w < 300; w += 50) {
+ createClickAction(w + "px", "Column " + c + " Width",
+ new Command<Grid, Integer>() {
+
+ @Override
+ public void execute(Grid grid, Integer value,
+ Object columnIndex) {
+ Object propertyId = getColumnProperty((Integer) columnIndex);
+ Column column = grid.getColumn(propertyId);
+ column.setWidth(value);
+ }
+ }, w, c);
+ }
+
+ LinkedHashMap<String, GridStaticCellType> defaultRows = new LinkedHashMap<String, GridStaticCellType>();
+ defaultRows.put("Text Header", GridStaticCellType.TEXT);
+ defaultRows.put("Html Header ", GridStaticCellType.HTML);
+ defaultRows.put("Widget Header", GridStaticCellType.WIDGET);
+
+ createMultiClickAction("Header Type", getColumnProperty(c),
+ defaultRows, new Command<Grid, GridStaticCellType>() {
+
+ @Override
+ public void execute(Grid grid,
+ GridStaticCellType value, Object columnIndex) {
+ final Object propertyId = getColumnProperty((Integer) columnIndex);
+ final HeaderCell cell = grid.getDefaultHeaderRow()
+ .getCell(propertyId);
+ switch (value) {
+ case TEXT:
+ cell.setText("Text Header");
+ break;
+ case HTML:
+ cell.setHtml("HTML Header");
+ break;
+ case WIDGET:
+ cell.setComponent(new Button("Button Header",
+ new ClickListener() {
+
+ @Override
+ public void buttonClick(
+ ClickEvent event) {
+ log("Button clicked!");
+ }
+ }));
+ default:
+ break;
+ }
+ }
+
+ }, c);
+
+ defaultRows = new LinkedHashMap<String, GridStaticCellType>();
+ defaultRows.put("Text Footer", GridStaticCellType.TEXT);
+ defaultRows.put("Html Footer", GridStaticCellType.HTML);
+ defaultRows.put("Widget Footer", GridStaticCellType.WIDGET);
+
+ createMultiClickAction("Footer Type", getColumnProperty(c),
+ defaultRows, new Command<Grid, GridStaticCellType>() {
+
+ @Override
+ public void execute(Grid grid,
+ GridStaticCellType value, Object columnIndex) {
+ final Object propertyId = getColumnProperty((Integer) columnIndex);
+ final FooterCell cell = grid.getFooterRow(0)
+ .getCell(propertyId);
+ switch (value) {
+ case TEXT:
+ cell.setText("Text Footer");
+ break;
+ case HTML:
+ cell.setHtml("HTML Footer");
+ break;
+ case WIDGET:
+ cell.setComponent(new Button("Button Footer",
+ new ClickListener() {
+
+ @Override
+ public void buttonClick(
+ ClickEvent event) {
+ log("Button clicked!");
+ }
+ }));
+ default:
+ break;
+ }
+ }
+
+ }, c);
+ }
+ }
+
+ private static String getColumnProperty(int c) {
+ return "Column " + c;
+ }
+
+ protected void createPropertyActions() {
+ createCategory("Properties", null);
+
+ createBooleanAction("Prepend property", "Properties", false,
+ new Command<Grid, Boolean>() {
+ private final Object propertyId = new Object();
+
+ @Override
+ public void execute(Grid c, Boolean enable, Object data) {
+ if (enable.booleanValue()) {
+ ds.addContainerProperty(propertyId, String.class,
+ "property value");
+ grid.getColumn(propertyId).setHeaderCaption(
+ "new property");
+ grid.setColumnOrder(propertyId);
+ } else {
+ ds.removeContainerProperty(propertyId);
+ }
+ }
+ }, null);
+ }
+
+ protected void createRowActions() {
+ createCategory("Body rows", null);
+
+ class NewRowCommand implements Command<Grid, String> {
+ private final int index;
+
+ public NewRowCommand() {
+ this(0);
+ }
+
+ public NewRowCommand(int index) {
+ this.index = index;
+ }
+
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ Item item = ds.addItemAt(index, new Object());
+ for (int i = 0; i < COLUMNS; i++) {
+ Class<?> type = ds.getType(getColumnProperty(i));
+ if (String.class.isAssignableFrom(type)) {
+ Property<String> itemProperty = getProperty(item, i);
+ itemProperty.setValue("newcell: " + i);
+ } else if (Integer.class.isAssignableFrom(type)) {
+ Property<Integer> itemProperty = getProperty(item, i);
+ itemProperty.setValue(Integer.valueOf(i));
+ } else {
+ // let the default value be taken implicitly.
+ }
+ }
+ }
+
+ private <T extends Object> Property<T> getProperty(Item item, int i) {
+ @SuppressWarnings("unchecked")
+ Property<T> itemProperty = item
+ .getItemProperty(getColumnProperty(i));
+ return itemProperty;
+ }
+ }
+ final NewRowCommand newRowCommand = new NewRowCommand();
+
+ createClickAction("Add 18 rows", "Body rows",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ for (int i = 0; i < 18; i++) {
+ newRowCommand.execute(c, value, data);
+ }
+ }
+ }, null);
+
+ createClickAction("Add first row", "Body rows", newRowCommand, null);
+
+ createClickAction("Add second row", "Body rows", new NewRowCommand(1),
+ null);
+
+ createClickAction("Remove first row", "Body rows",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ Object firstItemId = ds.getIdByIndex(0);
+ ds.removeItem(firstItemId);
+ }
+ }, null);
+
+ createClickAction("Remove 18 first rows", "Body rows",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ for (int i = 0; i < 18; i++) {
+ Object firstItemId = ds.getIdByIndex(0);
+ ds.removeItem(firstItemId);
+ }
+ }
+ }, null);
+
+ createClickAction("Modify first row (getItemProperty)", "Body rows",
+ new Command<Grid, String>() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ Object firstItemId = ds.getIdByIndex(0);
+ Item item = ds.getItem(firstItemId);
+ for (int i = 0; i < COLUMNS; i++) {
+ Property<?> property = item
+ .getItemProperty(getColumnProperty(i));
+ if (property.getType().equals(String.class)) {
+ ((Property<String>) property)
+ .setValue("modified: " + i);
+ }
+ }
+ }
+ }, null);
+
+ createClickAction("Modify first row (getContainerProperty)",
+ "Body rows", new Command<Grid, String>() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ Object firstItemId = ds.getIdByIndex(0);
+ for (Object containerPropertyId : ds
+ .getContainerPropertyIds()) {
+ Property<?> property = ds.getContainerProperty(
+ firstItemId, containerPropertyId);
+ if (property.getType().equals(String.class)) {
+ ((Property<String>) property)
+ .setValue("modified: "
+ + containerPropertyId);
+ }
+ }
+ }
+ }, null);
+
+ createBooleanAction("Select first row", "Body rows", false,
+ new Command<Grid, Boolean>() {
+ @Override
+ public void execute(Grid grid, Boolean select, Object data) {
+ final Object firstItemId = grid
+ .getContainerDataSource().firstItemId();
+ if (select.booleanValue()) {
+ grid.select(firstItemId);
+ } else {
+ grid.deselect(firstItemId);
+ }
+ }
+ });
+
+ createClickAction("Remove all rows", "Body rows",
+ new Command<Grid, String>() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ ds.removeAllItems();
+ }
+ }, null);
+ }
+
+ protected void createEditorRowActions() {
+ createBooleanAction("Enabled", "Editor row", false,
+ new Command<Grid, Boolean>() {
+ @Override
+ public void execute(Grid c, Boolean value, Object data) {
+ c.setEditorRowEnabled(value);
+ }
+ });
+
+ createClickAction("Edit item 5", "Editor row",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ c.editItem(5);
+ }
+ }, null);
+
+ createClickAction("Edit item 100", "Editor row",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ c.editItem(100);
+ }
+ }, null);
+ createClickAction("Save", "Editor row", new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ try {
+ c.saveEditorRow();
+ } catch (CommitException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }, null);
+ createClickAction("Cancel edit", "Editor row",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ c.cancelEditorRow();
+ }
+ }, null);
+ }
+
+ @SuppressWarnings("boxing")
+ protected void addHeightActions() {
+ createCategory("Height by Rows", "Size");
+
+ createBooleanAction("HeightMode Row", "Size", false,
+ new Command<Grid, Boolean>() {
+ @Override
+ public void execute(Grid c, Boolean heightModeByRows,
+ Object data) {
+ c.setHeightMode(heightModeByRows ? HeightMode.ROW
+ : HeightMode.CSS);
+ }
+ }, null);
+
+ addActionForHeightByRows(1d / 3d);
+ addActionForHeightByRows(2d / 3d);
+
+ for (double i = 1; i < 5; i++) {
+ addActionForHeightByRows(i);
+ addActionForHeightByRows(i + 1d / 3d);
+ addActionForHeightByRows(i + 2d / 3d);
+ }
+
+ Command<Grid, String> sizeCommand = new Command<Grid, String>() {
+ @Override
+ public void execute(Grid grid, String height, Object data) {
+ grid.setHeight(height);
+ }
+ };
+
+ createCategory("Height", "Size");
+ // header 20px + scrollbar 16px = 36px baseline
+ createClickAction("86px (no drag scroll select)", "Height",
+ sizeCommand, "86px");
+ createClickAction("96px (drag scroll select limit)", "Height",
+ sizeCommand, "96px");
+ createClickAction("106px (drag scroll select enabled)", "Height",
+ sizeCommand, "106px");
+ }
+
+ private void addActionForHeightByRows(final Double i) {
+ DecimalFormat df = new DecimalFormat("0.00");
+ createClickAction(df.format(i) + " rows", "Height by Rows",
+ new Command<Grid, String>() {
+ @Override
+ public void execute(Grid c, String value, Object data) {
+ c.setHeightByRows(i);
+ }
+ }, null);
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 12829;
+ }
+
+ @Override
+ protected Class<Grid> getTestClass() {
+ return Grid.class;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java
index f1d64a50e7..88ad1fcd5a 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java
@@ -65,18 +65,18 @@ public class EscalatorProxy extends Escalator {
}
@Override
- public void setColumnWidth(int index, int px)
+ public void setColumnWidth(int index, double px)
throws IllegalArgumentException {
columnConfiguration.setColumnWidth(index, px);
}
@Override
- public int getColumnWidth(int index) throws IllegalArgumentException {
+ public double getColumnWidth(int index) throws IllegalArgumentException {
return columnConfiguration.getColumnWidth(index);
}
@Override
- public int getColumnWidthActual(int index)
+ public double getColumnWidthActual(int index)
throws IllegalArgumentException {
return columnConfiguration.getColumnWidthActual(index);
}