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