简化 VersionIconType 相关代码 (#2669)

This commit is contained in:
Glavo
2024-01-23 11:03:25 +08:00
committed by GitHub
parent 9bdf08af1e
commit 308086b876
7 changed files with 56 additions and 57 deletions

View File

@@ -43,7 +43,9 @@ import org.jackhuang.hmcl.util.versioning.VersionNumber;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
@@ -52,7 +54,6 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.ui.FXUtils.newBuiltinImage;
import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.Pair.pair;
@@ -263,36 +264,43 @@ public class HMCLGameRepository extends DefaultGameRepository {
public Image getVersionIconImage(String id) {
if (id == null || !isLoaded())
return newBuiltinImage("/assets/img/grass.png");
return VersionIconType.DEFAULT.getIcon();
VersionSetting vs = getLocalVersionSettingOrCreate(id);
VersionIconType iconType = Optional.ofNullable(vs).map(VersionSetting::getVersionIcon).orElse(VersionIconType.DEFAULT);
VersionIconType iconType = vs != null ? Lang.requireNonNullElse(vs.getVersionIcon(), VersionIconType.DEFAULT) : VersionIconType.DEFAULT;
if (iconType == VersionIconType.DEFAULT) {
Version version = getVersion(id).resolve(this);
File iconFile = getVersionIconFile(id);
if (iconFile.exists())
return new Image("file:" + iconFile.getAbsolutePath());
else if (LibraryAnalyzer.isModded(this, version)) {
if (iconFile.exists()) {
try (InputStream inputStream = new FileInputStream(iconFile)) {
return new Image(inputStream);
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to load version icon of " + id, e);
}
}
if (LibraryAnalyzer.isModded(this, version)) {
LibraryAnalyzer libraryAnalyzer = LibraryAnalyzer.analyze(version);
if (libraryAnalyzer.has(LibraryAnalyzer.LibraryType.FABRIC))
return newBuiltinImage("/assets/img/fabric.png");
return VersionIconType.FABRIC.getIcon();
else if (libraryAnalyzer.has(LibraryAnalyzer.LibraryType.FORGE))
return newBuiltinImage("/assets/img/forge.png");
return VersionIconType.FORGE.getIcon();
else if (libraryAnalyzer.has(LibraryAnalyzer.LibraryType.NEO_FORGE))
return newBuiltinImage("/assets/img/neoforge.png");
return VersionIconType.NEO_FORGE.getIcon();
else if (libraryAnalyzer.has(LibraryAnalyzer.LibraryType.QUILT))
return newBuiltinImage("/assets/img/quilt.png");
return VersionIconType.QUILT.getIcon();
else if (libraryAnalyzer.has(LibraryAnalyzer.LibraryType.OPTIFINE))
return newBuiltinImage("/assets/img/command.png");
return VersionIconType.COMMAND.getIcon();
else if (libraryAnalyzer.has(LibraryAnalyzer.LibraryType.LITELOADER))
return newBuiltinImage("/assets/img/chicken.png");
return VersionIconType.CHICKEN.getIcon();
else
return newBuiltinImage("/assets/img/furnace.png");
} else
return newBuiltinImage("/assets/img/grass.png");
return VersionIconType.FURNACE.getIcon();
}
return VersionIconType.DEFAULT.getIcon();
} else {
return newBuiltinImage(iconType.getResourceUrl());
return iconType.getIcon();
}
}

View File

@@ -17,6 +17,9 @@
*/
package org.jackhuang.hmcl.setting;
import javafx.scene.image.Image;
import org.jackhuang.hmcl.ui.FXUtils;
public enum VersionIconType {
DEFAULT("/assets/img/grass.png"),
@@ -39,7 +42,7 @@ public enum VersionIconType {
this.resourceUrl = resourceUrl;
}
public String getResourceUrl() {
return resourceUrl;
public Image getIcon() {
return FXUtils.newBuiltinImage(resourceUrl);
}
}

View File

@@ -101,11 +101,10 @@ public final class FXUtils {
public static final String DEFAULT_MONOSPACE_FONT = OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS ? "Consolas" : "Monospace";
private static final Map<String, Image> builtinImageCache = new ConcurrentHashMap<>();
private static final Map<String, Path> remoteImageCache = new ConcurrentHashMap<>();
public static void shutdown() {
for (Map.Entry<String, Path> entry: remoteImageCache.entrySet()) {
for (Map.Entry<String, Path> entry : remoteImageCache.entrySet()) {
try {
Files.deleteIfExists(entry.getValue());
} catch (IOException e) {
@@ -686,13 +685,11 @@ public final class FXUtils {
* @see ResourceNotFoundError
*/
public static Image newBuiltinImage(String url) {
return builtinImageCache.computeIfAbsent(url, s -> {
try {
return new Image(s);
} catch (IllegalArgumentException e) {
throw new ResourceNotFoundError("Cannot access image: " + s, e);
}
});
try {
return builtinImageCache.computeIfAbsent(url, Image::new);
} catch (IllegalArgumentException e) {
throw new ResourceNotFoundError("Cannot access image: " + url, e);
}
}
/**

View File

@@ -35,6 +35,7 @@ import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.setting.Theme;
import org.jackhuang.hmcl.setting.VersionIconType;
import org.jackhuang.hmcl.ui.construct.RipplerContainer;
import org.jackhuang.hmcl.util.i18n.I18n;
@@ -46,7 +47,7 @@ import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
*/
public class InstallerItem extends Control {
private final String id;
private final String imageUrl;
private final VersionIconType iconType;
public final StringProperty libraryVersion = new SimpleStringProperty();
public final StringProperty incompatibleLibraryName = new SimpleStringProperty();
public final StringProperty dependencyName = new SimpleStringProperty();
@@ -73,30 +74,30 @@ public class InstallerItem extends Control {
switch (id) {
case "game":
imageUrl = "/assets/img/grass.png";
iconType = VersionIconType.GRASS;
break;
case "fabric":
case "fabric-api":
imageUrl = "/assets/img/fabric.png";
iconType = VersionIconType.FABRIC;
break;
case "forge":
imageUrl = "/assets/img/forge.png";
iconType = VersionIconType.FORGE;
break;
case "liteloader":
imageUrl = "/assets/img/chicken.png";
iconType = VersionIconType.CHICKEN;
break;
case "optifine":
imageUrl = "/assets/img/command.png";
iconType = VersionIconType.COMMAND;
break;
case "quilt":
case "quilt-api":
imageUrl = "/assets/img/quilt.png";
iconType = VersionIconType.QUILT;
break;
case "neoforge":
imageUrl = "/assets/img/neoforge.png";
iconType = VersionIconType.NEO_FORGE;
break;
default:
imageUrl = null;
iconType = null;
break;
}
}
@@ -221,8 +222,8 @@ public class InstallerItem extends Control {
pane.pseudoClassStateChanged(LIST_ITEM, control.style == Style.LIST_ITEM);
pane.pseudoClassStateChanged(CARD, control.style == Style.CARD);
if (control.imageUrl != null) {
ImageView view = new ImageView(FXUtils.newBuiltinImage(control.imageUrl));
if (control.iconType != null) {
ImageView view = new ImageView(control.iconType.getIcon());
Node node = FXUtils.limitingSize(view, 32, 32);
node.setMouseTransparent(true);
node.getStyleClass().add("installer-item-image");

View File

@@ -26,7 +26,6 @@ import javafx.beans.InvalidationListener;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.image.Image;
import javafx.scene.layout.*;
import org.jackhuang.hmcl.download.DownloadProvider;
import org.jackhuang.hmcl.download.RemoteVersion;
@@ -42,7 +41,6 @@ import org.jackhuang.hmcl.download.quilt.QuiltAPIRemoteVersion;
import org.jackhuang.hmcl.download.quilt.QuiltRemoteVersion;
import org.jackhuang.hmcl.setting.Theme;
import org.jackhuang.hmcl.setting.VersionIconType;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.SVG;
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
import org.jackhuang.hmcl.ui.animation.TransitionPane;
@@ -56,7 +54,6 @@ import org.jackhuang.hmcl.ui.wizard.WizardPage;
import org.jackhuang.hmcl.util.HMCLService;
import org.jackhuang.hmcl.util.Holder;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@@ -182,8 +179,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
btnRefresh.setGraphic(wrap(SVG.REFRESH.createIcon(Theme.blackFill(), -1, -1)));
Holder<RemoteVersionListCell> lastCell = new Holder<>();
EnumMap<VersionIconType, Image> icons = new EnumMap<>(VersionIconType.class);
list.setCellFactory(listView -> new RemoteVersionListCell(lastCell, icons));
list.setCellFactory(listView -> new RemoteVersionListCell(lastCell));
list.setOnMouseClicked(e -> {
if (list.getSelectionModel().getSelectedIndex() < 0)
@@ -276,21 +272,15 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
final StackPane pane = new StackPane();
private final Holder<RemoteVersionListCell> lastCell;
private final EnumMap<VersionIconType, Image> icons;
RemoteVersionListCell(Holder<RemoteVersionListCell> lastCell, EnumMap<VersionIconType, Image> icons) {
RemoteVersionListCell(Holder<RemoteVersionListCell> lastCell) {
this.lastCell = lastCell;
this.icons = icons;
pane.getStyleClass().add("md-list-cell");
StackPane.setMargin(content, new Insets(10, 16, 10, 16));
pane.getChildren().setAll(ripplerContainer);
}
private Image getIcon(VersionIconType type) {
return icons.computeIfAbsent(type, iconType -> FXUtils.newBuiltinImage(iconType.getResourceUrl()));
}
@Override
public void updateItem(RemoteVersion remoteVersion, boolean empty) {
super.updateItem(remoteVersion, empty);
@@ -317,15 +307,15 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
switch (remoteVersion.getVersionType()) {
case RELEASE:
content.getTags().setAll(i18n("version.game.release"));
content.setImage(getIcon(VersionIconType.GRASS));
content.setImage(VersionIconType.GRASS.getIcon());
break;
case SNAPSHOT:
content.getTags().setAll(i18n("version.game.snapshot"));
content.setImage(getIcon(VersionIconType.COMMAND));
content.setImage(VersionIconType.COMMAND.getIcon());
break;
default:
content.getTags().setAll(i18n("version.game.old"));
content.setImage(getIcon(VersionIconType.CRAFT_TABLE));
content.setImage(VersionIconType.CRAFT_TABLE.getIcon());
break;
}
} else {
@@ -345,7 +335,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
else
iconType = null;
content.setImage(iconType != null ? getIcon(iconType) : null);
content.setImage(iconType != null ? iconType.getIcon() : null);
if (content.getSubtitle() == null)
content.setSubtitle(remoteVersion.getGameVersion());
else

View File

@@ -23,6 +23,7 @@ import javafx.scene.image.ImageView;
import org.jackhuang.hmcl.event.Event;
import org.jackhuang.hmcl.setting.Profile;
import org.jackhuang.hmcl.setting.Profiles;
import org.jackhuang.hmcl.setting.VersionIconType;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.WeakListenerHolder;
import org.jackhuang.hmcl.ui.construct.AdvancedListItem;
@@ -30,7 +31,6 @@ import org.jackhuang.hmcl.util.Pair;
import java.util.function.Consumer;
import static org.jackhuang.hmcl.ui.FXUtils.newBuiltinImage;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class GameAdvancedListItem extends AdvancedListItem {
@@ -72,7 +72,7 @@ public class GameAdvancedListItem extends AdvancedListItem {
Tooltip.uninstall(this,tooltip);
setTitle(i18n("version.empty"));
setSubtitle(i18n("version.empty.add"));
imageView.setImage(newBuiltinImage("/assets/img/grass.png"));
imageView.setImage(VersionIconType.DEFAULT.getIcon());
tooltip.setText("");
}
}

View File

@@ -104,7 +104,7 @@ public class VersionIconDialog extends DialogPane {
}
private Node createIcon(VersionIconType type) {
ImageView imageView = new ImageView(FXUtils.newBuiltinImage(type.getResourceUrl()));
ImageView imageView = new ImageView(type.getIcon());
imageView.setMouseTransparent(true);
RipplerContainer container = new RipplerContainer(imageView);
FXUtils.setLimitWidth(container, 36);