From 5a34ac0d2bedc8ad63e1b54bf36893909e6e2dc7 Mon Sep 17 00:00:00 2001 From: Glavo Date: Fri, 23 Jan 2026 21:04:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=B8=8B=E8=BD=BD=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E6=9D=A1=E7=9B=AE=E6=A0=B7=E5=BC=8F=20(#5279)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmcl/ui/construct/FloatListCell.java | 69 ----------------- .../hmcl/ui/versions/DownloadListPage.java | 76 ++++++++++++------- HMCL/src/main/resources/assets/css/root.css | 4 - 3 files changed, 47 insertions(+), 102 deletions(-) delete mode 100644 HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FloatListCell.java diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FloatListCell.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FloatListCell.java deleted file mode 100644 index dc4faf062..000000000 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FloatListCell.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Hello Minecraft! Launcher - * Copyright (C) 2020 huangyuhui and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.jackhuang.hmcl.ui.construct; - -import com.jfoenix.controls.JFXListView; -import com.jfoenix.effects.JFXDepthManager; -import javafx.css.PseudoClass; -import javafx.geometry.Insets; -import javafx.scene.Cursor; -import javafx.scene.control.ListCell; -import javafx.scene.layout.Region; -import javafx.scene.layout.StackPane; -import org.jackhuang.hmcl.ui.FXUtils; - -public abstract class FloatListCell extends ListCell { - private final PseudoClass SELECTED = PseudoClass.getPseudoClass("selected"); - - protected final StackPane pane = new StackPane(); - - public FloatListCell(JFXListView listView) { - setText(null); - setGraphic(null); - - pane.getStyleClass().add("card"); - pane.setCursor(Cursor.HAND); - setPadding(new Insets(9, 9, 0, 9)); - JFXDepthManager.setDepth(pane, 1); - - FXUtils.onChangeAndOperate(selectedProperty(), selected -> { - pane.pseudoClassStateChanged(SELECTED, selected); - }); - - Region clippedContainer = (Region) listView.lookup(".clipped-container"); - setPrefWidth(0); - if (clippedContainer != null) { - maxWidthProperty().bind(clippedContainer.widthProperty()); - prefWidthProperty().bind(clippedContainer.widthProperty()); - minWidthProperty().bind(clippedContainer.widthProperty()); - } - } - - @Override - protected void updateItem(T item, boolean empty) { - super.updateItem(item, empty); - updateControl(item, empty); - if (empty) { - setGraphic(null); - } else { - setGraphic(pane); - } - } - - protected abstract void updateControl(T dataItem, boolean empty); -} 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 858f3df22..171fac320 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 @@ -17,10 +17,8 @@ */ package org.jackhuang.hmcl.ui.versions; -import com.jfoenix.controls.JFXButton; -import com.jfoenix.controls.JFXComboBox; -import com.jfoenix.controls.JFXListView; -import com.jfoenix.controls.JFXTextField; +import com.jfoenix.controls.*; +import com.jfoenix.effects.JFXDepthManager; import javafx.beans.binding.Bindings; import javafx.beans.binding.ObjectBinding; import javafx.beans.property.*; @@ -30,11 +28,9 @@ import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.geometry.Pos; +import javafx.scene.Cursor; import javafx.scene.Node; -import javafx.scene.control.Control; -import javafx.scene.control.Label; -import javafx.scene.control.Skin; -import javafx.scene.control.SkinBase; +import javafx.scene.control.*; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.KeyCode; @@ -52,7 +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.WeakListenerHolder; -import org.jackhuang.hmcl.ui.construct.FloatListCell; +import org.jackhuang.hmcl.ui.construct.RipplerContainer; import org.jackhuang.hmcl.ui.construct.SpinnerPane; import org.jackhuang.hmcl.ui.construct.TwoLineListItem; import org.jackhuang.hmcl.ui.decorator.DecoratorPage; @@ -525,46 +521,68 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP spinnerPane.setContent(listView); Bindings.bindContent(listView.getItems(), getSkinnable().items); - FXUtils.onClicked(listView, () -> { - if (listView.getSelectionModel().getSelectedIndex() < 0) - return; - RemoteMod selectedItem = listView.getSelectionModel().getSelectedItem(); - Controllers.navigate(new DownloadPage(getSkinnable(), selectedItem, getSkinnable().getProfileVersion(), getSkinnable().callback)); - }); - + listView.setSelectionModel(null); // ListViewBehavior would consume ESC pressed event, preventing us from handling it, so we ignore it here ignoreEvent(listView, KeyEvent.KEY_PRESSED, e -> e.getCode() == KeyCode.ESCAPE); - listView.setCellFactory(x -> new FloatListCell<>(listView) { + listView.setCellFactory(x -> new ListCell<>() { + private static final Insets PADDING = new Insets(9, 9, 0, 9); + + private final RipplerContainer graphic; + private final TwoLineListItem content = new TwoLineListItem(); private final ImageView imageView = new ImageView(); { + setPadding(PADDING); + HBox container = new HBox(8); + container.getStyleClass().add("card"); + container.setCursor(Cursor.HAND); container.setAlignment(Pos.CENTER_LEFT); - pane.getChildren().add(container); + JFXDepthManager.setDepth(container, 1); imageView.setFitWidth(40); imageView.setFitHeight(40); container.getChildren().setAll(FXUtils.limitingSize(imageView, 40, 40), content); HBox.setHgrow(content, Priority.ALWAYS); + + this.graphic = new RipplerContainer(container); + graphic.setPosition(JFXRippler.RipplerPos.FRONT); + FXUtils.onClicked(graphic, () -> { + RemoteMod item = getItem(); + if (item != null) + Controllers.navigate(new DownloadPage(getSkinnable(), item, getSkinnable().getProfileVersion(), getSkinnable().callback)); + }); + + setPrefWidth(0); + + if (listView.lookup(".clipped-container") instanceof Region clippedContainer) { + maxWidthProperty().bind(clippedContainer.widthProperty()); + prefWidthProperty().bind(clippedContainer.widthProperty()); + minWidthProperty().bind(clippedContainer.widthProperty()); + } } @Override - protected void updateControl(RemoteMod dataItem, boolean empty) { - if (empty) return; - ModTranslations.Mod mod = ModTranslations.getTranslationsByRepositoryType(getSkinnable().repository.getType()).getModByCurseForgeId(dataItem.getSlug()); - content.setTitle(mod != null && I18n.isUseChinese() ? mod.getDisplayName() : dataItem.getTitle()); - content.setSubtitle(dataItem.getDescription()); - content.getTags().clear(); - for (String category : dataItem.getCategories()) { - if (getSkinnable().shouldDisplayCategory(category)) - content.addTag(getSkinnable().getLocalizedCategory(category)); + protected void updateItem(RemoteMod item, boolean empty) { + super.updateItem(item, empty); + if (empty || item == null) { + setGraphic(null); + } else { + ModTranslations.Mod mod = ModTranslations.getTranslationsByRepositoryType(getSkinnable().repository.getType()).getModByCurseForgeId(item.getSlug()); + content.setTitle(mod != null && I18n.isUseChinese() ? mod.getDisplayName() : item.getTitle()); + content.setSubtitle(item.getDescription()); + content.getTags().clear(); + for (String category : item.getCategories()) { + if (getSkinnable().shouldDisplayCategory(category)) + content.addTag(getSkinnable().getLocalizedCategory(category)); + } + iconLoader.load(imageView.imageProperty(), item.getIconUrl()); + setGraphic(graphic); } - iconLoader.load(imageView.imageProperty(), dataItem.getIconUrl()); } - }); } diff --git a/HMCL/src/main/resources/assets/css/root.css b/HMCL/src/main/resources/assets/css/root.css index 353c0dbea..1ca74227d 100644 --- a/HMCL/src/main/resources/assets/css/root.css +++ b/HMCL/src/main/resources/assets/css/root.css @@ -999,10 +999,6 @@ -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.26), 5, 0.06, -0.5, 1); } -.card:selected { - -fx-background-color: -monet-secondary-container-transparent-80; -} - .card-list { -fx-padding: 10; -fx-spacing: 10;