/* * PresenterImpl * Copyright 2011 (C) Mr LoNee - (Laurent NICOLAS) - www.mrlonee.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. */ package mrlonee.presenter.impl; import java.util.ArrayList; import java.util.List; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; import javafx.animation.TimelineBuilder; import javafx.event.EventHandler; import javafx.geometry.Bounds; import javafx.scene.Group; import javafx.scene.Node; import javafx.scene.input.MouseEvent; import javafx.scene.paint.Color; import javafx.scene.paint.RadialGradientBuilder; import javafx.scene.paint.Stop; import javafx.scene.paint.StopBuilder; import javafx.scene.shape.Circle; import javafx.scene.shape.CircleBuilder; import javafx.util.Duration; import mrlonee.presenter.Presenter; public class PresenterImpl implements Presenter { protected List<Node> toPresentList = new ArrayList<Node>(); protected List<Node> thumbList = new ArrayList<Node>(); protected Group root = new Group(); protected Group thumb = new Group(); protected Node thumbSelection; protected int interationCounter = -1; protected Node currentPresentedNode = null; protected double screenX = 0; protected double screenY = 0; protected double screenWidth = 0.0d; protected double screenHeight = 0.0d; protected double speedInPixelPerSecond = 100; protected Circle target = CircleBuilder.create().radius(5) .fill(Color.BLACK).build(); public PresenterImpl() { this.thumbSelection = CircleBuilder.create().radius(11) .fill(Color.TRANSPARENT).strokeWidth(2).stroke(Color.BLUE) .build(); this.thumbSelection.setVisible(false); this.thumb.getChildren().add(this.thumbSelection); } @Override public void addElementToPresent(final Node node) { // Manage double click node.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(final MouseEvent mouseEvent) { if (mouseEvent.getClickCount() == 2) { presentElement(node); } } }); this.toPresentList.add(node); this.root.getChildren().add(node); this.thumb.getChildren().add(this.createThumb(node)); } @Override public Group getRootNode() { return this.root; } @Override public void presentNextElement() { int nextIndex = interationCounter + 1; if (nextIndex == this.toPresentList.size()) { nextIndex = 0; } this.presentElement(nextIndex); } @Override public void presentPreviousElement() { int previousIndex = interationCounter - 1; if (previousIndex < 0) { previousIndex = this.toPresentList.size() - 1; } this.presentElement(previousIndex); } @Override public void presentElement(final Node node) { int index = this.toPresentList.indexOf(node); this.presentElement(index); } @Override public void setScreenSize(double width, double height) { this.screenWidth = width; this.screenHeight = height; this.centerScreenOnCurrentBound(); } // @Override // public void setScreenLocation(double x, double y) { // this.screenX = x; // this.screenY= y; // // this.centerScreenOnCurrentBound(); // } @Override public Group getThumbNode() { return this.thumb; } protected void presentElement(int elementIndex) { if (interationCounter != elementIndex) { interationCounter = elementIndex; Node node = this.toPresentList.get(interationCounter); this.playTransitionToNode(node); this.currentPresentedNode = node; } } protected void playTransitionToNode(final Node node) { double toRotate = -node.getRotate(); if (toRotate == 360) toRotate = 0; // calculate the scale we will need to see the node in full screen double toScale = this.screenWidth / Math.max(node.getBoundsInParent().getWidth() + 30, node .getBoundsInParent().getHeight() + 30); double prevScale = this.root.getScaleX(); double prevRot = this.root.getRotate(); this.root.setRotate(toRotate); this.root.setScaleX(toScale); this.root.setScaleY(toScale); Bounds nodeBoundsInScene = this.root.localToScene(node .getBoundsInParent()); double toX = this.root.getTranslateX() + this.screenWidth / 2.0 - (nodeBoundsInScene.getMinX() + (nodeBoundsInScene.getWidth() / 2.0)); double toY = this.root.getTranslateY() + this.screenHeight / 2.0 - (nodeBoundsInScene.getMinY() + (nodeBoundsInScene.getHeight() / 2.0)); this.root.setScaleX(prevScale); this.root.setScaleY(prevScale); this.root.setRotate(prevRot); Timeline animationTransition = TimelineBuilder .create() .keyFrames( new KeyFrame(Duration.valueOf("600"), new KeyValue( this.root.translateXProperty(), toX), new KeyValue(this.root.translateYProperty(), toY), new KeyValue(this.root .scaleXProperty(), toScale), new KeyValue(this.root.scaleYProperty(), toScale), new KeyValue(this.root .rotateProperty(), toRotate))).build(); animationTransition.play(); selectThumb(); } protected double computeFinalScale(final Node node) { double scale = 1.0; System.err.println(scale); return scale; } protected void centerScreenOnCurrentBound() { if (this.currentPresentedNode != null) { double x = this.screenX + this.screenWidth / 2.0 - (currentPresentedNode.getBoundsInParent().getMinX() + currentPresentedNode .getBoundsInParent().getWidth() / 2.0); double y = this.screenY + this.screenHeight / 2.0 - (currentPresentedNode.getBoundsInParent().getMinY() + currentPresentedNode .getBoundsInParent().getHeight() / 2.0); this.root.setTranslateX(x); this.root.setTranslateY(y); } } protected Node createThumb(final Node node) { List<Stop> thumbStop = new ArrayList<Stop>(); thumbStop.add(StopBuilder.create().offset(0.2).color(Color.CYAN) .build()); thumbStop.add(StopBuilder.create().offset(0.8) .color(Color.CYAN.darker()).build()); thumbStop.add(StopBuilder.create().offset(1.0).color(Color.CYAN) .build()); Circle thumb = CircleBuilder .create() .radius(10) .fill(RadialGradientBuilder.create().centerX(0.3).centerY(0.3) .stops(thumbStop).build()) .translateX(30 * (this.toPresentList.size() - 1)).translateY(1) .build(); final int index = this.thumbList.size(); thumb.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(final MouseEvent paramT) { presentElement(index); } }); this.thumbList.add(thumb); return thumb; } protected void selectThumb() { thumbSelection.setVisible(true); Node thumb = this.thumbList.get(interationCounter); this.thumbSelection.translateXProperty().bind( thumb.translateXProperty()); this.thumbSelection.translateYProperty().bind( thumb.translateYProperty()); } }