From 1abf0e1bfa2b22d15537ad569f714dfd78155746 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Fri, 21 May 2021 12:00:46 +0200 Subject: [PATCH] Replace result table by result list --- .../ui/health/CheckDetailController.java | 23 ++--- .../ui/health/HealthCheckModule.java | 4 + .../ui/health/ResultActionTableCell.java | 30 ------ .../cryptomator/ui/health/ResultListCell.java | 19 ---- .../ui/health/ResultListCellController.java | 93 +++++++++++++++++++ .../ui/health/ResultListCellFactory.java | 58 ++++++++++++ .../ui/health/ResultSeverityTableCell.java | 47 ---------- .../resources/fxml/health_check_details.fxml | 13 +-- .../fxml/health_result_listcell.fxml | 26 ++++++ 9 files changed, 191 insertions(+), 122 deletions(-) delete mode 100644 main/ui/src/main/java/org/cryptomator/ui/health/ResultActionTableCell.java delete mode 100644 main/ui/src/main/java/org/cryptomator/ui/health/ResultListCell.java create mode 100644 main/ui/src/main/java/org/cryptomator/ui/health/ResultListCellController.java create mode 100644 main/ui/src/main/java/org/cryptomator/ui/health/ResultListCellFactory.java delete mode 100644 main/ui/src/main/java/org/cryptomator/ui/health/ResultSeverityTableCell.java create mode 100644 main/ui/src/main/resources/fxml/health_result_listcell.fxml diff --git a/main/ui/src/main/java/org/cryptomator/ui/health/CheckDetailController.java b/main/ui/src/main/java/org/cryptomator/ui/health/CheckDetailController.java index 404268f8e..a285d3400 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/health/CheckDetailController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/health/CheckDetailController.java @@ -2,21 +2,17 @@ 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.common.FxController; import javax.inject.Inject; import javafx.beans.binding.Binding; import javafx.beans.binding.BooleanBinding; import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleObjectProperty; -import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.concurrent.Worker; import javafx.fxml.FXML; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; +import javafx.scene.control.ListView; public class CheckDetailController implements FxController { @@ -24,19 +20,18 @@ public class CheckDetailController implements FxController { private final OptionalBinding taskState; private final Binding taskName; private final Binding taskDescription; + private final ResultListCellFactory resultListCellFactory; private final BooleanBinding producingResults; - public TableView resultsTableView; - public TableColumn resultDescriptionColumn; - public TableColumn resultSeverityColumn; - public TableColumn resultActionColumn; + public ListView resultsListView; @Inject - public CheckDetailController(ObjectProperty selectedTask) { + public CheckDetailController(ObjectProperty selectedTask, ResultListCellFactory resultListCellFactory) { this.results = EasyBind.wrapNullable(selectedTask).map(HealthCheckTask::results).orElse(FXCollections.emptyObservableList()); this.taskState = EasyBind.wrapNullable(selectedTask).mapObservable(HealthCheckTask::stateProperty); this.taskName = EasyBind.wrapNullable(selectedTask).map(HealthCheckTask::getTitle).orElse(""); this.taskDescription = EasyBind.wrapNullable(selectedTask).map(task -> task.getCheck().toString()).orElse(""); + this.resultListCellFactory = resultListCellFactory; this.producingResults = taskState.filter(this::producesResults).isPresent(); } @@ -49,12 +44,8 @@ public class CheckDetailController implements FxController { @FXML public void initialize() { - resultsTableView.itemsProperty().bind(results); - resultDescriptionColumn.setCellValueFactory(cellFeatures -> new SimpleStringProperty(cellFeatures.getValue().getDescription())); - resultSeverityColumn.setCellValueFactory(cellFeatures -> new SimpleObjectProperty<>(cellFeatures.getValue().getSeverity())); - resultSeverityColumn.setCellFactory(column -> new ResultSeverityTableCell()); - resultActionColumn.setCellValueFactory(cellFeatures -> new SimpleObjectProperty<>(cellFeatures.getValue())); - resultActionColumn.setCellFactory(column -> new ResultActionTableCell()); + resultsListView.itemsProperty().bind(results); + resultsListView.setCellFactory(resultListCellFactory); } /* Getter/Setter */ diff --git a/main/ui/src/main/java/org/cryptomator/ui/health/HealthCheckModule.java b/main/ui/src/main/java/org/cryptomator/ui/health/HealthCheckModule.java index aafb5cb22..7ca3cbd05 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/health/HealthCheckModule.java +++ b/main/ui/src/main/java/org/cryptomator/ui/health/HealthCheckModule.java @@ -134,5 +134,9 @@ abstract class HealthCheckModule { @FxControllerKey(CheckDetailController.class) abstract FxController bindCheckDetailController(CheckDetailController controller); + @Binds + @IntoMap + @FxControllerKey(ResultListCellController.class) + abstract FxController bindResultListCellController(ResultListCellController controller); } diff --git a/main/ui/src/main/java/org/cryptomator/ui/health/ResultActionTableCell.java b/main/ui/src/main/java/org/cryptomator/ui/health/ResultActionTableCell.java deleted file mode 100644 index 5781e514b..000000000 --- a/main/ui/src/main/java/org/cryptomator/ui/health/ResultActionTableCell.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.cryptomator.ui.health; - -import javafx.geometry.Pos; -import javafx.scene.control.Button; -import javafx.scene.control.TableCell; - -class ResultActionTableCell extends TableCell { - - private Button button; - - ResultActionTableCell() { - button = new Button(); - setGraphic(null); - } - - @Override - protected void updateItem(Runnable item, boolean empty) { - super.updateItem(item, empty); - if (empty || item == null) { - setText(null); - setGraphic(null); - } else { - setGraphic(button); - button.setOnAction(event -> item.run()); - button.setText("FIXME"); //FIXME - button.setAlignment(Pos.CENTER); - } - } - -} diff --git a/main/ui/src/main/java/org/cryptomator/ui/health/ResultListCell.java b/main/ui/src/main/java/org/cryptomator/ui/health/ResultListCell.java deleted file mode 100644 index 6458b4ff4..000000000 --- a/main/ui/src/main/java/org/cryptomator/ui/health/ResultListCell.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.cryptomator.ui.health; - -import org.cryptomator.cryptofs.health.api.DiagnosticResult; -import org.cryptomator.cryptofs.health.api.HealthCheck; - -import javafx.scene.control.ListCell; - -class ResultListCell extends ListCell { - - @Override - protected void updateItem(DiagnosticResult item, boolean empty) { - super.updateItem(item, empty); - if (item != null) { - setText(item.toString()); - } else { - setText(null); - } - } -} diff --git a/main/ui/src/main/java/org/cryptomator/ui/health/ResultListCellController.java b/main/ui/src/main/java/org/cryptomator/ui/health/ResultListCellController.java new file mode 100644 index 000000000..03704824f --- /dev/null +++ b/main/ui/src/main/java/org/cryptomator/ui/health/ResultListCellController.java @@ -0,0 +1,93 @@ +package org.cryptomator.ui.health; + +import com.tobiasdiez.easybind.EasyBind; +import org.cryptomator.cryptofs.health.api.DiagnosticResult; +import org.cryptomator.ui.common.FxController; +import org.cryptomator.ui.controls.FontAwesome5Icon; +import org.cryptomator.ui.controls.FontAwesome5IconView; + +import javax.inject.Inject; +import javafx.beans.binding.Binding; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ObservableValue; +import javafx.fxml.FXML; + +public class ResultListCellController implements FxController { + + private final ObjectProperty result; + private final Binding fixButtonVisible; + private final Binding description; + + @FXML + public FontAwesome5IconView iconView; + + @Inject + public ResultListCellController() { + this.result = new SimpleObjectProperty<>(null); + this.fixButtonVisible = EasyBind.wrapNullable(result) // + .map(val -> val.getSeverity() == DiagnosticResult.Severity.WARN).orElse(true); // + this.description = EasyBind.wrapNullable(result).map(DiagnosticResultAction::getDescription).orElse(""); + result.addListener(this::getGlyphForSeverity); + } + + private void getGlyphForSeverity(ObservableValue observable, DiagnosticResultAction oldVal, DiagnosticResultAction newVal) { + iconView.getStyleClass().clear(); + switch (newVal.getSeverity()) { + case INFO -> { + iconView.setGlyph(FontAwesome5Icon.INFO_CIRCLE); + iconView.getStyleClass().add("glyph-icon-muted"); + } + case GOOD -> { + iconView.setGlyph(FontAwesome5Icon.CHECK); + iconView.getStyleClass().add("glyph-icon-primary"); + } + case WARN -> { + iconView.setGlyph(FontAwesome5Icon.EXCLAMATION_TRIANGLE); + iconView.getStyleClass().add("glyph-icon-orange"); + } + case CRITICAL -> { + iconView.setGlyph(FontAwesome5Icon.TIMES); + iconView.getStyleClass().add("glyph-icon-red"); + } + } + } + + @FXML + public void runResultAction() { + final var realResult = result.get(); + if (realResult != null) { + realResult.run(); //TODO: this hogs currently the JAVAFX thread + } + } + + /* Getter & Setter */ + + public DiagnosticResultAction getResult() { + return result.get(); + } + + public void setResult(DiagnosticResultAction result) { + this.result.set(result); + } + + public ObjectProperty resultProperty() { + return result; + } + + public boolean isFixButtonVisibile() { + return fixButtonVisible.getValue(); + } + + public Binding fixButtonVisibleProperty() { + return fixButtonVisible; + } + + public String getDescription() { + return description.getValue(); + } + + public Binding descriptionProperty() { + return description; + } +} diff --git a/main/ui/src/main/java/org/cryptomator/ui/health/ResultListCellFactory.java b/main/ui/src/main/java/org/cryptomator/ui/health/ResultListCellFactory.java new file mode 100644 index 000000000..11f0e0f6b --- /dev/null +++ b/main/ui/src/main/java/org/cryptomator/ui/health/ResultListCellFactory.java @@ -0,0 +1,58 @@ +package org.cryptomator.ui.health; + + +import org.cryptomator.ui.common.FxmlLoaderFactory; + +import javax.inject.Inject; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.control.ContentDisplay; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.util.Callback; +import java.io.IOException; +import java.io.UncheckedIOException; + +public class ResultListCellFactory implements Callback, ListCell> { + + private final FxmlLoaderFactory fxmlLoaders; + + @Inject + ResultListCellFactory(@HealthCheckWindow FxmlLoaderFactory fxmlLoaders) { + this.fxmlLoaders = fxmlLoaders; + } + + @Override + public ListCell call(ListView param) { + try { + FXMLLoader fxmlLoader = fxmlLoaders.load("/fxml/health_result_listcell.fxml"); + return new ResultListCellFactory.Cell(fxmlLoader.getRoot(), fxmlLoader.getController()); + } catch (IOException e) { + throw new UncheckedIOException("Failed to load /fxml/health_result_listcell.fxml.", e); + } + } + + private static class Cell extends ListCell { + + private final Parent node; + private final ResultListCellController controller; + + public Cell(Parent node, ResultListCellController controller) { + this.node = node; + this.controller = controller; + } + + @Override + protected void updateItem(DiagnosticResultAction item, boolean empty) { + super.updateItem(item, empty); + if (item == null || empty) { + setText(null); + setGraphic(null); + } else { + controller.setResult(item); + setContentDisplay(ContentDisplay.GRAPHIC_ONLY); + setGraphic(node); + } + } + } +} \ No newline at end of file diff --git a/main/ui/src/main/java/org/cryptomator/ui/health/ResultSeverityTableCell.java b/main/ui/src/main/java/org/cryptomator/ui/health/ResultSeverityTableCell.java deleted file mode 100644 index a5a7b04b2..000000000 --- a/main/ui/src/main/java/org/cryptomator/ui/health/ResultSeverityTableCell.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.cryptomator.ui.health; - -import org.cryptomator.cryptofs.health.api.DiagnosticResult; -import org.cryptomator.ui.controls.FontAwesome5Icon; -import org.cryptomator.ui.controls.FontAwesome5IconView; - -import javafx.scene.control.TableCell; - -public class ResultSeverityTableCell extends TableCell { - - private FontAwesome5IconView iconView; - - ResultSeverityTableCell() { - iconView = new FontAwesome5IconView(); - } - - @Override - protected void updateItem(DiagnosticResult.Severity item, boolean empty) { - super.updateItem(item, empty); - iconView.getStyleClass().clear(); - if (empty || item == null) { - setText(null); - setGraphic(null); - } else { - switch (item) { - case INFO -> { - iconView.setGlyph(FontAwesome5Icon.INFO_CIRCLE); - iconView.getStyleClass().add("glyph-icon-muted"); - } - case GOOD -> { - iconView.setGlyph(FontAwesome5Icon.CHECK); - iconView.getStyleClass().add("glyph-icon-primary"); - } - case WARN -> { - iconView.setGlyph(FontAwesome5Icon.EXCLAMATION_TRIANGLE); - iconView.getStyleClass().add("glyph-icon-orange"); - } - case CRITICAL -> { - iconView.setGlyph(FontAwesome5Icon.TIMES); - iconView.getStyleClass().add("glyph-icon-red"); - } - } - setGraphic(iconView); - setText(item.name()); - } - } -} diff --git a/main/ui/src/main/resources/fxml/health_check_details.fxml b/main/ui/src/main/resources/fxml/health_check_details.fxml index 6a539e4f2..7e553d7a4 100644 --- a/main/ui/src/main/resources/fxml/health_check_details.fxml +++ b/main/ui/src/main/resources/fxml/health_check_details.fxml @@ -1,21 +1,14 @@ - - + - \ No newline at end of file diff --git a/main/ui/src/main/resources/fxml/health_result_listcell.fxml b/main/ui/src/main/resources/fxml/health_result_listcell.fxml new file mode 100644 index 000000000..22e6569f3 --- /dev/null +++ b/main/ui/src/main/resources/fxml/health_result_listcell.fxml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + +