diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/drag/target/ContainerXYDropTarget.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/drag/target/ContainerXYDropTarget.java index ddf1695e0..cea08b61b 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/drag/target/ContainerXYDropTarget.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/drag/target/ContainerXYDropTarget.java @@ -94,11 +94,14 @@ public boolean acceptDragSource(AbstractDragSource dragSource) { result = false; } else { boolean containsIntrinsic = false; + // Intrinsic node also should be accepted as drag source ? + /* for (FXOMObject draggedObject : dragSource.getDraggedObjects()) { if (draggedObject instanceof FXOMIntrinsic) { containsIntrinsic = true; } } + */ if (containsIntrinsic) { result = false; } else { @@ -114,10 +117,17 @@ public boolean acceptDragSource(AbstractDragSource dragSource) { public Job makeDropJob(AbstractDragSource dragSource, EditorController editorController) { assert acceptDragSource(dragSource); assert editorController != null; - - + final List draggedObjects = dragSource.getDraggedObjects(); - final FXOMObject hitObject = dragSource.getHitObject(); + final Map intrinsicInstanceMap = new HashMap<>(); + + // Treat FXOMIntrinsic as FXOMInstance to calculate layout temporarily. + draggedObjects.stream().filter(draggedObject -> draggedObject instanceof FXOMIntrinsic) + .forEach(draggedObject -> intrinsicInstanceMap.put(draggedObject, ((FXOMIntrinsic) draggedObject).createFxomInstanceFromIntrinsic())); + FXOMObject hitObject = dragSource.getHitObject(); + if(hitObject instanceof FXOMIntrinsic) + hitObject = ((FXOMIntrinsic) hitObject).createFxomInstanceFromIntrinsic(); + final double hitX = dragSource.getHitX(); final double hitY = dragSource.getHitY(); final FXOMObject currentParent = hitObject.getParentObject(); @@ -163,7 +173,7 @@ public Job makeDropJob(AbstractDragSource dragSource, EditorController editorCon result.addSubJob(new InsertAsSubComponentJob( draggedObject, targetContainer, -1, editorController)); } - + // Computes dragged object positions relatively to hitObject assert hitObject.getSceneGraphObject() instanceof Node; final Node hitNode = (Node) hitObject.getSceneGraphObject(); @@ -171,8 +181,11 @@ public Job makeDropJob(AbstractDragSource dragSource, EditorController editorCon final double layoutY0 = hitNode.getLayoutY(); final Map layoutDXY = new HashMap<>(); for (FXOMObject draggedObject : draggedObjects) { - assert draggedObject.getSceneGraphObject() instanceof Node; - final Node draggedNode = (Node) draggedObject.getSceneGraphObject(); + FXOMObject instanceObject = draggedObject; + if (draggedObject instanceof FXOMIntrinsic) + instanceObject = intrinsicInstanceMap.get(draggedObject); + assert instanceObject.getSceneGraphObject() instanceof Node; + final Node draggedNode = (Node) instanceObject.getSceneGraphObject(); final double layoutDX = draggedNode.getLayoutX() - layoutX0; final double layoutDY = draggedNode.getLayoutY() - layoutY0; layoutDXY.put(draggedObject, new Point2D(layoutDX, layoutDY)); @@ -191,12 +204,15 @@ public Job makeDropJob(AbstractDragSource dragSource, EditorController editorCon final double targetOriginY = targetCenter.getY() + currentDY; for (FXOMObject draggedObject : draggedObjects) { - assert draggedObject instanceof FXOMInstance; + FXOMObject instanceObject = draggedObject; + if (draggedObject instanceof FXOMIntrinsic) + instanceObject = intrinsicInstanceMap.get(draggedObject); + assert instanceObject instanceof FXOMInstance; final Point2D dxy = layoutDXY.get(draggedObject); assert dxy != null; final double newLayoutX = Math.round(targetOriginX + dxy.getX()); final double newLayoutY = Math.round(targetOriginY + dxy.getY()); - result.addSubJob(new RelocateNodeJob((FXOMInstance)draggedObject, + result.addSubJob(new RelocateNodeJob((FXOMInstance)instanceObject, newLayoutX, newLayoutY, editorController)); } } diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/job/wrap/UnwrapJob.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/job/wrap/UnwrapJob.java index fa15d5ba7..9f50c82f9 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/job/wrap/UnwrapJob.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/job/wrap/UnwrapJob.java @@ -316,38 +316,40 @@ protected List modifyChildrenJobs(final List children) { for (FXOMObject child : children) { assert child.getSceneGraphObject() instanceof Node; - final Node childNode = (Node) child.getSceneGraphObject(); - final double currentLayoutX = childNode.getLayoutX(); - final double currentLayoutY = childNode.getLayoutY(); - // Modify child LAYOUT bounds - if (newContainerMask.isFreeChildPositioning()) { - final Point2D nextLayoutXY = oldContainerNode.localToParent( - currentLayoutX, currentLayoutY); - - final ModifyObjectJob modifyLayoutX = WrapJobUtils.modifyObjectJob( - (FXOMInstance) child, "layoutX", nextLayoutXY.getX(), getEditorController()); - jobs.add(modifyLayoutX); - final ModifyObjectJob modifyLayoutY = WrapJobUtils.modifyObjectJob( - (FXOMInstance) child, "layoutY", nextLayoutXY.getY(), getEditorController()); - jobs.add(modifyLayoutY); - } else { - final ModifyObjectJob modifyLayoutX = WrapJobUtils.modifyObjectJob( - (FXOMInstance) child, "layoutX", 0.0, getEditorController()); - jobs.add(modifyLayoutX); - final ModifyObjectJob modifyLayoutY = WrapJobUtils.modifyObjectJob( - (FXOMInstance) child, "layoutY", 0.0, getEditorController()); - jobs.add(modifyLayoutY); - } - - // Remove static properties from child if (child instanceof FXOMInstance) { - final FXOMInstance fxomInstance = (FXOMInstance) child; - for (FXOMProperty p : fxomInstance.getProperties().values()) { - final Class residentClass = p.getName().getResidenceClass(); - if (residentClass != null - && residentClass != newContainer.getDeclaredClass()) { - jobs.add(new RemovePropertyJob(p, getEditorController())); + final Node childNode = (Node) child.getSceneGraphObject(); + final double currentLayoutX = childNode.getLayoutX(); + final double currentLayoutY = childNode.getLayoutY(); + + if (newContainerMask.isFreeChildPositioning()) { + final Point2D nextLayoutXY = oldContainerNode.localToParent( + currentLayoutX, currentLayoutY); + + final ModifyObjectJob modifyLayoutX = WrapJobUtils.modifyObjectJob( + (FXOMInstance) child, "layoutX", nextLayoutXY.getX(), getEditorController()); + jobs.add(modifyLayoutX); + final ModifyObjectJob modifyLayoutY = WrapJobUtils.modifyObjectJob( + (FXOMInstance) child, "layoutY", nextLayoutXY.getY(), getEditorController()); + jobs.add(modifyLayoutY); + } else { + final ModifyObjectJob modifyLayoutX = WrapJobUtils.modifyObjectJob( + (FXOMInstance) child, "layoutX", 0.0, getEditorController()); + jobs.add(modifyLayoutX); + final ModifyObjectJob modifyLayoutY = WrapJobUtils.modifyObjectJob( + (FXOMInstance) child, "layoutY", 0.0, getEditorController()); + jobs.add(modifyLayoutY); + } + + // Remove static properties from child + if (child instanceof FXOMInstance) { + final FXOMInstance fxomInstance = (FXOMInstance) child; + for (FXOMProperty p : fxomInstance.getProperties().values()) { + final Class residentClass = p.getName().getResidenceClass(); + if (residentClass != null + && residentClass != newContainer.getDeclaredClass()) { + jobs.add(new RemovePropertyJob(p, getEditorController())); + } } } } diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanelController.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanelController.java index b01ed53f9..304f76077 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanelController.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/content/ContentPanelController.java @@ -547,7 +547,7 @@ public FXOMObject pick( * @return an FXOMObject that matches (sceneGraphNode, sceneX, sceneY) */ public FXOMObject searchWithNode(Node sceneGraphNode, double sceneX, double sceneY) { - final FXOMObject result; + FXOMObject result = null; final FXOMDocument fxomDocument = getEditorController().getFxomDocument(); @@ -558,14 +558,16 @@ public FXOMObject searchWithNode(Node sceneGraphNode, double sceneX, double scen * With the logic above, a click in a 'tab header' returns the * fxom object associated to the 'tab pane'. We would like to get * the fxom object associated to the 'tab'. When the pick result is - * a 'TabPane' we need to refine this result. This refinement logic - * is available in AbstractDriver. + * a 'TabPane' we need to refine this result. For intrinsic node, + * it doesn't need to refine. This refinement logic is available + * in AbstractDriver. */ if (match != null) { + result = match; final AbstractDriver driver = lookupDriver(match); - result = driver.refinePick(sceneGraphNode, sceneX, sceneY, match); - } else { - result = null; + if(driver != null) { + result = driver.refinePick(sceneGraphNode, sceneX, sceneY, match); + } } return result; diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/content/mode/EditModeController.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/content/mode/EditModeController.java index 291347a44..75acbdc39 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/content/mode/EditModeController.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/content/mode/EditModeController.java @@ -60,6 +60,7 @@ import com.oracle.javafx.scenebuilder.kit.editor.util.ContextMenuController; import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument; import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance; +import com.oracle.javafx.scenebuilder.kit.fxom.FXOMIntrinsic; import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject; import com.oracle.javafx.scenebuilder.kit.metadata.Metadata; import com.oracle.javafx.scenebuilder.kit.metadata.property.ValuePropertyMetadata; @@ -440,7 +441,15 @@ private void updateHandles(ObjectSelectionGroup osg) { excludes.clear(); final Group handleLayer = contentPanelController.getHandleLayer(); for (FXOMObject incomingObject : incomingObjects) { - final AbstractDriver driver = contentPanelController.lookupDriver(incomingObject); + AbstractDriver driver; + // To attach handle to intrinsic node ( or ). + if(incomingObject instanceof FXOMIntrinsic) { + FXOMInstance fxomInstance = ((FXOMIntrinsic) incomingObject).createFxomInstanceFromIntrinsic(); + incomingObject = fxomInstance; + driver = contentPanelController.lookupDriver(fxomInstance); + } else { + driver = contentPanelController.lookupDriver(incomingObject); + } if (driver == null) { // incomingObject cannot be managed by content panel (eg MenuItem) excludes.add(incomingObject); diff --git a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMInstance.java b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMInstance.java index 8ace788fb..eff6cb4ad 100644 --- a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMInstance.java +++ b/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/fxom/FXOMInstance.java @@ -189,8 +189,17 @@ public FXOMObject searchWithSceneGraphObject(Object sceneGraphObject) { FXOMPropertyC propertyC = (FXOMPropertyC) property; final Iterator itValue = propertyC.getValues().iterator(); while ((result == null) && itValue.hasNext()) { - final FXOMObject value = itValue.next(); - result = value.searchWithSceneGraphObject(sceneGraphObject); + FXOMObject value = itValue.next(); + // Temporarily treat the node as FXOMInstance so that the intrinsic node can be searched. + if(value instanceof FXOMIntrinsic) { + FXOMObject fxomObject = ((FXOMIntrinsic) value).createFxomInstanceFromIntrinsic(); + result = fxomObject.searchWithSceneGraphObject(sceneGraphObject); + if(result != null) { + result = value; + } + } else { + result = value.searchWithSceneGraphObject(sceneGraphObject); + } } } }