1 /* 2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. 3 * All rights reserved. Use is subject to license terms. 4 * 5 * This file is available and licensed under the following license: 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the distribution. 16 * - Neither the name of Oracle Corporation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package com.oracle.javafx.scenebuilder.kit.editor.drag.source; 33 34 import com.oracle.javafx.scenebuilder.kit.util.MathUtils; 35 import javafx.geometry.Bounds; 36 import javafx.geometry.Rectangle2D; 37 import javafx.scene.Group; 38 import javafx.scene.Node; 39 import javafx.scene.SnapshotParameters; 40 import javafx.scene.image.ImageView; 41 import javafx.scene.layout.Region; 42 import javafx.scene.transform.NonInvertibleTransformException; 43 import javafx.scene.transform.Transform; 44 45 /** 46 * A shadow is the following construct: 47 * 48 * Group 49 * ImageView snapshot of a 'scene graph node' 50 * Region glass area with css styling 51 * 52 * Layout bounds of the group must be equal to layout bounds 53 * of the scene graph node. We ensure this by setting layoutX/Y 54 * on the image view and the region (1). 55 */ 56 class DragSourceShadow extends Group { 57 58 private final ImageView imageView = new ImageView(); 59 private final Region glass = new Region(); 60 private static final String NID_DRAG_SHADOW = "dragShadow"; //NOI18N 61 62 63 public DragSourceShadow() { 64 this.setId(NID_DRAG_SHADOW); 65 this.getChildren().add(imageView); 66 this.getChildren().add(glass); 67 68 this.getStyleClass().add("drag-shadow"); //NOI18N 69 this.glass.getStyleClass().add("drag-shadow-glass"); //NOI18N 70 } 71 72 public void setupForNode(Node node) { 73 assert node != null; 74 assert node.getScene() != null; 75 76 // Snapshot node 77 // Note : we setup snapshot view port with layout bounds. 78 final SnapshotParameters sp = new SnapshotParameters(); 79 final Transform l2p = node.getLocalToParentTransform(); 80 try { 81 sp.setTransform(l2p.createInverse()); 82 } catch(NonInvertibleTransformException x) { 83 throw new RuntimeException(x); 84 } 85 final Bounds vp = node.getLayoutBounds(); 86 if ((vp.getWidth() >= 0) && (vp.getHeight() >= 0)) { 87 sp.setViewport(new Rectangle2D(vp.getMinX(), vp.getMinY(), 88 vp.getWidth(), vp.getHeight())); 89 } 90 imageView.setImage(node.snapshot(sp, null)); 91 92 // Setup layoutX/layoutY on the image view and the region (1) 93 final Bounds inputBounds = vp; 94 imageView.setLayoutX(inputBounds.getMinX()); 95 imageView.setLayoutY(inputBounds.getMinY()); 96 glass.setLayoutX(inputBounds.getMinX()); 97 glass.setLayoutY(inputBounds.getMinY()); 98 glass.setPrefWidth(inputBounds.getWidth()); 99 glass.setPrefHeight(inputBounds.getHeight()); 100 101 final Bounds outputBounds = this.getLayoutBounds(); 102 assert MathUtils.equals(inputBounds.getMinX(), outputBounds.getMinX()) 103 : "inputBounds=" + inputBounds + ", outputBounds=" + outputBounds; //NOI18N 104 assert MathUtils.equals(inputBounds.getMinY(), outputBounds.getMinY()) 105 : "inputBounds=" + inputBounds + ", outputBounds=" + outputBounds; //NOI18N 106 assert MathUtils.equals(inputBounds.getWidth(), outputBounds.getWidth(), 5.0) 107 : "inputBounds=" + inputBounds + ", outputBounds=" + outputBounds; //NOI18N 108 assert MathUtils.equals(inputBounds.getHeight(), outputBounds.getHeight(), 5.0) 109 : "inputBounds=" + inputBounds + ", outputBounds=" + outputBounds; //NOI18N 110 } 111 }