summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorHenrik Paul <henrik@vaadin.com>2015-03-23 15:35:26 +0200
committerVaadin Code Review <review@vaadin.com>2015-03-25 06:14:39 +0000
commit754caf060f1473f2367c421ecd70f3a8966f6f10 (patch)
treeff4b9a3d9c2bc805cc41bcbab20e2e7f0b2f8b99 /client
parent25bfb426866cd164d6e4780f35ff881ecdb7dd1e (diff)
downloadvaadin-framework-754caf060f1473f2367c421ecd70f3a8966f6f10.tar.gz
vaadin-framework-754caf060f1473f2367c421ecd70f3a8966f6f10.zip
Adds Escalator.scrollToSpacer (#17270)
Change-Id: Ib420e8da6c167fdba9d3023a73cb242643c7af67
Diffstat (limited to 'client')
-rw-r--r--client/src/com/vaadin/client/widgets/Escalator.java159
1 files changed, 119 insertions, 40 deletions
diff --git a/client/src/com/vaadin/client/widgets/Escalator.java b/client/src/com/vaadin/client/widgets/Escalator.java
index 75b797eb1f..87f19d2ded 100644
--- a/client/src/com/vaadin/client/widgets/Escalator.java
+++ b/client/src/com/vaadin/client/widgets/Escalator.java
@@ -827,8 +827,8 @@ public class Escalator extends Widget implements RequiresResize,
boolean verticalScrollNeeded = scrollContentHeight > tableWrapperHeight
+ WidgetUtil.PIXEL_EPSILON
- - header.heightOfSection
- - footer.heightOfSection;
+ - header.getHeightOfSection()
+ - footer.getHeightOfSection();
boolean horizontalScrollNeeded = scrollContentWidth > tableWrapperWidth
+ WidgetUtil.PIXEL_EPSILON;
@@ -837,8 +837,8 @@ public class Escalator extends Widget implements RequiresResize,
if (!verticalScrollNeeded && horizontalScrollNeeded) {
verticalScrollNeeded = scrollContentHeight > tableWrapperHeight
+ WidgetUtil.PIXEL_EPSILON
- - header.heightOfSection
- - footer.heightOfSection
+ - header.getHeightOfSection()
+ - footer.getHeightOfSection()
- horizontalScrollbar.getScrollbarThickness();
} else {
horizontalScrollNeeded = scrollContentWidth > tableWrapperWidth
@@ -860,8 +860,10 @@ public class Escalator extends Widget implements RequiresResize,
tableWrapper.getStyle().setHeight(tableWrapperHeight, Unit.PX);
tableWrapper.getStyle().setWidth(tableWrapperWidth, Unit.PX);
+ double footerHeight = footer.getHeightOfSection();
+ double headerHeight = header.getHeightOfSection();
double vScrollbarHeight = Math.max(0, tableWrapperHeight
- - footer.heightOfSection - header.heightOfSection);
+ - footerHeight - headerHeight);
verticalScrollbar.setOffsetSize(vScrollbarHeight);
verticalScrollbar.setScrollSize(scrollContentHeight);
@@ -1158,7 +1160,7 @@ public class Escalator extends Widget implements RequiresResize,
final double viewportStartPx = getScrollTop();
final double viewportEndPx = viewportStartPx
- + body.calculateHeight();
+ + body.getHeightOfSection();
final double scrollTop = getScrollPos(destination, targetStartPx,
targetEndPx, viewportStartPx, viewportEndPx, padding);
@@ -1183,9 +1185,6 @@ public class Escalator extends Widget implements RequiresResize,
*/
protected final TableSectionElement root;
- /** The height of the combined rows in the DOM. Never negative. */
- protected double heightOfSection = 0;
-
/**
* The primary style name of the escalator. Most commonly provided by
* Escalator as "v-escalator".
@@ -2097,10 +2096,24 @@ public class Escalator extends Widget implements RequiresResize,
refreshCells(rowRange, colRange);
}
}
+
+ /**
+ * The height of this table section.
+ * <p>
+ * Note that {@link Escalator#getBody() the body} will calculate its
+ * height, while the others will return a precomputed value.
+ *
+ * @return the height of this table section
+ */
+ protected abstract double getHeightOfSection();
}
private abstract class AbstractStaticRowContainer extends
AbstractRowContainer {
+
+ /** The height of the combined rows in the DOM. Never negative. */
+ private double heightOfSection = 0;
+
public AbstractStaticRowContainer(final TableSectionElement headElement) {
super(headElement);
}
@@ -2194,7 +2207,8 @@ public class Escalator extends Widget implements RequiresResize,
* indices are calculated from the scrollbar position.
*/
verticalScrollbar.setOffsetSize(heightOfEscalator
- - header.heightOfSection - footer.heightOfSection);
+ - header.getHeightOfSection()
+ - footer.getHeightOfSection());
body.verifyEscalatorCount();
}
@@ -2246,6 +2260,11 @@ public class Escalator extends Widget implements RequiresResize,
assert root.isOrHasChild(tr) : "Row does not belong to this table section";
return true;
}
+
+ @Override
+ protected double getHeightOfSection() {
+ return Math.max(0, heightOfSection);
+ }
}
private class HeaderRowContainer extends AbstractStaticRowContainer {
@@ -2255,10 +2274,10 @@ public class Escalator extends Widget implements RequiresResize,
@Override
protected void sectionHeightCalculated() {
- bodyElem.getStyle().setMarginTop(heightOfSection, Unit.PX);
+ bodyElem.getStyle().setMarginTop(getHeightOfSection(), Unit.PX);
verticalScrollbar.getElement().getStyle()
- .setTop(heightOfSection, Unit.PX);
- headerDeco.getStyle().setHeight(heightOfSection, Unit.PX);
+ .setTop(getHeightOfSection(), Unit.PX);
+ headerDeco.getStyle().setHeight(getHeightOfSection(), Unit.PX);
}
@Override
@@ -2291,8 +2310,10 @@ public class Escalator extends Widget implements RequiresResize,
@Override
protected void sectionHeightCalculated() {
+ double headerHeight = header.getHeightOfSection();
+ double footerHeight = footer.getHeightOfSection();
int vscrollHeight = (int) Math.floor(heightOfEscalator
- - header.heightOfSection - footer.heightOfSection);
+ - headerHeight - footerHeight);
final boolean horizontalScrollbarNeeded = columnConfiguration
.calculateRowWidth() > widthOfEscalator;
@@ -2300,7 +2321,8 @@ public class Escalator extends Widget implements RequiresResize,
vscrollHeight -= horizontalScrollbar.getScrollbarThickness();
}
- footerDeco.getStyle().setHeight(footer.heightOfSection, Unit.PX);
+ footerDeco.getStyle().setHeight(footer.getHeightOfSection(),
+ Unit.PX);
verticalScrollbar.setOffsetSize(vscrollHeight);
}
@@ -2633,7 +2655,7 @@ public class Escalator extends Widget implements RequiresResize,
* getDefaultRowHeight() < getScrollTop();
final boolean addedRowsBelowCurrentViewport = index
* getDefaultRowHeight() > getScrollTop()
- + calculateHeight();
+ + getHeightOfSection();
if (addedRowsAboveCurrentViewport) {
/*
@@ -2917,7 +2939,7 @@ public class Escalator extends Widget implements RequiresResize,
private int getMaxEscalatorRowCapacity() {
final int maxEscalatorRowCapacity = (int) Math
- .ceil(calculateHeight() / getDefaultRowHeight()) + 1;
+ .ceil(getHeightOfSection() / getDefaultRowHeight()) + 1;
/*
* maxEscalatorRowCapacity can become negative if the headers and
@@ -3087,7 +3109,7 @@ public class Escalator extends Widget implements RequiresResize,
final double contentBottom = getRowCount()
* getDefaultRowHeight();
final double viewportBottom = tBodyScrollTop
- + calculateHeight();
+ + getHeightOfSection();
if (viewportBottom <= contentBottom) {
/*
* We're in the middle of the row container, everything
@@ -3219,7 +3241,7 @@ public class Escalator extends Widget implements RequiresResize,
* 5 5
*/
final double newScrollTop = contentBottom
- - calculateHeight();
+ - getHeightOfSection();
setScrollTop(newScrollTop);
/*
* Manually call the scroll handler, so we get immediate
@@ -3406,15 +3428,14 @@ public class Escalator extends Widget implements RequiresResize,
return "td";
}
- /**
- * Calculates the height of the {@code <tbody>} as it should be rendered
- * in the DOM.
- */
- private double calculateHeight() {
+ @Override
+ protected double getHeightOfSection() {
final int tableHeight = tableWrapper.getOffsetHeight();
- final double footerHeight = footer.heightOfSection;
- final double headerHeight = header.heightOfSection;
- return tableHeight - footerHeight - headerHeight;
+ final double footerHeight = footer.getHeightOfSection();
+ final double headerHeight = header.getHeightOfSection();
+
+ double heightOfSection = tableHeight - footerHeight - headerHeight;
+ return Math.max(0, heightOfSection);
}
@Override
@@ -3862,9 +3883,14 @@ public class Escalator extends Widget implements RequiresResize,
return visualRowOrder.contains(tr);
}
- public void reapplySpacerWidths() {
+ void reapplySpacerWidths() {
spacerContainer.reapplySpacerWidths();
}
+
+ void scrollToSpacer(int spacerIndex, ScrollDestination destination,
+ int padding) {
+ spacerContainer.scrollToSpacer(spacerIndex, destination, padding);
+ }
}
private class ColumnConfigurationImpl implements ColumnConfiguration {
@@ -4723,6 +4749,32 @@ public class Escalator extends Widget implements RequiresResize,
}
}
+ @SuppressWarnings("boxing")
+ void scrollToSpacer(int spacerIndex, ScrollDestination destination,
+ int padding) {
+
+ assert !destination.equals(ScrollDestination.MIDDLE)
+ || padding != 0 : "destination/padding check should be done before this method";
+
+ if (!rowIndexToSpacer.containsKey(spacerIndex)) {
+ throw new IllegalArgumentException("No spacer open at index "
+ + spacerIndex);
+ }
+
+ SpacerImpl spacer = rowIndexToSpacer.get(spacerIndex);
+ double targetStartPx = spacer.getTop();
+ double targetEndPx = targetStartPx + spacer.getHeight();
+
+ Range viewportPixels = getViewportPixels();
+ double viewportStartPx = viewportPixels.getStart();
+ double viewportEndPx = viewportPixels.getEnd();
+
+ double scrollTop = getScrollPos(destination, targetStartPx,
+ targetEndPx, viewportStartPx, viewportEndPx, padding);
+
+ setScrollTop(scrollTop);
+ }
+
public void reapplySpacerWidths() {
for (SpacerImpl spacer : rowIndexToSpacer.values()) {
spacer.getRootElement().getStyle()
@@ -5812,10 +5864,7 @@ public class Escalator extends Widget implements RequiresResize,
public void scrollToColumn(final int columnIndex,
final ScrollDestination destination, final int padding)
throws IndexOutOfBoundsException, IllegalArgumentException {
- if (destination == ScrollDestination.MIDDLE && padding != 0) {
- throw new IllegalArgumentException(
- "You cannot have a padding with a MIDDLE destination");
- }
+ validateScrollDestination(destination, padding);
verifyValidColumnIndex(columnIndex);
if (columnIndex < columnConfiguration.frozenColumns) {
@@ -5856,10 +5905,7 @@ public class Escalator extends Widget implements RequiresResize,
public void scrollToRow(final int rowIndex,
final ScrollDestination destination, final int padding)
throws IndexOutOfBoundsException, IllegalArgumentException {
- if (destination == ScrollDestination.MIDDLE && padding != 0) {
- throw new IllegalArgumentException(
- "You cannot have a padding with a MIDDLE destination");
- }
+ validateScrollDestination(destination, padding);
verifyValidRowIndex(rowIndex);
scroller.scrollToRow(rowIndex, destination, padding);
@@ -5873,6 +5919,39 @@ public class Escalator extends Widget implements RequiresResize,
}
/**
+ * Scrolls the body vertically so that the spacer at the given row index is
+ * visible and there is at least {@literal padding} pixesl to the given
+ * scroll destination
+ *
+ * @since
+ * @param spacerIndex
+ * the row index of the spacer to scroll to
+ * @param destination
+ * where the spacer should be aligned visually after scrolling
+ * @param padding
+ * the number of pixels to place between the scrolled-to spacer
+ * and the viewport edge
+ * @throws IllegalArgumentException
+ * if {@code spacerIndex} is not an opened spacer if
+ * {@code destination} is {@link ScrollDestination#MIDDLE} and
+ * padding is nonzero
+ */
+ public void scrollToSpacer(final int spacerIndex,
+ ScrollDestination destination, final int padding)
+ throws IllegalArgumentException {
+ validateScrollDestination(destination, padding);
+ body.scrollToSpacer(spacerIndex, destination, padding);
+ }
+
+ private static void validateScrollDestination(
+ final ScrollDestination destination, final int padding) {
+ if (destination == ScrollDestination.MIDDLE && padding != 0) {
+ throw new IllegalArgumentException(
+ "You cannot have a padding with a MIDDLE destination");
+ }
+ }
+
+ /**
* Recalculates the dimensions for all elements that require manual
* calculations. Also updates the dimension caches.
* <p>
@@ -6074,8 +6153,8 @@ public class Escalator extends Widget implements RequiresResize,
return;
}
- double headerHeight = header.heightOfSection;
- double footerHeight = footer.heightOfSection;
+ double headerHeight = header.getHeightOfSection();
+ double footerHeight = footer.getHeightOfSection();
double bodyHeight = body.getDefaultRowHeight() * heightByRows;
double scrollbar = horizontalScrollbar.showsScrollHandle() ? horizontalScrollbar
.getScrollbarThickness() : 0;
@@ -6271,8 +6350,8 @@ public class Escalator extends Widget implements RequiresResize,
private Range getViewportPixels() {
int from = (int) Math.floor(verticalScrollbar.getScrollPos());
- int to = (int) Math.ceil(body.heightOfSection);
- return Range.between(from, to);
+ int to = (int) body.getHeightOfSection();
+ return Range.withLength(from, to);
}
@Override