diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java index cbb24311a..ae5633634 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java @@ -31,6 +31,7 @@ import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Label; +import javafx.scene.control.Tooltip; import javafx.scene.image.ImageView; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; @@ -42,10 +43,16 @@ import javafx.scene.shape.Rectangle; import javafx.scene.text.TextFlow; import javafx.util.Duration; import org.jackhuang.hmcl.Metadata; +import org.jackhuang.hmcl.download.DefaultDependencyManager; +import org.jackhuang.hmcl.download.DownloadProvider; +import org.jackhuang.hmcl.download.VersionList; import org.jackhuang.hmcl.game.Version; +import org.jackhuang.hmcl.setting.DownloadProviders; import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.Profiles; import org.jackhuang.hmcl.setting.Theme; +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.SVG; @@ -61,16 +68,24 @@ import org.jackhuang.hmcl.ui.versions.Versions; import org.jackhuang.hmcl.upgrade.RemoteVersion; import org.jackhuang.hmcl.upgrade.UpdateChecker; import org.jackhuang.hmcl.upgrade.UpdateHandler; +import org.jackhuang.hmcl.util.Holder; +import org.jackhuang.hmcl.util.StringUtils; +import org.jackhuang.hmcl.util.TaskCancellationAction; import org.jackhuang.hmcl.util.javafx.BindingMapping; import org.jackhuang.hmcl.util.javafx.MappedObservableList; +import java.io.IOException; import java.util.List; import java.util.Objects; +import java.util.concurrent.CancellationException; +import java.util.function.Consumer; import java.util.stream.IntStream; +import static org.jackhuang.hmcl.download.RemoteVersion.Type.RELEASE; import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.ui.FXUtils.SINE; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; +import static org.jackhuang.hmcl.util.logging.Logger.LOG; public final class MainPage extends StackPane implements DecoratorPage { private static final String ANNOUNCEMENT = "announcement"; @@ -211,7 +226,6 @@ public final class MainPage extends StackPane implements DecoratorPage { launchButton.setPrefWidth(230); launchButton.setPrefHeight(55); //launchButton.setButtonType(JFXButton.ButtonType.RAISED); - launchButton.setOnAction(e -> launch()); launchButton.setDefaultButton(true); launchButton.setClip(new Rectangle(-100, -100, 310, 200)); { @@ -219,18 +233,34 @@ public final class MainPage extends StackPane implements DecoratorPage { graphic.setAlignment(Pos.CENTER); graphic.setTranslateX(-7); graphic.setMaxWidth(200); - Label launchLabel = new Label(i18n("version.launch")); + Label launchLabel = new Label(); launchLabel.setStyle("-fx-font-size: 16px;"); Label currentLabel = new Label(); currentLabel.setStyle("-fx-font-size: 12px;"); - currentLabel.textProperty().bind(Bindings.createStringBinding(() -> { - if (getCurrentGame() == null) { - return i18n("version.empty"); - } else { - return getCurrentGame(); + + FXUtils.onChangeAndOperate(currentGameProperty(), new Consumer<>() { + private Tooltip tooltip; + + @Override + public void accept(String currentGame) { + if (currentGame == null) { + launchLabel.setText(i18n("version.launch.empty")); + currentLabel.setText(null); + graphic.getChildren().setAll(launchLabel); + launchButton.setOnAction(e -> MainPage.this.launchNoGame()); + if (tooltip == null) + tooltip = new Tooltip(i18n("version.launch.empty.tooltip")); + FXUtils.installFastTooltip(launchButton, tooltip); + } else { + launchLabel.setText(i18n("version.launch")); + currentLabel.setText(currentGame); + graphic.getChildren().setAll(launchLabel, currentLabel); + launchButton.setOnAction(e -> MainPage.this.launch()); + if (tooltip != null) + Tooltip.uninstall(launchButton, tooltip); + } } - }, currentGameProperty())); - graphic.getChildren().setAll(launchLabel, currentLabel); + }); launchButton.setGraphic(graphic); } @@ -319,7 +349,46 @@ public final class MainPage extends StackPane implements DecoratorPage { } private void launch() { - Versions.launch(Profiles.getSelectedProfile()); + Profile profile = Profiles.getSelectedProfile(); + Versions.launch(profile, profile.getSelectedVersion(), null); + } + + private void launchNoGame() { + DownloadProvider downloadProvider = DownloadProviders.getDownloadProvider(); + VersionList versionList = downloadProvider.getVersionListById("game"); + + Holder gameVersionHolder = new Holder<>(); + Task task = versionList.refreshAsync("") + .thenSupplyAsync(() -> versionList.getVersions("").stream() + .filter(it -> it.getVersionType() == RELEASE) + .sorted() + .findFirst() + .orElseThrow(() -> new IOException("No versions found"))) + .thenComposeAsync(version -> { + Profile profile = Profiles.getSelectedProfile(); + DefaultDependencyManager dependency = profile.getDependency(); + String gameVersion = gameVersionHolder.value = version.getGameVersion(); + + return dependency.gameBuilder() + .name(gameVersion) + .gameVersion(gameVersion) + .buildAsync(); + }) + .whenComplete(any -> profile.getRepository().refreshVersions()) + .whenComplete(Schedulers.javafx(), (result, exception) -> { + if (exception == null) { + profile.setSelectedVersion(gameVersionHolder.value); + launch(); + } else if (exception instanceof CancellationException) { + Controllers.showToast(i18n("message.cancelled")); + } else { + LOG.warning("Failed to install game", exception); + Controllers.dialog(StringUtils.getStackTrace(exception), + i18n("install.failed"), + MessageDialogPane.MessageType.WARNING); + } + }); + Controllers.taskDialog(task, i18n("version.launch.empty.installing"), TaskCancellationAction.NORMAL); } private void onMenu() { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/Versions.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/Versions.java index efc7de9fb..aa95dd6c6 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/Versions.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/Versions.java @@ -205,14 +205,6 @@ public final class Versions { }); } - public static void launch(Profile profile) { - launch(profile, profile.getSelectedVersion()); - } - - public static void launch(Profile profile, String id) { - launch(profile, id, null); - } - public static void launch(Profile profile, String id, Consumer injecter) { if (!checkVersionForLaunching(profile, id)) return; diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index a64e0a31b..b6e5ecd2b 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -1436,6 +1436,9 @@ version.game.snapshot=Snapshot version.game.snapshots=Snapshots version.game.type=Type version.launch=Launch Game +version.launch.empty=Start Game +version.launch.empty.installing=Installing Game +version.launch.empty.tooltip=Install and launch the latest official release version.launch.test=Test Launch version.switch=Switch Instance version.launch_script=Export Launch Script diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 3a2d831d2..675658d37 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -1229,6 +1229,9 @@ version.game.snapshot=快照 version.game.snapshots=快照 version.game.type=版本類型 version.launch=啟動遊戲 +version.launch.empty=開始遊戲 +version.launch.empty.installing=安裝遊戲 +version.launch.empty.tooltip=安裝並啟動最新正式版遊戲 version.launch.test=測試遊戲 version.switch=切換實例 version.launch_script=生成啟動指令碼 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index b77fa243f..6b2807d96 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -1239,6 +1239,9 @@ version.game.snapshot=快照 version.game.snapshots=快照 version.game.type=版本类型 version.launch=启动游戏 +version.launch.empty=开始游戏 +version.launch.empty.installing=安装游戏 +version.launch.empty.tooltip=安装并启动最新正式版游戏 version.launch.test=测试游戏 version.switch=切换版本 version.launch_script=生成启动脚本