Further changes required for this, included in the same patch: - created GridClientRpc interface - created test case UI for server-side controlled Grid programmatic scrolling - refactored getScrollPos logic into Escalator and moved ScrollDestination enum to shared package Change-Id: Ibf72a4f75831807d83fb5941597a6ce3fda08e17tags/7.2.0.beta1
@@ -52,6 +52,7 @@ import com.vaadin.client.ui.grid.PositionFunction.WebkitTranslate3DPosition; | |||
import com.vaadin.client.ui.grid.ScrollbarBundle.HorizontalScrollbarBundle; | |||
import com.vaadin.client.ui.grid.ScrollbarBundle.VerticalScrollbarBundle; | |||
import com.vaadin.shared.ui.grid.Range; | |||
import com.vaadin.shared.ui.grid.ScrollDestination; | |||
import com.vaadin.shared.util.SharedUtil; | |||
/*- | |||
@@ -548,6 +549,80 @@ public class Escalator extends Widget { | |||
private static final int ROW_HEIGHT_PX = 20; | |||
/** | |||
* ScrollDestination case-specific handling logic. | |||
*/ | |||
private static double getScrollPos(final ScrollDestination destination, | |||
final double targetStartPx, final double targetEndPx, | |||
final double viewportStartPx, final double viewportEndPx, | |||
final int padding) { | |||
final double viewportLength = viewportEndPx - viewportStartPx; | |||
switch (destination) { | |||
/* | |||
* Scroll as little as possible to show the target element. If the | |||
* element fits into view, this works as START or END depending on the | |||
* current scroll position. If the element does not fit into view, this | |||
* works as START. | |||
*/ | |||
case ANY: { | |||
final double startScrollPos = targetStartPx - padding; | |||
final double endScrollPos = targetEndPx + padding - viewportLength; | |||
if (startScrollPos < viewportStartPx) { | |||
return startScrollPos; | |||
} else if (targetEndPx + padding > viewportEndPx) { | |||
return endScrollPos; | |||
} else { | |||
// NOOP, it's already visible | |||
return viewportStartPx; | |||
} | |||
} | |||
/* | |||
* Scrolls so that the element is shown at the end of the viewport. The | |||
* viewport will, however, not scroll before its first element. | |||
*/ | |||
case END: { | |||
return targetEndPx + padding - viewportLength; | |||
} | |||
/* | |||
* Scrolls so that the element is shown in the middle of the viewport. | |||
* The viewport will, however, not scroll beyond its contents, given | |||
* more elements than what the viewport is able to show at once. Under | |||
* no circumstances will the viewport scroll before its first element. | |||
*/ | |||
case MIDDLE: { | |||
final double targetMiddle = targetStartPx | |||
+ (targetEndPx - targetStartPx) / 2; | |||
return targetMiddle - viewportLength / 2; | |||
} | |||
/* | |||
* Scrolls so that the element is shown at the start of the viewport. | |||
* The viewport will, however, not scroll beyond its contents. | |||
*/ | |||
case START: { | |||
return targetStartPx - padding; | |||
} | |||
/* | |||
* Throw an error if we're here. This can only mean that | |||
* ScrollDestination has been carelessly amended.. | |||
*/ | |||
default: { | |||
throw new IllegalArgumentException( | |||
"Internal: ScrollDestination has been modified, " | |||
+ "but Escalator.getScrollPos has not been updated " | |||
+ "to match new values."); | |||
} | |||
} | |||
} | |||
/** An inner class that handles all logic related to scrolling. */ | |||
private class Scroller extends JsniWorkaround { | |||
private double lastScrollTop = 0; | |||
@@ -900,7 +975,7 @@ public class Escalator extends Widget { | |||
viewportEndPx -= Util.getNativeScrollbarSize(); | |||
} | |||
final double scrollLeft = destination.getScrollPos(targetStartPx, | |||
final double scrollLeft = getScrollPos(destination, targetStartPx, | |||
targetEndPx, viewportStartPx, viewportEndPx, padding); | |||
/* | |||
@@ -921,7 +996,7 @@ public class Escalator extends Widget { | |||
final double viewportEndPx = viewportStartPx | |||
+ body.calculateHeight(); | |||
final double scrollTop = destination.getScrollPos(targetStartPx, | |||
final double scrollTop = getScrollPos(destination, targetStartPx, | |||
targetEndPx, viewportStartPx, viewportEndPx, padding); | |||
/* | |||
@@ -3305,33 +3380,6 @@ public class Escalator extends Widget { | |||
horizontalScrollbar.setScrollPos(scrollLeft); | |||
} | |||
/** | |||
* Scrolls the body horizontally so that the column at the given index is | |||
* visible. | |||
* | |||
* @param columnIndex | |||
* the index of the column to scroll to | |||
* @param destination | |||
* where the column should be aligned visually after scrolling | |||
* @throws IndexOutOfBoundsException | |||
* if {@code columnIndex} is not a valid index for an existing | |||
* column | |||
* @throws IllegalArgumentException | |||
* if the column is frozen | |||
*/ | |||
public void scrollToColumn(final int columnIndex, | |||
final ScrollDestination destination) | |||
throws IndexOutOfBoundsException, IllegalArgumentException { | |||
verifyValidColumnIndex(columnIndex); | |||
if (columnIndex < columnConfiguration.frozenColumns) { | |||
throw new IllegalArgumentException("The given column index " | |||
+ columnIndex + " is frozen."); | |||
} | |||
scroller.scrollToColumn(columnIndex, destination, 0); | |||
} | |||
/** | |||
* Scrolls the body horizontally so that the column at the given index is | |||
* visible and there is at least {@code padding} pixels to the given scroll | |||
@@ -3348,14 +3396,15 @@ public class Escalator extends Widget { | |||
* if {@code columnIndex} is not a valid index for an existing | |||
* column | |||
* @throws IllegalArgumentException | |||
* if {@code destination} is {@link ScrollDestination#MIDDLE}, | |||
* because having a padding on a centered column is undefined | |||
* behavior or if the column is frozen | |||
* if {@code destination} is {@link ScrollDestination#MIDDLE} | |||
* and padding is nonzero, because having a padding on a | |||
* centered column is undefined behavior, or if the column is | |||
* frozen | |||
*/ | |||
public void scrollToColumn(final int columnIndex, | |||
final ScrollDestination destination, final int padding) | |||
throws IndexOutOfBoundsException, IllegalArgumentException { | |||
if (destination == ScrollDestination.MIDDLE) { | |||
if (destination == ScrollDestination.MIDDLE && padding != 0) { | |||
throw new IllegalArgumentException( | |||
"You cannot have a padding with a MIDDLE destination"); | |||
} | |||
@@ -3378,26 +3427,6 @@ public class Escalator extends Widget { | |||
} | |||
} | |||
/** | |||
* Scrolls the body vertically so that the row at the given index is | |||
* visible. | |||
* | |||
* @param rowIndex | |||
* the index of the row to scroll to | |||
* @param destination | |||
* where the row should be aligned visually after scrolling | |||
* @throws IndexOutOfBoundsException | |||
* if {@code rowIndex} is not a valid index for an existing | |||
* logical row | |||
*/ | |||
public void scrollToRow(final int rowIndex, | |||
final ScrollDestination destination) | |||
throws IndexOutOfBoundsException { | |||
verifyValidRowIndex(rowIndex); | |||
scroller.scrollToRow(rowIndex, destination, 0); | |||
} | |||
/** | |||
* Scrolls the body vertically so that the row at the given index is visible | |||
* and there is at least {@literal padding} pixels to the given scroll | |||
@@ -3413,14 +3442,14 @@ public class Escalator extends Widget { | |||
* @throws IndexOutOfBoundsException | |||
* if {@code rowIndex} is not a valid index for an existing row | |||
* @throws IllegalArgumentException | |||
* if {@code destination} is {@link ScrollDestination#MIDDLE}, | |||
* because having a padding on a centered row is undefined | |||
* behavior | |||
* if {@code destination} is {@link ScrollDestination#MIDDLE} | |||
* and padding is nonzero, because having a padding on a | |||
* centered row is undefined behavior | |||
*/ | |||
public void scrollToRow(final int rowIndex, | |||
final ScrollDestination destination, final int padding) | |||
throws IndexOutOfBoundsException, IllegalArgumentException { | |||
if (destination == ScrollDestination.MIDDLE) { | |||
if (destination == ScrollDestination.MIDDLE && padding != 0) { | |||
throw new IllegalArgumentException( | |||
"You cannot have a padding with a MIDDLE destination"); | |||
} |
@@ -18,6 +18,7 @@ package com.vaadin.client.ui.grid; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.logging.Logger; | |||
import com.google.gwt.core.shared.GWT; | |||
import com.google.gwt.dom.client.Element; | |||
@@ -28,6 +29,8 @@ import com.google.gwt.user.client.ui.Widget; | |||
import com.vaadin.client.data.DataChangeHandler; | |||
import com.vaadin.client.data.DataSource; | |||
import com.vaadin.client.ui.grid.renderers.TextRenderer; | |||
import com.vaadin.shared.ui.grid.GridConstants; | |||
import com.vaadin.shared.ui.grid.ScrollDestination; | |||
import com.vaadin.shared.util.SharedUtil; | |||
/** | |||
@@ -1225,4 +1228,91 @@ public class Grid<T> extends Composite { | |||
*/ | |||
return escalator.addRowVisibilityChangeHandler(handler); | |||
} | |||
/** | |||
* Scrolls to a certain row, using {@link ScrollDestination#ANY}. | |||
* | |||
* @param rowIndex | |||
* zero-based index of the row to scroll to. | |||
* @throws IllegalArgumentException | |||
* if rowIndex is below zero, or above the maximum value | |||
* supported by the data source. | |||
*/ | |||
public void scrollToRow(int rowIndex) throws IllegalArgumentException { | |||
scrollToRow(rowIndex, ScrollDestination.ANY, | |||
GridConstants.DEFAULT_PADDING); | |||
} | |||
/** | |||
* Scrolls to a certain row, using user-specified scroll destination. | |||
* | |||
* @param rowIndex | |||
* zero-based index of the row to scroll to. | |||
* @param destination | |||
* desired destination placement of scrolled-to-row. See | |||
* {@link ScrollDestination} for more information. | |||
* @throws IllegalArgumentException | |||
* if rowIndex is below zero, or above the maximum value | |||
* supported by the data source. | |||
*/ | |||
public void scrollToRow(int rowIndex, ScrollDestination destination) | |||
throws IllegalArgumentException { | |||
scrollToRow(rowIndex, destination, | |||
destination == ScrollDestination.MIDDLE ? 0 | |||
: GridConstants.DEFAULT_PADDING); | |||
} | |||
/** | |||
* Scrolls to a certain row using only user-specified parameters. | |||
* | |||
* @param rowIndex | |||
* zero-based index of the row to scroll to. | |||
* @param destination | |||
* desired destination placement of scrolled-to-row. See | |||
* {@link ScrollDestination} for more information. | |||
* @param paddingPx | |||
* number of pixels to overscroll. Behavior depends on | |||
* destination. | |||
* @throws IllegalArgumentException | |||
* if {@code destination} is {@link ScrollDestination#MIDDLE} | |||
* and padding is nonzero, because having a padding on a | |||
* centered row is undefined behavior, or if rowIndex is below | |||
* zero or above the row count of the data source. | |||
*/ | |||
private void scrollToRow(int rowIndex, ScrollDestination destination, | |||
int paddingPx) throws IllegalArgumentException { | |||
int maxsize = escalator.getBody().getRowCount() - 1; | |||
if (rowIndex < 0) { | |||
throw new IllegalArgumentException("Row index (" + rowIndex | |||
+ ") is below zero!"); | |||
} | |||
if (rowIndex > maxsize) { | |||
throw new IllegalArgumentException("Row index (" + rowIndex | |||
+ ") is above maximum (" + maxsize + ")!"); | |||
} | |||
escalator.scrollToRow(rowIndex, destination, paddingPx); | |||
} | |||
/** | |||
* Scrolls to the beginning of the very first row. | |||
*/ | |||
public void scrollToStart() { | |||
scrollToRow(0, ScrollDestination.START); | |||
} | |||
/** | |||
* Scrolls to the end of the very last row. | |||
*/ | |||
public void scrollToEnd() { | |||
scrollToRow(escalator.getBody().getRowCount() - 1, | |||
ScrollDestination.END); | |||
} | |||
private static final Logger getLogger() { | |||
return Logger.getLogger(Grid.class.getName()); | |||
} | |||
} |
@@ -29,9 +29,11 @@ import com.vaadin.client.ui.AbstractComponentConnector; | |||
import com.vaadin.shared.ui.Connect; | |||
import com.vaadin.shared.ui.grid.ColumnGroupRowState; | |||
import com.vaadin.shared.ui.grid.ColumnGroupState; | |||
import com.vaadin.shared.ui.grid.GridClientRpc; | |||
import com.vaadin.shared.ui.grid.GridColumnState; | |||
import com.vaadin.shared.ui.grid.GridServerRpc; | |||
import com.vaadin.shared.ui.grid.GridState; | |||
import com.vaadin.shared.ui.grid.ScrollDestination; | |||
/** | |||
* Connects the client side {@link Grid} widget with the server side | |||
@@ -96,6 +98,23 @@ public class GridConnector extends AbstractComponentConnector { | |||
event.getVisibleRowCount()); | |||
} | |||
}); | |||
registerRpc(GridClientRpc.class, new GridClientRpc() { | |||
@Override | |||
public void scrollToStart() { | |||
getWidget().scrollToStart(); | |||
} | |||
@Override | |||
public void scrollToEnd() { | |||
getWidget().scrollToEnd(); | |||
} | |||
@Override | |||
public void scrollToRow(int row, ScrollDestination destination) { | |||
getWidget().scrollToRow(row, destination); | |||
} | |||
}); | |||
} | |||
@Override |
@@ -1,102 +0,0 @@ | |||
/* | |||
* 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.client.ui.grid; | |||
/** | |||
* The destinations that are supported in an Escalator when scrolling rows or | |||
* columns into view. | |||
* | |||
* @since 7.2 | |||
* @author Vaadin Ltd | |||
*/ | |||
public enum ScrollDestination { | |||
/** | |||
* Scroll as little as possible to show the target element. If the element | |||
* fits into view, this works as START or END depending on the current | |||
* scroll position. If the element does not fit into view, this works as | |||
* START. | |||
*/ | |||
ANY { | |||
@Override | |||
double getScrollPos(final double targetStartPx, | |||
final double targetEndPx, final double viewportStartPx, | |||
final double viewportEndPx, final int padding) { | |||
final double startScrollPos = targetStartPx - padding; | |||
final double viewportLength = viewportEndPx - viewportStartPx; | |||
final double endScrollPos = targetEndPx + padding - viewportLength; | |||
if (startScrollPos < viewportStartPx) { | |||
return startScrollPos; | |||
} else if (targetEndPx + padding > viewportEndPx) { | |||
return endScrollPos; | |||
} else { | |||
// NOOP, it's already visible | |||
return viewportStartPx; | |||
} | |||
} | |||
}, | |||
/** | |||
* Scrolls so that the element is shown at the start of the viewport. The | |||
* viewport will, however, not scroll beyond its contents. | |||
*/ | |||
START { | |||
@Override | |||
double getScrollPos(final double targetStartPx, | |||
final double targetEndPx, final double viewportStartPx, | |||
final double viewportEndPx, final int padding) { | |||
return targetStartPx - padding; | |||
} | |||
}, | |||
/** | |||
* Scrolls so that the element is shown in the middle of the viewport. The | |||
* viewport will, however, not scroll beyond its contents, given more | |||
* elements than what the viewport is able to show at once. Under no | |||
* circumstances will the viewport scroll before its first element. | |||
*/ | |||
MIDDLE { | |||
@Override | |||
double getScrollPos(final double targetStartPx, | |||
final double targetEndPx, final double viewportStartPx, | |||
final double viewportEndPx, final int padding) { | |||
final double targetMiddle = targetStartPx | |||
+ (targetEndPx - targetStartPx) / 2; | |||
final double viewportLength = viewportEndPx - viewportStartPx; | |||
return targetMiddle - viewportLength / 2; | |||
} | |||
}, | |||
/** | |||
* Scrolls so that the element is shown at the end of the viewport. The | |||
* viewport will, however, not scroll before its first element. | |||
*/ | |||
END { | |||
@Override | |||
double getScrollPos(final double targetStartPx, | |||
final double targetEndPx, final double viewportStartPx, | |||
final double viewportEndPx, final int padding) { | |||
final double viewportLength = viewportEndPx - viewportStartPx; | |||
return targetEndPx + padding - viewportLength; | |||
} | |||
}; | |||
abstract double getScrollPos(final double targetStartPx, | |||
final double targetEndPx, final double viewportStartPx, | |||
final double viewportEndPx, final int padding); | |||
} |
@@ -0,0 +1,55 @@ | |||
/* | |||
* 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.shared.ui.grid; | |||
/** | |||
* Enumeration, specifying the destinations that are supported when scrolling | |||
* rows or columns into view. | |||
* | |||
* @since 7.2 | |||
* @author Vaadin Ltd | |||
*/ | |||
public enum ScrollDestination { | |||
/** | |||
* Scroll as little as possible to show the target element. If the element | |||
* fits into view, this works as START or END depending on the current | |||
* scroll position. If the element does not fit into view, this works as | |||
* START. | |||
*/ | |||
ANY, | |||
/** | |||
* Scrolls so that the element is shown at the start of the viewport. The | |||
* viewport will, however, not scroll beyond its contents. | |||
*/ | |||
START, | |||
/** | |||
* Scrolls so that the element is shown in the middle of the viewport. The | |||
* viewport will, however, not scroll beyond its contents, given more | |||
* elements than what the viewport is able to show at once. Under no | |||
* circumstances will the viewport scroll before its first element. | |||
*/ | |||
MIDDLE, | |||
/** | |||
* Scrolls so that the element is shown at the end of the viewport. The | |||
* viewport will, however, not scroll before its first element. | |||
*/ | |||
END | |||
} |
@@ -42,10 +42,12 @@ import com.vaadin.data.Property.ValueChangeNotifier; | |||
import com.vaadin.data.RpcDataProviderExtension; | |||
import com.vaadin.server.KeyMapper; | |||
import com.vaadin.shared.ui.grid.ColumnGroupRowState; | |||
import com.vaadin.shared.ui.grid.GridClientRpc; | |||
import com.vaadin.shared.ui.grid.GridColumnState; | |||
import com.vaadin.shared.ui.grid.GridServerRpc; | |||
import com.vaadin.shared.ui.grid.GridState; | |||
import com.vaadin.shared.ui.grid.Range; | |||
import com.vaadin.shared.ui.grid.ScrollDestination; | |||
import com.vaadin.ui.AbstractComponent; | |||
import com.vaadin.ui.Component; | |||
@@ -804,4 +806,56 @@ public class Grid extends AbstractComponent { | |||
public Object getLastFrozenPropertyId() { | |||
return columnKeys.get(getState().lastFrozenColumnId); | |||
} | |||
/** | |||
* Scrolls to a certain item, using {@link ScrollDestination#ANY}. | |||
* | |||
* @param itemId | |||
* id of item to scroll to. | |||
* @throws IllegalArgumentException | |||
* if the provided id is not recognized by the data source. | |||
*/ | |||
public void scrollToItem(Object itemId) throws IllegalArgumentException { | |||
scrollToItem(itemId, ScrollDestination.ANY); | |||
} | |||
/** | |||
* Scrolls to a certain item, using user-specified scroll destination. | |||
* | |||
* @param itemId | |||
* id of item to scroll to. | |||
* @param destination | |||
* value specifying desired position of scrolled-to row. | |||
* @throws IllegalArgumentException | |||
* if the provided id is not recognized by the data source. | |||
*/ | |||
public void scrollToItem(Object itemId, ScrollDestination destination) | |||
throws IllegalArgumentException { | |||
int row = datasource.indexOfId(itemId); | |||
if (row == -1) { | |||
throw new IllegalArgumentException( | |||
"Item with specified ID does not exist in data source"); | |||
} | |||
GridClientRpc clientRPC = getRpcProxy(GridClientRpc.class); | |||
clientRPC.scrollToRow(row, destination); | |||
} | |||
/** | |||
* Scrolls to the beginning of the first data row. | |||
*/ | |||
public void scrollToStart() { | |||
GridClientRpc clientRPC = getRpcProxy(GridClientRpc.class); | |||
clientRPC.scrollToStart(); | |||
} | |||
/** | |||
* Scrolls to the end of the last data row. | |||
*/ | |||
public void scrollToEnd() { | |||
GridClientRpc clientRPC = getRpcProxy(GridClientRpc.class); | |||
clientRPC.scrollToEnd(); | |||
} | |||
} |
@@ -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.shared.ui.grid; | |||
import com.vaadin.shared.communication.ClientRpc; | |||
/** | |||
* Server-to-client RPC interface for the Grid component. | |||
* | |||
* @since 7.2 | |||
* @author Vaadin Ltd | |||
*/ | |||
public interface GridClientRpc extends ClientRpc { | |||
/** | |||
* Command client Grid to scroll to a specific data row. | |||
* | |||
* @param row | |||
* zero-based row index. If the row index is below zero or above | |||
* the row count of the client-side data source, a client-side | |||
* exception will be triggered. Since this exception has no | |||
* handling by default, an out-of-bounds value will cause a | |||
* client-side crash. | |||
* @param destination | |||
* desired placement of scrolled-to row. See the documentation | |||
* for {@link ScrollDestination} for more information. | |||
*/ | |||
public void scrollToRow(int row, ScrollDestination destination); | |||
/** | |||
* Command client Grid to scroll to the first row. | |||
*/ | |||
public void scrollToStart(); | |||
/** | |||
* Command client Grid to scroll to the last row. | |||
*/ | |||
public void scrollToEnd(); | |||
} |
@@ -0,0 +1,33 @@ | |||
/* | |||
* 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.shared.ui.grid; | |||
/** | |||
* Container class for common constants and default values used by the Grid | |||
* component. | |||
* | |||
* @since 7.2 | |||
* @author Vaadin Ltd | |||
*/ | |||
public final class GridConstants { | |||
/** | |||
* Default padding in pixels when scrolling programmatically, without an | |||
* explicitly defined padding value. | |||
*/ | |||
public static final int DEFAULT_PADDING = 0; | |||
} |
@@ -0,0 +1,115 @@ | |||
/* | |||
* 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.grid; | |||
import com.vaadin.data.Item; | |||
import com.vaadin.data.util.IndexedContainer; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.shared.ui.grid.ScrollDestination; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Button.ClickEvent; | |||
import com.vaadin.ui.Button.ClickListener; | |||
import com.vaadin.ui.HorizontalLayout; | |||
import com.vaadin.ui.VerticalLayout; | |||
import com.vaadin.ui.components.grid.Grid; | |||
/** | |||
* | |||
*/ | |||
@SuppressWarnings("serial") | |||
public class GridScrolling extends AbstractTestUI { | |||
private Grid grid; | |||
private IndexedContainer ds; | |||
@Override | |||
@SuppressWarnings("unchecked") | |||
protected void setup(VaadinRequest request) { | |||
// Build data source | |||
ds = new IndexedContainer(); | |||
for (int col = 0; col < 5; col++) { | |||
ds.addContainerProperty("col" + col, String.class, ""); | |||
} | |||
for (int row = 0; row < 65536; row++) { | |||
Item item = ds.addItem(Integer.valueOf(row)); | |||
for (int col = 0; col < 5; col++) { | |||
item.getItemProperty("col" + col).setValue( | |||
"(" + row + ", " + col + ")"); | |||
} | |||
} | |||
grid = new Grid(ds); | |||
HorizontalLayout hl = new HorizontalLayout(); | |||
hl.addComponent(grid); | |||
hl.setMargin(true); | |||
hl.setSpacing(true); | |||
VerticalLayout vl = new VerticalLayout(); | |||
vl.setSpacing(true); | |||
// Add scroll buttons | |||
Button scrollUpButton = new Button("Top", new ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
grid.scrollToStart(); | |||
} | |||
}); | |||
scrollUpButton.setSizeFull(); | |||
vl.addComponent(scrollUpButton); | |||
for (int i = 1; i < 7; ++i) { | |||
final int row = (ds.size() / 7) * i; | |||
Button scrollButton = new Button("Scroll to row " + row, | |||
new ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
grid.scrollToItem(Integer.valueOf(row), | |||
ScrollDestination.MIDDLE); | |||
} | |||
}); | |||
scrollButton.setSizeFull(); | |||
vl.addComponent(scrollButton); | |||
} | |||
Button scrollDownButton = new Button("Bottom", new ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
grid.scrollToEnd(); | |||
} | |||
}); | |||
scrollDownButton.setSizeFull(); | |||
vl.addComponent(scrollDownButton); | |||
hl.addComponent(vl); | |||
addComponent(hl); | |||
} | |||
@Override | |||
protected String getTestDescription() { | |||
return "Test Grid programmatic scrolling features"; | |||
} | |||
@Override | |||
protected Integer getTicketNumber() { | |||
return 13327; | |||
} | |||
} |
@@ -16,8 +16,8 @@ | |||
package com.vaadin.tests.widgetset.client.grid; | |||
import com.vaadin.client.ui.AbstractComponentConnector; | |||
import com.vaadin.client.ui.grid.ScrollDestination; | |||
import com.vaadin.shared.ui.Connect; | |||
import com.vaadin.shared.ui.grid.ScrollDestination; | |||
import com.vaadin.tests.widgetset.server.grid.TestGrid; | |||
/** |
@@ -10,7 +10,7 @@ import com.vaadin.client.ui.grid.Escalator; | |||
import com.vaadin.client.ui.grid.EscalatorUpdater; | |||
import com.vaadin.client.ui.grid.Row; | |||
import com.vaadin.client.ui.grid.RowContainer; | |||
import com.vaadin.client.ui.grid.ScrollDestination; | |||
import com.vaadin.shared.ui.grid.ScrollDestination; | |||
public class VTestGrid extends Composite { | |||
@@ -174,20 +174,12 @@ public class VTestGrid extends Composite { | |||
public void scrollToRow(final int index, | |||
final ScrollDestination destination, final int padding) { | |||
if (padding != 0) { | |||
escalator.scrollToRow(index, destination, padding); | |||
} else { | |||
escalator.scrollToRow(index, destination); | |||
} | |||
escalator.scrollToRow(index, destination, padding); | |||
} | |||
public void scrollToColumn(final int index, | |||
final ScrollDestination destination, final int padding) { | |||
if (padding != 0) { | |||
escalator.scrollToColumn(index, destination, padding); | |||
} else { | |||
escalator.scrollToColumn(index, destination); | |||
} | |||
escalator.scrollToColumn(index, destination, padding); | |||
} | |||
public void removeRows(final int offset, final int amount) { |