diff options
author | Henrik Paul <henrik@vaadin.com> | 2013-11-11 15:04:45 +0200 |
---|---|---|
committer | Henrik Paul <henrik@vaadin.com> | 2013-11-11 15:04:45 +0200 |
commit | d060b01d3cc34620a12fcc9b858f5956680f7e07 (patch) | |
tree | cf8b6919f785c7a449331612ee32e066c830e142 /client | |
parent | ecb954092f2bb3e3b2c5b1acfc7447993ed84468 (diff) | |
download | vaadin-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.java | 107 | ||||
-rw-r--r-- | client/src/com/vaadin/client/ui/grid/ScrollDestination.java | 81 |
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); +} |