Skip to content

Commit

Permalink
Take padding into account when scrolling (#111)
Browse files Browse the repository at this point in the history
Otherwise last item in content isn't scrolled fully into view when using the scrollbar thumb.
  • Loading branch information
Jugen authored Aug 30, 2022
1 parent 3b45c92 commit a71ced6
Showing 1 changed file with 12 additions and 7 deletions.
19 changes: 12 additions & 7 deletions src/main/java/org/fxmisc/flowless/VirtualizedScrollPane.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
import javafx.beans.DefaultProperty;
import javafx.beans.NamedArg;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.value.ChangeListener;
import javafx.css.PseudoClass;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Region;
Expand All @@ -21,7 +20,7 @@
import org.reactfx.value.Var;

@DefaultProperty("content")
public class VirtualizedScrollPane<V extends Node & Virtualized> extends Region implements Virtualized {
public class VirtualizedScrollPane<V extends Region & Virtualized> extends Region implements Virtualized {

private static final PseudoClass CONTENT_FOCUSED = PseudoClass.getPseudoClass("content-focused");

Expand Down Expand Up @@ -84,12 +83,14 @@ public VirtualizedScrollPane(
hPosEstimate = Val.combine(
content.estimatedScrollXProperty(),
Val.map(content.layoutBoundsProperty(), Bounds::getWidth),
Val.map(content.paddingProperty(), p -> p.getLeft() + p.getRight()),
content.totalWidthEstimateProperty(),
VirtualizedScrollPane::offsetToScrollbarPosition)
.asVar(this::setHPosition);
vPosEstimate = Val.combine(
content.estimatedScrollYProperty(),
Val.map(content.layoutBoundsProperty(), Bounds::getHeight),
Val.map(content.paddingProperty(), p -> p.getTop() + p.getBottom()),
content.totalHeightEstimateProperty(),
VirtualizedScrollPane::offsetToScrollbarPosition)
.orElseConst(0.0)
Expand Down Expand Up @@ -320,17 +321,21 @@ protected void layoutChildren() {
}

private void setHPosition(double pos) {
Insets padding = content.getPadding();
double offset = scrollbarPositionToOffset(
pos,
content.getLayoutBounds().getWidth(),
padding.getLeft() + padding.getRight(),
content.totalWidthEstimateProperty().getValue());
content.estimatedScrollXProperty().setValue((double) Math.round(offset));
}

private void setVPosition(double pos) {
Insets padding = content.getPadding();
double offset = scrollbarPositionToOffset(
pos,
content.getLayoutBounds().getHeight(),
padding.getTop() + padding.getBottom(),
content.totalHeightEstimateProperty().getValue());
// offset needs rounding otherwise thin lines appear between cells,
// usually only visible when cells have dark backgrounds/borders.
Expand All @@ -353,16 +358,16 @@ protected double computeValue() {
}

private static double offsetToScrollbarPosition(
double contentOffset, double viewportSize, double contentSize) {
double contentOffset, double viewportSize, double padding, double contentSize) {
return contentSize > viewportSize
? contentOffset / (contentSize - viewportSize) * contentSize
? contentOffset / (contentSize - viewportSize + padding) * contentSize
: 0;
}

private static double scrollbarPositionToOffset(
double scrollbarPos, double viewportSize, double contentSize) {
double scrollbarPos, double viewportSize, double padding, double contentSize) {
return contentSize > viewportSize
? scrollbarPos / contentSize * (contentSize - viewportSize)
? scrollbarPos / contentSize * (contentSize - viewportSize + padding)
: 0;
}
}

0 comments on commit a71ced6

Please # to comment.