From 7629828df4e8840c45ff3f45f80f975bc02b9f17 Mon Sep 17 00:00:00 2001 From: crschnick Date: Sun, 26 Jan 2025 14:35:56 +0000 Subject: [PATCH] Fixes [stage] --- .../io/xpipe/app/comp/base/PrettySvgComp.java | 116 -------------- .../io/xpipe/app/comp/base/SvgHelper.java | 45 ------ .../java/io/xpipe/app/comp/base/SvgView.java | 146 ------------------ .../io/xpipe/app/icon/SystemIconCache.java | 3 +- .../io/xpipe/app/icon/SystemIconManager.java | 14 +- .../xpipe/app/icon/SystemIconSourceData.java | 5 +- .../io/xpipe/app/resources/AppImages.java | 49 ++---- version | 2 +- 8 files changed, 25 insertions(+), 355 deletions(-) delete mode 100644 app/src/main/java/io/xpipe/app/comp/base/PrettySvgComp.java delete mode 100644 app/src/main/java/io/xpipe/app/comp/base/SvgHelper.java delete mode 100644 app/src/main/java/io/xpipe/app/comp/base/SvgView.java diff --git a/app/src/main/java/io/xpipe/app/comp/base/PrettySvgComp.java b/app/src/main/java/io/xpipe/app/comp/base/PrettySvgComp.java deleted file mode 100644 index fc0b14cbe..000000000 --- a/app/src/main/java/io/xpipe/app/comp/base/PrettySvgComp.java +++ /dev/null @@ -1,116 +0,0 @@ -package io.xpipe.app.comp.base; - -import io.xpipe.app.comp.SimpleComp; -import io.xpipe.app.prefs.AppPrefs; -import io.xpipe.app.resources.AppImages; -import io.xpipe.app.util.PlatformThread; -import io.xpipe.core.store.FileNames; - -import javafx.beans.binding.Bindings; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.value.ObservableValue; -import javafx.geometry.Pos; -import javafx.scene.layout.Region; -import javafx.scene.layout.StackPane; - -import java.util.function.Consumer; - -public class PrettySvgComp extends SimpleComp { - - private final ObservableValue value; - private final double width; - private final double height; - - public PrettySvgComp(ObservableValue value, double width, double height) { - this.value = value; - this.width = width; - this.height = height; - } - - @Override - protected Region createSimple() { - var image = new SimpleStringProperty(); - var syncValue = PlatformThread.sync(value); - var storeIcon = SvgView.create(Bindings.createObjectBinding( - () -> { - if (image.get() == null) { - return null; - } - - if (AppImages.hasSvgImage(image.getValue())) { - return AppImages.svgImage(image.getValue()); - } else if (AppImages.hasSvgImage(image.getValue().replace("-dark", ""))) { - return AppImages.svgImage(image.getValue().replace("-dark", "")); - } else { - return null; - } - }, - image)); - var ar = Bindings.createDoubleBinding( - () -> { - return storeIcon.getWidth().getValue().doubleValue() - / storeIcon.getHeight().getValue().doubleValue(); - }, - storeIcon.getWidth(), - storeIcon.getHeight()); - var widthProperty = Bindings.createDoubleBinding( - () -> { - boolean widthLimited = width / height < ar.doubleValue(); - if (widthLimited) { - return width; - } else { - return height * ar.doubleValue(); - } - }, - ar); - var heightProperty = Bindings.createDoubleBinding( - () -> { - boolean widthLimited = width / height < ar.doubleValue(); - if (widthLimited) { - return width / ar.doubleValue(); - } else { - return height; - } - }, - ar); - - var stack = new StackPane(); - var wv = storeIcon.createWebview(); - if (wv.isPresent()) { - var node = wv.get(); - node.prefWidthProperty().bind(widthProperty); - node.maxWidthProperty().bind(widthProperty); - node.minWidthProperty().bind(widthProperty); - node.prefHeightProperty().bind(heightProperty); - node.maxHeightProperty().bind(heightProperty); - node.minHeightProperty().bind(heightProperty); - stack.getChildren().add(node); - } - - Consumer update = val -> { - var useDark = AppPrefs.get() != null - && AppPrefs.get().theme.get() != null - && AppPrefs.get().theme.get().isDark(); - var fixed = val != null - ? FileNames.getBaseName(val) + (useDark ? "-dark" : "") + "." + FileNames.getExtension(val) - : null; - image.set(fixed); - }; - - syncValue.subscribe(update); - if (AppPrefs.get() != null) { - AppPrefs.get().theme.addListener((observable, oldValue, newValue) -> { - update.accept(syncValue.getValue()); - }); - } - - stack.setFocusTraversable(false); - stack.setPrefWidth(width); - stack.setMinWidth(width); - stack.setPrefHeight(height); - stack.setMinHeight(height); - stack.setAlignment(Pos.CENTER); - stack.getStyleClass().add("stack"); - return stack; - } -} diff --git a/app/src/main/java/io/xpipe/app/comp/base/SvgHelper.java b/app/src/main/java/io/xpipe/app/comp/base/SvgHelper.java deleted file mode 100644 index 0c95d8cc8..000000000 --- a/app/src/main/java/io/xpipe/app/comp/base/SvgHelper.java +++ /dev/null @@ -1,45 +0,0 @@ -package io.xpipe.app.comp.base; - -import javafx.css.Size; -import javafx.css.SizeUnits; -import javafx.geometry.Point2D; - -import java.util.regex.Pattern; - -public class SvgHelper { - - public static Size parseSize(String string) { - for (SizeUnits unit : SizeUnits.values()) { - if (string.endsWith(unit.toString())) { - return new Size( - Double.parseDouble(string.substring( - 0, string.length() - unit.toString().length())), - unit); - } - } - return new Size(Double.parseDouble(string), SizeUnits.PX); - } - - public static Point2D getDimensions(String val) { - var regularExpression = Pattern.compile("]+?width=\"([^ ]+)\"", Pattern.DOTALL); - var matcher = regularExpression.matcher(val); - - if (!matcher.find()) { - var viewBox = Pattern.compile( - " width; - private final ObservableValue height; - private final ObservableValue svgContent; - - private static boolean canCreateWebview = true; - - private SvgView(ObservableValue width, ObservableValue height, ObservableValue svgContent) { - this.width = PlatformThread.sync(width); - this.height = PlatformThread.sync(height); - this.svgContent = PlatformThread.sync(svgContent); - } - - @SneakyThrows - public static SvgView create(ObservableValue content) { - var widthProperty = new SimpleIntegerProperty(); - var heightProperty = new SimpleIntegerProperty(); - content.subscribe(val -> { - if (val == null || val.isBlank()) { - return; - } - - var dim = SvgHelper.getDimensions(val); - widthProperty.set((int) Math.ceil(dim.getX())); - heightProperty.set((int) Math.ceil(dim.getY())); - }); - return new SvgView(widthProperty, heightProperty, content); - } - - private String getHtml(String content) { - return "" + content + ""; - } - - private WebView createWebView() { - if (!canCreateWebview) { - return null; - } - - WebView wv; - try { - // This can happen if we are using a custom JavaFX build without webkit - wv = new WebView(); - } catch (Throwable t) { - ErrorEvent.fromThrowable(t).omit().expected().handle(); - canCreateWebview = false; - return null; - } - - wv.getStyleClass().add("svg-comp"); - wv.getEngine() - .setUserDataDirectory( - AppProperties.get().getDataDir().resolve("webview").toFile()); - // Sometimes a web view might not render when the background is set 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); - wv.setAccessibleRole(AccessibleRole.IMAGE_VIEW); - wv.setDisable(true); - - wv.getEngine().loadContent(svgContent.getValue() != null ? getHtml(svgContent.getValue()) : null); - svgContent.subscribe(n -> { - if (n == null) { - wv.setOpacity(0.0); - return; - } - - wv.setOpacity(1.0); - var html = getHtml(n); - wv.getEngine().loadContent(html); - }); - - // Hide scrollbars that popup on every content change. Bug in WebView? - wv.getChildrenUnmodifiable().addListener((ListChangeListener) change -> { - Set scrolls = wv.lookupAll(".scroll-bar"); - for (Node scroll : scrolls) { - scroll.setFocusTraversable(false); - scroll.setVisible(false); - scroll.setManaged(false); - } - }); - - // As the aspect ratio of the WebView is kept constant, we can compute the zoom only using the width - wv.zoomProperty() - .bind(Bindings.createDoubleBinding( - () -> { - return wv.getWidth() / width.getValue().doubleValue(); - }, - wv.widthProperty(), - width)); - - wv.maxWidthProperty().bind(wv.prefWidthProperty()); - wv.maxHeightProperty().bind(wv.prefHeightProperty()); - - wv.minWidthProperty().bind(wv.prefWidthProperty()); - wv.minHeightProperty().bind(wv.prefHeightProperty()); - - return wv; - } - - public Optional createWebview() { - var wv = createWebView(); - return Optional.ofNullable(wv); - } - - @Value - @Builder - public static class Structure implements CompStructure { - StackPane pane; - WebView webView; - - @Override - public StackPane get() { - return pane; - } - } -} diff --git a/app/src/main/java/io/xpipe/app/icon/SystemIconCache.java b/app/src/main/java/io/xpipe/app/icon/SystemIconCache.java index c9f8978e7..8cc1e6cf6 100644 --- a/app/src/main/java/io/xpipe/app/icon/SystemIconCache.java +++ b/app/src/main/java/io/xpipe/app/icon/SystemIconCache.java @@ -6,6 +6,7 @@ import com.github.weisj.jsvg.attributes.ViewBox; import com.github.weisj.jsvg.parser.SVGLoader; import io.xpipe.app.core.AppProperties; import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.resources.AppImages; import lombok.Getter; import javax.imageio.ImageIO; @@ -41,7 +42,7 @@ public class SystemIconCache { } } - public static void buildCache(Map all) { + public static void rebuildCache(Map all) { try { for (var e : all.entrySet()) { var target = DIRECTORY.resolve(e.getKey().getId()); diff --git a/app/src/main/java/io/xpipe/app/icon/SystemIconManager.java b/app/src/main/java/io/xpipe/app/icon/SystemIconManager.java index a98557d6c..5b4020bee 100644 --- a/app/src/main/java/io/xpipe/app/icon/SystemIconManager.java +++ b/app/src/main/java/io/xpipe/app/icon/SystemIconManager.java @@ -29,12 +29,12 @@ public class SystemIconManager { } public static void init() throws Exception { - loadSources(); + reloadSources(); SystemIconCache.refreshBuilt(); - loadImages(); + reloadImages(); } - public static synchronized void loadSources() throws Exception { + public static synchronized void reloadSources() throws Exception { Files.createDirectories(DIRECTORY); LOADED.clear(); @@ -51,7 +51,8 @@ public class SystemIconManager { }); } - public static void loadImages() { + public static void reloadImages() { + AppImages.remove(s -> s.startsWith("icons/")); try { for (var source : AppPrefs.get().getIconSources().getValue()) { AppImages.loadRasterImages(SystemIconCache.getDirectory(source), "icons/" + source.getId()); @@ -66,9 +67,10 @@ public class SystemIconManager { for (var source : AppPrefs.get().getIconSources().getValue()) { source.refresh(); } - loadSources(); - SystemIconCache.buildCache(LOADED); + reloadSources(); + SystemIconCache.rebuildCache(LOADED); SystemIconCache.refreshBuilt(); + reloadImages(); } public static Path getPoolPath() { diff --git a/app/src/main/java/io/xpipe/app/icon/SystemIconSourceData.java b/app/src/main/java/io/xpipe/app/icon/SystemIconSourceData.java index b2367be1d..2e8120706 100644 --- a/app/src/main/java/io/xpipe/app/icon/SystemIconSourceData.java +++ b/app/src/main/java/io/xpipe/app/icon/SystemIconSourceData.java @@ -11,6 +11,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Locale; @Value public class SystemIconSourceData { @@ -39,7 +40,7 @@ public class SystemIconSourceData { var hasLightVariant = Files.exists(file.getParent().resolve(cleanedName + "-light.svg")); var hasDarkVariant = Files.exists(file.getParent().resolve(cleanedName + "-dark.svg")); if (hasLightVariant && !hasDarkVariant && name.endsWith("-light")) { - var s = new SystemIconSourceFile(source, cleanedName, file, true); + var s = new SystemIconSourceFile(source, cleanedName.toLowerCase(Locale.ROOT), file, true); sourceFiles.add(s); continue; } @@ -48,7 +49,7 @@ public class SystemIconSourceData { continue; } - var s = new SystemIconSourceFile(source, cleanedName, file, false); + var s = new SystemIconSourceFile(source, cleanedName.toLowerCase(Locale.ROOT), file, false); sourceFiles.add(s); } } diff --git a/app/src/main/java/io/xpipe/app/resources/AppImages.java b/app/src/main/java/io/xpipe/app/resources/AppImages.java index 8069c3780..cd944e1eb 100644 --- a/app/src/main/java/io/xpipe/app/resources/AppImages.java +++ b/app/src/main/java/io/xpipe/app/resources/AppImages.java @@ -20,25 +20,29 @@ import java.time.Duration; import java.time.Instant; import java.util.HashMap; import java.util.Map; +import java.util.function.Predicate; public class AppImages { public static final Image DEFAULT_IMAGE = new WritableImage(1, 1); private static final Map images = new HashMap<>(); - private static final Map svgImages = new HashMap<>(); + + public static void remove(Predicate filter) { + images.keySet().removeIf(filter); + } public static void init() { - if (images.size() > 0 || svgImages.size() > 0) { + if (images.size() > 0) { return; } TrackEvent.info("Loading images ..."); for (var module : AppExtensionManager.getInstance().getContentModules()) { - loadDirectory(module.getName(), "img", true, true); + loadDirectory(module.getName(), "img", true); } } - public static void loadDirectory(String module, String dir, boolean loadImages, boolean loadSvgs) { + public static void loadDirectory(String module, String dir, boolean loadImages) { var start = Instant.now(); AppResources.with(module, dir, basePath -> { if (!Files.exists(basePath)) { @@ -53,19 +57,12 @@ public class AppImages { var relativeFileName = FilenameUtils.separatorsToUnix( basePath.relativize(file).toString()); var key = defaultPrefix + relativeFileName; - if (images.containsKey(key) || svgImages.containsKey(key)) { + if (images.containsKey(key)) { return FileVisitResult.CONTINUE; } - try { - if (FilenameUtils.getExtension(file.toString()).equals("svg") && loadSvgs) { - var s = Files.readString(file); - svgImages.put(key, s); - } else if (loadImages) { - images.put(key, loadImage(file)); - } - } catch (IOException ex) { - ErrorEvent.fromThrowable(ex).omitted(true).build().handle(); + if (loadImages) { + images.put(key, loadImage(file)); } return FileVisitResult.CONTINUE; } @@ -97,21 +94,6 @@ public class AppImages { }); } - public static String svgImage(String file) { - if (file == null) { - return ""; - } - - var key = file.contains(":") ? file : "app:" + file; - - if (svgImages.containsKey(key)) { - return svgImages.get(key); - } - - TrackEvent.warn("Svg image " + key + " not found"); - return ""; - } - public static boolean hasNormalImage(String file) { if (file == null) { return false; @@ -125,15 +107,6 @@ public class AppImages { return images.containsKey(key); } - public static boolean hasSvgImage(String file) { - if (file == null) { - return false; - } - - var key = file.contains(":") ? file : "app:" + file; - return svgImages.containsKey(key); - } - public static Image image(String file) { if (file == null) { return DEFAULT_IMAGE; diff --git a/version b/version index 21cd89cd9..39049989f 100644 --- a/version +++ b/version @@ -1 +1 @@ -15.0-6 +15.0-7