From 6ad5ba37363f504f837be09fe9bf884771e50c45 Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Fri, 21 Feb 2020 00:10:16 +0800 Subject: [PATCH] alt: change UI of game installation wizard. Also UI performance improved. --- .../hmcl/ui/construct/FloatListCell.java | 49 +++++++ .../decorator/DecoratorWizardDisplayer.java | 2 +- .../ui/download/AdditionalInstallersPage.java | 65 ++------- .../hmcl/ui/download/InstallersPage.java | 55 +++++--- .../VanillaInstallWizardProvider.java | 2 +- .../hmcl/ui/download/VersionsPage.java | 73 +++++++++- .../hmcl/ui/download/VersionsPageItem.java | 91 ------------- .../hmcl/ui/versions/ModListPageSkin.java | 2 +- HMCL/src/main/resources/assets/css/root.css | 21 ++- .../assets/fxml/download/installers.fxml | 127 ++++++++++-------- .../assets/fxml/download/versions.fxml | 2 +- .../src/main/resources/assets/img/chicken.png | Bin 4231 -> 10052 bytes HMCL/src/main/resources/assets/img/fabric.png | Bin 0 -> 5867 bytes .../resources/assets/lang/I18N.properties | 2 +- .../resources/assets/lang/I18N_zh.properties | 2 +- .../assets/lang/I18N_zh_CN.properties | 2 +- 16 files changed, 258 insertions(+), 237 deletions(-) create mode 100644 HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FloatListCell.java delete mode 100644 HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPageItem.java create mode 100644 HMCL/src/main/resources/assets/img/fabric.png 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 new file mode 100644 index 000000000..59e6f547a --- /dev/null +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FloatListCell.java @@ -0,0 +1,49 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2020 huangyuhui and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.jackhuang.hmcl.ui.construct; + +import com.jfoenix.effects.JFXDepthManager; +import javafx.geometry.Insets; +import javafx.scene.control.ListCell; +import javafx.scene.layout.StackPane; + +public abstract class FloatListCell extends ListCell { + protected final StackPane pane = new StackPane(); + + { + setText(null); + setGraphic(null); + + pane.setStyle("-fx-background-color: white; -fx-padding: 8; -fx-cursor: HAND"); + setPadding(new Insets(5)); + JFXDepthManager.setDepth(pane, 1); + } + + @Override + protected void updateItem(T item, boolean empty) { + super.updateItem(item, empty); + if (empty) { + setGraphic(null); + } else { + updateControl(item); + setGraphic(pane); + } + } + + protected abstract void updateControl(T dataItem); +} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorWizardDisplayer.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorWizardDisplayer.java index 0cb631235..a6df18718 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorWizardDisplayer.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorWizardDisplayer.java @@ -52,7 +52,7 @@ public class DecoratorWizardDisplayer extends StackPane implements TaskExecutorD wizardController.setProvider(provider); wizardController.onStart(); - getStyleClass().add("white-background"); + // getStyleClass().add("white-background"); } @Override diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/AdditionalInstallersPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/AdditionalInstallersPage.java index ed6bc8702..351f8cf0f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/AdditionalInstallersPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/AdditionalInstallersPage.java @@ -37,60 +37,20 @@ import java.util.Optional; import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.*; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; -class AdditionalInstallersPage extends StackPane implements WizardPage { - private final InstallerWizardProvider provider; - private final WizardController controller; - - @FXML - private VBox list; - @FXML - private JFXButton btnFabric; - @FXML - private JFXButton btnForge; - @FXML - private JFXButton btnLiteLoader; - @FXML - private JFXButton btnOptiFine; - @FXML - private Label lblGameVersion; - @FXML - private Label lblVersionName; - @FXML - private Label lblFabric; - @FXML - private Label lblForge; - @FXML - private Label lblLiteLoader; - @FXML - private Label lblOptiFine; - @FXML - private JFXButton btnInstall; +class AdditionalInstallersPage extends InstallersPage { + protected final InstallerWizardProvider provider; public AdditionalInstallersPage(InstallerWizardProvider provider, WizardController controller, GameRepository repository, DownloadProvider downloadProvider) { + super(controller, repository, provider.getGameVersion(), downloadProvider); this.provider = provider; - this.controller = controller; - FXUtils.loadFXML(this, "/assets/fxml/download/additional-installers.fxml"); - - lblGameVersion.setText(provider.getGameVersion()); - lblVersionName.setText(provider.getVersion().getId()); - - JFXButton[] buttons = new JFXButton[]{btnFabric, btnForge, btnLiteLoader, btnOptiFine}; - String[] libraryIds = new String[]{"fabric", "forge", "liteloader", "optifine"}; - - for (int i = 0; i < libraryIds.length; ++i) { - String libraryId = libraryIds[i]; - buttons[i].setOnMouseClicked(e -> { - controller.onNext(new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), provider.getGameVersion(), downloadProvider, libraryId, () -> { - controller.onPrev(false); - })); - }); - } - - btnInstall.setOnMouseClicked(e -> onInstall()); + txtName.getValidators().clear(); + txtName.setText(provider.getVersion().getId()); + txtName.setEditable(false); } - private void onInstall() { + @Override + protected void onInstall() { controller.onFinish(); } @@ -105,17 +65,16 @@ class AdditionalInstallersPage extends StackPane implements WizardPage { @Override public void onNavigate(Map settings) { - lblGameVersion.setText(i18n("install.new_game.current_game_version") + ": " + provider.getGameVersion()); - LibraryAnalyzer analyzer = LibraryAnalyzer.analyze(provider.getVersion().resolvePreservingPatches(provider.getProfile().getRepository())); + String game = analyzer.getVersion(MINECRAFT).orElse(null); String fabric = analyzer.getVersion(FABRIC).orElse(null); String forge = analyzer.getVersion(FORGE).orElse(null); String liteLoader = analyzer.getVersion(LITELOADER).orElse(null); String optiFine = analyzer.getVersion(OPTIFINE).orElse(null); - Label[] labels = new Label[]{lblFabric, lblForge, lblLiteLoader, lblOptiFine}; - String[] libraryIds = new String[]{"fabric", "forge", "liteloader", "optifine"}; - String[] versions = new String[]{fabric, forge, liteLoader, optiFine}; + Label[] labels = new Label[]{lblGame, lblFabric, lblForge, lblLiteLoader, lblOptiFine}; + String[] libraryIds = new String[]{"game", "fabric", "forge", "liteloader", "optifine"}; + String[] versions = new String[]{game, fabric, forge, liteLoader, optiFine}; for (int i = 0; i < libraryIds.length; ++i) { String libraryId = libraryIds[i]; 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 ed3342559..263b50b34 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 @@ -19,8 +19,12 @@ package org.jackhuang.hmcl.ui.download; 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; @@ -40,50 +44,52 @@ import java.util.Map; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public class InstallersPage extends StackPane implements WizardPage { - private final WizardController controller; + protected final WizardController controller; @FXML - private VBox list; + protected VBox list; @FXML - private JFXButton btnFabric; + protected Node btnGame; @FXML - private JFXButton btnForge; + protected Node btnFabric; @FXML - private JFXButton btnLiteLoader; + protected Node btnForge; @FXML - private JFXButton btnOptiFine; + protected Node btnLiteLoader; @FXML - private Label lblGameVersion; + protected Node btnOptiFine; @FXML - private Label lblFabric; + protected Label lblGame; @FXML - private Label lblForge; + protected Label lblFabric; @FXML - private Label lblLiteLoader; + protected Label lblForge; @FXML - private Label lblOptiFine; + protected Label lblLiteLoader; @FXML - private JFXTextField txtName; + protected Label lblOptiFine; @FXML - private JFXButton btnInstall; + protected JFXTextField txtName; - public InstallersPage(WizardController controller, GameRepository repository, DownloadProvider downloadProvider) { + @FXML + protected JFXButton btnInstall; + + public InstallersPage(WizardController controller, GameRepository repository, String gameVersion, DownloadProvider downloadProvider) { this.controller = controller; FXUtils.loadFXML(this, "/assets/fxml/download/installers.fxml"); - String gameVersion = ((RemoteVersion) controller.getSettings().get("game")).getGameVersion(); Validator hasVersion = new Validator(s -> !repository.hasVersion(s) && StringUtils.isNotBlank(s)); hasVersion.setMessage(i18n("install.new_game.already_exists")); Validator nameValidator = new Validator(OperatingSystem::isNameValid); @@ -92,11 +98,18 @@ public class InstallersPage extends StackPane implements WizardPage { txtName.textProperty().addListener(e -> btnInstall.setDisable(!txtName.validate())); txtName.setText(gameVersion); - JFXButton[] buttons = new JFXButton[]{btnFabric, btnForge, btnLiteLoader, btnOptiFine}; - String[] libraryIds = new String[]{"fabric", "forge", "liteloader", "optifine"}; + 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"}; + + for (Node node : list.getChildren()) { + JFXDepthManager.setDepth(node, 1); + } 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)))); } @@ -113,10 +126,8 @@ public class InstallersPage extends StackPane implements WizardPage { @Override public void onNavigate(Map settings) { - lblGameVersion.setText(i18n("install.new_game.current_game_version") + ": " + getVersion("game")); - - Label[] labels = new Label[]{lblFabric, lblForge, lblLiteLoader, lblOptiFine}; - String[] libraryIds = new String[]{"fabric", "forge", "liteloader", "optifine"}; + Label[] labels = new Label[]{lblGame, lblFabric, lblForge, lblLiteLoader, lblOptiFine}; + String[] libraryIds = new String[]{"game", "fabric", "forge", "liteloader", "optifine"}; for (int i = 0; i < libraryIds.length; ++i) { String libraryId = libraryIds[i]; @@ -132,7 +143,7 @@ public class InstallersPage extends StackPane implements WizardPage { } @FXML - private void onInstall() { + protected void onInstall() { controller.getSettings().put("name", txtName.getText()); controller.onFinish(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VanillaInstallWizardProvider.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VanillaInstallWizardProvider.java index 076eb2c94..a4eb7202c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VanillaInstallWizardProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VanillaInstallWizardProvider.java @@ -72,7 +72,7 @@ public final class VanillaInstallWizardProvider implements WizardProvider { DownloadProvider provider = profile.getDependency().getPrimaryDownloadProvider(); switch (step) { case 0: - return new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer.game")), "", provider, "game", () -> controller.onNext(new InstallersPage(controller, profile.getRepository(), provider))); + return new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer.game")), "", provider, "game", () -> controller.onNext(new InstallersPage(controller, profile.getRepository(), ((RemoteVersion) controller.getSettings().get("game")).getGameVersion(), provider))); default: throw new IllegalStateException("error step " + step + ", settings: " + settings + ", pages: " + controller.getPages()); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java index 075bae4bb..c9461eee2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java @@ -23,16 +23,28 @@ import com.jfoenix.controls.JFXSpinner; import javafx.application.Platform; import javafx.beans.InvalidationListener; import javafx.fxml.FXML; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import org.jackhuang.hmcl.download.DownloadProvider; +import org.jackhuang.hmcl.download.RemoteVersion; import org.jackhuang.hmcl.download.VersionList; +import org.jackhuang.hmcl.download.fabric.FabricRemoteVersion; +import org.jackhuang.hmcl.download.forge.ForgeRemoteVersion; +import org.jackhuang.hmcl.download.game.GameRemoteVersion; +import org.jackhuang.hmcl.download.liteloader.LiteLoaderRemoteVersion; +import org.jackhuang.hmcl.download.optifine.OptiFineRemoteVersion; import org.jackhuang.hmcl.task.TaskExecutor; import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.animation.ContainerAnimations; import org.jackhuang.hmcl.ui.animation.TransitionHandler; +import org.jackhuang.hmcl.ui.construct.FloatListCell; +import org.jackhuang.hmcl.ui.construct.TwoLineListItem; import org.jackhuang.hmcl.ui.wizard.Refreshable; import org.jackhuang.hmcl.ui.wizard.WizardController; import org.jackhuang.hmcl.ui.wizard.WizardPage; @@ -43,6 +55,7 @@ import java.util.logging.Level; import java.util.stream.Collectors; import static org.jackhuang.hmcl.util.Logging.LOG; +import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public final class VersionsPage extends BorderPane implements WizardPage, Refreshable { private final String gameVersion; @@ -51,7 +64,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres private final WizardController controller; @FXML - private JFXListView list; + private JFXListView list; @FXML private JFXSpinner spinner; @FXML @@ -96,16 +109,65 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres chkSnapshot.selectedProperty().addListener(listener); chkOld.selectedProperty().addListener(listener); + list.setCellFactory(listView -> new FloatListCell() { + ImageView imageView = new ImageView(); + TwoLineListItem content = new TwoLineListItem(); + + { + HBox container = new HBox(12); + container.setPadding(new Insets(0, 0, 0, 6)); + container.setAlignment(Pos.CENTER_LEFT); + pane.getChildren().add(container); + + container.getChildren().setAll(imageView, content); + } + + @Override + protected void updateControl(RemoteVersion remoteVersion) { + content.setTitle(remoteVersion.getSelfVersion()); + content.setSubtitle(remoteVersion.getGameVersion()); + + if (remoteVersion instanceof GameRemoteVersion) { + switch (remoteVersion.getVersionType()) { + case RELEASE: + content.setSubtitle(i18n("version.game.release")); + imageView.setImage(new Image("/assets/img/grass.png", 32, 32, false, true)); + break; + case SNAPSHOT: + content.setSubtitle(i18n("version.game.snapshot")); + imageView.setImage(new Image("/assets/img/command.png", 32, 32, false, true)); + break; + default: + content.setSubtitle(i18n("version.game.old")); + imageView.setImage(new Image("/assets/img/craft_table.png", 32, 32, false, true)); + break; + } + } else if (remoteVersion instanceof LiteLoaderRemoteVersion) { + imageView.setImage(new Image("/assets/img/chicken.png", 32, 32, false, true)); + content.setSubtitle(remoteVersion.getGameVersion()); + } else if (remoteVersion instanceof OptiFineRemoteVersion) { + imageView.setImage(new Image("/assets/img/command.png", 32, 32, false, true)); + content.setSubtitle(remoteVersion.getGameVersion()); + } else if (remoteVersion instanceof ForgeRemoteVersion) { + imageView.setImage(new Image("/assets/img/forge.png", 32, 32, false, true)); + content.setSubtitle(remoteVersion.getGameVersion()); + } else if (remoteVersion instanceof FabricRemoteVersion) { + imageView.setImage(new Image("/assets/img/fabric.png", 32, 32, false, true)); + content.setSubtitle(remoteVersion.getGameVersion()); + } + } + }); + list.setOnMouseClicked(e -> { if (list.getSelectionModel().getSelectedIndex() < 0) return; - controller.getSettings().put(libraryId, list.getSelectionModel().getSelectedItem().getRemoteVersion()); + controller.getSettings().put(libraryId, list.getSelectionModel().getSelectedItem()); callback.run(); }); refresh(); } - private List loadVersions() { + private List loadVersions() { return versionList.getVersions(gameVersion).stream() .filter(it -> { switch (it.getVersionType()) { @@ -119,8 +181,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres return true; } }) - .sorted() - .map(VersionsPageItem::new).collect(Collectors.toList()); + .sorted().collect(Collectors.toList()); } @Override @@ -128,7 +189,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres transitionHandler.setContent(spinner, ContainerAnimations.FADE.getAnimationProducer()); executor = versionList.refreshAsync(gameVersion).whenComplete(exception -> { if (exception == null) { - List items = loadVersions(); + List items = loadVersions(); Platform.runLater(() -> { if (versionList.getVersions(gameVersion).isEmpty()) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPageItem.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPageItem.java deleted file mode 100644 index bcfa32bcf..000000000 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPageItem.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Hello Minecraft! Launcher - * Copyright (C) 2020 huangyuhui and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.jackhuang.hmcl.ui.download; - -import javafx.fxml.FXML; -import javafx.scene.control.Label; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.layout.HBox; -import javafx.scene.layout.StackPane; -import org.jackhuang.hmcl.download.RemoteVersion; -import org.jackhuang.hmcl.download.forge.ForgeRemoteVersion; -import org.jackhuang.hmcl.download.game.GameRemoteVersion; -import org.jackhuang.hmcl.download.liteloader.LiteLoaderRemoteVersion; -import org.jackhuang.hmcl.download.optifine.OptiFineRemoteVersion; -import org.jackhuang.hmcl.ui.FXUtils; - -import java.util.Objects; - -import static org.jackhuang.hmcl.util.i18n.I18n.i18n; - -/** - * @author huangyuhui - */ -public final class VersionsPageItem extends StackPane { - private final RemoteVersion remoteVersion; - @FXML - private Label lblSelfVersion; - @FXML - private Label lblGameVersion; - @FXML - private ImageView imageView; - @FXML - private HBox leftPane; - @FXML - private StackPane imageViewContainer; - - public VersionsPageItem(RemoteVersion remoteVersion) { - this.remoteVersion = Objects.requireNonNull(remoteVersion); - - FXUtils.loadFXML(this, "/assets/fxml/download/versions-list-item.fxml"); - lblSelfVersion.setText(remoteVersion.getSelfVersion()); - - if (remoteVersion instanceof GameRemoteVersion) { - switch (remoteVersion.getVersionType()) { - case RELEASE: - lblGameVersion.setText(i18n("version.game.release")); - imageView.setImage(new Image("/assets/img/icon.png", 32, 32, false, true)); - break; - case SNAPSHOT: - lblGameVersion.setText(i18n("version.game.snapshot")); - imageView.setImage(new Image("/assets/img/command.png", 32, 32, false, true)); - break; - default: - lblGameVersion.setText(i18n("version.game.old")); - imageView.setImage(new Image("/assets/img/grass.png", 32, 32, false, true)); - break; - } - } else if (remoteVersion instanceof LiteLoaderRemoteVersion) { - imageView.setImage(new Image("/assets/img/chicken.png", 32, 32, false, true)); - lblGameVersion.setText(remoteVersion.getGameVersion()); - } else if (remoteVersion instanceof OptiFineRemoteVersion) { - // optifine has no icon. - lblGameVersion.setText(remoteVersion.getGameVersion()); - } else if (remoteVersion instanceof ForgeRemoteVersion) { - imageView.setImage(new Image("/assets/img/forge.png", 32, 32, false, true)); - lblGameVersion.setText(remoteVersion.getGameVersion()); - } - - leftPane.getChildren().remove(imageViewContainer); - } - - public RemoteVersion getRemoteVersion() { - return remoteVersion; - } -} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java index 5514e7cb9..a9ed31889 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPageSkin.java @@ -53,7 +53,7 @@ class ModListPageSkin extends SkinBase { super(skinnable); StackPane pane = new StackPane(); - pane.getStyleClass().addAll("notice-pane", "white-background"); + pane.getStyleClass().addAll("notice-pane"); BorderPane root = new BorderPane(); JFXTreeTableView tableView = new JFXTreeTableView<>(); diff --git a/HMCL/src/main/resources/assets/css/root.css b/HMCL/src/main/resources/assets/css/root.css index a2f1d1d6d..d2e2415ec 100644 --- a/HMCL/src/main/resources/assets/css/root.css +++ b/HMCL/src/main/resources/assets/css/root.css @@ -137,7 +137,6 @@ .sponsor-pane { -fx-padding: 16; - -fx-background-color: white; -fx-cursor: hand; } @@ -522,6 +521,12 @@ -fx-cursor: hand; } +.jfx-button .jfx-rippler { + -jfx-rippler-fill: -fx-base-check-color; + -jfx-mask-type: CIRCLE; + -fx-padding: 0.0; +} + .jfx-button-raised { -fx-background-color: -fx-base-color; } @@ -614,7 +619,8 @@ *******************************************************************************/ .jfx-list-cell, .list-cell { - -fx-background-color: WHITE; + /*-fx-background-color: WHITE;*/ + -fx-background-color: transparent; } .list-cell:selected, .jfx-list-cell:selected, @@ -637,6 +643,17 @@ -jfx-cell-vertical-margin: 5.0; -jfx-vertical-gap: 10.0; -jfx-expanded: false; + -fx-background-color: transparent; +} + +.jfx-list-view-float { + -fx-padding: 5; + -fx-background-insets: 0.0; + -jfx-cell-horizontal-margin: 0.0; + -jfx-cell-vertical-margin: 5.0; + -jfx-vertical-gap: 10.0; + -jfx-expanded: false; + -fx-background-color: transparent; } .options-list { diff --git a/HMCL/src/main/resources/assets/fxml/download/installers.fxml b/HMCL/src/main/resources/assets/fxml/download/installers.fxml index bb6cecccb..76586bd20 100644 --- a/HMCL/src/main/resources/assets/fxml/download/installers.fxml +++ b/HMCL/src/main/resources/assets/fxml/download/installers.fxml @@ -3,70 +3,85 @@ + + + - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + +
+
+
+ + + + + + +
+
+ + + +
+ + + + + + +
+
+ + + +
+ + + + + + +
+
+ + + +
+ + + + + + +
+
+ + + +
- + diff --git a/HMCL/src/main/resources/assets/fxml/download/versions.fxml b/HMCL/src/main/resources/assets/fxml/download/versions.fxml index 201c2230a..68296fb9d 100644 --- a/HMCL/src/main/resources/assets/fxml/download/versions.fxml +++ b/HMCL/src/main/resources/assets/fxml/download/versions.fxml @@ -21,7 +21,7 @@ - + diff --git a/HMCL/src/main/resources/assets/img/chicken.png b/HMCL/src/main/resources/assets/img/chicken.png index 01fd49d1d744e3d4482a5bc3c202d8ca6b976024..e2e0ce061c9d98909f3b2084084999c5b259aa02 100644 GIT binary patch literal 10052 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 diff --git a/HMCL/src/main/resources/assets/img/fabric.png b/HMCL/src/main/resources/assets/img/fabric.png new file mode 100644 index 0000000000000000000000000000000000000000..4ab8370ff4b4de7b4ab665a6628e07b3f94cb44d GIT binary patch literal 5867 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 BTp|Df literal 0 HcmV?d00001 diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index c52b1a0ac..ad185ed34 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -100,7 +100,7 @@ download.failed.empty=No candidates. Click here to return. download.failed.refresh=Unable to download version list. Click here to retry. download.provider.mcbbs=MCBBS (https://www.mcbbs.net/) download.provider.bmclapi=BMCLAPI (bangbang93, https://bmclapi2.bangbang93.com/) -download.provider.mojang=Mojang (Forge and OptiFine installation are downloaded from BMCLAPI) +download.provider.mojang=Mojang (OptiFine download service is provided by BMCLAPI) extension.bat=Windows Bat file extension.mod=Mod file diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index a088351a2..44e2e2361 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -99,7 +99,7 @@ download.failed.empty=沒有能安裝的版本,按一下此處返回。 download.failed.refresh=載入版本列表失敗,按一下此處重試。 download.provider.mcbbs=我的世界中文論壇 (MCBBS, https://www.mcbbs.net/) download.provider.bmclapi=BMCLAPI (bangbang93,https://bmclapi2.bangbang93.com/) -download.provider.mojang=官方伺服器 (Forge 和 OptiFine 自動安裝的下載來源是 BMCLAPI) +download.provider.mojang=官方伺服器 (OptiFine 自動安裝的下載來源是 BMCLAPI) extension.bat=Windows 指令碼 extension.mod=模組檔案 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 0b9dff638..1efeae68f 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -99,7 +99,7 @@ download.failed.empty=没有可供安装的版本,点击此处返回。 download.failed.refresh=加载版本列表失败,点击此处重试。 download.provider.mcbbs=我的世界中文论坛 (MCBBS, https://www.mcbbs.net/) download.provider.bmclapi=BMCLAPI(bangbang93,https://bmclapi2.bangbang93.com/) -download.provider.mojang=官方(Forge 和 OptiFine 自动安装使用 BMCLAPI 下载源) +download.provider.mojang=官方(OptiFine 自动安装使用 BMCLAPI 下载源) extension.bat=Windows 脚本 extension.mod=模组文件