From 40aa3c14394bba17599d516b2fdccf2121f642dd Mon Sep 17 00:00:00 2001 From: KSSJW <165921128+KSSJW@users.noreply.github.com> Date: Sat, 11 Jul 2026 23:47:25 +0800 Subject: [PATCH 1/2] Refactor: ModDownloadListPageSkin --- .../hmcl/ui/versions/DownloadListPage.java | 88 +++++++++++-------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java index fa1075c3f6..43928f1508 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java @@ -48,6 +48,7 @@ import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.FXUtils; +import org.jackhuang.hmcl.ui.SVG; import org.jackhuang.hmcl.ui.WeakListenerHolder; import org.jackhuang.hmcl.ui.construct.*; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; @@ -254,46 +255,24 @@ protected ModDownloadListPageSkin(DownloadListPage control) { BorderPane pane = new BorderPane(); - GridPane searchPane = new GridPane(); + VBox searchPane = new VBox(8); pane.setTop(searchPane); searchPane.getStyleClass().addAll("card"); BorderPane.setMargin(searchPane, new Insets(10, 10, 0, 10)); - ColumnConstraints nameColumn = new ColumnConstraints(); - nameColumn.setMinWidth(USE_PREF_SIZE); - ColumnConstraints column1 = new ColumnConstraints(); - column1.setHgrow(Priority.ALWAYS); - ColumnConstraints column2 = new ColumnConstraints(); - column2.setHgrow(Priority.ALWAYS); - searchPane.getColumnConstraints().setAll(nameColumn, column1, nameColumn, column2); - - searchPane.setHgap(16); - searchPane.setVgap(10); + searchPane.setMaxWidth(Double.MAX_VALUE); { - int rowIndex = 0; - - if (control.versionSelection) { - searchPane.addRow(rowIndex); - int columns = 0; - Node lastNode = null; - - JFXComboBox versionsComboBox = new JFXComboBox<>(); - versionsComboBox.setMaxWidth(Double.MAX_VALUE); - Bindings.bindContent(versionsComboBox.getItems(), control.versions); - selectedItemPropertyFor(versionsComboBox).bindBidirectional(control.selectedVersion); + BooleanProperty isExpanded = new SimpleBooleanProperty(false); - searchPane.add(new Label(i18n("version")), columns++, rowIndex); - searchPane.add(lastNode = versionsComboBox, columns++, rowIndex); - - if (columns == 2) { - GridPane.setColumnSpan(lastNode, 3); - } - - rowIndex++; - } + HBox rowBox1 = new HBox(16); + rowBox1.setAlignment(Pos.CENTER_LEFT); + rowBox1.setMaxWidth(Double.MAX_VALUE); + GridPane.setHgrow(rowBox1, Priority.ALWAYS); JFXTextField nameField = new JFXTextField(); + HBox.setHgrow(nameField, Priority.ALWAYS); + nameField.setMaxWidth(Double.MAX_VALUE); nameField.setPromptText(getSkinnable().supportChinese.get() ? i18n("search.hint.chinese") : i18n("search.hint.english")); if (getSkinnable().supportChinese.get()) { FXUtils.installFastTooltip(nameField, i18n("search.hint.chinese")); @@ -301,15 +280,41 @@ protected ModDownloadListPageSkin(DownloadListPage control) { FXUtils.installFastTooltip(nameField, i18n("search.hint.english")); } + JFXButton btnExpend = FXUtils.newToggleButton4(SVG.ARROW_DROP_DOWN); + btnExpend.setOnAction(e -> { + isExpanded.set(!isExpanded.get()); + btnExpend.setGraphic(isExpanded.get() ? FXUtils.newToggleButton4(SVG.ARROW_DROP_UP) : FXUtils.newToggleButton4(SVG.ARROW_DROP_DOWN)); + }); + + if (control.versionSelection) { + JFXComboBox versionsComboBox = new JFXComboBox<>(); + versionsComboBox.setPrefWidth(200); + Bindings.bindContent(versionsComboBox.getItems(), control.versions); + selectedItemPropertyFor(versionsComboBox).bindBidirectional(control.selectedVersion); + + rowBox1.getChildren().addAll(new Label(i18n("version")), versionsComboBox, new Label(i18n("mods.name")), nameField, btnExpend); + } else { + rowBox1.getChildren().addAll(new Label(i18n("mods.name")), nameField, btnExpend); + } + + searchPane.getChildren().add(rowBox1); + + HBox rowBox2 = new HBox(16); + rowBox2.setAlignment(Pos.CENTER_LEFT); + GridPane.setHgrow(rowBox2, Priority.ALWAYS); + + rowBox2.visibleProperty().bind(isExpanded); + rowBox2.managedProperty().bind(isExpanded); + JFXComboBox gameVersionField = new JFXComboBox<>(); - gameVersionField.setMaxWidth(Double.MAX_VALUE); + gameVersionField.setPrefWidth(100); gameVersionField.setEditable(true); gameVersionField.getItems().setAll(GameVersionNumber.getDefaultGameVersions()); Label lblGameVersion = new Label(i18n("world.game_version")); - searchPane.addRow(rowIndex++, new Label(i18n("mods.name")), nameField, lblGameVersion, gameVersionField); + lblGameVersion.setMinWidth(USE_PREF_SIZE); ObjectBinding hasVersion = BindingMapping.of(getSkinnable().instanceReference) - .map(instanceReference -> instanceReference.instanceId() == null); + .map(instanceReference -> instanceReference.instanceId() == null); lblGameVersion.managedProperty().bind(hasVersion); lblGameVersion.visibleProperty().bind(hasVersion); gameVersionField.managedProperty().bind(hasVersion); @@ -325,6 +330,7 @@ protected ModDownloadListPageSkin(DownloadListPage control) { }); StackPane categoryStackPane = new StackPane(); + categoryStackPane.setPrefWidth(100); JFXComboBox categoryComboBox = new JFXComboBox<>(); categoryComboBox.getItems().setAll(CategoryIndented.ALL); categoryStackPane.getChildren().setAll(categoryComboBox); @@ -354,6 +360,7 @@ protected ModDownloadListPageSkin(DownloadListPage control) { }); StackPane sortStackPane = new StackPane(); + sortStackPane.setPrefWidth(100); JFXComboBox sortComboBox = new JFXComboBox<>(); sortStackPane.getChildren().setAll(sortComboBox); sortComboBox.prefWidthProperty().bind(sortStackPane.widthProperty()); @@ -361,7 +368,15 @@ protected ModDownloadListPageSkin(DownloadListPage control) { sortComboBox.setConverter(stringConverter(sortType -> i18n("curse.sort." + sortType.name().toLowerCase(Locale.ROOT)))); sortComboBox.getItems().setAll(RemoteAddonRepository.SortType.values()); sortComboBox.getSelectionModel().select(0); - searchPane.addRow(rowIndex++, new Label(i18n("addon.category")), categoryStackPane, new Label(i18n("search.sort")), sortStackPane); + + Label categoryLabel = new Label(i18n("addon.category")); + categoryLabel.setMinWidth(Region.USE_PREF_SIZE); + Label sortLabel = new Label(i18n("search.sort")); + sortLabel.setMinWidth(Region.USE_PREF_SIZE); + + rowBox2.getChildren().addAll(lblGameVersion, gameVersionField, categoryLabel, categoryStackPane, sortLabel, sortStackPane); + + searchPane.getChildren().add(rowBox2); IntegerProperty filterID = new SimpleIntegerProperty(this, "Filter ID", 0); IntegerProperty currentFilterID = new SimpleIntegerProperty(this, "Current Filter ID", -1); @@ -393,7 +408,6 @@ protected ModDownloadListPageSkin(DownloadListPage control) { )); HBox actionsBox = new HBox(8); - GridPane.setColumnSpan(actionsBox, 4); actionsBox.setAlignment(Pos.CENTER); { AggregatedObservableList actions = new AggregatedObservableList<>(); @@ -489,7 +503,7 @@ protected ModDownloadListPageSkin(DownloadListPage control) { Bindings.bindContent(actionsBox.getChildren(), actions.getAggregatedList()); } - searchPane.addRow(rowIndex++, actionsBox); + searchPane.getChildren().add(actionsBox); FXUtils.onChange(control.downloadSource, v -> searchAction.handle(null)); nameField.setOnAction(searchAction); From 7e6caf77f79f7a52b1503bfe34da77cc2c9f30be Mon Sep 17 00:00:00 2001 From: KSSJW <165921128+KSSJW@users.noreply.github.com> Date: Sat, 11 Jul 2026 23:55:08 +0800 Subject: [PATCH 2/2] Refactor: Button name and icon, remove GridPane, rowBox2 setMaxWidth --- .../hmcl/ui/versions/DownloadListPage.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java index 43928f1508..90f102f414 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DownloadListPage.java @@ -268,7 +268,6 @@ protected ModDownloadListPageSkin(DownloadListPage control) { HBox rowBox1 = new HBox(16); rowBox1.setAlignment(Pos.CENTER_LEFT); rowBox1.setMaxWidth(Double.MAX_VALUE); - GridPane.setHgrow(rowBox1, Priority.ALWAYS); JFXTextField nameField = new JFXTextField(); HBox.setHgrow(nameField, Priority.ALWAYS); @@ -280,10 +279,10 @@ protected ModDownloadListPageSkin(DownloadListPage control) { FXUtils.installFastTooltip(nameField, i18n("search.hint.english")); } - JFXButton btnExpend = FXUtils.newToggleButton4(SVG.ARROW_DROP_DOWN); - btnExpend.setOnAction(e -> { + JFXButton btnExpand = FXUtils.newToggleButton4(SVG.ARROW_DROP_DOWN); + btnExpand.setOnAction(e -> { isExpanded.set(!isExpanded.get()); - btnExpend.setGraphic(isExpanded.get() ? FXUtils.newToggleButton4(SVG.ARROW_DROP_UP) : FXUtils.newToggleButton4(SVG.ARROW_DROP_DOWN)); + btnExpand.setGraphic(isExpanded.get() ? SVG.ARROW_DROP_UP.createIcon() : SVG.ARROW_DROP_DOWN.createIcon()); }); if (control.versionSelection) { @@ -291,17 +290,16 @@ protected ModDownloadListPageSkin(DownloadListPage control) { versionsComboBox.setPrefWidth(200); Bindings.bindContent(versionsComboBox.getItems(), control.versions); selectedItemPropertyFor(versionsComboBox).bindBidirectional(control.selectedVersion); - - rowBox1.getChildren().addAll(new Label(i18n("version")), versionsComboBox, new Label(i18n("mods.name")), nameField, btnExpend); + rowBox1.getChildren().addAll(new Label(i18n("version")), versionsComboBox, new Label(i18n("mods.name")), nameField, btnExpand); } else { - rowBox1.getChildren().addAll(new Label(i18n("mods.name")), nameField, btnExpend); + rowBox1.getChildren().addAll(new Label(i18n("mods.name")), nameField, btnExpand); } searchPane.getChildren().add(rowBox1); HBox rowBox2 = new HBox(16); rowBox2.setAlignment(Pos.CENTER_LEFT); - GridPane.setHgrow(rowBox2, Priority.ALWAYS); + rowBox2.setMaxWidth(Double.MAX_VALUE); rowBox2.visibleProperty().bind(isExpanded); rowBox2.managedProperty().bind(isExpanded);