Skip to content

Commit ab26495

Browse files
authored
添加动画开关 (#2111)
1 parent 389d430 commit ab26495

11 files changed

Lines changed: 136 additions & 46 deletions

File tree

HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ public static Config fromJson(String json) throws JsonParseException {
191191
@SerializedName("preferredLoginType")
192192
private StringProperty preferredLoginType = new SimpleStringProperty();
193193

194+
@SerializedName("animationDisabled")
195+
private BooleanProperty animationDisabled = new SimpleBooleanProperty();
196+
194197
private transient ObservableHelper helper = new ObservableHelper(this);
195198

196199
public Config() {
@@ -601,6 +604,18 @@ public StringProperty preferredLoginTypeProperty() {
601604
return preferredLoginType;
602605
}
603606

607+
public boolean isAnimationDisabled() {
608+
return animationDisabled.get();
609+
}
610+
611+
public BooleanProperty animationDisabledProperty() {
612+
return animationDisabled;
613+
}
614+
615+
public void setAnimationDisabled(boolean animationDisabled) {
616+
this.animationDisabled.set(animationDisabled);
617+
}
618+
604619
public boolean isTitleTransparent() {
605620
return titleTransparent.get();
606621
}

HMCL/src/main/java/org/jackhuang/hmcl/setting/Settings.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import javafx.beans.binding.Bindings;
2121
import org.jackhuang.hmcl.Metadata;
2222
import org.jackhuang.hmcl.game.HMCLCacheRepository;
23+
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
2324
import org.jackhuang.hmcl.util.CacheRepository;
2425
import org.jackhuang.hmcl.util.io.FileUtils;
2526

@@ -54,6 +55,7 @@ private Settings() {
5455
Accounts.init();
5556
Profiles.init();
5657
AuthlibInjectorServers.init();
58+
AnimationUtils.init();
5759

5860
CacheRepository.setInstance(HMCLCacheRepository.REPOSITORY);
5961
HMCLCacheRepository.REPOSITORY.directoryProperty().bind(Bindings.createStringBinding(() -> {

HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import javafx.util.Duration;
4848
import javafx.util.StringConverter;
4949
import org.jackhuang.hmcl.task.Schedulers;
50+
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
5051
import org.jackhuang.hmcl.ui.construct.JFXHyperlink;
5152
import org.jackhuang.hmcl.util.Holder;
5253
import org.jackhuang.hmcl.util.Logging;
@@ -275,7 +276,8 @@ public static Node limitingSize(Node node, double width, double height) {
275276
}
276277

277278
public static void smoothScrolling(ScrollPane scrollPane) {
278-
ScrollUtils.addSmoothScrolling(scrollPane);
279+
if (AnimationUtils.isAnimationEnabled())
280+
ScrollUtils.addSmoothScrolling(scrollPane);
279281
}
280282

281283
public static void installFastTooltip(Node node, Tooltip tooltip) {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.jackhuang.hmcl.ui.animation;
2+
3+
import org.jackhuang.hmcl.setting.ConfigHolder;
4+
5+
public final class AnimationUtils {
6+
7+
private AnimationUtils() {
8+
}
9+
10+
/**
11+
* Trigger initialization of this class.
12+
* Should be called from {@link org.jackhuang.hmcl.setting.Settings#init()}.
13+
*/
14+
@SuppressWarnings("JavadocReference")
15+
public static void init() {
16+
}
17+
18+
private static final boolean enabled = !ConfigHolder.config().isAnimationDisabled();
19+
20+
public static boolean isAnimationEnabled() {
21+
return enabled;
22+
}
23+
}

HMCL/src/main/java/org/jackhuang/hmcl/ui/animation/TransitionPane.java

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,23 @@ public void setContent(Node newView, AnimationProducer transition, Duration dura
6969
return;
7070
}
7171

72-
transition.init(this);
73-
74-
// runLater or "init" will not work
75-
Platform.runLater(() -> {
76-
Timeline newAnimation = new Timeline();
77-
newAnimation.getKeyFrames().addAll(transition.animate(this));
78-
newAnimation.getKeyFrames().add(new KeyFrame(duration, e -> {
79-
setMouseTransparent(false);
80-
getChildren().remove(previousNode);
81-
}));
82-
FXUtils.playAnimation(this, "transition_pane", newAnimation);
83-
});
72+
if (AnimationUtils.isAnimationEnabled()) {
73+
transition.init(this);
74+
75+
// runLater or "init" will not work
76+
Platform.runLater(() -> {
77+
Timeline newAnimation = new Timeline();
78+
newAnimation.getKeyFrames().addAll(transition.animate(this));
79+
newAnimation.getKeyFrames().add(new KeyFrame(duration, e -> {
80+
setMouseTransparent(false);
81+
getChildren().remove(previousNode);
82+
}));
83+
FXUtils.playAnimation(this, "transition_pane", newAnimation);
84+
});
85+
} else {
86+
setMouseTransparent(false);
87+
getChildren().remove(previousNode);
88+
}
8489
}
8590

8691
private void updateContent(Node newView) {

HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/ComponentListCell.java

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
import javafx.application.Platform;
2626
import javafx.beans.property.BooleanProperty;
2727
import javafx.beans.property.SimpleBooleanProperty;
28+
import javafx.event.ActionEvent;
29+
import javafx.event.Event;
30+
import javafx.event.EventHandler;
2831
import javafx.geometry.Insets;
2932
import javafx.geometry.Pos;
3033
import javafx.scene.Node;
@@ -35,6 +38,7 @@
3538
import org.jackhuang.hmcl.setting.Theme;
3639
import org.jackhuang.hmcl.ui.FXUtils;
3740
import org.jackhuang.hmcl.ui.SVG;
41+
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
3842

3943
/**
4044
* @author huangyuhui
@@ -70,6 +74,7 @@ protected void layoutChildren() {
7074
}
7175
}
7276

77+
@SuppressWarnings("unchecked")
7378
private void updateLayout() {
7479
if (content instanceof ComponentList) {
7580
ComponentList list = (ComponentList) content;
@@ -134,42 +139,66 @@ private void updateLayout() {
134139
container.getChildren().setAll(content);
135140
groupNode.getChildren().add(container);
136141

137-
Runnable onExpand = () -> {
138-
if (expandAnimation != null && expandAnimation.getStatus() == Animation.Status.RUNNING) {
139-
expandAnimation.stop();
140-
}
142+
EventHandler<Event> onExpand;
143+
if (AnimationUtils.isAnimationEnabled()) {
144+
onExpand = e -> {
145+
if (expandAnimation != null && expandAnimation.getStatus() == Animation.Status.RUNNING) {
146+
expandAnimation.stop();
147+
}
141148

142-
setExpanded(!isExpanded());
149+
setExpanded(!isExpanded());
143150

144-
if (isExpanded()) {
145-
list.onExpand();
146-
list.layout();
147-
}
151+
if (isExpanded()) {
152+
list.onExpand();
153+
list.layout();
154+
}
155+
156+
Platform.runLater(() -> {
157+
double newAnimatedHeight = (content.prefHeight(-1) + 8 + 10) * (isExpanded() ? 1 : -1);
158+
double newHeight = isExpanded() ? getHeight() + newAnimatedHeight : prefHeight(-1);
159+
double contentHeight = isExpanded() ? newAnimatedHeight : 0;
160+
161+
if (isExpanded()) {
162+
updateClip(newHeight);
163+
}
164+
165+
expandAnimation = new Timeline(new KeyFrame(new Duration(320.0),
166+
new KeyValue(container.minHeightProperty(), contentHeight, FXUtils.SINE),
167+
new KeyValue(container.maxHeightProperty(), contentHeight, FXUtils.SINE)
168+
));
169+
170+
if (!isExpanded()) {
171+
expandAnimation.setOnFinished(e2 -> updateClip(newHeight));
172+
}
173+
174+
expandAnimation.play();
175+
});
176+
};
177+
} else {
178+
onExpand = e -> {
179+
setExpanded(!isExpanded());
148180

149-
Platform.runLater(() -> {
150181
double newAnimatedHeight = (content.prefHeight(-1) + 8 + 10) * (isExpanded() ? 1 : -1);
151182
double newHeight = isExpanded() ? getHeight() + newAnimatedHeight : prefHeight(-1);
152183
double contentHeight = isExpanded() ? newAnimatedHeight : 0;
153184

154185
if (isExpanded()) {
186+
list.onExpand();
187+
list.layout();
155188
updateClip(newHeight);
156189
}
157190

158-
expandAnimation = new Timeline(new KeyFrame(new Duration(320.0),
159-
new KeyValue(container.minHeightProperty(), contentHeight, FXUtils.SINE),
160-
new KeyValue(container.maxHeightProperty(), contentHeight, FXUtils.SINE)
161-
));
191+
container.setMinHeight(contentHeight);
192+
container.setMaxHeight(contentHeight);
162193

163194
if (!isExpanded()) {
164-
expandAnimation.setOnFinished(e2 -> updateClip(newHeight));
195+
updateClip(newHeight);
165196
}
197+
};
198+
}
166199

167-
expandAnimation.play();
168-
});
169-
};
170-
171-
headerRippler.setOnMouseClicked(e -> onExpand.run());
172-
expandButton.setOnMouseClicked(e -> onExpand.run());
200+
headerRippler.setOnMouseClicked(onExpand);
201+
expandButton.setOnAction((EventHandler<ActionEvent>) (Object) onExpand);
173202

174203
expandedProperty().addListener((a, b, newValue) ->
175204
expandIcon.setRotate(newValue ? 180 : 0));

HMCL/src/main/java/org/jackhuang/hmcl/ui/main/MainPage.java

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.jackhuang.hmcl.ui.Controllers;
4646
import org.jackhuang.hmcl.ui.FXUtils;
4747
import org.jackhuang.hmcl.ui.SVG;
48+
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
4849
import org.jackhuang.hmcl.ui.construct.AnnouncementCard;
4950
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
5051
import org.jackhuang.hmcl.ui.construct.PopupMenu;
@@ -254,18 +255,22 @@ private void showUpdate(boolean show) {
254255
}
255256

256257
private void doAnimation(boolean show) {
257-
Duration duration = Duration.millis(320);
258-
Timeline nowAnimation = new Timeline();
259-
nowAnimation.getKeyFrames().addAll(
260-
new KeyFrame(Duration.ZERO,
261-
new KeyValue(updatePane.translateXProperty(), show ? 260 : 0, SINE)),
262-
new KeyFrame(duration,
263-
new KeyValue(updatePane.translateXProperty(), show ? 0 : 260, SINE)));
264-
if (show) nowAnimation.getKeyFrames().add(
265-
new KeyFrame(Duration.ZERO, e -> updatePane.setVisible(true)));
266-
else nowAnimation.getKeyFrames().add(
267-
new KeyFrame(duration, e -> updatePane.setVisible(false)));
268-
nowAnimation.play();
258+
if (AnimationUtils.isAnimationEnabled()) {
259+
Duration duration = Duration.millis(320);
260+
Timeline nowAnimation = new Timeline();
261+
nowAnimation.getKeyFrames().addAll(
262+
new KeyFrame(Duration.ZERO,
263+
new KeyValue(updatePane.translateXProperty(), show ? 260 : 0, SINE)),
264+
new KeyFrame(duration,
265+
new KeyValue(updatePane.translateXProperty(), show ? 0 : 260, SINE)));
266+
if (show) nowAnimation.getKeyFrames().add(
267+
new KeyFrame(Duration.ZERO, e -> updatePane.setVisible(true)));
268+
else nowAnimation.getKeyFrames().add(
269+
new KeyFrame(duration, e -> updatePane.setVisible(false)));
270+
nowAnimation.play();
271+
} else {
272+
updatePane.setVisible(show);
273+
}
269274
}
270275

271276
private void launch() {

HMCL/src/main/java/org/jackhuang/hmcl/ui/main/PersonalizationPage.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ public PersonalizationPage() {
8888
titleTransparentButton.selectedProperty().bindBidirectional(config().titleTransparentProperty());
8989
titleTransparentButton.setTitle(i18n("settings.launcher.title_transparent"));
9090
}
91+
{
92+
OptionToggleButton animationButton = new OptionToggleButton();
93+
themeList.getContent().add(animationButton);
94+
animationButton.selectedProperty().bindBidirectional(config().animationDisabledProperty());
95+
animationButton.setTitle(i18n("settings.launcher.turn_off_animations"));
96+
}
9197
content.getChildren().addAll(ComponentList.createComponentListTitle(i18n("settings.launcher.appearance")), themeList);
9298

9399
{

HMCL/src/main/resources/assets/lang/I18N.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,7 @@ settings.launcher.proxy.socks=SOCKS
10661066
settings.launcher.proxy.username=Username
10671067
settings.launcher.theme=Theme
10681068
settings.launcher.title_transparent=Transparent titlebar
1069+
settings.launcher.turn_off_animations=Turn off animation (applies after restart)
10691070
settings.launcher.version_list_source=Version List
10701071

10711072
settings.memory=Memory

HMCL/src/main/resources/assets/lang/I18N_zh.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,7 @@ settings.launcher.proxy.socks=Socks
936936
settings.launcher.proxy.username=帳戶
937937
settings.launcher.theme=主題
938938
settings.launcher.title_transparent=標題欄透明
939+
settings.launcher.turn_off_animations=關閉動畫 (重啟後生效)
939940
settings.launcher.version_list_source=版本列表來源
940941

941942
settings.memory=遊戲記憶體

0 commit comments

Comments
 (0)