/*******************************************************************************
* Copyright (c) 2014, 2016 itemis AG and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthias Wienand (itemis AG) - initial API and implementation
*
*******************************************************************************/
package org.eclipse.gef.fx.examples.snippets;
import org.eclipse.gef.fx.examples.AbstractFxExample;
import org.eclipse.gef.fx.nodes.InfiniteCanvas;
import org.eclipse.gef.geometry.convert.fx.FX2Geometry;
import org.eclipse.gef.geometry.planar.AffineTransform;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.Affine;
import javafx.scene.transform.Transform;
public class InifinteCanvasSnippet extends AbstractFxExample {
public static void main(String[] args) {
launch();
}
private InfiniteCanvas infiniteCanvas;
public InifinteCanvasSnippet() {
super("InfiniteCanvasSnippet");
}
@Override
public Scene createScene() {
BorderPane root = new BorderPane();
infiniteCanvas = new InfiniteCanvas();
root.setCenter(infiniteCanvas);
infiniteCanvas.getContentGroup().getChildren().addAll(
rect(25, 25, 100, 50, Color.BLUE),
rect(25, 200, 25, 50, Color.BLUE),
rect(150, 100, 75, 75, Color.BLUE),
rect(-100, -100, 30, 60, Color.CYAN),
rect(75, 75, 150, 150, Color.RED));
// translate to top-left most content node
Bounds canvasBounds = infiniteCanvas.getContentBounds();
double minx = canvasBounds.getMinX();
double miny = canvasBounds.getMinY();
infiniteCanvas.setHorizontalScrollOffset(-minx);
infiniteCanvas.setVerticalScrollOffset(-miny);
infiniteCanvas.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if (MouseButton.SECONDARY.equals(event.getButton())) {
// determine pivot in content group
Group contentGroup = infiniteCanvas.getContentGroup();
Point2D contentPivot = contentGroup
.sceneToLocal(event.getSceneX(), event.getSceneY());
double zoomFactor = event.isControlDown() ? 4d / 5 : 5d / 4;
// compute zoom transformation
Affine tx = infiniteCanvas.getContentTransform();
AffineTransform at = FX2Geometry.toAffineTransform(tx);
at.concatenate(new AffineTransform()
.translate(contentPivot.getX(), contentPivot.getY())
.scale(zoomFactor, zoomFactor)
.translate(-contentPivot.getX(),
-contentPivot.getY()));
Affine affine = Transform.affine(at.getM00(), at.getM01(),
at.getM10(), at.getM11(), at.getTranslateX(),
at.getTranslateY());
infiniteCanvas.setContentTransform(affine);
}
}
});
return new Scene(root, 400, 300);
}
private Node rect(double layoutX, double layoutY, double width,
double height, Paint fill) {
final Rectangle rect = new Rectangle(width, height, fill);
rect.setLayoutX(layoutX);
rect.setLayoutY(layoutY);
// register drag listeners
final double[] initialLayout = new double[2];
final double[] initialMouse = new double[2];
rect.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
initialLayout[0] = rect.getLayoutX();
initialLayout[1] = rect.getLayoutY();
initialMouse[0] = event.getSceneX();
initialMouse[1] = event.getSceneY();
}
});
EventHandler<MouseEvent> dragHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
double dx = event.getSceneX() - initialMouse[0];
double dy = event.getSceneY() - initialMouse[1];
rect.setLayoutX(initialLayout[0] + dx);
rect.setLayoutY(initialLayout[1] + dy);
infiniteCanvas.reveal(rect);
}
};
rect.setOnMouseDragged(dragHandler);
rect.setOnMouseReleased(dragHandler);
return rect;
}
}