aboutsummaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorHenrik Paul <henrik@vaadin.com>2013-11-11 15:04:45 +0200
committerHenrik Paul <henrik@vaadin.com>2013-11-11 15:04:45 +0200
commitd060b01d3cc34620a12fcc9b858f5956680f7e07 (patch)
treecf8b6919f785c7a449331612ee32e066c830e142 /client
parentecb954092f2bb3e3b2c5b1acfc7447993ed84468 (diff)
downloadvaadin-framework-d060b01d3cc34620a12fcc9b858f5956680f7e07.tar.gz
vaadin-framework-d060b01d3cc34620a12fcc9b858f5956680f7e07.zip
Add scrollToRow/Column, also some final declarations (#12645)
Change-Id: I4142edff9bc078c35ee70643fc3368bec10003f9
Diffstat (limited to 'client')
-rw-r--r--client/src/com/vaadin/client/ui/grid/Escalator.java107
-rw-r--r--client/src/com/vaadin/client/ui/grid/ScrollDestination.java81
2 files changed, 166 insertions, 22 deletions
diff --git a/client/src/com/vaadin/client/ui/grid/Escalator.java b/client/src/com/vaadin/client/ui/grid/Escalator.java
index a67b701683..051203ecb6 100644
--- a/client/src/com/vaadin/client/ui/grid/Escalator.java
+++ b/client/src/com/vaadin/client/ui/grid/Escalator.java
@@ -211,6 +211,10 @@ public class Escalator extends Widget {
* escalator DOM). NOTE: these bits can most often also be identified by
* searching for code that call scrollElem.getScrollTop();.
*/
+ /*
+ * [[frozencol]]: This needs to be re-inspected once frozen columns are
+ * being implemented.
+ */
private static final int ROW_HEIGHT_PX = 20;
private static final int COLUMN_WIDTH_PX = 100;
@@ -432,6 +436,54 @@ public class Escalator extends Widget {
element.detachEvent("onmousewheel", this.@com.vaadin.client.ui.grid.JsniWorkaround::mousewheelListenerFunction);
}
}-*/;
+
+ public void scrollToColumn(final int columnIndex,
+ final ScrollDestination destination, final int padding) {
+ // TODO [[colwidth]]
+ final int targetStartPx = COLUMN_WIDTH_PX * columnIndex;
+ final int targetEndPx = targetStartPx + COLUMN_WIDTH_PX;
+
+ /*
+ * TODO [[frozencol]]: offset startPx by the pixels occupied by
+ * frozen columns.
+ */
+ final int viewportStartPx = getScrollLeft();
+ int viewportEndPx = viewportStartPx + getElement().getOffsetWidth();
+ if (needsVerticalScrollbars()) {
+ viewportEndPx -= Util.getNativeScrollbarSize();
+ }
+
+ final double scrollLeft = destination.getScrollPos(targetStartPx,
+ targetEndPx, viewportStartPx, viewportEndPx, padding);
+
+ /*
+ * note that it doesn't matter if the scroll would go beyond the
+ * content, since the browser will adjust for that, and everything
+ * fall into line accordingly.
+ */
+ setScrollLeft((int) scrollLeft);
+ }
+
+ public void scrollToRow(final int rowIndex,
+ final ScrollDestination destination, final int padding) {
+ // TODO [[rowheight]]
+ final int targetStartPx = ROW_HEIGHT_PX * rowIndex;
+ final int targetEndPx = targetStartPx + ROW_HEIGHT_PX;
+
+ final double viewportStartPx = getScrollTop();
+ final double viewportEndPx = viewportStartPx
+ + body.calculateHeight();
+
+ final double scrollTop = destination.getScrollPos(targetStartPx,
+ targetEndPx, viewportStartPx, viewportEndPx, padding);
+
+ /*
+ * note that it doesn't matter if the scroll would go beyond the
+ * content, since the browser will adjust for that, and everything
+ * falls into line accordingly.
+ */
+ setScrollTop(scrollTop);
+ }
}
private static class CellImpl implements Cell {
@@ -2100,12 +2152,17 @@ public class Escalator extends Widget {
* @throws IndexOutOfBoundsException
* if {@code columnIndex} is not a valid index for an existing
* column
+ * @throws IllegalArgumentException
+ * if {@code columnIndex} indicates a column that is set to be
+ * frozen
*/
public void scrollToColumn(final int columnIndex,
final ScrollDestination destination)
throws IndexOutOfBoundsException {
- // FIXME [[escalator]]
- throw new UnsupportedOperationException("Not implemented yet");
+ // TODO [[frozencol]] throw IAE if frozen
+ verifyValidColumnIndex(columnIndex);
+
+ scroller.scrollToColumn(columnIndex, destination, 0);
}
/**
@@ -2126,13 +2183,31 @@ public class Escalator extends Widget {
* @throws IllegalArgumentException
* if {@code destination} is {@link ScrollDestination#MIDDLE},
* because having a padding on a centered column is undefined
- * behavior.
+ * behavior
+ * @throws IllegalArgumentException
+ * if {@code columnIndex} indicates a column that is set to be
+ * frozen
*/
public void scrollToColumn(final int columnIndex,
final ScrollDestination destination, final int padding)
throws IndexOutOfBoundsException, IllegalArgumentException {
- // FIXME [[escalator]]
- throw new UnsupportedOperationException("Not implemented yet");
+ // TODO [[frozencol]] throw IAE if frozen
+ if (destination == ScrollDestination.MIDDLE) {
+ throw new IllegalArgumentException(
+ "You cannot have a padding with a MIDDLE destination");
+ }
+ verifyValidColumnIndex(columnIndex);
+
+ scroller.scrollToColumn(columnIndex, destination, padding);
+ }
+
+ private void verifyValidColumnIndex(final int columnIndex)
+ throws IndexOutOfBoundsException {
+ if (columnIndex < 0
+ || columnIndex >= columnConfiguration.getColumnCount()) {
+ throw new IndexOutOfBoundsException("The given column index "
+ + columnIndex + " does not exist.");
+ }
}
/**
@@ -2150,8 +2225,9 @@ public class Escalator extends Widget {
public void scrollToRow(final int rowIndex,
final ScrollDestination destination)
throws IndexOutOfBoundsException {
- // FIXME [[escalator]]
- throw new UnsupportedOperationException("Not implemented yet");
+ verifyValidRowIndex(rowIndex);
+
+ scroller.scrollToRow(rowIndex, destination, 0);
}
/**
@@ -2161,7 +2237,6 @@ public class Escalator extends Widget {
*
* @param rowIndex
* the index of the logical row to scroll to
- *
* @param destination
* where the row should be aligned visually after scrolling
* @param padding
@@ -2177,8 +2252,20 @@ public class Escalator extends Widget {
public void scrollToRow(final int rowIndex,
final ScrollDestination destination, final int padding)
throws IndexOutOfBoundsException, IllegalArgumentException {
- // FIXME [[escalator]]
- throw new UnsupportedOperationException("Not implemented yet");
+ if (destination == ScrollDestination.MIDDLE) {
+ throw new IllegalArgumentException(
+ "You cannot have a padding with a MIDDLE destination");
+ }
+ verifyValidRowIndex(rowIndex);
+
+ scroller.scrollToRow(rowIndex, destination, padding);
+ }
+
+ private void verifyValidRowIndex(final int rowIndex) {
+ if (rowIndex < 0 || rowIndex >= body.getRowCount()) {
+ throw new IndexOutOfBoundsException("The given row index "
+ + rowIndex + " does not exist.");
+ }
}
private void recalculateElementSizes() {
diff --git a/client/src/com/vaadin/client/ui/grid/ScrollDestination.java b/client/src/com/vaadin/client/ui/grid/ScrollDestination.java
index 8910216ac9..e14f50ff7c 100644
--- a/client/src/com/vaadin/client/ui/grid/ScrollDestination.java
+++ b/client/src/com/vaadin/client/ui/grid/ScrollDestination.java
@@ -23,23 +23,80 @@ package com.vaadin.client.ui.grid;
* @author Vaadin Ltd
*/
public enum ScrollDestination {
+
/**
- * "scrollIntoView" i.e. 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.
+ * 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,
+ 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 view port.
+ * Scrolls so that the element is shown at the start of the viewport. The
+ * viewport will, however, not scroll beyond its contents.
*/
- START,
+ 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 view port.
+ * 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,
+ 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 view port.
+ * Scrolls so that the element is shown at the end of the viewport. The
+ * viewport will, however, not scroll before its first element.
*/
- END
-} \ No newline at end of file
+ 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);
+}