支持以类型安全的方式读写 Navigation#getSettings() (#4504)
This commit is contained in:
@@ -23,8 +23,8 @@ import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.construct.Navigator;
|
||||
import org.jackhuang.hmcl.ui.construct.PageCloseEvent;
|
||||
import org.jackhuang.hmcl.ui.wizard.*;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class DecoratorWizardDisplayer extends DecoratorTransitionPage implements WizardDisplayer {
|
||||
@@ -94,7 +94,7 @@ public class DecoratorWizardDisplayer extends DecoratorTransitionPage implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTask(Map<String, Object> settings, Task<?> task) {
|
||||
public void handleTask(SettingsMap settings, Task<?> task) {
|
||||
displayer.handleTask(settings, task);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,7 @@ 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 org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
@@ -80,12 +79,12 @@ public abstract class AbstractInstallersPage extends Control implements WizardPa
|
||||
protected abstract void reload();
|
||||
|
||||
@Override
|
||||
public void onNavigate(Map<String, Object> settings) {
|
||||
public void onNavigate(SettingsMap settings) {
|
||||
reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void cleanup(Map<String, Object> settings);
|
||||
public abstract void cleanup(SettingsMap settings);
|
||||
|
||||
protected abstract void onInstall();
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ import org.jackhuang.hmcl.game.Version;
|
||||
import org.jackhuang.hmcl.ui.InstallerItem;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.jackhuang.hmcl.download.LibraryAnalyzer.LibraryType.MINECRAFT;
|
||||
@@ -109,6 +109,6 @@ class AdditionalInstallersPage extends AbstractInstallersPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(Map<String, Object> settings) {
|
||||
public void cleanup(SettingsMap settings) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,14 +51,13 @@ import org.jackhuang.hmcl.ui.versions.Versions;
|
||||
import org.jackhuang.hmcl.ui.wizard.Navigation;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
import org.jackhuang.hmcl.util.TaskCancellationAction;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -223,7 +222,7 @@ public class DownloadPage extends DecoratorAnimatedPage implements DecoratorPage
|
||||
}
|
||||
|
||||
private static final class DownloadNavigator implements Navigation {
|
||||
private final Map<String, Object> settings = new HashMap<>();
|
||||
private final SettingsMap settings = new SettingsMap();
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
@@ -260,7 +259,7 @@ public class DownloadPage extends DecoratorAnimatedPage implements DecoratorPage
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getSettings() {
|
||||
public SettingsMap getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@@ -287,37 +286,39 @@ public class DownloadPage extends DecoratorAnimatedPage implements DecoratorPage
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Map<String, Object> settings) {
|
||||
settings.put(PROFILE, profile);
|
||||
public void start(SettingsMap settings) {
|
||||
settings.put(ModpackPage.PROFILE, profile);
|
||||
settings.put(LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId(), gameVersion);
|
||||
}
|
||||
|
||||
private Task<Void> finishVersionDownloadingAsync(Map<String, Object> settings) {
|
||||
private Task<Void> finishVersionDownloadingAsync(SettingsMap settings) {
|
||||
GameBuilder builder = dependencyManager.gameBuilder();
|
||||
|
||||
String name = (String) settings.get("name");
|
||||
builder.name(name);
|
||||
builder.gameVersion(((RemoteVersion) settings.get(LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId())).getGameVersion());
|
||||
|
||||
for (Map.Entry<String, Object> entry : settings.entrySet())
|
||||
if (!LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId().equals(entry.getKey()) && entry.getValue() instanceof RemoteVersion)
|
||||
builder.version((RemoteVersion) entry.getValue());
|
||||
settings.asStringMap().forEach((key, value) -> {
|
||||
if (!LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId().equals(key)
|
||||
&& value instanceof RemoteVersion remoteVersion)
|
||||
builder.version(remoteVersion);
|
||||
});
|
||||
|
||||
return builder.buildAsync().whenComplete(any -> profile.getRepository().refreshVersions())
|
||||
.thenRunAsync(Schedulers.javafx(), () -> profile.setSelectedVersion(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object finish(Map<String, Object> settings) {
|
||||
public Object finish(SettingsMap settings) {
|
||||
settings.put("title", i18n("install.new_game.installation"));
|
||||
settings.put("success_message", i18n("install.success"));
|
||||
settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> UpdateInstallerWizardProvider.alertFailureMessage(exception, next));
|
||||
settings.put(FailureCallback.KEY, (settings1, exception, next) -> UpdateInstallerWizardProvider.alertFailureMessage(exception, next));
|
||||
|
||||
return finishVersionDownloadingAsync(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
||||
public Node createPage(WizardController controller, int step, SettingsMap settings) {
|
||||
switch (step) {
|
||||
case 0:
|
||||
return new InstallersPage(controller, profile.getRepository(), ((RemoteVersion) controller.getSettings().get("game")).getGameVersion(), downloadProvider);
|
||||
@@ -330,7 +331,5 @@ public class DownloadPage extends DecoratorAnimatedPage implements DecoratorPage
|
||||
public boolean cancel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final String PROFILE = "PROFILE";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,7 @@ import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
||||
import org.jackhuang.hmcl.ui.construct.RequiredValidator;
|
||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
import static javafx.beans.binding.Bindings.createBooleanBinding;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
@@ -73,7 +72,7 @@ public class InstallersPage extends AbstractInstallersPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(Map<String, Object> settings) {
|
||||
public void cleanup(SettingsMap settings) {
|
||||
}
|
||||
|
||||
private static boolean checkName(String name) {
|
||||
|
||||
@@ -36,16 +36,14 @@ import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
||||
import org.jackhuang.hmcl.ui.construct.RequiredValidator;
|
||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.io.CompressingUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
@@ -58,11 +56,11 @@ public final class LocalModpackPage extends ModpackPage {
|
||||
public LocalModpackPage(WizardController controller) {
|
||||
super(controller);
|
||||
|
||||
Profile profile = (Profile) controller.getSettings().get("PROFILE");
|
||||
Profile profile = controller.getSettings().get(ModpackPage.PROFILE);
|
||||
|
||||
Optional<String> name = tryCast(controller.getSettings().get(MODPACK_NAME), String.class);
|
||||
if (name.isPresent()) {
|
||||
txtModpackName.setText(name.get());
|
||||
String name = controller.getSettings().get(MODPACK_NAME);
|
||||
if (name != null) {
|
||||
txtModpackName.setText(name);
|
||||
txtModpackName.setDisable(true);
|
||||
} else {
|
||||
FXUtils.onChangeAndOperate(installAsVersion, installAsVersion -> {
|
||||
@@ -83,9 +81,9 @@ public final class LocalModpackPage extends ModpackPage {
|
||||
btnDescription.setVisible(false);
|
||||
|
||||
Path selectedFile;
|
||||
Optional<Path> filePath = tryCast(controller.getSettings().get(MODPACK_FILE), Path.class);
|
||||
if (filePath.isPresent()) {
|
||||
selectedFile = filePath.get();
|
||||
Path filePath = controller.getSettings().get(MODPACK_FILE);
|
||||
if (filePath != null) {
|
||||
selectedFile = filePath;
|
||||
} else {
|
||||
FileChooser chooser = new FileChooser();
|
||||
chooser.setTitle(i18n("modpack.choose"));
|
||||
@@ -112,7 +110,7 @@ public final class LocalModpackPage extends ModpackPage {
|
||||
lblName.setText(FileUtils.getName(selectedFile));
|
||||
installAsVersion.set(false);
|
||||
|
||||
if (name.isEmpty()) {
|
||||
if (name == null) {
|
||||
// trim: https://github.com/HMCL-dev/HMCL/issues/962
|
||||
txtModpackName.setText(FileUtils.getNameWithoutExtension(selectedFile));
|
||||
}
|
||||
@@ -133,7 +131,7 @@ public final class LocalModpackPage extends ModpackPage {
|
||||
lblVersion.setText(manifest.getVersion());
|
||||
lblAuthor.setText(manifest.getAuthor());
|
||||
|
||||
if (name.isEmpty()) {
|
||||
if (name == null) {
|
||||
// trim: https://github.com/HMCL-dev/HMCL/issues/962
|
||||
txtModpackName.setText(manifest.getName().trim());
|
||||
}
|
||||
@@ -144,7 +142,7 @@ public final class LocalModpackPage extends ModpackPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(Map<String, Object> settings) {
|
||||
public void cleanup(SettingsMap settings) {
|
||||
settings.remove(MODPACK_FILE);
|
||||
}
|
||||
|
||||
@@ -177,9 +175,9 @@ public final class LocalModpackPage extends ModpackPage {
|
||||
Controllers.navigate(new WebPage(i18n("modpack.description"), manifest.getDescription()));
|
||||
}
|
||||
|
||||
public static final String MODPACK_FILE = "MODPACK_FILE";
|
||||
public static final String MODPACK_NAME = "MODPACK_NAME";
|
||||
public static final String MODPACK_MANIFEST = "MODPACK_MANIFEST";
|
||||
public static final String MODPACK_CHARSET = "MODPACK_CHARSET";
|
||||
public static final String MODPACK_MANUALLY_CREATED = "MODPACK_MANUALLY_CREATED";
|
||||
public static final SettingsMap.Key<Path> MODPACK_FILE = new SettingsMap.Key<>("MODPACK_FILE");
|
||||
public static final SettingsMap.Key<String> MODPACK_NAME = new SettingsMap.Key<>("MODPACK_NAME");
|
||||
public static final SettingsMap.Key<Modpack> MODPACK_MANIFEST = new SettingsMap.Key<>("MODPACK_MANIFEST");
|
||||
public static final SettingsMap.Key<Charset> MODPACK_CHARSET = new SettingsMap.Key<>("MODPACK_CHARSET");
|
||||
public static final SettingsMap.Key<Boolean> MODPACK_MANUALLY_CREATED = new SettingsMap.Key<>("MODPACK_MANUALLY_CREATED");
|
||||
}
|
||||
|
||||
@@ -32,14 +32,13 @@ import org.jackhuang.hmcl.ui.Controllers;
|
||||
import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class ModpackInstallWizardProvider implements WizardProvider {
|
||||
@@ -66,21 +65,21 @@ public final class ModpackInstallWizardProvider implements WizardProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Map<String, Object> settings) {
|
||||
public void start(SettingsMap settings) {
|
||||
if (file != null)
|
||||
settings.put(LocalModpackPage.MODPACK_FILE, file);
|
||||
if (updateVersion != null)
|
||||
settings.put(LocalModpackPage.MODPACK_NAME, updateVersion);
|
||||
settings.put(PROFILE, profile);
|
||||
settings.put(ModpackPage.PROFILE, profile);
|
||||
}
|
||||
|
||||
private Task<?> finishModpackInstallingAsync(Map<String, Object> settings) {
|
||||
Path selected = tryCast(settings.get(LocalModpackPage.MODPACK_FILE), Path.class).orElse(null);
|
||||
ServerModpackManifest serverModpackManifest = tryCast(settings.get(RemoteModpackPage.MODPACK_SERVER_MANIFEST), ServerModpackManifest.class).orElse(null);
|
||||
Modpack modpack = tryCast(settings.get(LocalModpackPage.MODPACK_MANIFEST), Modpack.class).orElse(null);
|
||||
String name = tryCast(settings.get(LocalModpackPage.MODPACK_NAME), String.class).orElse(null);
|
||||
Charset charset = tryCast(settings.get(LocalModpackPage.MODPACK_CHARSET), Charset.class).orElse(null);
|
||||
boolean isManuallyCreated = tryCast(settings.get(LocalModpackPage.MODPACK_MANUALLY_CREATED), Boolean.class).orElse(false);
|
||||
private Task<?> finishModpackInstallingAsync(SettingsMap settings) {
|
||||
Path selected = settings.get(LocalModpackPage.MODPACK_FILE);
|
||||
ServerModpackManifest serverModpackManifest = settings.get(RemoteModpackPage.MODPACK_SERVER_MANIFEST);
|
||||
Modpack modpack = settings.get(LocalModpackPage.MODPACK_MANIFEST);
|
||||
String name = settings.get(LocalModpackPage.MODPACK_NAME);
|
||||
Charset charset = settings.get(LocalModpackPage.MODPACK_CHARSET);
|
||||
boolean isManuallyCreated = settings.getOrDefault(LocalModpackPage.MODPACK_MANUALLY_CREATED, false);
|
||||
|
||||
if (isManuallyCreated) {
|
||||
return ModpackHelper.getInstallManuallyCreatedModpackTask(profile, selected, name, charset);
|
||||
@@ -119,12 +118,10 @@ public final class ModpackInstallWizardProvider implements WizardProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object finish(Map<String, Object> settings) {
|
||||
public Object finish(SettingsMap settings) {
|
||||
settings.put("title", i18n("install.modpack.installation"));
|
||||
settings.put("success_message", i18n("install.success"));
|
||||
settings.put("failure_callback", new FailureCallback() {
|
||||
@Override
|
||||
public void onFail(Map<String, Object> settings, Exception exception, Runnable next) {
|
||||
settings.put(FailureCallback.KEY, (ignored, exception, next) -> {
|
||||
if (exception instanceof ModpackCompletionException) {
|
||||
if (exception.getCause() instanceof FileNotFoundException) {
|
||||
Controllers.dialog(i18n("modpack.type.curse.not_found"), i18n("install.failed"), MessageType.ERROR, next);
|
||||
@@ -134,14 +131,13 @@ public final class ModpackInstallWizardProvider implements WizardProvider {
|
||||
} else {
|
||||
UpdateInstallerWizardProvider.alertFailureMessage(exception, next);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return finishModpackInstallingAsync(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
||||
public Node createPage(WizardController controller, int step, SettingsMap settings) {
|
||||
switch (step) {
|
||||
case 0:
|
||||
return new ModpackSelectionPage(controller);
|
||||
@@ -161,6 +157,4 @@ public final class ModpackInstallWizardProvider implements WizardProvider {
|
||||
public boolean cancel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final String PROFILE = "PROFILE";
|
||||
}
|
||||
|
||||
@@ -7,16 +7,20 @@ import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.construct.ComponentList;
|
||||
import org.jackhuang.hmcl.ui.construct.SpinnerPane;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
import static javafx.beans.binding.Bindings.createBooleanBinding;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public abstract class ModpackPage extends SpinnerPane implements WizardPage {
|
||||
public static final SettingsMap.Key<Profile> PROFILE = new SettingsMap.Key<>("PROFILE");
|
||||
|
||||
protected final WizardController controller;
|
||||
|
||||
protected final Label lblName;
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.jackhuang.hmcl.ui.SVG;
|
||||
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
import org.jackhuang.hmcl.util.TaskCancellationAction;
|
||||
import org.jackhuang.hmcl.util.gson.JsonUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
@@ -43,13 +44,10 @@ import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.download.LocalModpackPage.MODPACK_FILE;
|
||||
import static org.jackhuang.hmcl.ui.download.LocalModpackPage.MODPACK_NAME;
|
||||
import static org.jackhuang.hmcl.ui.download.RemoteModpackPage.MODPACK_SERVER_MANIFEST;
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class ModpackSelectionPage extends VBox implements WizardPage {
|
||||
@@ -71,9 +69,9 @@ public final class ModpackSelectionPage extends VBox implements WizardPage {
|
||||
createButton("repository", this::onChooseRepository)
|
||||
);
|
||||
|
||||
Optional<Path> filePath = tryCast(controller.getSettings().get(MODPACK_FILE), Path.class);
|
||||
if (filePath.isPresent()) {
|
||||
controller.getSettings().put(MODPACK_FILE, filePath.get());
|
||||
Path filePath = controller.getSettings().get(MODPACK_FILE);
|
||||
if (filePath != null) {
|
||||
controller.getSettings().put(MODPACK_FILE, filePath);
|
||||
Platform.runLater(controller::onNext);
|
||||
}
|
||||
|
||||
@@ -167,14 +165,14 @@ public final class ModpackSelectionPage extends VBox implements WizardPage {
|
||||
}
|
||||
|
||||
public void onChooseRepository() {
|
||||
String modPackName = (String) controller.getSettings().get(MODPACK_NAME);
|
||||
String modPackName = controller.getSettings().get(MODPACK_NAME);
|
||||
DownloadPage downloadPage = new DownloadPage(modPackName);
|
||||
downloadPage.showModpackDownloads();
|
||||
Controllers.navigate(downloadPage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(Map<String, Object> settings) {
|
||||
public void cleanup(SettingsMap settings) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jackhuang.hmcl.ui.download;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import org.jackhuang.hmcl.game.HMCLGameRepository;
|
||||
import org.jackhuang.hmcl.mod.Modpack;
|
||||
import org.jackhuang.hmcl.mod.server.ServerModpackManifest;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
import org.jackhuang.hmcl.ui.Controllers;
|
||||
@@ -27,13 +28,11 @@ import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
||||
import org.jackhuang.hmcl.ui.construct.RequiredValidator;
|
||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class RemoteModpackPage extends ModpackPage {
|
||||
@@ -42,8 +41,9 @@ public final class RemoteModpackPage extends ModpackPage {
|
||||
public RemoteModpackPage(WizardController controller) {
|
||||
super(controller);
|
||||
|
||||
manifest = tryCast(controller.getSettings().get(MODPACK_SERVER_MANIFEST), ServerModpackManifest.class)
|
||||
.orElseThrow(() -> new IllegalStateException("MODPACK_SERVER_MANIFEST should exist"));
|
||||
manifest = controller.getSettings().get(MODPACK_SERVER_MANIFEST);
|
||||
if (manifest == null)
|
||||
throw new IllegalStateException("MODPACK_SERVER_MANIFEST should exist");
|
||||
|
||||
try {
|
||||
controller.getSettings().put(MODPACK_MANIFEST, manifest.toModpack(null));
|
||||
@@ -57,10 +57,10 @@ public final class RemoteModpackPage extends ModpackPage {
|
||||
lblVersion.setText(manifest.getVersion());
|
||||
lblAuthor.setText(manifest.getAuthor());
|
||||
|
||||
Profile profile = (Profile) controller.getSettings().get("PROFILE");
|
||||
Optional<String> name = tryCast(controller.getSettings().get(MODPACK_NAME), String.class);
|
||||
if (name.isPresent()) {
|
||||
txtModpackName.setText(name.get());
|
||||
Profile profile = controller.getSettings().get(ModpackPage.PROFILE);
|
||||
String name = controller.getSettings().get(MODPACK_NAME);
|
||||
if (name != null) {
|
||||
txtModpackName.setText(name);
|
||||
txtModpackName.setDisable(true);
|
||||
} else {
|
||||
// trim: https://github.com/HMCL-dev/HMCL/issues/962
|
||||
@@ -75,7 +75,7 @@ public final class RemoteModpackPage extends ModpackPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(Map<String, Object> settings) {
|
||||
public void cleanup(SettingsMap settings) {
|
||||
settings.remove(MODPACK_SERVER_MANIFEST);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public final class RemoteModpackPage extends ModpackPage {
|
||||
Controllers.navigate(new WebPage(i18n("modpack.description"), manifest.getDescription()));
|
||||
}
|
||||
|
||||
public static final String MODPACK_SERVER_MANIFEST = "MODPACK_SERVER_MANIFEST";
|
||||
public static final String MODPACK_NAME = "MODPACK_NAME";
|
||||
public static final String MODPACK_MANIFEST = "MODPACK_MANIFEST";
|
||||
public static final SettingsMap.Key<ServerModpackManifest> MODPACK_SERVER_MANIFEST = new SettingsMap.Key<>("MODPACK_SERVER_MANIFEST");
|
||||
public static final SettingsMap.Key<String> MODPACK_NAME = new SettingsMap.Key<>("MODPACK_NAME");
|
||||
public static final SettingsMap.Key<Modpack> MODPACK_MANIFEST = new SettingsMap.Key<>("MODPACK_MANIFEST");
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jackhuang.hmcl.ui.Controllers;
|
||||
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import org.jackhuang.hmcl.util.io.ResponseCodeException;
|
||||
@@ -40,7 +41,6 @@ import java.net.SocketTimeoutException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.zip.ZipException;
|
||||
|
||||
@@ -66,30 +66,29 @@ public final class UpdateInstallerWizardProvider implements WizardProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Map<String, Object> settings) {
|
||||
public void start(SettingsMap settings) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object finish(Map<String, Object> settings) {
|
||||
public Object finish(SettingsMap settings) {
|
||||
settings.put("title", i18n("install.change_version.process"));
|
||||
settings.put("success_message", i18n("install.success"));
|
||||
settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> alertFailureMessage(exception, next));
|
||||
settings.put(FailureCallback.KEY, (settings1, exception, next) -> alertFailureMessage(exception, next));
|
||||
|
||||
// We remove library but not save it,
|
||||
// so if installation failed will not break down current version.
|
||||
Task<Version> ret = Task.supplyAsync(() -> version);
|
||||
List<String> stages = new ArrayList<>();
|
||||
for (Object value : settings.values()) {
|
||||
if (value instanceof RemoteVersion) {
|
||||
RemoteVersion remoteVersion = (RemoteVersion) value;
|
||||
for (Object value : settings.asStringMap().values()) {
|
||||
if (value instanceof RemoteVersion remoteVersion) {
|
||||
ret = ret.thenComposeAsync(version -> dependencyManager.installLibraryAsync(version, remoteVersion));
|
||||
stages.add(String.format("hmcl.install.%s:%s", remoteVersion.getLibraryId(), remoteVersion.getSelfVersion()));
|
||||
if ("game".equals(remoteVersion.getLibraryId())) {
|
||||
stages.add("hmcl.install.libraries");
|
||||
stages.add("hmcl.install.assets");
|
||||
}
|
||||
} else if (value instanceof RemoveVersionAction) {
|
||||
ret = ret.thenComposeAsync(version -> dependencyManager.removeLibraryAsync(version, ((RemoveVersionAction) value).libraryId));
|
||||
} else if (value instanceof RemoveVersionAction removeVersionAction) {
|
||||
ret = ret.thenComposeAsync(version -> dependencyManager.removeLibraryAsync(version, removeVersionAction.libraryId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +96,7 @@ public final class UpdateInstallerWizardProvider implements WizardProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
||||
public Node createPage(WizardController controller, int step, SettingsMap settings) {
|
||||
switch (step) {
|
||||
case 0:
|
||||
return new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, downloadProvider, libraryId, () -> {
|
||||
|
||||
@@ -28,8 +28,7 @@ import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
||||
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
@@ -45,36 +44,37 @@ public final class VanillaInstallWizardProvider implements WizardProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Map<String, Object> settings) {
|
||||
settings.put(PROFILE, profile);
|
||||
public void start(SettingsMap settings) {
|
||||
settings.put(ModpackPage.PROFILE, profile);
|
||||
}
|
||||
|
||||
private Task<Void> finishVersionDownloadingAsync(Map<String, Object> settings) {
|
||||
private Task<Void> finishVersionDownloadingAsync(SettingsMap settings) {
|
||||
GameBuilder builder = dependencyManager.gameBuilder();
|
||||
|
||||
String name = (String) settings.get("name");
|
||||
builder.name(name);
|
||||
builder.gameVersion(((RemoteVersion) settings.get("game")).getGameVersion());
|
||||
|
||||
for (Map.Entry<String, Object> entry : settings.entrySet())
|
||||
if (!"game".equals(entry.getKey()) && entry.getValue() instanceof RemoteVersion)
|
||||
builder.version((RemoteVersion) entry.getValue());
|
||||
settings.asStringMap().forEach((key, value) -> {
|
||||
if (!"game".equals(key) && value instanceof RemoteVersion remoteVersion)
|
||||
builder.version(remoteVersion);
|
||||
});
|
||||
|
||||
return builder.buildAsync().whenComplete(any -> profile.getRepository().refreshVersions())
|
||||
.thenRunAsync(Schedulers.javafx(), () -> profile.setSelectedVersion(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object finish(Map<String, Object> settings) {
|
||||
public Object finish(SettingsMap settings) {
|
||||
settings.put("title", i18n("install.new_game.installation"));
|
||||
settings.put("success_message", i18n("install.success"));
|
||||
settings.put("failure_callback", (FailureCallback) (settings1, exception, next) -> UpdateInstallerWizardProvider.alertFailureMessage(exception, next));
|
||||
settings.put(FailureCallback.KEY, (settings1, exception, next) -> UpdateInstallerWizardProvider.alertFailureMessage(exception, next));
|
||||
|
||||
return finishVersionDownloadingAsync(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
||||
public Node createPage(WizardController controller, int step, SettingsMap settings) {
|
||||
switch (step) {
|
||||
case 0:
|
||||
return new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer.game")), "", downloadProvider, "game",
|
||||
@@ -88,6 +88,4 @@ public final class VanillaInstallWizardProvider implements WizardProvider {
|
||||
public boolean cancel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final String PROFILE = "PROFILE";
|
||||
}
|
||||
|
||||
@@ -54,12 +54,12 @@ import org.jackhuang.hmcl.ui.wizard.Navigation;
|
||||
import org.jackhuang.hmcl.ui.wizard.Refreshable;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
||||
import org.jackhuang.hmcl.util.Holder;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -124,7 +124,7 @@ public final class VersionsPage extends Control implements WizardPage, Refreshab
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(Map<String, Object> settings) {
|
||||
public void cleanup(SettingsMap settings) {
|
||||
settings.remove(libraryId);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardProvider;
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
import org.jackhuang.hmcl.util.io.JarUtils;
|
||||
import org.jackhuang.hmcl.util.io.Zipper;
|
||||
|
||||
@@ -54,17 +55,16 @@ public final class ExportWizardProvider implements WizardProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Map<String, Object> settings) {
|
||||
public void start(SettingsMap settings) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object finish(Map<String, Object> settings) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> whitelist = (List<String>) settings.get(ModpackFileSelectionPage.MODPACK_FILE_SELECTION);
|
||||
Path modpackFile = (Path) settings.get(ModpackInfoPage.MODPACK_FILE);
|
||||
ModpackExportInfo exportInfo = (ModpackExportInfo) settings.get(ModpackInfoPage.MODPACK_INFO);
|
||||
public Object finish(SettingsMap settings) {
|
||||
List<String> whitelist = settings.get(ModpackFileSelectionPage.MODPACK_FILE_SELECTION);
|
||||
Path modpackFile = settings.get(ModpackInfoPage.MODPACK_FILE);
|
||||
ModpackExportInfo exportInfo = settings.get(ModpackInfoPage.MODPACK_INFO);
|
||||
exportInfo.setWhitelist(whitelist);
|
||||
String modpackType = (String) settings.get(ModpackTypeSelectionPage.MODPACK_TYPE);
|
||||
String modpackType = settings.get(ModpackTypeSelectionPage.MODPACK_TYPE);
|
||||
|
||||
return exportWithLauncher(modpackType, exportInfo, modpackFile);
|
||||
}
|
||||
@@ -278,7 +278,7 @@ public final class ExportWizardProvider implements WizardProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
||||
public Node createPage(WizardController controller, int step, SettingsMap settings) {
|
||||
return switch (step) {
|
||||
case 0 -> new ModpackTypeSelectionPage(controller);
|
||||
case 1 -> new ModpackInfoPage(controller, profile.getRepository(), version);
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.construct.NoneMultipleSelectionModel;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
|
||||
@@ -162,7 +163,7 @@ public final class ModpackFileSelectionPage extends BorderPane implements Wizard
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(Map<String, Object> settings) {
|
||||
public void cleanup(SettingsMap settings) {
|
||||
controller.getSettings().remove(MODPACK_FILE_SELECTION);
|
||||
}
|
||||
|
||||
@@ -178,7 +179,7 @@ public final class ModpackFileSelectionPage extends BorderPane implements Wizard
|
||||
return i18n("modpack.wizard.step.2.title");
|
||||
}
|
||||
|
||||
public static final String MODPACK_FILE_SELECTION = "modpack.accepted";
|
||||
public static final SettingsMap.Key<List<String>> MODPACK_FILE_SELECTION = new SettingsMap.Key<>("modpack.accepted");
|
||||
private static final Map<String, String> TRANSLATION = mapOf(
|
||||
pair("minecraft/hmclversion.cfg", i18n("modpack.files.hmclversion_cfg")),
|
||||
pair("minecraft/servers.dat", i18n("modpack.files.servers_dat")),
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.jackhuang.hmcl.ui.FXUtils;
|
||||
import org.jackhuang.hmcl.ui.construct.*;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.io.JarUtils;
|
||||
@@ -57,7 +58,6 @@ import static org.jackhuang.hmcl.ui.export.ModpackTypeSelectionPage.MODPACK_TYPE
|
||||
import static org.jackhuang.hmcl.ui.export.ModpackTypeSelectionPage.MODPACK_TYPE_MODRINTH;
|
||||
import static org.jackhuang.hmcl.ui.export.ModpackTypeSelectionPage.MODPACK_TYPE_SERVER;
|
||||
import static org.jackhuang.hmcl.util.DataSizeUnit.MEGABYTES;
|
||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public final class ModpackInfoPage extends Control implements WizardPage {
|
||||
@@ -88,10 +88,12 @@ public final class ModpackInfoPage extends Control implements WizardPage {
|
||||
public ModpackInfoPage(WizardController controller, HMCLGameRepository gameRepository, String version) {
|
||||
this.controller = controller;
|
||||
this.gameRepository = gameRepository;
|
||||
this.options = tryCast(controller.getSettings().get(MODPACK_INFO_OPTION), ModpackExportInfo.Options.class)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Settings.MODPACK_INFO_OPTION is required"));
|
||||
this.options = controller.getSettings().get(MODPACK_INFO_OPTION);
|
||||
this.versionName = version;
|
||||
|
||||
if (this.options == null)
|
||||
throw new IllegalArgumentException("Settings.MODPACK_INFO_OPTION is required");
|
||||
|
||||
name.set(version);
|
||||
author.set(Optional.ofNullable(Accounts.getSelectedAccount()).map(Account::getUsername).orElse(""));
|
||||
|
||||
@@ -147,7 +149,7 @@ public final class ModpackInfoPage extends Control implements WizardPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(Map<String, Object> settings) {
|
||||
public void cleanup(SettingsMap settings) {
|
||||
controller.getSettings().remove(MODPACK_INFO);
|
||||
}
|
||||
|
||||
@@ -161,9 +163,9 @@ public final class ModpackInfoPage extends Control implements WizardPage {
|
||||
return new ModpackInfoPageSkin(this);
|
||||
}
|
||||
|
||||
public static final String MODPACK_INFO = "modpack.info";
|
||||
public static final String MODPACK_FILE = "modpack.file";
|
||||
public static final String MODPACK_INFO_OPTION = "modpack.info.option";
|
||||
public static final SettingsMap.Key<ModpackExportInfo> MODPACK_INFO = new SettingsMap.Key<>("modpack.info");
|
||||
public static final SettingsMap.Key<Path> MODPACK_FILE = new SettingsMap.Key<>("modpack.file");
|
||||
public static final SettingsMap.Key<ModpackExportInfo.Options> MODPACK_INFO_OPTION = new SettingsMap.Key<>("modpack.info.option");
|
||||
|
||||
public static class ModpackInfoPageSkin extends SkinBase<ModpackInfoPage> {
|
||||
private ObservableList<Node> originList;
|
||||
@@ -190,7 +192,8 @@ public final class ModpackInfoPage extends Control implements WizardPage {
|
||||
Hyperlink hyperlink = new Hyperlink(i18n("modpack.wizard.step.initialization.server"));
|
||||
hyperlink.setOnAction(e -> FXUtils.openLink(Metadata.DOCS_URL + "/modpack/serverpack.html"));
|
||||
borderPane.setTop(hyperlink);
|
||||
} if (skinnable.controller.getSettings().get(MODPACK_TYPE) == MODPACK_TYPE_MODRINTH) {
|
||||
}
|
||||
if (skinnable.controller.getSettings().get(MODPACK_TYPE) == MODPACK_TYPE_MODRINTH) {
|
||||
HintPane pane = new HintPane(MessageDialogPane.MessageType.INFO);
|
||||
pane.setText(i18n("modpack.wizard.step.initialization.modrinth.info"));
|
||||
borderPane.setTop(pane);
|
||||
|
||||
@@ -33,8 +33,7 @@ import org.jackhuang.hmcl.ui.SVG;
|
||||
import org.jackhuang.hmcl.ui.construct.TwoLineListItem;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||
import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
||||
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
import static org.jackhuang.hmcl.ui.export.ModpackInfoPage.MODPACK_INFO_OPTION;
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
@@ -89,7 +88,7 @@ public final class ModpackTypeSelectionPage extends VBox implements WizardPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup(Map<String, Object> settings) {
|
||||
public void cleanup(SettingsMap settings) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,7 +96,7 @@ public final class ModpackTypeSelectionPage extends VBox implements WizardPage {
|
||||
return i18n("modpack.wizard.step.3.title");
|
||||
}
|
||||
|
||||
public static final String MODPACK_TYPE = "modpack.type";
|
||||
public static final SettingsMap.Key<String> MODPACK_TYPE = new SettingsMap.Key<>("modpack.type");
|
||||
|
||||
public static final String MODPACK_TYPE_MCBBS = "mcbbs";
|
||||
public static final String MODPACK_TYPE_MULTIMC = "multimc";
|
||||
|
||||
@@ -22,8 +22,8 @@ import org.jackhuang.hmcl.task.Schedulers;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.task.TaskExecutor;
|
||||
import org.jackhuang.hmcl.ui.construct.TaskListPane;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
|
||||
public abstract class AbstractWizardDisplayer implements WizardDisplayer {
|
||||
@@ -34,7 +34,7 @@ public abstract class AbstractWizardDisplayer implements WizardDisplayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTask(Map<String, Object> settings, Task<?> task) {
|
||||
public void handleTask(SettingsMap settings, Task<?> task) {
|
||||
TaskExecutor executor = task.withRunAsync(Schedulers.javafx(), this::navigateToSuccess).executor();
|
||||
TaskListPane pane = new TaskListPane();
|
||||
pane.setExecutor(executor);
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
package org.jackhuang.hmcl.ui.wizard;
|
||||
|
||||
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
||||
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
public interface Navigation {
|
||||
|
||||
@@ -37,7 +36,7 @@ public interface Navigation {
|
||||
|
||||
void onCancel();
|
||||
|
||||
Map<String, Object> getSettings();
|
||||
SettingsMap getSettings();
|
||||
|
||||
enum NavigationDirection {
|
||||
START(ContainerAnimations.NONE),
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
package org.jackhuang.hmcl.ui.wizard;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class SinglePageWizardProvider implements WizardProvider {
|
||||
@@ -32,16 +32,16 @@ public class SinglePageWizardProvider implements WizardProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Map<String, Object> settings) {
|
||||
public void start(SettingsMap settings) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object finish(Map<String, Object> settings) {
|
||||
public Object finish(SettingsMap settings) {
|
||||
return page.finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node createPage(WizardController controller, int step, Map<String, Object> settings) {
|
||||
public Node createPage(WizardController controller, int step, SettingsMap settings) {
|
||||
if (step != 0) throw new IllegalStateException("Step must be 0");
|
||||
|
||||
return page = provider.apply(controller);
|
||||
|
||||
@@ -25,10 +25,10 @@ import org.jackhuang.hmcl.ui.Controllers;
|
||||
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
||||
import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
|
||||
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
import org.jackhuang.hmcl.util.StringUtils;
|
||||
import org.jackhuang.hmcl.util.TaskCancellationAction;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.CancellationException;
|
||||
|
||||
@@ -42,7 +42,7 @@ public abstract class TaskExecutorDialogWizardDisplayer extends AbstractWizardDi
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTask(Map<String, Object> settings, Task<?> task) {
|
||||
public void handleTask(SettingsMap settings, Task<?> task) {
|
||||
TaskExecutorDialogPane pane = new TaskExecutorDialogPane(new TaskCancellationAction(it -> {
|
||||
it.fireEvent(new DialogCloseEvent());
|
||||
onEnd();
|
||||
@@ -51,10 +51,10 @@ public abstract class TaskExecutorDialogWizardDisplayer extends AbstractWizardDi
|
||||
pane.setTitle(i18n("message.doing"));
|
||||
if (settings.containsKey("title")) {
|
||||
Object title = settings.get("title");
|
||||
if (title instanceof StringProperty)
|
||||
pane.titleProperty().bind((StringProperty) title);
|
||||
else if (title instanceof String)
|
||||
pane.setTitle((String) title);
|
||||
if (title instanceof StringProperty titleProperty)
|
||||
pane.titleProperty().bind(titleProperty);
|
||||
else if (title instanceof String titleMessage)
|
||||
pane.setTitle(titleMessage);
|
||||
}
|
||||
|
||||
runInFX(() -> {
|
||||
@@ -63,8 +63,8 @@ public abstract class TaskExecutorDialogWizardDisplayer extends AbstractWizardDi
|
||||
public void onStop(boolean success, TaskExecutor executor) {
|
||||
runInFX(() -> {
|
||||
if (success) {
|
||||
if (settings.containsKey("success_message") && settings.get("success_message") instanceof String)
|
||||
Controllers.dialog((String) settings.get("success_message"), null, MessageType.SUCCESS, () -> onEnd());
|
||||
if (settings.get("success_message") instanceof String successMessage)
|
||||
Controllers.dialog(successMessage, null, MessageType.SUCCESS, () -> onEnd());
|
||||
else if (!settings.containsKey("forbid_success_message"))
|
||||
Controllers.dialog(i18n("message.success"), null, MessageType.SUCCESS, () -> onEnd());
|
||||
} else {
|
||||
@@ -77,10 +77,10 @@ public abstract class TaskExecutorDialogWizardDisplayer extends AbstractWizardDi
|
||||
}
|
||||
|
||||
String appendix = StringUtils.getStackTrace(executor.getException());
|
||||
if (settings.get("failure_callback") instanceof WizardProvider.FailureCallback)
|
||||
((WizardProvider.FailureCallback) settings.get("failure_callback")).onFail(settings, executor.getException(), () -> onEnd());
|
||||
else if (settings.get("failure_message") instanceof String)
|
||||
Controllers.dialog(appendix, (String) settings.get("failure_message"), MessageType.ERROR, () -> onEnd());
|
||||
if (settings.get(WizardProvider.FailureCallback.KEY) != null)
|
||||
settings.get(WizardProvider.FailureCallback.KEY).onFail(settings, executor.getException(), () -> onEnd());
|
||||
else if (settings.get("failure_message") instanceof String failureMessage)
|
||||
Controllers.dialog(appendix, failureMessage, MessageType.ERROR, () -> onEnd());
|
||||
else if (!settings.containsKey("forbid_failure_message"))
|
||||
Controllers.dialog(appendix, i18n("wizard.failed"), MessageType.ERROR, () -> onEnd());
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jackhuang.hmcl.ui.wizard;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -27,7 +28,7 @@ import static org.jackhuang.hmcl.util.logging.Logger.LOG;
|
||||
public class WizardController implements Navigation {
|
||||
private final WizardDisplayer displayer;
|
||||
private WizardProvider provider = null;
|
||||
private final Map<String, Object> settings = new HashMap<>();
|
||||
private final SettingsMap settings = new SettingsMap();
|
||||
private final Stack<Node> pages = new Stack<>();
|
||||
private boolean stopped = false;
|
||||
|
||||
@@ -36,7 +37,7 @@ public class WizardController implements Navigation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getSettings() {
|
||||
public SettingsMap getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@ package org.jackhuang.hmcl.ui.wizard;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import org.jackhuang.hmcl.task.Task;
|
||||
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
public interface WizardDisplayer {
|
||||
default void onStart() {
|
||||
@@ -34,5 +33,5 @@ public interface WizardDisplayer {
|
||||
|
||||
void navigateTo(Node page, Navigation.NavigationDirection nav);
|
||||
|
||||
void handleTask(Map<String, Object> settings, Task<?> task);
|
||||
void handleTask(SettingsMap settings, Task<?> task);
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.wizard;
|
||||
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
public interface WizardPage {
|
||||
default void onNavigate(Map<String, Object> settings) {
|
||||
default void onNavigate(SettingsMap settings) {
|
||||
}
|
||||
|
||||
default void cleanup(Map<String, Object> settings) {
|
||||
default void cleanup(SettingsMap settings) {
|
||||
}
|
||||
|
||||
String getTitle();
|
||||
|
||||
@@ -18,15 +18,14 @@
|
||||
package org.jackhuang.hmcl.ui.wizard;
|
||||
|
||||
import javafx.scene.Node;
|
||||
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
public interface WizardProvider {
|
||||
void start(Map<String, Object> settings);
|
||||
void start(SettingsMap settings);
|
||||
|
||||
Object finish(Map<String, Object> settings);
|
||||
Object finish(SettingsMap settings);
|
||||
|
||||
Node createPage(WizardController controller, int step, Map<String, Object> settings);
|
||||
Node createPage(WizardController controller, int step, SettingsMap settings);
|
||||
|
||||
boolean cancel();
|
||||
|
||||
@@ -35,6 +34,8 @@ public interface WizardProvider {
|
||||
}
|
||||
|
||||
interface FailureCallback {
|
||||
void onFail(Map<String, Object> settings, Exception exception, Runnable next);
|
||||
SettingsMap.Key<FailureCallback> KEY = new SettingsMap.Key<>("failure_callback");
|
||||
|
||||
void onFail(SettingsMap settings, Exception exception, Runnable next);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
package org.jackhuang.hmcl.ui.wizard;
|
||||
|
||||
import javafx.scene.control.Control;
|
||||
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hmcl.util.SettingsMap;
|
||||
|
||||
public abstract class WizardSinglePage extends Control implements WizardPage {
|
||||
protected final Runnable onFinish;
|
||||
@@ -31,6 +30,6 @@ public abstract class WizardSinglePage extends Control implements WizardPage {
|
||||
protected abstract Object finish();
|
||||
|
||||
@Override
|
||||
public void cleanup(Map<String, Object> settings) {
|
||||
public void cleanup(SettingsMap settings) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/// A wrapper for `Map<String, Object>`, supporting type-safe reading and writing of values.
|
||||
///
|
||||
/// @author Glavo
|
||||
public final class SettingsMap {
|
||||
public record Key<T>(String key) {
|
||||
}
|
||||
|
||||
private final Map<String, Object> map = new HashMap<>();
|
||||
|
||||
public SettingsMap() {
|
||||
}
|
||||
|
||||
public Map<String, Object> asStringMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public boolean containsKey(@NotNull Key<?> key) {
|
||||
return map.containsKey(key.key);
|
||||
}
|
||||
|
||||
public boolean containsKey(@NotNull String key) {
|
||||
return map.containsKey(key);
|
||||
}
|
||||
|
||||
public <T> @Nullable T get(@NotNull Key<T> key) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T value = (T) map.get(key.key);
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object get(@NotNull String key) {
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
public <T> T getOrDefault(@NotNull Key<T> key, T defaultValue) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T value = (T) map.get(key.key);
|
||||
return value != null ? value : defaultValue;
|
||||
}
|
||||
|
||||
public <T> T put(@NotNull Key<T> key, @Nullable T value) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T result = (T) map.put(key.key, value);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Object put(@NotNull String key, @Nullable Object value) {
|
||||
return map.put(key, value);
|
||||
}
|
||||
|
||||
public <T> T remove(@NotNull Key<T> key) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T result = (T) map.remove(key.key);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Object remove(@NotNull String key) {
|
||||
return map.remove(key);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
map.clear();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user