From 62a6438e97f0712e9ddb9070900b4e73cb020a04 Mon Sep 17 00:00:00 2001 From: crschnick Date: Thu, 27 Apr 2023 22:50:51 +0000 Subject: [PATCH] More file browser fixes --- .../xpipe/app/browser/FileListCompEntry.java | 8 +--- .../app/browser/SelectedFileListComp.java | 39 ++++++++++++++++--- .../xpipe/app/fxcomps/impl/SvgCacheComp.java | 33 ++++++++++------ .../io/xpipe/app/resources/style/browser.css | 19 ++++++++- 4 files changed, 75 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/io/xpipe/app/browser/FileListCompEntry.java b/app/src/main/java/io/xpipe/app/browser/FileListCompEntry.java index 1262f1126..5f135ab5a 100644 --- a/app/src/main/java/io/xpipe/app/browser/FileListCompEntry.java +++ b/app/src/main/java/io/xpipe/app/browser/FileListCompEntry.java @@ -3,10 +3,8 @@ package io.xpipe.app.browser; import io.xpipe.core.store.FileSystem; import javafx.geometry.Point2D; import javafx.scene.Node; -import javafx.scene.Scene; -import javafx.scene.SnapshotParameters; import javafx.scene.control.TableView; -import javafx.scene.image.WritableImage; +import javafx.scene.image.Image; import javafx.scene.input.*; import lombok.Getter; @@ -156,9 +154,7 @@ public class FileListCompEntry { Dragboard db = row.startDragAndDrop(TransferMode.COPY); db.setContent(FileBrowserClipboard.startDrag(model.getFileSystemModel().getCurrentDirectory(), selected)); - var r = new SelectedFileListComp(selected).createRegion(); - new Scene(r); - WritableImage image = r.snapshot(new SnapshotParameters(), null); + Image image = SelectedFileListComp.snapshot(selected); db.setDragView(image, -20, 15); event.setDragDetect(true); diff --git a/app/src/main/java/io/xpipe/app/browser/SelectedFileListComp.java b/app/src/main/java/io/xpipe/app/browser/SelectedFileListComp.java index f698bb265..53e022cc3 100644 --- a/app/src/main/java/io/xpipe/app/browser/SelectedFileListComp.java +++ b/app/src/main/java/io/xpipe/app/browser/SelectedFileListComp.java @@ -1,13 +1,22 @@ package io.xpipe.app.browser; -import io.xpipe.app.browser.icon.FileIcons; +import io.xpipe.app.browser.icon.FileIconManager; import io.xpipe.app.comp.base.ListBoxViewComp; +import io.xpipe.app.core.AppStyle; +import io.xpipe.app.core.AppWindowHelper; +import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.SimpleComp; -import io.xpipe.app.fxcomps.impl.LabelComp; import io.xpipe.core.impl.FileNames; import io.xpipe.core.store.FileSystem; import javafx.collections.ObservableList; +import javafx.scene.Scene; +import javafx.scene.SnapshotParameters; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.image.WritableImage; import javafx.scene.layout.Region; +import javafx.scene.paint.Color; import lombok.EqualsAndHashCode; import lombok.Value; @@ -15,15 +24,33 @@ import lombok.Value; @EqualsAndHashCode(callSuper = true) public class SelectedFileListComp extends SimpleComp { + public static Image snapshot(ObservableList list) { + var r = new SelectedFileListComp(list).styleClass("drag").createRegion(); + var scene = new Scene(r); + AppWindowHelper.setupStylesheets(scene); + AppStyle.addStylesheets(scene); + SnapshotParameters parameters = new SnapshotParameters(); + parameters.setFill(Color.TRANSPARENT); + WritableImage image = r.snapshot(parameters, null); + return image; + } + ObservableList list; @Override protected Region createSimple() { var c = new ListBoxViewComp<>(list, list, entry -> { - var l = new LabelComp(FileNames.getFileName(entry.getPath())).apply(struc -> struc.get() - .setGraphic(FileIcons.createIcon(entry).createRegion())); - return l; - }).styleClass("selected-file-list"); + return Comp.of(() -> { + var icon = new ImageView(FileIconManager.getSvgCache() + .getCached(FileIconManager.getFileIcon(entry, false)) + .orElse(null)); + icon.setFitWidth(20); + icon.setFitHeight(20); + var l = new Label(FileNames.getFileName(entry.getPath()), icon); + return l; + }); + }) + .styleClass("selected-file-list"); return c.createRegion(); } } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/SvgCacheComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/SvgCacheComp.java index cbe1e5a49..d89be7212 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/SvgCacheComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/SvgCacheComp.java @@ -7,13 +7,17 @@ import javafx.animation.PauseTransition; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ObservableValue; +import javafx.scene.SnapshotParameters; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.image.WritableImage; import javafx.scene.layout.Region; import javafx.scene.layout.StackPane; +import javafx.scene.paint.Color; import javafx.util.Duration; +import java.util.concurrent.atomic.AtomicReference; + public class SvgCacheComp extends SimpleComp { private final ObservableValue width; @@ -45,7 +49,21 @@ public class SvgCacheComp extends SimpleComp { var webViewContent = new SimpleStringProperty(); var back = SvgView.create(webViewContent).createWebview(); + back.prefWidthProperty().bind(width); + back.prefHeightProperty().bind(height); + var animation = new AtomicReference(); svgFile.addListener((observable, oldValue, newValue) -> { + var cached = cache.getCached(newValue); + webViewContent.setValue(newValue != null || cached.isEmpty() ? AppImages.svgImage(newValue) : null); + frontContent.setValue(cached.orElse(null)); + back.setVisible(cached.isEmpty()); + front.setVisible(cached.isPresent()); + + if (animation.get() != null) { + animation.get().stop(); + animation.set(null); + } + var pt = new PauseTransition(); pt.setDuration(Duration.millis(1000)); pt.setOnFinished(actionEvent -> { @@ -57,7 +75,9 @@ public class SvgCacheComp extends SimpleComp { return; } - WritableImage image = back.snapshot(null, null); + SnapshotParameters parameters = new SnapshotParameters(); + parameters.setFill(Color.TRANSPARENT); + WritableImage image = back.snapshot(parameters, null); if (image.getWidth() < 10) { return; } @@ -65,16 +85,7 @@ public class SvgCacheComp extends SimpleComp { cache.put(newValue, image); }); pt.play(); - }); - back.prefWidthProperty().bind(width); - back.prefHeightProperty().bind(height); - - svgFile.addListener((observable, oldValue, newValue) -> { - var cached = cache.getCached(newValue); - webViewContent.setValue(newValue != null || cached.isEmpty() ? AppImages.svgImage(newValue) : null); - frontContent.setValue(cached.orElse(null)); - back.setVisible(cached.isEmpty()); - front.setVisible(cached.isPresent()); + animation.set(pt); }); var stack = new StackPane(back, front); diff --git a/app/src/main/resources/io/xpipe/app/resources/style/browser.css b/app/src/main/resources/io/xpipe/app/resources/style/browser.css index db7422619..82369e724 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/browser.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/browser.css @@ -5,13 +5,22 @@ } .selected-file-list { - -fx-padding: 10px; + -fx-spacing: 5px; + -fx-padding: 8px; } .selected-file-list * { -fx-spacing: 5px; } +.selected-file-list.drag { +-fx-border-width: 1px; +-fx-border-color: -color-neutral-emphasis; +-fx-background-color: -color-neutral-muted; +-fx-background-radius: 1px; +-fx-border-radius: 1px; +} + .browser .bookmark-list { -fx-border-width: 0 0 1 1; } @@ -58,6 +67,14 @@ -fx-opacity: 0.8; } +.browser .table-row-cell:hover { + -fx-background-color: -color-accent-subtle; +} + +.browser .table-row-cell:selected { + -fx-background-color: -color-success-subtle; +} + .browser .table-row-cell:folder:drag-over { -fx-background-color: -color-success-muted; }