Dealing with Parent Child Parameters via Script
Normally, you would open properties, go to summary, and set the ‘parent/owner’ & ‘child’ fields.
We’re going to do this by script so first we need to clarify a few things.
Parent, Child Definitions
Example 1: Parent/owner = “parent”, but Child = “no”
An object can be an owner, but not a parent.
When an object is an owner the child object’s ‘child’ entry field is set to ‘no’. You’ll notice that you can move the child object outside the parent’s boundaries. The child’s x/y coordinates are relative to its position on your screen.
Example 2: Parent/owner = “parent”, Child = “yes”
When an object is a parent, its child object’s ‘child’ entry field is set to ‘yes’. When you try to move the child outside the parent’s boundaries, it is not visible. The child’s x/y coordinates are relative to its position within the parent.
With those distinctions made, let’s begin by assigning an object a parent via script.
Object.Parent
Create two objects: “child1” & “testparent1” (leave their properties as is.)
Create a new script in “child1” and apply this simple script and hit ok:
'Called when L-click is released
Function Object_OnLButtonUp(x, y, dragged)
If not dragged then
Object.parent = DesktopX.Object(“testparent1”)
End If
End Function
L-click on the child to test the script. Just like that, you’ve assigned “testparent1” as child1’s parent! But, let’s look at child1 properties to clarify what we’ve done.
In properties, you’ll see “testparent1” in the parent/owner field, and child is set to ‘no’. So what we’ve really done is set “testparent1” as the ‘owner’ of child1. This is evident by the fact that we can move child1 outside of the “testparent1” boundaries, and its x/y coordinates are relative to its position on the screen.
Similarly, we can set object.parent = nothing, and child1 will go back to having no owner.
So, if using object.parent only sets an object as the ‘owner’, how do we set it so that “testparent1” is the ‘parent’ object, as per the definition in example 2?
Object.Child (what it does and doesn't do)
You might think to use object.child, but that will only query whether the current object is a child object. It will either return true or false, but you can’t actually set those values yourself.
One solution is to clone a template object with those parameters already set. Why clone? Well, it depends on what you’re doing. The advantage is that you can create as many ‘new’ child objects as you want, instead of just moving one from parent object to parent object.
Create 2 more objects: “child2” & “testparent2”
Position child2 inside testparent2, r-click and set parent to “testparent2” (Open child2 Properties > Summary. To make sure parent/owner is set to “testparent2” and set child to “yes”)
Now, what we’re gonna do is clone child2, change the parent to testparent1, and set its x/y coordinates to within testparent1’s boundaries. (Ideally, the script wouldn’t be in the object you’re cloning, because you’d end up with multiple scripts.)
'Called when L-click is released
Function Object_OnLButtonUp(x, y, dragged)
If Not dragged Then
clonename = "child3"
object.clone clonename, 10, 10 ‘—syntax: clonename, x position, y position
DesktopX.Object(clonename).parent = DesktopX.Object("testparent1")
End If
End Function
L-click on the child2 and see how it works. If all goes well you’ll see the new object appear inside testparent1.
Setting Child Parameters via Script
Lastly, I want to show you how to change an object from child= “yes” to child= “no” via scripting, even though I said it isn’t possible to set that value. While working on a project, I tangled with this problem and came up with a work around that allowed me to, at least, set child = “no”. I’ll do this in two parts so you can understand why this work around is a bit complicated.
PART 1
Let’s start from our template parent/child objects “child2” & “testparent2”. Remember, how I said you could set parent to nothing? That’s what we’re going to do. We’ll clone child2, and set the parent to nothing.
Replace child2’s script with this one:
'Called when L-click is released
Function Object_OnLButtonUp(x, y, dragged)
If Not dragged Then
clonename = "child4"
object.clone clonename, 10, 10 ‘—syntax: clonename, x position, y position
DesktopX.Object(clonename).parent = nothing
End If
End Function
L-click on child2 and see what happens.
It appears as though nothing happened. But wait, r-click on the DXBuilder icon and choose ‘list objects’. Aha! Child4 is listed, its parent is set to nothing, but why doesn’t it appear? If you r-click on it in the object list and open properties, you’ll see in the summary tab that child is still set to “yes”. It’s an anomaly!
Okay, now check this out. R-click on child4 in the object list and choose ‘clone’.
Voila! It appears! It seems all we need to do is clone the clone. Alright now delete child3, child4, and child5 so we can apply the final script.
PART 2
This time we’ll clone child2, set the parent to nothing, clone child3, delete child2, and reset child3’s name to child2. By deleting the first clone and renaming the 2nd clone after the first, it will give the illusion that we’ve only created one new object. Besides, you don’t want unseen anomalous objects haunting your desktop like ghosts in the machine!
Sounds complicated, but the script is still just as simple.
'Called when L-click is released
Function Object_OnLButtonUp(x, y, dragged)
If Not dragged Then
clonename = "child3"
object.clone clonename, 10, 10 '-syntax: clonename, x position, y position
DesktopX.Object(clonename).parent = nothing
DesktopX.object(clonename).clone "child4", 10, 10
DesktopX.Object(clonename).delete
DesktopX.Object("child4").name = "child3"
End If
End Function
Well, that’s it! I hope this helped someone.