From 75c4fb6550a5539e45b38885bf3dbc4a0d0d1d75 Mon Sep 17 00:00:00 2001 From: Glavo Date: Sat, 15 Nov 2025 21:22:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=9B=B4=E5=A4=9A=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E7=9A=84=E5=8A=A8=E7=94=BB=20(#4790)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/jackhuang/hmcl/ui/Controllers.java | 22 ++++++- .../ui/animation/ContainerAnimations.java | 56 ++++++++++++++++-- .../ui/decorator/DecoratorController.java | 57 ++----------------- .../hmcl/ui/main/JavaManagementPage.java | 2 +- .../org/jackhuang/hmcl/ui/main/RootPage.java | 3 + .../hmcl/ui/versions/ModListPage.java | 2 +- .../hmcl/ui/versions/VersionSettingsPage.java | 2 +- .../hmcl/ui/versions/WorldListItem.java | 2 +- 8 files changed, 83 insertions(+), 63 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java index ff9c85977..a832401e7 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -49,6 +49,7 @@ import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.task.TaskExecutor; import org.jackhuang.hmcl.ui.account.AccountListPage; import org.jackhuang.hmcl.ui.animation.AnimationUtils; +import org.jackhuang.hmcl.ui.animation.ContainerAnimations; import org.jackhuang.hmcl.ui.animation.Motion; import org.jackhuang.hmcl.ui.construct.*; import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType; @@ -91,7 +92,7 @@ public final class Controllers { private static Scene scene; private static Stage stage; - private static Lazy versionPage = new Lazy<>(VersionPage::new); + private static VersionPage versionPage; private static Lazy gameListPage = new Lazy<>(() -> { GameListPage gameListPage = new GameListPage(); gameListPage.selectedProfileProperty().bindBidirectional(Profiles.selectedProfileProperty()); @@ -128,7 +129,18 @@ public final class Controllers { // FXThread public static VersionPage getVersionPage() { - return versionPage.get(); + if (versionPage == null) { + versionPage = new VersionPage(); + } + return versionPage; + } + + @FXThread + public static void prepareVersionPage() { + if (versionPage == null) { + LOG.info("Prepare the version page"); + versionPage = FXUtils.prepareNode(new VersionPage()); + } } // FXThread @@ -521,7 +533,11 @@ public final class Controllers { } public static void navigate(Node node) { - decorator.navigate(node); + decorator.navigate(node, ContainerAnimations.NAVIGATION, Motion.SHORT4, Motion.EASE); + } + + public static void navigateForward(Node node) { + decorator.navigate(node, ContainerAnimations.FORWARD, Motion.SHORT4, Motion.EASE); } public static void showToast(String content) { diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/ContainerAnimations.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/ContainerAnimations.java index 98ddbf7d5..89a300be6 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/ContainerAnimations.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/ContainerAnimations.java @@ -17,13 +17,11 @@ */ package org.jackhuang.hmcl.ui.animation; -import javafx.animation.Interpolator; -import javafx.animation.KeyFrame; -import javafx.animation.KeyValue; -import javafx.animation.Timeline; +import javafx.animation.*; import javafx.scene.Node; import javafx.scene.layout.Pane; import javafx.util.Duration; +import org.jackhuang.hmcl.ui.decorator.DecoratorAnimatedPage; public enum ContainerAnimations implements TransitionPane.AnimationProducer { NONE { @@ -199,6 +197,56 @@ public enum ContainerAnimations implements TransitionPane.AnimationProducer { ); } }, + + NAVIGATION { + @Override + public void init(TransitionPane container, Node previousNode, Node nextNode) { + } + + @Override + public Animation animate(Pane container, Node previousNode, Node nextNode, Duration duration, Interpolator interpolator) { + Timeline timeline = new Timeline(); + if (previousNode instanceof TransitionPane.EmptyPane) { + return timeline; + } + + Duration halfDuration = duration.divide(2); + + timeline.getKeyFrames().add(new KeyFrame(Duration.ZERO, + new KeyValue(previousNode.opacityProperty(), 1, interpolator))); + timeline.getKeyFrames().add(new KeyFrame(halfDuration, + new KeyValue(previousNode.opacityProperty(), 0, interpolator))); + if (previousNode instanceof DecoratorAnimatedPage prevPage) { + Node left = prevPage.getLeft(); + Node center = prevPage.getCenter(); + + timeline.getKeyFrames().add(new KeyFrame(Duration.ZERO, + new KeyValue(left.translateXProperty(), 0, interpolator), + new KeyValue(center.translateXProperty(), 0, interpolator))); + timeline.getKeyFrames().add(new KeyFrame(halfDuration, + new KeyValue(left.translateXProperty(), -30, interpolator), + new KeyValue(center.translateXProperty(), 30, interpolator))); + } + + timeline.getKeyFrames().add(new KeyFrame(halfDuration, + new KeyValue(nextNode.opacityProperty(), 0, interpolator))); + timeline.getKeyFrames().add(new KeyFrame(duration, + new KeyValue(nextNode.opacityProperty(), 1, interpolator))); + if (nextNode instanceof DecoratorAnimatedPage nextPage) { + Node left = nextPage.getLeft(); + Node center = nextPage.getCenter(); + + timeline.getKeyFrames().add(new KeyFrame(halfDuration, + new KeyValue(left.translateXProperty(), -30, interpolator), + new KeyValue(center.translateXProperty(), 30, interpolator))); + timeline.getKeyFrames().add(new KeyFrame(duration, + new KeyValue(left.translateXProperty(), 0, interpolator), + new KeyValue(center.translateXProperty(), 0, interpolator))); + } + + return timeline; + } + } ; protected static void reset(Node node) { 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 1d34d0da4..95833a79b 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 @@ -51,6 +51,7 @@ import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.account.AddAuthlibInjectorServerPane; import org.jackhuang.hmcl.ui.animation.*; +import org.jackhuang.hmcl.ui.animation.TransitionPane.AnimationProducer; import org.jackhuang.hmcl.ui.construct.DialogAware; import org.jackhuang.hmcl.ui.construct.DialogCloseEvent; import org.jackhuang.hmcl.ui.construct.Navigator; @@ -364,57 +365,8 @@ public class DecoratorController { // ==== Navigation ==== - private static final TransitionPane.AnimationProducer ANIMATION = (Pane container, - Node previousNode, Node nextNode, - Duration duration, - Interpolator interpolator) -> { - Timeline timeline = new Timeline(); - if (previousNode instanceof TransitionPane.EmptyPane) { - return timeline; - } - - Duration halfDuration = duration.divide(2); - - List keyFrames = new ArrayList<>(); - - keyFrames.add(new KeyFrame(Duration.ZERO, - new KeyValue(previousNode.opacityProperty(), 1, interpolator))); - keyFrames.add(new KeyFrame(halfDuration, - new KeyValue(previousNode.opacityProperty(), 0, interpolator))); - if (previousNode instanceof DecoratorAnimatedPage prevPage) { - Node left = prevPage.getLeft(); - Node center = prevPage.getCenter(); - - keyFrames.add(new KeyFrame(Duration.ZERO, - new KeyValue(left.translateXProperty(), 0, interpolator), - new KeyValue(center.translateXProperty(), 0, interpolator))); - keyFrames.add(new KeyFrame(halfDuration, - new KeyValue(left.translateXProperty(), -30, interpolator), - new KeyValue(center.translateXProperty(), 30, interpolator))); - } - - keyFrames.add(new KeyFrame(halfDuration, - new KeyValue(nextNode.opacityProperty(), 0, interpolator))); - keyFrames.add(new KeyFrame(duration, - new KeyValue(nextNode.opacityProperty(), 1, interpolator))); - if (nextNode instanceof DecoratorAnimatedPage nextPage) { - Node left = nextPage.getLeft(); - Node center = nextPage.getCenter(); - - keyFrames.add(new KeyFrame(halfDuration, - new KeyValue(left.translateXProperty(), -30, interpolator), - new KeyValue(center.translateXProperty(), 30, interpolator))); - keyFrames.add(new KeyFrame(duration, - new KeyValue(left.translateXProperty(), 0, interpolator), - new KeyValue(center.translateXProperty(), 0, interpolator))); - } - - timeline.getKeyFrames().setAll(keyFrames); - return timeline; - }; - - public void navigate(Node node) { - navigator.navigate(node, ANIMATION); + public void navigate(Node node, AnimationProducer animationProducer, Duration duration, Interpolator interpolator) { + navigator.navigate(node, animationProducer, duration, interpolator); } private void close() { @@ -586,7 +538,8 @@ public class DecoratorController { public void startWizard(WizardProvider wizardProvider, String category) { FXUtils.checkFxUserThread(); - navigator.navigate(new DecoratorWizardDisplayer(wizardProvider, category), ContainerAnimations.FADE); + navigator.navigate(new DecoratorWizardDisplayer(wizardProvider, category), + ContainerAnimations.FORWARD, Motion.SHORT4, Motion.EASE); } // ==== Authlib Injector DnD ==== 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 50ec4dbae..0f5bec1a3 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 @@ -123,7 +123,7 @@ public final class JavaManagementPage extends ListPageBase instance.getId().equals(currentId)); }, it -> getSkinnable().getMainPage().getProfile().setSelectedVersion(it.getId())); + if (AnimationUtils.isAnimationEnabled()) { + FXUtils.prepareOnMouseEnter(gameListItem, Controllers::prepareVersionPage); + } // third item in left sidebar AdvancedListItem gameItem = new AdvancedListItem(); diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java index 0dce35cd2..b826216c9 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModListPage.java @@ -244,7 +244,7 @@ public final class ModListPage extends ListPageBase