优化更多界面的动画 (#4790)
This commit is contained in:
@@ -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> versionPage = new Lazy<>(VersionPage::new);
|
||||
private static VersionPage versionPage;
|
||||
private static Lazy<GameListPage> 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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<KeyFrame> 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 ====
|
||||
|
||||
@@ -123,7 +123,7 @@ public final class JavaManagementPage extends ListPageBase<JavaManagementPage.Ja
|
||||
}
|
||||
|
||||
void onShowRestoreJavaPage() {
|
||||
Controllers.navigate(new JavaRestorePage(ConfigHolder.globalConfig().getDisabledJava()));
|
||||
Controllers.navigateForward(new JavaRestorePage(ConfigHolder.globalConfig().getDisabledJava()));
|
||||
}
|
||||
|
||||
private void onAddJavaBinary(Path file) {
|
||||
|
||||
@@ -161,6 +161,9 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage {
|
||||
String currentId = getSkinnable().getMainPage().getCurrentGame();
|
||||
return Lang.indexWhere(list, instance -> 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();
|
||||
|
||||
@@ -244,7 +244,7 @@ public final class ModListPage extends ListPageBase<ModListPageSkin.ModInfoObjec
|
||||
} else if (result.isEmpty()) {
|
||||
Controllers.dialog(i18n("mods.check_updates.empty"));
|
||||
} else {
|
||||
Controllers.navigate(new ModUpdatesPage(modManager, result));
|
||||
Controllers.navigateForward(new ModUpdatesPage(modManager, result));
|
||||
}
|
||||
})
|
||||
.withStagesHint(Collections.singletonList("mods.check_updates")),
|
||||
|
||||
@@ -461,7 +461,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
||||
if (advancedVersionSettingPage == null)
|
||||
advancedVersionSettingPage = new AdvancedVersionSettingPage(profile, versionId, lastVersionSetting);
|
||||
|
||||
Controllers.navigate(advancedVersionSettingPage);
|
||||
Controllers.navigateForward(advancedVersionSettingPage);
|
||||
}
|
||||
});
|
||||
showAdvancedSettingPane.setRight(button);
|
||||
|
||||
@@ -91,6 +91,6 @@ public final class WorldListItem extends Control {
|
||||
}
|
||||
|
||||
public void showManagePage() {
|
||||
Controllers.navigate(new WorldManagePage(world, backupsDir));
|
||||
Controllers.navigateForward(new WorldManagePage(world, backupsDir));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user