From 235c3dd6b762b84d9f2420d358faa6a649ca3945 Mon Sep 17 00:00:00 2001 From: ToobLac Date: Mon, 3 Aug 2026 14:09:51 +0800 Subject: [PATCH 1/5] clear rippler --- .../com/jfoenix/controls/JFXComboBox.java | 4 ++-- .../com/jfoenix/controls/JFXListCell.java | 1 + .../java/com/jfoenix/controls/JFXRippler.java | 19 +++++++++++++++++++ .../java/org/jackhuang/hmcl/ui/FXUtils.java | 2 +- .../hmcl/ui/construct/FontComboBox.java | 2 +- .../hmcl/ui/construct/MDListCell.java | 5 +++-- .../hmcl/ui/construct/RipplerContainer.java | 4 ++++ .../hmcl/ui/download/VersionsPage.java | 4 +++- .../hmcl/ui/instances/DownloadListPage.java | 1 + .../hmcl/ui/instances/GameListCell.java | 3 ++- .../hmcl/ui/instances/GameListPopupMenu.java | 4 +++- .../hmcl/ui/instances/SchematicsPage.java | 1 + .../hmcl/ui/instances/WorldListPage.java | 1 + .../hmcl/ui/main/JavaManagementPage.java | 4 +++- .../hmcl/ui/main/ThemePackManagementPage.java | 3 ++- 15 files changed, 47 insertions(+), 11 deletions(-) diff --git a/HMCL/src/main/java/com/jfoenix/controls/JFXComboBox.java b/HMCL/src/main/java/com/jfoenix/controls/JFXComboBox.java index 8c9b634cfb3..59006dd62ca 100644 --- a/HMCL/src/main/java/com/jfoenix/controls/JFXComboBox.java +++ b/HMCL/src/main/java/com/jfoenix/controls/JFXComboBox.java @@ -70,7 +70,7 @@ public JFXComboBox(ObservableList items) { private void initialize() { getStyleClass().add(DEFAULT_STYLE_CLASS); - this.setCellFactory(listView -> new JFXListCell() { + this.setCellFactory(listView -> new JFXListCell<>() { @Override public void updateItem(T item, boolean empty) { super.updateItem(item, empty); @@ -80,7 +80,7 @@ public void updateItem(T item, boolean empty) { // had to refactor the code out of the skin class to allow // customization of the button cell - this.setButtonCell(new ListCell() { + this.setButtonCell(new ListCell<>() { { // fixed clearing the combo box value is causing // java prompt text to be shown because the button cell is not updated diff --git a/HMCL/src/main/java/com/jfoenix/controls/JFXListCell.java b/HMCL/src/main/java/com/jfoenix/controls/JFXListCell.java index 13b1eadaecf..b36fd0cb2cb 100644 --- a/HMCL/src/main/java/com/jfoenix/controls/JFXListCell.java +++ b/HMCL/src/main/java/com/jfoenix/controls/JFXListCell.java @@ -199,6 +199,7 @@ protected void makeChildrenTransparent() { */ @Override protected void updateItem(T item, boolean empty) { + cellRippler.clearRippleImmediately(); super.updateItem(item, empty); if (empty) { setText(null); diff --git a/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java b/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java index 61d2d8f7bd0..535c8874dbc 100644 --- a/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java +++ b/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java @@ -278,6 +278,10 @@ protected void releaseRipple() { rippler.releaseRipple(); } + public void clearRippleImmediately() { + rippler.clearRippleImmediately(); + } + /** * creates Ripple effect in the center of the control * @@ -405,6 +409,21 @@ private void releaseRipple() { } } + private void clearRippleImmediately() { + Ripple ripple = ripplesQueue.poll(); + if (ripple != null) { + getChildren().remove(ripple); + if (generating.getAndSet(false)) { + if (overlayRect != null) { + overlayRect.inAnimation.stop(); + if (!forceOverlay) { + overlayRect.setOpacity(0D); + } + } + } + } + } + void cacheRippleClip(boolean cached) { cacheRipplerClip = cached; } 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 d006a67656a..1a5f7ae5573 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java @@ -1391,7 +1391,7 @@ public T fromString(String string) { } public static Callback, ListCell> jfxListCellFactory(Function graphicBuilder) { - return view -> new JFXListCell() { + return view -> new JFXListCell<>() { @Override public void updateItem(T item, boolean empty) { super.updateItem(item, empty); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FontComboBox.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FontComboBox.java index 64ffda3317e..75cd2e449fc 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FontComboBox.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/FontComboBox.java @@ -39,7 +39,7 @@ public FontComboBox() { styleProperty().bind(Bindings.concat("-fx-font-family: \"", valueProperty(), "\"")); - setCellFactory(listView -> new JFXListCell() { + setCellFactory(listView -> new JFXListCell<>() { @Override public void updateItem(String item, boolean empty) { super.updateItem(item, empty); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MDListCell.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MDListCell.java index bf62346f034..8d85d00c968 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MDListCell.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MDListCell.java @@ -30,6 +30,7 @@ public abstract class MDListCell extends ListCell { private final StackPane container = new StackPane(); private final StackPane root = new StackPane(); + private final RipplerContainer ripplerContainer = new RipplerContainer(container); public MDListCell(JFXListView listView) { @@ -37,7 +38,6 @@ public MDListCell(JFXListView listView) { setGraphic(null); root.getStyleClass().add("md-list-cell"); - RipplerContainer ripplerContainer = new RipplerContainer(container); root.getChildren().setAll(ripplerContainer); Region clippedContainer = (Region) listView.lookup(".clipped-container"); @@ -56,12 +56,13 @@ protected void updateItem(T item, boolean empty) { T oldItem = getItem(); boolean oldEmpty = isEmpty(); + ripplerContainer.clearRippleImmediately(); super.updateItem(item, empty); if (oldItem == item && oldEmpty == empty) return; updateControl(item, empty); - if (empty) { + if (empty || item == null) { setGraphic(null); } else { setGraphic(root); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java index 4c6fae21bee..c1cc5d19330 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java @@ -205,6 +205,10 @@ public void setRipplerFill(Paint ripplerFill) { ripplerFillProperty().set(ripplerFill); } + public void clearRippleImmediately() { + buttonRippler.clearRippleImmediately(); + } + @Override public List> getCssMetaData() { return getClassCssMetaData(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java index 09a062e73ae..93115fc88ac 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java @@ -158,6 +158,7 @@ private static class RemoteVersionListCell extends ListCell { private final TwoLineListItem twoLineListItem = new TwoLineListItem(); private final ImageView imageView = new ImageView(); private final StackPane pane = new StackPane(); + private final RipplerContainer ripplerContainer; RemoteVersionListCell(VersionsPage control) { this.control = control; @@ -188,7 +189,7 @@ private static class RemoteVersionListCell extends ListCell { pane.getStyleClass().add("md-list-cell"); StackPane.setMargin(hbox, new Insets(10, 16, 10, 16)); - pane.getChildren().setAll(new RipplerContainer(hbox)); + pane.getChildren().setAll(ripplerContainer = new RipplerContainer(hbox)); FXUtils.onClicked(this, this::onAction); } @@ -214,6 +215,7 @@ private void onOpenWiki() { public void updateItem(RemoteVersion remoteVersion, boolean empty) { RemoteVersion oldRemoteVersion = getItem(); + ripplerContainer.clearRippleImmediately(); super.updateItem(remoteVersion, empty); if (empty) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadListPage.java index f39535a4c38..0bb14dec368 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadListPage.java @@ -581,6 +581,7 @@ protected ModDownloadListPageSkin(DownloadListPage control) { @Override protected void updateItem(RemoteAddon item, boolean empty) { + this.graphic.clearRippleImmediately(); super.updateItem(item, empty); if (empty || item == null) { setGraphic(null); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListCell.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListCell.java index 7a7d9ecc5d6..e4b9686ed85 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListCell.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListCell.java @@ -40,7 +40,7 @@ public final class GameListCell extends ListCell { - private final Region graphic; + private final RipplerContainer graphic; private final ImageContainer imageView; private final TwoLineListItem content; @@ -162,6 +162,7 @@ public void fire() { @Override public void updateItem(GameListItem item, boolean empty) { + this.graphic.clearRippleImmediately(); super.updateItem(item, empty); this.imageView.imageProperty().unbind(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListPopupMenu.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListPopupMenu.java index b95dd77da72..b8596596328 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListPopupMenu.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListPopupMenu.java @@ -100,6 +100,7 @@ public ObservableList getItems() { private static final class Cell extends ListCell { private final Region graphic; + private final RipplerContainer ripplerContainer; private final ImageContainer imageView; private final TwoLineListItem content; @@ -128,7 +129,7 @@ public Cell(ListView listView) { container.setLeft(imageView); container.setCenter(content); - RipplerContainer ripplerContainer = new RipplerContainer(container); + this.ripplerContainer = new RipplerContainer(container); StackPane rootPane = new StackPane(); rootPane.getStyleClass().add("advanced-list-item"); @@ -149,6 +150,7 @@ public Cell(ListView listView) { @Override protected void updateItem(GameItem item, boolean empty) { + this.ripplerContainer.clearRippleImmediately(); super.updateItem(item, empty); this.imageView.imageProperty().unbind(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/SchematicsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/SchematicsPage.java index b7e21447c37..575944c7616 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/SchematicsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/SchematicsPage.java @@ -598,6 +598,7 @@ public Cell() { @Override protected void updateItem(Item item, boolean empty) { + graphics.clearRippleImmediately(); super.updateItem(item, empty); iconImageView.setImage(null); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/WorldListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/WorldListPage.java index fe02c80c66c..e9756acd0ef 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/WorldListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/WorldListPage.java @@ -326,6 +326,7 @@ protected void updateItem(World world, boolean empty) { World oldWorld = getItem(); boolean oldEmpty = isEmpty(); + this.graphic.clearRippleImmediately(); super.updateItem(world, empty); if (oldWorld == world && oldEmpty == empty) return; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java index b3eeb858956..6033b7bd60d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java @@ -227,7 +227,7 @@ protected ListCell createListCell(JFXListView listView } private static final class JavaItemCell extends ListCell { - private final Node graphic; + private final RipplerContainer graphic; private final Label label = new Label(); private final TwoLineListItem content; @@ -298,6 +298,8 @@ private static final class JavaItemCell extends ListCell { @Override protected void updateItem(JavaRuntime item, boolean empty) { JavaRuntime oldItem = getItem(); + + this.graphic.clearRippleImmediately(); super.updateItem(item, empty); if (empty || item == null) { setGraphic(null); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/ThemePackManagementPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/ThemePackManagementPage.java index c9354736704..53512d84cc4 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/ThemePackManagementPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/ThemePackManagementPage.java @@ -632,7 +632,7 @@ private static final class ThemePackItemCell extends ListCell Date: Mon, 3 Aug 2026 18:15:35 +0800 Subject: [PATCH 2/5] animation --- .../java/com/jfoenix/controls/JFXRippler.java | 99 ++++++++++++------- 1 file changed, 61 insertions(+), 38 deletions(-) diff --git a/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java b/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java index 535c8874dbc..3885cf62644 100644 --- a/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java +++ b/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java @@ -45,6 +45,7 @@ import javafx.scene.shape.Rectangle; import javafx.scene.shape.Shape; import javafx.util.Duration; +import org.jackhuang.hmcl.setting.SettingsManager; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -65,6 +66,11 @@ */ @DefaultProperty(value = "control") public class JFXRippler extends StackPane { + + public static boolean isAnimationEnabled() { + return !SettingsManager.settings().isAnimationDisabled(); + } + public enum RipplerPos { FRONT, BACK } @@ -270,16 +276,16 @@ protected void createRipple(double x, double y) { if (!isRipplerDisabled()) { rippler.setGeneratorCenterX(x); rippler.setGeneratorCenterY(y); - rippler.createRipple(); + rippler.createRipple(isAnimationEnabled()); } } protected void releaseRipple() { - rippler.releaseRipple(); + rippler.releaseRipple(isAnimationEnabled()); } public void clearRippleImmediately() { - rippler.clearRippleImmediately(); + rippler.releaseRipple(false); } /** @@ -291,7 +297,7 @@ public Runnable createManualRipple() { if (!isRipplerDisabled()) { rippler.setGeneratorCenterX(control.getLayoutBounds().getWidth() / 2); rippler.setGeneratorCenterY(control.getLayoutBounds().getHeight() / 2); - rippler.createRipple(); + rippler.createRipple(isAnimationEnabled()); return () -> { // create fade out transition for the ripple releaseRipple(); @@ -329,16 +335,22 @@ public void showOverlay() { rippler.overlayRect.outAnimation.stop(); } rippler.createOverlay(); - rippler.overlayRect.inAnimation.play(); + if (isAnimationEnabled()) { + rippler.overlayRect.setOpacity(1D); + } else { + rippler.overlayRect.inAnimation.play(); + } } public void hideOverlay() { if (!forceOverlay) { if (rippler.overlayRect != null) { rippler.overlayRect.inAnimation.stop(); - } - if (rippler.overlayRect != null) { - rippler.overlayRect.outAnimation.play(); + if (isAnimationEnabled()) { + rippler.overlayRect.outAnimation.play(); + } else { + rippler.overlayRect.setOpacity(0D); + } } } else { System.err.println("Ripple Overlay is forced!"); @@ -368,7 +380,7 @@ protected final class RippleGenerator extends Group { this.setCacheHint(CacheHint.SPEED); } - void createRipple() { + private void createRipple(boolean animation) { if (!generating.getAndSet(true)) { // create overlay once then change its color later createOverlay(); @@ -384,40 +396,46 @@ void createRipple() { // animate the ripple overlayRect.outAnimation.stop(); - overlayRect.inAnimation.play(); - ripple.inAnimation.play(); + if (animation) { + overlayRect.inAnimation.play(); + ripple.inAnimation.play(); + } else { + overlayRect.setOpacity(1D); + ripple.setScaleX(0D); + ripple.setScaleY(0D); + ripple.setTranslateX(0D); + ripple.setTranslateY(0D); + ripple.setOpacity(1D); + } } } - private void releaseRipple() { + private void releaseRipple(boolean animation) { Ripple ripple = ripplesQueue.poll(); if (ripple != null) { - ripple.inAnimation.stop(); - ripple.outAnimation = new Timeline( - new KeyFrame(Duration.millis(Math.min(800, (0.9 * 500) / ripple.getScaleX())) - , ripple.outKeyValues)); - ripple.outAnimation.setOnFinished((event) -> getChildren().remove(ripple)); - ripple.outAnimation.play(); - if (generating.getAndSet(false)) { - if (overlayRect != null) { - overlayRect.inAnimation.stop(); - if (!forceOverlay) { - overlayRect.outAnimation.play(); + if (animation) { + ripple.inAnimation.stop(); + ripple.outAnimation = new Timeline( + new KeyFrame(Duration.millis(Math.min(800, (0.9 * 500) / ripple.getScaleX())) + , ripple.outKeyValues)); + ripple.outAnimation.setOnFinished((event) -> getChildren().remove(ripple)); + ripple.outAnimation.play(); + if (generating.getAndSet(false)) { + if (overlayRect != null) { + overlayRect.inAnimation.stop(); + if (!forceOverlay) { + overlayRect.outAnimation.play(); + } } } - } - } - } - - private void clearRippleImmediately() { - Ripple ripple = ripplesQueue.poll(); - if (ripple != null) { - getChildren().remove(ripple); - if (generating.getAndSet(false)) { - if (overlayRect != null) { - overlayRect.inAnimation.stop(); - if (!forceOverlay) { - overlayRect.setOpacity(0D); + } else { + getChildren().remove(ripple); + if (generating.getAndSet(false)) { + if (overlayRect != null) { + overlayRect.inAnimation.stop(); + if (!forceOverlay) { + overlayRect.setOpacity(0D); + } } } } @@ -567,8 +585,13 @@ private void resetOverLay() { if (rippler.overlayRect != null) { rippler.overlayRect.inAnimation.stop(); final RippleGenerator.OverLayRipple oldOverlay = rippler.overlayRect; - rippler.overlayRect.outAnimation.setOnFinished((finish) -> rippler.getChildren().remove(oldOverlay)); - rippler.overlayRect.outAnimation.play(); + if (isAnimationEnabled()) { + rippler.overlayRect.outAnimation.setOnFinished((finish) -> rippler.getChildren().remove(oldOverlay)); + rippler.overlayRect.outAnimation.play(); + } else { + rippler.overlayRect.setOpacity(0D); + rippler.getChildren().remove(oldOverlay); + } rippler.overlayRect = null; } } From 79ba5b014ca044868ce64bbcc9aa4701e26191df Mon Sep 17 00:00:00 2001 From: ToobLac Date: Tue, 4 Aug 2026 19:43:26 +0800 Subject: [PATCH 3/5] update --- HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java b/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java index 3885cf62644..ba3df64a45f 100644 --- a/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java +++ b/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java @@ -336,9 +336,9 @@ public void showOverlay() { } rippler.createOverlay(); if (isAnimationEnabled()) { - rippler.overlayRect.setOpacity(1D); - } else { rippler.overlayRect.inAnimation.play(); + } else { + rippler.overlayRect.setOpacity(1D); } } From b86567919e3cac33b07403451b76c1fb774ccf17 Mon Sep 17 00:00:00 2001 From: ToobLac Date: Tue, 4 Aug 2026 19:49:00 +0800 Subject: [PATCH 4/5] update --- HMCL/src/main/java/com/jfoenix/controls/JFXListCell.java | 2 +- HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java | 2 +- .../java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HMCL/src/main/java/com/jfoenix/controls/JFXListCell.java b/HMCL/src/main/java/com/jfoenix/controls/JFXListCell.java index b36fd0cb2cb..25883328eb6 100644 --- a/HMCL/src/main/java/com/jfoenix/controls/JFXListCell.java +++ b/HMCL/src/main/java/com/jfoenix/controls/JFXListCell.java @@ -199,7 +199,7 @@ protected void makeChildrenTransparent() { */ @Override protected void updateItem(T item, boolean empty) { - cellRippler.clearRippleImmediately(); + cellRippler.releaseRippleImmediately(); super.updateItem(item, empty); if (empty) { setText(null); diff --git a/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java b/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java index ba3df64a45f..570b400a4ae 100644 --- a/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java +++ b/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java @@ -284,7 +284,7 @@ protected void releaseRipple() { rippler.releaseRipple(isAnimationEnabled()); } - public void clearRippleImmediately() { + public void releaseRippleImmediately() { rippler.releaseRipple(false); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java index c1cc5d19330..0b22ddb1199 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java @@ -206,7 +206,7 @@ public void setRipplerFill(Paint ripplerFill) { } public void clearRippleImmediately() { - buttonRippler.clearRippleImmediately(); + buttonRippler.releaseRippleImmediately(); } @Override From 4a5a99d05d3520b5b67b18a652bedbac63e93e37 Mon Sep 17 00:00:00 2001 From: ToobLac Date: Fri, 7 Aug 2026 10:09:13 +0800 Subject: [PATCH 5/5] update --- .../java/com/jfoenix/controls/JFXRippler.java | 100 +++++++----------- .../hmcl/ui/construct/MDListCell.java | 2 +- .../hmcl/ui/construct/RipplerContainer.java | 2 +- .../hmcl/ui/download/VersionsPage.java | 2 +- .../hmcl/ui/instances/DownloadListPage.java | 2 +- .../hmcl/ui/instances/GameListCell.java | 2 +- .../hmcl/ui/instances/GameListPopupMenu.java | 2 +- .../hmcl/ui/instances/SchematicsPage.java | 2 +- .../hmcl/ui/instances/WorldListPage.java | 2 +- .../hmcl/ui/main/JavaManagementPage.java | 2 +- .../hmcl/ui/main/ThemePackManagementPage.java | 2 +- 11 files changed, 49 insertions(+), 71 deletions(-) diff --git a/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java b/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java index 570b400a4ae..e534277b4a6 100644 --- a/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java +++ b/HMCL/src/main/java/com/jfoenix/controls/JFXRippler.java @@ -45,7 +45,6 @@ import javafx.scene.shape.Rectangle; import javafx.scene.shape.Shape; import javafx.util.Duration; -import org.jackhuang.hmcl.setting.SettingsManager; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -66,11 +65,6 @@ */ @DefaultProperty(value = "control") public class JFXRippler extends StackPane { - - public static boolean isAnimationEnabled() { - return !SettingsManager.settings().isAnimationDisabled(); - } - public enum RipplerPos { FRONT, BACK } @@ -276,16 +270,16 @@ protected void createRipple(double x, double y) { if (!isRipplerDisabled()) { rippler.setGeneratorCenterX(x); rippler.setGeneratorCenterY(y); - rippler.createRipple(isAnimationEnabled()); + rippler.createRipple(); } } protected void releaseRipple() { - rippler.releaseRipple(isAnimationEnabled()); + rippler.releaseRipple(); } public void releaseRippleImmediately() { - rippler.releaseRipple(false); + rippler.releaseRippleImmediately(); } /** @@ -297,7 +291,7 @@ public Runnable createManualRipple() { if (!isRipplerDisabled()) { rippler.setGeneratorCenterX(control.getLayoutBounds().getWidth() / 2); rippler.setGeneratorCenterY(control.getLayoutBounds().getHeight() / 2); - rippler.createRipple(isAnimationEnabled()); + rippler.createRipple(); return () -> { // create fade out transition for the ripple releaseRipple(); @@ -335,22 +329,16 @@ public void showOverlay() { rippler.overlayRect.outAnimation.stop(); } rippler.createOverlay(); - if (isAnimationEnabled()) { - rippler.overlayRect.inAnimation.play(); - } else { - rippler.overlayRect.setOpacity(1D); - } + rippler.overlayRect.inAnimation.play(); } public void hideOverlay() { if (!forceOverlay) { if (rippler.overlayRect != null) { rippler.overlayRect.inAnimation.stop(); - if (isAnimationEnabled()) { - rippler.overlayRect.outAnimation.play(); - } else { - rippler.overlayRect.setOpacity(0D); - } + } + if (rippler.overlayRect != null) { + rippler.overlayRect.outAnimation.play(); } } else { System.err.println("Ripple Overlay is forced!"); @@ -380,7 +368,7 @@ protected final class RippleGenerator extends Group { this.setCacheHint(CacheHint.SPEED); } - private void createRipple(boolean animation) { + void createRipple() { if (!generating.getAndSet(true)) { // create overlay once then change its color later createOverlay(); @@ -396,46 +384,41 @@ private void createRipple(boolean animation) { // animate the ripple overlayRect.outAnimation.stop(); - if (animation) { - overlayRect.inAnimation.play(); - ripple.inAnimation.play(); - } else { - overlayRect.setOpacity(1D); - ripple.setScaleX(0D); - ripple.setScaleY(0D); - ripple.setTranslateX(0D); - ripple.setTranslateY(0D); - ripple.setOpacity(1D); - } + overlayRect.inAnimation.play(); + ripple.inAnimation.play(); } } - private void releaseRipple(boolean animation) { + private void releaseRipple() { Ripple ripple = ripplesQueue.poll(); if (ripple != null) { - if (animation) { - ripple.inAnimation.stop(); - ripple.outAnimation = new Timeline( - new KeyFrame(Duration.millis(Math.min(800, (0.9 * 500) / ripple.getScaleX())) - , ripple.outKeyValues)); - ripple.outAnimation.setOnFinished((event) -> getChildren().remove(ripple)); - ripple.outAnimation.play(); - if (generating.getAndSet(false)) { - if (overlayRect != null) { - overlayRect.inAnimation.stop(); - if (!forceOverlay) { - overlayRect.outAnimation.play(); - } + ripple.inAnimation.stop(); + ripple.outAnimation = new Timeline( + new KeyFrame(Duration.millis(Math.min(800, (0.9 * 500) / ripple.getScaleX())) + , ripple.outKeyValues)); + ripple.outAnimation.setOnFinished((event) -> getChildren().remove(ripple)); + ripple.outAnimation.play(); + if (generating.getAndSet(false)) { + if (overlayRect != null) { + overlayRect.inAnimation.stop(); + if (!forceOverlay) { + overlayRect.outAnimation.play(); } } - } else { - getChildren().remove(ripple); - if (generating.getAndSet(false)) { - if (overlayRect != null) { - overlayRect.inAnimation.stop(); - if (!forceOverlay) { - overlayRect.setOpacity(0D); - } + } + } + } + + private void releaseRippleImmediately() { + Ripple ripple = ripplesQueue.poll(); + if (ripple != null) { + getChildren().remove(ripple); + if (generating.getAndSet(false)) { + if (overlayRect != null) { + overlayRect.inAnimation.stop(); + if (!forceOverlay) { + overlayRect.outAnimation.stop(); + overlayRect.setOpacity(0D); } } } @@ -585,13 +568,8 @@ private void resetOverLay() { if (rippler.overlayRect != null) { rippler.overlayRect.inAnimation.stop(); final RippleGenerator.OverLayRipple oldOverlay = rippler.overlayRect; - if (isAnimationEnabled()) { - rippler.overlayRect.outAnimation.setOnFinished((finish) -> rippler.getChildren().remove(oldOverlay)); - rippler.overlayRect.outAnimation.play(); - } else { - rippler.overlayRect.setOpacity(0D); - rippler.getChildren().remove(oldOverlay); - } + rippler.overlayRect.outAnimation.setOnFinished((finish) -> rippler.getChildren().remove(oldOverlay)); + rippler.overlayRect.outAnimation.play(); rippler.overlayRect = null; } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MDListCell.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MDListCell.java index 8d85d00c968..ba236c974e2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MDListCell.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MDListCell.java @@ -56,7 +56,7 @@ protected void updateItem(T item, boolean empty) { T oldItem = getItem(); boolean oldEmpty = isEmpty(); - ripplerContainer.clearRippleImmediately(); + ripplerContainer.releaseRippleImmediately(); super.updateItem(item, empty); if (oldItem == item && oldEmpty == empty) return; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java index 0b22ddb1199..063a236423c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/RipplerContainer.java @@ -205,7 +205,7 @@ public void setRipplerFill(Paint ripplerFill) { ripplerFillProperty().set(ripplerFill); } - public void clearRippleImmediately() { + public void releaseRippleImmediately() { buttonRippler.releaseRippleImmediately(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java index 93115fc88ac..69a79bb7fc9 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/download/VersionsPage.java @@ -215,7 +215,7 @@ private void onOpenWiki() { public void updateItem(RemoteVersion remoteVersion, boolean empty) { RemoteVersion oldRemoteVersion = getItem(); - ripplerContainer.clearRippleImmediately(); + ripplerContainer.releaseRippleImmediately(); super.updateItem(remoteVersion, empty); if (empty) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadListPage.java index 0bb14dec368..f9ad6b1a11f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/DownloadListPage.java @@ -581,7 +581,7 @@ protected ModDownloadListPageSkin(DownloadListPage control) { @Override protected void updateItem(RemoteAddon item, boolean empty) { - this.graphic.clearRippleImmediately(); + this.graphic.releaseRippleImmediately(); super.updateItem(item, empty); if (empty || item == null) { setGraphic(null); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListCell.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListCell.java index e4b9686ed85..54b881667a0 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListCell.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListCell.java @@ -162,7 +162,7 @@ public void fire() { @Override public void updateItem(GameListItem item, boolean empty) { - this.graphic.clearRippleImmediately(); + this.graphic.releaseRippleImmediately(); super.updateItem(item, empty); this.imageView.imageProperty().unbind(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListPopupMenu.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListPopupMenu.java index b8596596328..81c54b96477 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListPopupMenu.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/GameListPopupMenu.java @@ -150,7 +150,7 @@ public Cell(ListView listView) { @Override protected void updateItem(GameItem item, boolean empty) { - this.ripplerContainer.clearRippleImmediately(); + this.ripplerContainer.releaseRippleImmediately(); super.updateItem(item, empty); this.imageView.imageProperty().unbind(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/SchematicsPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/SchematicsPage.java index 575944c7616..3f6eb22328e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/SchematicsPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/SchematicsPage.java @@ -598,7 +598,7 @@ public Cell() { @Override protected void updateItem(Item item, boolean empty) { - graphics.clearRippleImmediately(); + graphics.releaseRippleImmediately(); super.updateItem(item, empty); iconImageView.setImage(null); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/WorldListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/WorldListPage.java index e9756acd0ef..aa5134042e4 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/WorldListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/instances/WorldListPage.java @@ -326,7 +326,7 @@ protected void updateItem(World world, boolean empty) { World oldWorld = getItem(); boolean oldEmpty = isEmpty(); - this.graphic.clearRippleImmediately(); + this.graphic.releaseRippleImmediately(); super.updateItem(world, empty); if (oldWorld == world && oldEmpty == empty) return; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java index 6033b7bd60d..c615ad82010 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/JavaManagementPage.java @@ -299,7 +299,7 @@ private static final class JavaItemCell extends ListCell { protected void updateItem(JavaRuntime item, boolean empty) { JavaRuntime oldItem = getItem(); - this.graphic.clearRippleImmediately(); + this.graphic.releaseRippleImmediately(); super.updateItem(item, empty); if (empty || item == null) { setGraphic(null); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/ThemePackManagementPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/ThemePackManagementPage.java index 53512d84cc4..3be7b6c6dc6 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/ThemePackManagementPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/main/ThemePackManagementPage.java @@ -715,7 +715,7 @@ private ThemePackItemCell(ThemePackManagementPage page) { protected void updateItem(ThemePackManager.@Nullable InstalledThemePack themePack, boolean empty) { var currentItem = getItem(); - this.graphic.clearRippleImmediately(); + this.graphic.releaseRippleImmediately(); super.updateItem(themePack, empty); if (Objects.equals(getItem(), currentItem)) return;