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.panel.content.driver;
  33 
  34 import com.oracle.javafx.scenebuilder.kit.editor.drag.target.AbstractDropTarget;
  35 import com.oracle.javafx.scenebuilder.kit.editor.drag.target.AccessoryDropTarget;
  36 import com.oracle.javafx.scenebuilder.kit.editor.drag.target.ContainerXYDropTarget;
  37 import com.oracle.javafx.scenebuilder.kit.editor.drag.target.ContainerZDropTarget;
  38 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController;
  39 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.handles.AbstractHandles;
  40 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.handles.NodeHandles;
  41 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.pring.AbstractPring;
  42 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.pring.NodePring;
  43 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.AbstractResizer;
  44 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.CanvasResizer;
  45 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.ImageViewResizer;
  46 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.RegionResizer;
  47 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.SubSceneResizer;
  48 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.WebViewResizer;
  49 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.shape.ArcResizer;
  50 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.shape.CircleResizer;
  51 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.shape.EllipseResizer;
  52 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.shape.RectangleResizer;
  53 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.shape.TextResizer;
  54 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.tring.AbstractTring;
  55 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.tring.NodeTring;
  56 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance;
  57 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject;
  58 import com.oracle.javafx.scenebuilder.kit.metadata.util.DesignHierarchyMask;
  59 import javafx.geometry.Bounds;
  60 import javafx.scene.Node;
  61 import javafx.scene.SubScene;
  62 import javafx.scene.canvas.Canvas;
  63 import javafx.scene.control.ComboBox;
  64 import javafx.scene.control.Labeled;
  65 import javafx.scene.control.TextInputControl;
  66 import javafx.scene.control.TitledPane;
  67 import javafx.scene.image.ImageView;
  68 import javafx.scene.layout.Region;
  69 import javafx.scene.shape.Arc;
  70 import javafx.scene.shape.Circle;
  71 import javafx.scene.shape.Ellipse;
  72 import javafx.scene.shape.Rectangle;
  73 import javafx.scene.text.Text;
  74 import javafx.scene.web.WebView;
  75 
  76 /**
  77  *
  78  */
  79 public abstract class AbstractNodeDriver extends AbstractDriver {
  80 
  81     public AbstractNodeDriver(ContentPanelController contentPanelController) {
  82         super(contentPanelController);
  83     }
  84 
  85     /*
  86      * AbstractDriver
  87      */
  88 
  89     @Override
  90     public AbstractHandles<?> makeHandles(FXOMObject fxomObject) {
  91         assert fxomObject.getSceneGraphObject() instanceof Node;
  92         assert fxomObject instanceof FXOMInstance;
  93         return new NodeHandles(contentPanelController, (FXOMInstance)fxomObject);
  94     }
  95 
  96     @Override
  97     public AbstractPring<?> makePring(FXOMObject fxomObject) {
  98         assert fxomObject.getSceneGraphObject() instanceof Node;
  99         assert fxomObject instanceof FXOMInstance;
 100         return new NodePring(contentPanelController, (FXOMInstance)fxomObject);
 101     }
 102 
 103     @Override
 104     public AbstractTring<?> makeTring(AbstractDropTarget dropTarget) {
 105         assert dropTarget != null;
 106         assert dropTarget.getTargetObject() instanceof FXOMInstance;
 107         assert dropTarget.getTargetObject().getSceneGraphObject() instanceof Node;
 108         return new NodeTring(contentPanelController, (FXOMInstance) dropTarget.getTargetObject());
 109     }
 110 
 111     @Override
 112     public AbstractResizer<?> makeResizer(FXOMObject fxomObject) {
 113         final AbstractResizer<?> result;
 114 
 115         /*
 116          * To avoid creating one driver for each resizer,
 117          * we make the dispatch here:
 118          */
 119 
 120         final Object sceneGraphObject = fxomObject.getSceneGraphObject();
 121         if (sceneGraphObject instanceof ImageView) {
 122             result = new ImageViewResizer((ImageView) sceneGraphObject);
 123         } else if (sceneGraphObject instanceof Region) {
 124             result = new RegionResizer((Region) sceneGraphObject);
 125         } else if (sceneGraphObject instanceof WebView) {
 126             result = new WebViewResizer((WebView) sceneGraphObject);
 127         } else if (sceneGraphObject instanceof Canvas) {
 128             result = new CanvasResizer((Canvas) sceneGraphObject);
 129         } else if (sceneGraphObject instanceof Arc) {
 130             result = new ArcResizer((Arc) sceneGraphObject);
 131         } else if (sceneGraphObject instanceof Circle) {
 132             result = new CircleResizer((Circle) sceneGraphObject);
 133         } else if (sceneGraphObject instanceof Ellipse) {
 134             result = new EllipseResizer((Ellipse) sceneGraphObject);
 135         } else if (sceneGraphObject instanceof Rectangle) {
 136             result = new RectangleResizer((Rectangle) sceneGraphObject);
 137         } else if (sceneGraphObject instanceof Text) {
 138             result = new TextResizer((Text) sceneGraphObject);
 139         } else if (sceneGraphObject instanceof SubScene) {
 140             result = new SubSceneResizer((SubScene) sceneGraphObject);
 141         } else {
 142             result = null;
 143         }
 144 
 145         return result;
 146     }
 147 
 148     @Override
 149     public FXOMObject refinePick(Node hitNode, double sceneX, double sceneY, FXOMObject fxomObject) {
 150         return fxomObject;
 151     }
 152 
 153     @Override
 154     public AbstractDropTarget makeDropTarget(FXOMObject fxomObject, double sceneX, double sceneY) {
 155         assert fxomObject instanceof FXOMInstance;
 156         assert fxomObject.getSceneGraphObject() != null; // Because mouse cannot be above a unresolved component
 157 
 158         final AbstractDropTarget result;
 159 
 160         final FXOMInstance fxomInstance = (FXOMInstance) fxomObject;
 161         final DesignHierarchyMask mask = new DesignHierarchyMask(fxomObject);
 162         if (mask.isFreeChildPositioning()) {
 163             result = new ContainerXYDropTarget(fxomInstance, sceneX, sceneY);
 164         } else {
 165             if (mask.isAcceptingAccessory(DesignHierarchyMask.Accessory.CONTENT)) {
 166                 result = new AccessoryDropTarget(fxomInstance, DesignHierarchyMask.Accessory.CONTENT);
 167             } else {
 168                 result = new ContainerZDropTarget(fxomInstance, null);
 169             }
 170         }
 171 
 172         return result;
 173     }
 174 
 175     @Override
 176     public Node getInlineEditorBounds(FXOMObject fxomObject) {
 177         final Node result;
 178 
 179         final Object sceneGraphObject = fxomObject.getSceneGraphObject();
 180         if (sceneGraphObject instanceof ComboBox) {
 181             result = (ComboBox<?>) sceneGraphObject;
 182         } else if (sceneGraphObject instanceof Labeled) {
 183             result = (Labeled) sceneGraphObject;
 184         } else if (sceneGraphObject instanceof Text) {
 185             result = (Text) sceneGraphObject;
 186         } else if (sceneGraphObject instanceof TextInputControl) {
 187             result = (TextInputControl) sceneGraphObject;
 188         } else if (sceneGraphObject instanceof TitledPane) {
 189             result = (TitledPane) sceneGraphObject;
 190         } else {
 191             result = null;
 192         }
 193 
 194         return result;
 195     }
 196 
 197     @Override
 198     public boolean intersectsBounds(FXOMObject fxomObject, Bounds bounds) {
 199         assert fxomObject.getSceneGraphObject() instanceof Node;
 200 
 201         // Note: bounds are in root scene coordinates
 202         final Node sceneGraphNode
 203                 = (Node) fxomObject.getSceneGraphObject();
 204         final Bounds sceneGraphNodeBounds
 205                 = sceneGraphNode.localToScene(sceneGraphNode.getLayoutBounds(), true /* rootScene */);
 206 
 207         return sceneGraphNodeBounds.intersects(bounds);
 208     }
 209 
 210 }