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;
  27 
  28 import test.com.sun.javafx.test.MouseEventGenerator;
  29 import static org.junit.Assert.*;
  30 import javafx.event.EventHandler;
  31 import javafx.scene.input.MouseEvent;
  32 import javafx.scene.shape.Rectangle;
  33 import javafx.stage.Stage;
  34 
  35 import org.junit.Assert;
  36 import org.junit.Test;
  37 
  38 import test.com.sun.javafx.pgstub.StubScene;
  39 import test.com.sun.javafx.pgstub.StubToolkit;
  40 import com.sun.javafx.tk.Toolkit;
  41 import javafx.event.EventTarget;
  42 import javafx.event.EventType;
  43 import javafx.scene.Cursor;
  44 import javafx.scene.CursorShim;
  45 import javafx.scene.Group;
  46 import javafx.scene.Node;
  47 import javafx.scene.ParentShim;
  48 import javafx.scene.PerspectiveCamera;
  49 import javafx.scene.Scene;
  50 import javafx.scene.SubScene;
  51 import javafx.scene.input.MouseDragEvent;
  52 import javafx.scene.input.PickResult;
  53 import javafx.scene.paint.Color;
  54 import javafx.scene.transform.Rotate;
  55 
  56 public class MouseTest {
  57 
  58     private static final double DONT_TEST = 0.0;
  59 
  60     @Test
  61     public void moveShouldBubbleToParent() {
  62         SimpleTestScene scene = new SimpleTestScene();
  63         MouseEventGenerator generator = new MouseEventGenerator();
  64 
  65         scene.processEvent(generator.generateMouseEvent(
  66                 MouseEvent.MOUSE_MOVED, 250, 250));
  67 
  68         assertTrue(scene.smallSquareTracker.wasMoved());
  69         assertFalse(scene.bigSquareTracker.wasMoved());
  70         assertTrue(scene.groupTracker.wasMoved());
  71     }
  72 
  73     @Test
  74     public void moveOutsideNodesShouldntBeNoticed() {
  75         SimpleTestScene scene = new SimpleTestScene();
  76         MouseEventGenerator generator = new MouseEventGenerator();
  77 
  78         scene.processEvent(generator.generateMouseEvent(
  79                 MouseEvent.MOUSE_MOVED, 350, 350));
  80 
  81         assertFalse(scene.smallSquareTracker.wasMoved());
  82         assertFalse(scene.bigSquareTracker.wasMoved());
  83         assertFalse(scene.groupTracker.wasMoved());
  84     }
  85 
  86     @Test
  87     public void moveOutsideNodesShouldGoToScene() {
  88         SimpleTestScene scene = new SimpleTestScene();
  89         MouseEventGenerator generator = new MouseEventGenerator();
  90 
  91         scene.processEvent(generator.generateMouseEvent(
  92                 MouseEvent.MOUSE_MOVED, 350, 350));
  93 
  94         assertTrue(scene.wasMoused());
  95     }
  96 
  97     @Test
  98     public void ImpossibleToComputeCoordsShouldResultInNaNs() {
  99         final SimpleTestScene scene = new SimpleTestScene();
 100 
 101         scene.smallSquareTracker.node.setOnMouseMoved(event -> scene.smallSquareTracker.node.setScaleX(0));
 102 
 103         scene.smallSquareTracker.node.setOnMouseExited(event -> {
 104             assertTrue(Double.isNaN(event.getX()));
 105             assertTrue(Double.isNaN(event.getY()));
 106             assertTrue(Double.isNaN(event.getZ()));
 107         });
 108 
 109         scene.processEvent(MouseEventGenerator.generateMouseEvent(
 110                 MouseEvent.MOUSE_MOVED, 250, 250));
 111         scene.processEvent(MouseEventGenerator.generateMouseEvent(
 112                 MouseEvent.MOUSE_MOVED, 260, 260));
 113         assertTrue(scene.smallSquareTracker.enteredMe);
 114     }
 115 
 116     @Test
 117     public void PdrGestureShouldGoToOneNode() {
 118         SimpleTestScene scene = new SimpleTestScene();
 119         MouseEventGenerator generator = new MouseEventGenerator();
 120 
 121         /* gesture */
 122         scene.processEvent(generator.generateMouseEvent(
 123                 MouseEvent.MOUSE_PRESSED, 250, 250));
 124 
 125         scene.processEvent(generator.generateMouseEvent(
 126                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 127 
 128         scene.processEvent(generator.generateMouseEvent(
 129                 MouseEvent.MOUSE_RELEASED, 150, 150));
 130 
 131         assertTrue(scene.smallSquareTracker.wasPressed());
 132         assertTrue(scene.smallSquareTracker.wasDragged());
 133         assertTrue(scene.smallSquareTracker.wasReleased());
 134         assertFalse(scene.bigSquareTracker.wasPressed());
 135         assertFalse(scene.bigSquareTracker.wasDragged());
 136         assertFalse(scene.bigSquareTracker.wasReleased());
 137         assertFalse(scene.bigSquareTracker.wasMoved());
 138 
 139         /* gesture ended */
 140         scene.processEvent(generator.generateMouseEvent(
 141                 MouseEvent.MOUSE_MOVED, 140, 140));
 142 
 143         assertTrue(scene.bigSquareTracker.wasMoved());
 144     }
 145 
 146     @Test
 147     public void PdrGestureOnSceneShouldGoOnlyToScene() {
 148         SimpleTestScene scene = new SimpleTestScene();
 149         MouseEventGenerator generator = new MouseEventGenerator();
 150 
 151         /* gesture */
 152         scene.processEvent(generator.generateMouseEvent(
 153                 MouseEvent.MOUSE_PRESSED, 50, 50));
 154 
 155         assertTrue(scene.wasMoused());
 156         assertFalse(scene.smallSquareTracker.wasPressed());
 157         assertFalse(scene.smallSquareTracker.wasDragged());
 158         assertFalse(scene.smallSquareTracker.wasReleased());
 159         assertFalse(scene.bigSquareTracker.wasPressed());
 160         assertFalse(scene.bigSquareTracker.wasDragged());
 161         assertFalse(scene.bigSquareTracker.wasReleased());
 162         assertFalse(scene.bigSquareTracker.wasMoved());
 163         scene.clear();
 164 
 165         scene.processEvent(generator.generateMouseEvent(
 166                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 167 
 168         assertTrue(scene.wasMoused());
 169         assertFalse(scene.smallSquareTracker.wasPressed());
 170         assertFalse(scene.smallSquareTracker.wasDragged());
 171         assertFalse(scene.smallSquareTracker.wasReleased());
 172         assertFalse(scene.bigSquareTracker.wasPressed());
 173         assertFalse(scene.bigSquareTracker.wasDragged());
 174         assertFalse(scene.bigSquareTracker.wasReleased());
 175         assertFalse(scene.bigSquareTracker.wasMoved());
 176         scene.clear();
 177 
 178         scene.processEvent(generator.generateMouseEvent(
 179                 MouseEvent.MOUSE_RELEASED, 150, 150));
 180 
 181         assertTrue(scene.wasMoused());
 182         assertFalse(scene.smallSquareTracker.wasPressed());
 183         assertFalse(scene.smallSquareTracker.wasDragged());
 184         assertFalse(scene.smallSquareTracker.wasReleased());
 185         assertFalse(scene.bigSquareTracker.wasPressed());
 186         assertFalse(scene.bigSquareTracker.wasDragged());
 187         assertFalse(scene.bigSquareTracker.wasReleased());
 188         assertFalse(scene.bigSquareTracker.wasMoved());
 189 
 190         /* gesture ended */
 191         scene.processEvent(generator.generateMouseEvent(
 192                 MouseEvent.MOUSE_MOVED, 140, 140));
 193 
 194         assertTrue(scene.bigSquareTracker.wasMoved());
 195     }
 196 
 197     @Test
 198     public void testEnteredExitedGeneration() {
 199         SimpleTestScene scene = new SimpleTestScene();
 200         MouseEventGenerator generator = new MouseEventGenerator();
 201 
 202         scene.processEvent(generator.generateMouseEvent(
 203                 MouseEvent.MOUSE_MOVED, 350, 350));
 204 
 205         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 206         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 207         assertFalse(scene.groupTracker.wasEnteredMe());
 208         assertFalse(scene.smallSquareTracker.wasExitedMe());
 209         assertFalse(scene.bigSquareTracker.wasExitedMe());
 210         assertFalse(scene.groupTracker.wasExitedMe());
 211         assertTrue(scene.sceneTracker.wasEnteredMe());
 212         assertFalse(scene.sceneTracker.wasExitedMe());
 213         scene.clear();
 214 
 215         scene.processEvent(generator.generateMouseEvent(
 216                 MouseEvent.MOUSE_MOVED, 250, 250));
 217 
 218         assertTrue(scene.smallSquareTracker.wasEnteredMe());
 219         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 220         assertTrue(scene.groupTracker.wasEnteredMe());
 221         assertFalse(scene.smallSquareTracker.wasExitedMe());
 222         assertFalse(scene.bigSquareTracker.wasExitedMe());
 223         assertFalse(scene.groupTracker.wasExitedMe());
 224         assertFalse(scene.sceneTracker.wasEnteredMe());
 225         assertFalse(scene.sceneTracker.wasExitedMe());
 226         scene.clear();
 227 
 228         scene.processEvent(generator.generateMouseEvent(
 229                 MouseEvent.MOUSE_MOVED, 150, 150));
 230 
 231         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 232         assertTrue(scene.bigSquareTracker.wasEnteredMe());
 233         assertFalse(scene.groupTracker.wasEnteredMe());
 234         assertTrue(scene.smallSquareTracker.wasExitedMe());
 235         assertFalse(scene.bigSquareTracker.wasExitedMe());
 236         assertFalse(scene.groupTracker.wasExitedMe());
 237         assertFalse(scene.sceneTracker.wasEnteredMe());
 238         assertFalse(scene.sceneTracker.wasExitedMe());
 239         scene.clear();
 240 
 241         scene.processEvent(generator.generateMouseEvent(
 242                 MouseEvent.MOUSE_MOVED, 50, 50));
 243 
 244         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 245         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 246         assertFalse(scene.groupTracker.wasEnteredMe());
 247         assertFalse(scene.smallSquareTracker.wasExitedMe());
 248         assertTrue(scene.bigSquareTracker.wasExitedMe());
 249         assertTrue(scene.groupTracker.wasExitedMe());
 250         assertFalse(scene.sceneTracker.wasEnteredMe());
 251         assertFalse(scene.sceneTracker.wasExitedMe());
 252         scene.clear();
 253 
 254         scene.processEvent(generator.generateMouseEvent(
 255                 MouseEvent.MOUSE_MOVED, -1, 50));
 256         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 257         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 258         assertFalse(scene.groupTracker.wasEnteredMe());
 259         assertFalse(scene.smallSquareTracker.wasExitedMe());
 260         assertFalse(scene.bigSquareTracker.wasExitedMe());
 261         assertFalse(scene.groupTracker.wasExitedMe());
 262         assertFalse(scene.sceneTracker.wasEnteredMe());
 263         assertTrue(scene.sceneTracker.wasExitedMe());
 264         scene.clear();
 265     }
 266 
 267     @Test
 268     public void testEnteredExitedGenerationDuringPdr() {
 269         SimpleTestScene scene = new SimpleTestScene();
 270         MouseEventGenerator generator = new MouseEventGenerator();
 271 
 272         scene.processEvent(generator.generateMouseEvent(
 273                 MouseEvent.MOUSE_PRESSED, 255, 255));
 274 
 275         scene.processEvent(generator.generateMouseEvent(
 276                 MouseEvent.MOUSE_DRAGGED, 250, 250));
 277 
 278         assertTrue(scene.smallSquareTracker.wasEnteredMe());
 279         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 280         assertTrue(scene.groupTracker.wasEnteredMe());
 281         assertFalse(scene.smallSquareTracker.wasExitedMe());
 282         assertFalse(scene.bigSquareTracker.wasExitedMe());
 283         assertFalse(scene.groupTracker.wasExitedMe());
 284         assertTrue(scene.sceneTracker.wasEnteredMe());
 285         assertFalse(scene.sceneTracker.wasExitedMe());
 286         scene.clear();
 287 
 288         scene.processEvent(generator.generateMouseEvent(
 289                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 290 
 291         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 292         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 293         assertFalse(scene.groupTracker.wasEnteredMe());
 294         assertTrue(scene.smallSquareTracker.wasExitedMe());
 295         assertFalse(scene.bigSquareTracker.wasExitedMe());
 296         assertFalse(scene.groupTracker.wasExitedMe());
 297         assertFalse(scene.sceneTracker.wasEnteredMe());
 298         assertFalse(scene.sceneTracker.wasExitedMe());
 299         scene.clear();
 300 
 301         scene.processEvent(generator.generateMouseEvent(
 302                 MouseEvent.MOUSE_DRAGGED, 50, 50));
 303 
 304         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 305         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 306         assertFalse(scene.groupTracker.wasEnteredMe());
 307         assertFalse(scene.smallSquareTracker.wasExitedMe());
 308         assertFalse(scene.bigSquareTracker.wasExitedMe());
 309         assertTrue(scene.groupTracker.wasExitedMe());
 310         assertFalse(scene.sceneTracker.wasEnteredMe());
 311         assertFalse(scene.sceneTracker.wasExitedMe());
 312         scene.clear();
 313 
 314         scene.processEvent(generator.generateMouseEvent(
 315                 MouseEvent.MOUSE_DRAGGED, -1, 50));
 316 
 317         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 318         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 319         assertFalse(scene.groupTracker.wasEnteredMe());
 320         assertFalse(scene.smallSquareTracker.wasExitedMe());
 321         assertFalse(scene.bigSquareTracker.wasExitedMe());
 322         assertFalse(scene.groupTracker.wasExitedMe());
 323         assertFalse(scene.sceneTracker.wasEnteredMe());
 324         assertTrue(scene.sceneTracker.wasExitedMe());
 325         scene.clear();
 326 
 327         scene.processEvent(generator.generateMouseEvent(
 328                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 329 
 330         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 331         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 332         assertTrue(scene.groupTracker.wasEnteredMe());
 333         assertFalse(scene.smallSquareTracker.wasExitedMe());
 334         assertFalse(scene.bigSquareTracker.wasExitedMe());
 335         assertFalse(scene.groupTracker.wasExitedMe());
 336         assertTrue(scene.sceneTracker.wasEnteredMe());
 337         assertFalse(scene.sceneTracker.wasExitedMe());
 338         scene.clear();
 339 
 340         scene.processEvent(generator.generateMouseEvent(
 341                 MouseEvent.MOUSE_RELEASED, 350, 350));
 342 
 343         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 344         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 345         assertFalse(scene.groupTracker.wasEnteredMe());
 346         assertFalse(scene.smallSquareTracker.wasExitedMe());
 347         assertFalse(scene.bigSquareTracker.wasExitedMe());
 348         assertTrue(scene.groupTracker.wasExitedMe());
 349         assertFalse(scene.sceneTracker.wasEnteredMe());
 350         assertFalse(scene.sceneTracker.wasExitedMe());
 351     }
 352 
 353     @Test
 354     public void testEnteredExitedGenerationAfterPdr() {
 355         SimpleTestScene scene = new SimpleTestScene();
 356         MouseEventGenerator generator = new MouseEventGenerator();
 357 
 358         scene.processEvent(generator.generateMouseEvent(
 359                 MouseEvent.MOUSE_PRESSED, 155, 155));
 360 
 361         scene.processEvent(generator.generateMouseEvent(
 362                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 363 
 364         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 365         assertTrue(scene.bigSquareTracker.wasEnteredMe());
 366         assertTrue(scene.groupTracker.wasEnteredMe());
 367         assertFalse(scene.smallSquareTracker.wasExitedMe());
 368         assertFalse(scene.bigSquareTracker.wasExitedMe());
 369         assertFalse(scene.groupTracker.wasExitedMe());
 370         scene.clear();
 371 
 372         scene.processEvent(generator.generateMouseEvent(
 373                 MouseEvent.MOUSE_DRAGGED, 250, 250));
 374 
 375         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 376         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 377         assertFalse(scene.groupTracker.wasEnteredMe());
 378         assertFalse(scene.smallSquareTracker.wasExitedMe());
 379         assertTrue(scene.bigSquareTracker.wasExitedMe());
 380         assertFalse(scene.groupTracker.wasExitedMe());
 381         scene.clear();
 382 
 383         scene.processEvent(generator.generateMouseEvent(
 384                 MouseEvent.MOUSE_RELEASED, 250, 250));
 385 
 386         assertTrue(scene.smallSquareTracker.wasEnteredMe());
 387         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 388         assertFalse(scene.groupTracker.wasEnteredMe());
 389         assertFalse(scene.smallSquareTracker.wasExitedMe());
 390         assertFalse(scene.bigSquareTracker.wasExitedMe());
 391         assertFalse(scene.groupTracker.wasExitedMe());
 392         scene.clear();
 393 
 394         scene.processEvent(generator.generateMouseEvent(
 395                 MouseEvent.MOUSE_MOVED, 250, 250));
 396 
 397         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 398         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 399         assertFalse(scene.groupTracker.wasEnteredMe());
 400         assertFalse(scene.smallSquareTracker.wasExitedMe());
 401         assertFalse(scene.bigSquareTracker.wasExitedMe());
 402         assertFalse(scene.groupTracker.wasExitedMe());
 403     }
 404 
 405     @Test
 406     public void testEnteredExitedGenerationDuringDndOnScene() {
 407         SimpleTestScene scene = new SimpleTestScene();
 408         MouseEventGenerator generator = new MouseEventGenerator();
 409 
 410         scene.processEvent(generator.generateMouseEvent(
 411                 MouseEvent.MOUSE_PRESSED, 50, 50));
 412 
 413         scene.processEvent(generator.generateMouseEvent(
 414                 MouseEvent.MOUSE_DRAGGED, 250, 250));
 415 
 416         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 417         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 418         assertFalse(scene.groupTracker.wasEnteredMe());
 419         assertFalse(scene.smallSquareTracker.wasExitedMe());
 420         assertFalse(scene.bigSquareTracker.wasExitedMe());
 421         assertFalse(scene.groupTracker.wasExitedMe());
 422         scene.clear();
 423 
 424         scene.processEvent(generator.generateMouseEvent(
 425                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 426 
 427         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 428         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 429         assertFalse(scene.groupTracker.wasEnteredMe());
 430         assertFalse(scene.smallSquareTracker.wasExitedMe());
 431         assertFalse(scene.bigSquareTracker.wasExitedMe());
 432         assertFalse(scene.groupTracker.wasExitedMe());
 433         scene.clear();
 434 
 435         scene.processEvent(generator.generateMouseEvent(
 436                 MouseEvent.MOUSE_DRAGGED, 50, 50));
 437 
 438         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 439         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 440         assertFalse(scene.groupTracker.wasEnteredMe());
 441         assertFalse(scene.smallSquareTracker.wasExitedMe());
 442         assertFalse(scene.bigSquareTracker.wasExitedMe());
 443         assertFalse(scene.groupTracker.wasExitedMe());
 444         scene.clear();
 445 
 446         scene.processEvent(generator.generateMouseEvent(
 447                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 448 
 449         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 450         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 451         assertFalse(scene.groupTracker.wasEnteredMe());
 452         assertFalse(scene.smallSquareTracker.wasExitedMe());
 453         assertFalse(scene.bigSquareTracker.wasExitedMe());
 454         assertFalse(scene.groupTracker.wasExitedMe());
 455         scene.clear();
 456 
 457         scene.processEvent(generator.generateMouseEvent(
 458                 MouseEvent.MOUSE_RELEASED, 350, 350));
 459 
 460         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 461         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 462         assertFalse(scene.groupTracker.wasEnteredMe());
 463         assertFalse(scene.smallSquareTracker.wasExitedMe());
 464         assertFalse(scene.bigSquareTracker.wasExitedMe());
 465         assertFalse(scene.groupTracker.wasExitedMe());
 466     }
 467 
 468     @Test
 469     public void testEnteredExitedMeChildSwitching() {
 470         SimpleTestScene scene = new SimpleTestScene();
 471         MouseEventGenerator generator = new MouseEventGenerator();
 472 
 473         scene.processEvent(generator.generateMouseEvent(
 474                 MouseEvent.MOUSE_MOVED, 150, 150));
 475 
 476         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 477         assertTrue(scene.bigSquareTracker.wasEnteredMe());
 478         assertTrue(scene.groupTracker.wasEnteredMe());
 479         assertFalse(scene.smallSquareTracker.wasExitedMe());
 480         assertFalse(scene.bigSquareTracker.wasExitedMe());
 481         assertFalse(scene.groupTracker.wasExitedMe());
 482         assertFalse(scene.smallSquareTracker.wasEnteredChild());
 483         assertFalse(scene.bigSquareTracker.wasEnteredChild());
 484         assertTrue(scene.groupTracker.wasEnteredChild());
 485         assertFalse(scene.smallSquareTracker.wasExitedChild());
 486         assertFalse(scene.bigSquareTracker.wasExitedChild());
 487         assertFalse(scene.groupTracker.wasExitedChild());
 488         scene.clear();
 489 
 490         scene.processEvent(generator.generateMouseEvent(
 491                 MouseEvent.MOUSE_MOVED, 250, 250));
 492 
 493         assertTrue(scene.smallSquareTracker.wasEnteredMe());
 494         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 495         assertFalse(scene.groupTracker.wasEnteredMe());
 496         assertFalse(scene.smallSquareTracker.wasExitedMe());
 497         assertTrue(scene.bigSquareTracker.wasExitedMe());
 498         assertFalse(scene.groupTracker.wasExitedMe());
 499         assertFalse(scene.smallSquareTracker.wasEnteredChild());
 500         assertFalse(scene.bigSquareTracker.wasEnteredChild());
 501         assertTrue(scene.groupTracker.wasEnteredChild());
 502         assertFalse(scene.smallSquareTracker.wasExitedChild());
 503         assertFalse(scene.bigSquareTracker.wasExitedChild());
 504         assertTrue(scene.groupTracker.wasExitedChild());
 505         scene.clear();
 506 
 507         scene.processEvent(generator.generateMouseEvent(
 508                 MouseEvent.MOUSE_MOVED, 350, 350));
 509 
 510         assertFalse(scene.smallSquareTracker.wasEnteredMe());
 511         assertFalse(scene.bigSquareTracker.wasEnteredMe());
 512         assertFalse(scene.groupTracker.wasEnteredMe());
 513         assertTrue(scene.smallSquareTracker.wasExitedMe());
 514         assertFalse(scene.bigSquareTracker.wasExitedMe());
 515         assertTrue(scene.groupTracker.wasExitedMe());
 516         assertFalse(scene.smallSquareTracker.wasEnteredChild());
 517         assertFalse(scene.bigSquareTracker.wasEnteredChild());
 518         assertFalse(scene.groupTracker.wasEnteredChild());
 519         assertFalse(scene.smallSquareTracker.wasExitedChild());
 520         assertFalse(scene.bigSquareTracker.wasExitedChild());
 521         assertTrue(scene.groupTracker.wasExitedChild());
 522     }
 523 
 524     @Test
 525     public void platformCursorShouldBeUpdated() {
 526         SimpleTestScene scene = new SimpleTestScene();
 527         MouseEventGenerator generator = new MouseEventGenerator();
 528 
 529         scene.processEvent(generator.generateMouseEvent(
 530                 MouseEvent.MOUSE_MOVED, 250, 250));
 531 
 532         assertSame(CursorShim.getCurrentFrame(Cursor.HAND), scene.getCursorFrame());
 533 
 534         scene.processEvent(generator.generateMouseEvent(
 535                 MouseEvent.MOUSE_MOVED, 150, 150));
 536 
 537         assertSame(CursorShim.getCurrentFrame(Cursor.TEXT), scene.getCursorFrame());
 538 
 539         scene.processEvent(generator.generateMouseEvent(
 540                 MouseEvent.MOUSE_MOVED, 50, 50));
 541 
 542         assertSame(CursorShim.getCurrentFrame(Cursor.DEFAULT),
 543                    scene.getCursorFrame());
 544     }
 545 
 546     @Test
 547     public void platformCursorShouldBeUpdatedOnPulse() {
 548 
 549         final StubToolkit toolkit = (StubToolkit) Toolkit.getToolkit();
 550         SimpleTestScene scene = new SimpleTestScene();
 551         MouseEventGenerator generator = new MouseEventGenerator();
 552 
 553         scene.processEvent(generator.generateMouseEvent(
 554                 MouseEvent.MOUSE_MOVED, 250, 250));
 555 
 556         assertSame(CursorShim.getCurrentFrame(Cursor.HAND), scene.getCursorFrame());
 557 
 558         scene.scene.setCursor(Cursor.TEXT);
 559         toolkit.firePulse();
 560         assertSame(CursorShim.getCurrentFrame(Cursor.TEXT), scene.getCursorFrame());
 561 
 562     }
 563 
 564     @Test
 565     public void testHover() {
 566         SimpleTestScene scene = new SimpleTestScene();
 567         MouseEventGenerator generator = new MouseEventGenerator();
 568 
 569         scene.processEvent(generator.generateMouseEvent(
 570                 MouseEvent.MOUSE_MOVED, 250, 250));
 571 
 572         assertTrue(scene.smallSquareTracker.isHover());
 573         assertFalse(scene.bigSquareTracker.isHover());
 574         assertTrue(scene.groupTracker.isHover());
 575 
 576         scene.processEvent(generator.generateMouseEvent(
 577                 MouseEvent.MOUSE_MOVED, 150, 150));
 578 
 579         assertFalse(scene.smallSquareTracker.isHover());
 580         assertTrue(scene.bigSquareTracker.isHover());
 581         assertTrue(scene.groupTracker.isHover());
 582 
 583         scene.processEvent(generator.generateMouseEvent(
 584                 MouseEvent.MOUSE_MOVED, 50, 50));
 585 
 586         assertFalse(scene.smallSquareTracker.isHover());
 587         assertFalse(scene.bigSquareTracker.isHover());
 588         assertFalse(scene.groupTracker.isHover());
 589     }
 590 
 591     @Test
 592     public void clickShouldBeGeneratedFromPressRelease() {
 593         SimpleTestScene scene = new SimpleTestScene();
 594         MouseEventGenerator generator = new MouseEventGenerator();
 595 
 596         scene.processEvent(generator.generateMouseEvent(
 597                 MouseEvent.MOUSE_PRESSED, 250, 250));
 598         scene.processEvent(generator.generateMouseEvent(
 599                 MouseEvent.MOUSE_RELEASED, 250, 250));
 600 
 601         assertTrue(scene.smallSquareTracker.wasClicked());
 602         assertFalse(scene.bigSquareTracker.wasClicked());
 603         assertTrue(scene.groupTracker.wasClicked());
 604     }
 605 
 606     @Test
 607     public void clickShouldBeGeneratedWhenReleasedOnTheSameNode() {
 608         SimpleTestScene scene = new SimpleTestScene();
 609         MouseEventGenerator generator = new MouseEventGenerator();
 610 
 611         scene.processEvent(generator.generateMouseEvent(
 612                 MouseEvent.MOUSE_PRESSED, 250, 250));
 613         scene.processEvent(generator.generateMouseEvent(
 614                 MouseEvent.MOUSE_DRAGGED, 50, 50));
 615         scene.processEvent(generator.generateMouseEvent(
 616                 MouseEvent.MOUSE_DRAGGED, 270, 270));
 617         scene.processEvent(generator.generateMouseEvent(
 618                 MouseEvent.MOUSE_RELEASED, 270, 270));
 619 
 620         assertTrue(scene.smallSquareTracker.wasClicked());
 621         assertFalse(scene.bigSquareTracker.wasClicked());
 622         assertTrue(scene.groupTracker.wasClicked());
 623     }
 624 
 625     @Test
 626     public void clickShouldBeGeneratedWhenReleasedOnParent() {
 627         SimpleTestScene scene = new SimpleTestScene();
 628         MouseEventGenerator generator = new MouseEventGenerator();
 629 
 630         scene.processEvent(generator.generateMouseEvent(
 631                 MouseEvent.MOUSE_PRESSED, 250, 250));
 632         scene.processEvent(generator.generateMouseEvent(
 633                 MouseEvent.MOUSE_DRAGGED, 150, 150));
 634         scene.processEvent(generator.generateMouseEvent(
 635                 MouseEvent.MOUSE_RELEASED, 150, 150));
 636 
 637         assertFalse(scene.smallSquareTracker.wasClicked());
 638         assertFalse(scene.bigSquareTracker.wasClicked());
 639         assertTrue(scene.groupTracker.wasClicked());
 640     }
 641 
 642     @Test
 643     public void doubleClickShouldBeGeneratedFromPressedReleasedTwoTimes() {
 644         SimpleTestScene scene = new SimpleTestScene();
 645         MouseEventGenerator generator = new MouseEventGenerator();
 646 
 647         scene.processEvent(generator.generateMouseEvent(
 648                 MouseEvent.MOUSE_PRESSED, 250, 250));
 649         scene.processEvent(generator.generateMouseEvent(
 650                 MouseEvent.MOUSE_RELEASED, 250, 250));
 651         scene.processEvent(generator.generateMouseEvent(
 652                 MouseEvent.MOUSE_PRESSED, 250, 250));
 653         scene.processEvent(generator.generateMouseEvent(
 654                 MouseEvent.MOUSE_RELEASED, 250, 250));
 655 
 656         assertTrue(scene.smallSquareTracker.wasDoubleClicked());
 657         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 658         assertTrue(scene.groupTracker.wasDoubleClicked());
 659     }
 660 
 661     @Test
 662     public void doubleClickShouldBeGeneratedEvenIfNodeChangesInBetween() {
 663         SimpleTestScene scene = new SimpleTestScene();
 664         MouseEventGenerator generator = new MouseEventGenerator();
 665 
 666         scene.processEvent(generator.generateMouseEvent(
 667                 MouseEvent.MOUSE_PRESSED, 199, 250));
 668         scene.processEvent(generator.generateMouseEvent(
 669                 MouseEvent.MOUSE_RELEASED, 199, 250));
 670         scene.processEvent(generator.generateMouseEvent(
 671                 MouseEvent.MOUSE_PRESSED, 201, 250));
 672         scene.processEvent(generator.generateMouseEvent(
 673                 MouseEvent.MOUSE_RELEASED, 201, 250));
 674 
 675         assertTrue(scene.smallSquareTracker.wasDoubleClicked());
 676         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 677         assertTrue(scene.bigSquareTracker.wasClicked());
 678     }
 679 
 680     @Test
 681     public void doubleClickShouldBeGeneratedFromPressedReleasedTwoTimesWithHysteresis() {
 682         SimpleTestScene scene = new SimpleTestScene();
 683         MouseEventGenerator generator = new MouseEventGenerator();
 684 
 685         scene.processEvent(generator.generateMouseEvent(
 686                 MouseEvent.MOUSE_PRESSED, 250, 250));
 687         scene.processEvent(generator.generateMouseEvent(
 688                 MouseEvent.MOUSE_DRAGGED, 251, 251));
 689         scene.processEvent(generator.generateMouseEvent(
 690                 MouseEvent.MOUSE_RELEASED, 251, 251));
 691         scene.processEvent(generator.generateMouseEvent(
 692                 MouseEvent.MOUSE_DRAGGED, 252, 252));
 693         scene.processEvent(generator.generateMouseEvent(
 694                 MouseEvent.MOUSE_PRESSED, 252, 252));
 695         scene.processEvent(generator.generateMouseEvent(
 696                 MouseEvent.MOUSE_DRAGGED, 253, 253));
 697         scene.processEvent(generator.generateMouseEvent(
 698                 MouseEvent.MOUSE_RELEASED, 253, 253));
 699 
 700         assertTrue(scene.smallSquareTracker.wasDoubleClicked());
 701         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 702         assertTrue(scene.groupTracker.wasDoubleClicked());
 703     }
 704 
 705     @Test
 706     public void doubleClickShouldNotBeGeneratedWhenMovedFarAwayBetweenClick() {
 707         SimpleTestScene scene = new SimpleTestScene();
 708         MouseEventGenerator generator = new MouseEventGenerator();
 709 
 710         scene.processEvent(generator.generateMouseEvent(
 711                 MouseEvent.MOUSE_PRESSED, 250, 250));
 712         scene.processEvent(generator.generateMouseEvent(
 713                 MouseEvent.MOUSE_RELEASED, 250, 250));
 714         scene.processEvent(generator.generateMouseEvent(
 715                 MouseEvent.MOUSE_DRAGGED, 258, 258));
 716         scene.processEvent(generator.generateMouseEvent(
 717                 MouseEvent.MOUSE_PRESSED, 258, 258));
 718         scene.processEvent(generator.generateMouseEvent(
 719                 MouseEvent.MOUSE_RELEASED, 258, 258));
 720 
 721         assertTrue(scene.smallSquareTracker.wasClicked());
 722         assertFalse(scene.bigSquareTracker.wasClicked());
 723         assertTrue(scene.groupTracker.wasClicked());
 724         assertFalse(scene.smallSquareTracker.wasDoubleClicked());
 725         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 726         assertFalse(scene.groupTracker.wasDoubleClicked());
 727     }
 728 
 729     @Test
 730     public void doubleClickShouldNotBeGeneratedWhenMovedFarAwayInFirstClick() {
 731         SimpleTestScene scene = new SimpleTestScene();
 732         MouseEventGenerator generator = new MouseEventGenerator();
 733 
 734         scene.processEvent(generator.generateMouseEvent(
 735                 MouseEvent.MOUSE_PRESSED, 250, 250));
 736         scene.processEvent(generator.generateMouseEvent(
 737                 MouseEvent.MOUSE_DRAGGED, 258, 258));
 738         scene.processEvent(generator.generateMouseEvent(
 739                 MouseEvent.MOUSE_RELEASED, 258, 258));
 740         scene.processEvent(generator.generateMouseEvent(
 741                 MouseEvent.MOUSE_PRESSED, 258, 258));
 742         scene.processEvent(generator.generateMouseEvent(
 743                 MouseEvent.MOUSE_RELEASED, 258, 258));
 744 
 745         assertTrue(scene.smallSquareTracker.wasClicked());
 746         assertFalse(scene.bigSquareTracker.wasClicked());
 747         assertTrue(scene.groupTracker.wasClicked());
 748         assertFalse(scene.smallSquareTracker.wasDoubleClicked());
 749         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 750         assertFalse(scene.groupTracker.wasDoubleClicked());
 751     }
 752 
 753     @Test
 754     public void doubleClickShouldBeGeneratedWhenMovedFarAwayInSecondClick() {
 755         SimpleTestScene scene = new SimpleTestScene();
 756         MouseEventGenerator generator = new MouseEventGenerator();
 757 
 758         scene.processEvent(generator.generateMouseEvent(
 759                 MouseEvent.MOUSE_PRESSED, 250, 250));
 760         scene.processEvent(generator.generateMouseEvent(
 761                 MouseEvent.MOUSE_RELEASED, 250, 250));
 762         scene.processEvent(generator.generateMouseEvent(
 763                 MouseEvent.MOUSE_PRESSED, 250, 250));
 764         scene.processEvent(generator.generateMouseEvent(
 765                 MouseEvent.MOUSE_DRAGGED, 258, 258));
 766         scene.processEvent(generator.generateMouseEvent(
 767                 MouseEvent.MOUSE_RELEASED, 258, 258));
 768 
 769         assertTrue(scene.smallSquareTracker.wasDoubleClicked());
 770         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 771         assertTrue(scene.groupTracker.wasDoubleClicked());
 772     }
 773 
 774     @Test
 775     public void doubleClickShouldNotBeGeneratedWithLongTimeBetweenClicks() {
 776         SimpleTestScene scene = new SimpleTestScene();
 777         MouseEventGenerator generator = new MouseEventGenerator();
 778 
 779         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(0);
 780 
 781         scene.processEvent(generator.generateMouseEvent(
 782                 MouseEvent.MOUSE_PRESSED, 250, 250));
 783         scene.processEvent(generator.generateMouseEvent(
 784                 MouseEvent.MOUSE_RELEASED, 250, 250));
 785 
 786         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(2000);
 787 
 788         scene.processEvent(generator.generateMouseEvent(
 789                 MouseEvent.MOUSE_PRESSED, 250, 250));
 790         scene.processEvent(generator.generateMouseEvent(
 791                 MouseEvent.MOUSE_RELEASED, 250, 250));
 792 
 793         assertTrue(scene.smallSquareTracker.wasClicked());
 794         assertFalse(scene.bigSquareTracker.wasClicked());
 795         assertTrue(scene.groupTracker.wasClicked());
 796         assertFalse(scene.smallSquareTracker.wasDoubleClicked());
 797         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 798         assertFalse(scene.groupTracker.wasDoubleClicked());
 799     }
 800 
 801     @Test
 802     public void doubleClickShouldNotBeGeneratedWithLongTimeInFirstClick() {
 803         SimpleTestScene scene = new SimpleTestScene();
 804         MouseEventGenerator generator = new MouseEventGenerator();
 805 
 806         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(0);
 807 
 808         scene.processEvent(generator.generateMouseEvent(
 809                 MouseEvent.MOUSE_PRESSED, 250, 250));
 810 
 811         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(2000);
 812 
 813         scene.processEvent(generator.generateMouseEvent(
 814                 MouseEvent.MOUSE_RELEASED, 250, 250));
 815         scene.processEvent(generator.generateMouseEvent(
 816                 MouseEvent.MOUSE_PRESSED, 250, 250));
 817         scene.processEvent(generator.generateMouseEvent(
 818                 MouseEvent.MOUSE_RELEASED, 250, 250));
 819 
 820         assertTrue(scene.smallSquareTracker.wasClicked());
 821         assertFalse(scene.bigSquareTracker.wasClicked());
 822         assertTrue(scene.groupTracker.wasClicked());
 823         assertFalse(scene.smallSquareTracker.wasDoubleClicked());
 824         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 825         assertFalse(scene.groupTracker.wasDoubleClicked());
 826     }
 827 
 828     @Test
 829     public void doubleClickShouldBeGeneratedWithLongTimeInSecondClick() {
 830         SimpleTestScene scene = new SimpleTestScene();
 831         MouseEventGenerator generator = new MouseEventGenerator();
 832 
 833         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(0);
 834 
 835         scene.processEvent(generator.generateMouseEvent(
 836                 MouseEvent.MOUSE_PRESSED, 250, 250));
 837         scene.processEvent(generator.generateMouseEvent(
 838                 MouseEvent.MOUSE_RELEASED, 250, 250));
 839         scene.processEvent(generator.generateMouseEvent(
 840                 MouseEvent.MOUSE_PRESSED, 250, 250));
 841 
 842         ((StubToolkit) Toolkit.getToolkit()).setAnimationTime(2000);
 843 
 844         scene.processEvent(generator.generateMouseEvent(
 845                 MouseEvent.MOUSE_RELEASED, 250, 250));
 846 
 847         assertTrue(scene.smallSquareTracker.wasDoubleClicked());
 848         assertFalse(scene.bigSquareTracker.wasDoubleClicked());
 849         assertTrue(scene.groupTracker.wasDoubleClicked());
 850     }
 851 
 852     @Test
 853     public void testClickCountOfMouseEvents() {
 854         SimpleTestScene scene = new SimpleTestScene();
 855         MouseEventGenerator generator = new MouseEventGenerator();
 856 
 857         scene.processEvent(generator.generateMouseEvent(
 858                 MouseEvent.MOUSE_MOVED, 250, 250));
 859         assertEquals(0, scene.smallSquareTracker.getLastClickCount());
 860         scene.smallSquareTracker.clear();
 861 
 862         scene.processEvent(generator.generateMouseEvent(
 863                 MouseEvent.MOUSE_PRESSED, 250, 250));
 864         assertEquals(1, scene.smallSquareTracker.getLastClickCount());
 865         scene.smallSquareTracker.clear();
 866 
 867         scene.processEvent(generator.generateMouseEvent(
 868                 MouseEvent.MOUSE_DRAGGED, 251, 251));
 869         assertEquals(1, scene.smallSquareTracker.getLastClickCount());
 870         scene.smallSquareTracker.clear();
 871 
 872         scene.processEvent(generator.generateMouseEvent(
 873                 MouseEvent.MOUSE_RELEASED, 251, 251));
 874         assertEquals(1, scene.smallSquareTracker.getLastClickCount());
 875         scene.smallSquareTracker.clear();
 876 
 877         scene.processEvent(generator.generateMouseEvent(
 878                 MouseEvent.MOUSE_MOVED, 252, 252));
 879         assertEquals(0, scene.smallSquareTracker.getLastClickCount());
 880         scene.smallSquareTracker.clear();
 881 
 882         scene.processEvent(generator.generateMouseEvent(
 883                 MouseEvent.MOUSE_PRESSED, 252, 252));
 884         assertEquals(2, scene.smallSquareTracker.getLastClickCount());
 885         scene.smallSquareTracker.clear();
 886 
 887         scene.processEvent(generator.generateMouseEvent(
 888                 MouseEvent.MOUSE_DRAGGED, 280, 280));
 889         assertEquals(2, scene.smallSquareTracker.getLastClickCount());
 890         scene.smallSquareTracker.clear();
 891 
 892         scene.processEvent(generator.generateMouseEvent(
 893                 MouseEvent.MOUSE_RELEASED, 280, 280));
 894         assertEquals(2, scene.smallSquareTracker.getLastClickCount());
 895         scene.smallSquareTracker.clear();
 896 
 897         scene.processEvent(generator.generateMouseEvent(
 898                 MouseEvent.MOUSE_MOVED, 280, 280));
 899         assertEquals(0, scene.smallSquareTracker.getLastClickCount());
 900         scene.smallSquareTracker.clear();
 901 
 902         scene.processEvent(generator.generateMouseEvent(
 903                 MouseEvent.MOUSE_PRESSED, 280, 280));
 904         assertEquals(1, scene.smallSquareTracker.getLastClickCount());
 905         scene.smallSquareTracker.clear();
 906 
 907         scene.processEvent(generator.generateMouseEvent(
 908                 MouseEvent.MOUSE_RELEASED, 280, 280));
 909         assertEquals(1, scene.smallSquareTracker.getLastClickCount());
 910         scene.smallSquareTracker.clear();
 911     }
 912 
 913     @Test
 914     public void testIsStillOfMouseEvents() {
 915         SimpleTestScene scene = new SimpleTestScene();
 916         MouseEventGenerator generator = new MouseEventGenerator();
 917 
 918         scene.processEvent(generator.generateMouseEvent(
 919                 MouseEvent.MOUSE_MOVED, 250, 250));
 920         assertFalse(scene.smallSquareTracker.wasLastStill());
 921 
 922         scene.processEvent(generator.generateMouseEvent(
 923                 MouseEvent.MOUSE_PRESSED, 250, 250));
 924         assertFalse(scene.smallSquareTracker.wasLastStill());
 925 
 926         scene.processEvent(generator.generateMouseEvent(
 927                 MouseEvent.MOUSE_DRAGGED, 252, 252));
 928         assertTrue(scene.smallSquareTracker.wasLastStill());
 929 
 930         scene.processEvent(generator.generateMouseEvent(
 931                 MouseEvent.MOUSE_RELEASED, 252, 252));
 932         assertTrue(scene.smallSquareTracker.wasLastStill());
 933 
 934         scene.processEvent(generator.generateMouseEvent(
 935                 MouseEvent.MOUSE_MOVED, 254, 254));
 936         assertTrue(scene.smallSquareTracker.wasLastStill());
 937 
 938         scene.processEvent(generator.generateMouseEvent(
 939                 MouseEvent.MOUSE_PRESSED, 254, 254));
 940         assertTrue(scene.smallSquareTracker.wasLastStill());
 941 
 942         scene.processEvent(generator.generateMouseEvent(
 943                 MouseEvent.MOUSE_DRAGGED, 257, 257));
 944         assertTrue(scene.smallSquareTracker.wasLastStill());
 945 
 946         scene.processEvent(generator.generateMouseEvent(
 947                 MouseEvent.MOUSE_DRAGGED, 265, 265));
 948         assertFalse(scene.smallSquareTracker.wasLastStill());
 949 
 950         scene.processEvent(generator.generateMouseEvent(
 951                 MouseEvent.MOUSE_RELEASED, 265, 265));
 952         assertFalse(scene.smallSquareTracker.wasLastStill());
 953 
 954         scene.processEvent(generator.generateMouseEvent(
 955                 MouseEvent.MOUSE_MOVED, 266, 266));
 956         assertFalse(scene.smallSquareTracker.wasLastStill());
 957 
 958         scene.processEvent(generator.generateMouseEvent(
 959                 MouseEvent.MOUSE_PRESSED, 266, 266));
 960         assertFalse(scene.smallSquareTracker.wasLastStill());
 961 
 962         scene.processEvent(generator.generateMouseEvent(
 963                 MouseEvent.MOUSE_RELEASED, 266, 266));
 964         assertTrue(scene.smallSquareTracker.wasLastStill());
 965     }
 966 
 967     @Test
 968     public void nodeMovementsWithStillMouseShouldFireEnteredExited() {
 969         SimpleTestScene scene = new SimpleTestScene();
 970         MouseEventGenerator generator = new MouseEventGenerator();
 971 
 972         scene.processEvent(generator.generateMouseEvent(
 973                 MouseEvent.MOUSE_ENTERED, 250, 250));
 974         scene.processEvent(generator.generateMouseEvent(
 975                 MouseEvent.MOUSE_MOVED, 250, 250));
 976         scene.smallSquareTracker.clear();
 977 
 978         assertFalse(scene.smallSquareTracker.exitedMe);
 979         ((Rectangle) scene.smallSquareTracker.node).setX(400);
 980         ((StubToolkit) Toolkit.getToolkit()).firePulse();
 981         assertTrue(scene.smallSquareTracker.exitedMe);
 982 
 983         scene.smallSquareTracker.clear();
 984 
 985         assertFalse(scene.smallSquareTracker.enteredMe);
 986         ((Rectangle) scene.smallSquareTracker.node).setX(200);
 987         ((StubToolkit) Toolkit.getToolkit()).firePulse();
 988         assertTrue(scene.smallSquareTracker.enteredMe);
 989     }
 990 
 991     @Test
 992     public void nodeWithNoninvertibleTransformShouldGetNanCoords() {
 993         SimpleTestScene scene = new SimpleTestScene();
 994         MouseEventGenerator generator = new MouseEventGenerator();
 995 
 996         scene.processEvent(generator.generateMouseEvent(
 997                 MouseEvent.MOUSE_PRESSED, 250, 250));
 998         scene.smallSquareTracker.clear();
 999 
1000         scene.smallSquareTracker.node.addEventHandler(MouseEvent.MOUSE_RELEASED,
1001                 event -> {
1002                     Assert.assertEquals(Double.NaN, event.getX(), 0.0001);
1003                     Assert.assertEquals(Double.NaN, event.getY(), 0.0001);
1004                     Assert.assertEquals(251.0, event.getSceneX(), 0.0001);
1005                     Assert.assertEquals(251.0, event.getSceneY(), 0.0001);
1006                 }
1007         );
1008 
1009         ((Rectangle) scene.smallSquareTracker.node).setScaleX(0);
1010 
1011         scene.processEvent(generator.generateMouseEvent(
1012                 MouseEvent.MOUSE_RELEASED, 251, 251));
1013 
1014         assertTrue(scene.smallSquareTracker.released);
1015     }
1016 
1017     @Test
1018     public void topMostNodeShouldBePickedWithDepthBufferByPerspectiveCamera() {
1019         SimpleTestScene scene = new SimpleTestScene(true, true);
1020         MouseEventGenerator generator = new MouseEventGenerator();
1021 
1022         scene.processEvent(generator.generateMouseEvent(
1023                 MouseEvent.MOUSE_MOVED, 250, 250));
1024 
1025         assertFalse(scene.smallSquareTracker.wasMoved());
1026         assertTrue(scene.bigSquareTracker.wasMoved());
1027         assertTrue(scene.groupTracker.wasMoved());
1028     }
1029 
1030     @Test
1031     public void topMostNodeShouldBePickedWithDepthBufferByParallelCamera() {
1032         SimpleTestScene scene = new SimpleTestScene(true, false);
1033         MouseEventGenerator generator = new MouseEventGenerator();
1034 
1035         scene.processEvent(generator.generateMouseEvent(
1036                 MouseEvent.MOUSE_MOVED, 250, 250));
1037 
1038         assertFalse(scene.smallSquareTracker.wasMoved());
1039         assertTrue(scene.bigSquareTracker.wasMoved());
1040         assertTrue(scene.groupTracker.wasMoved());
1041     }
1042 
1043     @Test
1044     public void subSceneShouldBePickedOnFill() {
1045         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1046 
1047         s.subScene1.setFill(Color.BLACK);
1048 
1049         s.scene.addEventFilter(MouseEvent.MOUSE_MOVED,
1050                 s.handler(s.subScene1, DONT_TEST, DONT_TEST));
1051 
1052         s.processEvent(MouseEvent.MOUSE_MOVED, 22, 12);
1053         s.assertCalled();
1054     }
1055 
1056     @Test
1057     public void subSceneShouldNotBePickedWithoutFill() {
1058         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1059 
1060         s.scene.addEventFilter(MouseEvent.MOUSE_MOVED,
1061                 s.handler(s.scene, DONT_TEST, DONT_TEST));
1062 
1063         s.processEvent(MouseEvent.MOUSE_MOVED, 22, 12);
1064         s.assertCalled();
1065     }
1066 
1067     @Test
1068     public void eventShouldBubbleOutOfSubScene() {
1069         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1070 
1071         s.parent1.setOnMouseMoved(s.handler(s.innerRect1, 120, 20));
1072 
1073         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1074         s.assertCalled();
1075     }
1076 
1077     @Test
1078     public void enteredEventShouldBeGeneratedInsideSubScene() {
1079         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1080 
1081         s.innerRect1.setOnMouseEntered(s.handler(s.innerRect1, 10, 10));
1082 
1083         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1084         s.assertCalled();
1085     }
1086 
1087     @Test
1088     public void enteredEventShouldBubbleOutOfSubScene() {
1089         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1090 
1091         s.parent1.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET,
1092                 event -> {
1093                     if (event.getTarget() == s.innerRect1) {
1094                         s.called = true;
1095                     }
1096                 }
1097         );
1098 
1099         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1100         s.assertCalled();
1101     }
1102 
1103     @Test
1104     public void enteredEventShouldBeGeneratedOutsideSubScene() {
1105         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1106 
1107         s.parent1.setOnMouseEntered(s.handler(s.parent1, 120, 20));
1108 
1109         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1110         s.assertCalled();
1111     }
1112 
1113     @Test
1114     public void exitedEventShouldBeGeneratedInsideSubScene() {
1115         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1116 
1117         s.innerRect1.setOnMouseExited(s.handler(s.innerRect1, 60, 10));
1118 
1119         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1120         s.processEvent(MouseEvent.MOUSE_MOVED, 180, 30);
1121         s.assertCalled();
1122     }
1123 
1124     @Test
1125     public void exitedEventShouldBeGeneratedInsideSubSceneWhenMovedOut() {
1126         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1127 
1128         s.innerRect1.setOnMouseExited(s.handler(s.innerRect1, 60, -15));
1129 
1130         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1131         s.processEvent(MouseEvent.MOUSE_MOVED, 180, 5);
1132         s.assertCalled();
1133     }
1134 
1135     @Test
1136     public void exitedEventShouldBeGeneratedInsideSubSceneWhenMovedToOtherSubScene() {
1137         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1138 
1139         s.innerRect1.setOnMouseExited(s.handler(s.innerRect1, 240, 10));
1140 
1141         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1142         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1143         s.assertCalled();
1144     }
1145 
1146     @Test
1147     public void cursorShouldBePropagatedFromSubScene() {
1148         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1149 
1150         s.innerRect1.setCursor(Cursor.HAND);
1151         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1152         assertSame(CursorShim.getCurrentFrame(Cursor.HAND), s.getCursorFrame());
1153     }
1154 
1155     @Test
1156     public void cursorShouldBeTakenFromOutsideOfSubScene() {
1157         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1158 
1159         s.parent1.setCursor(Cursor.HAND);
1160         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1161         assertSame(CursorShim.getCurrentFrame(Cursor.HAND), s.getCursorFrame());
1162     }
1163 
1164     @Test
1165     public void coordinatesShouldBeFineWhenDraggedOutOfSubSecne() {
1166         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1167 
1168         s.innerRect1.setOnMouseDragged(s.handler(s.innerRect1, 60, -15));
1169 
1170         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1171         s.processEvent(MouseEvent.MOUSE_PRESSED, 130, 30);
1172         s.processEvent(MouseEvent.MOUSE_DRAGGED, 180, 5);
1173         s.processEvent(MouseEvent.MOUSE_RELEASED, 180, 5);
1174 
1175         s.assertCalled();
1176         assertNotNull(s.lastPickResult);
1177         assertNull(s.lastPickResult.getIntersectedNode());
1178     }
1179 
1180     @Test
1181     public void coordinatesShouldBeFineWhenDraggedToOtherSubSecne() {
1182         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1183 
1184         s.innerRect1.setOnMouseDragged(s.handler(s.innerRect1, 240, 10));
1185 
1186         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1187         s.processEvent(MouseEvent.MOUSE_PRESSED, 130, 30);
1188         s.processEvent(MouseEvent.MOUSE_DRAGGED, 360, 30);
1189         s.processEvent(MouseEvent.MOUSE_RELEASED, 360, 30);
1190 
1191         s.assertCalled();
1192         assertNotNull(s.lastPickResult);
1193         assertSame(s.innerRect2, s.lastPickResult.getIntersectedNode());
1194     }
1195 
1196     @Test
1197     public void fullDragShouldDeliverToOtherSubScene() {
1198         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1199 
1200         s.innerRect1.setOnDragDetected(event -> s.innerRect1.startFullDrag());
1201         s.innerRect2.setOnMouseDragOver(s.handler(s.innerRect2, 10, 10));
1202 
1203         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1204         s.processEvent(MouseEvent.MOUSE_PRESSED, 130, 30);
1205         s.processEvent(MouseEvent.MOUSE_DRAGGED, 360, 29);
1206         s.processEvent(MouseEvent.MOUSE_DRAGGED, 360, 30);
1207         s.processEvent(MouseEvent.MOUSE_RELEASED, 360, 30);
1208 
1209         s.assertCalled();
1210     }
1211 
1212     @Test
1213     public void fullDragEnterShouldDeliverToOtherSubScene() {
1214         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1215 
1216         s.innerRect1.setOnDragDetected(event -> s.innerRect1.startFullDrag());
1217         s.innerRect2.setOnMouseDragEntered(s.handler(s.innerRect2, 10, 10));
1218 
1219         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1220         s.processEvent(MouseEvent.MOUSE_PRESSED, 130, 30);
1221         s.processEvent(MouseEvent.MOUSE_DRAGGED, 360, 30);
1222         s.processEvent(MouseEvent.MOUSE_RELEASED, 360, 30);
1223 
1224         s.assertCalled();
1225     }
1226 
1227     @Test
1228     public void fullDragEnterShouldDeliverToOtherSubScenesParent() {
1229         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1230 
1231         s.innerRect1.setOnDragDetected(event -> s.innerRect1.startFullDrag());
1232         s.parent2.setOnMouseDragEntered(s.handler(s.parent2, 130, 20));
1233 
1234         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1235         s.processEvent(MouseEvent.MOUSE_PRESSED, 130, 30);
1236         s.processEvent(MouseEvent.MOUSE_DRAGGED, 360, 30);
1237         s.processEvent(MouseEvent.MOUSE_RELEASED, 360, 30);
1238 
1239         s.assertCalled();
1240     }
1241 
1242     @Test
1243     public void depthBufferShouldWorkInsideSubScene() {
1244         final TestSceneWithSubScenes s = new TestSceneWithSubScenes(false, true);
1245 
1246         Rectangle r = new Rectangle(50, 50);
1247         r.setTranslateX(100);
1248         r.setTranslateY(10);
1249         r.setTranslateZ(1);
1250         ParentShim.getChildren(s.subScene1.getRoot()).add(r);
1251 
1252         s.innerRect1.addEventFilter(MouseEvent.MOUSE_MOVED,
1253                 s.handler(s.innerRect1, DONT_TEST, DONT_TEST));
1254 
1255         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1256         s.assertCalled();
1257     }
1258 
1259     @Test
1260     public void sceneDepthBufferShouldNotInfluenceSubSceneDepthBuffer() {
1261         final TestSceneWithSubScenes s = new TestSceneWithSubScenes(true, false);
1262 
1263         Rectangle r = new Rectangle(50, 50);
1264         r.setTranslateX(100);
1265         r.setTranslateY(10);
1266         r.setTranslateZ(1);
1267         ParentShim.getChildren(s.subScene1.getRoot()).add(r);
1268 
1269         r.addEventFilter(MouseEvent.MOUSE_MOVED,
1270                 s.handler(r, DONT_TEST, DONT_TEST));
1271 
1272         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1273         s.assertCalled();
1274     }
1275 
1276     @Test
1277     public void sceneShouldConsiderSubScenesFlat() {
1278         final TestSceneWithSubScenes s = new TestSceneWithSubScenes(false, true);
1279 
1280         s.parent2.setTranslateX(10);
1281         s.innerRect2.setTranslateZ(-10);
1282         s.parent2.setTranslateZ(1);
1283 
1284         s.innerRect2.addEventFilter(MouseEvent.MOUSE_MOVED,
1285                 s.handler(s.innerRect2, DONT_TEST, DONT_TEST));
1286 
1287         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1288         s.assertCalled();
1289     }
1290 
1291     @Test
1292     public void coordinatesShouldBeFlattenedWhenBubblingOutOfSubScene() {
1293         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1294 
1295         s.subScene1.setTranslateZ(5);
1296         s.innerRect1.setTranslateZ(10);
1297 
1298         s.parent1.setOnMouseMoved(event -> {
1299             Assert.assertEquals(5, event.getZ(), 0.00001);
1300             assertSame(s.innerRect1, event.getTarget());
1301             s.called = true;
1302         });
1303 
1304         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1305         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1306         s.assertCalled();
1307     }
1308 
1309     @Test
1310     public void coordinatesShouldBeReComputedToSubScenePlane() {
1311         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1312 
1313         s.parent2.setTranslateZ(10);
1314         s.innerRect2.setTranslateZ(10);
1315 
1316         s.innerRect1.setOnMouseExited(s.handler(s.innerRect1, 240, 10));
1317 
1318         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1319         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1320         s.assertCalled();
1321     }
1322 
1323     @Test
1324     public void coordinatesShouldBeRecomputedToSubSceneProjectionPlane() {
1325         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1326 
1327         s.scene.setCamera(new PerspectiveCamera());
1328         s.subScene1.setCamera(new PerspectiveCamera());
1329         s.subScene2.setCamera(new PerspectiveCamera());
1330 
1331         s.subScene1.setRotationAxis(Rotate.Y_AXIS);
1332         s.subScene1.setRotate(45);
1333         s.subScene2.setRotationAxis(Rotate.Y_AXIS);
1334         s.subScene2.setRotate(-45);
1335         ((Group) s.subScene1.getRoot()).getChildren().add(s.subScene1.getCamera());
1336         s.subScene1.getCamera().setTranslateZ(-3.0);
1337 
1338         s.innerRect1.setOnMouseExited(event -> {
1339             assertSame(s.innerRect2, event.getPickResult().getIntersectedNode());
1340             assertSame(s.innerRect1, event.getTarget());
1341             Assert.assertEquals(16.58, event.getPickResult().getIntersectedPoint().getX(), 0.1);
1342             Assert.assertEquals(7.33, event.getPickResult().getIntersectedPoint().getY(), 0.1);
1343             Assert.assertEquals(0.0, event.getPickResult().getIntersectedPoint().getZ(), 0.0001);
1344             Assert.assertEquals(295.81, event.getX(), 0.1);
1345             Assert.assertEquals(57.64, event.getY(), 0.1);
1346             Assert.assertEquals(-3.0, event.getZ(), 0.1);
1347 
1348             s.called = true;
1349         });
1350 
1351         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1352         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1353         s.assertCalled();
1354     }
1355 
1356     @Test
1357     public void coordinatesShouldBeRecomputedToNodeLocalCoordsOfSubSceneProjectionPlane() {
1358         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1359 
1360         s.scene.setCamera(new PerspectiveCamera());
1361         s.subScene1.setCamera(new PerspectiveCamera());
1362         s.subScene2.setCamera(new PerspectiveCamera());
1363 
1364         s.subScene1.setRotationAxis(Rotate.Y_AXIS);
1365         s.subScene1.setRotate(45);
1366         s.innerRect1.setRotationAxis(Rotate.Y_AXIS);
1367         s.innerRect1.setRotate(-45);
1368         s.subScene2.setRotationAxis(Rotate.Y_AXIS);
1369         s.subScene2.setRotate(-45);
1370         s.innerRect2.setRotationAxis(Rotate.Y_AXIS);
1371         s.innerRect2.setRotate(45);
1372 
1373         s.innerRect1.setOnMouseExited(event -> {
1374             assertSame(s.innerRect2, event.getPickResult().getIntersectedNode());
1375             assertSame(s.innerRect1, event.getTarget());
1376             Assert.assertEquals(14.07, event.getPickResult().getIntersectedPoint().getX(), 0.1);
1377             Assert.assertEquals(5.97, event.getPickResult().getIntersectedPoint().getY(), 0.1);
1378             Assert.assertEquals(0.0, event.getPickResult().getIntersectedPoint().getZ(), 0.0001);
1379             Assert.assertEquals(216.49, event.getX(), 0.1);
1380             Assert.assertEquals(57.64, event.getY(), 0.1);
1381             Assert.assertEquals(-191.49, event.getZ(), 0.1);
1382 
1383             s.called = true;
1384         });
1385 
1386         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1387         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1388         s.assertCalled();
1389     }
1390 
1391     @Test
1392     public void ImpossibleToComputeSubSceneInnerNodeCoordsShouldResultInNaNs() {
1393         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1394 
1395         s.parent2.setTranslateZ(10);
1396         s.innerRect2.setTranslateZ(10);
1397 
1398         s.innerRect1.setOnMouseMoved(event -> s.innerRect1.setScaleX(0.0));
1399 
1400         s.innerRect1.setOnMouseExited(event -> {
1401             assertSame(s.innerRect1, event.getTarget());
1402             assertTrue(Double.isNaN(event.getX()));
1403             assertTrue(Double.isNaN(event.getY()));
1404             assertTrue(Double.isNaN(event.getZ()));
1405             s.called = true;
1406         });
1407 
1408         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1409         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1410         s.assertCalled();
1411     }
1412 
1413     @Test
1414     public void ImpossibleToComputeSubSceneCoordsShouldResultInNaNs() {
1415         final TestSceneWithSubScenes s = new TestSceneWithSubScenes();
1416 
1417         s.parent2.setTranslateZ(10);
1418         s.innerRect2.setTranslateZ(10);
1419 
1420         s.innerRect1.setOnMouseMoved(event -> {
1421             s.subScene1.setRotationAxis(Rotate.Y_AXIS);
1422             s.subScene1.setRotate(90);
1423         });
1424 
1425         s.innerRect1.setOnMouseExited(event -> {
1426             assertSame(s.innerRect1, event.getTarget());
1427             assertTrue(Double.isNaN(event.getX()));
1428             assertTrue(Double.isNaN(event.getY()));
1429             assertTrue(Double.isNaN(event.getZ()));
1430             s.called = true;
1431         });
1432 
1433         s.processEvent(MouseEvent.MOUSE_MOVED, 130, 30);
1434         s.processEvent(MouseEvent.MOUSE_MOVED, 360, 30);
1435         s.assertCalled();
1436     }
1437 
1438     @Test
1439     public void mouseExitedShouldBeGeneratedBeforeNodeRemoval() {
1440         final SimpleTestScene s = new SimpleTestScene();
1441         s.smallSquareTracker.node.addEventHandler(MouseEvent.MOUSE_EXITED,
1442                 event -> assertNotNull(s.smallSquareTracker.node.getScene())
1443         );
1444 
1445         s.processEvent(MouseEventGenerator.generateMouseEvent(
1446                 MouseEvent.MOUSE_MOVED, 250, 250));
1447         assertTrue(s.smallSquareTracker.enteredMe);
1448         assertFalse(s.smallSquareTracker.exitedMe);
1449 
1450         ParentShim.getChildren(s.scene.getRoot()).clear();
1451 
1452         assertTrue(s.smallSquareTracker.exitedMe);
1453     }
1454 
1455     @Test
1456     public void pdrGestureShouldHandleDraggedNodeRemoval() {
1457         final SimpleTestScene s = new SimpleTestScene();
1458 
1459         s.processEvent(MouseEventGenerator.generateMouseEvent(
1460                 MouseEvent.MOUSE_MOVED, 250, 250));
1461         assertTrue(s.smallSquareTracker.node.isHover());
1462         assertFalse(s.smallSquareTracker.node.isPressed());
1463 
1464         s.processEvent(MouseEventGenerator.generateMouseEvent(
1465                 MouseEvent.MOUSE_PRESSED, 250, 250));
1466         assertTrue(s.smallSquareTracker.node.isHover());
1467         assertTrue(s.smallSquareTracker.node.isPressed());
1468         assertTrue(s.smallSquareTracker.wasPressed());
1469         assertTrue(s.groupTracker.wasPressed());
1470 
1471         s.processEvent(MouseEventGenerator.generateMouseEvent(
1472                 MouseEvent.MOUSE_DRAGGED, 255, 255));
1473         assertTrue(s.smallSquareTracker.node.isHover());
1474         assertTrue(s.smallSquareTracker.node.isPressed());
1475         assertTrue(s.smallSquareTracker.wasDragged());
1476         assertTrue(s.groupTracker.wasDragged());
1477 
1478         s.smallSquareTracker.clear();
1479         s.groupTracker.clear();
1480         s.rootTracker.clear();
1481 
1482         ParentShim.getChildren(s.scene.getRoot()).clear();
1483         assertFalse(s.smallSquareTracker.node.isHover());
1484         assertFalse(s.smallSquareTracker.node.isPressed());
1485         assertFalse(s.groupTracker.node.isHover());
1486         assertFalse(s.groupTracker.node.isPressed());
1487         assertTrue(s.rootTracker.node.isHover());
1488         assertTrue(s.rootTracker.node.isPressed());
1489         assertTrue(s.smallSquareTracker.wasExitedMe());
1490         assertTrue(s.groupTracker.wasExitedMe());
1491         assertFalse(s.rootTracker.wasExitedMe());
1492 
1493         s.processEvent(MouseEventGenerator.generateMouseEvent(
1494                 MouseEvent.MOUSE_DRAGGED, 260, 260));
1495         assertFalse(s.smallSquareTracker.wasDragged());
1496         assertFalse(s.groupTracker.wasDragged());
1497         assertTrue(s.rootTracker.wasDragged());
1498 
1499         s.processEvent(MouseEventGenerator.generateMouseEvent(
1500                 MouseEvent.MOUSE_RELEASED, 270, 270));
1501         assertFalse(s.smallSquareTracker.wasReleased());
1502         assertFalse(s.groupTracker.wasReleased());
1503         assertTrue(s.rootTracker.wasReleased());
1504     }
1505 
1506     @Test
1507     public void testMouseEventCanEditCursor() {
1508         final SimpleTestScene s = new SimpleTestScene();
1509 
1510         s.smallSquare.setOnMousePressed(event -> s.smallSquare.setCursor(Cursor.CROSSHAIR));
1511 
1512         s.smallSquare.setOnMouseReleased(event -> s.smallSquare.setCursor(Cursor.WAIT));
1513 
1514         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_MOVED, 250, 250));
1515         assertSame(CursorShim.getCurrentFrame(Cursor.HAND), s.getCursorFrame());
1516         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 250, 250));
1517         assertSame(CursorShim.getCurrentFrame(Cursor.CROSSHAIR), s.getCursorFrame());
1518         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 250, 250));
1519         assertSame(CursorShim.getCurrentFrame(Cursor.WAIT), s.getCursorFrame());
1520 
1521         s.smallSquare.setOnMouseClicked(event -> s.smallSquare.setCursor(Cursor.TEXT));
1522 
1523         s.smallSquare.setCursor(Cursor.HAND);
1524 
1525         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_MOVED, 250, 250));
1526         assertSame(CursorShim.getCurrentFrame(Cursor.HAND), s.getCursorFrame());
1527         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_PRESSED, 250, 250));
1528         assertSame(CursorShim.getCurrentFrame(Cursor.CROSSHAIR), s.getCursorFrame());
1529         s.processEvent(MouseEventGenerator.generateMouseEvent(MouseEvent.MOUSE_RELEASED, 250, 250));
1530         assertSame(CursorShim.getCurrentFrame(Cursor.TEXT), s.getCursorFrame());
1531     }
1532 
1533     private static class SimpleTestScene {
1534 
1535         MouseEventTracker sceneTracker;
1536         MouseEventTracker rootTracker;
1537         MouseEventTracker groupTracker;
1538         MouseEventTracker bigSquareTracker;
1539         MouseEventTracker smallSquareTracker;
1540 
1541         Rectangle smallSquare;
1542         private boolean moused = false;
1543         private Scene scene;
1544 
1545         public SimpleTestScene() {
1546             this(false, false);
1547         }
1548 
1549         public SimpleTestScene(boolean depthBuffer, boolean perspective) {
1550             final Group root = new Group();
1551             scene = new Scene(root, 400, 400, depthBuffer);
1552             if (perspective) {
1553                 scene.setCamera(new PerspectiveCamera());
1554             }
1555 
1556             Group group = new Group();
1557             Rectangle bigSquare = new Rectangle(100, 100, 200, 200);
1558             smallSquare = new Rectangle(200, 200, 100, 100);
1559             bigSquare.setTranslateZ(-1);
1560 
1561             smallSquare.setCursor(Cursor.HAND);
1562             group.setCursor(Cursor.TEXT);
1563 
1564             ParentShim.getChildren(group).add(bigSquare);
1565             ParentShim.getChildren(group).add(smallSquare);
1566 
1567             ParentShim.getChildren(root).add(group);
1568 
1569             sceneTracker = new MouseEventTracker(scene);
1570             rootTracker = new MouseEventTracker(root);
1571             groupTracker = new MouseEventTracker(group);
1572             bigSquareTracker = new MouseEventTracker(bigSquare);
1573             smallSquareTracker = new MouseEventTracker(smallSquare);
1574 
1575             scene.addEventHandler(MouseEvent.ANY, event -> {
1576                 moused = true;
1577             });
1578 
1579             Stage stage = new Stage();
1580             stage.setScene(scene);
1581             stage.show();
1582         }
1583 
1584         public void processEvent(MouseEvent e) {
1585             scene.impl_processMouseEvent(e);
1586         }
1587 
1588         public Object getCursorFrame() {
1589             return ((StubScene) scene.impl_getPeer()).getCursor();
1590         }
1591 
1592         public boolean wasMoused() {
1593             return moused;
1594         }
1595 
1596         public void clear() {
1597             moused = false;
1598             sceneTracker.clear();
1599             groupTracker.clear();
1600             bigSquareTracker.clear();
1601             smallSquareTracker.clear();
1602         }
1603     }
1604 
1605     private static class MouseEventTracker {
1606 
1607         private Node node;
1608         private boolean pressed = false;
1609         private boolean released = false;
1610         private boolean clicked = false;
1611         private boolean doubleClicked = false;
1612         private boolean moved = false;
1613         private boolean dragged = false;
1614         private boolean enteredMe = false;
1615         private boolean exitedMe = false;
1616         private boolean enteredChild = false;
1617         private boolean exitedChild = false;
1618         private int lastClickCount = 0;
1619         private boolean lastIsStill = false;
1620 
1621         public MouseEventTracker(Node node) {
1622             this.node = node;
1623 
1624             node.setOnMousePressed(event -> {
1625                 pressed = true;
1626             });
1627 
1628             node.setOnMouseReleased(event -> {
1629                 released = true;
1630             });
1631 
1632             node.setOnMouseClicked(event -> {
1633                 if (event.getClickCount() == 1) {
1634                     clicked = true;
1635                 } else if (event.getClickCount() == 2) {
1636                     doubleClicked = true;
1637                 }
1638             });
1639 
1640             node.setOnMouseMoved(event -> {
1641                 moved = true;
1642             });
1643 
1644             node.setOnMouseDragged(event -> {
1645                 dragged = true;
1646             });
1647 
1648             node.addEventHandler(MouseEvent.MOUSE_ENTERED_TARGET, event -> {
1649                 if (event.getTarget() == MouseEventTracker.this.node) {
1650                     enteredMe = true;
1651                 } else {
1652                     enteredChild = true;
1653                 }
1654             });
1655 
1656             node.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, event -> {
1657                 if (event.getTarget() == MouseEventTracker.this.node) {
1658                     exitedMe = true;
1659                 } else {
1660                     exitedChild = true;
1661                 }
1662             });
1663 
1664             node.addEventHandler(MouseEvent.ANY, event -> {
1665                 if (event.getEventType() != MouseEvent.MOUSE_CLICKED) {
1666                     lastClickCount = event.getClickCount();
1667                     lastIsStill = event.isStillSincePress();
1668                 }
1669             });
1670         }
1671 
1672         public MouseEventTracker(Scene scene) {
1673             scene.setOnMouseEntered(event -> {
1674                 enteredMe = true;
1675             });
1676 
1677             scene.setOnMouseExited(event -> {
1678                 exitedMe = true;
1679             });
1680         }
1681 
1682         public boolean wasClicked() {
1683             return clicked;
1684         }
1685 
1686         public boolean wasDoubleClicked() {
1687             return doubleClicked;
1688         }
1689 
1690         public boolean wasDragged() {
1691             return dragged;
1692         }
1693 
1694         public boolean wasEnteredMe() {
1695             return enteredMe;
1696         }
1697 
1698         public boolean wasExitedMe() {
1699             return exitedMe;
1700         }
1701 
1702         public boolean wasMoved() {
1703             return moved;
1704         }
1705 
1706         public boolean wasPressed() {
1707             return pressed;
1708         }
1709 
1710         public boolean wasReleased() {
1711             return released;
1712         }
1713 
1714         public boolean wasEnteredChild() {
1715             return enteredChild;
1716         }
1717 
1718         public boolean wasExitedChild() {
1719             return exitedChild;
1720         }
1721 
1722         public boolean isHover() {
1723             return node.isHover();
1724         }
1725 
1726         public int getLastClickCount() {
1727             return lastClickCount;
1728         }
1729 
1730         public boolean wasLastStill() {
1731             return lastIsStill;
1732         }
1733 
1734         public void clear() {
1735             pressed = false;
1736             released = false;
1737             clicked = false;
1738             doubleClicked = false;
1739             moved = false;
1740             dragged = false;
1741             enteredMe = false;
1742             exitedMe = false;
1743             enteredChild = false;
1744             exitedChild = false;
1745             lastClickCount = 0;
1746         }
1747     }
1748 
1749     private static class TestSceneWithSubScenes {
1750         private SubScene subScene1, subScene2;
1751         private Rectangle innerRect1, innerRect2;
1752         private Group root, parent1, parent2;
1753         private Scene scene;
1754         private boolean called = false;
1755         private PickResult lastPickResult = null;
1756 
1757         public TestSceneWithSubScenes() {
1758             this(false, false);
1759         }
1760 
1761         public TestSceneWithSubScenes(boolean depthBuffer, boolean subDepthBuffer) {
1762             root = new Group();
1763             scene = new Scene(root, 500, 400, depthBuffer);
1764 
1765             innerRect1 = new Rectangle(50, 50);
1766             innerRect1.setTranslateX(100);
1767             innerRect1.setTranslateY(10);
1768             subScene1 = new SubScene(new Group(innerRect1), 200, 100,
1769                     subDepthBuffer, null);
1770             subScene1.setTranslateX(10);
1771             parent1 = new Group(subScene1);
1772             parent1.setTranslateX(10);
1773             parent1.setTranslateY(10);
1774 
1775             innerRect2 = new Rectangle(50, 50);
1776             innerRect2.setTranslateX(100);
1777             innerRect2.setTranslateY(10);
1778             subScene2 = new SubScene(new Group(innerRect2), 200, 100);
1779             subScene2.setTranslateX(20);
1780 
1781             parent2 = new Group(subScene2);
1782             parent2.setTranslateX(230);
1783             parent2.setTranslateY(10);
1784 
1785 
1786             ParentShim.getChildren(root).addAll(parent1, parent2);
1787 
1788             Stage stage = new Stage();
1789             stage.setScene(scene);
1790             stage.show();
1791         }
1792 
1793         public void processEvent(EventType<MouseEvent> type, double x, double y) {
1794             scene.impl_processMouseEvent(
1795                     MouseEventGenerator.generateMouseEvent(type, x, y));
1796         }
1797 
1798         public Object getCursorFrame() {
1799             return ((StubScene) scene.impl_getPeer()).getCursor();
1800         }
1801 
1802         public EventHandler<MouseEvent> handler(final EventTarget target,
1803                 final double x, final double y) {
1804 
1805             return event -> {
1806                 if (target != null) assertSame(target, event.getTarget());
1807                 if (x != DONT_TEST) assertEquals(x, event.getX(), 0.00001);
1808                 if (y != DONT_TEST) assertEquals(y, event.getY(), 0.00001);
1809                 assertEquals(0.0, event.getZ(), 0.00001);
1810                 lastPickResult = event.getPickResult();
1811                 called = true;
1812             };
1813         }
1814 
1815         public void assertCalled() {
1816             assertTrue(called);
1817         }
1818     }
1819 
1820 }