mirror of
https://github.com/packwiz/packwiz-installer.git
synced 2025-04-19 21:16:30 +02:00
Implement optional mods and cancel buttons
This commit is contained in:
parent
5a54a90f59
commit
7946377159
@ -3,6 +3,7 @@ package link.infra.packwiz.installer;
|
|||||||
import link.infra.packwiz.installer.metadata.SpaceSafeURI;
|
import link.infra.packwiz.installer.metadata.SpaceSafeURI;
|
||||||
import link.infra.packwiz.installer.ui.CLIHandler;
|
import link.infra.packwiz.installer.ui.CLIHandler;
|
||||||
import link.infra.packwiz.installer.ui.IUserInterface;
|
import link.infra.packwiz.installer.ui.IUserInterface;
|
||||||
|
import link.infra.packwiz.installer.ui.InputStateHandler;
|
||||||
import link.infra.packwiz.installer.ui.InstallWindow;
|
import link.infra.packwiz.installer.ui.InstallWindow;
|
||||||
import org.apache.commons.cli.*;
|
import org.apache.commons.cli.*;
|
||||||
|
|
||||||
@ -10,10 +11,11 @@ import javax.swing.*;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
// Actual main() is in RequiresBootstrap!
|
// Actual main() is in RequiresBootstrap!
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public Main(String[] args) {
|
public Main(String[] args) {
|
||||||
// Big overarching try/catch just in case everything breaks
|
// Big overarching try/catch just in case everything breaks
|
||||||
try {
|
try {
|
||||||
@ -79,7 +81,8 @@ public class Main {
|
|||||||
ui.setTitle(title);
|
ui.setTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.show();
|
InputStateHandler inputStateHandler = new InputStateHandler();
|
||||||
|
ui.show(inputStateHandler);
|
||||||
|
|
||||||
UpdateManager.Options uOptions = new UpdateManager.Options();
|
UpdateManager.Options uOptions = new UpdateManager.Options();
|
||||||
|
|
||||||
@ -111,7 +114,7 @@ public class Main {
|
|||||||
try {
|
try {
|
||||||
ui.executeManager(() -> {
|
ui.executeManager(() -> {
|
||||||
try {
|
try {
|
||||||
new UpdateManager(uOptions, ui);
|
new UpdateManager(uOptions, ui, inputStateHandler);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// TODO: better error message?
|
// TODO: better error message?
|
||||||
ui.handleExceptionAndExit(e);
|
ui.handleExceptionAndExit(e);
|
||||||
|
@ -16,6 +16,7 @@ import link.infra.packwiz.installer.metadata.hash.HashUtils;
|
|||||||
import link.infra.packwiz.installer.request.HandlerManager;
|
import link.infra.packwiz.installer.request.HandlerManager;
|
||||||
import link.infra.packwiz.installer.ui.IExceptionDetails;
|
import link.infra.packwiz.installer.ui.IExceptionDetails;
|
||||||
import link.infra.packwiz.installer.ui.IUserInterface;
|
import link.infra.packwiz.installer.ui.IUserInterface;
|
||||||
|
import link.infra.packwiz.installer.ui.InputStateHandler;
|
||||||
import link.infra.packwiz.installer.ui.InstallProgress;
|
import link.infra.packwiz.installer.ui.InstallProgress;
|
||||||
import okio.Okio;
|
import okio.Okio;
|
||||||
import okio.Source;
|
import okio.Source;
|
||||||
@ -33,6 +34,7 @@ public class UpdateManager {
|
|||||||
public final IUserInterface ui;
|
public final IUserInterface ui;
|
||||||
private boolean cancelled;
|
private boolean cancelled;
|
||||||
private boolean cancelledStartGame = false;
|
private boolean cancelledStartGame = false;
|
||||||
|
private InputStateHandler stateHandler;
|
||||||
|
|
||||||
public static class Options {
|
public static class Options {
|
||||||
SpaceSafeURI downloadURI = null;
|
SpaceSafeURI downloadURI = null;
|
||||||
@ -92,9 +94,10 @@ public class UpdateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateManager(Options opts, IUserInterface ui) {
|
UpdateManager(Options opts, IUserInterface ui, InputStateHandler inputStateHandler) {
|
||||||
this.opts = opts;
|
this.opts = opts;
|
||||||
this.ui = ui;
|
this.ui = ui;
|
||||||
|
this.stateHandler = inputStateHandler;
|
||||||
this.start();
|
this.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +117,11 @@ public class UpdateManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stateHandler.getCancelButton()) {
|
||||||
|
showCancellationDialog();
|
||||||
|
handleCancellation();
|
||||||
|
}
|
||||||
|
|
||||||
ui.submitProgress(new InstallProgress("Loading pack file..."));
|
ui.submitProgress(new InstallProgress("Loading pack file..."));
|
||||||
GeneralHashingSource packFileSource;
|
GeneralHashingSource packFileSource;
|
||||||
try {
|
try {
|
||||||
@ -133,6 +141,11 @@ public class UpdateManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stateHandler.getCancelButton()) {
|
||||||
|
showCancellationDialog();
|
||||||
|
handleCancellation();
|
||||||
|
}
|
||||||
|
|
||||||
ui.submitProgress(new InstallProgress("Checking local files..."));
|
ui.submitProgress(new InstallProgress("Checking local files..."));
|
||||||
|
|
||||||
// Invalidation checking must be done here, as it must happen before pack/index hashes are checked
|
// Invalidation checking must be done here, as it must happen before pack/index hashes are checked
|
||||||
@ -162,11 +175,18 @@ public class UpdateManager {
|
|||||||
if (manifest.packFileHash != null && packFileSource.hashIsEqual(manifest.packFileHash) && invalidatedUris.isEmpty()) {
|
if (manifest.packFileHash != null && packFileSource.hashIsEqual(manifest.packFileHash) && invalidatedUris.isEmpty()) {
|
||||||
System.out.println("Modpack is already up to date!");
|
System.out.println("Modpack is already up to date!");
|
||||||
// todo: --force?
|
// todo: --force?
|
||||||
|
if (!stateHandler.getOptionsButton()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println("Modpack name: " + pf.name);
|
System.out.println("Modpack name: " + pf.name);
|
||||||
|
|
||||||
|
if (stateHandler.getCancelButton()) {
|
||||||
|
showCancellationDialog();
|
||||||
|
handleCancellation();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// This is badly written, I'll probably heavily refactor it at some point
|
// This is badly written, I'll probably heavily refactor it at some point
|
||||||
processIndex(HandlerManager.getNewLoc(opts.downloadURI, pf.index.file),
|
processIndex(HandlerManager.getNewLoc(opts.downloadURI, pf.index.file),
|
||||||
@ -175,15 +195,7 @@ public class UpdateManager {
|
|||||||
ui.handleExceptionAndExit(e1);
|
ui.handleExceptionAndExit(e1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cancelled) {
|
handleCancellation();
|
||||||
System.out.println("Update cancelled by user!");
|
|
||||||
System.exit(1);
|
|
||||||
return;
|
|
||||||
} else if (cancelledStartGame) {
|
|
||||||
System.out.println("Update cancelled by user! Continuing to start game...");
|
|
||||||
System.exit(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: update MMC params, java args etc
|
// TODO: update MMC params, java args etc
|
||||||
|
|
||||||
@ -205,8 +217,10 @@ public class UpdateManager {
|
|||||||
private void processIndex(SpaceSafeURI indexUri, Hash indexHash, String hashFormat, ManifestFile manifest, List<SpaceSafeURI> invalidatedUris) {
|
private void processIndex(SpaceSafeURI indexUri, Hash indexHash, String hashFormat, ManifestFile manifest, List<SpaceSafeURI> invalidatedUris) {
|
||||||
if (manifest.indexFileHash != null && manifest.indexFileHash.equals(indexHash) && invalidatedUris.isEmpty()) {
|
if (manifest.indexFileHash != null && manifest.indexFileHash.equals(indexHash) && invalidatedUris.isEmpty()) {
|
||||||
System.out.println("Modpack files are already up to date!");
|
System.out.println("Modpack files are already up to date!");
|
||||||
|
if (!stateHandler.getOptionsButton()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
manifest.indexFileHash = indexHash;
|
manifest.indexFileHash = indexHash;
|
||||||
|
|
||||||
GeneralHashingSource indexFileSource;
|
GeneralHashingSource indexFileSource;
|
||||||
@ -233,6 +247,11 @@ public class UpdateManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stateHandler.getCancelButton()) {
|
||||||
|
showCancellationDialog();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (manifest.cachedFiles == null) {
|
if (manifest.cachedFiles == null) {
|
||||||
manifest.cachedFiles = new HashMap<>();
|
manifest.cachedFiles = new HashMap<>();
|
||||||
}
|
}
|
||||||
@ -269,13 +288,21 @@ public class UpdateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stateHandler.getCancelButton()) {
|
||||||
|
showCancellationDialog();
|
||||||
|
return;
|
||||||
|
}
|
||||||
ui.submitProgress(new InstallProgress("Comparing new files..."));
|
ui.submitProgress(new InstallProgress("Comparing new files..."));
|
||||||
|
|
||||||
// TODO: progress bar, parallelify
|
// TODO: progress bar?
|
||||||
List<DownloadTask> tasks = DownloadTask.createTasksFromIndex(indexFile, indexFile.hashFormat, opts.side);
|
List<DownloadTask> tasks = DownloadTask.createTasksFromIndex(indexFile, indexFile.hashFormat, opts.side);
|
||||||
// If the side changes, invalidate EVERYTHING just in case
|
// If the side changes, invalidate EVERYTHING just in case
|
||||||
// Might not be needed, but done just to be safe
|
// Might not be needed, but done just to be safe
|
||||||
boolean invalidateAll = !opts.side.equals(manifest.cachedSide);
|
boolean invalidateAll = !opts.side.equals(manifest.cachedSide);
|
||||||
|
if (invalidateAll) {
|
||||||
|
System.out.println("Side changed, invalidating all mods");
|
||||||
|
}
|
||||||
tasks.forEach(f -> {
|
tasks.forEach(f -> {
|
||||||
// TODO: should linkedfile be checked as well? should this be done in the download section?
|
// TODO: should linkedfile be checked as well? should this be done in the download section?
|
||||||
if (invalidateAll) {
|
if (invalidateAll) {
|
||||||
@ -291,7 +318,14 @@ public class UpdateManager {
|
|||||||
// If it is null, the DownloadTask will make a new empty cachedFile
|
// If it is null, the DownloadTask will make a new empty cachedFile
|
||||||
f.updateFromCache(file);
|
f.updateFromCache(file);
|
||||||
});
|
});
|
||||||
tasks.forEach(f -> f.downloadMetadata(indexFile, indexUri));
|
|
||||||
|
if (stateHandler.getCancelButton()) {
|
||||||
|
showCancellationDialog();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's hope downloadMetadata is a pure function!!!
|
||||||
|
tasks.parallelStream().forEach(f -> f.downloadMetadata(indexFile, indexUri));
|
||||||
|
|
||||||
List<IExceptionDetails> failedTasks = tasks.stream().filter(t -> t.getException() != null).collect(Collectors.toList());
|
List<IExceptionDetails> failedTasks = tasks.stream().filter(t -> t.getException() != null).collect(Collectors.toList());
|
||||||
if (failedTasks.size() > 0) {
|
if (failedTasks.size() > 0) {
|
||||||
@ -315,10 +349,15 @@ public class UpdateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stateHandler.getCancelButton()) {
|
||||||
|
showCancellationDialog();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
List<DownloadTask> nonFailedFirstTasks = tasks.stream().filter(t -> t.getException() == null).collect(Collectors.toList());
|
List<DownloadTask> nonFailedFirstTasks = tasks.stream().filter(t -> t.getException() == null).collect(Collectors.toList());
|
||||||
List<DownloadTask> optionTasks = nonFailedFirstTasks.stream().filter(DownloadTask::correctSide).filter(DownloadTask::isOptional).collect(Collectors.toList());
|
List<DownloadTask> optionTasks = nonFailedFirstTasks.stream().filter(DownloadTask::correctSide).filter(DownloadTask::isOptional).collect(Collectors.toList());
|
||||||
// If options changed, present all options again
|
// If options changed, present all options again
|
||||||
if (optionTasks.stream().anyMatch(DownloadTask::isNewOptional)) {
|
if (stateHandler.getOptionsButton() || optionTasks.stream().anyMatch(DownloadTask::isNewOptional)) {
|
||||||
// new ArrayList is requires so it's an IOptionDetails rather than a DownloadTask list
|
// new ArrayList is requires so it's an IOptionDetails rather than a DownloadTask list
|
||||||
Future<Boolean> cancelledResult = ui.showOptions(new ArrayList<>(optionTasks));
|
Future<Boolean> cancelledResult = ui.showOptions(new ArrayList<>(optionTasks));
|
||||||
try {
|
try {
|
||||||
@ -332,6 +371,7 @@ public class UpdateManager {
|
|||||||
ui.handleExceptionAndExit(e);
|
ui.handleExceptionAndExit(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ui.disableOptionsButton();
|
||||||
|
|
||||||
// TODO: different thread pool type?
|
// TODO: different thread pool type?
|
||||||
ExecutorService threadPool = Executors.newFixedThreadPool(10);
|
ExecutorService threadPool = Executors.newFixedThreadPool(10);
|
||||||
@ -355,7 +395,7 @@ public class UpdateManager {
|
|||||||
if (task.getException() != null) {
|
if (task.getException() != null) {
|
||||||
ManifestFile.File file = task.cachedFile.getRevert();
|
ManifestFile.File file = task.cachedFile.getRevert();
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
manifest.cachedFiles.put(task.metadata.file, file);
|
manifest.cachedFiles.putIfAbsent(task.metadata.file, file);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// idiot, if it wasn't there in the first place it won't magically appear there
|
// idiot, if it wasn't there in the first place it won't magically appear there
|
||||||
@ -376,6 +416,13 @@ public class UpdateManager {
|
|||||||
progress = "Failed to download, unknown reason";
|
progress = "Failed to download, unknown reason";
|
||||||
}
|
}
|
||||||
ui.submitProgress(new InstallProgress(progress, i + 1, tasks.size()));
|
ui.submitProgress(new InstallProgress(progress, i + 1, tasks.size()));
|
||||||
|
|
||||||
|
if (stateHandler.getCancelButton()) {
|
||||||
|
// Stop all tasks, don't launch the game (it's in an invalid state!)
|
||||||
|
threadPool.shutdown();
|
||||||
|
cancelled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<IExceptionDetails> failedTasks2ElectricBoogaloo = nonFailedFirstTasks.stream().filter(t -> t.getException() != null).collect(Collectors.toList());
|
List<IExceptionDetails> failedTasks2ElectricBoogaloo = nonFailedFirstTasks.stream().filter(t -> t.getException() != null).collect(Collectors.toList());
|
||||||
@ -399,4 +446,34 @@ public class UpdateManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showCancellationDialog() {
|
||||||
|
IExceptionDetails.ExceptionListResult exceptionListResult;
|
||||||
|
try {
|
||||||
|
exceptionListResult = ui.showCancellationDialog().get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
// Interrupted means cancelled???
|
||||||
|
ui.handleExceptionAndExit(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (exceptionListResult) {
|
||||||
|
case CONTINUE:
|
||||||
|
throw new RuntimeException("Continuation not allowed here!");
|
||||||
|
case CANCEL:
|
||||||
|
cancelled = true;
|
||||||
|
return;
|
||||||
|
case IGNORE:
|
||||||
|
cancelledStartGame = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleCancellation() {
|
||||||
|
if (cancelled) {
|
||||||
|
System.out.println("Update cancelled by user!");
|
||||||
|
System.exit(1);
|
||||||
|
} else if (cancelledStartGame) {
|
||||||
|
System.out.println("Update cancelled by user! Continuing to start game...");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ public class IndexFile {
|
|||||||
|
|
||||||
public transient ModFile linkedFile;
|
public transient ModFile linkedFile;
|
||||||
public transient SpaceSafeURI linkedFileURI;
|
public transient SpaceSafeURI linkedFileURI;
|
||||||
public transient boolean optionValue = true;
|
|
||||||
|
|
||||||
public void downloadMeta(IndexFile parentIndexFile, SpaceSafeURI indexUri) throws Exception {
|
public void downloadMeta(IndexFile parentIndexFile, SpaceSafeURI indexUri) throws Exception {
|
||||||
if (!metafile) {
|
if (!metafile) {
|
||||||
|
@ -12,7 +12,7 @@ public class CLIHandler implements IUserInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void show() {}
|
public void show(InputStateHandler h) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void submitProgress(InstallProgress progress) {
|
public void submitProgress(InstallProgress progress) {
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package link.infra.packwiz.installer.ui;
|
package link.infra.packwiz.installer.ui;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public interface IUserInterface {
|
public interface IUserInterface {
|
||||||
|
|
||||||
void show();
|
void show(InputStateHandler handler);
|
||||||
|
|
||||||
void handleException(Exception e);
|
void handleException(Exception e);
|
||||||
|
|
||||||
@ -25,4 +26,13 @@ public interface IUserInterface {
|
|||||||
|
|
||||||
Future<IExceptionDetails.ExceptionListResult> showExceptions(List<IExceptionDetails> opts, int numTotal, boolean allowsIgnore);
|
Future<IExceptionDetails.ExceptionListResult> showExceptions(List<IExceptionDetails> opts, int numTotal, boolean allowsIgnore);
|
||||||
|
|
||||||
|
default void disableOptionsButton() {}
|
||||||
|
|
||||||
|
// Should not return CONTINUE
|
||||||
|
default Future<IExceptionDetails.ExceptionListResult> showCancellationDialog() {
|
||||||
|
CompletableFuture<IExceptionDetails.ExceptionListResult> future = new CompletableFuture<>();
|
||||||
|
future.complete(IExceptionDetails.ExceptionListResult.CANCEL);
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package link.infra.packwiz.installer.ui;
|
||||||
|
|
||||||
|
public class InputStateHandler {
|
||||||
|
private boolean optionsButtonPressed = false;
|
||||||
|
private boolean cancelButtonPressed = false;
|
||||||
|
|
||||||
|
synchronized void pressCancelButton() {
|
||||||
|
this.cancelButtonPressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized void pressOptionsButton() {
|
||||||
|
this.optionsButtonPressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean getCancelButton() {
|
||||||
|
return cancelButtonPressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean getOptionsButton() {
|
||||||
|
return optionsButtonPressed;
|
||||||
|
}
|
||||||
|
}
|
@ -13,18 +13,21 @@ public class InstallWindow implements IUserInterface {
|
|||||||
private JFrame frmPackwizlauncher;
|
private JFrame frmPackwizlauncher;
|
||||||
private JLabel lblProgresslabel;
|
private JLabel lblProgresslabel;
|
||||||
private JProgressBar progressBar;
|
private JProgressBar progressBar;
|
||||||
|
private InputStateHandler inputStateHandler;
|
||||||
|
|
||||||
private String title = "Updating modpack...";
|
private String title = "Updating modpack...";
|
||||||
private SwingWorkerButWithPublicPublish<Void, InstallProgress> worker;
|
private SwingWorkerButWithPublicPublish<Void, InstallProgress> worker;
|
||||||
private AtomicBoolean aboutToCrash = new AtomicBoolean();
|
private AtomicBoolean aboutToCrash = new AtomicBoolean();
|
||||||
|
private JButton btnOptions;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void show() {
|
public void show(InputStateHandler handler) {
|
||||||
|
this.inputStateHandler = handler;
|
||||||
EventQueue.invokeLater(() -> {
|
EventQueue.invokeLater(() -> {
|
||||||
try {
|
try {
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
InstallWindow.this.initialize();
|
initialize();
|
||||||
InstallWindow.this.frmPackwizlauncher.setVisible(true);
|
frmPackwizlauncher.setVisible(true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -60,7 +63,12 @@ public class InstallWindow implements IUserInterface {
|
|||||||
GridBagLayout gbl_panel_1 = new GridBagLayout();
|
GridBagLayout gbl_panel_1 = new GridBagLayout();
|
||||||
panel_1.setLayout(gbl_panel_1);
|
panel_1.setLayout(gbl_panel_1);
|
||||||
|
|
||||||
JButton btnOptions = new JButton("Configure...");
|
btnOptions = new JButton("Optional mods...");
|
||||||
|
btnOptions.addActionListener(e -> {
|
||||||
|
btnOptions.setText("Loading...");
|
||||||
|
btnOptions.setEnabled(false);
|
||||||
|
inputStateHandler.pressOptionsButton();
|
||||||
|
});
|
||||||
btnOptions.setAlignmentX(Component.CENTER_ALIGNMENT);
|
btnOptions.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
GridBagConstraints gbc_btnOptions = new GridBagConstraints();
|
GridBagConstraints gbc_btnOptions = new GridBagConstraints();
|
||||||
gbc_btnOptions.gridx = 0;
|
gbc_btnOptions.gridx = 0;
|
||||||
@ -68,14 +76,9 @@ public class InstallWindow implements IUserInterface {
|
|||||||
panel_1.add(btnOptions, gbc_btnOptions);
|
panel_1.add(btnOptions, gbc_btnOptions);
|
||||||
|
|
||||||
JButton btnCancel = new JButton("Cancel");
|
JButton btnCancel = new JButton("Cancel");
|
||||||
btnCancel.addActionListener(event -> {
|
btnCancel.addActionListener(e -> {
|
||||||
if (worker != null) {
|
btnCancel.setEnabled(false);
|
||||||
worker.cancel(true);
|
inputStateHandler.pressCancelButton();
|
||||||
}
|
|
||||||
frmPackwizlauncher.dispose();
|
|
||||||
// TODO: show window to ask user what to do
|
|
||||||
System.out.println("Update process cancelled by user!");
|
|
||||||
System.exit(1);
|
|
||||||
});
|
});
|
||||||
btnCancel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
btnCancel.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
GridBagConstraints gbc_btnCancel = new GridBagConstraints();
|
GridBagConstraints gbc_btnCancel = new GridBagConstraints();
|
||||||
@ -113,12 +116,23 @@ public class InstallWindow implements IUserInterface {
|
|||||||
public void setTitle(String title) {
|
public void setTitle(String title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
if (frmPackwizlauncher != null) {
|
if (frmPackwizlauncher != null) {
|
||||||
EventQueue.invokeLater(() -> InstallWindow.this.frmPackwizlauncher.setTitle(title));
|
EventQueue.invokeLater(() -> frmPackwizlauncher.setTitle(title));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void submitProgress(InstallProgress progress) {
|
public void submitProgress(InstallProgress progress) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (progress.hasProgress) {
|
||||||
|
sb.append('(');
|
||||||
|
sb.append(progress.progress);
|
||||||
|
sb.append('/');
|
||||||
|
sb.append(progress.progressTotal);
|
||||||
|
sb.append(") ");
|
||||||
|
}
|
||||||
|
sb.append(progress.message);
|
||||||
|
// TODO: better logging library?
|
||||||
|
System.out.println(sb.toString());
|
||||||
if (worker != null) {
|
if (worker != null) {
|
||||||
worker.publishPublic(progress);
|
worker.publishPublic(progress);
|
||||||
}
|
}
|
||||||
@ -190,4 +204,25 @@ public class InstallWindow implements IUserInterface {
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disableOptionsButton() {
|
||||||
|
if (btnOptions != null) {
|
||||||
|
btnOptions.setText("Optional mods...");
|
||||||
|
btnOptions.setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<IExceptionDetails.ExceptionListResult> showCancellationDialog() {
|
||||||
|
CompletableFuture<IExceptionDetails.ExceptionListResult> future = new CompletableFuture<>();
|
||||||
|
EventQueue.invokeLater(() -> {
|
||||||
|
Object[] buttons = {"Quit", "Ignore"};
|
||||||
|
int result = JOptionPane.showOptionDialog(frmPackwizlauncher,
|
||||||
|
"The installation was cancelled. Would you like to quit the game, or ignore the update and start the game?",
|
||||||
|
"Cancelled installation",
|
||||||
|
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, buttons, buttons[0]);
|
||||||
|
future.complete(result == 0 ? IExceptionDetails.ExceptionListResult.CANCEL : IExceptionDetails.ExceptionListResult.IGNORE);
|
||||||
|
});
|
||||||
|
return future;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package link.infra.packwiz.installer.ui;
|
package link.infra.packwiz.installer.ui;
|
||||||
|
|
||||||
// Serves as a proxy for IOptionDetails, so that setOptionValue isn't called until OK is clicked
|
// Serves as a proxy for IOptionDetails, so that setOptionValue isn't called until OK is clicked
|
||||||
public class OptionTempHandler implements IOptionDetails {
|
class OptionTempHandler implements IOptionDetails {
|
||||||
private final IOptionDetails opt;
|
private final IOptionDetails opt;
|
||||||
private boolean tempValue;
|
private boolean tempValue;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user