Expose ProgressBar looked-up color variables

This commit is contained in:
mkpaz 2022-09-12 16:31:48 +04:00
parent 27b43246ef
commit 0a0949af66
3 changed files with 157 additions and 3 deletions

@ -4,11 +4,17 @@ package atlantafx.sampler.page.components;
import atlantafx.base.theme.Styles;
import atlantafx.sampler.page.AbstractPage;
import atlantafx.sampler.page.SampleBlock;
import atlantafx.sampler.theme.CSSFragment;
import javafx.concurrent.Task;
import javafx.css.PseudoClass;
import javafx.geometry.Pos;
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.text.Text;
@ -31,7 +37,8 @@ public class ProgressPage extends AbstractPage {
userContent.getChildren().addAll(
basicBarSamples().getRoot(),
basicIndicatorSamples().getRoot(),
barSizeSamples().getRoot()
barSizeSamples().getRoot(),
colorChangeSample().getRoot()
);
}
@ -73,6 +80,91 @@ public class ProgressPage extends AbstractPage {
return new SampleBlock("Size", container);
}
private SampleBlock colorChangeSample() {
var stateSuccess = PseudoClass.getPseudoClass("state-success");
var stateDanger = PseudoClass.getPseudoClass("state-danger");
var width = 400;
var bar = new ProgressBar(0);
bar.getStyleClass().add(Styles.LARGE);
bar.setPrefWidth(width);
bar.setMaxWidth(width);
var barText = new Label();
var barStack = new StackPane(bar, barText);
barStack.getStyleClass().add("example");
barStack.setPrefWidth(width);
barStack.setMaxWidth(width);
var runBtn = new Button("Start");
runBtn.disableProperty().bind(bar.progressProperty().greaterThan(0));
// ~
var content = new VBox(10);
content.getChildren().setAll(barStack, runBtn);
content.setAlignment(Pos.CENTER_LEFT);
bar.progressProperty().addListener((obs, old, val) -> {
if (val == null) { return; }
if (val.floatValue() > 0.80) {
barStack.pseudoClassStateChanged(stateDanger, true);
} else if (val.floatValue() > 0.47) {
barStack.pseudoClassStateChanged(stateSuccess, true);
}
});
new CSSFragment("""
.example:state-success .progress-bar {
-color-progress-bar-fill: -color-success-emphasis;
}
.example:state-danger .progress-bar {
-color-progress-bar-fill: -color-danger-emphasis;
}
.example:state-success .label,
.example:state-danger .label {
-fx-text-fill: -color-fg-emphasis;
}
""").addTo(content);
runBtn.setOnAction(e1 -> {
var task = new Task<Void>() {
@Override
protected Void call() throws Exception {
int steps = 1_000;
for (int i = 0; i < steps; i++) {
Thread.sleep(10);
updateProgress(i, steps);
updateMessage(String.valueOf(i));
}
return null;
}
};
// reset properties, so we can start a new task
task.setOnSucceeded(e2 -> {
bar.progressProperty().unbind();
barText.textProperty().unbind();
bar.setProgress(0);
barText.setText(null);
barStack.pseudoClassStateChanged(stateSuccess, false);
barStack.pseudoClassStateChanged(stateDanger, false);
});
bar.progressProperty().bind(task.progressProperty());
barText.textProperty().bind(task.messageProperty());
new Thread(task).start();
});
return new SampleBlock("Live color change", content);
}
private ProgressIndicator progressBar(double progress, boolean disabled, String... styleClasses) {
var bar = new ProgressBar(progress);
bar.getStyleClass().addAll(styleClasses);

@ -0,0 +1,56 @@
/* SPDX-License-Identifier: MIT */
package atlantafx.sampler.theme;
import javafx.scene.layout.Region;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Objects;
public final class CSSFragment {
private static final String DATA_URI_PREFIX = "data:base64,";
private final String css;
public CSSFragment(String css) {
this.css = Objects.requireNonNull(css);
}
public void addTo(Region region) {
Objects.requireNonNull(region);
region.getStylesheets().add(toDataURI());
}
public void removeFrom(Region region) {
Objects.requireNonNull(region);
region.getStyleClass().remove(toDataURI());
}
public boolean existsIn(Region region) {
Objects.requireNonNull(region);
return region.getStyleClass().contains(toDataURI());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CSSFragment cssFragment = (CSSFragment) o;
return css.equals(cssFragment.css);
}
@Override
public int hashCode() {
return Objects.hash(css);
}
@Override
public String toString() {
return css;
}
public String toDataURI() {
return DATA_URI_PREFIX + new String(Base64.getEncoder().encode(css.getBytes()), StandardCharsets.UTF_8);
}
}

@ -7,6 +7,9 @@
// ProgressBar //
///////////////////////////////////////////////////////////////////////////////
$progress-bar-track-color: -color-bg-subtle !default;
$progress-bar-fill-color: -color-accent-emphasis !default;
$size: (
"small": 2px,
"medium": 0.4em,
@ -15,19 +18,22 @@ $size: (
.progress-bar {
-color-progress-bar-track: $progress-bar-track-color;
-color-progress-bar-fill: $progress-bar-fill-color;
-fx-indeterminate-bar-length: 60;
-fx-indeterminate-bar-escape: true;
-fx-indeterminate-bar-flip: true;
-fx-indeterminate-bar-animation-time: 2;
>.track {
-fx-background-color: -color-bg-subtle;
-fx-background-color: -color-progress-bar-track;
-fx-background-insets: 0;
-fx-background-radius: cfg.$border-radius;
}
>.bar {
-fx-background-color: -color-accent-emphasis;
-fx-background-color: -color-progress-bar-fill;
-fx-background-insets: 0;
-fx-background-radius: cfg.$border-radius;
-fx-padding: map-get($size, "medium");