diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java index 44f7a58ee..9e8892827 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java @@ -158,6 +158,9 @@ public final class Config implements Cloneable, Observable { @SerializedName("logLines") private IntegerProperty logLines = new SimpleIntegerProperty(100); + @SerializedName("titleTransparent") + private BooleanProperty titleTransparent = new SimpleBooleanProperty(false); + @SerializedName("authlibInjectorServers") private ObservableList authlibInjectorServers = FXCollections.observableArrayList(server -> new Observable[] { server }); @@ -581,4 +584,15 @@ public final class Config implements Cloneable, Observable { return preferredLoginType; } + public boolean isTitleTransparent() { + return titleTransparent.get(); + } + + public BooleanProperty titleTransparentProperty() { + return titleTransparent; + } + + public void setTitleTransparent(boolean titleTransparent) { + this.titleTransparent.set(titleTransparent); + } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/OptionToggleButton.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/OptionToggleButton.java index 741a72a12..a60d5c7d5 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/OptionToggleButton.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/OptionToggleButton.java @@ -45,14 +45,14 @@ public class OptionToggleButton extends StackPane { getChildren().setAll(container); VBox left = new VBox(); + left.setMouseTransparent(true); Label titleLabel = new Label(); - titleLabel.setMouseTransparent(true); titleLabel.textProperty().bind(title); Label subtitleLabel = new Label(); subtitleLabel.setMouseTransparent(true); subtitleLabel.textProperty().bind(subtitle); pane.setLeft(left); - BorderPane.setAlignment(left, Pos.CENTER_LEFT); + left.setAlignment(Pos.CENTER_LEFT); JFXToggleButton toggleButton = new JFXToggleButton(); pane.setRight(toggleButton); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java index 4c3c87641..8b90bbbb2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java @@ -52,6 +52,7 @@ public class Decorator extends Control { private final BooleanProperty canBack = new SimpleBooleanProperty(false); private final BooleanProperty canClose = new SimpleBooleanProperty(false); private final BooleanProperty showCloseAsHome = new SimpleBooleanProperty(false); + private final BooleanProperty titleTransparent = new SimpleBooleanProperty(false); private final Stage primaryStage; private Navigation.NavigationDirection navigationDirection = Navigation.NavigationDirection.START; private StackPane drawerWrapper; @@ -204,6 +205,18 @@ public class Decorator extends Control { this.dragging.set(dragging); } + public boolean isTitleTransparent() { + return titleTransparent.get(); + } + + public BooleanProperty titleTransparentProperty() { + return titleTransparent; + } + + public void setTitleTransparent(boolean titleTransparent) { + this.titleTransparent.set(titleTransparent); + } + public ObjectProperty> onBackNavButtonActionProperty() { return onBackNavButtonAction; } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java index 872a2e210..26109fa09 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java @@ -74,6 +74,7 @@ public class DecoratorController { public DecoratorController(Stage stage, Node mainPage) { decorator = new Decorator(stage); decorator.setOnCloseButtonAction(Launcher::stopApplication); + decorator.titleTransparentProperty().bind(config().titleTransparentProperty()); navigator = new Navigator(); navigator.setOnNavigated(this::onNavigated); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java index 649139ec2..fe4e83ed4 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java @@ -106,19 +106,17 @@ public class DecoratorSkin extends SkinBase { parent.getChildren().add(wrapper); - // center node with a animation layer at bottom, a container layer at middle and a "welcome" layer at top. + // center node with an animation layer at bottom, a container layer at middle and a "welcome" layer at top. StackPane container = new StackPane(); - container.backgroundProperty().bind(skinnable.contentBackgroundProperty()); FXUtils.setOverflowHidden(container); // animation layer at bottom + HBox drawerPane = new HBox(); { - HBox layer = new HBox(); leftPane = new StackPane(); leftPane.setPrefWidth(0); leftPane.getStyleClass().add("jfx-decorator-drawer"); - layer.getChildren().setAll(leftPane); - container.getChildren().add(layer); + drawerPane.getChildren().setAll(leftPane); } // content layer at middle @@ -153,7 +151,26 @@ public class DecoratorSkin extends SkinBase { titleContainer = new StackPane(); titleContainer.setPickOnBounds(false); - titleContainer.getStyleClass().addAll("jfx-tool-bar", "background"); + titleContainer.getStyleClass().addAll("jfx-tool-bar"); + + FXUtils.onChangeAndOperate(skinnable.titleTransparentProperty(), titleTransparent -> { + if (titleTransparent) { + wrapper.backgroundProperty().bind(skinnable.contentBackgroundProperty()); + container.backgroundProperty().unbind(); + container.setBackground(null); + titleContainer.getStyleClass().remove("background"); + container.getChildren().remove(drawerPane); + wrapper.getChildren().add(0, drawerPane); + } else { + container.backgroundProperty().bind(skinnable.contentBackgroundProperty()); + wrapper.backgroundProperty().unbind(); + wrapper.setBackground(null); + titleContainer.getStyleClass().add("background"); + wrapper.getChildren().remove(drawerPane); + container.getChildren().add(0, drawerPane); + } + }); + control.capableDraggingWindow(titleContainer); BorderPane titleBar = new BorderPane(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java index 1bc1b7cba..6bea6d78b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/DownloadPage.java @@ -99,7 +99,7 @@ public class DownloadPage extends BorderPane implements DecoratorPage { Profiles.registerVersionsListener(this::loadVersions); - tab.getSelectionModel().select(newGameTab); + tab.select(newGameTab); FXUtils.onChangeAndOperate(tab.getSelectionModel().selectedItemProperty(), newValue -> { if (newValue.initializeIfNeeded()) { if (newValue.getNode() instanceof VersionPage.VersionLoadable) { @@ -115,37 +115,37 @@ public class DownloadPage extends BorderPane implements DecoratorPage { item.setTitle(i18n("game")); item.setLeftGraphic(wrap(SVG::gamepad)); item.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(newGameTab)); - item.setOnAction(e -> tab.getSelectionModel().select(newGameTab)); + item.setOnAction(e -> tab.select(newGameTab)); }) .addNavigationDrawerItem(item -> { item.setTitle(i18n("mods")); item.setLeftGraphic(wrap(SVG::puzzle)); item.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(modTab)); - item.setOnAction(e -> tab.getSelectionModel().select(modTab)); + item.setOnAction(e -> tab.select(modTab)); }) .addNavigationDrawerItem(settingsItem -> { settingsItem.setTitle(i18n("modpack")); settingsItem.setLeftGraphic(wrap(SVG::pack)); settingsItem.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(modpackTab)); - settingsItem.setOnAction(e -> tab.getSelectionModel().select(modpackTab)); + settingsItem.setOnAction(e -> tab.select(modpackTab)); }) .addNavigationDrawerItem(item -> { item.setTitle(i18n("resourcepack")); item.setLeftGraphic(wrap(SVG::textureBox)); item.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(resourcePackTab)); - item.setOnAction(e -> tab.getSelectionModel().select(resourcePackTab)); + item.setOnAction(e -> tab.select(resourcePackTab)); }) // .addNavigationDrawerItem(item -> { // item.setTitle(i18n("download.curseforge.customization")); // item.setLeftGraphic(wrap(SVG::script)); // item.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(customizationTab)); -// item.setOnAction(e -> tab.getSelectionModel().select(customizationTab)); +// item.setOnAction(e -> tab.select(customizationTab)); // }) .addNavigationDrawerItem(item -> { item.setTitle(i18n("world")); item.setLeftGraphic(wrap(SVG::earth)); item.activeProperty().bind(tab.getSelectionModel().selectedItemProperty().isEqualTo(worldTab)); - item.setOnAction(e -> tab.getSelectionModel().select(worldTab)); + item.setOnAction(e -> tab.select(worldTab)); }); FXUtils.setLimitWidth(sideBar, 200); setLeft(sideBar); @@ -212,6 +212,10 @@ public class DownloadPage extends BorderPane implements DecoratorPage { return state.getReadOnlyProperty(); } + public void showGameDownloads() { + tab.select(newGameTab); + } + private class DownloadNavigator implements Navigation { private final Map settings = new HashMap<>(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/FeedbackPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/FeedbackPage.java index 46e0c688c..26f45a3ba 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/FeedbackPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/FeedbackPage.java @@ -147,9 +147,10 @@ public class FeedbackPage extends VBox implements PageAware { if (empty) return; content.setTitle(feedback.getTitle()); content.setSubtitle(feedback.getAuthor()); - content.getTags().add("#" + feedback.getId()); - content.getTags().add(i18n("feedback.state." + feedback.getState().name().toLowerCase(Locale.US))); - content.getTags().add(i18n("feedback.type." + feedback.getType().name().toLowerCase(Locale.US))); + content.getTags().setAll( + "#" + feedback.getId(), + i18n("feedback.state." + feedback.getState().name().toLowerCase(Locale.US)), + i18n("feedback.type." + feedback.getType().name().toLowerCase(Locale.US))); } }); listView.setOnMouseClicked(e -> { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/PersonalizationPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/PersonalizationPage.java index da03742e5..6a0b18569 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/PersonalizationPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/PersonalizationPage.java @@ -59,10 +59,10 @@ public class PersonalizationPage extends StackPane { scrollPane.setFitToWidth(true); getChildren().setAll(scrollPane); + ComponentList themeList = new ComponentList(); { - ComponentList themeList = new ComponentList(); BorderPane themePane = new BorderPane(); - themeList.getContent().setAll(themePane); + themeList.getContent().add(themePane); Label left = new Label(i18n("settings.launcher.theme")); BorderPane.setAlignment(left, Pos.CENTER_LEFT); @@ -81,9 +81,14 @@ public class PersonalizationPage extends StackPane { }); themeColorPickerContainer.getChildren().setAll(picker); Platform.runLater(() -> JFXDepthManager.setDepth(picker, 0)); - - content.getChildren().addAll(ComponentList.createComponentListTitle(i18n("settings.launcher.appearance")), themeList); } + { + OptionToggleButton titleTransparentButton = new OptionToggleButton(); + themeList.getContent().add(titleTransparentButton); + titleTransparentButton.selectedProperty().bindBidirectional(config().titleTransparentProperty()); + titleTransparentButton.setTitle(i18n("settings.launcher.title_transparent")); + } + content.getChildren().addAll(ComponentList.createComponentListTitle(i18n("settings.launcher.appearance")), themeList); { ComponentList componentList = new ComponentList(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java index 7c5625a16..6f94fa660 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java @@ -149,9 +149,6 @@ public class MultiplayerPageSkin extends SkinBase { scrollPane.setFitToHeight(true); root.setCenter(scrollPane); - HintPane hint = new HintPane(MessageDialogPane.MessageType.INFO); - hint.setText(i18n("multiplayer.hint")); - ComponentList roomPane = new ComponentList(); { TransitionPane transitionPane = new TransitionPane(); @@ -290,7 +287,6 @@ public class MultiplayerPageSkin extends SkinBase { } content.getChildren().setAll( - hint, ComponentList.createComponentListTitle(i18n("multiplayer.session")), roomPane, ComponentList.createComponentListTitle(i18n("multiplayer.nat")), diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java index 6ede8c77e..1a85461af 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/GameListPage.java @@ -168,7 +168,7 @@ public class GameListPage extends ListPageBase implements Decorato .add(installModpackItem) .add(refreshItem) .add(globalManageItem); - FXUtils.setLimitHeight(bottomLeftCornerList, 40 * 3 + 12 * 2); + FXUtils.setLimitHeight(bottomLeftCornerList, 40 * 4 + 12 * 2); left.setBottom(bottomLeftCornerList); } } 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 673f531b8..a1a7d9c4a 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 @@ -41,7 +41,6 @@ import org.jackhuang.hmcl.ui.construct.MessageDialogPane; import org.jackhuang.hmcl.ui.construct.PromptDialogPane; import org.jackhuang.hmcl.ui.construct.Validator; import org.jackhuang.hmcl.ui.download.ModpackInstallWizardProvider; -import org.jackhuang.hmcl.ui.download.VanillaInstallWizardProvider; import org.jackhuang.hmcl.ui.export.ExportWizardProvider; import org.jackhuang.hmcl.util.Logging; import org.jackhuang.hmcl.util.StringUtils; @@ -64,10 +63,8 @@ public final class Versions { } public static void addNewGame() { - Profile profile = Profiles.getSelectedProfile(); - if (profile.getRepository().isLoaded()) { - Controllers.getDecorator().startWizard(new VanillaInstallWizardProvider(profile), i18n("install.new_game")); - } + Controllers.getDownloadPage().showGameDownloads(); + Controllers.navigate(Controllers.getDownloadPage()); } public static void importModpack() { @@ -255,9 +252,6 @@ public final class Versions { public static void modifyGlobalSettings(Profile profile) { Controllers.getSettingsPage().showGameSettings(profile); Controllers.navigate(Controllers.getSettingsPage()); -// VersionSettingsPage page = new VersionSettingsPage(); -// page.loadVersion(profile, null); -// Controllers.navigate(page); } public static void modifyGameSettings(Profile profile, String version) { diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index 66f6f85a6..02268310c 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -636,7 +636,7 @@ multiplayer.powered_by=Multiplayer service is provided by