Rework image handling for browser

This commit is contained in:
crschnick 2024-03-26 19:38:24 +00:00
parent 07472cad9a
commit 86ae1271a4
1230 changed files with 89 additions and 272 deletions

View file

@ -3,9 +3,9 @@ package io.xpipe.app.browser;
import atlantafx.base.controls.RingProgressIndicator; import atlantafx.base.controls.RingProgressIndicator;
import atlantafx.base.controls.Spacer; import atlantafx.base.controls.Spacer;
import atlantafx.base.theme.Styles; import atlantafx.base.theme.Styles;
import io.xpipe.app.browser.icon.DirectoryType; import io.xpipe.app.browser.icon.BrowserIconDirectoryType;
import io.xpipe.app.browser.icon.FileIconManager; import io.xpipe.app.browser.icon.FileIconManager;
import io.xpipe.app.browser.icon.FileType; import io.xpipe.app.browser.icon.BrowserIconFileType;
import io.xpipe.app.comp.base.MultiContentComp; import io.xpipe.app.comp.base.MultiContentComp;
import io.xpipe.app.comp.base.SideSplitPaneComp; import io.xpipe.app.comp.base.SideSplitPaneComp;
import io.xpipe.app.core.AppLayoutModel; import io.xpipe.app.core.AppLayoutModel;
@ -52,8 +52,8 @@ public class BrowserComp extends SimpleComp {
@Override @Override
protected Region createSimple() { protected Region createSimple() {
FileType.loadDefinitions(); BrowserIconFileType.loadDefinitions();
DirectoryType.loadDefinitions(); BrowserIconDirectoryType.loadDefinitions();
ThreadHelper.runAsync(() -> { ThreadHelper.runAsync(() -> {
FileIconManager.loadIfNecessary(); FileIconManager.loadIfNecessary();
}); });
@ -269,7 +269,7 @@ public class BrowserComp extends SimpleComp {
.get() .get()
.getProvider() .getProvider()
.getDisplayIconFileName(model.getEntry().getStore()); .getDisplayIconFileName(model.getEntry().getStore());
var logo = PrettyImageHelper.ofFixedSquare(image, 16).createRegion(); var logo = PrettyImageHelper.ofFixedSizeSquare(image, 16).createRegion();
tab.graphicProperty() tab.graphicProperty()
.bind(Bindings.createObjectBinding( .bind(Bindings.createObjectBinding(

View file

@ -1,7 +1,7 @@
package io.xpipe.app.browser; package io.xpipe.app.browser;
import io.xpipe.app.browser.icon.DirectoryType; import io.xpipe.app.browser.icon.BrowserIconDirectoryType;
import io.xpipe.app.browser.icon.FileType; import io.xpipe.app.browser.icon.BrowserIconFileType;
import io.xpipe.core.store.FileKind; import io.xpipe.core.store.FileKind;
import io.xpipe.core.store.FileNames; import io.xpipe.core.store.FileNames;
import io.xpipe.core.store.FileSystem; import io.xpipe.core.store.FileSystem;
@ -13,8 +13,8 @@ public class BrowserEntry {
private final BrowserFileListModel model; private final BrowserFileListModel model;
private final FileSystem.FileEntry rawFileEntry; private final FileSystem.FileEntry rawFileEntry;
private final boolean synthetic; private final boolean synthetic;
private final FileType fileType; private final BrowserIconFileType fileType;
private final DirectoryType directoryType; private final BrowserIconDirectoryType directoryType;
public BrowserEntry(FileSystem.FileEntry rawFileEntry, BrowserFileListModel model, boolean synthetic) { public BrowserEntry(FileSystem.FileEntry rawFileEntry, BrowserFileListModel model, boolean synthetic) {
this.rawFileEntry = rawFileEntry; this.rawFileEntry = rawFileEntry;
@ -24,12 +24,12 @@ public class BrowserEntry {
this.directoryType = directoryType(rawFileEntry); this.directoryType = directoryType(rawFileEntry);
} }
private static FileType fileType(FileSystem.FileEntry rawFileEntry) { private static BrowserIconFileType fileType(FileSystem.FileEntry rawFileEntry) {
if (rawFileEntry.getKind() == FileKind.DIRECTORY) { if (rawFileEntry.getKind() == FileKind.DIRECTORY) {
return null; return null;
} }
for (var f : FileType.ALL) { for (var f : BrowserIconFileType.ALL) {
if (f.matches(rawFileEntry)) { if (f.matches(rawFileEntry)) {
return f; return f;
} }
@ -38,12 +38,12 @@ public class BrowserEntry {
return null; return null;
} }
private static DirectoryType directoryType(FileSystem.FileEntry rawFileEntry) { private static BrowserIconDirectoryType directoryType(FileSystem.FileEntry rawFileEntry) {
if (rawFileEntry.getKind() != FileKind.DIRECTORY) { if (rawFileEntry.getKind() != FileKind.DIRECTORY) {
return null; return null;
} }
for (var f : DirectoryType.ALL) { for (var f : BrowserIconDirectoryType.ALL) {
if (f.matches(rawFileEntry)) { if (f.matches(rawFileEntry)) {
return f; return f;
} }

View file

@ -8,7 +8,7 @@ import io.xpipe.app.comp.base.LazyTextFieldComp;
import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.app.fxcomps.augment.ContextMenuAugment; import io.xpipe.app.fxcomps.augment.ContextMenuAugment;
import io.xpipe.app.fxcomps.impl.PrettySvgComp; import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.util.BooleanScope; import io.xpipe.app.util.BooleanScope;
import io.xpipe.app.util.HumanReadableFormat; import io.xpipe.app.util.HumanReadableFormat;
@ -526,12 +526,13 @@ final class BrowserFileListComp extends SimpleComp {
}; };
text.addListener(listener); text.addListener(listener);
Node imageView = new PrettySvgComp(img, 24, 24).createRegion(); Node imageView = PrettyImageHelper.ofFixedSize(img, 24, 24).createRegion();
HBox graphic = new HBox(imageView, HBox graphic = new HBox(imageView,
new Spacer(7), new Spacer(7),
quickAccess, quickAccess,
new Spacer(3), new Spacer(3),
textField); textField);
graphic.setAlignment(Pos.CENTER_LEFT);
HBox.setHgrow(textField, Priority.ALWAYS); HBox.setHgrow(textField, Priority.ALWAYS);
graphic.setAlignment(Pos.CENTER_LEFT); graphic.setAlignment(Pos.CENTER_LEFT);
setGraphic(graphic); setGraphic(graphic);
@ -550,8 +551,8 @@ final class BrowserFileListComp extends SimpleComp {
// Don't set image as that would trigger image comp update // Don't set image as that would trigger image comp update
// and cells are emptied on each change, leading to unnecessary changes // and cells are emptied on each change, leading to unnecessary changes
// img.set(null); // img.set(null);
// Use opacity instead of visibility as visibility is kinda bugged with web views // Visibility seems to be bugged, so use opacity
setOpacity(0.0); setOpacity(0.0);
} else { } else {
var isParentLink = getTableRow() var isParentLink = getTableRow()
@ -580,8 +581,7 @@ final class BrowserFileListComp extends SimpleComp {
&& (getTableRow().getItem().getRawFileEntry().isHidden() || fileName.startsWith(".")); && (getTableRow().getItem().getRawFileEntry().isHidden() || fileName.startsWith("."));
getTableRow().pseudoClassStateChanged(HIDDEN, hidden); getTableRow().pseudoClassStateChanged(HIDDEN, hidden);
text.set(fileName); text.set(fileName);
// Visibility seems to be bugged, so use opacity
// Use opacity instead of visibility as visibility is kinda bugged with web views
setOpacity(1.0); setOpacity(1.0);
} }
} }

View file

@ -6,10 +6,7 @@ import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.app.fxcomps.augment.ContextMenuAugment; import io.xpipe.app.fxcomps.augment.ContextMenuAugment;
import io.xpipe.app.fxcomps.impl.HorizontalComp; import io.xpipe.app.fxcomps.impl.*;
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
import io.xpipe.app.fxcomps.impl.StackComp;
import io.xpipe.app.fxcomps.impl.TextFieldComp;
import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import io.xpipe.app.util.BooleanScope; import io.xpipe.app.util.BooleanScope;
import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
@ -96,7 +93,7 @@ public class BrowserNavBar extends SimpleComp {
: "home_icon.svg"; : "home_icon.svg";
}, },
model.getCurrentPath()); model.getCurrentPath());
var breadcrumbsGraphic = PrettyImageHelper.ofSvg(graphic, 16, 16) var breadcrumbsGraphic = new PrettySvgComp(graphic, 16, 16)
.padding(new Insets(0, 0, 1, 0)) .padding(new Insets(0, 0, 1, 0))
.styleClass("path-graphic") .styleClass("path-graphic")
.createRegion(); .createRegion();

View file

@ -52,7 +52,7 @@ public class BrowserSelectionListComp extends SimpleComp {
protected Region createSimple() { protected Region createSimple() {
var c = new ListBoxViewComp<>(list, list, entry -> { var c = new ListBoxViewComp<>(list, list, entry -> {
return Comp.of(() -> { return Comp.of(() -> {
var wv = PrettyImageHelper.ofFixedSquare(FileIconManager.getFileIcon(entry, false), 20) var wv = PrettyImageHelper.ofFixedSizeSquare(FileIconManager.getFileIcon(entry, false), 20)
.createRegion(); .createRegion();
var l = new Label(null, wv); var l = new Label(null, wv);
l.setTextOverrun(OverrunStyle.CENTER_ELLIPSIS); l.setTextOverrun(OverrunStyle.CENTER_ELLIPSIS);

View file

@ -9,6 +9,7 @@ import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.LabelComp; import io.xpipe.app.fxcomps.impl.LabelComp;
import io.xpipe.app.fxcomps.impl.PrettyImageHelper; import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
import io.xpipe.app.fxcomps.impl.PrettySvgComp;
import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.util.JfxHelper; import io.xpipe.app.util.JfxHelper;
@ -42,7 +43,7 @@ public class BrowserWelcomeComp extends SimpleComp {
var vbox = new VBox(welcome, new Spacer(4, Orientation.VERTICAL)); var vbox = new VBox(welcome, new Spacer(4, Orientation.VERTICAL));
vbox.setAlignment(Pos.CENTER_LEFT); vbox.setAlignment(Pos.CENTER_LEFT);
var img = PrettyImageHelper.ofSvg(new SimpleStringProperty("Hips.svg"), 50, 75) var img = new PrettySvgComp(new SimpleStringProperty("Hips.svg"), 50, 75)
.padding(new Insets(5, 0, 0, 0)) .padding(new Insets(5, 0, 0, 0))
.createRegion(); .createRegion();
var hbox = new HBox(img, vbox); var hbox = new HBox(img, vbox);

View file

@ -15,11 +15,11 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public interface DirectoryType { public interface BrowserIconDirectoryType {
List<DirectoryType> ALL = new ArrayList<>(); List<BrowserIconDirectoryType> ALL = new ArrayList<>();
static DirectoryType byId(String id) { static BrowserIconDirectoryType byId(String id) {
return ALL.stream() return ALL.stream()
.filter(fileType -> fileType.getId().equals(id)) .filter(fileType -> fileType.getId().equals(id))
.findAny() .findAny()
@ -27,7 +27,7 @@ public interface DirectoryType {
} }
static void loadDefinitions() { static void loadDefinitions() {
ALL.add(new DirectoryType() { ALL.add(new BrowserIconDirectoryType() {
@Override @Override
public String getId() { public String getId() {
@ -80,7 +80,7 @@ public interface DirectoryType {
String getIcon(FileSystem.FileEntry entry, boolean open); String getIcon(FileSystem.FileEntry entry, boolean open);
class Simple implements DirectoryType { class Simple implements BrowserIconDirectoryType {
@Getter @Getter
private final String id; private final String id;

View file

@ -12,11 +12,11 @@ import java.nio.file.Files;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public interface FileType { public interface BrowserIconFileType {
List<FileType> ALL = new ArrayList<>(); List<BrowserIconFileType> ALL = new ArrayList<>();
static FileType byId(String id) { static BrowserIconFileType byId(String id) {
return ALL.stream() return ALL.stream()
.filter(fileType -> fileType.getId().equals(id)) .filter(fileType -> fileType.getId().equals(id))
.findAny() .findAny()
@ -47,7 +47,7 @@ public interface FileType {
.collect(Collectors.toSet()); .collect(Collectors.toSet());
var darkIcon = split[2].trim(); var darkIcon = split[2].trim();
var lightIcon = split.length > 3 ? split[3].trim() : darkIcon; var lightIcon = split.length > 3 ? split[3].trim() : darkIcon;
ALL.add(new FileType.Simple(id, lightIcon, darkIcon, filter)); ALL.add(new BrowserIconFileType.Simple(id, lightIcon, darkIcon, filter));
} }
} }
}); });
@ -60,7 +60,7 @@ public interface FileType {
String getIcon(); String getIcon();
@Getter @Getter
class Simple implements FileType { class Simple implements BrowserIconFileType {
private final String id; private final String id;
private final IconVariant icon; private final IconVariant icon;

View file

@ -7,18 +7,18 @@ import io.xpipe.core.store.FileSystem;
public class BrowserIcons { public class BrowserIcons {
public static Comp<?> createDefaultFileIcon() { public static Comp<?> createDefaultFileIcon() {
return PrettyImageHelper.ofFixedSquare("default_file.svg", 22); return PrettyImageHelper.ofFixedSizeSquare("default_file.svg", 22);
} }
public static Comp<?> createDefaultDirectoryIcon() { public static Comp<?> createDefaultDirectoryIcon() {
return PrettyImageHelper.ofFixedSquare("default_folder.svg", 22); return PrettyImageHelper.ofFixedSizeSquare("default_folder.svg", 22);
} }
public static Comp<?> createIcon(FileType type) { public static Comp<?> createIcon(BrowserIconFileType type) {
return PrettyImageHelper.ofFixedSquare(type.getIcon(), 22); return PrettyImageHelper.ofFixedSizeSquare(type.getIcon(), 22);
} }
public static Comp<?> createIcon(FileSystem.FileEntry entry) { public static Comp<?> createIcon(FileSystem.FileEntry entry) {
return PrettyImageHelper.ofFixedSquare(FileIconManager.getFileIcon(entry, false), 22); return PrettyImageHelper.ofFixedSizeSquare(FileIconManager.getFileIcon(entry, false), 22);
} }
} }

View file

@ -25,13 +25,13 @@ public class FileIconManager {
var r = entry.resolved(); var r = entry.resolved();
if (r.getKind() != FileKind.DIRECTORY) { if (r.getKind() != FileKind.DIRECTORY) {
for (var f : FileType.ALL) { for (var f : BrowserIconFileType.ALL) {
if (f.matches(r)) { if (f.matches(r)) {
return getIconPath(f.getIcon()); return getIconPath(f.getIcon());
} }
} }
} else { } else {
for (var f : DirectoryType.ALL) { for (var f : BrowserIconDirectoryType.ALL) {
if (f.matches(r)) { if (f.matches(r)) {
return getIconPath(f.getIcon(r, open)); return getIconPath(f.getIcon(r, open));
} }

View file

@ -3,7 +3,7 @@ package io.xpipe.app.comp.base;
import io.xpipe.app.comp.store.StoreEntryWrapper; import io.xpipe.app.comp.store.StoreEntryWrapper;
import io.xpipe.app.core.AppResources; import io.xpipe.app.core.AppResources;
import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.PrettyImageHelper; import io.xpipe.app.fxcomps.impl.PrettyImageComp;
import io.xpipe.app.fxcomps.impl.StackComp; import io.xpipe.app.fxcomps.impl.StackComp;
import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.core.process.OsNameState; import io.xpipe.core.process.OsNameState;
@ -55,7 +55,7 @@ public class OsLogoComp extends SimpleComp {
var hide = BindingsHelper.map(img, s -> s != null); var hide = BindingsHelper.map(img, s -> s != null);
return new StackComp(List.of( return new StackComp(List.of(
new SystemStateComp(state).hide(hide), new SystemStateComp(state).hide(hide),
PrettyImageHelper.ofRasterized(img, 24, 24).visible(hide))) new PrettyImageComp(img, 24, 24).visible(hide)))
.createRegion(); .createRegion();
} }

View file

@ -82,7 +82,7 @@ public class StoreCreationMenu {
}); });
sub.forEach(dataStoreProvider -> { sub.forEach(dataStoreProvider -> {
var item = new MenuItem(dataStoreProvider.getDisplayName()); var item = new MenuItem(dataStoreProvider.getDisplayName());
item.setGraphic(PrettyImageHelper.ofFixedSmallSquare(dataStoreProvider.getDisplayIconFileName(null)) item.setGraphic(PrettyImageHelper.ofFixedSizeSquare(dataStoreProvider.getDisplayIconFileName(null), 16)
.createRegion()); .createRegion());
item.setOnAction(event -> { item.setOnAction(event -> {
StoreCreationComp.showCreation(dataStoreProvider, category); StoreCreationComp.showCreation(dataStoreProvider, category);

View file

@ -4,7 +4,7 @@ import atlantafx.base.theme.Styles;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.PrettyImageHelper; import io.xpipe.app.fxcomps.impl.PrettySvgComp;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.util.ScanAlert; import io.xpipe.app.util.ScanAlert;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
@ -35,7 +35,7 @@ public class StoreIntroComp extends SimpleComp {
var scanPane = new StackPane(scanButton); var scanPane = new StackPane(scanButton);
scanPane.setAlignment(Pos.CENTER); scanPane.setAlignment(Pos.CENTER);
var img = PrettyImageHelper.ofSvg(new SimpleStringProperty("Wave.svg"), 80, 150) var img = new PrettySvgComp(new SimpleStringProperty("Wave.svg"), 80, 150)
.createRegion(); .createRegion();
var text = new VBox(title, introDesc); var text = new VBox(title, introDesc);
text.setSpacing(5); text.setSpacing(5);

View file

@ -62,9 +62,7 @@ public class StoreQuickAccessButtonComp extends SimpleComp {
var graphic = var graphic =
w.getEntry().getProvider().getDisplayIconFileName(w.getEntry().getStore()); w.getEntry().getProvider().getDisplayIconFileName(w.getEntry().getStore());
if (c.isEmpty()) { if (c.isEmpty()) {
var item = new MenuItem( var item = new MenuItem(w.getName().getValue(), PrettyImageHelper.ofFixedSizeSquare(graphic, 16).createRegion());
w.getName().getValue(),
PrettyImageHelper.ofFixedSquare(graphic, 16).createRegion());
item.setOnAction(event -> { item.setOnAction(event -> {
action.accept(w); action.accept(w);
contextMenu.hide(); contextMenu.hide();
@ -81,9 +79,7 @@ public class StoreQuickAccessButtonComp extends SimpleComp {
items.add(recurse(contextMenu, sub)); items.add(recurse(contextMenu, sub));
} }
var m = new Menu( var m = new Menu(w.getName().getValue(), PrettyImageHelper.ofFixedSizeSquare(graphic, 16).createRegion());
w.getName().getValue(),
PrettyImageHelper.ofFixedSquare(graphic, 16).createRegion());
m.getItems().setAll(items); m.getItems().setAll(items);
m.setOnAction(event -> { m.setOnAction(event -> {
if (event.getTarget() == m) { if (event.getTarget() == m) {

View file

@ -59,12 +59,12 @@ public class StoreSectionMiniComp extends Comp<CompStructure<VBox>> {
.apply(struc -> { .apply(struc -> {
var provider = section.getWrapper().getEntry().getProvider(); var provider = section.getWrapper().getEntry().getProvider();
struc.get() struc.get()
.setGraphic(PrettyImageHelper.ofFixedSmallSquare( .setGraphic(PrettyImageHelper.ofFixedSizeSquare(
provider != null provider != null
? provider.getDisplayIconFileName(section.getWrapper() ? provider.getDisplayIconFileName(section.getWrapper()
.getEntry() .getEntry()
.getStore()) .getStore())
: null) : null, 16)
.createRegion()); .createRegion());
}) })
.apply(struc -> { .apply(struc -> {

View file

@ -186,12 +186,10 @@ public class DataStoreChoiceComp<T extends DataStore> extends SimpleComp {
button.apply(struc -> { button.apply(struc -> {
struc.get().setMaxWidth(2000); struc.get().setMaxWidth(2000);
struc.get().setAlignment(Pos.CENTER_LEFT); struc.get().setAlignment(Pos.CENTER_LEFT);
Comp<?> graphic = PrettyImageHelper.ofSvg( Comp<?> graphic = new PrettySvgComp(Bindings.createStringBinding(() -> {
Bindings.createStringBinding( if (selected.getValue() == null) {
() -> { return null;
if (selected.getValue() == null) { }
return null;
}
return selected.getValue() return selected.getValue()
.get() .get()

View file

@ -41,8 +41,8 @@ public class DataStoreListChoiceComp<T extends DataStore> extends SimpleComp {
} }
var label = new LabelComp(t.get().getName()).apply(struc -> struc.get() var label = new LabelComp(t.get().getName()).apply(struc -> struc.get()
.setGraphic(PrettyImageHelper.ofFixedSmallSquare( .setGraphic(PrettyImageHelper.ofFixedSizeSquare(
t.get().getProvider().getDisplayIconFileName(t.getStore())) t.get().getProvider().getDisplayIconFileName(t.getStore()), 16)
.createRegion())); .createRegion()));
var delete = new IconButtonComp("mdal-delete_outline", () -> { var delete = new IconButtonComp("mdal-delete_outline", () -> {
selectedList.remove(t); selectedList.remove(t);

View file

@ -23,7 +23,7 @@ public class PrettyImageComp extends SimpleComp {
private final double width; private final double width;
private final double height; private final double height;
PrettyImageComp(ObservableValue<String> value, double width, double height) { public PrettyImageComp(ObservableValue<String> value, double width, double height) {
this.value = value; this.value = value;
this.width = width; this.width = width;
this.height = height; this.height = height;
@ -74,13 +74,14 @@ public class PrettyImageComp extends SimpleComp {
return null; return null;
} }
if (AppImages.hasNormalImage(image.getValue())) { var value = image.getValue();
return AppImages.image(image.getValue()); if (AppImages.hasNormalImage(value)) {
} else if (AppImages.hasNormalImage(image.getValue().replace("-dark", ""))) { return AppImages.image(value);
return AppImages.image(image.getValue().replace("-dark", "")); } else if (AppImages.hasNormalImage(value.replace("-dark", ""))) {
return AppImages.image(value.replace("-dark", ""));
} else { } else {
TrackEvent.withWarn("Image file not found") TrackEvent.withWarn("Image file not found")
.tag("file", image.getValue()) .tag("file", value)
.handle(); .handle();
return null; return null;
} }

View file

@ -2,6 +2,7 @@ package io.xpipe.app.fxcomps.impl;
import io.xpipe.app.core.AppImages; import io.xpipe.app.core.AppImages;
import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.core.store.FileNames; import io.xpipe.core.store.FileNames;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
@ -10,19 +11,19 @@ import java.util.Optional;
public class PrettyImageHelper { public class PrettyImageHelper {
public static Optional<Comp<?>> rasterizedIfExists(String img, int width, int height) { private static Optional<String> rasterizedImageIfExists(String img, int width, int height) {
if (img != null && img.endsWith(".svg")) { if (img != null && img.endsWith(".svg")) {
var base = FileNames.getBaseName(img); var base = FileNames.getBaseName(img);
var renderedName = base + "-" + height + ".png"; var renderedName = base + "-" + height + ".png";
if (AppImages.hasNormalImage(base + "-" + height + ".png")) { if (AppImages.hasNormalImage(base + "-" + height + ".png")) {
return Optional.of(new PrettyImageComp(new SimpleStringProperty(renderedName), width, height)); return Optional.of(renderedName);
} }
} }
return Optional.empty(); return Optional.empty();
} }
public static Comp<?> ofFixedSquare(String img, int size) { public static Comp<?> ofFixedSizeSquare(String img, int size) {
return ofFixedSize(img, size, size); return ofFixedSize(img, size, size);
} }
@ -31,9 +32,9 @@ public class PrettyImageHelper {
return new PrettyImageComp(new SimpleStringProperty(null), w, h); return new PrettyImageComp(new SimpleStringProperty(null), w, h);
} }
var rasterized = rasterizedIfExists(img, w, h); var rasterized = rasterizedImageIfExists(img, w, h);
if (rasterized.isPresent()) { if (rasterized.isPresent()) {
return rasterized.get(); return new PrettyImageComp(new SimpleStringProperty(rasterized.get()), w, h);
} else { } else {
return img.endsWith(".svg") return img.endsWith(".svg")
? new PrettySvgComp(new SimpleStringProperty(img), w, h) ? new PrettySvgComp(new SimpleStringProperty(img), w, h)
@ -41,15 +42,14 @@ public class PrettyImageHelper {
} }
} }
public static Comp<?> ofSvg(ObservableValue<String> img, int w, int h) { public static Comp<?> ofFixedSize(ObservableValue<String> img, int w, int h) {
return new PrettySvgComp(img, w, h); if (img == null) {
} return new PrettyImageComp(new SimpleStringProperty(null), w, h);
}
public static Comp<?> ofRasterized(ObservableValue<String> img, int w, int h) { var binding = BindingsHelper.map(img, s -> {
return new PrettyImageComp(img, w, h); return rasterizedImageIfExists(s, w, h).orElse(s);
} });
return new PrettyImageComp(binding, w, h);
public static Comp<?> ofFixedSmallSquare(String img) {
return ofFixedSize(img, 16, 16);
} }
} }

View file

@ -65,7 +65,7 @@ public class JfxHelper {
} }
var size = 40; var size = 40;
var graphic = PrettyImageHelper.ofFixedSquare(image, size).createRegion(); var graphic = PrettyImageHelper.ofFixedSizeSquare(image, size).createRegion();
var hbox = new HBox(graphic, text); var hbox = new HBox(graphic, text);
hbox.setAlignment(Pos.CENTER_LEFT); hbox.setAlignment(Pos.CENTER_LEFT);

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 931 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 989 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,017 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 990 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,000 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 608 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 807 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 889 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,011 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 987 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 774 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,006 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,007 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

Some files were not shown because too many files have changed in this diff Show more