mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-08-04 11:56:55 -04:00
--------- Co-authored-by: Glavo <zjx001202@gmail.com>
This commit is contained in:
parent
b079e50916
commit
1ac677365b
@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher
|
||||||
|
* Copyright (C) 2025 huangyuhui <huanghongxun2008@126.com> 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.ui.download;
|
||||||
|
|
||||||
|
import com.jfoenix.controls.JFXButton;
|
||||||
|
import com.jfoenix.controls.JFXTextField;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.layout.FlowPane;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||||
|
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||||
|
import org.jackhuang.hmcl.ui.Controllers;
|
||||||
|
import javafx.scene.layout.BorderPane;
|
||||||
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
|
import org.jackhuang.hmcl.ui.InstallerItem;
|
||||||
|
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
||||||
|
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||||
|
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
|
public abstract class AbstractInstallersPage extends Control implements WizardPage {
|
||||||
|
protected final WizardController controller;
|
||||||
|
|
||||||
|
protected InstallerItem.InstallerItemGroup group;
|
||||||
|
protected JFXTextField txtName = new JFXTextField();
|
||||||
|
|
||||||
|
protected BooleanProperty installable = new SimpleBooleanProperty();
|
||||||
|
|
||||||
|
public AbstractInstallersPage(WizardController controller, String gameVersion, DownloadProvider downloadProvider) {
|
||||||
|
this.controller = controller;
|
||||||
|
this.group = new InstallerItem.InstallerItemGroup(gameVersion, getInstallerItemStyle());
|
||||||
|
|
||||||
|
for (InstallerItem library : group.getLibraries()) {
|
||||||
|
String libraryId = library.getLibraryId();
|
||||||
|
if (libraryId.equals(LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId())) continue;
|
||||||
|
library.setOnInstall(() -> {
|
||||||
|
if (LibraryAnalyzer.LibraryType.FABRIC_API.getPatchId().equals(libraryId)) {
|
||||||
|
Controllers.dialog(i18n("install.installer.fabric-api.warning"), i18n("message.warning"), MessageDialogPane.MessageType.WARNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(library.resolvedStateProperty().get() instanceof InstallerItem.IncompatibleState))
|
||||||
|
controller.onNext(new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, downloadProvider, libraryId, () -> controller.onPrev(false)));
|
||||||
|
});
|
||||||
|
library.setOnRemove(() -> {
|
||||||
|
controller.getSettings().remove(libraryId);
|
||||||
|
reload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected InstallerItem.Style getInstallerItemStyle() {
|
||||||
|
return InstallerItem.Style.CARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract String getTitle();
|
||||||
|
|
||||||
|
protected abstract void reload();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNavigate(Map<String, Object> settings) {
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract void cleanup(Map<String, Object> settings);
|
||||||
|
|
||||||
|
protected abstract void onInstall();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Skin<?> createDefaultSkin() {
|
||||||
|
return new InstallersPageSkin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class InstallersPageSkin extends SkinBase<AbstractInstallersPage> {
|
||||||
|
/**
|
||||||
|
* Constructor for all SkinBase instances.
|
||||||
|
*
|
||||||
|
* @param control The control for which this Skin should attach to.
|
||||||
|
*/
|
||||||
|
protected InstallersPageSkin(AbstractInstallersPage control) {
|
||||||
|
super(control);
|
||||||
|
|
||||||
|
BorderPane root = new BorderPane();
|
||||||
|
root.setPadding(new Insets(16));
|
||||||
|
|
||||||
|
{
|
||||||
|
HBox versionNamePane = new HBox(8);
|
||||||
|
versionNamePane.getStyleClass().add("card-non-transparent");
|
||||||
|
versionNamePane.setStyle("-fx-padding: 20 8 20 16");
|
||||||
|
versionNamePane.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
|
control.txtName.setMaxWidth(300);
|
||||||
|
versionNamePane.getChildren().setAll(new Label(i18n("version.name")), control.txtName);
|
||||||
|
root.setTop(versionNamePane);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
InstallerItem[] libraries = control.group.getLibraries();
|
||||||
|
|
||||||
|
FlowPane libraryPane = new FlowPane(libraries);
|
||||||
|
libraryPane.setVgap(16);
|
||||||
|
libraryPane.setHgap(16);
|
||||||
|
|
||||||
|
if (libraries.length <= 8) {
|
||||||
|
BorderPane.setMargin(libraryPane, new Insets(16, 0, 16, 0));
|
||||||
|
root.setCenter(libraryPane);
|
||||||
|
} else {
|
||||||
|
ScrollPane scrollPane = new ScrollPane(libraryPane);
|
||||||
|
scrollPane.setFitToWidth(true);
|
||||||
|
scrollPane.setFitToHeight(true);
|
||||||
|
BorderPane.setMargin(scrollPane, new Insets(16, 0, 16, 0));
|
||||||
|
root.setCenter(scrollPane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
JFXButton installButton = FXUtils.newRaisedButton(i18n("button.install"));
|
||||||
|
installButton.disableProperty().bind(control.installable.not());
|
||||||
|
installButton.setPrefWidth(100);
|
||||||
|
installButton.setPrefHeight(40);
|
||||||
|
installButton.setOnAction(e -> control.onInstall());
|
||||||
|
BorderPane.setAlignment(installButton, Pos.CENTER_RIGHT);
|
||||||
|
root.setBottom(installButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
getChildren().setAll(root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.ui.download;
|
package org.jackhuang.hmcl.ui.download;
|
||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||||
@ -36,26 +35,21 @@ import java.util.Optional;
|
|||||||
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.MINECRAFT;
|
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.MINECRAFT;
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
class AdditionalInstallersPage extends InstallersPage {
|
class AdditionalInstallersPage extends AbstractInstallersPage {
|
||||||
protected final BooleanProperty compatible = new SimpleBooleanProperty();
|
protected final BooleanProperty compatible = new SimpleBooleanProperty();
|
||||||
protected final GameRepository repository;
|
protected final GameRepository repository;
|
||||||
protected final String gameVersion;
|
protected final String gameVersion;
|
||||||
protected final Version version;
|
protected final Version version;
|
||||||
|
|
||||||
public AdditionalInstallersPage(String gameVersion, Version version, WizardController controller, HMCLGameRepository repository, DownloadProvider downloadProvider) {
|
public AdditionalInstallersPage(String gameVersion, Version version, WizardController controller, HMCLGameRepository repository, DownloadProvider downloadProvider) {
|
||||||
super(controller, repository, gameVersion, downloadProvider);
|
super(controller, gameVersion, downloadProvider);
|
||||||
this.gameVersion = gameVersion;
|
this.gameVersion = gameVersion;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
|
|
||||||
txtName.getValidators().clear();
|
|
||||||
txtName.setText(version.getId());
|
txtName.setText(version.getId());
|
||||||
txtName.setEditable(false);
|
txtName.setEditable(false);
|
||||||
|
|
||||||
installable.bind(Bindings.createBooleanBinding(
|
|
||||||
() -> compatible.get() && txtName.validate(),
|
|
||||||
txtName.textProperty(), compatible));
|
|
||||||
|
|
||||||
for (InstallerItem library : group.getLibraries()) {
|
for (InstallerItem library : group.getLibraries()) {
|
||||||
String libraryId = library.getLibraryId();
|
String libraryId = library.getLibraryId();
|
||||||
if (libraryId.equals("game")) continue;
|
if (libraryId.equals("game")) continue;
|
||||||
|
@ -17,28 +17,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.ui.download;
|
package org.jackhuang.hmcl.ui.download;
|
||||||
|
|
||||||
import com.jfoenix.controls.JFXButton;
|
|
||||||
import com.jfoenix.controls.JFXTextField;
|
|
||||||
import javafx.beans.property.BooleanProperty;
|
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
|
||||||
import javafx.geometry.Insets;
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.*;
|
|
||||||
import javafx.scene.layout.BorderPane;
|
|
||||||
import javafx.scene.layout.FlowPane;
|
|
||||||
import javafx.scene.layout.HBox;
|
|
||||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||||
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
import org.jackhuang.hmcl.download.LibraryAnalyzer;
|
||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.game.HMCLGameRepository;
|
import org.jackhuang.hmcl.game.HMCLGameRepository;
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
import org.jackhuang.hmcl.ui.Controllers;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
|
||||||
import org.jackhuang.hmcl.ui.InstallerItem;
|
import org.jackhuang.hmcl.ui.InstallerItem;
|
||||||
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
||||||
import org.jackhuang.hmcl.ui.construct.RequiredValidator;
|
import org.jackhuang.hmcl.ui.construct.RequiredValidator;
|
||||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
import org.jackhuang.hmcl.ui.construct.Validator;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -46,18 +34,12 @@ import java.util.Map;
|
|||||||
import static javafx.beans.binding.Bindings.createBooleanBinding;
|
import static javafx.beans.binding.Bindings.createBooleanBinding;
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
public class InstallersPage extends Control implements WizardPage {
|
public class InstallersPage extends AbstractInstallersPage {
|
||||||
protected final WizardController controller;
|
|
||||||
|
|
||||||
protected InstallerItem.InstallerItemGroup group;
|
|
||||||
protected JFXTextField txtName = new JFXTextField();
|
|
||||||
protected BooleanProperty installable = new SimpleBooleanProperty();
|
|
||||||
|
|
||||||
private boolean isNameModifiedByUser = false;
|
private boolean isNameModifiedByUser = false;
|
||||||
|
|
||||||
public InstallersPage(WizardController controller, HMCLGameRepository repository, String gameVersion, DownloadProvider downloadProvider) {
|
public InstallersPage(WizardController controller, HMCLGameRepository repository, String gameVersion, DownloadProvider downloadProvider) {
|
||||||
this.controller = controller;
|
super(controller, gameVersion, downloadProvider);
|
||||||
this.group = new InstallerItem.InstallerItemGroup(gameVersion, getInstallerItemStyle());
|
|
||||||
|
|
||||||
txtName.getValidators().addAll(
|
txtName.getValidators().addAll(
|
||||||
new RequiredValidator(),
|
new RequiredValidator(),
|
||||||
@ -66,27 +48,6 @@ public class InstallersPage extends Control implements WizardPage {
|
|||||||
installable.bind(createBooleanBinding(txtName::validate, txtName.textProperty()));
|
installable.bind(createBooleanBinding(txtName::validate, txtName.textProperty()));
|
||||||
|
|
||||||
txtName.textProperty().addListener((obs, oldText, newText) -> isNameModifiedByUser = true);
|
txtName.textProperty().addListener((obs, oldText, newText) -> isNameModifiedByUser = true);
|
||||||
|
|
||||||
for (InstallerItem library : group.getLibraries()) {
|
|
||||||
String libraryId = library.getLibraryId();
|
|
||||||
if (libraryId.equals(LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId())) continue;
|
|
||||||
library.setOnInstall(() -> {
|
|
||||||
if (LibraryAnalyzer.LibraryType.FABRIC_API.getPatchId().equals(libraryId)) {
|
|
||||||
Controllers.dialog(i18n("install.installer.fabric-api.warning"), i18n("message.warning"), MessageDialogPane.MessageType.WARNING);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(library.resolvedStateProperty().get() instanceof InstallerItem.IncompatibleState))
|
|
||||||
controller.onNext(new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, downloadProvider, libraryId, () -> controller.onPrev(false)));
|
|
||||||
});
|
|
||||||
library.setOnRemove(() -> {
|
|
||||||
controller.getSettings().remove(libraryId);
|
|
||||||
reload();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected InstallerItem.Style getInstallerItemStyle() {
|
|
||||||
return InstallerItem.Style.CARD;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -112,11 +73,6 @@ public class InstallersPage extends Control implements WizardPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNavigate(Map<String, Object> settings) {
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanup(Map<String, Object> settings) {
|
public void cleanup(Map<String, Object> settings) {
|
||||||
}
|
}
|
||||||
@ -143,11 +99,6 @@ public class InstallersPage extends Control implements WizardPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Skin<?> createDefaultSkin() {
|
|
||||||
return new InstallersPageSkin(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setTxtNameWithLoaders() {
|
private void setTxtNameWithLoaders() {
|
||||||
StringBuilder nameBuilder = new StringBuilder(group.getGame().versionProperty().get().getVersion());
|
StringBuilder nameBuilder = new StringBuilder(group.getGame().versionProperty().get().getVersion());
|
||||||
|
|
||||||
@ -190,62 +141,4 @@ public class InstallersPage extends Control implements WizardPage {
|
|||||||
txtName.setText(nameBuilder.toString());
|
txtName.setText(nameBuilder.toString());
|
||||||
isNameModifiedByUser = false;
|
isNameModifiedByUser = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class InstallersPageSkin extends SkinBase<InstallersPage> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor for all SkinBase instances.
|
|
||||||
*
|
|
||||||
* @param control The control for which this Skin should attach to.
|
|
||||||
*/
|
|
||||||
protected InstallersPageSkin(InstallersPage control) {
|
|
||||||
super(control);
|
|
||||||
|
|
||||||
BorderPane root = new BorderPane();
|
|
||||||
root.setPadding(new Insets(16));
|
|
||||||
|
|
||||||
{
|
|
||||||
HBox versionNamePane = new HBox(8);
|
|
||||||
versionNamePane.getStyleClass().add("card-non-transparent");
|
|
||||||
versionNamePane.setStyle("-fx-padding: 20 8 20 16");
|
|
||||||
versionNamePane.setAlignment(Pos.CENTER_LEFT);
|
|
||||||
|
|
||||||
control.txtName.setMaxWidth(300);
|
|
||||||
versionNamePane.getChildren().setAll(new Label(i18n("version.name")), control.txtName);
|
|
||||||
root.setTop(versionNamePane);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
InstallerItem[] libraries = control.group.getLibraries();
|
|
||||||
|
|
||||||
FlowPane libraryPane = new FlowPane(libraries);
|
|
||||||
libraryPane.setVgap(16);
|
|
||||||
libraryPane.setHgap(16);
|
|
||||||
|
|
||||||
if (libraries.length <= 8) {
|
|
||||||
BorderPane.setMargin(libraryPane, new Insets(16, 0, 16, 0));
|
|
||||||
root.setCenter(libraryPane);
|
|
||||||
} else {
|
|
||||||
ScrollPane scrollPane = new ScrollPane(libraryPane);
|
|
||||||
scrollPane.setFitToWidth(true);
|
|
||||||
scrollPane.setFitToHeight(true);
|
|
||||||
BorderPane.setMargin(scrollPane, new Insets(16, 0, 16, 0));
|
|
||||||
root.setCenter(scrollPane);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
JFXButton installButton = FXUtils.newRaisedButton(i18n("button.install"));
|
|
||||||
installButton.disableProperty().bind(control.installable.not());
|
|
||||||
installButton.setPrefWidth(100);
|
|
||||||
installButton.setPrefHeight(40);
|
|
||||||
installButton.setOnAction(e -> control.onInstall());
|
|
||||||
BorderPane.setAlignment(installButton, Pos.CENTER_RIGHT);
|
|
||||||
root.setBottom(installButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
getChildren().setAll(root);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user