alt: actions in game list now also in version page

This commit is contained in:
huanghongxun
2020-03-16 22:48:42 +08:00
parent 2bc7bdba8a
commit bde76707f3
10 changed files with 147 additions and 81 deletions

View File

@@ -40,6 +40,7 @@ import org.jackhuang.hmcl.util.Logging;
import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.platform.JavaVersion; import org.jackhuang.hmcl.util.platform.JavaVersion;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer; import java.util.function.Consumer;
import static org.jackhuang.hmcl.setting.ConfigHolder.config; import static org.jackhuang.hmcl.setting.ConfigHolder.config;
@@ -138,14 +139,19 @@ public final class Controllers {
dialog(new MessageDialogPane(text, title, type, onAccept)); dialog(new MessageDialogPane(text, title, type, onAccept));
} }
public static void confirmDialog(String text, String title, Runnable onAccept, Runnable onCancel) { public static void confirm(String text, String title, Runnable onAccept, Runnable onCancel) {
dialog(new MessageDialogPane(text, title, onAccept, onCancel)); dialog(new MessageDialogPane(text, title, onAccept, onCancel));
} }
public static InputDialogPane inputDialog(String text, FutureCallback<String> onResult) { public static CompletableFuture<String> prompt(String text, FutureCallback<String> onResult) {
return prompt(text, onResult, "");
}
public static CompletableFuture<String> prompt(String text, FutureCallback<String> onResult, String initialValue) {
InputDialogPane pane = new InputDialogPane(text, onResult); InputDialogPane pane = new InputDialogPane(text, onResult);
dialog(pane); dialog(pane);
return pane; pane.setInitialValue(initialValue);
return pane.getCompletableFuture();
} }
public static TaskExecutorDialogPane taskDialog(TaskExecutor executor, String title) { public static TaskExecutorDialogPane taskDialog(TaskExecutor executor, String title) {

View File

@@ -26,7 +26,10 @@ import javafx.scene.layout.StackPane;
import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.util.FutureCallback; import org.jackhuang.hmcl.util.FutureCallback;
import java.util.concurrent.CompletableFuture;
public class InputDialogPane extends StackPane { public class InputDialogPane extends StackPane {
private final CompletableFuture<String> future = new CompletableFuture<>();
@FXML @FXML
private JFXButton acceptButton; private JFXButton acceptButton;
@@ -47,8 +50,10 @@ public class InputDialogPane extends StackPane {
cancelButton.setOnMouseClicked(e -> fireEvent(new DialogCloseEvent())); cancelButton.setOnMouseClicked(e -> fireEvent(new DialogCloseEvent()));
acceptButton.setOnMouseClicked(e -> { acceptButton.setOnMouseClicked(e -> {
acceptPane.showSpinner(); acceptPane.showSpinner();
onResult.call(textField.getText(), () -> { onResult.call(textField.getText(), () -> {
acceptPane.hideSpinner(); acceptPane.hideSpinner();
future.complete(textField.getText());
fireEvent(new DialogCloseEvent()); fireEvent(new DialogCloseEvent());
}, msg -> { }, msg -> {
acceptPane.hideSpinner(); acceptPane.hideSpinner();
@@ -62,7 +67,11 @@ public class InputDialogPane extends StackPane {
)); ));
} }
public void setInitialText(String text) { public void setInitialValue(String value) {
textField.setText(text); textField.setText(value);
}
public CompletableFuture<String> getCompletableFuture() {
return future;
} }
} }

View File

@@ -42,7 +42,7 @@ import java.nio.file.Path;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import static org.jackhuang.hmcl.ui.download.LocalModpackPage.*; import static org.jackhuang.hmcl.ui.download.LocalModpackPage.MODPACK_FILE;
import static org.jackhuang.hmcl.ui.download.RemoteModpackPage.MODPACK_SERVER_MANIFEST; import static org.jackhuang.hmcl.ui.download.RemoteModpackPage.MODPACK_SERVER_MANIFEST;
import static org.jackhuang.hmcl.util.Lang.tryCast; import static org.jackhuang.hmcl.util.Lang.tryCast;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
@@ -90,7 +90,7 @@ public final class ModpackSelectionPage extends StackPane implements WizardPage
@FXML @FXML
private void onChooseRemoteFile() { private void onChooseRemoteFile() {
Controllers.inputDialog(i18n("modpack.choose.remote.tooltip"), (urlString, resolve, reject) -> { Controllers.prompt(i18n("modpack.choose.remote.tooltip"), (urlString, resolve, reject) -> {
try { try {
URL url = new URL(urlString); URL url = new URL(urlString);
if (urlString.endsWith("server-manifest.json")) { if (urlString.endsWith("server-manifest.json")) {

View File

@@ -58,7 +58,7 @@ class DatapackListPageSkin extends SkinBase<DatapackListPage> {
toolbar.getChildren().add(createToolbarButton(i18n("button.refresh"), SVG::refresh, skinnable::refresh)); toolbar.getChildren().add(createToolbarButton(i18n("button.refresh"), SVG::refresh, skinnable::refresh));
toolbar.getChildren().add(createToolbarButton(i18n("datapack.add"), SVG::plus, skinnable::add)); toolbar.getChildren().add(createToolbarButton(i18n("datapack.add"), SVG::plus, skinnable::add));
toolbar.getChildren().add(createToolbarButton(i18n("button.remove"), SVG::delete, () -> { toolbar.getChildren().add(createToolbarButton(i18n("button.remove"), SVG::delete, () -> {
Controllers.confirmDialog(i18n("button.remove.confirm"), i18n("button.remove"), () -> { Controllers.confirm(i18n("button.remove.confirm"), i18n("button.remove"), () -> {
skinnable.removeSelected(listView.getSelectionModel().getSelectedItems()); skinnable.removeSelected(listView.getSelectionModel().getSelectedItems());
}, null); }, null);
})); }));

View File

@@ -39,6 +39,8 @@ import static org.jackhuang.hmcl.ui.FXUtils.runInFX;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
public class GameListItemSkin extends SkinBase<GameListItem> { public class GameListItemSkin extends SkinBase<GameListItem> {
private static JFXPopup popup;
private static GameListItem currentSkinnable;
public GameListItemSkin(GameListItem skinnable) { public GameListItemSkin(GameListItem skinnable) {
super(skinnable); super(skinnable);
@@ -56,20 +58,22 @@ public class GameListItemSkin extends SkinBase<GameListItem> {
gameItem.setMouseTransparent(true); gameItem.setMouseTransparent(true);
root.setCenter(gameItem); root.setCenter(gameItem);
PopupMenu menu = new PopupMenu(); if (popup == null) {
JFXPopup popup = new JFXPopup(menu); PopupMenu menu = new PopupMenu();
popup = new JFXPopup(menu);
menu.getContent().setAll( menu.getContent().setAll(
new IconedMenuItem(FXUtils.limitingSize(SVG.launch(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch.test"), FXUtils.withJFXPopupClosing(skinnable::launch, popup)), new IconedMenuItem(FXUtils.limitingSize(SVG.launch(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch.test"), FXUtils.withJFXPopupClosing(() -> currentSkinnable.launch(), popup)),
new IconedMenuItem(FXUtils.limitingSize(SVG.script(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch_script"), FXUtils.withJFXPopupClosing(skinnable::generateLaunchScript, popup)), new IconedMenuItem(FXUtils.limitingSize(SVG.script(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch_script"), FXUtils.withJFXPopupClosing(() -> currentSkinnable.generateLaunchScript(), popup)),
new MenuSeparator(), new MenuSeparator(),
new IconedMenuItem(FXUtils.limitingSize(SVG.gear(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.manage.manage"), FXUtils.withJFXPopupClosing(skinnable::modifyGameSettings, popup)), new IconedMenuItem(FXUtils.limitingSize(SVG.gear(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.manage.manage"), FXUtils.withJFXPopupClosing(() -> currentSkinnable.modifyGameSettings(), popup)),
new MenuSeparator(), new MenuSeparator(),
new IconedMenuItem(FXUtils.limitingSize(SVG.pencil(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.manage.rename"), FXUtils.withJFXPopupClosing(skinnable::rename, popup)), new IconedMenuItem(FXUtils.limitingSize(SVG.pencil(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.manage.rename"), FXUtils.withJFXPopupClosing(() -> currentSkinnable.rename(), popup)),
new IconedMenuItem(FXUtils.limitingSize(SVG.delete(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.manage.remove"), FXUtils.withJFXPopupClosing(skinnable::remove, popup)), new IconedMenuItem(FXUtils.limitingSize(SVG.delete(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.manage.remove"), FXUtils.withJFXPopupClosing(() -> currentSkinnable.remove(), popup)),
new IconedMenuItem(FXUtils.limitingSize(SVG.export(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("modpack.export"), FXUtils.withJFXPopupClosing(skinnable::export, popup)), new IconedMenuItem(FXUtils.limitingSize(SVG.export(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("modpack.export"), FXUtils.withJFXPopupClosing(() -> currentSkinnable.export(), popup)),
new MenuSeparator(), new MenuSeparator(),
new IconedMenuItem(FXUtils.limitingSize(SVG.folderOpen(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("folder.game"), FXUtils.withJFXPopupClosing(skinnable::browse, popup))); new IconedMenuItem(FXUtils.limitingSize(SVG.folderOpen(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("folder.game"), FXUtils.withJFXPopupClosing(() -> currentSkinnable.browse(), popup)));
}
HBox right = new HBox(); HBox right = new HBox();
right.setAlignment(Pos.CENTER_RIGHT); right.setAlignment(Pos.CENTER_RIGHT);
@@ -84,6 +88,7 @@ public class GameListItemSkin extends SkinBase<GameListItem> {
JFXButton btnManage = new JFXButton(); JFXButton btnManage = new JFXButton();
btnManage.setOnMouseClicked(e -> { btnManage.setOnMouseClicked(e -> {
currentSkinnable = skinnable;
popup.show(root, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.RIGHT, 0, root.getHeight()); popup.show(root, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.RIGHT, 0, root.getHeight());
}); });
btnManage.getStyleClass().add("toggle-icon4"); btnManage.getStyleClass().add("toggle-icon4");
@@ -105,6 +110,7 @@ public class GameListItemSkin extends SkinBase<GameListItem> {
skinnable.modifyGameSettings(); skinnable.modifyGameSettings();
} }
} else if (e.getButton() == MouseButton.SECONDARY) { } else if (e.getButton() == MouseButton.SECONDARY) {
currentSkinnable = skinnable;
popup.show(root, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.LEFT, e.getX(), e.getY()); popup.show(root, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.LEFT, e.getX(), e.getY());
} }
}); });

View File

@@ -64,7 +64,7 @@ class ModListPageSkin extends SkinBase<ModListPage> {
toolbar.getChildren().add(createToolbarButton(i18n("button.refresh"), SVG::refresh, skinnable::refresh)); toolbar.getChildren().add(createToolbarButton(i18n("button.refresh"), SVG::refresh, skinnable::refresh));
toolbar.getChildren().add(createToolbarButton(i18n("mods.add"), SVG::plus, skinnable::add)); toolbar.getChildren().add(createToolbarButton(i18n("mods.add"), SVG::plus, skinnable::add));
toolbar.getChildren().add(createToolbarButton(i18n("button.remove"), SVG::delete, () -> { toolbar.getChildren().add(createToolbarButton(i18n("button.remove"), SVG::delete, () -> {
Controllers.confirmDialog(i18n("button.remove.confirm"), i18n("button.remove"), () -> { Controllers.confirm(i18n("button.remove.confirm"), i18n("button.remove"), () -> {
skinnable.removeSelected(listView.getSelectionModel().getSelectedItems()); skinnable.removeSelected(listView.getSelectionModel().getSelectedItems());
}, null); }, null);
})); }));

View File

@@ -18,20 +18,19 @@
package org.jackhuang.hmcl.ui.versions; package org.jackhuang.hmcl.ui.versions;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXListCell;
import com.jfoenix.controls.JFXListView; import com.jfoenix.controls.JFXListView;
import com.jfoenix.controls.JFXPopup; import com.jfoenix.controls.JFXPopup;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Control; import javafx.scene.control.*;
import javafx.scene.control.SelectionMode; import javafx.scene.input.MouseButton;
import javafx.scene.control.SkinBase;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color; import javafx.util.Callback;
import javafx.scene.shape.Rectangle;
import org.jackhuang.hmcl.game.HMCLGameRepository; import org.jackhuang.hmcl.game.HMCLGameRepository;
import org.jackhuang.hmcl.game.Version; import org.jackhuang.hmcl.game.Version;
import org.jackhuang.hmcl.setting.Profile; import org.jackhuang.hmcl.setting.Profile;
@@ -71,16 +70,27 @@ public class VersionPage extends Control implements DecoratorPage {
private final WorldListPage worldListPage = new WorldListPage(); private final WorldListPage worldListPage = new WorldListPage();
private final TransitionPane transitionPane = new TransitionPane(); private final TransitionPane transitionPane = new TransitionPane();
private final ObjectProperty<TabHeader.Tab> selectedTab = new SimpleObjectProperty<>(); private final ObjectProperty<TabHeader.Tab> selectedTab = new SimpleObjectProperty<>();
private final BooleanProperty currentVersionUpgradable = new SimpleBooleanProperty();
private Profile profile; private Profile profile;
private String version; private String version;
private String preferredVersionName = null;
{ {
Profiles.registerVersionsListener(this::loadVersions); Profiles.registerVersionsListener(this::loadVersions);
listView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { listView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null && !Objects.equals(oldValue, newValue)) if (newValue != null && !Objects.equals(oldValue, newValue))
loadVersion(newValue, profile); loadVersion(newValue, profile);
if (newValue == null && !Objects.equals(oldValue, newValue)) {
if (listView.getItems().contains(preferredVersionName)) {
loadVersion(preferredVersionName, profile);
preferredVersionName = null;
} else if (!listView.getItems().isEmpty()) {
loadVersion(listView.getItems().get(0), profile);
}
}
}); });
versionSettingsTab.setNode(versionSettingsPage); versionSettingsTab.setNode(versionSettingsPage);
@@ -118,6 +128,7 @@ public class VersionPage extends Control implements DecoratorPage {
listView.getSelectionModel().select(version); listView.getSelectionModel().select(version);
versionSettingsPage.loadVersion(profile, version); versionSettingsPage.loadVersion(profile, version);
currentVersionUpgradable.set(profile.getRepository().isModpack(version));
CompletableFuture.allOf( CompletableFuture.allOf(
modListPage.loadVersion(profile, version), modListPage.loadVersion(profile, version),
@@ -160,6 +171,27 @@ public class VersionPage extends Control implements DecoratorPage {
Versions.testGame(profile, version); Versions.testGame(profile, version);
} }
private void updateGame() {
Versions.updateVersion(profile, version);
}
private void generateLaunchScript() {
Versions.generateLaunchScript(profile, version);
}
private void export() {
Versions.exportVersion(profile, version);
}
private void rename() {
Versions.renameVersion(profile, version)
.thenApply(newVersionName -> this.preferredVersionName = newVersionName);
}
private void remove() {
Versions.deleteVersion(profile, version);
}
@Override @Override
protected Skin createDefaultSkin() { protected Skin createDefaultSkin() {
return new Skin(this); return new Skin(this);
@@ -172,6 +204,9 @@ public class VersionPage extends Control implements DecoratorPage {
public static class Skin extends SkinBase<VersionPage> { public static class Skin extends SkinBase<VersionPage> {
String currentVersion;
private JFXPopup listViewItemPopup;
/** /**
* Constructor for all SkinBase instances. * Constructor for all SkinBase instances.
* *
@@ -180,7 +215,46 @@ public class VersionPage extends Control implements DecoratorPage {
protected Skin(VersionPage control) { protected Skin(VersionPage control) {
super(control); super(control);
PopupMenu menu = new PopupMenu();
listViewItemPopup = new JFXPopup(menu);
menu.getContent().setAll(
new IconedMenuItem(FXUtils.limitingSize(SVG.launch(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch.test"), FXUtils.withJFXPopupClosing(() -> {
Versions.testGame(getSkinnable().profile, currentVersion);
}, listViewItemPopup)),
new IconedMenuItem(FXUtils.limitingSize(SVG.script(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch_script"), FXUtils.withJFXPopupClosing(() -> {
Versions.generateLaunchScript(getSkinnable().profile, currentVersion);
}, listViewItemPopup)),
new MenuSeparator(),
new IconedMenuItem(FXUtils.limitingSize(SVG.pencil(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.manage.rename"), FXUtils.withJFXPopupClosing(() -> {
Versions.renameVersion(getSkinnable().profile, currentVersion).thenApply(name -> getSkinnable().preferredVersionName = name);
}, listViewItemPopup)),
new IconedMenuItem(FXUtils.limitingSize(SVG.delete(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.manage.remove"), FXUtils.withJFXPopupClosing(() -> {
Versions.deleteVersion(getSkinnable().profile, currentVersion);
}, listViewItemPopup)),
new IconedMenuItem(FXUtils.limitingSize(SVG.export(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("modpack.export"), FXUtils.withJFXPopupClosing(() -> {
Versions.exportVersion(getSkinnable().profile, currentVersion);
}, listViewItemPopup)),
new MenuSeparator(),
new IconedMenuItem(FXUtils.limitingSize(SVG.folderOpen(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("folder.game"), FXUtils.withJFXPopupClosing(() -> {
Versions.openFolder(getSkinnable().profile, currentVersion);
}, listViewItemPopup))
);
control.listView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); control.listView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
control.listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
@Override
public ListCell<String> call(ListView<String> param) {
JFXListCell<String> cell = new JFXListCell<>();
cell.setOnMouseClicked(e -> {
if (cell.getItem() == null) return;
currentVersion = cell.getItem();
if (e.getButton() == MouseButton.SECONDARY) {
listViewItemPopup.show(cell, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.LEFT, e.getX(), e.getY());
}
});
return cell;
}
});
SpinnerPane spinnerPane = new SpinnerPane(); SpinnerPane spinnerPane = new SpinnerPane();
spinnerPane.getStyleClass().add("large-spinner-pane"); spinnerPane.getStyleClass().add("large-spinner-pane");
@@ -235,11 +309,28 @@ public class VersionPage extends Control implements DecoratorPage {
PopupMenu managementList = new PopupMenu(); PopupMenu managementList = new PopupMenu();
JFXPopup managementPopup = new JFXPopup(managementList); JFXPopup managementPopup = new JFXPopup(managementList);
managementList.getContent().setAll( managementList.getContent().setAll(
new IconedMenuItem(FXUtils.limitingSize(SVG.launch(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch.test"), FXUtils.withJFXPopupClosing(control::testGame, managementPopup)),
new IconedMenuItem(FXUtils.limitingSize(SVG.script(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.launch_script"), FXUtils.withJFXPopupClosing(control::generateLaunchScript, managementPopup)),
new MenuSeparator(),
new IconedMenuItem(FXUtils.limitingSize(SVG.pencil(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.manage.rename"), FXUtils.withJFXPopupClosing(control::rename, managementPopup)),
new IconedMenuItem(FXUtils.limitingSize(SVG.delete(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("version.manage.remove"), FXUtils.withJFXPopupClosing(control::remove, managementPopup)),
new IconedMenuItem(FXUtils.limitingSize(SVG.export(Theme.blackFillBinding(), 14, 14), 14, 14), i18n("modpack.export"), FXUtils.withJFXPopupClosing(control::export, managementPopup)),
new MenuSeparator(),
new IconedMenuItem(null, i18n("version.manage.redownload_assets_index"), FXUtils.withJFXPopupClosing(control::redownloadAssetIndex, managementPopup)), new IconedMenuItem(null, i18n("version.manage.redownload_assets_index"), FXUtils.withJFXPopupClosing(control::redownloadAssetIndex, managementPopup)),
new IconedMenuItem(null, i18n("version.manage.remove_libraries"), FXUtils.withJFXPopupClosing(control::clearLibraries, managementPopup)), new IconedMenuItem(null, i18n("version.manage.remove_libraries"), FXUtils.withJFXPopupClosing(control::clearLibraries, managementPopup)),
new IconedMenuItem(null, i18n("version.manage.clean"), FXUtils.withJFXPopupClosing(control::clearJunkFiles, managementPopup)).addTooltip(i18n("version.manage.clean.tooltip")) new IconedMenuItem(null, i18n("version.manage.clean"), FXUtils.withJFXPopupClosing(control::clearJunkFiles, managementPopup)).addTooltip(i18n("version.manage.clean.tooltip"))
); );
JFXButton upgradeButton = new JFXButton();
FXUtils.setLimitWidth(upgradeButton, 40);
FXUtils.setLimitHeight(upgradeButton, 40);
upgradeButton.setGraphic(SVG.update(Theme.whiteFillBinding(), 20, 20));
upgradeButton.getStyleClass().add("jfx-decorator-button");
upgradeButton.ripplerFillProperty().bind(Theme.whiteFillBinding());
upgradeButton.setOnAction(event -> control.updateGame());
upgradeButton.visibleProperty().bind(control.currentVersionUpgradable);
FXUtils.installFastTooltip(upgradeButton, i18n("version.update"));
JFXButton testGameButton = new JFXButton(); JFXButton testGameButton = new JFXButton();
FXUtils.setLimitWidth(testGameButton, 40); FXUtils.setLimitWidth(testGameButton, 40);
FXUtils.setLimitHeight(testGameButton, 40); FXUtils.setLimitHeight(testGameButton, 40);
@@ -267,7 +358,7 @@ public class VersionPage extends Control implements DecoratorPage {
managementMenuButton.setOnAction(event -> managementPopup.show(managementMenuButton, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.RIGHT, 0, managementMenuButton.getHeight())); managementMenuButton.setOnAction(event -> managementPopup.show(managementMenuButton, JFXPopup.PopupVPosition.TOP, JFXPopup.PopupHPosition.RIGHT, 0, managementMenuButton.getHeight()));
FXUtils.installFastTooltip(managementMenuButton, i18n("settings.game.management")); FXUtils.installFastTooltip(managementMenuButton, i18n("settings.game.management"));
toolBar.getChildren().setAll(testGameButton, browseMenuButton, managementMenuButton); toolBar.getChildren().setAll(upgradeButton, testGameButton, browseMenuButton, managementMenuButton);
} }
BorderPane titleBar = new BorderPane(); BorderPane titleBar = new BorderPane();

View File

@@ -35,6 +35,7 @@ import org.jackhuang.hmcl.util.platform.OperatingSystem;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level; import java.util.logging.Level;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
@@ -47,20 +48,20 @@ public class Versions {
String message = isIndependent ? i18n("version.manage.remove.confirm.independent", version) : String message = isIndependent ? i18n("version.manage.remove.confirm.independent", version) :
isMovingToTrashSupported ? i18n("version.manage.remove.confirm.trash", version, version + "_removed") : isMovingToTrashSupported ? i18n("version.manage.remove.confirm.trash", version, version + "_removed") :
i18n("version.manage.remove.confirm", version); i18n("version.manage.remove.confirm", version);
Controllers.confirmDialog(message, i18n("message.confirm"), () -> { Controllers.confirm(message, i18n("message.confirm"), () -> {
profile.getRepository().removeVersionFromDisk(version); profile.getRepository().removeVersionFromDisk(version);
}, null); }, null);
} }
public static void renameVersion(Profile profile, String version) { public static CompletableFuture<String> renameVersion(Profile profile, String version) {
Controllers.inputDialog(i18n("version.manage.rename.message"), (res, resolve, reject) -> { return Controllers.prompt(i18n("version.manage.rename.message"), (res, resolve, reject) -> {
if (profile.getRepository().renameVersion(version, res)) { if (profile.getRepository().renameVersion(version, res)) {
profile.getRepository().refreshVersionsAsync().start(); profile.getRepository().refreshVersionsAsync().start();
resolve.run(); resolve.run();
} else { } else {
reject.accept(i18n("version.manage.rename.fail")); reject.accept(i18n("version.manage.rename.fail"));
} }
}).setInitialText(version); }, version);
} }
public static void exportVersion(Profile profile, String version) { public static void exportVersion(Profile profile, String version) {

View File

@@ -113,7 +113,7 @@ public class WorldListPage extends ListPageBase<WorldListItem> {
// Or too many input dialogs are popped. // Or too many input dialogs are popped.
Task.supplyAsync(() -> new World(zipFile.toPath())) Task.supplyAsync(() -> new World(zipFile.toPath()))
.whenComplete(Schedulers.javafx(), world -> { .whenComplete(Schedulers.javafx(), world -> {
Controllers.inputDialog(i18n("world.name.enter"), (name, resolve, reject) -> { Controllers.prompt(i18n("world.name.enter"), (name, resolve, reject) -> {
Task.runAsync(() -> world.install(savesDir, name)) Task.runAsync(() -> world.install(savesDir, name))
.whenComplete(Schedulers.javafx(), () -> { .whenComplete(Schedulers.javafx(), () -> {
itemsProperty().add(new WorldListItem(new World(savesDir.resolve(name)))); itemsProperty().add(new WorldListItem(new World(savesDir.resolve(name))));
@@ -126,7 +126,7 @@ public class WorldListPage extends ListPageBase<WorldListItem> {
else else
reject.accept(i18n("world.import.failed", e.getClass().getName() + ": " + e.getLocalizedMessage())); reject.accept(i18n("world.import.failed", e.getClass().getName() + ": " + e.getLocalizedMessage()));
}).start(); }).start();
}).setInitialText(world.getWorldName()); }, world.getWorldName());
}, e -> { }, e -> {
Logging.LOG.log(Level.WARNING, "Unable to parse world file " + zipFile, e); Logging.LOG.log(Level.WARNING, "Unable to parse world file " + zipFile, e);
Controllers.dialog(i18n("world.import.invalid")); Controllers.dialog(i18n("world.import.invalid"));

View File

@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import org.jackhuang.hmcl.ui.versions.VersionSettingsPage?>
<?import org.jackhuang.hmcl.ui.versions.ModListPage?>
<?import org.jackhuang.hmcl.ui.versions.InstallerListPage?>
<?import org.jackhuang.hmcl.ui.versions.WorldListPage?>
<fx:root xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
type="StackPane">
<StackPane fx:id="contentPane">
<JFXTabPane fx:id="tabPane">
<Tab text="%settings">
<VersionSettingsPage fx:id="versionSettings" />
</Tab>
<Tab fx:id="modTab" text="%mods">
<ModListPage fx:id="mod" />
</Tab>
<Tab text="%settings.tabs.installers">
<InstallerListPage fx:id="installer" />
</Tab>
<Tab text="%world">
<WorldListPage fx:id="world" />
</Tab>
</JFXTabPane>
<HBox alignment="TOP_RIGHT" style="-fx-padding: 4;" spacing="3" pickOnBounds="false">
<JFXButton fx:id="btnTestGame" maxHeight="40.0" minHeight="40.0" onMouseClicked="#onTestGame"
styleClass="toggle-icon3" />
<JFXButton fx:id="btnBrowseMenu" maxHeight="40.0" minHeight="40.0" onMouseClicked="#onBrowseMenu"
styleClass="toggle-icon3">
<graphic>
<fx:include source="/assets/svg/folder-open.fxml"/>
</graphic>
</JFXButton>
<JFXButton fx:id="btnManagementMenu" maxHeight="40.0" minHeight="40.0" onMouseClicked="#onManagementMenu"
styleClass="toggle-icon3">
<graphic>
<fx:include source="/assets/svg/wrench-white.fxml"/>
</graphic>
</JFXButton>
</HBox>
</StackPane>
</fx:root>