modules/controls/src/main/java/javafx/scene/control/skin/ScrollBarSkin.java
Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization
*** 21,56 ****
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
! package com.sun.javafx.scene.control.skin;
import javafx.geometry.Orientation;
import javafx.geometry.Point2D;
import javafx.scene.AccessibleAction;
import javafx.scene.AccessibleAttribute;
import javafx.scene.AccessibleRole;
import javafx.scene.control.ScrollBar;
import javafx.scene.input.MouseButton;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.Node;
import com.sun.javafx.util.Utils;
import com.sun.javafx.scene.control.behavior.ScrollBarBehavior;
! public class ScrollBarSkin extends BehaviorSkinBase<ScrollBar, ScrollBarBehavior> {
/***************************************************************************
* *
! * UI Subcomponents *
* *
**************************************************************************/
! public final static int DEFAULT_LENGTH = 100;
! public final static int DEFAULT_WIDTH = 20;
private StackPane thumb;
private StackPane trackBackground;
private StackPane track;
private EndButton incButton;
--- 21,70 ----
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
! package javafx.scene.control.skin;
+ import com.sun.javafx.scene.control.Properties;
+ import com.sun.javafx.scene.control.behavior.BehaviorBase;
+ import javafx.beans.value.ObservableValue;
import javafx.geometry.Orientation;
import javafx.geometry.Point2D;
import javafx.scene.AccessibleAction;
import javafx.scene.AccessibleAttribute;
import javafx.scene.AccessibleRole;
+ import javafx.scene.control.Accordion;
+ import javafx.scene.control.Button;
+ import javafx.scene.control.Control;
import javafx.scene.control.ScrollBar;
+ import javafx.scene.control.SkinBase;
import javafx.scene.input.MouseButton;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.Node;
import com.sun.javafx.util.Utils;
import com.sun.javafx.scene.control.behavior.ScrollBarBehavior;
! import java.util.function.Consumer;
!
! /**
! * Default skin implementation for the {@link ScrollBar} control.
! *
! * @see ScrollBar
! * @since 9
! */
! public class ScrollBarSkin extends SkinBase<ScrollBar> {
/***************************************************************************
* *
! * Private fields *
* *
**************************************************************************/
! private final ScrollBarBehavior behavior;
private StackPane thumb;
private StackPane trackBackground;
private StackPane track;
private EndButton incButton;
*** 62,89 ****
private double preDragThumbPos;
private Point2D dragStart; // in the track's coord system
private double trackPos;
/***************************************************************************
* *
* Constructors *
* *
**************************************************************************/
! public ScrollBarSkin(ScrollBar scrollbar) {
! super(scrollbar, new ScrollBarBehavior(scrollbar));
initialize();
getSkinnable().requestLayout();
// Register listeners
! registerChangeListener(scrollbar.minProperty(), "MIN");
! registerChangeListener(scrollbar.maxProperty(), "MAX");
! registerChangeListener(scrollbar.valueProperty(), "VALUE");
! registerChangeListener(scrollbar.orientationProperty(), "ORIENTATION");
! registerChangeListener(scrollbar.visibleAmountProperty(), "VISIBLE_AMOUNT");
}
/**
* Initializes the ScrollBarSkin. Creates the scene and sets up all the
* bindings for the group.
*/
private void initialize() {
--- 76,321 ----
private double preDragThumbPos;
private Point2D dragStart; // in the track's coord system
private double trackPos;
+
+
/***************************************************************************
* *
* Constructors *
* *
**************************************************************************/
! /**
! * Creates a new ScrollBarSkin instance, installing the necessary child
! * nodes into the Control {@link Control#getChildren() children} list, as
! * well as the necessary input mappings for handling key, mouse, etc events.
! *
! * @param control The control that this skin should be installed onto.
! */
! public ScrollBarSkin(ScrollBar control) {
! super(control);
!
! // install default input map for the ScrollBar control
! this.behavior = new ScrollBarBehavior(control);
! // control.setInputMap(behavior.getInputMap());
!
initialize();
getSkinnable().requestLayout();
+
// Register listeners
! final Consumer<ObservableValue<?>> consumer = e -> {
! positionThumb();
! getSkinnable().requestLayout();
! };
! registerChangeListener(control.minProperty(), consumer);
! registerChangeListener(control.maxProperty(), consumer);
! registerChangeListener(control.visibleAmountProperty(), consumer);
! registerChangeListener(control.valueProperty(), e -> positionThumb());
! registerChangeListener(control.orientationProperty(), e -> getSkinnable().requestLayout());
! }
!
!
!
! /***************************************************************************
! * *
! * Public API *
! * *
! **************************************************************************/
!
! /** {@inheritDoc} */
! @Override public void dispose() {
! super.dispose();
!
! if (behavior != null) {
! behavior.dispose();
! }
! }
!
! /** {@inheritDoc} */
! @Override protected void layoutChildren(final double x, final double y,
! final double w, final double h) {
!
! final ScrollBar s = getSkinnable();
!
! /**
! * Compute the percentage length of thumb as (visibleAmount/range)
! * if max isn't greater than min then there is nothing to do here
! */
! double visiblePortion;
! if (s.getMax() > s.getMin()) {
! visiblePortion = s.getVisibleAmount()/(s.getMax() - s.getMin());
! }
! else {
! visiblePortion = 1.0;
! }
!
! if (s.getOrientation() == Orientation.VERTICAL) {
! if (!Properties.IS_TOUCH_SUPPORTED) {
! double decHeight = snapSize(decButton.prefHeight(-1));
! double incHeight = snapSize(incButton.prefHeight(-1));
!
! decButton.resize(w, decHeight);
! incButton.resize(w, incHeight);
!
! trackLength = snapSize(h - (decHeight + incHeight));
! thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
!
! trackBackground.resizeRelocate(snapPosition(x), snapPosition(y), w, trackLength+decHeight+incHeight);
! decButton.relocate(snapPosition(x), snapPosition(y));
! incButton.relocate(snapPosition(x), snapPosition(y + h - incHeight));
! track.resizeRelocate(snapPosition(x), snapPosition(y + decHeight), w, trackLength);
! thumb.resize(snapSize(x >= 0 ? w : w + x), thumbLength); // Account for negative padding (see also RT-10719)
! positionThumb();
! }
! else {
! trackLength = snapSize(h);
! thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
!
! track.resizeRelocate(snapPosition(x), snapPosition(y), w, trackLength);
! thumb.resize(snapSize(x >= 0 ? w : w + x), thumbLength); // Account for negative padding (see also RT-10719)
! positionThumb();
! }
! } else {
! if (!Properties.IS_TOUCH_SUPPORTED) {
! double decWidth = snapSize(decButton.prefWidth(-1));
! double incWidth = snapSize(incButton.prefWidth(-1));
!
! decButton.resize(decWidth, h);
! incButton.resize(incWidth, h);
!
! trackLength = snapSize(w - (decWidth + incWidth));
! thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
!
! trackBackground.resizeRelocate(snapPosition(x), snapPosition(y), trackLength+decWidth+incWidth, h);
! decButton.relocate(snapPosition(x), snapPosition(y));
! incButton.relocate(snapPosition(x + w - incWidth), snapPosition(y));
! track.resizeRelocate(snapPosition(x + decWidth), snapPosition(y), trackLength, h);
! thumb.resize(thumbLength, snapSize(y >= 0 ? h : h + y)); // Account for negative padding (see also RT-10719)
! positionThumb();
! }
! else {
! trackLength = snapSize(w);
! thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
!
! track.resizeRelocate(snapPosition(x), snapPosition(y), trackLength, h);
! thumb.resize(thumbLength, snapSize(y >= 0 ? h : h + y)); // Account for negative padding (see also RT-10719)
! positionThumb();
}
+ s.resize(snapSize(s.getWidth()), snapSize(s.getHeight()));
+ }
+
+ // things should be invisible only when well below minimum length
+ if (s.getOrientation() == Orientation.VERTICAL && h >= (computeMinHeight(-1, (int)y , snappedRightInset(), snappedBottomInset(), (int)x) - (y+snappedBottomInset())) ||
+ s.getOrientation() == Orientation.HORIZONTAL && w >= (computeMinWidth(-1, (int)y , snappedRightInset(), snappedBottomInset(), (int)x) - (x+snappedRightInset()))) {
+ trackBackground.setVisible(true);
+ track.setVisible(true);
+ thumb.setVisible(true);
+ if (!Properties.IS_TOUCH_SUPPORTED) {
+ incButton.setVisible(true);
+ decButton.setVisible(true);
+ }
+ }
+ else {
+ trackBackground.setVisible(false);
+ track.setVisible(false);
+ thumb.setVisible(false);
+
+ if (!Properties.IS_TOUCH_SUPPORTED) {
+ /*
+ ** once the space is big enough for one button we
+ ** can look at drawing
+ */
+ if (h >= decButton.computeMinWidth(-1)) {
+ decButton.setVisible(true);
+ }
+ else {
+ decButton.setVisible(false);
+ }
+ if (h >= incButton.computeMinWidth(-1)) {
+ incButton.setVisible(true);
+ }
+ else {
+ incButton.setVisible(false);
+ }
+ }
+ }
+ }
+
+ /*
+ * Minimum length is the length of the end buttons plus twice the
+ * minimum thumb length, which should be enough for a reasonably-sized
+ * track. Minimum breadth is determined by the breadths of the
+ * end buttons.
+ */
+ /** {@inheritDoc} */
+ @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+ if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
+ return getBreadth();
+ } else {
+ if (!Properties.IS_TOUCH_SUPPORTED) {
+ return decButton.minWidth(-1) + incButton.minWidth(-1) + minTrackLength()+leftInset+rightInset;
+ } else {
+ return minTrackLength()+leftInset+rightInset;
+ }
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+ if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
+ if (!Properties.IS_TOUCH_SUPPORTED) {
+ return decButton.minHeight(-1) + incButton.minHeight(-1) + minTrackLength()+topInset+bottomInset;
+ } else {
+ return minTrackLength()+topInset+bottomInset;
+ }
+ } else {
+ return getBreadth();
+ }
+ }
+
+ /*
+ * Preferred size. The breadth is determined by the breadth of
+ * the end buttons. The length is a constant default length.
+ * Usually applications or other components will either set a
+ * specific length using LayoutInfo or will stretch the length
+ * of the scrollbar to fit a container.
+ */
+ /** {@inheritDoc} */
+ @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+ final ScrollBar s = getSkinnable();
+ return s.getOrientation() == Orientation.VERTICAL ? getBreadth() : Properties.DEFAULT_LENGTH+leftInset+rightInset;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected double computePrefHeight(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+ final ScrollBar s = getSkinnable();
+ return s.getOrientation() == Orientation.VERTICAL ? Properties.DEFAULT_LENGTH+topInset+bottomInset : getBreadth();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
+ final ScrollBar s = getSkinnable();
+ return s.getOrientation() == Orientation.VERTICAL ? s.prefWidth(-1) : Double.MAX_VALUE;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
+ final ScrollBar s = getSkinnable();
+ return s.getOrientation() == Orientation.VERTICAL ? Double.MAX_VALUE : s.prefHeight(-1);
+ }
+
+
+
+ /***************************************************************************
+ * *
+ * Private implementation *
+ * *
+ **************************************************************************/
+
/**
* Initializes the ScrollBarSkin. Creates the scene and sets up all the
* bindings for the group.
*/
private void initialize() {
*** 105,115 ****
};
thumb.getStyleClass().setAll("thumb");
thumb.setAccessibleRole(AccessibleRole.THUMB);
! if (!IS_TOUCH_SUPPORTED) {
incButton = new EndButton("increment-button", "increment-arrow") {
@Override
public void executeAccessibleAction(AccessibleAction action, Object... parameters) {
switch (action) {
--- 337,347 ----
};
thumb.getStyleClass().setAll("thumb");
thumb.setAccessibleRole(AccessibleRole.THUMB);
! if (!Properties.IS_TOUCH_SUPPORTED) {
incButton = new EndButton("increment-button", "increment-arrow") {
@Override
public void executeAccessibleAction(AccessibleAction action, Object... parameters) {
switch (action) {
*** 124,143 ****
incButton.setOnMousePressed(me -> {
/*
** if the tracklenght isn't greater than do nothing....
*/
if (!thumb.isVisible() || trackLength > thumbLength) {
! getBehavior().incButtonPressed();
}
me.consume();
});
incButton.setOnMouseReleased(me -> {
/*
** if the tracklenght isn't greater than do nothing....
*/
if (!thumb.isVisible() || trackLength > thumbLength) {
! getBehavior().incButtonReleased();
}
me.consume();
});
decButton = new EndButton("decrement-button", "decrement-arrow") {
--- 356,375 ----
incButton.setOnMousePressed(me -> {
/*
** if the tracklenght isn't greater than do nothing....
*/
if (!thumb.isVisible() || trackLength > thumbLength) {
! behavior.incButtonPressed();
}
me.consume();
});
incButton.setOnMouseReleased(me -> {
/*
** if the tracklenght isn't greater than do nothing....
*/
if (!thumb.isVisible() || trackLength > thumbLength) {
! behavior.incButtonReleased();
}
me.consume();
});
decButton = new EndButton("decrement-button", "decrement-arrow") {
*** 155,198 ****
decButton.setOnMousePressed(me -> {
/*
** if the tracklenght isn't greater than do nothing....
*/
if (!thumb.isVisible() || trackLength > thumbLength) {
! getBehavior().decButtonPressed();
}
me.consume();
});
decButton.setOnMouseReleased(me -> {
/*
** if the tracklenght isn't greater than do nothing....
*/
if (!thumb.isVisible() || trackLength > thumbLength) {
! getBehavior().decButtonReleased();
}
me.consume();
});
}
track.setOnMousePressed(me -> {
if (!thumb.isPressed() && me.getButton() == MouseButton.PRIMARY) {
if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
if (trackLength != 0) {
! getBehavior().trackPress(me.getY() / trackLength);
me.consume();
}
} else {
if (trackLength != 0) {
! getBehavior().trackPress(me.getX() / trackLength);
me.consume();
}
}
}
});
track.setOnMouseReleased(me -> {
! getBehavior().trackRelease();
me.consume();
});
thumb.setOnMousePressed(me -> {
if (me.isSynthesized()) {
--- 387,430 ----
decButton.setOnMousePressed(me -> {
/*
** if the tracklenght isn't greater than do nothing....
*/
if (!thumb.isVisible() || trackLength > thumbLength) {
! behavior.decButtonPressed();
}
me.consume();
});
decButton.setOnMouseReleased(me -> {
/*
** if the tracklenght isn't greater than do nothing....
*/
if (!thumb.isVisible() || trackLength > thumbLength) {
! behavior.decButtonReleased();
}
me.consume();
});
}
track.setOnMousePressed(me -> {
if (!thumb.isPressed() && me.getButton() == MouseButton.PRIMARY) {
if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
if (trackLength != 0) {
! behavior.trackPress(me.getY() / trackLength);
me.consume();
}
} else {
if (trackLength != 0) {
! behavior.trackPress(me.getX() / trackLength);
me.consume();
}
}
}
});
track.setOnMouseReleased(me -> {
! behavior.trackRelease();
me.consume();
});
thumb.setOnMousePressed(me -> {
if (me.isSynthesized()) {
*** 230,240 ****
if (dragStart == null) {
// we're getting dragged without getting a mouse press
dragStart = thumb.localToParent(me.getX(), me.getY());
}
double dragPos = getSkinnable().getOrientation() == Orientation.VERTICAL ? cur.getY() - dragStart.getY(): cur.getX() - dragStart.getX();
! getBehavior().thumbDragged(preDragThumbPos + dragPos / (trackLength - thumbLength));
}
me.consume();
}
});
--- 462,472 ----
if (dragStart == null) {
// we're getting dragged without getting a mouse press
dragStart = thumb.localToParent(me.getX(), me.getY());
}
double dragPos = getSkinnable().getOrientation() == Orientation.VERTICAL ? cur.getY() - dragStart.getY(): cur.getX() - dragStart.getX();
! behavior.thumbDragged(preDragThumbPos + dragPos / (trackLength - thumbLength));
}
me.consume();
}
});
*** 267,277 ****
if (dragStart == null) {
// we're getting dragged without getting a mouse press
dragStart = thumb.localToParent(event.getX(), event.getY());
}
double dragPos = getSkinnable().getOrientation() == Orientation.VERTICAL ? cur.getY() - dragStart.getY(): cur.getX() - dragStart.getX();
! getBehavior().thumbDragged(/*todo*/ preDragThumbPos + dragPos / (trackLength - thumbLength));
}
event.consume();
return;
}
--- 499,509 ----
if (dragStart == null) {
// we're getting dragged without getting a mouse press
dragStart = thumb.localToParent(event.getX(), event.getY());
}
double dragPos = getSkinnable().getOrientation() == Orientation.VERTICAL ? cur.getY() - dragStart.getY(): cur.getX() - dragStart.getX();
! behavior.thumbDragged(/*todo*/ preDragThumbPos + dragPos / (trackLength - thumbLength));
}
event.consume();
return;
}
*** 308,318 ****
* TODO: this fix causes RT-23406 ([ScrollBar, touch] Dragging scrollbar from the
* track on touchscreen causes flickering)
*/
if (event.isDirect()) {
if (trackLength > thumbLength) {
! getBehavior().thumbDragged((getSkinnable().getOrientation() == Orientation.VERTICAL ? event.getY(): event.getX()) / trackLength);
event.consume();
}
}
else {
if (delta > 0.0 && sb.getValue() > sb.getMin()) {
--- 540,550 ----
* TODO: this fix causes RT-23406 ([ScrollBar, touch] Dragging scrollbar from the
* track on touchscreen causes flickering)
*/
if (event.isDirect()) {
if (trackLength > thumbLength) {
! behavior.thumbDragged((getSkinnable().getOrientation() == Orientation.VERTICAL ? event.getY() : event.getX()) / trackLength);
event.consume();
}
}
else {
if (delta > 0.0 && sb.getValue() > sb.getMin()) {
*** 325,384 ****
}
}
});
getChildren().clear();
! if (!IS_TOUCH_SUPPORTED) {
getChildren().addAll(trackBackground, incButton, decButton, track, thumb);
}
else {
getChildren().addAll(track, thumb);
}
}
-
- @Override protected void handleControlPropertyChanged(String p) {
- super.handleControlPropertyChanged(p);
- if ("ORIENTATION".equals(p)) {
- getSkinnable().requestLayout();
- } else if ("MIN".equals(p) || "MAX".equals(p) || "VISIBLE_AMOUNT".equals(p)) {
- positionThumb();
- getSkinnable().requestLayout();
- } else if ("VALUE".equals(p)) {
- positionThumb();
- }
- }
-
- /***************************************************************************
- * *
- * Layout *
- * *
- **************************************************************************/
-
- private static final double DEFAULT_EMBEDDED_SB_BREADTH = 8.0;
-
/*
* Gets the breadth of the scrollbar. The "breadth" is the distance
* across the scrollbar, i.e. if vertical the width, otherwise the height.
* On desktop this is determined by the greater of the breadths of the end-buttons.
* Embedded doesn't have end-buttons, so currently we use a default breadth.
* We should change this when we get width/height css properties.
*/
double getBreadth() {
! if (!IS_TOUCH_SUPPORTED) {
if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
return Math.max(decButton.prefWidth(-1), incButton.prefWidth(-1)) +snappedLeftInset()+snappedRightInset();
} else {
return Math.max(decButton.prefHeight(-1), incButton.prefHeight(-1)) +snappedTopInset()+snappedBottomInset();
}
}
else {
if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
! return Math.max(DEFAULT_EMBEDDED_SB_BREADTH, DEFAULT_EMBEDDED_SB_BREADTH)+snappedLeftInset()+snappedRightInset();
} else {
! return Math.max(DEFAULT_EMBEDDED_SB_BREADTH, DEFAULT_EMBEDDED_SB_BREADTH)+snappedTopInset()+snappedBottomInset();
}
}
}
double minThumbLength() {
--- 557,595 ----
}
}
});
getChildren().clear();
! if (!Properties.IS_TOUCH_SUPPORTED) {
getChildren().addAll(trackBackground, incButton, decButton, track, thumb);
}
else {
getChildren().addAll(track, thumb);
}
}
/*
* Gets the breadth of the scrollbar. The "breadth" is the distance
* across the scrollbar, i.e. if vertical the width, otherwise the height.
* On desktop this is determined by the greater of the breadths of the end-buttons.
* Embedded doesn't have end-buttons, so currently we use a default breadth.
* We should change this when we get width/height css properties.
*/
double getBreadth() {
! if (!Properties.IS_TOUCH_SUPPORTED) {
if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
return Math.max(decButton.prefWidth(-1), incButton.prefWidth(-1)) +snappedLeftInset()+snappedRightInset();
} else {
return Math.max(decButton.prefHeight(-1), incButton.prefHeight(-1)) +snappedTopInset()+snappedBottomInset();
}
}
else {
if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
! return Math.max(Properties.DEFAULT_EMBEDDED_SB_BREADTH, Properties.DEFAULT_EMBEDDED_SB_BREADTH)+snappedLeftInset()+snappedRightInset();
} else {
! return Math.max(Properties.DEFAULT_EMBEDDED_SB_BREADTH, Properties.DEFAULT_EMBEDDED_SB_BREADTH)+snappedTopInset()+snappedBottomInset();
}
}
}
double minThumbLength() {
*** 387,462 ****
double minTrackLength() {
return 2.0f * getBreadth();
}
- /*
- * Minimum length is the length of the end buttons plus twice the
- * minimum thumb length, which should be enough for a reasonably-sized
- * track. Minimum breadth is determined by the breadths of the
- * end buttons.
- */
- @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
- if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
- return getBreadth();
- } else {
- if (!IS_TOUCH_SUPPORTED) {
- return decButton.minWidth(-1) + incButton.minWidth(-1) + minTrackLength()+leftInset+rightInset;
- } else {
- return minTrackLength()+leftInset+rightInset;
- }
- }
- }
-
- @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
- if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
- if (!IS_TOUCH_SUPPORTED) {
- return decButton.minHeight(-1) + incButton.minHeight(-1) + minTrackLength()+topInset+bottomInset;
- } else {
- return minTrackLength()+topInset+bottomInset;
- }
- } else {
- return getBreadth();
- }
- }
-
- /*
- * Preferred size. The breadth is determined by the breadth of
- * the end buttons. The length is a constant default length.
- * Usually applications or other components will either set a
- * specific length using LayoutInfo or will stretch the length
- * of the scrollbar to fit a container.
- */
- @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
- final ScrollBar s = getSkinnable();
- return s.getOrientation() == Orientation.VERTICAL ? getBreadth() : DEFAULT_LENGTH+leftInset+rightInset;
- }
-
- @Override protected double computePrefHeight(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
- final ScrollBar s = getSkinnable();
- return s.getOrientation() == Orientation.VERTICAL ? DEFAULT_LENGTH+topInset+bottomInset : getBreadth();
- }
-
- @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
- final ScrollBar s = getSkinnable();
- return s.getOrientation() == Orientation.VERTICAL ? s.prefWidth(-1) : Double.MAX_VALUE;
- }
-
- @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
- final ScrollBar s = getSkinnable();
- return s.getOrientation() == Orientation.VERTICAL ? Double.MAX_VALUE : s.prefHeight(-1);
- }
-
/**
* Called when ever either min, max or value changes, so thumb's layoutX, Y is recomputed.
*/
void positionThumb() {
ScrollBar s = getSkinnable();
double clampedValue = Utils.clamp(s.getMin(), s.getValue(), s.getMax());
trackPos = (s.getMax() - s.getMin() > 0) ? ((trackLength - thumbLength) * (clampedValue - s.getMin()) / (s.getMax() - s.getMin())) : (0.0F);
! if (!IS_TOUCH_SUPPORTED) {
if (s.getOrientation() == Orientation.VERTICAL) {
trackPos += decButton.prefHeight(-1);
} else {
trackPos += decButton.prefWidth(-1);
}
--- 598,616 ----
double minTrackLength() {
return 2.0f * getBreadth();
}
/**
* Called when ever either min, max or value changes, so thumb's layoutX, Y is recomputed.
*/
void positionThumb() {
ScrollBar s = getSkinnable();
double clampedValue = Utils.clamp(s.getMin(), s.getValue(), s.getMax());
trackPos = (s.getMax() - s.getMin() > 0) ? ((trackLength - thumbLength) * (clampedValue - s.getMin()) / (s.getMax() - s.getMin())) : (0.0F);
! if (!Properties.IS_TOUCH_SUPPORTED) {
if (s.getOrientation() == Orientation.VERTICAL) {
trackPos += decButton.prefHeight(-1);
} else {
trackPos += decButton.prefWidth(-1);
}
*** 464,600 ****
thumb.setTranslateX( snapPosition(s.getOrientation() == Orientation.VERTICAL ? snappedLeftInset() : trackPos + snappedLeftInset()));
thumb.setTranslateY( snapPosition(s.getOrientation() == Orientation.VERTICAL ? trackPos + snappedTopInset() : snappedTopInset()));
}
! @Override protected void layoutChildren(final double x, final double y,
! final double w, final double h) {
!
! final ScrollBar s = getSkinnable();
!
! /**
! * Compute the percentage length of thumb as (visibleAmount/range)
! * if max isn't greater than min then there is nothing to do here
! */
! double visiblePortion;
! if (s.getMax() > s.getMin()) {
! visiblePortion = s.getVisibleAmount()/(s.getMax() - s.getMin());
! }
! else {
! visiblePortion = 1.0;
! }
!
! if (s.getOrientation() == Orientation.VERTICAL) {
! if (!IS_TOUCH_SUPPORTED) {
! double decHeight = snapSize(decButton.prefHeight(-1));
! double incHeight = snapSize(incButton.prefHeight(-1));
!
! decButton.resize(w, decHeight);
! incButton.resize(w, incHeight);
!
! trackLength = snapSize(h - (decHeight + incHeight));
! thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
!
! trackBackground.resizeRelocate(snapPosition(x), snapPosition(y), w, trackLength+decHeight+incHeight);
! decButton.relocate(snapPosition(x), snapPosition(y));
! incButton.relocate(snapPosition(x), snapPosition(y + h - incHeight));
! track.resizeRelocate(snapPosition(x), snapPosition(y + decHeight), w, trackLength);
! thumb.resize(snapSize(x >= 0 ? w : w + x), thumbLength); // Account for negative padding (see also RT-10719)
! positionThumb();
! }
! else {
! trackLength = snapSize(h);
! thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
!
! track.resizeRelocate(snapPosition(x), snapPosition(y), w, trackLength);
! thumb.resize(snapSize(x >= 0 ? w : w + x), thumbLength); // Account for negative padding (see also RT-10719)
! positionThumb();
! }
! } else {
! if (!IS_TOUCH_SUPPORTED) {
! double decWidth = snapSize(decButton.prefWidth(-1));
! double incWidth = snapSize(incButton.prefWidth(-1));
!
! decButton.resize(decWidth, h);
! incButton.resize(incWidth, h);
!
! trackLength = snapSize(w - (decWidth + incWidth));
! thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
!
! trackBackground.resizeRelocate(snapPosition(x), snapPosition(y), trackLength+decWidth+incWidth, h);
! decButton.relocate(snapPosition(x), snapPosition(y));
! incButton.relocate(snapPosition(x + w - incWidth), snapPosition(y));
! track.resizeRelocate(snapPosition(x + decWidth), snapPosition(y), trackLength, h);
! thumb.resize(thumbLength, snapSize(y >= 0 ? h : h + y)); // Account for negative padding (see also RT-10719)
! positionThumb();
! }
! else {
! trackLength = snapSize(w);
! thumbLength = snapSize(Utils.clamp(minThumbLength(), (trackLength * visiblePortion), trackLength));
!
! track.resizeRelocate(snapPosition(x), snapPosition(y), trackLength, h);
! thumb.resize(thumbLength, snapSize(y >= 0 ? h : h + y)); // Account for negative padding (see also RT-10719)
! positionThumb();
! }
!
! s.resize(snapSize(s.getWidth()), snapSize(s.getHeight()));
! }
!
! // things should be invisible only when well below minimum length
! if (s.getOrientation() == Orientation.VERTICAL && h >= (computeMinHeight(-1, (int)y , snappedRightInset(), snappedBottomInset(), (int)x) - (y+snappedBottomInset())) ||
! s.getOrientation() == Orientation.HORIZONTAL && w >= (computeMinWidth(-1, (int)y , snappedRightInset(), snappedBottomInset(), (int)x) - (x+snappedRightInset()))) {
! trackBackground.setVisible(true);
! track.setVisible(true);
! thumb.setVisible(true);
! if (!IS_TOUCH_SUPPORTED) {
! incButton.setVisible(true);
! decButton.setVisible(true);
! }
! }
! else {
! trackBackground.setVisible(false);
! track.setVisible(false);
! thumb.setVisible(false);
!
! if (!IS_TOUCH_SUPPORTED) {
! /*
! ** once the space is big enough for one button we
! ** can look at drawing
! */
! if (h >= decButton.computeMinWidth(-1)) {
! decButton.setVisible(true);
! }
! else {
! decButton.setVisible(false);
! }
! if (h >= incButton.computeMinWidth(-1)) {
! incButton.setVisible(true);
! }
! else {
! incButton.setVisible(false);
! }
! }
! }
! }
!
!
! public Node getThumb() {
return thumb;
}
! public Node getTrack() {
return track;
}
! public Node getIncButton() {
return incButton;
}
! public Node getDecButton() {
return decButton;
}
private static class EndButton extends Region {
private Region arrow;
private EndButton(String styleClass, String arrowStyleClass) {
getStyleClass().setAll(styleClass);
--- 618,651 ----
thumb.setTranslateX( snapPosition(s.getOrientation() == Orientation.VERTICAL ? snappedLeftInset() : trackPos + snappedLeftInset()));
thumb.setTranslateY( snapPosition(s.getOrientation() == Orientation.VERTICAL ? trackPos + snappedTopInset() : snappedTopInset()));
}
! private Node getThumb() {
return thumb;
}
! private Node getTrack() {
return track;
}
! private Node getIncrementButton() {
return incButton;
}
! private Node getDecrementButton() {
return decButton;
}
+
+
+ /***************************************************************************
+ * *
+ * Support classes *
+ * *
+ **************************************************************************/
+
private static class EndButton extends Region {
private Region arrow;
private EndButton(String styleClass, String arrowStyleClass) {
getStyleClass().setAll(styleClass);