Port border docking and resizing issue

Hello,

Can someone help me with a following issue…
I have a custom node with a port. The port can be dragged inside (image 1, undocked) and
around the border (second and third image), but in a way that this time it is docked by the border of the parent
node. It cannot be moved out from the border. That functionality I have, but the problem is when I put the port
on the outside of the border and try to resize the node, port goes inside the
border (node eats the port Shocked) and undock itself (last picture). I need that port to be docked on the border and after resizing.
Thanks in advance.

I suggest you use a custom GoRoundedRectangle that overrides the DoResize method. In addition to calling the base method, find all of the “docked” ports of the parent GoNode and make sure they are all positioned appropriately.

Be sure to make this custom rectangle the GoObject.SelectionObject of your node class, if it isn’t already, depending on the kind of node class you are inheriting from.

Hi Walter, thanks for your reply.

As you suggest, I create PathGradientRoundedRectangle class that inherits from GoRoundedRectangle, set it’s Selectable and DragsNode propertys to true and in my custum node class that inherits from GoNode - Selectable property to false. Within PathGradientRoundedRectangle class I override DoResize method.
So, I got selection handlers only around GoRoundedRectangle object inside the node and my port can be docked and movable fine around that border. But when I try to resize it, my port undocks!

My questions are:

  1. Should I make this custom rectangle the GoObject.SelectionObject of my node class, because it (node class) inherits from GoNode?

  2. I’m pretty new in GoDiagrams programming so, can you described me in more details, or put some code - how to accomplish to “find all the docked ports and be sure they are positioned appropriately” and prevent port(s) from undocking during resize.

Thank you so much for helping me.

Renato

You probably don’t want to make any part of a node be Selectable unless you really want to allow that particular object to be in the GoSelection. So node parts are normally not Selectable, but the whole nodes themselves are Selectable.

But you do want to make your special rectangle appear to be selected, which is why you want it to be the SelectionObject for your node. If you are inheriting directly from GoNode, you should override the SelectionObject property to return your special rectangle. If you are inheriting from some of the predefined node classes, this is already done for you – for example, GoIconicNode overrides SelectionObject to return the Icon if it’s non-null.

Sorry for not being clearer. Basically what you want is a custom layout where your docked ports are always positioned in a certain manner relative to your special rectangle.

So I would override the node’s LayoutChildren method to first call the base method and then make sure each port is positioned the way you want it. (This assumes your special rectangle is an immediate child of the node.)

public override void LayoutChildren(GoObject childchanged) {
base.LayoutChildren(childchanged);
// find your special rectangle, perhaps using FindChild if your rectangle
is named,
// or else as a particular indexed child of the node –
// there are many examples of this in the samples
PathGradientRoundedRectangle rect = …
if (rect != null) {
foreach (GoPort port in this.Ports) {
if (… port is not docked …) continue;
port.Position = … // relative to the special rect
}
}
}

Hi Walter,

do we have some method in GoNode for overriding to find a new position of the resized rectangle to put the new port in exactly that position or?

GoGroup.LayoutChildren is called after the rectangle has been resized.

If GoObject.ResizesRealtime is true, the rectangle is resized continuously during the user’s resizing gestures, so LayoutChildren will be called frequently during the resizing.

I don’t think you need to override any more methods.

It does occur to me now, though, that you may want to disable your code in LayoutChildren during the time when the user is dragging a dockable port. Otherwise LayoutChildren might continuously reposition the port being dragged, causing the port not to move in the user-controlled manner. That would mean setting a flag when starting your PortMovingTool and clearing it when the tool stops.

I’m sorry for not being clearer.
This is the line of code: port.Position = … // relative to the special rect
that I don’t understand.
I guess, if I’m right, docked port should follow the exactly right position on the node border as been before resizing and need to know the info about a new position during resizing… this is the routine I missed…Confused

Thanks for your effort…

Did you start with ActivityNode in the Processor demo? (It has movable ports.)



Note that ActivityNode overrides OnChildBoundsChanged and catches the resize of the icon, positioning the ports relative to the middle of the previous center.



It looks like you may be able to change the logic here to scale the position of the ports.

Thanks Walter,

I found out how to change the logic in LayoutChildren and how to reposition the docked nodes.

Thanks again for your effort.

Renato