소스 검색

Replace result table by result list

Armin Schrenk 4 년 전
부모
커밋
1abf0e1bfa

+ 7 - 16
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<Worker.State> taskState;
 	private final Binding<String> taskName;
 	private final Binding<String> taskDescription;
+	private final ResultListCellFactory resultListCellFactory;
 	private final BooleanBinding producingResults;
 
-	public TableView<DiagnosticResultAction> resultsTableView;
-	public TableColumn<DiagnosticResultAction, String> resultDescriptionColumn;
-	public TableColumn<DiagnosticResultAction, DiagnosticResult.Severity> resultSeverityColumn;
-	public TableColumn<DiagnosticResultAction, Runnable> resultActionColumn;
+	public ListView<DiagnosticResultAction> resultsListView;
 
 	@Inject
-	public CheckDetailController(ObjectProperty<HealthCheckTask> selectedTask) {
+	public CheckDetailController(ObjectProperty<HealthCheckTask> 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 */
 

+ 4 - 0
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);
 
 }

+ 0 - 30
main/ui/src/main/java/org/cryptomator/ui/health/ResultActionTableCell.java

@@ -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<DiagnosticResultAction, Runnable> {
-
-	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);
-		}
-	}
-
-}

+ 0 - 19
main/ui/src/main/java/org/cryptomator/ui/health/ResultListCell.java

@@ -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<DiagnosticResult> {
-
-	@Override
-	protected void updateItem(DiagnosticResult item, boolean empty) {
-		super.updateItem(item, empty);
-		if (item != null) {
-			setText(item.toString());
-		} else {
-			setText(null);
-		}
-	}
-}

+ 93 - 0
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<DiagnosticResultAction> result;
+	private final Binding<Boolean> fixButtonVisible;
+	private final Binding<String> 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<? extends DiagnosticResultAction> 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<DiagnosticResultAction> resultProperty() {
+		return result;
+	}
+
+	public boolean isFixButtonVisibile() {
+		return fixButtonVisible.getValue();
+	}
+
+	public Binding<Boolean> fixButtonVisibleProperty() {
+		return fixButtonVisible;
+	}
+
+	public String getDescription() {
+		return description.getValue();
+	}
+
+	public Binding<String> descriptionProperty() {
+		return description;
+	}
+}

+ 58 - 0
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<ListView<DiagnosticResultAction>, ListCell<DiagnosticResultAction>> {
+
+	private final FxmlLoaderFactory fxmlLoaders;
+
+	@Inject
+	ResultListCellFactory(@HealthCheckWindow FxmlLoaderFactory fxmlLoaders) {
+		this.fxmlLoaders = fxmlLoaders;
+	}
+
+	@Override
+	public ListCell<DiagnosticResultAction> call(ListView<DiagnosticResultAction> 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<DiagnosticResultAction> {
+
+		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);
+			}
+		}
+	}
+}

+ 0 - 47
main/ui/src/main/java/org/cryptomator/ui/health/ResultSeverityTableCell.java

@@ -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<DiagnosticResultAction, DiagnosticResult.Severity> {
-
-	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());
-		}
-	}
-}

+ 3 - 10
main/ui/src/main/resources/fxml/health_check_details.fxml

@@ -1,21 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <?import javafx.scene.control.Label?>
-<?import javafx.scene.control.TableColumn?>
-<?import javafx.scene.control.TableView?>
+<?import javafx.scene.control.ListView?>
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.text.Text?>
 <VBox xmlns:fx="http://javafx.com/fxml"
 	  xmlns="http://javafx.com/javafx"
 	  fx:controller="org.cryptomator.ui.health.CheckDetailController"
 	  spacing="6">
-	<Label fx:id="checkTitle" styleClass="label-large" text="${controller.taskName}"/>
+	<Label fx:id="checkTitle" styleClass="label-large" text="${controller.taskName}"/> <!-- use formatted label and let the text be "Results of [TASKNAME] -->
 	<Text fx:id="checkDescription" styleClass="label" text="${controller.taskDescription}"/>
-	<TableView fx:id="resultsTableView" visible="${controller.producingResults}" managed="${controller.producingResults}" VBox.vgrow="ALWAYS">
-		<columns>
-			<TableColumn fx:id="resultDescriptionColumn" text="Info" editable="false" maxWidth="Infinity" />
-			<TableColumn fx:id="resultSeverityColumn" text="Severity" editable="false" />
-			<TableColumn fx:id="resultActionColumn" text="Action" editable="false"/>
-		</columns>
-	</TableView>
+	<ListView fx:id="resultsListView"/>
 </VBox>

+ 26 - 0
main/ui/src/main/resources/fxml/health_result_listcell.fxml

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.layout.Region?>
+<HBox xmlns:fx="http://javafx.com/fxml"
+	  xmlns="http://javafx.com/javafx"
+	  fx:controller="org.cryptomator.ui.health.ResultListCellController"
+	  prefHeight="25"
+	  prefWidth="200"
+	  spacing="6"
+	  alignment="CENTER_LEFT">
+	<!-- Remark Check the containing list view for a fixed cell size before editing height properties -->
+	<padding>
+		<Insets topRightBottomLeft="6"/>
+	</padding>
+	<children>
+		<FontAwesome5IconView fx:id="iconView" HBox.hgrow="NEVER" glyphSize="16"/>
+		<Label text="${controller.description}" wrapText="true"/>
+		<Region HBox.hgrow="ALWAYS"/>
+		<Button text="YOLO" onAction="#runResultAction" alignment="CENTER_RIGHT" visible="${controller.fixButtonVisibile}"/>
+	</children>
+</HBox>