From 84e054978c8b9126645279e8f21cd308265b0428 Mon Sep 17 00:00:00 2001 From: crschnick Date: Tue, 6 Jun 2023 13:54:08 +0000 Subject: [PATCH] Browser list performance improvements --- .../app/browser/BrowserFileListComp.java | 131 ++++++++++-------- .../io/xpipe/app/fxcomps/impl/SvgView.java | 7 +- 2 files changed, 82 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserFileListComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserFileListComp.java index d96c5db1..647a16a9 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserFileListComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserFileListComp.java @@ -23,6 +23,7 @@ import javafx.beans.property.*; import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; import javafx.css.PseudoClass; import javafx.geometry.Bounds; import javafx.geometry.Pos; @@ -108,19 +109,7 @@ final class BrowserFileListComp extends SimpleComp { table.getSortOrder().add(filenameCol); table.setFocusTraversable(true); table.setSortPolicy(param -> { - var comp = table.getComparator(); - if (comp == null) { - return true; - } - - var syntheticFirst = Comparator.comparing(path -> !path.isSynthetic()); - var dirsFirst = Comparator.comparing( - path -> path.getRawFileEntry().getKind() != FileKind.DIRECTORY); - - Comparator us = - syntheticFirst.thenComparing(dirsFirst).thenComparing(comp); - FXCollections.sort(param.getItems(), us); - return true; + return sort(table, param.getItems()); }); table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY_FLEX_LAST_COLUMN); filenameCol.minWidthProperty().bind(table.widthProperty().multiply(0.5)); @@ -135,6 +124,22 @@ final class BrowserFileListComp extends SimpleComp { return table; } + private boolean sort(TableView table, ObservableList list) { + var comp = table.getComparator(); + if (comp == null) { + return true; + } + + var syntheticFirst = Comparator.comparing(path -> !path.isSynthetic()); + var dirsFirst = Comparator.comparing( + path -> path.getRawFileEntry().getKind() != FileKind.DIRECTORY); + + Comparator us = + syntheticFirst.thenComparing(dirsFirst).thenComparing(comp); + FXCollections.sort(list, us); + return true; + } + private void prepareTableSelectionModel(TableView table) { if (!fileList.getMode().isMultiple()) { table.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); @@ -232,33 +237,44 @@ final class BrowserFileListComp extends SimpleComp { table.setRowFactory(param -> { TableRow row = new TableRow<>(); - row.accessibleTextProperty().bind(Bindings.createStringBinding(() -> { - return row.getItem() != null ? row.getItem().getFileName() : null; - }, row.itemProperty())); - row.focusTraversableProperty().bind(Bindings.createBooleanBinding(() -> { - return row.getItem() != null; - }, row.itemProperty())); - new ContextMenuAugment<>(event -> { - if (row.getItem() == null) { - return event.getButton() == MouseButton.SECONDARY; - } + row.accessibleTextProperty() + .bind(Bindings.createStringBinding( + () -> { + return row.getItem() != null ? row.getItem().getFileName() : null; + }, + row.itemProperty())); + row.focusTraversableProperty() + .bind(Bindings.createBooleanBinding( + () -> { + return row.getItem() != null; + }, + row.itemProperty())); + new ContextMenuAugment<>( + event -> { + if (row.getItem() == null) { + return event.getButton() == MouseButton.SECONDARY; + } - if (row.getItem() != null && row.getItem().getRawFileEntry().getKind() == FileKind.DIRECTORY) { - return event.getButton() == MouseButton.SECONDARY; - } + if (row.getItem() != null + && row.getItem().getRawFileEntry().getKind() == FileKind.DIRECTORY) { + return event.getButton() == MouseButton.SECONDARY; + } - if (row.getItem() != null && row.getItem().getRawFileEntry().getKind() != FileKind.DIRECTORY) { - return event.getButton() == MouseButton.SECONDARY || event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2; - } + if (row.getItem() != null + && row.getItem().getRawFileEntry().getKind() != FileKind.DIRECTORY) { + return event.getButton() == MouseButton.SECONDARY + || event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2; + } - return false; - }, () -> { - if (row.getItem() != null && row.getItem().isSynthetic()) { - return null; - } + return false; + }, + () -> { + if (row.getItem() != null && row.getItem().isSynthetic()) { + return null; + } - return new BrowserContextMenu(fileList.getFileSystemModel(), row.getItem()); - }) + return new BrowserContextMenu(fileList.getFileSystemModel(), row.getItem()); + }) .augment(new SimpleCompStructure<>(row)); var listEntry = Bindings.createObjectBinding( () -> new BrowserFileListCompEntry(row, row.getItem(), fileList), row.itemProperty()); @@ -347,8 +363,11 @@ final class BrowserFileListComp extends SimpleComp { } if (!table.getItems().equals(newItems)) { - table.getItems().setAll(newItems); - table.sort(); + // Sort the list ourselves as sorting the table would incur a lot of cell updates + var obs = FXCollections.observableList(newItems); + sort(table, obs); + table.getItems().setAll(obs); + // table.sort(); } var currentDirectory = fileList.getFileSystemModel().getCurrentDirectory(); @@ -410,13 +429,17 @@ final class BrowserFileListComp extends SimpleComp { .createRegion(); private final StackPane textField = new LazyTextFieldComp(text).createStructure().get(); + private final HBox graphic; private final BooleanProperty updating = new SimpleBooleanProperty(); public FilenameCell(Property editing) { - accessibleTextProperty().bind(Bindings.createStringBinding(() -> { - return getItem() != null ? getItem() : null; - }, itemProperty())); + accessibleTextProperty() + .bind(Bindings.createStringBinding( + () -> { + return getItem() != null ? getItem() : null; + }, + itemProperty())); setAccessibleRole(AccessibleRole.TEXT); editing.addListener((observable, oldValue, newValue) -> { @@ -436,30 +459,29 @@ final class BrowserFileListComp extends SimpleComp { updateItem(getItem(), isEmpty()); }; text.addListener(listener); + + graphic = new HBox(imageView, textField); + graphic.setSpacing(10); + graphic.setAlignment(Pos.CENTER_LEFT); + HBox.setHgrow(textField, Priority.ALWAYS); + setGraphic(graphic); } @Override - protected void updateItem(String fullPath, boolean empty) { + protected void updateItem(String newName, boolean empty) { if (updating.get()) { - super.updateItem(fullPath, empty); + super.updateItem(newName, empty); return; } try (var ignored = new BusyProperty(updating)) { - super.updateItem(fullPath, empty); - setText(null); - if (empty || getTableRow() == null || getTableRow().getItem() == null) { + super.updateItem(newName, empty); + if (empty || newName == null) { // Don't set image as that would trigger image comp update // and cells are emptied on each change, leading to unnecessary changes // img.set(null); - setGraphic(null); + setOpacity(0.0); } else { - var box = new HBox(imageView, textField); - box.setSpacing(10); - box.setAlignment(Pos.CENTER_LEFT); - HBox.setHgrow(textField, Priority.ALWAYS); - setGraphic(box); - var isParentLink = getTableRow() .getItem() .getRawFileEntry() @@ -473,11 +495,12 @@ final class BrowserFileListComp extends SimpleComp { var isDirectory = getTableRow().getItem().getRawFileEntry().getKind() == FileKind.DIRECTORY; pseudoClassStateChanged(FOLDER, isDirectory); - var fileName = isParentLink ? ".." : FileNames.getFileName(fullPath); + var fileName = isParentLink ? ".." : FileNames.getFileName(newName); var hidden = !isParentLink && (getTableRow().getItem().getRawFileEntry().isHidden() || fileName.startsWith(".")); getTableRow().pseudoClassStateChanged(HIDDEN, hidden); text.set(fileName); + setOpacity(1.0); } } } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/SvgView.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/SvgView.java index 14944ffc..81075d72 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/SvgView.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/SvgView.java @@ -95,7 +95,9 @@ public class SvgView { private WebView createWebView() { var wv = new WebView(); - wv.setPageFill(Color.TRANSPARENT); + // Sometimes a web view might not render when the background is said to transparent, at least according to stack overflow + wv.setPageFill(Color.valueOf("#00000001")); + // wv.setPageFill(Color.BLACK); wv.getEngine().setJavaScriptEnabled(false); wv.setContextMenuEnabled(false); wv.setFocusTraversable(false); @@ -114,8 +116,9 @@ public class SvgView { wv.getChildrenUnmodifiable().addListener((ListChangeListener) change -> { Set scrolls = wv.lookupAll(".scroll-bar"); for (Node scroll : scrolls) { - scroll.setVisible(false); scroll.setFocusTraversable(false); + scroll.setVisible(false); + scroll.setManaged(false); } });