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