Inceptum/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.java

233 lines
13 KiB
Java

package io.gitlab.jfronny.inceptum.gtk.window.settings.instance;
import io.github.jwharm.javagi.GErrorException;
import io.gitlab.jfronny.commons.ArgumentsTokenizer;
import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.*;
import io.gitlab.jfronny.inceptum.gtk.control.ILabel;
import io.gitlab.jfronny.inceptum.gtk.control.settings.SettingsTab;
import io.gitlab.jfronny.inceptum.gtk.util.I18n;
import io.gitlab.jfronny.inceptum.gtk.util.Memory;
import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi;
import io.gitlab.jfronny.inceptum.launcher.api.McApi;
import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricVersionLoaderInfo;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionsList;
import io.gitlab.jfronny.inceptum.launcher.system.instance.*;
import io.gitlab.jfronny.inceptum.launcher.util.GameVersionParser;
import org.gtk.gio.File;
import org.gtk.gobject.BindingFlags;
import org.gtk.gtk.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Stream;
public class GeneralTab extends SettingsTab {
private static final VersionsList VERSIONS = McApi.getVersions();
public GeneralTab(Instance instance, InstanceSettingsWindow window) {
super(window);
section(null, section -> {
var row = section.row("instance.settings.general.name", "instance.settings.general.name.placeholder");
Button apply = Button.newWithLabel(I18n.get("instance.settings.apply"));
Entry entry = row.setEntry(instance.name, s -> apply.sensitive = !s.equals(instance.name));
entry.placeholderText = I18n.get("instance.settings.general.name.placeholder");
apply.valign = Align.CENTER;
apply.onClicked(() -> {
try {
Path newPath = MetaHolder.INSTANCE_DIR.resolve(InstanceNameTool.getNextValid(entry.text));
Files.move(instance.path, newPath);
window.close();
new InstanceSettingsWindow(window.application, InstanceList.read(newPath)).show();
} catch (IOException e) {
showError("Could not rename", e);
}
});
apply.sensitive = false;
row.append(apply);
});
section("instance.settings.general.game", section -> {
{
var ref = new Object() {
Switch fabricEnabled = null;
Runnable versionChanged = null;
DropDown fabricVersion = null;
String defaultFabric = null;
String[] fabricVersions = null;
};
var gameRow = section.row("instance.settings.general.game.version", "instance.settings.general.game.version.subtitle");
String[] versions = VERSIONS.versions.stream()
.filter(s -> InceptumConfig.snapshots || s.type.equals("release"))
.map(s -> s.id)
.toArray(String[]::new);
int def = 0;
for (int i = 0; i < versions.length; i++) if (versions[i].equals(instance.gameVersion)) def = i;
gameRow.setDropdown(
versions,
def,
i -> {
instance.meta.gameVersion = instance.isFabric
? GameVersionParser.createVersionWithFabric(versions[i], instance.loaderVersion)
: versions[i];
instance.writeMeta();
ref.versionChanged.run();
}).enableSearch = true;
var fabricRow = section.row("instance.settings.general.game.fabric.enabled", "instance.settings.general.game.fabric.enabled.subtitle");
var loaderRow = section.row("instance.settings.general.game.fabric.version", "instance.settings.general.game.fabric.version.subtitle");
loaderRow.visible = instance.isFabric;
ref.fabricEnabled = fabricRow.setSwitch(instance.isFabric, bl -> {
if (bl) {
if (ref.fabricVersions != null && ref.fabricVersions.length != 0 && ref.defaultFabric != null) {
instance.meta.gameVersion = GameVersionParser.createVersionWithFabric(instance.gameVersion, ref.defaultFabric);
instance.writeMeta();
} else {
ref.fabricEnabled.active = false;
}
} else {
instance.meta.gameVersion = instance.gameVersion;
instance.writeMeta();
}
});
ref.fabricEnabled.bindProperty("active", loaderRow, "visible", BindingFlags.DEFAULT);
ref.versionChanged = () -> {
var ver = VERSIONS.versions.stream()
.filter(s -> s.id.equals(instance.gameVersion))
.findFirst()
.map(FabricMetaApi::getLoaderVersions)
.map(s -> s.toArray(FabricVersionLoaderInfo[]::new));
ref.defaultFabric = instance.isFabric ? instance.loaderVersion : ver
.map(Arrays::stream)
.map(a -> a.filter(s -> s.loader.stable))
.flatMap(Stream::findFirst)
.map(s -> s.loader.version)
.orElse(null);
ref.fabricVersions = ver.map(Arrays::stream)
.map(a -> a.map(s -> s.loader.version).toArray(String[]::new))
.orElse(null);
if (ref.fabricVersions == null || ref.fabricVersions.length == 0) {
ref.fabricEnabled.active = false;
} else if (ref.fabricVersion != null) ref.fabricVersion.model = new StringList(ref.fabricVersions);
};
ref.versionChanged.run();
ref.fabricVersion = loaderRow.setDropdown(ref.fabricVersions, ref.fabricVersions.indexOf(ref.defaultFabric), i -> {
instance.meta.gameVersion = i == -1 ? instance.gameVersion : GameVersionParser.createVersionWithFabric(instance.gameVersion, ref.fabricVersions[i]);
instance.writeMeta();
});
ref.fabricVersion.enableSearch = true;
}
{
var row = section.row("instance.settings.general.game.java", "instance.settings.general.game.java.subtitle");
var entry = row.setEntry(instance.meta.java, s -> {
instance.meta.java = s.isBlank() ? null : s;
instance.writeMeta();
});
var btn = Button.newFromIconName("folder-symbolic");
btn.valign = Align.CENTER;
btn.onClicked(() -> {
FileChooserNative dialog = new FileChooserNative(
I18n.get("instance.settings.general.game.java"),
window,
FileChooserAction.OPEN,
"_" + I18n.get("select"),
"_" + I18n.get("cancel")
);
if (instance.meta.java != null && Files.exists(Path.of(instance.meta.java))) {
try {
dialog.setFile(File.newForPath(instance.meta.java));
} catch (GErrorException e) {
Utils.LOGGER.error("Could not set starting point", e);
}
}
dialog.onResponse(responseId -> {
if (responseId == ResponseType.ACCEPT.value) {
var file = dialog.file.path;
if (file != null) entry.text = file;
}
});
dialog.show();
});
row.append(btn);
}
{
var row = section.row("instance.settings.general.game.memory.min", "instance.settings.general.game.memory.min.subtitle");
row.setSpinButton(instance.meta.minMem == null ? 512 : instance.meta.minMem / Memory.MB, 512, Memory.maxMBForInstance, 128, v -> {
instance.meta.minMem = (long) (v * Memory.MB);
if (instance.meta.minMem == Memory.GB / 2) instance.meta.minMem = null;
instance.writeMeta();
});
}
{
var row = section.row("instance.settings.general.game.memory.max", "instance.settings.general.game.memory.max.subtitle");
row.setSpinButton(instance.meta.maxMem == null ? 1024 : instance.meta.maxMem / Memory.MB, 1024, Memory.maxMBForInstance, 128, v -> {
instance.meta.maxMem = (long) (v * Memory.MB);
if (instance.meta.maxMem == Memory.GB) instance.meta.maxMem = null;
instance.writeMeta();
});
}
});
section("instance.settings.general.args", section -> {
if (instance.meta.arguments == null) instance.meta.arguments = new InstanceMeta.Arguments(List.of(), List.of(), List.of());
if (instance.meta.arguments.jvm == null) instance.meta.arguments = instance.meta.arguments.withJvm(List.of());
if (instance.meta.arguments.client == null) instance.meta.arguments = instance.meta.arguments.withClient(List.of());
if (instance.meta.arguments.server == null) instance.meta.arguments = instance.meta.arguments.withServer(List.of());
{
var row = section.row("instance.settings.general.args.jvm", "instance.settings.general.args.jvm.subtitle");
row.setEntry(ArgumentsTokenizer.join(instance.meta.arguments.jvm.toArray(String[]::new)), s -> {
instance.meta.arguments = instance.meta.arguments.withJvm(List.of(ArgumentsTokenizer.tokenize(s)));
instance.writeMeta();
});
}
{
var row = section.row("instance.settings.general.args.client", "instance.settings.general.args.client.subtitle");
row.setEntry(ArgumentsTokenizer.join(instance.meta.arguments.client.toArray(String[]::new)), s -> {
instance.meta.arguments = instance.meta.arguments.withClient(List.of(ArgumentsTokenizer.tokenize(s)));
instance.writeMeta();
});
}
{
var row = section.row("instance.settings.general.args.server", "instance.settings.general.args.server.subtitle");
row.setEntry(ArgumentsTokenizer.join(instance.meta.arguments.server.toArray(String[]::new)), s -> {
instance.meta.arguments = instance.meta.arguments.withServer(List.of(ArgumentsTokenizer.tokenize(s)));
instance.writeMeta();
});
}
});
section("instance.settings.general.manage", section -> {
{
var row = section.row("instance.delete", "instance.delete.subtitle");
row.setButton("instance.delete", () -> {
MessageDialog dialog = new MessageDialog(window, DialogFlags.MODAL.or(DialogFlags.DESTROY_WITH_PARENT), MessageType.WARNING, ButtonsType.OK_CANCEL, null);
dialog.markup = I18n.get("instance.delete.confirm");
dialog.title = I18n.get("instance.delete.confirm.title");
dialog.onResponse(responseId -> {
switch (ResponseType.of(responseId)) {
case OK -> {
try {
JFiles.deleteRecursive(instance.path);
dialog.close();
window.close();
} catch (IOException e) {
showError(I18n.get("instance.delete.fail"), e);
}
dialog.close();
}
case CLOSE, CANCEL -> dialog.close();
case DELETE_EVENT -> dialog.destroy();
}
});
dialog.show();
});
}
{
var row = section.row("instance.directory", "instance.directory.subtitle");
row.setButton("instance.directory", () -> Utils.openFile(instance.path.toFile()));
}
});
long timestamp = instance.meta.lastLaunched == null ? 0 : instance.meta.lastLaunched;
append(new ILabel("instance.settings.general.last-launched", ILabel.Mode.SUBTITLE, new Date(timestamp * 1000).toString()));
}
}