Hey Guys (Walter)! I’m trying to figure out how to fire the reposition the new link label onto the link when it is added in. It is called when the diagram is drawn, but I have no idea how to call it outside of that. The Overridden function is LayoutChildren in my Link class that extends GoLabeledLink
public override void LayoutChildren(GoObject childchanged)
{
if (this.Initializing)
return;
base.LayoutChildren(childchanged);
foreach (GoObject child in this)
{
//Oooo this is what positions the bloody link ZOMG!
IGoLinkLabel l = child as IGoLinkLabel;
PositionLinkLabel(l, childchanged);
}
}
private void PositionLinkLabel(IGoLinkLabel l, GoObject childchanged)
{
if (l == null) return;
if (l == childchanged)
{
PointF center = childchanged.Center;
GoStroke s = this.RealLink;
float closestdist = 10e20f;
PointF closestpt = new PointF();
int closestseg = -1;
int numpts = s.PointsCount;
for (int i = 0; i < numpts - 1; i++)
{
PointF start = s.GetPoint(i);
PointF end = s.GetPoint(i + 1);
PointF R;
GoStroke.NearestPointOnLine(start, end, center, out R);
float dist = ((R.X - center.X) * (R.X - center.X) + (R.Y - center.Y) * (R.Y - center.Y));
if (dist < closestdist)
{
closestdist = dist;
closestpt = R;
closestseg = i;
}
}
if (closestseg > -1)
{
l.Offset = new SizeF(center.X - closestpt.X, center.Y - closestpt.Y);
l.Segment = closestseg;
PointF A = s.GetPoint(closestseg);
PointF B = s.GetPoint(closestseg + 1);
PointF R = closestpt;
double rdist = Math.Sqrt((A.X - R.X) * (A.X - R.X) + (A.Y - R.Y) * (A.Y - R.Y));
double sdist = Math.Sqrt((A.X - B.X) * (A.X - B.X) + (A.Y - B.Y) * (A.Y - B.Y));
if (sdist <= 0)
l.SegmentPercentage = 0;
else
l.SegmentPercentage = (float)(rdist * 100 / sdist);
}
}
else
{
SizeF off = l.Offset;
PointF cp = l.LinkLabelConnectionPoint;
((GoObject)l).Center = new PointF(cp.X + off.Width, cp.Y + off.Height);
}
}
This code is almost verbatim from the FlowLink class in the Processor document. I want to call this repositioning everytime the label is changed. So what I do is I kill the original link label and I add a new one, but the new one is way off somewhere else on the document. Thanks a lot for your help!
Hey walter I tried that but it keeps on not positioning my linklabel. How would I just use the PositionLabel function on a new label I made on the GoDocument. I tried using
Label = new LinkLabel();
Label.Text = ccode;
LayoutChildren(Label);
Add(Label);
but the current label is not positioned correctly. Thanks Walter!
Actually, LayoutChildren is also called automatically when a child is Add’ed or Remove’d.
So just doing:
[code]LinkLabel lab = new LinkLabel();
lab.Text = ccode;
if (ccode == "") lab.Visible = false;
Add(lab);[/code]
should be sufficient.
In any case, if the code is the same as in the Processor example, then it should be working fine. What exactly is the problem, anyway? Do you need to set some of the LinkLabel properties before you Add it?
When I draw the graph initially on open I get my labels in the correct position, but when I recode my links and re-add the labels they end up in the top of the document and not on the link itself.
I made the movable true, and the editable false. Otherwise this should be verbatim from the processor example. Also here is my entire code for changing the link color and the label after the new code is selected.
public void SetLinkStyle()
{
Pen p = new Pen(ReturnColor(), 2);
this.Pen = p;
this.ToArrow = true;
this.HighlightPen = new Pen(Color.White, 6);
this.Highlight = true;
if (Added == true)
{
Remove(Label);
}
Label = new LinkLabel();
Label.Text = ccode;
if (Label.Text.Equals(""))
{
Label.Visible = false;
}
Add(Label);
LayoutChildren(Label);
Added = true;
}
I couldn’t figure out how to just refresh the current label so that’s why I just remove it and add a new one. Also I just stepped through the whole process of adding a new Label and the initializing is always set to false.
So at most you will have just one label for each link, right?
I suggest you just use the GoLabeledLink.MidLabel property if you want easy access to that LinkLabel. And your override of LayoutChildren need not call the base method. since it would just set the position in the normal manner, which would be re-set by the code in PositionLinkLabel.
Another reason for avoiding the definition of child-reference fields in your subclasses is so that you don't need to update them in an override of CopyChildren or in an override of Remove. If you did have a "Label" field/property, you would need to override CopyChildren to make sure the copied link's "Label" referred to the copied LinkLabel rather than to the original one.
Walter removing and adding it in seemed like a horrid way to do it after talking to you so I just instantiated the linklabel in the constructor and now my code does this