X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=tmf%2Forg.lttng.scope.tmf2.views.ui%2Fsrc%2Forg%2Flttng%2Fscope%2Ftmf2%2Fviews%2Fui%2Fjfx%2Fexamples%2FZoomExample.java;fp=tmf%2Forg.lttng.scope.tmf2.views.ui%2Fsrc%2Forg%2Flttng%2Fscope%2Ftmf2%2Fviews%2Fui%2Fjfx%2Fexamples%2FZoomExample.java;h=0409003c641c65059f8f88063d64dcd98a49306d;hb=c879c4dbd44a9d1b6f5213831e98e807bb091f36;hp=0000000000000000000000000000000000000000;hpb=0b55ad30f1f5ee8ca3fd0ce5ff4c40022dff8661;p=deliverable%2Ftracecompass.git diff --git a/tmf/org.lttng.scope.tmf2.views.ui/src/org/lttng/scope/tmf2/views/ui/jfx/examples/ZoomExample.java b/tmf/org.lttng.scope.tmf2.views.ui/src/org/lttng/scope/tmf2/views/ui/jfx/examples/ZoomExample.java new file mode 100644 index 0000000000..0409003c64 --- /dev/null +++ b/tmf/org.lttng.scope.tmf2.views.ui/src/org/lttng/scope/tmf2/views/ui/jfx/examples/ZoomExample.java @@ -0,0 +1,194 @@ +package org.lttng.scope.tmf2.views.ui.jfx.examples; + +import java.net.MalformedURLException; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +import javafx.application.Application; +import javafx.geometry.Bounds; +import javafx.geometry.Point2D; +import javafx.geometry.Pos; +import javafx.scene.Group; +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.scene.canvas.Canvas; +import javafx.scene.canvas.GraphicsContext; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.SplitPane; +import javafx.scene.layout.Pane; +import javafx.scene.layout.Region; +import javafx.scene.layout.StackPane; +import javafx.scene.paint.Color; +import javafx.scene.shape.Circle; +import javafx.stage.Stage; + +@NonNullByDefault({}) +public class ZoomExample extends Application { + + public static Region createContent() { + double width = 1000; + double height = 1000; + + Canvas canvas = new Canvas(width, height); + GraphicsContext gc = canvas.getGraphicsContext2D(); + + gc.setFill(Color.LIGHTGREY); + gc.fillRect(0, 0, width, height); + + gc.setStroke(Color.BLUE); + gc.beginPath(); + + for (int i = 50; i < width; i += 50) { + gc.moveTo(i, 0); + gc.lineTo(i, height); + } + + for (int i = 50; i < height; i += 50) { + gc.moveTo(0, i); + gc.lineTo(width, i); + } + gc.stroke(); + + Pane content = new Pane( + new Circle(50, 50, 20), + new Circle(120, 90, 20, Color.RED), + new Circle(200, 70, 20, Color.GREEN) + ); + + StackPane result = new StackPane(canvas, content); + result.setAlignment(Pos.TOP_LEFT); + + class DragData { + + double startX; + double startY; + double startLayoutX; + double startLayoutY; + Node dragTarget; + } + + DragData dragData = new DragData(); + + content.setOnMousePressed(evt -> { + if (evt.getTarget() != content) { + // initiate drag gesture, if a child of content receives the + // event to prevent ScrollPane from panning. + evt.consume(); + evt.setDragDetect(true); + } + }); + + content.setOnDragDetected(evt -> { + Node n = (Node) evt.getTarget(); + if (n != content) { + // set start paremeters + while (n.getParent() != content) { + n = n.getParent(); + } + dragData.startX = evt.getX(); + dragData.startY = evt.getY(); + dragData.startLayoutX = n.getLayoutX(); + dragData.startLayoutY = n.getLayoutY(); + dragData.dragTarget = n; + n.startFullDrag(); + evt.consume(); + } + }); + + // stop dragging when mouse is released + content.setOnMouseReleased(evt -> dragData.dragTarget = null); + + content.setOnMouseDragged(evt -> { + if (dragData.dragTarget != null) { + // move dragged node + dragData.dragTarget.setLayoutX(evt.getX() + dragData.startLayoutX - dragData.startX); + dragData.dragTarget.setLayoutY(evt.getY() + dragData.startLayoutY - dragData.startY); +// Point2D p = new Point2D(evt.getX(), evt.getY()); + evt.consume(); + } + }); + + return result; + } + + @Override + public void start(Stage primaryStage) throws MalformedURLException { + Region zoomTarget = createContent(); + zoomTarget.setPrefSize(1000, 1000); + zoomTarget.setOnDragDetected(evt -> { + Node target = (Node) evt.getTarget(); + while (target != zoomTarget && target != null) { + target = target.getParent(); + } + if (target != null) { + target.startFullDrag(); + } + }); + + Group group = new Group(zoomTarget); + + // stackpane for centering the content, in case the ScrollPane viewport + // is larget than zoomTarget + StackPane content = new StackPane(group); + group.layoutBoundsProperty().addListener((observable, oldBounds, newBounds) -> { + // keep it at least as large as the content + content.setMinWidth(newBounds.getWidth()); + content.setMinHeight(newBounds.getHeight()); + }); + + ScrollPane scrollPane = new ScrollPane(content); + scrollPane.setPannable(true); + scrollPane.viewportBoundsProperty().addListener((observable, oldBounds, newBounds) -> { + // use vieport size, if not too small for zoomTarget + content.setPrefSize(newBounds.getWidth(), newBounds.getHeight()); + }); + + content.setOnScroll(evt -> { + if (evt.isControlDown()) { + evt.consume(); + + final double zoomFactor = evt.getDeltaY() > 0 ? 1.2 : 1 / 1.2; + + Bounds groupBounds = group.getLayoutBounds(); + final Bounds viewportBounds = scrollPane.getViewportBounds(); + + // calculate pixel offsets from [0, 1] range + double valX = scrollPane.getHvalue() * (groupBounds.getWidth() - viewportBounds.getWidth()); + double valY = scrollPane.getVvalue() * (groupBounds.getHeight() - viewportBounds.getHeight()); + + // convert content coordinates to zoomTarget coordinates + Point2D posInZoomTarget = zoomTarget.parentToLocal(group.parentToLocal(new Point2D(evt.getX(), evt.getY()))); + + // calculate adjustment of scroll position (pixels) + Point2D adjustment = zoomTarget.getLocalToParentTransform().deltaTransform(posInZoomTarget.multiply(zoomFactor - 1)); + + // do the resizing + zoomTarget.setScaleX(zoomFactor * zoomTarget.getScaleX()); + zoomTarget.setScaleY(zoomFactor * zoomTarget.getScaleY()); + + // refresh ScrollPane scroll positions & content bounds + scrollPane.layout(); + + // convert back to [0, 1] range + // (too large/small values are automatically corrected by ScrollPane) + groupBounds = group.getLayoutBounds(); + scrollPane.setHvalue((valX + adjustment.getX()) / (groupBounds.getWidth() - viewportBounds.getWidth())); + scrollPane.setVvalue((valY + adjustment.getY()) / (groupBounds.getHeight() - viewportBounds.getHeight())); + } + }); + + StackPane left = new StackPane(new Label("Left Menu")); + SplitPane root = new SplitPane(left, scrollPane); + + Scene scene = new Scene(root, 800, 600); + + primaryStage.setScene(scene); + primaryStage.show(); + } + + public static void main(String[] args) { + launch(args); + } + +} \ No newline at end of file