Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
import javafx.scene.control.ButtonBase;
import javafx.scene.control.Label;
import javafx.scene.layout.Region;
import javafx.stage.*;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.util.Duration;
import org.jackhuang.hmcl.Launcher;
import org.jackhuang.hmcl.Metadata;
Expand All @@ -46,12 +49,12 @@
import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType;
import org.jackhuang.hmcl.ui.decorator.Decorator;
import org.jackhuang.hmcl.ui.download.DownloadPage;
import org.jackhuang.hmcl.ui.instances.GameInstancePage;
import org.jackhuang.hmcl.ui.instances.GameListPage;
import org.jackhuang.hmcl.ui.instances.Instances;
import org.jackhuang.hmcl.ui.main.LauncherSettingsPage;
import org.jackhuang.hmcl.ui.main.RootPage;
import org.jackhuang.hmcl.ui.terracotta.TerracottaPage;
import org.jackhuang.hmcl.ui.instances.GameListPage;
import org.jackhuang.hmcl.ui.instances.GameInstancePage;
import org.jackhuang.hmcl.ui.instances.Instances;
import org.jackhuang.hmcl.upgrade.UpdateChecker;
import org.jackhuang.hmcl.util.*;
import org.jackhuang.hmcl.util.i18n.I18n;
Expand All @@ -70,10 +73,7 @@
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

import static org.jackhuang.hmcl.setting.SettingsManager.settings;
import static org.jackhuang.hmcl.setting.SettingsManager.getAuthlibInjectorServers;
import static org.jackhuang.hmcl.setting.SettingsManager.state;
import static org.jackhuang.hmcl.setting.SettingsManager.userState;
import static org.jackhuang.hmcl.setting.SettingsManager.*;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;

Expand Down Expand Up @@ -501,6 +501,19 @@ public static TaskExecutorDialogPane taskDialog(Task<?> task, String title, @Not
return pane;
}

public static TaskLoadingDialog taskLoadingDialog(TaskExecutor executor, String title, @NotNull TaskCancellationAction onCancel) {
TaskLoadingDialog pane = new TaskLoadingDialog(title, onCancel, executor);
dialog(pane);
return pane;
}

public static TaskLoadingDialog taskLoadingDialog(Task<?> task, String title, @NotNull TaskCancellationAction onCancel) {
TaskExecutor executor = task.executor();
TaskLoadingDialog pane = taskLoadingDialog(executor, title, onCancel);
executor.start();
return pane;
}

public static void navigate(Node node) {
decorator.navigate(node, ContainerAnimations.NAVIGATION, Motion.SHORT4, Motion.EASE);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2026 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.ui.construct;

import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDialogLayout;
import com.jfoenix.controls.JFXSpinner;
import javafx.application.Platform;
import javafx.beans.property.StringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import org.jackhuang.hmcl.task.TaskExecutor;
import org.jackhuang.hmcl.task.TaskListener;
import org.jackhuang.hmcl.theme.Themes;
import org.jackhuang.hmcl.util.TaskCancellationAction;
import org.jetbrains.annotations.NotNull;

import static org.jackhuang.hmcl.util.i18n.I18n.i18n;

public final class TaskLoadingDialog extends JFXDialogLayout {
private final Label lblTitle;

public TaskLoadingDialog(String title, @NotNull TaskCancellationAction onCancel, TaskExecutor executor) {
var vbox = new VBox(20);
vbox.setPadding(new Insets(10));
vbox.setAlignment(Pos.CENTER);

lblTitle = new Label(title);
lblTitle.setStyle("-fx-font-size: 16px; -fx-font-weight: BOLD;");

JFXSpinner spinner = new JFXSpinner();

JFXButton cancelButton = new JFXButton(i18n("button.cancel"));

if (onCancel.getCancellationAction() != null) {
cancelButton.setOnAction(event -> onCancel.getCancellationAction().accept(this));
} else cancelButton.setDisable(true);

cancelButton.setTextFill(Themes.getColorScheme().getOnSurface());

executor.addTaskListener(new TaskListener() {
@Override
public void onStop(boolean success, TaskExecutor executor) {
Platform.runLater(() -> fireEvent(new DialogCloseEvent()));
}
});

vbox.getChildren().addAll(lblTitle, spinner, cancelButton);
getChildren().setAll(vbox);
}

public StringProperty titleProperty() {
return lblTitle.textProperty();
}

public String getTitle() {
return lblTitle.getText();
}

public void setTitle(String currentState) {
lblTitle.setText(currentState);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import java.util.List;

import static org.jackhuang.hmcl.setting.SettingsManager.settings;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;

public final class ExportWizardProvider implements WizardProvider {
private final HMCLGameRepository repository;
Expand All @@ -57,6 +58,8 @@ public ExportWizardProvider(HMCLGameRepository repository, GameInstanceID instan

@Override
public void start(SettingsMap settings) {
settings.put("use_loading_dialog", "true");
settings.put("title", i18n("modpack.exporting"));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ private void updateFiles() {
private void exportList() {
Path path = Paths.get("hmcl-mod-update-list-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss")) + ".csv").toAbsolutePath();

Controllers.taskDialog(Task.runAsync(() -> {
Controllers.taskLoadingDialog(Task.runAsync(() -> {
CSVTable csvTable = new CSVTable();

csvTable.set(0, 0, "Source File Name");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ protected Skin<?> createDefaultSkin() {
}

void createBackup() {
Controllers.taskDialog(new WorldBackupTask(world, backupsDir, false).setName(i18n("world.backup.processing")).thenApplyAsync(path -> {
Controllers.taskLoadingDialog(new WorldBackupTask(world, backupsDir, false).thenApplyAsync(path -> {
Matcher matcher = backupFileNamePattern.matcher(path.getFileName().toString());
if (!matcher.matches()) {
throw new AssertionError("Wrong backup file name" + path);
Expand All @@ -156,7 +156,7 @@ void createBackup() {
LOG.warning("Failed to create backup", exception);
Controllers.dialog(i18n("world.backup.create.failed", StringUtils.getStackTrace(exception)), null, MessageDialogPane.MessageType.WARNING);
}
}), i18n("world.backup"), TaskCancellationAction.NO_CANCEL);
}), i18n("world.backup.processing"), TaskCancellationAction.NO_CANCEL);
}

private final class WorldBackupsPageSkin extends ToolbarListPageSkin<BackupInfo, WorldBackupsPage> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
import org.jackhuang.hmcl.java.JavaInfo;
import org.jackhuang.hmcl.java.JavaManager;
import org.jackhuang.hmcl.java.JavaRuntime;
import org.jackhuang.hmcl.setting.SettingsManager;
import org.jackhuang.hmcl.setting.DownloadProviders;
import org.jackhuang.hmcl.setting.SettingsManager;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.task.Task;
import org.jackhuang.hmcl.ui.*;
Expand All @@ -50,17 +50,19 @@
import org.jackhuang.hmcl.util.Pair;
import org.jackhuang.hmcl.util.TaskCancellationAction;
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.platform.UnsupportedPlatformException;
import org.jackhuang.hmcl.util.tree.ArchiveFileTree;
import org.jetbrains.annotations.Nullable;
import org.jackhuang.hmcl.util.platform.Architecture;
import org.jackhuang.hmcl.util.platform.OperatingSystem;
import org.jackhuang.hmcl.util.platform.Platform;
import org.jackhuang.hmcl.util.platform.UnsupportedPlatformException;
import org.jackhuang.hmcl.util.tree.ArchiveFileTree;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
Expand Down Expand Up @@ -348,7 +350,7 @@ private void onRemove(JavaRuntime java) {
Controllers.confirm(
i18n("java.uninstall.confirm"),
i18n("message.warning"),
() -> Controllers.taskDialog(JavaManager.getUninstallJavaTask(java), i18n("java.uninstall"), TaskCancellationAction.NORMAL),
() -> Controllers.taskLoadingDialog(JavaManager.getUninstallJavaTask(java), i18n("java.uninstall"), TaskCancellationAction.NORMAL),
null
);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,15 @@
import com.jfoenix.controls.JFXTextField;
import javafx.animation.PauseTransition;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Skin;
import javafx.scene.control.SkinBase;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
Expand Down Expand Up @@ -251,7 +243,7 @@ private void confirmApplyTheme(ThemePackManager.InstalledThemePack themePack, Th
private void applyTheme(ThemePackManager.InstalledThemePack themePack, Theme theme) {
try {
if (Themes.shouldWaitForThemeBackground()) {
Controllers.taskDialog(
Controllers.taskLoadingDialog(
Themes.applyTheme(themePack, theme),
i18n("launcher.background.loading"),
TaskCancellationAction.NO_CANCEL);
Expand Down
Loading