From 98b43945ed900b4d727549afa9813d0cb2ce7922 Mon Sep 17 00:00:00 2001 From: huangyuhui Date: Wed, 7 Feb 2018 22:33:52 +0800 Subject: [PATCH] Global and special version settings. Fixed property bindings --- .../java/org/jackhuang/hmcl/ui/FXUtils.java | 24 +++++-- .../hmcl/ui/SafeIntStringConverter.java | 6 +- .../org/jackhuang/hmcl/ui/VersionPage.java | 2 +- .../hmcl/ui/VersionSettingsController.java | 69 ++++++++++++++----- .../hmcl/ui/construct/MultiFileItem.java | 14 +++- .../assets/fxml/version/version-settings.fxml | 2 + .../resources/assets/lang/I18N.properties | 6 +- .../assets/lang/I18N_zh_CN.properties | 6 +- .../hmcl/game/DefaultGameRepository.java | 2 +- 9 files changed, 95 insertions(+), 36 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java index 88835e084..9b7049ee8 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java @@ -234,26 +234,38 @@ public final class FXUtils { } } - public static void bindInt(JFXTextField textField, Property property) { - textField.textProperty().unbind(); - textField.textProperty().bindBidirectional((Property) property, SafeIntStringConverter.INSTANCE); + public static void bindInt(JFXTextField textField, Property property) { + textField.textProperty().bindBidirectional(property, SafeIntStringConverter.INSTANCE); + } + + public static void unbindInt(JFXTextField textField, Property property) { + textField.textProperty().unbindBidirectional(property); } public static void bindString(JFXTextField textField, Property property) { - textField.textProperty().unbind(); textField.textProperty().bindBidirectional(property); } + public static void unbindString(JFXTextField textField, Property property) { + textField.textProperty().unbindBidirectional(property); + } + public static void bindBoolean(JFXToggleButton toggleButton, Property property) { - toggleButton.selectedProperty().unbind(); toggleButton.selectedProperty().bindBidirectional(property); } + public static void unbindBoolean(JFXToggleButton toggleButton, Property property) { + toggleButton.selectedProperty().unbindBidirectional(property); + } + public static void bindBoolean(JFXCheckBox checkBox, Property property) { - checkBox.selectedProperty().unbind(); checkBox.selectedProperty().bindBidirectional(property); } + public static void unbindBoolean(JFXCheckBox checkBox, Property property) { + checkBox.selectedProperty().unbindBidirectional(property); + } + public static void bindEnum(JFXComboBox comboBox, Property property) { unbindEnum(comboBox); ChangeListener listener = (a, b, newValue) -> { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SafeIntStringConverter.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SafeIntStringConverter.java index c1c30fe7f..a2ef2039f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/SafeIntStringConverter.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/SafeIntStringConverter.java @@ -25,19 +25,19 @@ import java.util.Optional; /** * @author huangyuhui */ -public final class SafeIntStringConverter extends StringConverter { +public final class SafeIntStringConverter extends StringConverter { public static final SafeIntStringConverter INSTANCE = new SafeIntStringConverter(); private SafeIntStringConverter() { } @Override - public Integer fromString(String string) { + public Number fromString(String string) { return Optional.ofNullable(string).map(Lang::toIntOrNull).orElse(null); } @Override - public String toString(Integer object) { + public String toString(Number object) { return Optional.ofNullable(object).map(Object::toString).orElse(""); } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionPage.java index e0661a183..222bc6719 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionPage.java @@ -92,7 +92,7 @@ public final class VersionPage extends StackPane implements DecoratorPage { title.set(Main.i18n("settings.game") + " - " + id); - versionSettingsController.loadVersionSetting(profile, id, profile.getVersionSetting(id)); + versionSettingsController.loadVersionSetting(profile, id); modController.setParentTab(tabPane); modTab.setUserData(modController); modController.loadMods(profile.getModManager(), id); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionSettingsController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionSettingsController.java index 68ce718a4..8a14d4e87 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionSettingsController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/VersionSettingsController.java @@ -18,6 +18,7 @@ package org.jackhuang.hmcl.ui; import com.jfoenix.controls.*; +import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.fxml.FXML; import javafx.scene.Node; @@ -71,6 +72,7 @@ public final class VersionSettingsController { @FXML private JFXToggleButton chkNoJVMArgs; @FXML private JFXToggleButton chkNoCommon; @FXML private JFXToggleButton chkNoGameCheck; + @FXML private MultiFileItem globalItem; @FXML private MultiFileItem javaItem; @FXML private MultiFileItem gameDirItem; @FXML private JFXToggleButton chkShowLogs; @@ -121,32 +123,41 @@ public final class VersionSettingsController { gameDirItem.createChildren(Main.i18n("settings.advanced.game_dir.independent"), EnumGameDirectory.VERSION_FOLDER) )); + globalItem.loadChildren(Arrays.asList( + globalItem.createChildren(Main.i18n("settings.type.global"), true), + globalItem.createChildren(Main.i18n("settings.type.special"), false) + )); + FXUtils.installTooltip(btnIconSelection, 0, 5000, 0, new Tooltip(Main.i18n("button.edit"))); } - public void loadVersionSetting(Profile profile, String versionId, VersionSetting versionSetting) { + public void loadVersionSetting(Profile profile, String versionId) { rootPane.getChildren().remove(advancedSettingsPane); this.profile = profile; this.versionId = versionId; + VersionSetting versionSetting = profile.getVersionSetting(versionId); + gameDirItem.setDisable(profile.getRepository().isModpack(versionId)); + globalItem.setDisable(profile.getRepository().isModpack(versionId)); if (lastVersionSetting != null) { - lastVersionSetting.widthProperty().unbind(); - lastVersionSetting.heightProperty().unbind(); - lastVersionSetting.maxMemoryProperty().unbind(); - lastVersionSetting.javaArgsProperty().unbind(); - lastVersionSetting.minecraftArgsProperty().unbind(); - lastVersionSetting.permSizeProperty().unbind(); - lastVersionSetting.wrapperProperty().unbind(); - lastVersionSetting.preLaunchCommandProperty().unbind(); - lastVersionSetting.serverIpProperty().unbind(); - lastVersionSetting.fullscreenProperty().unbind(); - lastVersionSetting.notCheckGameProperty().unbind(); - lastVersionSetting.noCommonProperty().unbind(); - lastVersionSetting.javaDirProperty().unbind(); - lastVersionSetting.showLogsProperty().unbind(); + FXUtils.unbindInt(txtWidth, lastVersionSetting.widthProperty()); + FXUtils.unbindInt(txtHeight, lastVersionSetting.heightProperty()); + FXUtils.unbindInt(txtMaxMemory, lastVersionSetting.maxMemoryProperty()); + FXUtils.unbindString(javaItem.getTxtCustom(), lastVersionSetting.javaDirProperty()); + FXUtils.unbindString(gameDirItem.getTxtCustom(), lastVersionSetting.gameDirProperty()); + FXUtils.unbindString(txtJVMArgs, lastVersionSetting.javaArgsProperty()); + FXUtils.unbindString(txtGameArgs, lastVersionSetting.minecraftArgsProperty()); + FXUtils.unbindString(txtMetaspace, lastVersionSetting.permSizeProperty()); + FXUtils.unbindString(txtWrapper, lastVersionSetting.wrapperProperty()); + FXUtils.unbindString(txtPrecallingCommand, lastVersionSetting.preLaunchCommandProperty()); + FXUtils.unbindString(txtServerIP, lastVersionSetting.serverIpProperty()); + FXUtils.unbindBoolean(chkFullscreen, lastVersionSetting.fullscreenProperty()); + FXUtils.unbindBoolean(chkNoGameCheck, lastVersionSetting.notCheckGameProperty()); + FXUtils.unbindBoolean(chkNoCommon, lastVersionSetting.noCommonProperty()); + FXUtils.unbindBoolean(chkShowLogs, lastVersionSetting.showLogsProperty()); FXUtils.unbindEnum(cboLauncherVisibility); } @@ -161,11 +172,11 @@ public final class VersionSettingsController { FXUtils.bindString(txtWrapper, versionSetting.wrapperProperty()); FXUtils.bindString(txtPrecallingCommand, versionSetting.preLaunchCommandProperty()); FXUtils.bindString(txtServerIP, versionSetting.serverIpProperty()); - FXUtils.bindEnum(cboLauncherVisibility, versionSetting.launcherVisibilityProperty()); FXUtils.bindBoolean(chkFullscreen, versionSetting.fullscreenProperty()); FXUtils.bindBoolean(chkNoGameCheck, versionSetting.notCheckGameProperty()); FXUtils.bindBoolean(chkNoCommon, versionSetting.noCommonProperty()); FXUtils.bindBoolean(chkShowLogs, versionSetting.showLogsProperty()); + FXUtils.bindEnum(cboLauncherVisibility, versionSetting.launcherVisibilityProperty()); String javaGroupKey = "java_group.listener"; @@ -204,6 +215,28 @@ public final class VersionSettingsController { versionSetting.javaProperty().setChangedListener(it -> initJavaSubtitle(versionSetting)); initJavaSubtitle(versionSetting); + + String globalGroupKey = "global_group.listener"; + + Lang.get(globalItem.getGroup().getProperties(), globalGroupKey, ChangeListener.class) + .ifPresent(globalItem.getGroup().selectedToggleProperty()::removeListener); + ChangeListener globalListener = (a, b, newValue) -> { + if ((Boolean) newValue.getUserData()) + profile.globalizeVersionSetting(versionId); + else + profile.specializeVersionSetting(versionId); + + Platform.runLater(() -> loadVersionSetting(profile, versionId)); + }; + if (versionSetting.isUsesGlobal()) + globalItem.getGroup().getToggles().stream().filter(it -> it.getUserData() == Boolean.TRUE).findFirst().ifPresent(it -> it.setSelected(true)); + else + globalItem.getGroup().getToggles().stream().filter(it -> it.getUserData() == Boolean.FALSE).findFirst().ifPresent(it -> it.setSelected(true)); + globalItem.getGroup().getProperties().put(globalGroupKey, globalListener); + globalItem.getGroup().selectedToggleProperty().addListener(globalListener); + versionSetting.usesGlobalProperty().setChangedListener(it -> initUsesGlobalSubtitle(versionSetting)); + initUsesGlobalSubtitle(versionSetting); + String gameDirKey = "game_dir.listener"; Lang.get(gameDirItem.getGroup().getProperties(), gameDirKey, ChangeListener.class) .ifPresent(gameDirItem.getGroup().selectedToggleProperty()::removeListener); @@ -246,6 +279,10 @@ public final class VersionSettingsController { gameDirItem.setSubtitle(profile.getRepository().getRunDirectory(versionId).getAbsolutePath()); } + private void initUsesGlobalSubtitle(VersionSetting versionSetting) { + globalItem.setSubtitle(Main.i18n(versionSetting.isUsesGlobal() ? "settings.type.global" : "settings.type.special")); + } + @FXML private void onShowAdvanced() { if (!rootPane.getChildren().contains(advancedSettingsPane)) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MultiFileItem.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MultiFileItem.java index cf3530776..c68166351 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MultiFileItem.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MultiFileItem.java @@ -20,6 +20,7 @@ package org.jackhuang.hmcl.ui.construct; import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXRadioButton; import com.jfoenix.controls.JFXTextField; +import javafx.beans.NamedArg; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleStringProperty; @@ -55,8 +56,11 @@ public class MultiFileItem extends ComponentList { private final JFXRadioButton radioCustom = new JFXRadioButton(); private final BorderPane custom = new BorderPane(); private final VBox pane = new VBox(); + private final boolean hasCustom; + + public MultiFileItem(@NamedArg(value = "hasCustom", defaultValue = "true") boolean hasCustom) { + this.hasCustom = hasCustom; - { BorderPane.setAlignment(txtCustom, Pos.CENTER_RIGHT); btnSelect.setGraphic(SVG.folderOpen("black", 15, 15)); @@ -92,7 +96,9 @@ public class MultiFileItem extends ComponentList { pane.setStyle("-fx-padding: 0 0 10 0;"); pane.setSpacing(8); - pane.getChildren().add(custom); + + if (hasCustom) + pane.getChildren().add(custom); addChildren(pane); } @@ -124,7 +130,9 @@ public class MultiFileItem extends ComponentList { public void loadChildren(Collection list) { pane.getChildren().setAll(list); - pane.getChildren().add(custom); + + if (hasCustom) + pane.getChildren().add(custom); } public void onExploreJavaDir() { diff --git a/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml b/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml index fe81a4696..fa394f70e 100644 --- a/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml +++ b/HMCL/src/main/resources/assets/fxml/version/version-settings.fxml @@ -17,6 +17,8 @@ + + diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index ff35104ec..4e2b093f8 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -348,9 +348,9 @@ settings.tabs.assets_downloads=Assets settings.tabs.game_download=Games settings.tabs.installers=Installers settings.test_game=Test game -settings.type.global=Click here to switch to version specialized setting. Now it is global setting. -settings.type.none=No version here, please turn to game download tab. -settings.type.special=Click here to switch to global setting. Not it is version specialized setting. +settings.type.global=Global version settings(all shared) +settings.type=Version setting type +settings.type.special=Specialized version settings(will not affect other versions) settings.update_version=Update version json. update.failed=Failed to check for updates. 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 a4a623ff5..35b9f1677 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -348,9 +348,9 @@ settings.tabs.assets_downloads=资源下载 settings.tabs.game_download=游戏下载 settings.tabs.installers=自动安装 settings.test_game=测试游戏 -settings.type.global=点击此处切换为版本特定设置。该版本正在使用全局设置,修改以下设置会影响到其他使用全局设置的版本 -settings.type.none=缺少游戏版本,请切换到游戏下载页下载游戏 -settings.type.special=点击此处切换为全局设置。该版本正在使用版本特定设置,修改以下设置不会影响到其他版本设置 +settings.type.global=全局版本设置(使用该设置的版本共用一套设定) +settings.type=版本设置类型 +settings.type.special=单独版本设置(不会影响到其他版本的设定) settings.update_version=更新版本文件 update.failed=检查更新失败 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java index 0689f5fda..e82aece0a 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/DefaultGameRepository.java @@ -211,7 +211,7 @@ public class DefaultGameRepository implements GameRepository { if (EventBus.EVENT_BUS.fireEvent(new LoadedOneVersionEvent(this, resolved)) != Event.Result.DENY) versions.put(version.getId(), version); } catch (VersionNotFoundException e) { - Logging.LOG.log(Level.WARNING, "Ignoring version {0} because it inherits from a nonexistent version."); + Logging.LOG.log(Level.WARNING, "Ignoring version {0} because it inherits from a nonexistent version.", version.getId()); } }