Import views plugins
[deliverable/tracecompass.git] / tmf / org.lttng.scope.tmf2.views.ui / src / org / lttng / scope / tmf2 / views / ui / jfx / examples / ZoomExample.java
1 package org.lttng.scope.tmf2.views.ui.jfx.examples;
2
3 import java.net.MalformedURLException;
4
5 import org.eclipse.jdt.annotation.NonNullByDefault;
6
7 import javafx.application.Application;
8 import javafx.geometry.Bounds;
9 import javafx.geometry.Point2D;
10 import javafx.geometry.Pos;
11 import javafx.scene.Group;
12 import javafx.scene.Node;
13 import javafx.scene.Scene;
14 import javafx.scene.canvas.Canvas;
15 import javafx.scene.canvas.GraphicsContext;
16 import javafx.scene.control.Label;
17 import javafx.scene.control.ScrollPane;
18 import javafx.scene.control.SplitPane;
19 import javafx.scene.layout.Pane;
20 import javafx.scene.layout.Region;
21 import javafx.scene.layout.StackPane;
22 import javafx.scene.paint.Color;
23 import javafx.scene.shape.Circle;
24 import javafx.stage.Stage;
25
26 @NonNullByDefault({})
27 public class ZoomExample extends Application {
28
29 public static Region createContent() {
30 double width = 1000;
31 double height = 1000;
32
33 Canvas canvas = new Canvas(width, height);
34 GraphicsContext gc = canvas.getGraphicsContext2D();
35
36 gc.setFill(Color.LIGHTGREY);
37 gc.fillRect(0, 0, width, height);
38
39 gc.setStroke(Color.BLUE);
40 gc.beginPath();
41
42 for (int i = 50; i < width; i += 50) {
43 gc.moveTo(i, 0);
44 gc.lineTo(i, height);
45 }
46
47 for (int i = 50; i < height; i += 50) {
48 gc.moveTo(0, i);
49 gc.lineTo(width, i);
50 }
51 gc.stroke();
52
53 Pane content = new Pane(
54 new Circle(50, 50, 20),
55 new Circle(120, 90, 20, Color.RED),
56 new Circle(200, 70, 20, Color.GREEN)
57 );
58
59 StackPane result = new StackPane(canvas, content);
60 result.setAlignment(Pos.TOP_LEFT);
61
62 class DragData {
63
64 double startX;
65 double startY;
66 double startLayoutX;
67 double startLayoutY;
68 Node dragTarget;
69 }
70
71 DragData dragData = new DragData();
72
73 content.setOnMousePressed(evt -> {
74 if (evt.getTarget() != content) {
75 // initiate drag gesture, if a child of content receives the
76 // event to prevent ScrollPane from panning.
77 evt.consume();
78 evt.setDragDetect(true);
79 }
80 });
81
82 content.setOnDragDetected(evt -> {
83 Node n = (Node) evt.getTarget();
84 if (n != content) {
85 // set start paremeters
86 while (n.getParent() != content) {
87 n = n.getParent();
88 }
89 dragData.startX = evt.getX();
90 dragData.startY = evt.getY();
91 dragData.startLayoutX = n.getLayoutX();
92 dragData.startLayoutY = n.getLayoutY();
93 dragData.dragTarget = n;
94 n.startFullDrag();
95 evt.consume();
96 }
97 });
98
99 // stop dragging when mouse is released
100 content.setOnMouseReleased(evt -> dragData.dragTarget = null);
101
102 content.setOnMouseDragged(evt -> {
103 if (dragData.dragTarget != null) {
104 // move dragged node
105 dragData.dragTarget.setLayoutX(evt.getX() + dragData.startLayoutX - dragData.startX);
106 dragData.dragTarget.setLayoutY(evt.getY() + dragData.startLayoutY - dragData.startY);
107 // Point2D p = new Point2D(evt.getX(), evt.getY());
108 evt.consume();
109 }
110 });
111
112 return result;
113 }
114
115 @Override
116 public void start(Stage primaryStage) throws MalformedURLException {
117 Region zoomTarget = createContent();
118 zoomTarget.setPrefSize(1000, 1000);
119 zoomTarget.setOnDragDetected(evt -> {
120 Node target = (Node) evt.getTarget();
121 while (target != zoomTarget && target != null) {
122 target = target.getParent();
123 }
124 if (target != null) {
125 target.startFullDrag();
126 }
127 });
128
129 Group group = new Group(zoomTarget);
130
131 // stackpane for centering the content, in case the ScrollPane viewport
132 // is larget than zoomTarget
133 StackPane content = new StackPane(group);
134 group.layoutBoundsProperty().addListener((observable, oldBounds, newBounds) -> {
135 // keep it at least as large as the content
136 content.setMinWidth(newBounds.getWidth());
137 content.setMinHeight(newBounds.getHeight());
138 });
139
140 ScrollPane scrollPane = new ScrollPane(content);
141 scrollPane.setPannable(true);
142 scrollPane.viewportBoundsProperty().addListener((observable, oldBounds, newBounds) -> {
143 // use vieport size, if not too small for zoomTarget
144 content.setPrefSize(newBounds.getWidth(), newBounds.getHeight());
145 });
146
147 content.setOnScroll(evt -> {
148 if (evt.isControlDown()) {
149 evt.consume();
150
151 final double zoomFactor = evt.getDeltaY() > 0 ? 1.2 : 1 / 1.2;
152
153 Bounds groupBounds = group.getLayoutBounds();
154 final Bounds viewportBounds = scrollPane.getViewportBounds();
155
156 // calculate pixel offsets from [0, 1] range
157 double valX = scrollPane.getHvalue() * (groupBounds.getWidth() - viewportBounds.getWidth());
158 double valY = scrollPane.getVvalue() * (groupBounds.getHeight() - viewportBounds.getHeight());
159
160 // convert content coordinates to zoomTarget coordinates
161 Point2D posInZoomTarget = zoomTarget.parentToLocal(group.parentToLocal(new Point2D(evt.getX(), evt.getY())));
162
163 // calculate adjustment of scroll position (pixels)
164 Point2D adjustment = zoomTarget.getLocalToParentTransform().deltaTransform(posInZoomTarget.multiply(zoomFactor - 1));
165
166 // do the resizing
167 zoomTarget.setScaleX(zoomFactor * zoomTarget.getScaleX());
168 zoomTarget.setScaleY(zoomFactor * zoomTarget.getScaleY());
169
170 // refresh ScrollPane scroll positions & content bounds
171 scrollPane.layout();
172
173 // convert back to [0, 1] range
174 // (too large/small values are automatically corrected by ScrollPane)
175 groupBounds = group.getLayoutBounds();
176 scrollPane.setHvalue((valX + adjustment.getX()) / (groupBounds.getWidth() - viewportBounds.getWidth()));
177 scrollPane.setVvalue((valY + adjustment.getY()) / (groupBounds.getHeight() - viewportBounds.getHeight()));
178 }
179 });
180
181 StackPane left = new StackPane(new Label("Left Menu"));
182 SplitPane root = new SplitPane(left, scrollPane);
183
184 Scene scene = new Scene(root, 800, 600);
185
186 primaryStage.setScene(scene);
187 primaryStage.show();
188 }
189
190 public static void main(String[] args) {
191 launch(args);
192 }
193
194 }
This page took 0.036068 seconds and 5 git commands to generate.