/**
* Get more info at : www.jrebirth.org .
* Copyright JRebirth.org © 2011-2013
* Contact : sebastien.bordes@jrebirth.org
*
* Licensed 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 org.jrebirth.af.presentation.ui.image;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javafx.animation.Animation;
import javafx.animation.FadeTransition;
import javafx.animation.FadeTransitionBuilder;
import javafx.animation.ParallelTransition;
import javafx.animation.ParallelTransitionBuilder;
import javafx.animation.PauseTransitionBuilder;
import javafx.animation.SequentialTransitionBuilder;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.ImageViewBuilder;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.RectangleBuilder;
import javafx.util.Duration;
import org.jrebirth.af.api.exception.CoreException;
import org.jrebirth.af.core.resource.Resources;
import org.jrebirth.af.core.resource.image.RelImage;
import org.jrebirth.af.presentation.ui.base.AbstractSlideView;
import org.jrebirth.presentation.model.AnimationType;
/**
*
* The class <strong>ImageSlideView</strong>.
*
* @author Sébastien Bordes
*
*/
public final class ImageSlideView extends
AbstractSlideView<ImageSlideModel, StackPane, ImageSlideController> {
/**
* The <code>RANDOM</code> field is used to build a random integer.
*/
private static final Random RANDOM = new Random();
/** The tile transition. */
private Animation tileTransition;
/** The fade transition. */
private Animation fadeTransition;
/** The image to display. */
private Image image;
/** The number of tiles per row and column. */
private int tilePerRow = 50;
private Label slideLabel;
/**
* Default Constructor.
*
* @param model the splash view model
*
* @throws CoreException if build fails
*/
public ImageSlideView(final ImageSlideModel model) throws CoreException {
super(model);
}
/**
* {@inheritDoc}
*/
@Override
protected void initView() {
getRootNode().getStyleClass().add("ImageSlide");
if (getModel().getSlide().getStyle() != null) {
getRootNode().getStyleClass().add(getModel().getSlide().getStyle());
}
this.image = Resources.create(new RelImage(getModel().getImage())).get();
if (getModel().getSlide().getShowAnimation() == null ||
!"TileIn".equalsIgnoreCase(getModel().getSlide().getShowAnimation().value())
&& !"TileIn60k".equalsIgnoreCase(getModel().getSlide().getShowAnimation().value())) {
getRootNode().getChildren().add(ImageViewBuilder.create()
.image(this.image)
.layoutX(0).layoutY(0)
.fitWidth(this.image.getWidth()).fitHeight(this.image.getHeight())
.build());
// getRootNode().setOpacity(0);
}
if (getModel().getSlide().getShowAnimation() != null && AnimationType.TILE_IN == getModel().getSlide().getShowAnimation()) {
this.tilePerRow = 5;
} else if (getModel().getSlide().getShowAnimation() != null && AnimationType.TILE_IN_60_K == getModel().getSlide().getShowAnimation()) {
this.tilePerRow = 50;
}
getTileTransition();
getFadeTransition();
if (getModel().getTitle() != null) {
this.slideLabel = new Label();
this.slideLabel.setPrefSize(1200, 80);
this.slideLabel.setAlignment(Pos.CENTER);
this.slideLabel.getStyleClass().add("ImageTitle");
this.slideLabel.setText(getModel().getTitle());
getRootNode().getChildren().add(this.slideLabel);
this.slideLabel.setOpacity(0.0);
StackPane.setAlignment(this.slideLabel, Pos.BOTTOM_CENTER);
StackPane.setMargin(this.slideLabel, new Insets(0, 0, 100, 0));
}
}
/**
* Return the image node.
*
* @return the image node
*/
Image getImage() {
return this.image;
}
/**
* {@inheritDoc}
*/
@Override
public void start() {
if (getModel().getSlide().getShowAnimation() != null && AnimationType.TILE_IN == getModel().getSlide().getShowAnimation()) {
for (final Node n : getRootNode().getChildren()) {
n.setOpacity(0.0);
}
this.tilePerRow = 5;
final ParallelTransition st = ParallelTransitionBuilder.create().children(
getTileTransition(),
getSlideLabelTransition(Duration.millis(1200)))
.build();
st.play();
} else if (getModel().getSlide().getShowAnimation() != null && AnimationType.TILE_IN_60_K == getModel().getSlide().getShowAnimation()) {
for (final Node n : getRootNode().getChildren()) {
n.setOpacity(0.0);
}
this.tilePerRow = 50;
final ParallelTransition st = ParallelTransitionBuilder.create().children(
getTileTransition(),
getSlideLabelTransition(Duration.millis(1200)))
.build();
st.play();
} else {
getSlideLabelTransition(Duration.millis(0)).play();
}
}
/**
* TODO To complete.
*
* @return
*/
private FadeTransition getSlideLabelTransition(Duration gap) {
return FadeTransitionBuilder.create()
.node(this.slideLabel)
.delay(gap)
.duration(Duration.millis(1200))
.fromValue(0).toValue(1)
.build();
}
/**
* @return Returns the fadeTransition.
*/
Animation getFadeTransition() {
if (this.fadeTransition == null) {
this.fadeTransition = FadeTransitionBuilder.create()
.node(getRootNode())
.fromValue(0).toValue(1)
.duration(Duration.seconds(1))
.build();
}
return this.fadeTransition;
}
/**
* @return Returns the tileTransition.
*/
Animation getTileTransition() {
if (this.tileTransition == null) {
// Map<Point2D, ImageView> tiles = new HashMap<>();
final double width = getImage().getWidth();
final double height = getImage().getHeight();
final double tileWidth = width / this.tilePerRow;
final double tileHeight = height / this.tilePerRow;
final List<Animation> fades = new ArrayList<>();
for (double x = 0; x < width; x += tileWidth) {
for (double y = 0; y < height; y += tileHeight) {
final ImageView iv = ImageViewBuilder
.create()
.image(getImage())
.clip(RectangleBuilder.create().x(x).y(y)
.width(tileWidth).height(tileHeight)
.build()).opacity(0.0).layoutX(x)
.layoutY(y).build();
getRootNode().getChildren().add(iv);
fades.add(SequentialTransitionBuilder
.create()
.children(
PauseTransitionBuilder.create()
.duration(getRandomDuration())
.build(),
FadeTransitionBuilder.create().node(iv)
.fromValue(0.0).toValue(1.0)
.duration(getRandomDuration())
.build()).build());
}
}
this.tileTransition = ParallelTransitionBuilder.create()
.children(fades).build();
this.tileTransition.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(final ActionEvent arg0) {
for (final Node n : getRootNode().getChildren()) {
n.setOpacity(1.0);
}
}
});
}
return this.tileTransition;
}
/**
* Get a random duration from the range [300-1200].
*
* @return a duration object
*/
private Duration getRandomDuration() {
return Duration.millis(RANDOM.nextInt(Integer.MAX_VALUE) % 900 + 300);
}
/**
* {@inheritDoc}
*/
@Override
public void reload() {
// Nothing to do yet
}
/**
* {@inheritDoc}
*/
@Override
public void hide() {
// Nothing to do yet
}
}