diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerItem.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerItem.java index c34d99970..ef3503ae3 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerItem.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/InstallerItem.java @@ -19,12 +19,16 @@ package org.jackhuang.hmcl.ui; import com.jfoenix.controls.JFXButton; import com.jfoenix.effects.JFXDepthManager; +import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.ui.construct.TwoLineListItem; +import org.jackhuang.hmcl.util.i18n.I18n; import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; @@ -36,21 +40,45 @@ import static org.jackhuang.hmcl.util.i18n.I18n.i18n; */ public class InstallerItem extends BorderPane { - public InstallerItem(String artifact, String version, @Nullable Runnable upgrade, @Nullable Consumer deleteCallback) { + public InstallerItem(String libraryId, String libraryVersion, @Nullable Runnable upgrade, @Nullable Consumer deleteCallback) { getStyleClass().add("two-line-list-item"); setStyle("-fx-background-radius: 2; -fx-background-color: white; -fx-padding: 8;"); JFXDepthManager.setDepth(this, 1); - if (version != null) { - TwoLineListItem item = new TwoLineListItem(); - item.setTitle(artifact); - item.setSubtitle(i18n("archive.version") + ": " + version); - setCenter(item); - } else { - Label label = new Label(artifact); - label.setStyle("-fx-font-size: 15px;"); - BorderPane.setAlignment(label, Pos.CENTER_LEFT); - setCenter(label); + String[] urls = new String[]{"/assets/img/grass.png", "/assets/img/fabric.png", "/assets/img/forge.png", "/assets/img/chicken.png", "/assets/img/command.png"}; + String[] libraryIds = new String[]{"game", "fabric", "forge", "liteloader", "optifine"}; + + boolean regularLibrary = false; + for (int i = 0; i < 5; ++i) { + if (libraryIds[i].equals(libraryId)) { + setLeft(FXUtils.limitingSize(new ImageView(new Image(urls[i], 32, 32, true, true)), 32, 32)); + Label label = new Label(); + BorderPane.setAlignment(label, Pos.CENTER_LEFT); + BorderPane.setMargin(label, new Insets(0, 0, 0, 8)); + if (libraryVersion == null) { + label.setText(i18n("install.installer.not_installed", i18n("install.installer." + libraryId))); + } else { + label.setText(i18n("install.installer.version", i18n("install.installer." + libraryId)) + ": " + libraryVersion); + } + setCenter(label); + regularLibrary = true; + break; + } + } + + if (!regularLibrary) { + String title = I18n.hasKey("install.installer." + libraryId) ? i18n("install.installer." + libraryId) : libraryId; + if (libraryVersion != null) { + TwoLineListItem item = new TwoLineListItem(); + item.setTitle(title); + item.setSubtitle(i18n("archive.version") + ": " + libraryVersion); + setCenter(item); + } else { + Label label = new Label(); + label.setStyle("-fx-font-size: 15px;"); + BorderPane.setAlignment(label, Pos.CENTER_LEFT); + setCenter(label); + } } { @@ -58,7 +86,11 @@ public class InstallerItem extends BorderPane { if (upgrade != null) { JFXButton upgradeButton = new JFXButton(); - upgradeButton.setGraphic(SVG.update(Theme.blackFillBinding(), -1, -1)); + if (libraryVersion == null) { + upgradeButton.setGraphic(SVG.arrowRight(Theme.blackFillBinding(), -1, -1)); + } else { + upgradeButton.setGraphic(SVG.update(Theme.blackFillBinding(), -1, -1)); + } upgradeButton.getStyleClass().add("toggle-icon4"); FXUtils.installFastTooltip(upgradeButton, i18n("install.change_version")); upgradeButton.setOnMouseClicked(e -> upgrade.run()); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FloatListCell.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FloatListCell.java index 5bc940d36..383f9322d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FloatListCell.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FloatListCell.java @@ -18,12 +18,16 @@ package org.jackhuang.hmcl.ui.construct; import com.jfoenix.effects.JFXDepthManager; +import javafx.css.PseudoClass; import javafx.geometry.Insets; import javafx.scene.Cursor; import javafx.scene.control.ListCell; import javafx.scene.layout.StackPane; +import org.jackhuang.hmcl.ui.FXUtils; public abstract class FloatListCell extends ListCell { + private final PseudoClass SELECTED = PseudoClass.getPseudoClass("selected"); + protected final StackPane pane = new StackPane(); { @@ -35,6 +39,10 @@ public abstract class FloatListCell extends ListCell { pane.setPadding(new Insets(8)); setPadding(new Insets(5)); JFXDepthManager.setDepth(pane, 1); + + FXUtils.onChangeAndOperate(selectedProperty(), selected -> { + pane.pseudoClassStateChanged(SELECTED, selected); + }); } @Override diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallersPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallersPage.java index 263b50b34..eec131442 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallersPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/InstallersPage.java @@ -21,10 +21,8 @@ import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXTextField; import com.jfoenix.effects.JFXDepthManager; import javafx.fxml.FXML; -import javafx.geometry.Insets; import javafx.scene.Node; import javafx.scene.control.Label; -import javafx.scene.layout.BorderPane; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import org.jackhuang.hmcl.download.DownloadProvider; @@ -34,11 +32,9 @@ import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.construct.Validator; import org.jackhuang.hmcl.ui.wizard.WizardController; import org.jackhuang.hmcl.ui.wizard.WizardPage; -import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.platform.OperatingSystem; -import java.nio.file.Paths; import java.util.Map; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; @@ -98,7 +94,6 @@ public class InstallersPage extends StackPane implements WizardPage { txtName.textProperty().addListener(e -> btnInstall.setDisable(!txtName.validate())); txtName.setText(gameVersion); - Label[] labels = new Label[]{lblGame, lblFabric, lblForge, lblLiteLoader, lblOptiFine}; Node[] buttons = new Node[]{btnGame, btnFabric, btnForge, btnLiteLoader, btnOptiFine}; String[] libraryIds = new String[]{"game", "fabric", "forge", "liteloader", "optifine"}; @@ -108,7 +103,6 @@ public class InstallersPage extends StackPane implements WizardPage { for (int i = 0; i < libraryIds.length; ++i) { String libraryId = libraryIds[i]; - BorderPane.setMargin(labels[i], new Insets(0, 0, 0, 8)); if (libraryId.equals("game")) continue; buttons[i].setOnMouseClicked(e -> controller.onNext(new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, downloadProvider, libraryId, () -> controller.onPrev(false)))); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/UpdateInstallerWizardProvider.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/UpdateInstallerWizardProvider.java index 20aa3ec76..88755d8ea 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/UpdateInstallerWizardProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/UpdateInstallerWizardProvider.java @@ -26,6 +26,7 @@ import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.wizard.WizardController; import org.jackhuang.hmcl.ui.wizard.WizardProvider; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Map; @@ -39,7 +40,7 @@ public final class UpdateInstallerWizardProvider implements WizardProvider { private final String libraryId; private final String oldLibraryVersion; - public UpdateInstallerWizardProvider(@NotNull Profile profile, @NotNull String gameVersion, @NotNull Version version, @NotNull String libraryId, @NotNull String oldLibraryVersion) { + public UpdateInstallerWizardProvider(@NotNull Profile profile, @NotNull String gameVersion, @NotNull Version version, @NotNull String libraryId, @Nullable String oldLibraryVersion) { this.profile = profile; this.gameVersion = gameVersion; this.version = version; @@ -69,8 +70,12 @@ public final class UpdateInstallerWizardProvider implements WizardProvider { switch (step) { case 0: return new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, provider, libraryId, () -> { - Controllers.confirmDialog(i18n("install.change_version.confirm", i18n("install.installer." + libraryId), oldLibraryVersion, ((RemoteVersion) settings.get(libraryId)).getSelfVersion()), - i18n("install.change_version"), controller::onFinish, controller::onCancel); + if (oldLibraryVersion == null) { + controller.onFinish(); + } else { + Controllers.confirmDialog(i18n("install.change_version.confirm", i18n("install.installer." + libraryId), oldLibraryVersion, ((RemoteVersion) settings.get(libraryId)).getSelfVersion()), + i18n("install.change_version"), controller::onFinish, controller::onCancel); + } }); default: throw new IllegalStateException(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java index 450241d11..f8049305b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/InstallerListPage.java @@ -33,11 +33,11 @@ import org.jackhuang.hmcl.ui.*; import org.jackhuang.hmcl.ui.download.InstallerWizardProvider; import org.jackhuang.hmcl.ui.download.UpdateInstallerWizardProvider; import org.jackhuang.hmcl.util.Lang; -import org.jackhuang.hmcl.util.i18n.I18n; import org.jackhuang.hmcl.util.io.FileUtils; import java.io.File; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; @@ -84,18 +84,32 @@ public class InstallerListPage extends ListPageBase { }; itemsProperty().clear(); + + for (LibraryAnalyzer.LibraryType type : LibraryAnalyzer.LibraryType.values()) { + String libraryId = type.getPatchId(); + String libraryVersion = analyzer.getVersion(type).orElse(null); + Consumer action = libraryVersion == null ? null : removeAction.apply(libraryId); + itemsProperty().add(new InstallerItem(libraryId, libraryVersion, () -> { + Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, libraryId, libraryVersion)); + }, action)); + } + for (LibraryAnalyzer.LibraryMark mark : analyzer) { String libraryId = mark.getLibraryId(); String libraryVersion = mark.getLibraryVersion(); - String title = I18n.hasKey("install.installer." + libraryId) ? i18n("install.installer." + libraryId) : libraryId; - Consumer action = "game".equals(libraryId) ? null : removeAction.apply(libraryId); + + // we have done this library above. + if (LibraryAnalyzer.LibraryType.fromPatchId(libraryId) != null) + continue; + + Consumer action = removeAction.apply(libraryId); if (libraryVersion != null && Lang.test(() -> profile.getDependency().getVersionList(libraryId))) itemsProperty().add( - new InstallerItem(title, libraryVersion, () -> { + new InstallerItem(libraryId, libraryVersion, () -> { Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, libraryId, libraryVersion)); }, action)); else - itemsProperty().add(new InstallerItem(title, libraryVersion, null, action)); + itemsProperty().add(new InstallerItem(libraryId, libraryVersion, null, action)); } }, Platform::runLater); } @@ -145,8 +159,7 @@ public class InstallerListPage extends ListPageBase { @Override protected List initializeToolbar(InstallerListPage skinnable) { - return Arrays.asList( - createToolbarButton(i18n("install.installer.install_online"), SVG::plus, skinnable::installOnline), + return Collections.singletonList( createToolbarButton(i18n("install.installer.install_offline"), SVG::plus, skinnable::installOffline)); } } diff --git a/HMCL/src/main/resources/assets/css/root.css b/HMCL/src/main/resources/assets/css/root.css index bb88e4680..8fe972b53 100644 --- a/HMCL/src/main/resources/assets/css/root.css +++ b/HMCL/src/main/resources/assets/css/root.css @@ -685,6 +685,10 @@ -fx-background-radius: 4; } +.card:selected { + -fx-background-color: derive(-fx-base-color, 60%); +} + .options-sublist { -fx-background-color: white; } diff --git a/HMCL/src/main/resources/assets/fxml/download/installers.fxml b/HMCL/src/main/resources/assets/fxml/download/installers.fxml index a15b4e634..f18b275af 100644 --- a/HMCL/src/main/resources/assets/fxml/download/installers.fxml +++ b/HMCL/src/main/resources/assets/fxml/download/installers.fxml @@ -5,10 +5,13 @@ - + + + +
@@ -23,7 +26,7 @@
-
@@ -33,7 +36,7 @@
-
@@ -46,7 +49,7 @@
-
@@ -59,7 +62,7 @@
-
@@ -72,7 +75,7 @@
-