Add RingProgressIndicator control
This commit is contained in:
parent
2716cca2a0
commit
1c4c6a5232
85
base/src/main/java/atlantafx/base/controls/RingProgressIndicator.java
Executable file
85
base/src/main/java/atlantafx/base/controls/RingProgressIndicator.java
Executable file
@ -0,0 +1,85 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
package atlantafx.base.controls;
|
||||
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
import javafx.scene.control.Skin;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
public class RingProgressIndicator extends ProgressIndicator {
|
||||
|
||||
public RingProgressIndicator() { }
|
||||
|
||||
public RingProgressIndicator(double progress) {
|
||||
this(progress, false);
|
||||
}
|
||||
|
||||
public RingProgressIndicator(double progress, boolean reverse) {
|
||||
super(progress);
|
||||
this.reverse.set(reverse);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Skin<?> createDefaultSkin() {
|
||||
return new RingProgressIndicatorSkin(this);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Properties //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected final ObjectProperty<Node> graphic = new SimpleObjectProperty<>(this, "graphic", null);
|
||||
|
||||
public Node getGraphic() {
|
||||
return graphicProperty().get();
|
||||
}
|
||||
|
||||
public void setGraphic(Node graphic) {
|
||||
graphicProperty().set(graphic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Any node to be displayed within the progress indicator. If null,
|
||||
* it will fall back to the Label with integer progress value from 1 to 100.
|
||||
*/
|
||||
public ObjectProperty<Node> graphicProperty() {
|
||||
return graphic;
|
||||
}
|
||||
|
||||
// ~
|
||||
|
||||
protected final ObjectProperty<StringConverter<Double>> stringConverter = new SimpleObjectProperty<>(this, "converter", null);
|
||||
|
||||
public StringConverter<Double> getStringConverter() {
|
||||
return stringConverterProperty().get();
|
||||
}
|
||||
|
||||
public void setStringConverter(StringConverter<Double> stringConverter) {
|
||||
this.stringConverterProperty().set(stringConverter);
|
||||
}
|
||||
|
||||
/** Optional converter to transform progress value to string. */
|
||||
public ObjectProperty<StringConverter<Double>> stringConverterProperty() {
|
||||
return stringConverter;
|
||||
}
|
||||
|
||||
// ~
|
||||
|
||||
private final ReadOnlyBooleanWrapper reverse = new ReadOnlyBooleanWrapper(this, "reverse", false);
|
||||
|
||||
public boolean isReverse() {
|
||||
return reverse.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse progress indicator scale. For indeterminate variant
|
||||
* this means it will be rotated counterclockwise.
|
||||
*/
|
||||
public ReadOnlyBooleanProperty reverseProperty() {
|
||||
return reverse.getReadOnlyProperty();
|
||||
}
|
||||
}
|
261
base/src/main/java/atlantafx/base/controls/RingProgressIndicatorSkin.java
Executable file
261
base/src/main/java/atlantafx/base/controls/RingProgressIndicatorSkin.java
Executable file
@ -0,0 +1,261 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
package atlantafx.base.controls;
|
||||
|
||||
import javafx.animation.Animation;
|
||||
import javafx.animation.Interpolator;
|
||||
import javafx.animation.RotateTransition;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.value.WritableValue;
|
||||
import javafx.css.CssMetaData;
|
||||
import javafx.css.Styleable;
|
||||
import javafx.css.StyleableDoubleProperty;
|
||||
import javafx.css.StyleableProperty;
|
||||
import javafx.css.converter.SizeConverter;
|
||||
import javafx.scene.CacheHint;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.SkinBase;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Arc;
|
||||
import javafx.scene.shape.Circle;
|
||||
import javafx.util.Duration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class RingProgressIndicatorSkin extends SkinBase<RingProgressIndicator> {
|
||||
|
||||
protected static final double DEFAULT_ANIMATION_TIME = 3;
|
||||
|
||||
protected final StackPane container = new StackPane();
|
||||
protected final Circle trackCircle = new Circle();
|
||||
protected final Arc progressArc = new Arc();
|
||||
protected final Label progressLabel = new Label();
|
||||
protected final RotateTransition transition = new RotateTransition(
|
||||
Duration.seconds(DEFAULT_ANIMATION_TIME), progressArc
|
||||
);
|
||||
|
||||
public RingProgressIndicatorSkin(RingProgressIndicator indicator) {
|
||||
super(indicator);
|
||||
|
||||
trackCircle.getStyleClass().add("track");
|
||||
trackCircle.setManaged(false);
|
||||
trackCircle.setFill(Color.TRANSPARENT);
|
||||
|
||||
progressArc.getStyleClass().add("ring");
|
||||
progressArc.setManaged(false);
|
||||
progressArc.setStartAngle(90);
|
||||
progressArc.setLength(calcProgressArcLength());
|
||||
progressArc.setCache(true);
|
||||
progressArc.setCacheHint(CacheHint.ROTATE);
|
||||
progressArc.setFill(Color.TRANSPARENT);
|
||||
|
||||
transition.setAutoReverse(false);
|
||||
transition.setByAngle(-getMaxAngle());
|
||||
transition.setCycleCount(Animation.INDEFINITE);
|
||||
transition.setDelay(Duration.ZERO);
|
||||
transition.setInterpolator(Interpolator.LINEAR);
|
||||
|
||||
progressLabel.getStyleClass().add("progress");
|
||||
|
||||
container.getStyleClass().addAll("container");
|
||||
container.setMaxHeight(Region.USE_PREF_SIZE);
|
||||
container.setMaxWidth(Region.USE_PREF_SIZE);
|
||||
container.getChildren().addAll(trackCircle, progressArc);
|
||||
container.getChildren().add(indicator.getGraphic() != null ? indicator.getGraphic() : progressLabel);
|
||||
|
||||
indicator.getStyleClass().add("ring-progress-indicator");
|
||||
indicator.setMaxHeight(Region.USE_PREF_SIZE);
|
||||
indicator.setMaxWidth(Region.USE_PREF_SIZE);
|
||||
getChildren().add(container);
|
||||
|
||||
// == INIT LISTENERS ==
|
||||
|
||||
updateProgressLabel();
|
||||
toggleIndeterminate();
|
||||
|
||||
registerChangeListener(indicator.progressProperty(), e -> {
|
||||
updateProgressLabel();
|
||||
progressArc.setLength(calcProgressArcLength());
|
||||
});
|
||||
|
||||
registerChangeListener(indicator.indeterminateProperty(), e -> toggleIndeterminate());
|
||||
|
||||
registerChangeListener(indicator.visibleProperty(), e -> {
|
||||
if (indicator.isVisible() && indicator.isIndeterminate()) {
|
||||
transition.play();
|
||||
} else {
|
||||
transition.pause();
|
||||
}
|
||||
});
|
||||
|
||||
registerChangeListener(indeterminateAnimationTimeProperty(), e -> {
|
||||
transition.setDuration(Duration.seconds(getIndeterminateAnimationTime()));
|
||||
if (indicator.isIndeterminate()) {
|
||||
transition.playFromStart();
|
||||
}
|
||||
});
|
||||
|
||||
registerChangeListener(indicator.graphicProperty(), e -> {
|
||||
if (indicator.getGraphic() != null) {
|
||||
container.getChildren().remove(progressLabel);
|
||||
container.getChildren().add(indicator.getGraphic());
|
||||
} else {
|
||||
if (container.getChildren().size() > 1) {
|
||||
container.getChildren().remove(1);
|
||||
container.getChildren().add(progressLabel);
|
||||
updateProgressLabel();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private int getMaxAngle() {
|
||||
return getSkinnable().isReverse() ? 360 : -360;
|
||||
}
|
||||
|
||||
private double calcProgressArcLength() {
|
||||
var progress = getSkinnable().getProgress();
|
||||
return getSkinnable().isReverse() ? (1 - progress) * getMaxAngle() : progress * getMaxAngle();
|
||||
}
|
||||
|
||||
protected void updateProgressLabel() {
|
||||
var progress = getSkinnable().getProgress();
|
||||
|
||||
if (getSkinnable().getStringConverter() != null) {
|
||||
progressLabel.setText(getSkinnable().getStringConverter().toString(progress));
|
||||
return;
|
||||
}
|
||||
|
||||
if (progress >= 0) {
|
||||
progressLabel.setText((int) Math.ceil(progress * 100) + "%");
|
||||
}
|
||||
}
|
||||
|
||||
protected void toggleIndeterminate() {
|
||||
var indeterminate = getSkinnable().isIndeterminate();
|
||||
progressLabel.setManaged(!indeterminate);
|
||||
|
||||
if (indeterminate) {
|
||||
if (getSkinnable().isVisible()) {
|
||||
transition.play();
|
||||
}
|
||||
} else {
|
||||
progressArc.setRotate(0);
|
||||
transition.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void layoutChildren(double x, double y, double w, double h) {
|
||||
var size = Math.max(w, h);
|
||||
var radius = (size / 2) - (progressArc.getStrokeWidth() / 2);
|
||||
|
||||
trackCircle.setCenterX(size / 2);
|
||||
trackCircle.setCenterY(size / 2);
|
||||
trackCircle.setRadius(radius);
|
||||
|
||||
progressArc.setCenterX(size / 2);
|
||||
progressArc.setCenterY(size / 2);
|
||||
progressArc.setRadiusX(radius);
|
||||
progressArc.setRadiusY(radius);
|
||||
|
||||
container.resizeRelocate(x, y, size, size);
|
||||
}
|
||||
|
||||
// Control height is always equal to its width.
|
||||
@Override
|
||||
protected double computeMinHeight(double width, double topInset, double rightInset,
|
||||
double bottomInset, double leftInset) {
|
||||
return super.computeMinWidth(0, topInset, rightInset, bottomInset, leftInset);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double computePrefHeight(double width, double topInset, double rightInset,
|
||||
double bottomInset, double leftInset) {
|
||||
return super.computePrefWidth(0, topInset, rightInset, bottomInset, leftInset);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double computeMaxHeight(double width, double topInset, double rightInset,
|
||||
double bottomInset, double leftInset) {
|
||||
return super.computeMaxWidth(0, topInset, rightInset, bottomInset, leftInset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
transition.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
|
||||
return getClassCssMetaData();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Styleable Properties //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected DoubleProperty indeterminateAnimationTime = null;
|
||||
|
||||
private DoubleProperty indeterminateAnimationTimeProperty() {
|
||||
if (indeterminateAnimationTime == null) {
|
||||
indeterminateAnimationTime = new StyleableDoubleProperty(DEFAULT_ANIMATION_TIME) {
|
||||
|
||||
@Override
|
||||
public Object getBean() {
|
||||
return RingProgressIndicatorSkin.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "indeterminateAnimationTime";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CssMetaData<RingProgressIndicator, Number> getCssMetaData() {
|
||||
return StyleableProperties.INDETERMINATE_ANIMATION_TIME;
|
||||
}
|
||||
};
|
||||
}
|
||||
return indeterminateAnimationTime;
|
||||
}
|
||||
|
||||
public double getIndeterminateAnimationTime() {
|
||||
return indeterminateAnimationTime == null ? DEFAULT_ANIMATION_TIME : indeterminateAnimationTime.get();
|
||||
}
|
||||
|
||||
private static class StyleableProperties {
|
||||
|
||||
private static final CssMetaData<RingProgressIndicator, Number> INDETERMINATE_ANIMATION_TIME =
|
||||
new CssMetaData<>("-fx-indeterminate-animation-time", SizeConverter.getInstance(), DEFAULT_ANIMATION_TIME) {
|
||||
|
||||
@Override
|
||||
public boolean isSettable(RingProgressIndicator n) {
|
||||
return n.getSkin() instanceof RingProgressIndicatorSkin s &&
|
||||
(s.indeterminateAnimationTime == null || !s.indeterminateAnimationTime.isBound());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("RedundantCast")
|
||||
public StyleableProperty<Number> getStyleableProperty(RingProgressIndicator n) {
|
||||
final RingProgressIndicatorSkin skin = (RingProgressIndicatorSkin) n.getSkin();
|
||||
return (StyleableProperty<Number>) (WritableValue<Number>) skin.indeterminateAnimationTimeProperty();
|
||||
}
|
||||
};
|
||||
|
||||
private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
|
||||
|
||||
static {
|
||||
final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(SkinBase.getClassCssMetaData());
|
||||
styleables.add(INDETERMINATE_ANIMATION_TIME);
|
||||
STYLEABLES = Collections.unmodifiableList(styleables);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
|
||||
return RingProgressIndicatorSkin.StyleableProperties.STYLEABLES;
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
package atlantafx.sampler.page.components;
|
||||
|
||||
import atlantafx.base.controls.RingProgressIndicator;
|
||||
import atlantafx.sampler.page.AbstractPage;
|
||||
import atlantafx.sampler.page.Page;
|
||||
import atlantafx.sampler.page.SampleBlock;
|
||||
@ -12,11 +13,11 @@ import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
import javafx.scene.layout.FlowPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.StringConverter;
|
||||
import org.kordamp.ikonli.feather.Feather;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import static atlantafx.base.theme.Styles.*;
|
||||
import static atlantafx.sampler.page.SampleBlock.BLOCK_HGAP;
|
||||
@ -33,50 +34,111 @@ public class ProgressPage extends AbstractPage {
|
||||
|
||||
public ProgressPage() {
|
||||
super();
|
||||
setUserContent(new VBox(Page.PAGE_VGAP,
|
||||
expandingHBox(basicBarSample(), basicIndicatorSample()),
|
||||
expandingHBox(barSizeSample(), colorChangeSample())
|
||||
));
|
||||
|
||||
var grid = new GridPane();
|
||||
grid.setHgap(Page.PAGE_HGAP);
|
||||
grid.setVgap(Page.PAGE_VGAP);
|
||||
|
||||
grid.add(basicBarSample(), 0, 0);
|
||||
grid.add(basicIndicatorSample(), 1, 0);
|
||||
|
||||
grid.add(ringIndicatorSample(), 0, 1);
|
||||
grid.add(barSizeSample(), 1, 1);
|
||||
|
||||
grid.add(colorChangeSample(), 0, 2);
|
||||
|
||||
setUserContent(grid);
|
||||
}
|
||||
|
||||
private SampleBlock basicBarSample() {
|
||||
var flowPane = new FlowPane(
|
||||
BLOCK_HGAP, BLOCK_VGAP,
|
||||
createBar(0, false),
|
||||
createBar(0.5, false),
|
||||
createBar(1, false),
|
||||
createBar(0.5, true)
|
||||
);
|
||||
var flowPane = new FlowPane(BLOCK_HGAP, BLOCK_VGAP, createBar(0, false), createBar(0.5, false), createBar(1, false), createBar(0.5, true));
|
||||
flowPane.setAlignment(Pos.CENTER_LEFT);
|
||||
|
||||
return new SampleBlock("Progress Bar", flowPane);
|
||||
}
|
||||
|
||||
private SampleBlock basicIndicatorSample() {
|
||||
var flowPane = new FlowPane(
|
||||
BLOCK_HGAP, BLOCK_VGAP,
|
||||
createIndicator(0, false),
|
||||
createIndicator(0.5, false),
|
||||
createIndicator(1, false),
|
||||
createIndicator(0.5, true)
|
||||
);
|
||||
var flowPane = new FlowPane(BLOCK_HGAP, BLOCK_VGAP, createIndicator(0, false), createIndicator(0.5, false), createIndicator(1, false), createIndicator(0.5, true));
|
||||
flowPane.setAlignment(Pos.TOP_LEFT);
|
||||
|
||||
return new SampleBlock("Progress Indicator", flowPane);
|
||||
}
|
||||
|
||||
private SampleBlock barSizeSample() {
|
||||
var container = new VBox(
|
||||
BLOCK_VGAP,
|
||||
new HBox(20, createBar(0.5, false, SMALL), new Text("small")),
|
||||
new HBox(20, createBar(0.5, false, MEDIUM), new Text("medium")),
|
||||
new HBox(20, createBar(0.5, false, LARGE), new Text("large"))
|
||||
);
|
||||
var container = new VBox(BLOCK_VGAP, new HBox(20, createBar(0.5, false, SMALL), new Text("small")), new HBox(20, createBar(0.5, false, MEDIUM), new Text("medium")), new HBox(20, createBar(0.5, false, LARGE), new Text("large")));
|
||||
container.getChildren().forEach(c -> ((HBox) c).setAlignment(Pos.CENTER_LEFT));
|
||||
|
||||
return new SampleBlock("Size", container);
|
||||
}
|
||||
|
||||
private SampleBlock ringIndicatorSample() {
|
||||
var basicIndicator = new RingProgressIndicator(0, false);
|
||||
|
||||
var customTextIndicator = new RingProgressIndicator(0.5, false);
|
||||
customTextIndicator.setPrefSize(75, 75);
|
||||
customTextIndicator.setStringConverter(new StringConverter<>() {
|
||||
@Override
|
||||
public String toString(Double progress) {
|
||||
return (int) Math.ceil(progress * 100) + "°";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double fromString(String progress) {
|
||||
return 0d;
|
||||
}
|
||||
});
|
||||
|
||||
var reverseIndicator = new RingProgressIndicator(0.25, true);
|
||||
reverseIndicator.setPrefSize(150, 150);
|
||||
|
||||
var reverseIndicatorLabel = new Label("25%");
|
||||
reverseIndicatorLabel.getStyleClass().add(TITLE_4);
|
||||
|
||||
var reversePlayButton = new Button("", new FontIcon(Feather.PLAY));
|
||||
reversePlayButton.getStyleClass().addAll(BUTTON_CIRCLE, FLAT);
|
||||
reversePlayButton.disableProperty().bind(reverseIndicator.progressProperty().greaterThan(0.25));
|
||||
reversePlayButton.setOnAction(e1 -> {
|
||||
var task = new Task<Void>() {
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
int steps = 100;
|
||||
|
||||
for (int i = 25; i <= steps; i++) {
|
||||
Thread.sleep(100);
|
||||
updateProgress(i, steps);
|
||||
updateMessage(i + "%");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// reset properties, so we can start a new task
|
||||
task.setOnSucceeded(e2 -> {
|
||||
reverseIndicator.progressProperty().unbind();
|
||||
reverseIndicatorLabel.textProperty().unbind();
|
||||
|
||||
reverseIndicator.setProgress(0.25);
|
||||
reverseIndicatorLabel.setText("25%");
|
||||
});
|
||||
|
||||
reverseIndicator.progressProperty().bind(task.progressProperty());
|
||||
reverseIndicatorLabel.textProperty().bind(task.messageProperty());
|
||||
|
||||
new Thread(task).start();
|
||||
});
|
||||
|
||||
var reverseBox = new VBox(10, reverseIndicatorLabel, reversePlayButton);
|
||||
reverseBox.setAlignment(Pos.CENTER);
|
||||
reverseIndicator.setGraphic(reverseBox);
|
||||
|
||||
// ~
|
||||
|
||||
var box = new HBox(BLOCK_HGAP, basicIndicator, customTextIndicator, reverseIndicator);
|
||||
box.setAlignment(Pos.CENTER_LEFT);
|
||||
|
||||
return new SampleBlock("Ring Indicator", box);
|
||||
}
|
||||
|
||||
private SampleBlock colorChangeSample() {
|
||||
var stateSuccess = PseudoClass.getPseudoClass("state-success");
|
||||
var stateDanger = PseudoClass.getPseudoClass("state-danger");
|
||||
@ -124,8 +186,7 @@ public class ProgressPage extends AbstractPage {
|
||||
.example:state-danger .label {
|
||||
-fx-text-fill: -color-fg-emphasis;
|
||||
}
|
||||
"""
|
||||
).addTo(content);
|
||||
""").addTo(content);
|
||||
|
||||
runBtn.setOnAction(e1 -> {
|
||||
var task = new Task<Void>() {
|
||||
|
@ -10,6 +10,9 @@
|
||||
$color-bar-track: -color-bg-subtle !default;
|
||||
$color-bar-fill: -color-accent-emphasis !default;
|
||||
|
||||
$color-ring-indicator-track: -color-bg-subtle !default;
|
||||
$color-ring-indicator-fill: -color-accent-emphasis !default;
|
||||
|
||||
$size: (
|
||||
"small": 2px,
|
||||
"medium": 0.4em,
|
||||
@ -163,3 +166,40 @@ $size: (
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ring-progress-indicator {
|
||||
-fx-indeterminate-animation-time: 3;
|
||||
-color-progress-indicator-track: $color-ring-indicator-track;
|
||||
-color-progress-indicator-fill: $color-ring-indicator-fill;
|
||||
|
||||
>.container {
|
||||
// for extra small/large indicators you should also change the stroke width
|
||||
-fx-min-width: 4em;
|
||||
|
||||
>.track {
|
||||
-fx-stroke: -color-progress-indicator-track;
|
||||
-fx-stroke-width: 5px;
|
||||
}
|
||||
|
||||
>.ring {
|
||||
-fx-stroke: -color-progress-indicator-fill;
|
||||
-fx-stroke-width: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
&:indeterminate {
|
||||
>.container {
|
||||
// for extra small/large indicators you should also change the stroke width
|
||||
-fx-min-width: 1.5em;
|
||||
|
||||
>.track {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
>.ring {
|
||||
-fx-stroke: linear-gradient(-color-bg-default, -color-progress-indicator-fill);
|
||||
-fx-stroke-width: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user