mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-13 22:07:01 -04:00
feat: title bar swipe animation.
This commit is contained in:
parent
5da4ad7a62
commit
0939ed819e
@ -173,7 +173,49 @@ public enum ContainerAnimations {
|
|||||||
new KeyValue(c.getPreviousNode().translateXProperty(), 0, Interpolator.EASE_BOTH)),
|
new KeyValue(c.getPreviousNode().translateXProperty(), 0, Interpolator.EASE_BOTH)),
|
||||||
new KeyFrame(c.getDuration(),
|
new KeyFrame(c.getDuration(),
|
||||||
new KeyValue(c.getCurrentNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
|
new KeyValue(c.getCurrentNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
|
||||||
new KeyValue(c.getPreviousNode().translateXProperty(), c.getCurrentRoot().getWidth(), Interpolator.EASE_BOTH))));
|
new KeyValue(c.getPreviousNode().translateXProperty(), c.getCurrentRoot().getWidth(), Interpolator.EASE_BOTH)))),
|
||||||
|
|
||||||
|
SWIPE_LEFT_FADE_SHORT(c -> {
|
||||||
|
c.getPreviousNode().setScaleX(1);
|
||||||
|
c.getPreviousNode().setScaleY(1);
|
||||||
|
c.getPreviousNode().setOpacity(0);
|
||||||
|
c.getPreviousNode().setTranslateX(0);
|
||||||
|
c.getCurrentNode().setScaleX(1);
|
||||||
|
c.getCurrentNode().setScaleY(1);
|
||||||
|
c.getCurrentNode().setOpacity(1);
|
||||||
|
c.getCurrentNode().setTranslateX(c.getCurrentRoot().getWidth());
|
||||||
|
}, c ->
|
||||||
|
Arrays.asList(new KeyFrame(Duration.ZERO,
|
||||||
|
new KeyValue(c.getCurrentNode().translateXProperty(), 50, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getPreviousNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getCurrentNode().opacityProperty(), 0, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getPreviousNode().opacityProperty(), 1, Interpolator.EASE_BOTH)),
|
||||||
|
new KeyFrame(c.getDuration(),
|
||||||
|
new KeyValue(c.getCurrentNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getPreviousNode().translateXProperty(), -50, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getCurrentNode().opacityProperty(), 1, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getPreviousNode().opacityProperty(), 0, Interpolator.EASE_BOTH)))),
|
||||||
|
|
||||||
|
SWIPE_RIGHT_FADE_SHORT(c -> {
|
||||||
|
c.getPreviousNode().setScaleX(1);
|
||||||
|
c.getPreviousNode().setScaleY(1);
|
||||||
|
c.getPreviousNode().setOpacity(0);
|
||||||
|
c.getPreviousNode().setTranslateX(0);
|
||||||
|
c.getCurrentNode().setScaleX(1);
|
||||||
|
c.getCurrentNode().setScaleY(1);
|
||||||
|
c.getCurrentNode().setOpacity(1);
|
||||||
|
c.getCurrentNode().setTranslateX(c.getCurrentRoot().getWidth());
|
||||||
|
}, c ->
|
||||||
|
Arrays.asList(new KeyFrame(Duration.ZERO,
|
||||||
|
new KeyValue(c.getCurrentNode().translateXProperty(), -50, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getPreviousNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getCurrentNode().opacityProperty(), 0, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getPreviousNode().opacityProperty(), 1, Interpolator.EASE_BOTH)),
|
||||||
|
new KeyFrame(c.getDuration(),
|
||||||
|
new KeyValue(c.getCurrentNode().translateXProperty(), 0, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getPreviousNode().translateXProperty(), 50, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getCurrentNode().opacityProperty(), 1, Interpolator.EASE_BOTH),
|
||||||
|
new KeyValue(c.getPreviousNode().opacityProperty(), 0, Interpolator.EASE_BOTH))));
|
||||||
|
|
||||||
private final AnimationProducer animationProducer;
|
private final AnimationProducer animationProducer;
|
||||||
private ContainerAnimations opposite;
|
private ContainerAnimations opposite;
|
||||||
|
@ -30,6 +30,7 @@ import org.jackhuang.hmcl.ui.FXUtils;
|
|||||||
import org.jackhuang.hmcl.ui.animation.AnimationProducer;
|
import org.jackhuang.hmcl.ui.animation.AnimationProducer;
|
||||||
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
||||||
import org.jackhuang.hmcl.ui.animation.TransitionPane;
|
import org.jackhuang.hmcl.ui.animation.TransitionPane;
|
||||||
|
import org.jackhuang.hmcl.ui.wizard.Navigation;
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
import org.jackhuang.hmcl.util.Logging;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -48,7 +49,7 @@ public class Navigator extends TransitionPane {
|
|||||||
backable.set(canGoBack());
|
backable.set(canGoBack());
|
||||||
getChildren().setAll(init);
|
getChildren().setAll(init);
|
||||||
|
|
||||||
fireEvent(new NavigationEvent(this, init, NavigationEvent.NAVIGATED));
|
fireEvent(new NavigationEvent(this, init, Navigation.NavigationDirection.START, NavigationEvent.NAVIGATED));
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
@ -68,14 +69,14 @@ public class Navigator extends TransitionPane {
|
|||||||
stack.push(node);
|
stack.push(node);
|
||||||
backable.set(canGoBack());
|
backable.set(canGoBack());
|
||||||
|
|
||||||
NavigationEvent navigating = new NavigationEvent(this, from, NavigationEvent.NAVIGATING);
|
NavigationEvent navigating = new NavigationEvent(this, from, Navigation.NavigationDirection.NEXT, NavigationEvent.NAVIGATING);
|
||||||
fireEvent(navigating);
|
fireEvent(navigating);
|
||||||
node.fireEvent(navigating);
|
node.fireEvent(navigating);
|
||||||
|
|
||||||
node.getProperties().put("hmcl.navigator.animation", animationProducer);
|
node.getProperties().put("hmcl.navigator.animation", animationProducer);
|
||||||
setContent(node, animationProducer);
|
setContent(node, animationProducer);
|
||||||
|
|
||||||
NavigationEvent navigated = new NavigationEvent(this, node, NavigationEvent.NAVIGATED);
|
NavigationEvent navigated = new NavigationEvent(this, node, Navigation.NavigationDirection.NEXT, NavigationEvent.NAVIGATED);
|
||||||
node.fireEvent(navigated);
|
node.fireEvent(navigated);
|
||||||
|
|
||||||
EventHandler<PageCloseEvent> handler = event -> close(node);
|
EventHandler<PageCloseEvent> handler = event -> close(node);
|
||||||
@ -111,7 +112,7 @@ public class Navigator extends TransitionPane {
|
|||||||
backable.set(canGoBack());
|
backable.set(canGoBack());
|
||||||
Node node = stack.peek();
|
Node node = stack.peek();
|
||||||
|
|
||||||
NavigationEvent navigating = new NavigationEvent(this, from, NavigationEvent.NAVIGATING);
|
NavigationEvent navigating = new NavigationEvent(this, from, Navigation.NavigationDirection.PREVIOUS, NavigationEvent.NAVIGATING);
|
||||||
fireEvent(navigating);
|
fireEvent(navigating);
|
||||||
node.fireEvent(navigating);
|
node.fireEvent(navigating);
|
||||||
|
|
||||||
@ -122,7 +123,7 @@ public class Navigator extends TransitionPane {
|
|||||||
setContent(node, ContainerAnimations.NONE.getAnimationProducer());
|
setContent(node, ContainerAnimations.NONE.getAnimationProducer());
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationEvent navigated = new NavigationEvent(this, node, NavigationEvent.NAVIGATED);
|
NavigationEvent navigated = new NavigationEvent(this, node, Navigation.NavigationDirection.PREVIOUS, NavigationEvent.NAVIGATED);
|
||||||
node.fireEvent(navigated);
|
node.fireEvent(navigated);
|
||||||
|
|
||||||
Optional.ofNullable(from.getProperties().get(PROPERTY_DIALOG_CLOSE_HANDLER))
|
Optional.ofNullable(from.getProperties().get(PROPERTY_DIALOG_CLOSE_HANDLER))
|
||||||
@ -206,12 +207,14 @@ public class Navigator extends TransitionPane {
|
|||||||
|
|
||||||
private final Navigator source;
|
private final Navigator source;
|
||||||
private final Node node;
|
private final Node node;
|
||||||
|
private final Navigation.NavigationDirection direction;
|
||||||
|
|
||||||
public NavigationEvent(Navigator source, Node target, EventType<? extends Event> eventType) {
|
public NavigationEvent(Navigator source, Node target, Navigation.NavigationDirection direction, EventType<? extends Event> eventType) {
|
||||||
super(source, target, eventType);
|
super(source, target, eventType);
|
||||||
|
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.node = target;
|
this.node = target;
|
||||||
|
this.direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -222,5 +225,9 @@ public class Navigator extends TransitionPane {
|
|||||||
public Node getNode() {
|
public Node getNode() {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Navigation.NavigationDirection getDirection() {
|
||||||
|
return direction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import javafx.scene.layout.StackPane;
|
|||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import javafx.stage.StageStyle;
|
import javafx.stage.StageStyle;
|
||||||
|
import org.jackhuang.hmcl.ui.wizard.Navigation;
|
||||||
|
|
||||||
public class Decorator extends Control {
|
public class Decorator extends Control {
|
||||||
private final ListProperty<Node> drawer = new SimpleListProperty<>(FXCollections.observableArrayList());
|
private final ListProperty<Node> drawer = new SimpleListProperty<>(FXCollections.observableArrayList());
|
||||||
@ -51,6 +52,7 @@ public class Decorator extends Control {
|
|||||||
private final BooleanProperty canClose = new SimpleBooleanProperty(false);
|
private final BooleanProperty canClose = new SimpleBooleanProperty(false);
|
||||||
private final BooleanProperty showCloseAsHome = new SimpleBooleanProperty(false);
|
private final BooleanProperty showCloseAsHome = new SimpleBooleanProperty(false);
|
||||||
private final Stage primaryStage;
|
private final Stage primaryStage;
|
||||||
|
private Navigation.NavigationDirection navigationDirection = Navigation.NavigationDirection.START;
|
||||||
private StackPane drawerWrapper;
|
private StackPane drawerWrapper;
|
||||||
|
|
||||||
private final ReadOnlyBooleanWrapper allowMove = new ReadOnlyBooleanWrapper();
|
private final ReadOnlyBooleanWrapper allowMove = new ReadOnlyBooleanWrapper();
|
||||||
@ -238,4 +240,13 @@ public class Decorator extends Control {
|
|||||||
e.consume();
|
e.consume();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Dirty implementation.
|
||||||
|
public Navigation.NavigationDirection getNavigationDirection() {
|
||||||
|
return navigationDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNavigationDirection(Navigation.NavigationDirection navigationDirection) {
|
||||||
|
this.navigationDirection = navigationDirection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,6 +243,8 @@ public class DecoratorController {
|
|||||||
decorator.showCloseAsHomeProperty().set(true);
|
decorator.showCloseAsHomeProperty().set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decorator.setNavigationDirection(event.getDirection());
|
||||||
|
|
||||||
// state property should be updated at last.
|
// state property should be updated at last.
|
||||||
if (to instanceof DecoratorPage) {
|
if (to instanceof DecoratorPage) {
|
||||||
decorator.stateProperty().bind(((DecoratorPage) to).stateProperty());
|
decorator.stateProperty().bind(((DecoratorPage) to).stateProperty());
|
||||||
|
@ -41,8 +41,10 @@ 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.AnimationProducer;
|
||||||
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
||||||
import org.jackhuang.hmcl.ui.animation.TransitionPane;
|
import org.jackhuang.hmcl.ui.animation.TransitionPane;
|
||||||
|
import org.jackhuang.hmcl.ui.wizard.Navigation;
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
|
|
||||||
public class DecoratorSkin extends SkinBase<Decorator> {
|
public class DecoratorSkin extends SkinBase<Decorator> {
|
||||||
@ -165,7 +167,16 @@ public class DecoratorSkin extends SkinBase<Decorator> {
|
|||||||
Node node = createNavBar(skinnable, s.isTitleBarTransparent(), s.getLeftPaneWidth(), s.isBackable(), skinnable.canCloseProperty().get(), skinnable.showCloseAsHomeProperty().get(), s.isRefreshable(), s.getTitle(), s.getTitleNode());
|
Node node = createNavBar(skinnable, s.isTitleBarTransparent(), s.getLeftPaneWidth(), s.isBackable(), skinnable.canCloseProperty().get(), skinnable.showCloseAsHomeProperty().get(), s.isRefreshable(), s.getTitle(), s.getTitleNode());
|
||||||
double targetOpacity = s.isTitleBarTransparent() ? 0 : 1;
|
double targetOpacity = s.isTitleBarTransparent() ? 0 : 1;
|
||||||
if (s.isAnimate()) {
|
if (s.isAnimate()) {
|
||||||
navBarPane.setContent(node, ContainerAnimations.FADE.getAnimationProducer());
|
AnimationProducer animation;
|
||||||
|
if (skinnable.getNavigationDirection() == Navigation.NavigationDirection.NEXT) {
|
||||||
|
animation = ContainerAnimations.SWIPE_LEFT_FADE_SHORT.getAnimationProducer();
|
||||||
|
} else if (skinnable.getNavigationDirection() == Navigation.NavigationDirection.PREVIOUS) {
|
||||||
|
animation = ContainerAnimations.SWIPE_RIGHT_FADE_SHORT.getAnimationProducer();
|
||||||
|
} else {
|
||||||
|
animation = ContainerAnimations.FADE.getAnimationProducer();
|
||||||
|
}
|
||||||
|
skinnable.setNavigationDirection(Navigation.NavigationDirection.START);
|
||||||
|
navBarPane.setContent(node, animation);
|
||||||
} else {
|
} else {
|
||||||
navBarPane.getChildren().setAll(node);
|
navBarPane.getChildren().setAll(node);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
|||||||
import org.jackhuang.hmcl.ui.construct.Navigator;
|
import org.jackhuang.hmcl.ui.construct.Navigator;
|
||||||
import org.jackhuang.hmcl.ui.construct.TabControl;
|
import org.jackhuang.hmcl.ui.construct.TabControl;
|
||||||
import org.jackhuang.hmcl.ui.construct.TabHeader;
|
import org.jackhuang.hmcl.ui.construct.TabHeader;
|
||||||
|
import org.jackhuang.hmcl.ui.wizard.Navigation;
|
||||||
|
|
||||||
public abstract class DecoratorTabPage extends DecoratorTransitionPage implements TabControl {
|
public abstract class DecoratorTabPage extends DecoratorTransitionPage implements TabControl {
|
||||||
|
|
||||||
@ -36,10 +37,10 @@ public abstract class DecoratorTabPage extends DecoratorTransitionPage implement
|
|||||||
}
|
}
|
||||||
if (newValue.getNode() != null) {
|
if (newValue.getNode() != null) {
|
||||||
onNavigating(getCurrentPage());
|
onNavigating(getCurrentPage());
|
||||||
if (getCurrentPage() != null) getCurrentPage().fireEvent(new Navigator.NavigationEvent(null, getCurrentPage(), Navigator.NavigationEvent.NAVIGATING));
|
if (getCurrentPage() != null) getCurrentPage().fireEvent(new Navigator.NavigationEvent(null, getCurrentPage(), Navigation.NavigationDirection.NEXT, Navigator.NavigationEvent.NAVIGATING));
|
||||||
navigate(newValue.getNode(), ContainerAnimations.FADE.getAnimationProducer());
|
navigate(newValue.getNode(), ContainerAnimations.FADE.getAnimationProducer());
|
||||||
onNavigated(getCurrentPage());
|
onNavigated(getCurrentPage());
|
||||||
if (getCurrentPage() != null) getCurrentPage().fireEvent(new Navigator.NavigationEvent(null, getCurrentPage(), Navigator.NavigationEvent.NAVIGATED));
|
if (getCurrentPage() != null) getCurrentPage().fireEvent(new Navigator.NavigationEvent(null, getCurrentPage(), Navigation.NavigationDirection.NEXT, Navigator.NavigationEvent.NAVIGATED));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user