在未安装游戏版本时支持一键下载启动游戏 (#4248)
This commit is contained in:
@@ -31,6 +31,7 @@ import javafx.geometry.Insets;
|
|||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.Tooltip;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.input.MouseButton;
|
import javafx.scene.input.MouseButton;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
@@ -42,10 +43,16 @@ import javafx.scene.shape.Rectangle;
|
|||||||
import javafx.scene.text.TextFlow;
|
import javafx.scene.text.TextFlow;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import org.jackhuang.hmcl.Metadata;
|
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.game.Version;
|
||||||
|
import org.jackhuang.hmcl.setting.DownloadProviders;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.setting.Profiles;
|
import org.jackhuang.hmcl.setting.Profiles;
|
||||||
import org.jackhuang.hmcl.setting.Theme;
|
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.Controllers;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.SVG;
|
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.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.upgrade.UpdateChecker;
|
import org.jackhuang.hmcl.upgrade.UpdateChecker;
|
||||||
import org.jackhuang.hmcl.upgrade.UpdateHandler;
|
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.BindingMapping;
|
||||||
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
|
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.IntStream;
|
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.setting.ConfigHolder.config;
|
||||||
import static org.jackhuang.hmcl.ui.FXUtils.SINE;
|
import static org.jackhuang.hmcl.ui.FXUtils.SINE;
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
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 {
|
public final class MainPage extends StackPane implements DecoratorPage {
|
||||||
private static final String ANNOUNCEMENT = "announcement";
|
private static final String ANNOUNCEMENT = "announcement";
|
||||||
@@ -211,7 +226,6 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
launchButton.setPrefWidth(230);
|
launchButton.setPrefWidth(230);
|
||||||
launchButton.setPrefHeight(55);
|
launchButton.setPrefHeight(55);
|
||||||
//launchButton.setButtonType(JFXButton.ButtonType.RAISED);
|
//launchButton.setButtonType(JFXButton.ButtonType.RAISED);
|
||||||
launchButton.setOnAction(e -> launch());
|
|
||||||
launchButton.setDefaultButton(true);
|
launchButton.setDefaultButton(true);
|
||||||
launchButton.setClip(new Rectangle(-100, -100, 310, 200));
|
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.setAlignment(Pos.CENTER);
|
||||||
graphic.setTranslateX(-7);
|
graphic.setTranslateX(-7);
|
||||||
graphic.setMaxWidth(200);
|
graphic.setMaxWidth(200);
|
||||||
Label launchLabel = new Label(i18n("version.launch"));
|
Label launchLabel = new Label();
|
||||||
launchLabel.setStyle("-fx-font-size: 16px;");
|
launchLabel.setStyle("-fx-font-size: 16px;");
|
||||||
Label currentLabel = new Label();
|
Label currentLabel = new Label();
|
||||||
currentLabel.setStyle("-fx-font-size: 12px;");
|
currentLabel.setStyle("-fx-font-size: 12px;");
|
||||||
currentLabel.textProperty().bind(Bindings.createStringBinding(() -> {
|
|
||||||
if (getCurrentGame() == null) {
|
FXUtils.onChangeAndOperate(currentGameProperty(), new Consumer<>() {
|
||||||
return i18n("version.empty");
|
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 {
|
} else {
|
||||||
return getCurrentGame();
|
launchLabel.setText(i18n("version.launch"));
|
||||||
}
|
currentLabel.setText(currentGame);
|
||||||
}, currentGameProperty()));
|
|
||||||
graphic.getChildren().setAll(launchLabel, currentLabel);
|
graphic.getChildren().setAll(launchLabel, currentLabel);
|
||||||
|
launchButton.setOnAction(e -> MainPage.this.launch());
|
||||||
|
if (tooltip != null)
|
||||||
|
Tooltip.uninstall(launchButton, tooltip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
launchButton.setGraphic(graphic);
|
launchButton.setGraphic(graphic);
|
||||||
}
|
}
|
||||||
@@ -319,7 +349,46 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void launch() {
|
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<String> 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() {
|
private void onMenu() {
|
||||||
|
|||||||
@@ -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<LauncherHelper> injecter) {
|
public static void launch(Profile profile, String id, Consumer<LauncherHelper> injecter) {
|
||||||
if (!checkVersionForLaunching(profile, id))
|
if (!checkVersionForLaunching(profile, id))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1436,6 +1436,9 @@ version.game.snapshot=Snapshot
|
|||||||
version.game.snapshots=Snapshots
|
version.game.snapshots=Snapshots
|
||||||
version.game.type=Type
|
version.game.type=Type
|
||||||
version.launch=Launch Game
|
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.launch.test=Test Launch
|
||||||
version.switch=Switch Instance
|
version.switch=Switch Instance
|
||||||
version.launch_script=Export Launch Script
|
version.launch_script=Export Launch Script
|
||||||
|
|||||||
@@ -1229,6 +1229,9 @@ version.game.snapshot=快照
|
|||||||
version.game.snapshots=快照
|
version.game.snapshots=快照
|
||||||
version.game.type=版本類型
|
version.game.type=版本類型
|
||||||
version.launch=啟動遊戲
|
version.launch=啟動遊戲
|
||||||
|
version.launch.empty=開始遊戲
|
||||||
|
version.launch.empty.installing=安裝遊戲
|
||||||
|
version.launch.empty.tooltip=安裝並啟動最新正式版遊戲
|
||||||
version.launch.test=測試遊戲
|
version.launch.test=測試遊戲
|
||||||
version.switch=切換實例
|
version.switch=切換實例
|
||||||
version.launch_script=生成啟動指令碼
|
version.launch_script=生成啟動指令碼
|
||||||
|
|||||||
@@ -1239,6 +1239,9 @@ version.game.snapshot=快照
|
|||||||
version.game.snapshots=快照
|
version.game.snapshots=快照
|
||||||
version.game.type=版本类型
|
version.game.type=版本类型
|
||||||
version.launch=启动游戏
|
version.launch=启动游戏
|
||||||
|
version.launch.empty=开始游戏
|
||||||
|
version.launch.empty.installing=安装游戏
|
||||||
|
version.launch.empty.tooltip=安装并启动最新正式版游戏
|
||||||
version.launch.test=测试游戏
|
version.launch.test=测试游戏
|
||||||
version.switch=切换版本
|
version.switch=切换版本
|
||||||
version.launch_script=生成启动脚本
|
version.launch_script=生成启动脚本
|
||||||
|
|||||||
Reference in New Issue
Block a user