Positionning GoSubgraph

Hello,

I’ve been trying to do something from quite some time now, and the more I try, the less I understand… :(

I’m using a class derived from GoSubGraph. I have the following requirements :

  • There is no direct link between inside and outside, all go through a port on the subgraph
  • When collapsed, the SubGraph should be displayed as an icon
  • When collapsed, the Location of the SubGraph should be the center of the icon
  • When expanded, I don’t care much about location, but the handle should be at the same position as is was on a collapsed node, so that the user can toggle it several times without mouse moves.

Here are some images to make me better understood :

I can’t get it to work… There are always some small shifts.

I tried to take the MultiPortSubGraph from the SubGraphApp demo (uncommenting both customisation code), in order to better understand what happens.

Making seemingly innocent modifications (such as changing some margins, in order to understand what those margins really represent) changes the position of the handle on expand/collapse.

Is there anything obvious I’m missing ?

Best regards

I assume you didn’t have any problem overriding the GoObject.Location property so that both get and set did what you wanted, nor with overriding CreateCollapsedObject (or setting that property).
And apparently you adapted the code from the example MultiPortSubGraph class to handle multiple ports, overriding LayoutChildren to call a method to position the ports, and overriding the …Skip methods to make sure your ports were not considered in the computation for how big the subgraph needed to be.
It isn’t clear to me that you want to have any margins, actually. If the margins are zero all around (or at least at the top-left), does the Handle move when you collapse/expand? Perhaps you need to override ComputeCollapsedRectangle to position the collapsed object slightly differently.
protected override RectangleF ComputeCollapsedRectangle(SizeF s) {
PointF hpos = ComputeReferencePoint();
// DEFAULT:
//return new RectangleF(hpos.X, hpos.Y, s.Width, s.Height);
// assume handle inside margin, at top-left
return new RectangleF(hpos.X + this.TopLeftMargin.Width, hpos.Y + this.TopLeftMargin.Height, s.Width, s.Height);
}
I don’t know exactly what you are doing, so this might not be appropriate.

[QUOTE=walter]

I assume you didn’t have any problem overriding the GoObject.Location property so that both get and set did what you wanted,[/quote]

I had no problem with the get function in collapsed mode. The set is more tricky, since I do not have a clear view of what the different dimentions specified really represent. Is it possible to have a drawing of a GoSubGraph with all quantities that have an impact on the position of the elements of the subgraph? I think this would be a great addition to the documentation.

Another problem I have is that, from what I understand, when expanding a node, the location remains unchanged. What I want is the handle to remain unmoved. Therefore I have to set the location in expanded mode accordingly, and I have to understand where the handle really is.

[QUOTE=walter]nor with overriding CreateCollapsedObject (or setting that property).[/quote]

That part works.

[QUOTE=walter]And apparently you adapted the code from the example MultiPortSubGraph class to handle multiple ports, overriding LayoutChildren to call a method to position the ports, and overriding the ...Skip methods to make sure your ports were not considered in the computation for how big the subgraph needed to be.[/quote]

That part seems to work too.

[QUOTE=walter]It isn't clear to me that you want to have any margins, actually. If the margins are zero all around (or at least at the top-left), does the Handle move when you collapse/expand? [/quote]

I probably do not want margins in collapsed mode. I want them in expanded mode. I just tried to play with tthose margins in the SubGraph demo, in order to try and understand what they mean.

[QUOTE=walter]Perhaps you need to override ComputeCollapsedRectangle to position the collapsed object slightly differently.

protected override RectangleF ComputeCollapsedRectangle(SizeF s) { PointF hpos = ComputeReferencePoint(); // DEFAULT: //return new RectangleF(hpos.X, hpos.Y, s.Width, s.Height); // assume handle inside margin, at top-left return new RectangleF(hpos.X + this.TopLeftMargin.Width, hpos.Y + this.TopLeftMargin.Height, s.Width, s.Height); }[/quote]

I tried this, but it did not work, the handle kept moving in the subgraph app. I made the following changes (in a darwinian way : If you make enough random changes, one may be the good one and survive) :

protected override RectangleF ComputeCollapsedRectangle(SizeF s)
{
PointF hpos = ComputeReferencePoint();
return new RectangleF(
hpos.X - this.TopLeftMargin.Width + CollapsedTopLeftMargin.Width,
hpos.Y - this.TopLeftMargin.Height+ CollapsedTopLeftMargin.Height,
s.Width, s.Height);
}

It seemed to work in the SubGraph demo. I’ll try and apply it to my real program.

Regards,

Well, it did not work so neatly…

It only worked as long as the node label was narrower than the node itself. I seem to have reached a solution by overriding correctly Location, through some manual computation of the node width (expanded/collapsed), and the node label width (taking wrapping into account). Further tests will show wether it hold right in all cases.

I think I finally understood, at least partially, what mean the involved dimensions, offsets… For instance, when I discovered through trial and guess that ComputeCollapsedSize does not take the label into account, it helped me understanding the situation.