com.jfoenix.controls.JFXTogglePane Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.jfoenix.controls;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Node;
import javafx.scene.control.Control;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.util.Duration;
/**
* @author Shadi Shaheen toggle pane is a hidden pane that is shown upon mouse click on its toggle node NOTE : the
* toggle animation is specified by the pane clipping shape TODO : reimplement, currently not used
*/
public class JFXTogglePane extends StackPane {
private Timeline toggleAnimation = null;
private ObjectProperty toggleNode = new SimpleObjectProperty<>();
private ObjectProperty contentNode = new SimpleObjectProperty<>();
/*
* the scaling factor controls area of the clipping node when
* toggeling the pane
*
*/
private DoubleProperty scalingFactor = new SimpleDoubleProperty(2.4);
public JFXTogglePane() {
this.clipProperty().addListener((o, oldVal, newVal) -> {
if (newVal != null) {
if (getToggleNode() != null) {
Region toggleNode = getToggleNode();
newVal.layoutXProperty()
.bind(Bindings.createDoubleBinding(() -> toggleNode.getLayoutX() + toggleNode.getWidth() / 2,
toggleNode.widthProperty(),
toggleNode.layoutXProperty()));
newVal.layoutYProperty()
.bind(Bindings.createDoubleBinding(() -> toggleNode.getLayoutY() + toggleNode.getHeight() / 2,
toggleNode.heightProperty(),
toggleNode.layoutYProperty()));
}
}
});
this.widthProperty().addListener((o, oldVal, newVal) -> updateToggleAnimation());
this.heightProperty().addListener((o, oldVal, newVal) -> updateToggleAnimation());
toggleNode.addListener((o, oldVal, newVal) -> {
if (newVal != null) {
if (getClip() != null) {
getClip().layoutXProperty().unbind();
getClip().layoutYProperty().unbind();
getClip().layoutXProperty()
.bind(Bindings.createDoubleBinding(() -> newVal.getLayoutX() + newVal.getWidth() / 2,
newVal.widthProperty(),
newVal.layoutXProperty()));
getClip().layoutYProperty()
.bind(Bindings.createDoubleBinding(() -> newVal.getLayoutY() + newVal.getHeight() / 2,
newVal.heightProperty(),
newVal.layoutYProperty()));
}
}
updateToggleAnimation();
newVal.widthProperty().addListener((o1, oldVal1, newVal1) -> updateToggleAnimation());
newVal.heightProperty().addListener((o1, oldVal1, newVal1) -> updateToggleAnimation());
newVal.setOnMouseClicked((click) -> togglePane());
});
}
public void togglePane() {
if (toggleAnimation == null) {
updateToggleAnimation();
}
this.getClip().scaleXProperty().unbind();
this.getClip().scaleYProperty().unbind();
toggleAnimation.setRate(toggleAnimation.getRate() * -1);
if (toggleAnimation.getCurrentTime().equals(Duration.millis(0)) && toggleAnimation.getRate() == -1) {
toggleAnimation.playFrom(Duration.millis(510));
} else {
toggleAnimation.play();
}
}
private void updateToggleAnimation() {
if (getContentNode() == null) {
return;
}
double rateX = this.getWidth() / getClip().getLayoutBounds().getWidth();
double rateY = this.getHeight() / getClip().getLayoutBounds().getHeight();
double newRate = Math.max(rateX, rateY) * getScalingFactor();
double animationRate = toggleAnimation == null ? -1 : toggleAnimation.getRate();
toggleAnimation = new Timeline(
new KeyFrame(Duration.millis(0), new KeyValue(getClip().scaleXProperty(), 1, Interpolator.EASE_BOTH)),
new KeyFrame(Duration.millis(0), new KeyValue(getClip().scaleYProperty(), 1, Interpolator.EASE_BOTH)),
new KeyFrame(Duration.millis(0),
new KeyValue(getContentNode().opacityProperty(), 0, Interpolator.EASE_BOTH)),
new KeyFrame(Duration.millis(350),
new KeyValue(getClip().scaleXProperty(), newRate, Interpolator.EASE_BOTH)),
new KeyFrame(Duration.millis(350),
new KeyValue(getClip().scaleYProperty(), newRate, Interpolator.EASE_BOTH)),
new KeyFrame(Duration.millis(370),
new KeyValue(getContentNode().opacityProperty(), 0, Interpolator.EASE_BOTH)),
new KeyFrame(Duration.millis(510),
new KeyValue(getContentNode().opacityProperty(), 1, Interpolator.EASE_BOTH)));
toggleAnimation.setOnFinished((finish) -> {
if (toggleAnimation.getRate() == 1) {
this.getClip().scaleXProperty().bind(Bindings.createDoubleBinding(() -> {
double X = this.getWidth() / getClip().getLayoutBounds().getWidth();
double Y = this.getHeight() / getClip().getLayoutBounds().getHeight();
return Math.max(X, Y) * getScalingFactor();
}, this.widthProperty(), this.heightProperty()));
this.getClip().scaleYProperty().bind(Bindings.createDoubleBinding(() -> {
double X = this.getWidth() / getClip().getLayoutBounds().getWidth();
double Y = this.getHeight() / getClip().getLayoutBounds().getHeight();
return Math.max(X, Y) * getScalingFactor();
}, this.widthProperty(), this.heightProperty()));
}
});
toggleAnimation.setRate(animationRate);
}
/***************************************************************************
* *
* Public Properties *
* *
**************************************************************************/
public final ObjectProperty toggleNodeProperty() {
return this.toggleNode;
}
public final Control getToggleNode() {
return this.toggleNodeProperty().get();
}
public final void setToggleNode(final Control toggleNode) {
this.toggleNodeProperty().set(toggleNode);
}
public final ObjectProperty contentNodeProperty() {
return this.contentNode;
}
public final Node getContentNode() {
return this.contentNodeProperty().get();
}
public final void setContentNode(final Node content) {
this.contentNodeProperty().set(content);
content.setOpacity(0);
}
public final DoubleProperty scalingFactorProperty() {
return this.scalingFactor;
}
public final double getScalingFactor() {
return this.scalingFactorProperty().get();
}
public final void setScalingFactor(final double scalingFactor) {
this.scalingFactorProperty().set(scalingFactor);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy