/* * Copyright (C) 2015 thirdy * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package net.thirdy.blackmarket.fxcontrols; import java.util.concurrent.atomic.AtomicBoolean; import javafx.animation.Animation; import javafx.animation.Transition; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.layout.GridPane; import javafx.scene.layout.Priority; import javafx.util.Duration; /** Animates a node on and off screen to the left. */ public class SlidingPane extends GridPane { /** @return a control button to hide and show the sidebar */ public Button getControlButton() { return controlButton; } private final Button controlButton; private final AtomicBoolean expanded = new AtomicBoolean(true); private DoubleProperty minY = new SimpleDoubleProperty(); public DoubleProperty minYProperty(){return minY;} private DoubleProperty expandedHeight = new SimpleDoubleProperty(); public DoubleProperty expandedHeightProperty(){return expandedHeight;} /** creates a sidebar containing a vertical alignment of the given nodes */ public SlidingPane(Node node) { minY.bind(expandedHeightProperty().subtract(18.0)); prefHeightProperty().bind(expandedHeightProperty()); GridPane.setHgrow(node, Priority.ALWAYS); GridPane.setVgrow(node, Priority.ALWAYS); add(node, 0, 0); // create a button to hide and show the sidebar. controlButton = new Button(); controlButton.getStyleClass().add("controlPane-min"); // apply the animations when the button is pressed. controlButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent actionEvent) { toggleSlide(); } }); } public void toggleSlide() { // create an animation to hide sidebar. final Animation hideSidebar = new Transition() { { setCycleDuration(Duration.millis(100)); } protected void interpolate(double frac) { final double curHeight = expandedHeight.get() * (1.0 - frac); double translateValue = -(-expandedHeight.get() + curHeight); if (translateValue >= minY.get()) { translateValue = minY.get(); } SlidingPane.this.setTranslateY(translateValue); } }; hideSidebar.onFinishedProperty().set(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent actionEvent) { expanded.set(false); controlButton.getStyleClass().remove("controlPane-min"); controlButton.getStyleClass().add("controlPane-max"); } }); // create an animation to show a sidebar. final Animation showSidebar = new Transition() { { setCycleDuration(Duration.millis(100)); } protected void interpolate(double frac) { final double curHeight = minY.get() * frac; double translateValue = minY.get() - curHeight; SlidingPane.this.setTranslateY(translateValue); } }; showSidebar.onFinishedProperty().set(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent actionEvent) { expanded.set(true); controlButton.getStyleClass().add("controlPane-min"); controlButton.getStyleClass().remove("controlPane-max"); } }); if (showSidebar.statusProperty().get() == Animation.Status.STOPPED && hideSidebar.statusProperty().get() == Animation.Status.STOPPED) { if (expanded.get()) { hideSidebar.play(); } else { expanded.set(true); showSidebar.play(); } } } public boolean isExpanded() { return expanded.get(); } }