mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-13 05:46:59 -04:00
添加动画开关 (#2111)
This commit is contained in:
parent
389d430dbd
commit
ab264955f5
@ -191,6 +191,9 @@ public final class Config implements Cloneable, Observable {
|
|||||||
@SerializedName("preferredLoginType")
|
@SerializedName("preferredLoginType")
|
||||||
private StringProperty preferredLoginType = new SimpleStringProperty();
|
private StringProperty preferredLoginType = new SimpleStringProperty();
|
||||||
|
|
||||||
|
@SerializedName("animationDisabled")
|
||||||
|
private BooleanProperty animationDisabled = new SimpleBooleanProperty();
|
||||||
|
|
||||||
private transient ObservableHelper helper = new ObservableHelper(this);
|
private transient ObservableHelper helper = new ObservableHelper(this);
|
||||||
|
|
||||||
public Config() {
|
public Config() {
|
||||||
@ -601,6 +604,18 @@ public final class Config implements Cloneable, Observable {
|
|||||||
return preferredLoginType;
|
return preferredLoginType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAnimationDisabled() {
|
||||||
|
return animationDisabled.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanProperty animationDisabledProperty() {
|
||||||
|
return animationDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAnimationDisabled(boolean animationDisabled) {
|
||||||
|
this.animationDisabled.set(animationDisabled);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isTitleTransparent() {
|
public boolean isTitleTransparent() {
|
||||||
return titleTransparent.get();
|
return titleTransparent.get();
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ package org.jackhuang.hmcl.setting;
|
|||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import org.jackhuang.hmcl.Metadata;
|
import org.jackhuang.hmcl.Metadata;
|
||||||
import org.jackhuang.hmcl.game.HMCLCacheRepository;
|
import org.jackhuang.hmcl.game.HMCLCacheRepository;
|
||||||
|
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
|
||||||
import org.jackhuang.hmcl.util.CacheRepository;
|
import org.jackhuang.hmcl.util.CacheRepository;
|
||||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
|
|
||||||
@ -54,6 +55,7 @@ public final class Settings {
|
|||||||
Accounts.init();
|
Accounts.init();
|
||||||
Profiles.init();
|
Profiles.init();
|
||||||
AuthlibInjectorServers.init();
|
AuthlibInjectorServers.init();
|
||||||
|
AnimationUtils.init();
|
||||||
|
|
||||||
CacheRepository.setInstance(HMCLCacheRepository.REPOSITORY);
|
CacheRepository.setInstance(HMCLCacheRepository.REPOSITORY);
|
||||||
HMCLCacheRepository.REPOSITORY.directoryProperty().bind(Bindings.createStringBinding(() -> {
|
HMCLCacheRepository.REPOSITORY.directoryProperty().bind(Bindings.createStringBinding(() -> {
|
||||||
|
@ -47,6 +47,7 @@ import javafx.util.Callback;
|
|||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import javafx.util.StringConverter;
|
import javafx.util.StringConverter;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
|
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
|
||||||
import org.jackhuang.hmcl.ui.construct.JFXHyperlink;
|
import org.jackhuang.hmcl.ui.construct.JFXHyperlink;
|
||||||
import org.jackhuang.hmcl.util.Holder;
|
import org.jackhuang.hmcl.util.Holder;
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
@ -275,6 +276,7 @@ public final class FXUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void smoothScrolling(ScrollPane scrollPane) {
|
public static void smoothScrolling(ScrollPane scrollPane) {
|
||||||
|
if (AnimationUtils.isAnimationEnabled())
|
||||||
ScrollUtils.addSmoothScrolling(scrollPane);
|
ScrollUtils.addSmoothScrolling(scrollPane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package org.jackhuang.hmcl.ui.animation;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.setting.ConfigHolder;
|
||||||
|
|
||||||
|
public final class AnimationUtils {
|
||||||
|
|
||||||
|
private AnimationUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger initialization of this class.
|
||||||
|
* Should be called from {@link org.jackhuang.hmcl.setting.Settings#init()}.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JavadocReference")
|
||||||
|
public static void init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final boolean enabled = !ConfigHolder.config().isAnimationDisabled();
|
||||||
|
|
||||||
|
public static boolean isAnimationEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
}
|
@ -69,6 +69,7 @@ public class TransitionPane extends StackPane implements AnimationHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AnimationUtils.isAnimationEnabled()) {
|
||||||
transition.init(this);
|
transition.init(this);
|
||||||
|
|
||||||
// runLater or "init" will not work
|
// runLater or "init" will not work
|
||||||
@ -81,6 +82,10 @@ public class TransitionPane extends StackPane implements AnimationHandler {
|
|||||||
}));
|
}));
|
||||||
FXUtils.playAnimation(this, "transition_pane", newAnimation);
|
FXUtils.playAnimation(this, "transition_pane", newAnimation);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
setMouseTransparent(false);
|
||||||
|
getChildren().remove(previousNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateContent(Node newView) {
|
private void updateContent(Node newView) {
|
||||||
|
@ -25,6 +25,9 @@ import javafx.animation.Timeline;
|
|||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
import javafx.event.ActionEvent;
|
||||||
|
import javafx.event.Event;
|
||||||
|
import javafx.event.EventHandler;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
@ -35,6 +38,7 @@ import javafx.util.Duration;
|
|||||||
import org.jackhuang.hmcl.setting.Theme;
|
import org.jackhuang.hmcl.setting.Theme;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.SVG;
|
import org.jackhuang.hmcl.ui.SVG;
|
||||||
|
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author huangyuhui
|
* @author huangyuhui
|
||||||
@ -70,6 +74,7 @@ class ComponentListCell extends StackPane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private void updateLayout() {
|
private void updateLayout() {
|
||||||
if (content instanceof ComponentList) {
|
if (content instanceof ComponentList) {
|
||||||
ComponentList list = (ComponentList) content;
|
ComponentList list = (ComponentList) content;
|
||||||
@ -134,7 +139,9 @@ class ComponentListCell extends StackPane {
|
|||||||
container.getChildren().setAll(content);
|
container.getChildren().setAll(content);
|
||||||
groupNode.getChildren().add(container);
|
groupNode.getChildren().add(container);
|
||||||
|
|
||||||
Runnable onExpand = () -> {
|
EventHandler<Event> onExpand;
|
||||||
|
if (AnimationUtils.isAnimationEnabled()) {
|
||||||
|
onExpand = e -> {
|
||||||
if (expandAnimation != null && expandAnimation.getStatus() == Animation.Status.RUNNING) {
|
if (expandAnimation != null && expandAnimation.getStatus() == Animation.Status.RUNNING) {
|
||||||
expandAnimation.stop();
|
expandAnimation.stop();
|
||||||
}
|
}
|
||||||
@ -167,9 +174,31 @@ class ComponentListCell extends StackPane {
|
|||||||
expandAnimation.play();
|
expandAnimation.play();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
onExpand = e -> {
|
||||||
|
setExpanded(!isExpanded());
|
||||||
|
|
||||||
headerRippler.setOnMouseClicked(e -> onExpand.run());
|
double newAnimatedHeight = (content.prefHeight(-1) + 8 + 10) * (isExpanded() ? 1 : -1);
|
||||||
expandButton.setOnMouseClicked(e -> onExpand.run());
|
double newHeight = isExpanded() ? getHeight() + newAnimatedHeight : prefHeight(-1);
|
||||||
|
double contentHeight = isExpanded() ? newAnimatedHeight : 0;
|
||||||
|
|
||||||
|
if (isExpanded()) {
|
||||||
|
list.onExpand();
|
||||||
|
list.layout();
|
||||||
|
updateClip(newHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
container.setMinHeight(contentHeight);
|
||||||
|
container.setMaxHeight(contentHeight);
|
||||||
|
|
||||||
|
if (!isExpanded()) {
|
||||||
|
updateClip(newHeight);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
headerRippler.setOnMouseClicked(onExpand);
|
||||||
|
expandButton.setOnAction((EventHandler<ActionEvent>) (Object) onExpand);
|
||||||
|
|
||||||
expandedProperty().addListener((a, b, newValue) ->
|
expandedProperty().addListener((a, b, newValue) ->
|
||||||
expandIcon.setRotate(newValue ? 180 : 0));
|
expandIcon.setRotate(newValue ? 180 : 0));
|
||||||
|
@ -45,6 +45,7 @@ import org.jackhuang.hmcl.setting.Theme;
|
|||||||
import org.jackhuang.hmcl.ui.Controllers;
|
import org.jackhuang.hmcl.ui.Controllers;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.SVG;
|
import org.jackhuang.hmcl.ui.SVG;
|
||||||
|
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
|
||||||
import org.jackhuang.hmcl.ui.construct.AnnouncementCard;
|
import org.jackhuang.hmcl.ui.construct.AnnouncementCard;
|
||||||
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
|
||||||
import org.jackhuang.hmcl.ui.construct.PopupMenu;
|
import org.jackhuang.hmcl.ui.construct.PopupMenu;
|
||||||
@ -254,6 +255,7 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void doAnimation(boolean show) {
|
private void doAnimation(boolean show) {
|
||||||
|
if (AnimationUtils.isAnimationEnabled()) {
|
||||||
Duration duration = Duration.millis(320);
|
Duration duration = Duration.millis(320);
|
||||||
Timeline nowAnimation = new Timeline();
|
Timeline nowAnimation = new Timeline();
|
||||||
nowAnimation.getKeyFrames().addAll(
|
nowAnimation.getKeyFrames().addAll(
|
||||||
@ -266,6 +268,9 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
|||||||
else nowAnimation.getKeyFrames().add(
|
else nowAnimation.getKeyFrames().add(
|
||||||
new KeyFrame(duration, e -> updatePane.setVisible(false)));
|
new KeyFrame(duration, e -> updatePane.setVisible(false)));
|
||||||
nowAnimation.play();
|
nowAnimation.play();
|
||||||
|
} else {
|
||||||
|
updatePane.setVisible(show);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launch() {
|
private void launch() {
|
||||||
|
@ -88,6 +88,12 @@ public class PersonalizationPage extends StackPane {
|
|||||||
titleTransparentButton.selectedProperty().bindBidirectional(config().titleTransparentProperty());
|
titleTransparentButton.selectedProperty().bindBidirectional(config().titleTransparentProperty());
|
||||||
titleTransparentButton.setTitle(i18n("settings.launcher.title_transparent"));
|
titleTransparentButton.setTitle(i18n("settings.launcher.title_transparent"));
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
OptionToggleButton animationButton = new OptionToggleButton();
|
||||||
|
themeList.getContent().add(animationButton);
|
||||||
|
animationButton.selectedProperty().bindBidirectional(config().animationDisabledProperty());
|
||||||
|
animationButton.setTitle(i18n("settings.launcher.turn_off_animations"));
|
||||||
|
}
|
||||||
content.getChildren().addAll(ComponentList.createComponentListTitle(i18n("settings.launcher.appearance")), themeList);
|
content.getChildren().addAll(ComponentList.createComponentListTitle(i18n("settings.launcher.appearance")), themeList);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -1066,6 +1066,7 @@ settings.launcher.proxy.socks=SOCKS
|
|||||||
settings.launcher.proxy.username=Username
|
settings.launcher.proxy.username=Username
|
||||||
settings.launcher.theme=Theme
|
settings.launcher.theme=Theme
|
||||||
settings.launcher.title_transparent=Transparent titlebar
|
settings.launcher.title_transparent=Transparent titlebar
|
||||||
|
settings.launcher.turn_off_animations=Turn off animation (applies after restart)
|
||||||
settings.launcher.version_list_source=Version List
|
settings.launcher.version_list_source=Version List
|
||||||
|
|
||||||
settings.memory=Memory
|
settings.memory=Memory
|
||||||
|
@ -936,6 +936,7 @@ settings.launcher.proxy.socks=Socks
|
|||||||
settings.launcher.proxy.username=帳戶
|
settings.launcher.proxy.username=帳戶
|
||||||
settings.launcher.theme=主題
|
settings.launcher.theme=主題
|
||||||
settings.launcher.title_transparent=標題欄透明
|
settings.launcher.title_transparent=標題欄透明
|
||||||
|
settings.launcher.turn_off_animations=關閉動畫 (重啟後生效)
|
||||||
settings.launcher.version_list_source=版本列表來源
|
settings.launcher.version_list_source=版本列表來源
|
||||||
|
|
||||||
settings.memory=遊戲記憶體
|
settings.memory=遊戲記憶體
|
||||||
|
@ -934,6 +934,7 @@ settings.launcher.proxy.socks=Socks
|
|||||||
settings.launcher.proxy.username=帐户
|
settings.launcher.proxy.username=帐户
|
||||||
settings.launcher.theme=主题
|
settings.launcher.theme=主题
|
||||||
settings.launcher.title_transparent=标题栏透明
|
settings.launcher.title_transparent=标题栏透明
|
||||||
|
settings.launcher.turn_off_animations=关闭动画 (重启后生效)
|
||||||
settings.launcher.version_list_source=版本列表源
|
settings.launcher.version_list_source=版本列表源
|
||||||
|
|
||||||
settings.memory=游戏内存
|
settings.memory=游戏内存
|
||||||
|
Loading…
x
Reference in New Issue
Block a user