[WIP] CFV Refactor
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / provisional / tmf / ui / views / timegraph2 / swtjfx / examples / ExampleMouseDrag2.java
1 package org.eclipse.tracecompass.internal.provisional.tmf.ui.views.timegraph2.swtjfx.examples;
2
3 import java.util.Arrays;
4 import java.util.HashSet;
5 import java.util.Random;
6 import java.util.Set;
7
8 import org.eclipse.jdt.annotation.Nullable;
9
10 import javafx.application.Application;
11 import javafx.event.EventHandler;
12 import javafx.scene.Node;
13 import javafx.scene.Scene;
14 import javafx.scene.control.Label;
15 import javafx.scene.image.Image;
16 import javafx.scene.image.ImageView;
17 import javafx.scene.input.MouseEvent;
18 import javafx.scene.layout.Pane;
19 import javafx.scene.layout.Region;
20 import javafx.scene.paint.Color;
21 import javafx.scene.shape.Rectangle;
22 import javafx.scene.shape.StrokeLineCap;
23 import javafx.stage.Stage;
24
25 public class ExampleMouseDrag2 extends Application {
26
27 // public static Image image = new Image("http://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Siberischer_tiger_de_edit02.jpg/320px-Siberischer_tiger_de_edit02.jpg");
28 public Image image = new Image("file:///home/alexandre/Desktop/tiger.jpg");
29 // public Image image = new Image( getClass().getResource( "/home/alexandre/Desktop/tiger.jpg").toExternalForm());
30
31 SelectionModel selectionModel = new SelectionModel();
32
33 DragMouseGestures dragMouseGestures = new DragMouseGestures();
34
35 static Random rnd = new Random();
36
37 @Override
38 public void start(@Nullable Stage primaryStage) {
39 if (primaryStage == null) {
40 return;
41 }
42
43 Pane pane = new Pane();
44 pane.setStyle("-fx-background-color:white");
45
46 new RubberBandSelection( pane);
47
48 double width = 200;
49 double height = 160;
50
51 double padding = 20;
52 for( int row=0; row < 4; row++) {
53 for( int col=0; col < 4; col++) {
54
55 Selectable selectable = new Selectable( width, height);
56 selectable.relocate( padding * (col+1) + width * col, padding * (row + 1) + height * row);
57
58 pane.getChildren().add(selectable);
59
60 dragMouseGestures.makeDraggable(selectable);
61
62 }
63 }
64
65 Label infoLabel = new Label( "Drag on scene for Rubberband Selection. Shift+Click to add to selection, CTRL+Click to toggle selection. Drag selected nodes for multi-dragging.");
66 pane.getChildren().add( infoLabel);
67
68 Scene scene = new Scene( pane, 1600, 900);
69 scene.getStylesheets().add( getClass().getResource("application.css").toExternalForm());
70
71 primaryStage.setScene( scene);
72 primaryStage.show();
73
74
75
76 }
77
78 private class Selectable extends Region {
79
80 ImageView view;
81
82 public Selectable( double width, double height) {
83
84 view = new ImageView( image);
85 view.setFitWidth(width);
86 view.setFitHeight(height);
87
88 getChildren().add( view);
89
90 this.setPrefSize(width, height);
91 }
92
93 }
94
95 private class SelectionModel {
96
97 Set<Node> selection = new HashSet<>();
98
99 public void add( Node node) {
100
101 if( !node.getStyleClass().contains("highlight")) {
102 node.getStyleClass().add( "highlight");
103 }
104
105 selection.add( node);
106 }
107
108 public void remove( Node node) {
109 node.getStyleClass().remove( "highlight");
110 selection.remove( node);
111 }
112
113 public void clear() {
114
115 while( !selection.isEmpty()) {
116 remove( selection.iterator().next());
117 }
118
119 }
120
121 public boolean contains( Node node) {
122 return selection.contains(node);
123 }
124
125 // public int size() {
126 // return selection.size();
127 // }
128
129 public void log() {
130 System.out.println( "Items in model: " + Arrays.asList( selection.toArray()));
131 }
132
133 }
134
135 private class DragMouseGestures {
136
137 final DragContext dragContext = new DragContext();
138
139 private boolean enabled = false;
140
141 public void makeDraggable(final Node node) {
142
143 node.setOnMousePressed(onMousePressedEventHandler);
144 node.setOnMouseDragged(onMouseDraggedEventHandler);
145 node.setOnMouseReleased(onMouseReleasedEventHandler);
146
147 }
148
149 EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {
150
151 @Override
152 public void handle(MouseEvent event) {
153
154 // don't do anything if the user is in the process of adding to the selection model
155 if( event.isControlDown() || event.isShiftDown()) {
156 return;
157 }
158
159 Node node = (Node) event.getSource();
160
161 dragContext.x = node.getTranslateX() - event.getSceneX();
162 dragContext.y = node.getTranslateY() - event.getSceneY();
163
164 // clear the model if the current node isn't in the selection => new selection
165 if( !selectionModel.contains(node)) {
166 selectionModel.clear();
167 selectionModel.add( node);
168 }
169
170 // flag that the mouse released handler should consume the event, so it won't bubble up to the pane which has a rubberband selection mouse released handler
171 enabled = true;
172
173 // prevent rubberband selection handler
174 event.consume();
175 }
176 };
177
178 EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
179
180 @Override
181 public void handle(MouseEvent event) {
182
183 if( !enabled) {
184 return;
185 }
186
187 // all in selection
188 for( Node node: selectionModel.selection) {
189 node.setTranslateX( dragContext.x + event.getSceneX());
190 node.setTranslateY( dragContext.y + event.getSceneY());
191 }
192
193 }
194 };
195
196 EventHandler<MouseEvent> onMouseReleasedEventHandler = new EventHandler<MouseEvent>() {
197
198 @Override
199 public void handle(MouseEvent event) {
200
201 // prevent rubberband selection handler
202 if( enabled) {
203
204 // set node's layout position to current position,remove translate coordinates
205 for( Node node: selectionModel.selection) {
206 fixPosition(node);
207 }
208
209 enabled = false;
210
211 event.consume();
212 }
213 }
214 };
215
216 /**
217 * Set node's layout position to current position, remove translate coordinates.
218 * @param node
219 */
220 private void fixPosition( Node node) {
221
222 double x = node.getTranslateX();
223 double y = node.getTranslateY();
224
225 node.relocate(node.getLayoutX() + x, node.getLayoutY() + y);
226
227 node.setTranslateX(0);
228 node.setTranslateY(0);
229
230 }
231
232 class DragContext {
233
234 double x;
235 double y;
236
237 }
238
239 }
240
241 private class RubberBandSelection {
242
243 final DragContext dragContext = new DragContext();
244 final Rectangle rect;
245
246 Pane group;
247 boolean enabled = false;
248
249 public RubberBandSelection( Pane group) {
250
251 this.group = group;
252
253 rect = new Rectangle( 0,0,0,0);
254 rect.setStroke(Color.BLUE);
255 rect.setStrokeWidth(1);
256 rect.setStrokeLineCap(StrokeLineCap.ROUND);
257 rect.setFill(Color.LIGHTBLUE.deriveColor(0, 1.2, 1, 0.6));
258
259 group.addEventHandler(MouseEvent.MOUSE_PRESSED, onMousePressedEventHandler);
260 group.addEventHandler(MouseEvent.MOUSE_DRAGGED, onMouseDraggedEventHandler);
261 group.addEventHandler(MouseEvent.MOUSE_RELEASED, onMouseReleasedEventHandler);
262
263 }
264
265 EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {
266
267 @Override
268 public void handle(MouseEvent event) {
269
270 // simple flag to prevent multiple handling of this event or we'd get an exception because rect is already on the scene
271 // eg if you drag with left mouse button and while doing that click the right mouse button
272 if( enabled) {
273 return;
274 }
275
276 dragContext.mouseAnchorX = event.getSceneX();
277 dragContext.mouseAnchorY = event.getSceneY();
278
279 rect.setX(dragContext.mouseAnchorX);
280 rect.setY(dragContext.mouseAnchorY);
281 rect.setWidth(0);
282 rect.setHeight(0);
283
284 group.getChildren().add( rect);
285
286 event.consume();
287
288 enabled = true;
289 }
290 };
291
292 EventHandler<MouseEvent> onMouseReleasedEventHandler = new EventHandler<MouseEvent>() {
293
294 @Override
295 public void handle(MouseEvent event) {
296
297 if( !event.isShiftDown() && !event.isControlDown()) {
298 selectionModel.clear();
299 }
300
301 for( Node node: group.getChildren()) {
302
303 if( node instanceof Selectable) {
304 if( node.getBoundsInParent().intersects( rect.getBoundsInParent())) {
305
306 if( event.isShiftDown()) {
307
308 selectionModel.add( node);
309
310 } else if( event.isControlDown()) {
311
312 if( selectionModel.contains( node)) {
313 selectionModel.remove( node);
314 } else {
315 selectionModel.add( node);
316 }
317 } else {
318 selectionModel.add( node);
319 }
320
321 }
322 }
323
324 }
325
326 selectionModel.log();
327
328 rect.setX(0);
329 rect.setY(0);
330 rect.setWidth(0);
331 rect.setHeight(0);
332
333 group.getChildren().remove( rect);
334
335 event.consume();
336
337 enabled = false;
338 }
339 };
340
341 EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
342
343 @Override
344 public void handle(MouseEvent event) {
345
346 double offsetX = event.getSceneX() - dragContext.mouseAnchorX;
347 double offsetY = event.getSceneY() - dragContext.mouseAnchorY;
348
349 if( offsetX > 0) {
350 rect.setWidth( offsetX);
351 } else {
352 rect.setX(event.getSceneX());
353 rect.setWidth(dragContext.mouseAnchorX - rect.getX());
354 }
355
356 if( offsetY > 0) {
357 rect.setHeight( offsetY);
358 } else {
359 rect.setY(event.getSceneY());
360 rect.setHeight(dragContext.mouseAnchorY - rect.getY());
361 }
362
363 event.consume();
364
365 }
366 };
367
368 private final class DragContext {
369
370 public double mouseAnchorX;
371 public double mouseAnchorY;
372
373
374 }
375 }
376
377
378 public static void main(String[] args) {
379 launch(args);
380 }
381
382 }
This page took 0.040778 seconds and 5 git commands to generate.