mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-15 06:45:42 -04:00
Add dragging world pack to GUI for installation
This commit is contained in:
parent
1d2b59d5a2
commit
b7723a88c3
@ -21,7 +21,6 @@ import com.jfoenix.concurrency.JFXUtilities;
|
|||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.input.TransferMode;
|
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.jackhuang.hmcl.Launcher;
|
import org.jackhuang.hmcl.Launcher;
|
||||||
@ -140,27 +139,9 @@ public final class Controllers {
|
|||||||
public static MainPage getMainPage() {
|
public static MainPage getMainPage() {
|
||||||
if (mainPage == null) {
|
if (mainPage == null) {
|
||||||
MainPage mainPage = new MainPage();
|
MainPage mainPage = new MainPage();
|
||||||
mainPage.setOnDragOver(event -> {
|
FXUtils.applyDragListener(mainPage, it -> "zip".equals(FileUtils.getExtension(it)), modpacks -> {
|
||||||
if (event.getGestureSource() != mainPage && event.getDragboard().hasFiles()) {
|
|
||||||
if (event.getDragboard().getFiles().stream().anyMatch(it -> "zip".equals(FileUtils.getExtension(it))))
|
|
||||||
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
|
|
||||||
}
|
|
||||||
event.consume();
|
|
||||||
});
|
|
||||||
|
|
||||||
mainPage.setOnDragDropped(event -> {
|
|
||||||
List<File> files = event.getDragboard().getFiles();
|
|
||||||
if (files != null) {
|
|
||||||
List<File> modpacks = files.stream()
|
|
||||||
.filter(it -> "zip".equals(FileUtils.getExtension(it)))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
if (!modpacks.isEmpty()) {
|
|
||||||
File modpack = modpacks.get(0);
|
File modpack = modpacks.get(0);
|
||||||
Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(Profiles.getSelectedProfile(), modpack), i18n("install.modpack"));
|
Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(Profiles.getSelectedProfile(), modpack), i18n("install.modpack"));
|
||||||
event.setDropCompleted(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
event.consume();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
FXUtils.onChangeAndOperate(Profiles.selectedVersionProperty(), version -> {
|
FXUtils.onChangeAndOperate(Profiles.selectedVersionProperty(), version -> {
|
||||||
|
@ -37,6 +37,7 @@ import javafx.scene.control.*;
|
|||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
import javafx.scene.input.ScrollEvent;
|
import javafx.scene.input.ScrollEvent;
|
||||||
|
import javafx.scene.input.TransferMode;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.shape.Rectangle;
|
import javafx.scene.shape.Rectangle;
|
||||||
@ -50,11 +51,13 @@ import org.jackhuang.hmcl.util.javafx.ExtendedProperties;
|
|||||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UncheckedIOException;
|
import java.io.UncheckedIOException;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
@ -62,6 +65,7 @@ import java.util.function.Consumer;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.Lang.thread;
|
import static org.jackhuang.hmcl.util.Lang.thread;
|
||||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||||
@ -445,6 +449,34 @@ public final class FXUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void applyDragListener(Node node, FileFilter filter, Consumer<List<File>> callback) {
|
||||||
|
applyDragListener(node, filter, callback, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void applyDragListener(Node node, FileFilter filter, Consumer<List<File>> callback, Runnable dragDropped) {
|
||||||
|
node.setOnDragOver(event -> {
|
||||||
|
if (event.getGestureSource() != node && event.getDragboard().hasFiles()) {
|
||||||
|
if (event.getDragboard().getFiles().stream().anyMatch(filter::accept))
|
||||||
|
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
|
||||||
|
}
|
||||||
|
event.consume();
|
||||||
|
});
|
||||||
|
|
||||||
|
node.setOnDragDropped(event -> {
|
||||||
|
List<File> files = event.getDragboard().getFiles();
|
||||||
|
if (files != null) {
|
||||||
|
List<File> acceptFiles = files.stream().filter(filter::accept).collect(Collectors.toList());
|
||||||
|
if (!acceptFiles.isEmpty()) {
|
||||||
|
callback.accept(acceptFiles);
|
||||||
|
event.setDropCompleted(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dragDropped != null)
|
||||||
|
dragDropped.run();
|
||||||
|
event.consume();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> StringConverter<T> stringConverter(Function<T, String> func) {
|
public static <T> StringConverter<T> stringConverter(Function<T, String> func) {
|
||||||
return new StringConverter<T>() {
|
return new StringConverter<T>() {
|
||||||
|
|
||||||
|
@ -19,10 +19,10 @@ package org.jackhuang.hmcl.ui.versions;
|
|||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import javafx.scene.input.TransferMode;
|
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import org.jackhuang.hmcl.mod.Datapack;
|
import org.jackhuang.hmcl.mod.Datapack;
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
import org.jackhuang.hmcl.ui.Controllers;
|
||||||
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.ListPage;
|
import org.jackhuang.hmcl.ui.ListPage;
|
||||||
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
@ -34,7 +34,6 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
@ -60,19 +59,7 @@ public class DatapackListPage extends ListPage<DatapackListItem> implements Deco
|
|||||||
}
|
}
|
||||||
})));
|
})));
|
||||||
|
|
||||||
setOnDragOver(event -> {
|
FXUtils.applyDragListener(this, it -> Objects.equals("zip", FileUtils.getExtension(it)), mods -> {
|
||||||
if (event.getGestureSource() != this && event.getDragboard().hasFiles())
|
|
||||||
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
|
|
||||||
event.consume();
|
|
||||||
});
|
|
||||||
|
|
||||||
setOnDragDropped(event -> {
|
|
||||||
List<File> files = event.getDragboard().getFiles();
|
|
||||||
if (files != null) {
|
|
||||||
Collection<File> mods = files.stream()
|
|
||||||
.filter(it -> Objects.equals("zip", FileUtils.getExtension(it)))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
if (!mods.isEmpty()) {
|
|
||||||
mods.forEach(it -> {
|
mods.forEach(it -> {
|
||||||
try {
|
try {
|
||||||
Datapack zip = new Datapack(it.toPath());
|
Datapack zip = new Datapack(it.toPath());
|
||||||
@ -82,12 +69,7 @@ public class DatapackListPage extends ListPage<DatapackListItem> implements Deco
|
|||||||
Logging.LOG.log(Level.WARNING, "Unable to parse datapack file " + it, e);
|
Logging.LOG.log(Level.WARNING, "Unable to parse datapack file " + it, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
event.setDropCompleted(true);
|
}, datapack::loadFromDir);
|
||||||
}
|
|
||||||
}
|
|
||||||
datapack.loadFromDir();
|
|
||||||
event.consume();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,7 +19,6 @@ package org.jackhuang.hmcl.ui.versions;
|
|||||||
|
|
||||||
import com.jfoenix.concurrency.JFXUtilities;
|
import com.jfoenix.concurrency.JFXUtilities;
|
||||||
import com.jfoenix.controls.JFXTabPane;
|
import com.jfoenix.controls.JFXTabPane;
|
||||||
import javafx.scene.input.TransferMode;
|
|
||||||
import javafx.stage.FileChooser;
|
import javafx.stage.FileChooser;
|
||||||
import org.jackhuang.hmcl.mod.ModInfo;
|
import org.jackhuang.hmcl.mod.ModInfo;
|
||||||
import org.jackhuang.hmcl.mod.ModManager;
|
import org.jackhuang.hmcl.mod.ModManager;
|
||||||
@ -35,11 +34,9 @@ import org.jackhuang.hmcl.util.io.FileUtils;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
@ -50,19 +47,7 @@ public final class ModListPage extends ListPage<ModItem> {
|
|||||||
private String versionId;
|
private String versionId;
|
||||||
|
|
||||||
public ModListPage() {
|
public ModListPage() {
|
||||||
setOnDragOver(event -> {
|
FXUtils.applyDragListener(this, it -> Arrays.asList("jar", "zip", "litemod").contains(FileUtils.getExtension(it)), mods -> {
|
||||||
if (event.getGestureSource() != this && event.getDragboard().hasFiles())
|
|
||||||
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
|
|
||||||
event.consume();
|
|
||||||
});
|
|
||||||
|
|
||||||
setOnDragDropped(event -> {
|
|
||||||
List<File> files = event.getDragboard().getFiles();
|
|
||||||
if (files != null) {
|
|
||||||
Collection<File> mods = files.stream()
|
|
||||||
.filter(it -> Arrays.asList("jar", "zip", "litemod").contains(FileUtils.getExtension(it)))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
if (!mods.isEmpty()) {
|
|
||||||
mods.forEach(it -> {
|
mods.forEach(it -> {
|
||||||
try {
|
try {
|
||||||
modManager.addMod(versionId, it);
|
modManager.addMod(versionId, it);
|
||||||
@ -71,10 +56,6 @@ public final class ModListPage extends ListPage<ModItem> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
loadMods(modManager, versionId);
|
loadMods(modManager, versionId);
|
||||||
event.setDropCompleted(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
event.consume();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,13 +23,14 @@ import org.jackhuang.hmcl.setting.Profile;
|
|||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
import org.jackhuang.hmcl.ui.Controllers;
|
||||||
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.ListPage;
|
import org.jackhuang.hmcl.ui.ListPage;
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.FileAlreadyExistsException;
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -41,6 +42,9 @@ public class WorldListPage extends ListPage<WorldListItem> {
|
|||||||
private Path savesDir;
|
private Path savesDir;
|
||||||
|
|
||||||
public WorldListPage() {
|
public WorldListPage() {
|
||||||
|
FXUtils.applyDragListener(this, it -> "zip".equals(FileUtils.getExtension(it)), modpacks -> {
|
||||||
|
installWorld(modpacks.get(0));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadVersion(Profile profile, String id) {
|
public void loadVersion(Profile profile, String id) {
|
||||||
@ -58,10 +62,14 @@ public class WorldListPage extends ListPage<WorldListItem> {
|
|||||||
List<File> res = chooser.showOpenMultipleDialog(Controllers.getStage());
|
List<File> res = chooser.showOpenMultipleDialog(Controllers.getStage());
|
||||||
|
|
||||||
if (res == null || res.isEmpty()) return;
|
if (res == null || res.isEmpty()) return;
|
||||||
|
installWorld(res.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void installWorld(File zipFile) {
|
||||||
try {
|
try {
|
||||||
// Only accept one world file because user is required to confirm the new world name
|
// Only accept one world file because user is required to confirm the new world name
|
||||||
// Or too many input dialogs are popped.
|
// Or too many input dialogs are popped.
|
||||||
World world = new World(res.get(0).toPath());
|
World world = new World(zipFile.toPath());
|
||||||
|
|
||||||
Controllers.inputDialog(i18n("world.name.enter"), (name, resolve, reject) -> {
|
Controllers.inputDialog(i18n("world.name.enter"), (name, resolve, reject) -> {
|
||||||
Task.of(() -> world.install(savesDir, name))
|
Task.of(() -> world.install(savesDir, name))
|
||||||
@ -77,7 +85,7 @@ public class WorldListPage extends ListPage<WorldListItem> {
|
|||||||
}).setInitialText(world.getWorldName());
|
}).setInitialText(world.getWorldName());
|
||||||
|
|
||||||
} catch (IOException | IllegalArgumentException e) {
|
} catch (IOException | IllegalArgumentException e) {
|
||||||
Logging.LOG.log(Level.WARNING, "Unable to parse datapack file " + res.get(0), e);
|
Logging.LOG.log(Level.WARNING, "Unable to parse datapack file " + zipFile, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user