jafea7-ctbrec-v5.3.2-based/client/src/main/java/ctbrec/ui/settings/api/Preferences.java

183 lines
6.4 KiB
Java

package ctbrec.ui.settings.api;
import static java.util.Optional.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.ui.controls.SearchBox;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
public class Preferences {
private static final Logger LOG = LoggerFactory.getLogger(Preferences.class);
private Category[] categories;
private TreeView<Category> categoryTree;
private Preferences(PreferencesStorage preferencesStorage, Category...categories) {
this.categories = categories;
for (Category category : categories) {
assignPreferencesStorage(category, preferencesStorage);
}
}
private void assignPreferencesStorage(Category cat, PreferencesStorage preferencesStorage) {
if(cat.hasSubCategories()) {
for (Category sub : cat.getSubCategories()) {
assignPreferencesStorage(sub, preferencesStorage);
}
} else {
for (Group group : cat.getGroups()) {
for (Setting setting : group.getSettings()) {
setting.setPreferencesStorage(preferencesStorage);
}
}
}
}
public static Preferences of(PreferencesStorage preferencesStorage, Category... categories) {
return new Preferences(preferencesStorage, categories);
}
public void save() {
throw new RuntimeException("save not implemented");
}
Category[] getCategories() {
return categories;
}
public Node getView() {
SearchBox search = new SearchBox(true);
search.textProperty().addListener(this::filterTree);
TreeItem<Category> categoryTreeItems = createCategoryTree(categories, new TreeItem<>(), null);
categoryTree = new TreeView<>(categoryTreeItems);
categoryTree.showRootProperty().set(false);
VBox leftSide = new VBox(search, categoryTree);
VBox.setVgrow(categoryTree, Priority.ALWAYS);
VBox.setMargin(search, new Insets(2));
VBox.setMargin(categoryTree, new Insets(2));
BorderPane main = new BorderPane();
main.setLeft(leftSide);
main.setCenter(new Label("Center"));
BorderPane.setMargin(leftSide, new Insets(2));
categoryTree.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> {
if (newV != null) {
Category cat = newV.getValue();
Node gui = cat.getGuiOrElse(() -> createGui(cat));
BorderPane.setMargin(gui, new Insets(10));
main.setCenter(gui);
}
});
return main;
}
private void filterTree(ObservableValue<? extends String> obs, String oldV, String newV) {
String q = ofNullable(newV).orElse("").toLowerCase().trim();
TreeItem<Category> filteredCategoryTree = createCategoryTree(categories, new TreeItem<>(), q);
categoryTree.setRoot(filteredCategoryTree);
expandAll(categoryTree.getRoot());
TreeItem<Category> parent = categoryTree.getRoot();
while (!parent.getChildren().isEmpty()) {
parent = parent.getChildren().get(0);
categoryTree.getSelectionModel().select(parent);
}
for (Category category : categories) {
if (q.length() > 2) {
HighlightingSupport.highlightMatchess(category, q);
} else {
HighlightingSupport.removeHighlights(category);
}
}
}
private void expandAll(TreeItem<Category> treeItem) {
treeItem.setExpanded(true);
for (TreeItem<Category> child : treeItem.getChildren()) {
expandAll(child);
}
}
private Node createGui(Category cat) {
try {
if (cat.hasSubCategories()) {
return new Label(cat.getName());
} else if(cat.hasGroups()) {
return createPaneWithGroups(cat);
} else {
return createGrid(cat.getGroups()[0].getSettings());
}
} catch(Exception e) {
LOG.error("Error creating the GUI", e);
return new Label(e.getLocalizedMessage());
}
}
private Node createPaneWithGroups(Category cat) throws Exception {
VBox pane = new VBox();
for (Group grp : cat.getGroups()) {
Label groupLabel = new Label(grp.getName());
groupLabel.getStyleClass().add("settings-group-label");
VBox.setMargin(groupLabel, new Insets(20, 0, 10, 20));
pane.getChildren().add(groupLabel);
Node parameterGrid = createGrid(grp.getSettings());
pane.getChildren().add(parameterGrid);
VBox.setMargin(parameterGrid, new Insets(0, 0, 0, 40));
}
return pane;
}
private Node createGrid(Setting[] settings) throws Exception {
GridPane pane = new GridPane();
int row = 0;
for (Setting setting : settings) {
Node node = setting.getGui();
Label label = new Label(setting.getName());
label.labelForProperty().set(node);
if (setting.getTooltip() != null) {
label.setTooltip(new Tooltip(setting.getTooltip()));
}
pane.addRow(row++, label, node);
GridPane.setMargin(node, new Insets(5, 0, 5, 10));
GridPane.setHgrow(node, Priority.ALWAYS);
}
return pane;
}
/**
* Creates a tree of the given categories. Filters out categories, which don't match the filter
* @param filter may be null
*/
private TreeItem<Category> createCategoryTree(Category[] categories, TreeItem<Category> parent, String filter) {
for (Category category : categories) {
TreeItem<Category> child = new TreeItem<>(category);
if (category.hasSubCategories()) {
createCategoryTree(category.getSubCategories(), child, filter);
if (!child.getChildren().isEmpty()) {
parent.getChildren().add(child);
}
} else if(category.contains(filter)) {
parent.getChildren().add(child);
}
}
return parent;
}
}