1 /*
   2  * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package test.javafx.scene.input;
  27 
  28 import javafx.event.EventHandler;
  29 import javafx.event.EventType;
  30 import javafx.scene.Group;
  31 import javafx.scene.Node;
  32 import javafx.scene.Scene;
  33 import javafx.scene.shape.Rectangle;
  34 import javafx.stage.Stage;
  35 
  36 import test.com.sun.javafx.test.MouseEventGenerator;
  37 import javafx.event.Event;
  38 import javafx.geometry.Point3D;
  39 import javafx.scene.input.MouseButton;
  40 import javafx.scene.input.MouseDragEvent;
  41 import javafx.scene.input.MouseEvent;
  42 import javafx.scene.input.PickResult;
  43 
  44 import static org.junit.Assert.*;
  45 import org.junit.Test;
  46 
  47 public class MouseDragEventTest {
  48 
  49     @Test public void testShortConstructor() {
  50         Rectangle node = new Rectangle();
  51         node.setTranslateX(3);
  52         node.setTranslateY(2);
  53         node.setTranslateZ(50);
  54         Rectangle gsrc = new Rectangle();
  55 
  56         PickResult pickRes = new PickResult(node, new Point3D(15, 25, 100), 33);
  57 
  58         MouseDragEvent e = new MouseDragEvent(MouseDragEvent.MOUSE_DRAG_OVER,
  59                 10, 20, 30, 40, MouseButton.MIDDLE, 3,
  60                 true, false, false, true,
  61                 false, true, false,
  62                 true, false, pickRes, gsrc);
  63 
  64         assertSame(MouseDragEvent.MOUSE_DRAG_OVER, e.getEventType());
  65         assertEquals(18, e.getX(), 10e-20);
  66         assertEquals(27, e.getY(), 10e-20);
  67         assertEquals(150, e.getZ(), 10e-20);
  68         assertEquals(10, e.getSceneX(), 10e-20);
  69         assertEquals(20, e.getSceneY(), 10e-20);
  70         assertEquals(30, e.getScreenX(), 10e-20);
  71         assertEquals(40, e.getScreenY(), 10e-20);
  72         assertSame(MouseButton.MIDDLE, e.getButton());
  73         assertEquals(3, e.getClickCount());
  74         assertTrue(e.isShiftDown());
  75         assertFalse(e.isControlDown());
  76         assertFalse(e.isAltDown());
  77         assertTrue(e.isMetaDown());
  78         assertFalse(e.isPrimaryButtonDown());
  79         assertTrue(e.isMiddleButtonDown());
  80         assertFalse(e.isSecondaryButtonDown());
  81         assertTrue(e.isSynthesized());
  82         assertFalse(e.isPopupTrigger());
  83         assertSame(gsrc, e.getGestureSource());
  84         assertFalse(e.isConsumed());
  85         assertSame(pickRes, e.getPickResult());
  86         assertSame(Event.NULL_SOURCE_TARGET, e.getSource());
  87         assertSame(Event.NULL_SOURCE_TARGET, e.getTarget());
  88 
  89         e = new MouseDragEvent(MouseDragEvent.MOUSE_DRAG_OVER,
  90                 10, 20, 30, 40, MouseButton.MIDDLE, 3,
  91                 false, true, true, false,
  92                 true, false, true,
  93                 false, true, pickRes, gsrc);
  94 
  95         assertFalse(e.isShiftDown());
  96         assertTrue(e.isControlDown());
  97         assertTrue(e.isAltDown());
  98         assertFalse(e.isMetaDown());
  99         assertTrue(e.isPrimaryButtonDown());
 100         assertFalse(e.isMiddleButtonDown());
 101         assertTrue(e.isSecondaryButtonDown());
 102         assertFalse(e.isSynthesized());
 103         assertTrue(e.isPopupTrigger());
 104     }
 105 
 106     @Test public void testShortConstructorWithoutPickResult() {
 107         MouseDragEvent e = new MouseDragEvent(MouseDragEvent.MOUSE_DRAG_OVER,
 108                 10, 20, 30, 40, MouseButton.MIDDLE, 3,
 109                 true, false, false, true,
 110                 false, true, false,
 111                 true, false, null, new Rectangle());
 112         assertEquals(10, e.getX(), 10e-20);
 113         assertEquals(20, e.getY(), 10e-20);
 114         assertEquals(0, e.getZ(), 10e-20);
 115         assertEquals(10, e.getSceneX(), 10e-20);
 116         assertEquals(20, e.getSceneY(), 10e-20);
 117         assertEquals(30, e.getScreenX(), 10e-20);
 118         assertEquals(40, e.getScreenY(), 10e-20);
 119         assertNotNull(e.getPickResult());
 120         assertNotNull(e.getPickResult().getIntersectedPoint());
 121         assertEquals(10, e.getPickResult().getIntersectedPoint().getX(), 10e-20);
 122         assertEquals(20, e.getPickResult().getIntersectedPoint().getY(), 10e-20);
 123         assertEquals(0, e.getPickResult().getIntersectedPoint().getZ(), 10e-20);
 124         assertSame(Event.NULL_SOURCE_TARGET, e.getSource());
 125         assertSame(Event.NULL_SOURCE_TARGET, e.getTarget());
 126     }
 127 
 128     @Test public void testLongConstructor() {
 129         Rectangle n1 = new Rectangle(10, 10);
 130         Rectangle n2 = new Rectangle(10, 10);
 131         Rectangle node = new Rectangle();
 132         node.setTranslateX(3);
 133         node.setTranslateY(2);
 134         node.setTranslateZ(50);
 135         Rectangle gsrc = new Rectangle();
 136 
 137         PickResult pickRes = new PickResult(node, new Point3D(15, 25, 100), 33);
 138 
 139         MouseDragEvent e = new MouseDragEvent(n1, n2, MouseDragEvent.MOUSE_DRAG_OVER,
 140                 10, 20, 30, 40, MouseButton.MIDDLE, 3,
 141                 true, false, false, true,
 142                 false, true, false,
 143                 true, false, pickRes, gsrc);
 144 
 145         assertSame(MouseDragEvent.MOUSE_DRAG_OVER, e.getEventType());
 146         assertEquals(18, e.getX(), 10e-20);
 147         assertEquals(27, e.getY(), 10e-20);
 148         assertEquals(150, e.getZ(), 10e-20);
 149         assertEquals(10, e.getSceneX(), 10e-20);
 150         assertEquals(20, e.getSceneY(), 10e-20);
 151         assertEquals(30, e.getScreenX(), 10e-20);
 152         assertEquals(40, e.getScreenY(), 10e-20);
 153         assertSame(MouseButton.MIDDLE, e.getButton());
 154         assertEquals(3, e.getClickCount());
 155         assertTrue(e.isShiftDown());
 156         assertFalse(e.isControlDown());
 157         assertFalse(e.isAltDown());
 158         assertTrue(e.isMetaDown());
 159         assertFalse(e.isPrimaryButtonDown());
 160         assertTrue(e.isMiddleButtonDown());
 161         assertFalse(e.isSecondaryButtonDown());
 162         assertTrue(e.isSynthesized());
 163         assertFalse(e.isPopupTrigger());
 164         assertSame(gsrc, e.getGestureSource());
 165         assertFalse(e.isConsumed());
 166         assertSame(pickRes, e.getPickResult());
 167         assertSame(n1, e.getSource());
 168         assertSame(n2, e.getTarget());
 169 
 170         e = new MouseDragEvent(n1, n2, MouseDragEvent.MOUSE_DRAG_OVER,
 171                 10, 20, 30, 40, MouseButton.MIDDLE, 3,
 172                 false, true, true, false,
 173                 true, false, true,
 174                 false, true, pickRes, gsrc);
 175 
 176         assertSame(n1, e.getSource());
 177         assertSame(n2, e.getTarget());
 178         assertFalse(e.isShiftDown());
 179         assertTrue(e.isControlDown());
 180         assertTrue(e.isAltDown());
 181         assertFalse(e.isMetaDown());
 182         assertTrue(e.isPrimaryButtonDown());
 183         assertFalse(e.isMiddleButtonDown());
 184         assertTrue(e.isSecondaryButtonDown());
 185         assertFalse(e.isSynthesized());
 186         assertTrue(e.isPopupTrigger());
 187     }
 188 
 189 
 190     @Test public void testLongConstructorWithoutPickResult() {
 191         Rectangle n1 = new Rectangle(10, 10);
 192         Rectangle n2 = new Rectangle(10, 10);
 193         MouseDragEvent e = new MouseDragEvent(n1, n2, MouseDragEvent.MOUSE_DRAG_OVER,
 194                 10, 20, 30, 40, MouseButton.MIDDLE, 3,
 195                 true, false, false, true,
 196                 false, true, false,
 197                 true, false, null, new Rectangle());
 198         assertSame(n1, e.getSource());
 199         assertSame(n2, e.getTarget());
 200         assertEquals(10, e.getX(), 10e-20);
 201         assertEquals(20, e.getY(), 10e-20);
 202         assertEquals(0, e.getZ(), 10e-20);
 203         assertEquals(10, e.getSceneX(), 10e-20);
 204         assertEquals(20, e.getSceneY(), 10e-20);
 205         assertEquals(30, e.getScreenX(), 10e-20);
 206         assertEquals(40, e.getScreenY(), 10e-20);
 207         assertNotNull(e.getPickResult());
 208         assertNotNull(e.getPickResult().getIntersectedPoint());
 209         assertEquals(10, e.getPickResult().getIntersectedPoint().getX(), 10e-20);
 210         assertEquals(20, e.getPickResult().getIntersectedPoint().getY(), 10e-20);
 211         assertEquals(0, e.getPickResult().getIntersectedPoint().getZ(), 10e-20);
 212     }
 213 
 214     @Test
 215     public void fullPDRShouldNotStartAutomatically() {
 216         World w = new World(false, false);
 217 
 218         // Press and move
 219         w.event(MouseEvent.MOUSE_PRESSED, 400, 150);
 220         w.event(MouseEvent.MOUSE_PRESSED, 410, 150);
 221         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 222         w.event(MouseEvent.MOUSE_DRAGGED, 150, 150);
 223         w.event(MouseEvent.MOUSE_RELEASED, 160, 150);
 224 
 225         w.getScene().getAny().assertNotCalled();
 226         w.getSource().getAny().assertNotCalled();
 227         w.getTarget().getAny().assertNotCalled();
 228 
 229         w.clear();
 230     }
 231 
 232     @Test
 233     public void activatingFullPDRShouldCauseEnteredEvents() {
 234         World w = new World(false, false);
 235 
 236         // Press
 237         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 238 
 239         w.getSource().getDragEntered().assertNotCalled();
 240         w.getSource().getAny().assertNotCalled();
 241 
 242         // Move - initiates the gesture
 243         w.event(MouseEvent.MOUSE_DRAGGED, 160, 151);
 244 
 245         // Move - first event in the gesture, causes all the entered events
 246         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 247 
 248         w.getSource().getDragEntered().assertCalled();
 249         w.getSource().getDragEntered().assertCoords(60, 50);
 250         w.getSource().getDragEntered().assertGestureSource(w.getSource().getNode());
 251         w.getSource().getDragEnteredTarget().assertCalled();
 252         w.getSource().getDragEnteredTarget().assertCoords(60, 50);
 253         w.getSource().getDragEnteredTarget().assertGestureSource(w.getSource().getNode());
 254         w.getBelowSource().getDragEntered().assertNotCalled();
 255         w.getSourceParent().getDragEntered().assertCalled();
 256         w.getSourceParent().getDragEntered().assertCoords(160, 150);
 257         w.getSourceParent().getDragEnteredTarget().assertCalled();
 258         w.getSourceParent().getDragEnteredTarget().assertCoords(160, 150);
 259         w.getScene().getDragEntered().assertCalled();
 260         w.getScene().getDragEntered().assertCoords(160, 150);
 261 
 262         w.event(MouseEvent.MOUSE_RELEASED, 160, 150);
 263 
 264         w.clear();
 265     }
 266 
 267     @Test
 268     public void activatingFullPDRShouldCauseEnteredEventsRepeatedly() {
 269         World w = new World(false, false);
 270 
 271         // First time
 272         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 273         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 274         w.event(MouseEvent.MOUSE_RELEASED, 160, 150);
 275         w.clear();
 276 
 277         //Second time
 278         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 279         w.event(MouseEvent.MOUSE_DRAGGED, 160, 151);
 280         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 281 
 282         w.getSource().getDragEntered().assertCalled();
 283         w.getSource().getDragEntered().assertCoords(60, 50);
 284         w.getSource().getDragEntered().assertGestureSource(w.getSource().getNode());
 285         w.getSource().getDragEnteredTarget().assertCalled();
 286         w.getSource().getDragEnteredTarget().assertCoords(60, 50);
 287         w.getSource().getDragEnteredTarget().assertGestureSource(w.getSource().getNode());
 288         w.getBelowSource().getDragEntered().assertNotCalled();
 289         w.getSourceParent().getDragEntered().assertCalled();
 290         w.getSourceParent().getDragEntered().assertCoords(160, 150);
 291         w.getSourceParent().getDragEnteredTarget().assertCalled();
 292         w.getSourceParent().getDragEnteredTarget().assertCoords(160, 150);
 293         w.getScene().getDragEntered().assertCalled();
 294         w.getScene().getDragEntered().assertCoords(160, 150);
 295 
 296         w.event(MouseEvent.MOUSE_RELEASED, 160, 150);
 297 
 298         w.clear();
 299     }
 300 
 301     @Test
 302     public void activatingFullPDRShouldCauseEnteredEventsForUnderlyingNode() {
 303         World w = new World(true, true);
 304 
 305         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 306         w.event(MouseEvent.MOUSE_DRAGGED, 160, 151);
 307         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 308 
 309         w.getSource().getDragEntered().assertNotCalled();
 310         w.getBelowSource().getDragEntered().assertCalled();
 311         w.getBelowSource().getDragEntered().assertCoords(160, 150);
 312         w.getBelowSource().getDragEntered().assertGestureSource(w.getSource().getNode());
 313 
 314         w.event(MouseEvent.MOUSE_RELEASED, 160, 150);
 315 
 316         w.clear();
 317     }
 318 
 319 
 320     @Test
 321     public void fullPDRShouldProduceDragOverEvents() {
 322         World w = new World(false, false);
 323 
 324         // Initiate the gesture
 325         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 326         w.event(MouseEvent.MOUSE_DRAGGED, 159, 150);
 327         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 328 
 329         w.getSource().getDragOver().assertCalled();
 330         w.getSource().getDragOver().assertCoords(60, 50);
 331         w.getSource().getDragOver().assertGestureSource(w.getSource().getNode());
 332         w.getBelowSource().getDragOver().assertNotCalled();
 333         w.getSourceParent().getDragOver().assertCalled();
 334         w.getSourceParent().getDragOver().assertCoords(160, 150);
 335         w.getScene().getDragOver().assertCalled();
 336         w.getScene().getDragOver().assertCoords(160, 150);
 337 
 338         w.event(MouseEvent.MOUSE_RELEASED, 160, 150);
 339 
 340         w.clear();
 341     }
 342 
 343     @Test
 344     public void endingFullPDRShouldProduceReleaseEvents() {
 345         World w = new World(false, false);
 346 
 347         // Initiate the gesture
 348         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 349         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 350 
 351         w.getSource().getDragReleased().assertNotCalled();
 352         w.getScene().getDragReleased().assertNotCalled();
 353 
 354         w.event(MouseEvent.MOUSE_RELEASED, 170, 150);
 355 
 356         w.getSource().getDragReleased().assertCalled();
 357         w.getSource().getDragReleased().assertCoords(70, 50);
 358         w.getSource().getDragReleased().assertGestureSource(w.getSource().getNode());
 359         w.getBelowSource().getDragReleased().assertNotCalled();
 360         w.getSourceParent().getDragReleased().assertCalled();
 361         w.getSourceParent().getDragReleased().assertCoords(170, 150);
 362         w.getScene().getDragReleased().assertCalled();
 363         w.getScene().getDragReleased().assertCoords(170, 150);
 364 
 365         w.clear();
 366     }
 367 
 368     @Test
 369     public void endingFullPDRShouldCuaseExitedEvents() {
 370         World w = new World(false, false);
 371 
 372         // Initiate the gesture
 373         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 374         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 375 
 376         w.getSource().getDragExited().assertNotCalled();
 377         w.getScene().getDragExited().assertNotCalled();
 378 
 379         w.event(MouseEvent.MOUSE_RELEASED, 170, 150);
 380 
 381         w.getSource().getDragExited().assertCalled();
 382         w.getSource().getDragExited().assertCoords(70, 50);
 383         w.getSource().getDragExited().assertGestureSource(w.getSource().getNode());
 384         w.getSource().getDragExitedTarget().assertCalled();
 385         w.getSource().getDragExitedTarget().assertCoords(70, 50);
 386         w.getSource().getDragExitedTarget().assertGestureSource(w.getSource().getNode());
 387         w.getBelowSource().getDragExited().assertNotCalled();
 388         w.getSourceParent().getDragExited().assertCalled();
 389         w.getSourceParent().getDragExited().assertCoords(170, 150);
 390         w.getSourceParent().getDragExitedTarget().assertCalled();
 391         w.getSourceParent().getDragExitedTarget().assertCoords(170, 150);
 392         w.getScene().getDragExited().assertCalled();
 393         w.getScene().getDragExited().assertCoords(170, 150);
 394 
 395         w.clear();
 396     }
 397 
 398     @Test
 399     public void draggedNodeGetsAllTheEvents() {
 400         World w = new World(true, false);
 401 
 402         // Initiate the gesture
 403         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 404         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 405 
 406         // Move to target (source is dragged)
 407         w.event(MouseEvent.MOUSE_DRAGGED, 199, 150);
 408         w.event(MouseEvent.MOUSE_DRAGGED, 248, 150);
 409         w.event(MouseEvent.MOUSE_DRAGGED, 297, 150);
 410         w.event(MouseEvent.MOUSE_DRAGGED, 346, 150);
 411         w.event(MouseEvent.MOUSE_DRAGGED, 395, 150);
 412         w.event(MouseEvent.MOUSE_DRAGGED, 410, 150);
 413 
 414         w.getTarget().getAny().assertNotCalled();
 415         w.getBelowTarget().getAny().assertNotCalled();
 416         w.getTargetParent().getAny().assertNotCalled();
 417         w.getBelowSource().getAny().assertNotCalled();
 418         w.getSource().getDragOver().assertCalled();
 419         w.getSource().getDragOver().assertCoords(50, 50);
 420         w.getSource().getDragOver().assertGestureSource(w.getSource().getNode());
 421 
 422         w.clear();
 423 
 424         w.event(MouseEvent.MOUSE_RELEASED, 410, 150);
 425 
 426         w.getTarget().getAny().assertNotCalled();
 427         w.getBelowTarget().getAny().assertNotCalled();
 428         w.getTargetParent().getAny().assertNotCalled();
 429         w.getBelowSource().getAny().assertNotCalled();
 430         w.getSource().getDragReleased().assertCalled();
 431         w.getSource().getDragReleased().assertCoords(50, 50);
 432         w.getSource().getDragReleased().assertGestureSource(w.getSource().getNode());
 433     }
 434 
 435     @Test
 436     public void fullPDRShouldPickAfterMouseEventHandlers() {
 437         World w = new World(true, false);
 438 
 439         // Initiate the gesture
 440         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 441         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 442 
 443         // Move to target (jumps temorarily out of the source)
 444         w.event(MouseEvent.MOUSE_DRAGGED, 410, 150);
 445 
 446         w.getTarget().getAny().assertNotCalled();
 447         w.getBelowTarget().getAny().assertNotCalled();
 448         w.getTargetParent().getAny().assertNotCalled();
 449         w.getBelowSource().getAny().assertNotCalled();
 450         w.getSource().getDragOver().assertCalled();
 451         w.getSource().getDragOver().assertCoords(50, 50);
 452         w.getSource().getDragOver().assertGestureSource(w.getSource().getNode());
 453 
 454         w.clear();
 455 
 456         w.event(MouseEvent.MOUSE_RELEASED, 410, 150);
 457 
 458         w.getTarget().getAny().assertNotCalled();
 459         w.getBelowTarget().getAny().assertNotCalled();
 460         w.getTargetParent().getAny().assertNotCalled();
 461         w.getBelowSource().getAny().assertNotCalled();
 462         w.getSource().getDragReleased().assertCalled();
 463         w.getSource().getDragReleased().assertCoords(50, 50);
 464         w.getSource().getDragReleased().assertGestureSource(w.getSource().getNode());
 465     }
 466 
 467     @Test
 468     public void transparentNodeShouldBeDraggable() {
 469         World w = new World(true, true);
 470 
 471         // Initiate the gesture
 472         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 473         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 474 
 475         // Move to target (source is dragged)
 476         w.event(MouseEvent.MOUSE_DRAGGED, 410, 150);
 477 
 478         w.getSource().assertTranslate(360, 100);
 479 
 480         w.event(MouseEvent.MOUSE_RELEASED, 410, 150);
 481     }
 482 
 483     @Test
 484     public void transparentNodeShouldAllowUnderlyingTarget() {
 485         World w = new World(true, true);
 486 
 487         // Initiate the gesture
 488         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 489         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 490 
 491         // Move to target (source is dragged)
 492         w.event(MouseEvent.MOUSE_DRAGGED, 199, 150);
 493         w.event(MouseEvent.MOUSE_DRAGGED, 248, 150);
 494         w.event(MouseEvent.MOUSE_DRAGGED, 297, 150);
 495         w.event(MouseEvent.MOUSE_DRAGGED, 346, 150);
 496 
 497         w.clear();
 498 
 499         w.event(MouseEvent.MOUSE_DRAGGED, 395, 150);
 500 
 501         w.getSource().getAny().assertNotCalled();
 502         w.getBelowTarget().getDragExited().assertCalled();
 503         w.getTarget().getDragEntered().assertCalled();
 504         w.getTarget().getDragEntered().assertCoords(45, 50);
 505         w.getTarget().getDragEntered().assertGestureSource(w.getSource().getNode());
 506         w.getTarget().getDragOver().assertCalled();
 507         w.getTarget().getDragOver().assertCoords(45, 50);
 508         w.getTarget().getDragOver().assertGestureSource(w.getSource().getNode());
 509 
 510         w.event(MouseEvent.MOUSE_RELEASED, 410, 150);
 511 
 512         w.getTarget().getDragReleased().assertCalled();
 513         w.getTarget().getDragReleased().assertCoords(60, 50);
 514         w.getTarget().getDragReleased().assertGestureSource(w.getSource().getNode());
 515         w.getSource().getAny().clear();
 516     }
 517 
 518     @Test
 519     public void gestureSourceShouldBeGivenByStartFullDragCall() {
 520         World w = new World(false, false);
 521 
 522         // Initiate the gesture
 523         w.event(MouseEvent.MOUSE_PRESSED, 225, 150);
 524         w.event(MouseEvent.MOUSE_DRAGGED, 135, 150);
 525 
 526         w.clear();
 527 
 528         w.event(MouseEvent.MOUSE_DRAGGED, 400, 150);
 529 
 530         w.getTarget().getDragOver().assertGestureSource(w.sourceParent.getNode());
 531     }
 532 
 533     @Test
 534     public void fullPDRShouldRecognizeLeavingScene() {
 535         World w = new World(false, false);
 536 
 537         // Initiate the gesture
 538         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 539         w.event(MouseEvent.MOUSE_DRAGGED, 160, 151);
 540         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 541 
 542         w.getScene().getDragEntered().assertCalled();
 543 
 544         w.clear();
 545 
 546         // Move inside the scene
 547         w.event(MouseEvent.MOUSE_DRAGGED, 1, 1);
 548         w.getScene().getDragExited().assertNotCalled();
 549 
 550         // Leave the scene
 551         w.event(MouseEvent.MOUSE_DRAGGED, 1000, 1);
 552         w.getScene().getDragExited().assertCalled();
 553 
 554         w.clear();
 555 
 556         // Move outside of scene
 557         w.event(MouseEvent.MOUSE_DRAGGED, -10, 10);
 558         w.getScene().getAny().assertNotCalled();
 559 
 560         // Move back to scene
 561         w.event(MouseEvent.MOUSE_DRAGGED, 10, 10);
 562         w.getScene().getDragEntered().assertCalled();
 563 
 564         // Move out again
 565         w.event(MouseEvent.MOUSE_DRAGGED, -5, -5);
 566         w.getScene().getDragExited().assertCalled();
 567         w.clear();
 568 
 569         // Release there
 570         w.event(MouseEvent.MOUSE_RELEASED, -5, -5);
 571         w.getScene().getAny().assertNotCalled();
 572     }
 573 
 574     @Test
 575     public void testFullGesture() {
 576         World w = new World(false, false);
 577 
 578         // Initiate gesture
 579         w.event(MouseEvent.MOUSE_PRESSED, 150, 150);
 580         w.event(MouseEvent.MOUSE_DRAGGED, 160, 151);
 581         w.event(MouseEvent.MOUSE_DRAGGED, 160, 150);
 582 
 583         w.getSource().getDragEntered().assertCalled();
 584         w.getSource().getDragEntered().assertCoords(60, 50);
 585         w.getSource().getDragEntered().assertGestureSource(w.getSource().getNode());
 586         w.getSource().getDragEnteredTarget().assertCalled();
 587         w.getSource().getDragEnteredTarget().assertCoords(60, 50);
 588         w.getSource().getDragEnteredTarget().assertGestureSource(w.getSource().getNode());
 589         w.getBelowSource().getDragEntered().assertNotCalled();
 590         w.getSourceParent().getDragEntered().assertCalled();
 591         w.getSourceParent().getDragEntered().assertCoords(160, 150);
 592         w.getSourceParent().getDragEnteredTarget().assertCalled();
 593         w.getSourceParent().getDragEnteredTarget().assertCoords(160, 150);
 594         w.getScene().getDragEntered().assertCalled();
 595 
 596         w.clear();
 597 
 598         // Move to covered node
 599         w.event(MouseEvent.MOUSE_DRAGGED, 225, 150);
 600 
 601         w.getSource().getDragExited().assertCalled();
 602         w.getSource().getDragExited().assertCoords(125, 50);
 603         w.getSource().getDragExited().assertGestureSource(w.getSource().getNode());
 604         w.getSource().getDragExitedTarget().assertCalled();
 605         w.getSource().getDragExitedTarget().assertCoords(125, 50);
 606         w.getSource().getDragExitedTarget().assertGestureSource(w.getSource().getNode());
 607         w.getBelowSource().getDragEntered().assertCalled();
 608         w.getBelowSource().getDragEntered().assertCoords(225, 150);
 609         w.getBelowSource().getDragEntered().assertGestureSource(w.getSource().getNode());
 610         w.getBelowSource().getDragExitedTarget().assertNotCalled();
 611         w.getSourceParent().getDragEntered().assertNotCalled();
 612         w.getSourceParent().getDragExited().assertNotCalled();
 613         w.getSourceParent().getDragEnteredTarget().assertCalled();
 614         w.getSourceParent().getDragExitedTarget().assertCalled();
 615         w.getScene().getDragEntered().assertNotCalled();
 616         w.getScene().getDragExited().assertNotCalled();
 617         w.getScene().getDragEnteredTarget().assertCalled();
 618         w.getScene().getDragExitedTarget().assertCalled();
 619 
 620         w.clear();
 621 
 622         // Move a bit
 623         w.event(MouseEvent.MOUSE_DRAGGED, 226, 150);
 624 
 625         w.getSource().getDragOver().assertNotCalled();
 626         w.getBelowSource().getDragOver().assertCalled();
 627         w.getSourceParent().getDragOver().assertCalled();
 628         w.getSourceParent().getDragOver().assertCoords(226, 150);
 629         w.getSourceParent().getDragOver().assertGestureSource(w.getSource().getNode());
 630         w.getScene().getDragOver().assertCalled();
 631         w.getScene().getDragEnteredTarget().assertNotCalled();
 632         w.getScene().getDragExitedTarget().assertNotCalled();
 633         w.getScene().getDragReleased().assertNotCalled();
 634 
 635         w.clear();
 636 
 637         // Move to node covered by target
 638         w.event(MouseEvent.MOUSE_DRAGGED, 325, 150);
 639 
 640         w.getSource().getAny().assertNotCalled();
 641         w.getBelowSource().getDragExited().assertCalled();
 642         w.getSourceParent().getDragExited().assertCalled();
 643         w.getBelowTarget().getDragEntered().assertCalled();
 644         w.getBelowTarget().getDragEntered().assertCoords(325, 150);
 645         w.getBelowTarget().getDragEntered().assertGestureSource(w.getSource().getNode());
 646         w.getTargetParent().getDragEntered().assertCalled();
 647         w.getBelowTarget().getDragOver().assertCalled();
 648         w.getBelowTarget().getDragOver().assertCoords(325,150);
 649         w.getBelowTarget().getDragOver().assertGestureSource(w.getSource().getNode());
 650         w.getScene().getDragEntered().assertNotCalled();
 651         w.getScene().getDragExited().assertNotCalled();
 652         w.getScene().getDragEnteredTarget().assertCalled();
 653         w.getScene().getDragExitedTarget().assertCalled();
 654 
 655         w.clear();
 656 
 657         // Move to the target
 658         w.event(MouseEvent.MOUSE_DRAGGED, 400, 150);
 659 
 660         w.getSource().getAny().assertNotCalled();
 661         w.getSourceParent().getAny().assertNotCalled();
 662         w.getBelowSource().getAny().assertNotCalled();
 663         w.getBelowTarget().getDragExited().assertCalled();
 664         w.getBelowTarget().getDragOver().assertNotCalled();
 665         w.getTarget().getDragEntered().assertCalled();
 666         w.getTarget().getDragEntered().assertCoords(50, 50);
 667         w.getTarget().getDragEntered().assertGestureSource(w.getSource().getNode());
 668         w.getTarget().getDragOver().assertCalled();
 669         w.getTarget().getDragOver().assertCoords(50, 50);
 670         w.getTarget().getDragOver().assertGestureSource(w.getSource().getNode());
 671         w.getTargetParent().getDragEntered().assertNotCalled();
 672         w.getTargetParent().getDragExited().assertNotCalled();
 673         w.getTargetParent().getDragEnteredTarget().assertCalled();
 674         w.getTargetParent().getDragExitedTarget().assertCalled();
 675 
 676         w.clear();
 677 
 678         // Release
 679         w.event(MouseEvent.MOUSE_RELEASED, 410, 150);
 680 
 681         w.getSource().getAny().assertNotCalled();
 682         w.getBelowSource().getAny().assertNotCalled();
 683         w.getSourceParent().getAny().assertNotCalled();
 684         w.getBelowTarget().getAny().assertNotCalled();
 685         w.getTarget().getDragReleased().assertCalled();
 686         w.getTarget().getDragReleased().assertCoords(60, 50);
 687         w.getTarget().getDragReleased().assertGestureSource(w.getSource().getNode());
 688         w.getTargetParent().getDragReleased().assertCalled();
 689         w.getTargetParent().getDragReleased().assertCoords(410, 150);
 690         w.getTargetParent().getDragReleased().assertGestureSource(w.getSource().getNode());
 691         w.getScene().getDragReleased().assertCalled();
 692         w.getScene().getDragReleased().assertCoords(410, 150);
 693         w.getScene().getDragReleased().assertGestureSource(w.getSource().getNode());
 694         w.getTarget().getDragExited().assertCalled();
 695         w.getTarget().getDragExited().assertCoords(60, 50);
 696         w.getTarget().getDragExited().assertGestureSource(w.getSource().getNode());
 697         w.getTargetParent().getDragExited().assertCalled();
 698         w.getTargetParent().getDragExited().assertCoords(410, 150);
 699         w.getTargetParent().getDragExited().assertGestureSource(w.getSource().getNode());
 700         w.getScene().getDragExited().assertCalled();
 701         w.getScene().getDragExited().assertCoords(410, 150);
 702         w.getScene().getDragExited().assertGestureSource(w.getSource().getNode());
 703 
 704         w.clear();
 705     }
 706 
 707     @Test
 708     public void shouldGetNonEmptyDescription() {
 709         String s = new MouseDragEvent(MouseDragEvent.MOUSE_DRAG_OVER,
 710                 10, 20, 20, 30, MouseButton.NONE, 0, true, true, true, true,
 711                 true, true, true, false, false, null, null)
 712                 .toString();
 713         assertNotNull(s);
 714         assertFalse(s.isEmpty());
 715     }
 716 
 717     private class World {
 718         private HandledNode scene;
 719         private HandledNode source;
 720         private HandledNode belowSource;
 721         private HandledNode sourceParent;
 722         private HandledNode target;
 723         private HandledNode belowTarget;
 724         private HandledNode targetParent;
 725         private HandledNode root;
 726         private Scene sceneNode;
 727 
 728         private double anchorX, anchorY;
 729         private MouseEventGenerator generator;
 730 
 731 
 732         public World(boolean sourceDragged, final boolean sourceMouseTransparent) {
 733 
 734             generator = new MouseEventGenerator();
 735 
 736             final Group rootNode = new Group();
 737             sceneNode = new Scene(rootNode, 550, 300);
 738 
 739             final Group sourceParentNode = new Group();
 740             final Rectangle belowSourceNode = new Rectangle(50, 50, 200, 200);
 741             final Rectangle sourceNode = new Rectangle(100, 100);
 742             sourceNode.setTranslateX(100);
 743             sourceNode.setTranslateY(100);
 744 
 745             final Group targetParentNode = new Group();
 746             final Rectangle belowTargetNode = new Rectangle(300, 50, 200, 200);
 747             final Rectangle targetNode = new Rectangle(100, 100);
 748             targetNode.setTranslateX(350);
 749             targetNode.setTranslateY(100);
 750 
 751             sourceParentNode.getChildren().addAll(belowSourceNode, sourceNode);
 752             targetParentNode.getChildren().addAll(belowTargetNode, targetNode);
 753             rootNode.getChildren().addAll(targetParentNode, sourceParentNode);
 754 
 755             scene = new HandledNode(sceneNode);
 756             source = new HandledNode(sourceNode);
 757             belowSource = new HandledNode(belowSourceNode);
 758             sourceParent = new HandledNode(sourceParentNode);
 759             target = new HandledNode(targetNode);
 760             belowTarget = new HandledNode(belowTargetNode);
 761             targetParent = new HandledNode(targetParentNode);
 762             root = new HandledNode(rootNode);
 763 
 764             sourceNode.setOnDragDetected(event -> sourceNode.startFullDrag());
 765 
 766             belowSourceNode.setOnDragDetected(event -> sourceParentNode.startFullDrag());
 767 
 768             if (sourceDragged) {
 769                 sourceNode.setOnMousePressed(event -> {
 770                     anchorX = event.getSceneX();
 771                     anchorY = event.getSceneY();
 772                     if (sourceMouseTransparent) {
 773                         sourceNode.setMouseTransparent(true);
 774                     }
 775                 });
 776 
 777                 sourceNode.setOnMouseDragged(event -> {
 778                     sourceNode.setTranslateX(sourceNode.getTranslateX()
 779                             + event.getSceneX() - anchorX);
 780                     sourceNode.setTranslateY(sourceNode.getTranslateY()
 781                             + event.getSceneY() - anchorY);
 782                     anchorX = event.getSceneX();
 783                     anchorY = event.getSceneY();
 784                 });
 785 
 786                 sourceNode.setOnMouseReleased(event -> {
 787                     if (sourceMouseTransparent) {
 788                         sourceNode.setMouseTransparent(false);
 789                     }
 790                 });
 791             }
 792 
 793             Stage stage = new Stage();
 794             stage.setScene(sceneNode);
 795             stage.show();
 796         }
 797 
 798         public HandledNode getBelowSource() {
 799             return belowSource;
 800         }
 801 
 802         public HandledNode getBelowTarget() {
 803             return belowTarget;
 804         }
 805 
 806         public HandledNode getRoot() {
 807             return root;
 808         }
 809 
 810         public HandledNode getScene() {
 811             return scene;
 812         }
 813 
 814         public HandledNode getSource() {
 815             return source;
 816         }
 817 
 818         public HandledNode getSourceParent() {
 819             return sourceParent;
 820         }
 821 
 822         public HandledNode getTarget() {
 823             return target;
 824         }
 825 
 826         public HandledNode getTargetParent() {
 827             return targetParent;
 828         }
 829 
 830         public void event(EventType<MouseEvent> type, double x, double y) {
 831             sceneNode.impl_processMouseEvent(
 832                     generator.generateMouseEvent(type, x, y));
 833         }
 834 
 835         public void clear() {
 836             scene.clear();
 837             source.clear();
 838             belowSource.clear();
 839             sourceParent.clear();
 840             target.clear();
 841             belowTarget.clear();
 842             targetParent.clear();
 843             root.clear();
 844         }
 845 
 846     }
 847 
 848     private class HandledNode {
 849         private Node node;
 850         private Handler dragOver;
 851         private Handler dragReleased;
 852         private Handler dragEntered;
 853         private Handler dragExited;
 854         private Handler dragEnteredTarget;
 855         private Handler dragExitedTarget;
 856         private Handler any;
 857 
 858         public HandledNode(Node node) {
 859             this.node = node;
 860             node.setOnMouseDragOver(dragOver = new Handler());
 861             node.setOnMouseDragReleased(dragReleased = new Handler());
 862             node.setOnMouseDragEntered(dragEntered = new Handler());
 863             node.setOnMouseDragExited(dragExited = new Handler());
 864             node.addEventHandler(MouseDragEvent.MOUSE_DRAG_ENTERED_TARGET,
 865                     dragEnteredTarget = new Handler());
 866             node.addEventHandler(MouseDragEvent.MOUSE_DRAG_EXITED_TARGET,
 867                     dragExitedTarget = new Handler());
 868             node.addEventHandler(MouseDragEvent.ANY,
 869                     any = new Handler());
 870         }
 871 
 872         public HandledNode(Scene scene) {
 873             this.node = null;
 874             scene.setOnMouseDragOver(dragOver = new Handler());
 875             scene.setOnMouseDragReleased(dragReleased = new Handler());
 876             scene.setOnMouseDragEntered(dragEntered = new Handler());
 877             scene.setOnMouseDragExited(dragExited = new Handler());
 878             scene.addEventHandler(MouseDragEvent.MOUSE_DRAG_ENTERED_TARGET,
 879                     dragEnteredTarget = new Handler());
 880             scene.addEventHandler(MouseDragEvent.MOUSE_DRAG_EXITED_TARGET,
 881                     dragExitedTarget = new Handler());
 882             scene.addEventHandler(MouseDragEvent.ANY,
 883                     any = new Handler());
 884         }
 885 
 886         public Handler getAny() {
 887             return any;
 888         }
 889 
 890         public Handler getDragEntered() {
 891             return dragEntered;
 892         }
 893 
 894         public Handler getDragEnteredTarget() {
 895             return dragEnteredTarget;
 896         }
 897 
 898         public Handler getDragExited() {
 899             return dragExited;
 900         }
 901 
 902         public Handler getDragExitedTarget() {
 903             return dragExitedTarget;
 904         }
 905 
 906         public Handler getDragOver() {
 907             return dragOver;
 908         }
 909 
 910         public Handler getDragReleased() {
 911             return dragReleased;
 912         }
 913 
 914         public void assertTranslate(double x, double y) {
 915             assertEquals(x, node.getTranslateX(), 0.0001);
 916             assertEquals(y, node.getTranslateY(), 0.0001);
 917         }
 918 
 919         public Node getNode() {
 920             return node;
 921         }
 922 
 923         public void clear() {
 924             dragOver.clear();
 925             dragReleased.clear();
 926             dragEntered.clear();
 927             dragExited.clear();
 928             dragEnteredTarget.clear();
 929             dragExitedTarget.clear();
 930             any.clear();
 931         }
 932     }
 933 
 934     private class Handler implements EventHandler<MouseDragEvent> {
 935 
 936         private boolean called = false;
 937         private double x = 0.0;
 938         private double y = 0.0;
 939         private EventType type = null;
 940         private Object gestureSource = null;
 941 
 942         @Override public void handle(MouseDragEvent event) {
 943             called = true;
 944             x = event.getX();
 945             y = event.getY();
 946             type = event.getEventType();
 947             gestureSource = event.getGestureSource();
 948         }
 949 
 950         public void assertCalled() {
 951             assertTrue(called);
 952         }
 953 
 954         public void assertNotCalled() {
 955             assertFalse(called);
 956         }
 957 
 958         public void assertCoords(double x, double y) {
 959             assertEquals(x, this.x, 0.0001);
 960             assertEquals(y, this.y, 0.0001);
 961         }
 962 
 963         public void assertType(EventType type) {
 964             assertSame(type, this.type);
 965         }
 966 
 967         public void assertGestureSource(Object gestureSource) {
 968             assertSame(gestureSource, this.gestureSource);
 969         }
 970 
 971         public void clear() {
 972             called = false;
 973             x = 0.0;
 974             y = 0.0;
 975             type = null;
 976             gestureSource = null;
 977         }
 978     }
 979 }