mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-04-19 17:16:53 -04:00
Add CheckState icon to check detail view
This commit is contained in:
@@ -3,6 +3,7 @@ package org.cryptomator.ui.health;
|
||||
import com.tobiasdiez.easybind.EasyBind;
|
||||
import com.tobiasdiez.easybind.EasyObservableList;
|
||||
import com.tobiasdiez.easybind.Subscription;
|
||||
import com.tobiasdiez.easybind.optional.ObservableOptionalValue;
|
||||
import com.tobiasdiez.easybind.optional.OptionalBinding;
|
||||
import org.cryptomator.cryptofs.health.api.DiagnosticResult;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
@@ -21,6 +22,7 @@ import java.util.stream.Stream;
|
||||
public class CheckDetailController implements FxController {
|
||||
|
||||
private final EasyObservableList<Result> results;
|
||||
private final ObjectProperty<Check> check;
|
||||
private final OptionalBinding<Check.CheckState> checkState;
|
||||
private final Binding<String> checkName;
|
||||
private final Binding<Boolean> checkRunning;
|
||||
@@ -34,6 +36,7 @@ public class CheckDetailController implements FxController {
|
||||
private final Binding<Number> countOfCritSeverity;
|
||||
private final ResultListCellFactory resultListCellFactory;
|
||||
|
||||
public CheckStateIconView checkStateIconView;
|
||||
public ListView<Result> resultsListView;
|
||||
private Subscription resultSubscription;
|
||||
|
||||
@@ -41,6 +44,7 @@ public class CheckDetailController implements FxController {
|
||||
public CheckDetailController(ObjectProperty<Check> selectedTask, ResultListCellFactory resultListCellFactory) {
|
||||
this.resultListCellFactory = resultListCellFactory;
|
||||
this.results = EasyBind.wrapList(FXCollections.observableArrayList());
|
||||
this.check = selectedTask;
|
||||
this.checkState = EasyBind.wrapNullable(selectedTask).mapObservable(Check::stateProperty);
|
||||
this.checkName = EasyBind.wrapNullable(selectedTask).map(Check::getLocalizedName).orElse("");
|
||||
this.checkRunning = checkState.map(Check.CheckState.RUNNING::equals).orElse(false);
|
||||
@@ -156,4 +160,11 @@ public class CheckDetailController implements FxController {
|
||||
return checkCancelled;
|
||||
}
|
||||
|
||||
public ObjectProperty<Check> checkProperty() {
|
||||
return check;
|
||||
}
|
||||
|
||||
public Check getCheck() {
|
||||
return check.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
package org.cryptomator.ui.health;
|
||||
|
||||
import com.tobiasdiez.easybind.EasyBind;
|
||||
import org.cryptomator.cryptofs.health.api.DiagnosticResult;
|
||||
import org.cryptomator.ui.controls.FontAwesome5Icon;
|
||||
import org.cryptomator.ui.controls.FontAwesome5IconView;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
@@ -15,7 +10,7 @@ import javafx.scene.layout.StackPane;
|
||||
|
||||
class CheckListCell extends ListCell<Check> {
|
||||
|
||||
private final FontAwesome5IconView stateIcon = new FontAwesome5IconView();
|
||||
private final CheckStateIconView stateIcon = new CheckStateIconView();
|
||||
private CheckBox checkBox = new CheckBox();
|
||||
private final StackPane graphicContainer = new StackPane(stateIcon, checkBox);
|
||||
|
||||
@@ -27,11 +22,6 @@ class CheckListCell extends ListCell<Check> {
|
||||
graphicContainer.minWidth(20);
|
||||
graphicContainer.maxWidth(20);
|
||||
graphicContainer.setAlignment(Pos.CENTER);
|
||||
|
||||
EasyBind.includeWhen(stateIcon.getStyleClass(), "glyph-icon-muted", stateIcon.glyphProperty().isEqualTo(FontAwesome5Icon.INFO_CIRCLE));
|
||||
EasyBind.includeWhen(stateIcon.getStyleClass(), "glyph-icon-primary", stateIcon.glyphProperty().isEqualTo(FontAwesome5Icon.CHECK));
|
||||
EasyBind.includeWhen(stateIcon.getStyleClass(), "glyph-icon-orange", stateIcon.glyphProperty().isEqualTo(FontAwesome5Icon.EXCLAMATION_TRIANGLE));
|
||||
EasyBind.includeWhen(stateIcon.getStyleClass(), "glyph-icon-red", stateIcon.glyphProperty().isEqualTo(FontAwesome5Icon.TIMES));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,36 +30,19 @@ class CheckListCell extends ListCell<Check> {
|
||||
if (item != null) {
|
||||
setText(item.getLocalizedName());
|
||||
setGraphic(graphicContainer);
|
||||
stateIcon.setCheck(item);
|
||||
checkBox.visibleProperty().bind(Bindings.createBooleanBinding(() -> item.getState() == Check.CheckState.RUNNABLE, item.stateProperty()));
|
||||
stateIcon.visibleProperty().bind(Bindings.createBooleanBinding(() -> item.getState() != Check.CheckState.RUNNABLE, item.stateProperty()));
|
||||
stateIcon.glyphProperty().bind(Bindings.createObjectBinding(() -> glyphForState(item), item.stateProperty(), item.highestResultSeverityProperty()));
|
||||
checkBox.selectedProperty().bindBidirectional(item.chosenForExecutionProperty());
|
||||
} else {
|
||||
graphicProperty();
|
||||
checkBox.visibleProperty().unbind();
|
||||
stateIcon.visibleProperty().unbind();
|
||||
stateIcon.setCheck(null);
|
||||
setGraphic(null);
|
||||
setText(null);
|
||||
checkBox.selectedProperty().unbind();
|
||||
}
|
||||
}
|
||||
|
||||
private FontAwesome5Icon glyphForState(Check item) {
|
||||
return switch (item.getState()) {
|
||||
case RUNNABLE -> null;
|
||||
case SKIPPED -> FontAwesome5Icon.FAST_FORWARD;
|
||||
case SCHEDULED -> FontAwesome5Icon.CLOCK;
|
||||
case RUNNING -> FontAwesome5Icon.SPINNER;
|
||||
case ERROR -> FontAwesome5Icon.TIMES;
|
||||
case CANCELLED -> FontAwesome5Icon.BAN;
|
||||
case SUCCEEDED -> {
|
||||
if (item.getHighestResultSeverity() == DiagnosticResult.Severity.INFO || item.getHighestResultSeverity() == DiagnosticResult.Severity.GOOD) {
|
||||
yield FontAwesome5Icon.CHECK;
|
||||
} else {
|
||||
yield FontAwesome5Icon.EXCLAMATION_TRIANGLE;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.cryptomator.ui.health;
|
||||
|
||||
import com.tobiasdiez.easybind.EasyBind;
|
||||
import com.tobiasdiez.easybind.optional.OptionalBinding;
|
||||
import org.cryptomator.cryptofs.health.api.DiagnosticResult;
|
||||
import org.cryptomator.ui.controls.FontAwesome5Icon;
|
||||
import org.cryptomator.ui.controls.FontAwesome5IconView;
|
||||
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CheckStateIconView extends FontAwesome5IconView {
|
||||
|
||||
private final ObjectProperty<Check> check = new SimpleObjectProperty<>();
|
||||
private final OptionalBinding<Check.CheckState> state;
|
||||
private final OptionalBinding<DiagnosticResult.Severity> severity;
|
||||
|
||||
public CheckStateIconView() {
|
||||
super();
|
||||
this.getStyleClass().remove("glyph-icon");
|
||||
this.state = EasyBind.wrapNullable(check).mapObservable(Check::stateProperty);
|
||||
this.severity = EasyBind.wrapNullable(check).mapObservable(Check::highestResultSeverityProperty);
|
||||
glyphProperty().bind(EasyBind.combine(state, severity, this::glyphForState));
|
||||
EasyBind.includeWhen(getStyleClass(), "glyph-icon-muted", glyphProperty().isEqualTo(FontAwesome5Icon.INFO_CIRCLE));
|
||||
EasyBind.includeWhen(getStyleClass(), "glyph-icon-primary", glyphProperty().isEqualTo(FontAwesome5Icon.CHECK));
|
||||
EasyBind.includeWhen(getStyleClass(), "glyph-icon-orange", glyphProperty().isEqualTo(FontAwesome5Icon.EXCLAMATION_TRIANGLE));
|
||||
EasyBind.includeWhen(getStyleClass(), "glyph-icon-red", glyphProperty().isEqualTo(FontAwesome5Icon.TIMES));
|
||||
}
|
||||
|
||||
private FontAwesome5Icon glyphForState(Optional<Check.CheckState> state, Optional<DiagnosticResult.Severity> severity) {
|
||||
return state.map(s -> switch (s) {
|
||||
case RUNNABLE -> null;
|
||||
case SKIPPED -> FontAwesome5Icon.FAST_FORWARD;
|
||||
case SCHEDULED -> FontAwesome5Icon.CLOCK;
|
||||
case RUNNING -> FontAwesome5Icon.SPINNER;
|
||||
case ERROR -> FontAwesome5Icon.TIMES;
|
||||
case CANCELLED -> FontAwesome5Icon.BAN;
|
||||
case SUCCEEDED -> severity.map(se -> DiagnosticResult.Severity.GOOD.compareTo(se) >= 0 ? FontAwesome5Icon.CHECK : FontAwesome5Icon.EXCLAMATION_TRIANGLE).orElse(null);
|
||||
}).orElse(null);
|
||||
}
|
||||
|
||||
public ObjectProperty<Check> checkProperty() {
|
||||
return check;
|
||||
}
|
||||
|
||||
public void setCheck(Check c) {
|
||||
check.set(c);
|
||||
}
|
||||
|
||||
public Check getCheck() {
|
||||
return check.get();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,12 +4,17 @@
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import org.cryptomator.ui.health.CheckStateIconView?>
|
||||
<VBox xmlns:fx="http://javafx.com/fxml"
|
||||
xmlns="http://javafx.com/javafx"
|
||||
fx:controller="org.cryptomator.ui.health.CheckDetailController"
|
||||
prefWidth="500"
|
||||
spacing="6">
|
||||
<FormattedLabel fx:id="checkTitle" styleClass="label-large" format="%health.check.detail.header" arg1="${controller.checkName}"/>
|
||||
<FormattedLabel fx:id="checkTitle" styleClass="label-large" format="%health.check.detail.header" arg1="${controller.checkName}" contentDisplay="LEFT">
|
||||
<graphic>
|
||||
<CheckStateIconView fx:id="checkStateIconView" check="${controller.check}" glyphSize="20"/>
|
||||
</graphic>
|
||||
</FormattedLabel>
|
||||
|
||||
<Label text="%health.check.detail.checkRunning" visible="${controller.checkRunning}" managed="${controller.checkRunning}"/>
|
||||
<Label text="%health.check.detail.checkScheduled" visible="${controller.checkScheduled}" managed="${controller.checkScheduled}"/>
|
||||
@@ -19,6 +24,6 @@
|
||||
<Label text="%health.check.detail.checkSucceeded" visible="${controller.checkSucceeded}" managed="${controller.checkSucceeded}"/>
|
||||
|
||||
<FormattedLabel styleClass="label" format="%health.check.detail.problemCount" arg1="${controller.countOfWarnSeverity}" arg2="${controller.countOfCritSeverity}" visible="${!controller.checkSkipped}"
|
||||
managed="${!controller.checkSkipped}" />
|
||||
managed="${!controller.checkSkipped}"/>
|
||||
<ListView fx:id="resultsListView" VBox.vgrow="ALWAYS" visible="${!controller.checkSkipped}"/>
|
||||
</VBox>
|
||||
Reference in New Issue
Block a user