From b7723a88c35f09c0c4bc46c3bb010951e028774e Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Thu, 20 Dec 2018 20:24:23 +0800 Subject: [PATCH] Add dragging world pack to GUI for installation --- .../org/jackhuang/hmcl/ui/Controllers.java | 25 ++---------- .../java/org/jackhuang/hmcl/ui/FXUtils.java | 32 +++++++++++++++ .../hmcl/ui/versions/DatapackListPage.java | 40 +++++-------------- .../hmcl/ui/versions/ModListPage.java | 35 ++++------------ .../hmcl/ui/versions/WorldListPage.java | 14 +++++-- 5 files changed, 65 insertions(+), 81 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java index adb821001..6611d3a97 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -21,7 +21,6 @@ import com.jfoenix.concurrency.JFXUtilities; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.image.Image; -import javafx.scene.input.TransferMode; import javafx.scene.layout.Region; import javafx.stage.Stage; import org.jackhuang.hmcl.Launcher; @@ -140,27 +139,9 @@ public final class Controllers { public static MainPage getMainPage() { if (mainPage == null) { MainPage mainPage = new MainPage(); - mainPage.setOnDragOver(event -> { - 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 files = event.getDragboard().getFiles(); - if (files != null) { - List modpacks = files.stream() - .filter(it -> "zip".equals(FileUtils.getExtension(it))) - .collect(Collectors.toList()); - if (!modpacks.isEmpty()) { - File modpack = modpacks.get(0); - Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(Profiles.getSelectedProfile(), modpack), i18n("install.modpack")); - event.setDropCompleted(true); - } - } - event.consume(); + FXUtils.applyDragListener(mainPage, it -> "zip".equals(FileUtils.getExtension(it)), modpacks -> { + File modpack = modpacks.get(0); + Controllers.getDecorator().startWizard(new ModpackInstallWizardProvider(Profiles.getSelectedProfile(), modpack), i18n("install.modpack")); }); FXUtils.onChangeAndOperate(Profiles.selectedVersionProperty(), version -> { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java index 0854b7e61..eaa5c1e43 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java @@ -37,6 +37,7 @@ import javafx.scene.control.*; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; import javafx.scene.input.ScrollEvent; +import javafx.scene.input.TransferMode; import javafx.scene.layout.Region; import javafx.scene.layout.StackPane; import javafx.scene.shape.Rectangle; @@ -50,11 +51,13 @@ import org.jackhuang.hmcl.util.javafx.ExtendedProperties; import org.jackhuang.hmcl.util.platform.OperatingSystem; import java.io.File; +import java.io.FileFilter; import java.io.IOException; import java.io.UncheckedIOException; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.URI; +import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BooleanSupplier; @@ -62,6 +65,7 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; 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.tryCast; @@ -445,6 +449,34 @@ public final class FXUtils { } } + public static void applyDragListener(Node node, FileFilter filter, Consumer> callback) { + applyDragListener(node, filter, callback, null); + } + + public static void applyDragListener(Node node, FileFilter filter, Consumer> 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 files = event.getDragboard().getFiles(); + if (files != null) { + List 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 StringConverter stringConverter(Function func) { return new StringConverter() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DatapackListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DatapackListPage.java index 805b7fb5b..9f2acc63c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DatapackListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DatapackListPage.java @@ -19,10 +19,10 @@ package org.jackhuang.hmcl.ui.versions; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; -import javafx.scene.input.TransferMode; import javafx.stage.FileChooser; import org.jackhuang.hmcl.mod.Datapack; import org.jackhuang.hmcl.ui.Controllers; +import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.ListPage; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; import org.jackhuang.hmcl.util.Logging; @@ -34,7 +34,6 @@ import java.io.IOException; import java.nio.file.Path; import java.util.*; import java.util.logging.Level; -import java.util.stream.Collectors; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; @@ -60,34 +59,17 @@ public class DatapackListPage extends ListPage implements Deco } }))); - setOnDragOver(event -> { - if (event.getGestureSource() != this && event.getDragboard().hasFiles()) - event.acceptTransferModes(TransferMode.COPY_OR_MOVE); - event.consume(); - }); - - setOnDragDropped(event -> { - List files = event.getDragboard().getFiles(); - if (files != null) { - Collection mods = files.stream() - .filter(it -> Objects.equals("zip", FileUtils.getExtension(it))) - .collect(Collectors.toList()); - if (!mods.isEmpty()) { - mods.forEach(it -> { - try { - Datapack zip = new Datapack(it.toPath()); - zip.loadFromZip(); - zip.installTo(worldDir); - } catch (IOException | IllegalArgumentException e) { - Logging.LOG.log(Level.WARNING, "Unable to parse datapack file " + it, e); - } - }); - event.setDropCompleted(true); + FXUtils.applyDragListener(this, it -> Objects.equals("zip", FileUtils.getExtension(it)), mods -> { + mods.forEach(it -> { + try { + Datapack zip = new Datapack(it.toPath()); + zip.loadFromZip(); + zip.installTo(worldDir); + } catch (IOException | IllegalArgumentException e) { + Logging.LOG.log(Level.WARNING, "Unable to parse datapack file " + it, e); } - } - datapack.loadFromDir(); - event.consume(); - }); + }); + }, datapack::loadFromDir); } @Override diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java index aca9dcc80..f57773a9c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java @@ -19,7 +19,6 @@ package org.jackhuang.hmcl.ui.versions; import com.jfoenix.concurrency.JFXUtilities; import com.jfoenix.controls.JFXTabPane; -import javafx.scene.input.TransferMode; import javafx.stage.FileChooser; import org.jackhuang.hmcl.mod.ModInfo; import org.jackhuang.hmcl.mod.ModManager; @@ -35,11 +34,9 @@ import org.jackhuang.hmcl.util.io.FileUtils; import java.io.File; import java.io.IOException; import java.util.Arrays; -import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; -import java.util.stream.Collectors; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; @@ -50,31 +47,15 @@ public final class ModListPage extends ListPage { private String versionId; public ModListPage() { - setOnDragOver(event -> { - if (event.getGestureSource() != this && event.getDragboard().hasFiles()) - event.acceptTransferModes(TransferMode.COPY_OR_MOVE); - event.consume(); - }); - - setOnDragDropped(event -> { - List files = event.getDragboard().getFiles(); - if (files != null) { - Collection mods = files.stream() - .filter(it -> Arrays.asList("jar", "zip", "litemod").contains(FileUtils.getExtension(it))) - .collect(Collectors.toList()); - if (!mods.isEmpty()) { - mods.forEach(it -> { - try { - modManager.addMod(versionId, it); - } catch (IOException | IllegalArgumentException e) { - Logging.LOG.log(Level.WARNING, "Unable to parse mod file " + it, e); - } - }); - loadMods(modManager, versionId); - event.setDropCompleted(true); + FXUtils.applyDragListener(this, it -> Arrays.asList("jar", "zip", "litemod").contains(FileUtils.getExtension(it)), mods -> { + mods.forEach(it -> { + try { + modManager.addMod(versionId, it); + } catch (IOException | IllegalArgumentException e) { + Logging.LOG.log(Level.WARNING, "Unable to parse mod file " + it, e); } - } - event.consume(); + }); + loadMods(modManager, versionId); }); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java index ce719ea40..2e50d4792 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java @@ -23,13 +23,14 @@ import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.ui.Controllers; +import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.ListPage; import org.jackhuang.hmcl.util.Logging; +import org.jackhuang.hmcl.util.io.FileUtils; import java.io.File; import java.io.IOException; import java.nio.file.FileAlreadyExistsException; -import java.nio.file.Files; import java.nio.file.Path; import java.util.List; import java.util.logging.Level; @@ -41,6 +42,9 @@ public class WorldListPage extends ListPage { private Path savesDir; public WorldListPage() { + FXUtils.applyDragListener(this, it -> "zip".equals(FileUtils.getExtension(it)), modpacks -> { + installWorld(modpacks.get(0)); + }); } public void loadVersion(Profile profile, String id) { @@ -58,10 +62,14 @@ public class WorldListPage extends ListPage { List res = chooser.showOpenMultipleDialog(Controllers.getStage()); if (res == null || res.isEmpty()) return; + installWorld(res.get(0)); + } + + public void installWorld(File zipFile) { try { // Only accept one world file because user is required to confirm the new world name // 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) -> { Task.of(() -> world.install(savesDir, name)) @@ -77,7 +85,7 @@ public class WorldListPage extends ListPage { }).setInitialText(world.getWorldName()); } 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); } } }