Creating a Custom Grapher link
In this section,
IlvLinkImage is subclassed to create a grapher link that meets the following specifications:
The link is always drawn as a straight line between its two nodes.
The start point is either defined by a connection pin or located at the center of the start node.
The end point is such that the link stays perpendicular to the face of the end node closest to the start point. If this cannot be done, the end point is located on the closest corner of the node bounding box.
The link is drawn the same way as in the base class
IlvLinkImage. Therefore, the corresponding methods inherited from
IlvGraphic are left unchanged. Also, there are only two points defining the shape of the link (the two end points, and no intermediate points). There are two possibilities for defining the link: overloading the
IlvLinkImage::getLinkPoints method or the
IlvLinkImage::computePoints method. The second alternative has been chosen for this example:
void
MyLink::computePoints(IlvPoint& src,
IlvPoint& dst,
const IlvTransformer* t) const
{
//== [1] ==
IlvGrapherPin* pin = IlvGrapherPin::Get(getFrom());
if (!pin || !pin->getLinkLocation(getFrom(),this,t,src)) {
IlvRect bbox;
getFrom()->boundingBox(bbox,t);
src.move(bbox.centerx(),bbox.centery());
}
//== [2] ==
IlvRect toBBox;
getTo()->boundingBox(toBBox,t);
if (src.x()<toBBox.x()) {
if (src.y() < toBBox.y()) // Upper left quadrant
dst.move(toBBox.x(),
toBBox.y());
else if (src.y() >= toBBox.bottom()) // Lower left quadrant
dst.move(toBBox.x(),
toBBox.y()+toBBox.h()-1);
else // Left quadrant
dst.move(toBBox.x(),
src.y());
} else if (src.x()>=toBBox.right()) {
if (src.y() < toBBox.y()) // Upper right quadrant
dst.move(toBBox.x()+toBBox.w()-1,
toBBox.y());
else if (src.y() >= toBBox.bottom()) // Lower right quadrant
dst.move(toBBox.x()+toBBox.w()-1,
toBBox.y()+toBBox.h()-1);
else // Right quadrant
dst.move(toBBox.x()+toBBox.w()-1,
src.y());
} else {
if (src.y() < toBBox.y()) // Upper quadrant
dst.move(src.x(),
toBBox.y());
else if (src.y() >= toBBox.bottom()) // Lower quadrant
dst.move(src.x(),
toBBox.y()+toBBox.h()-1);
else // src inside toBBox
dst.move(toBBox.centerx(),toBBox.centery());
}
}
In the first part ([1]) of the code, a verification is made to see whether the link is attached to a connection pin defined on its start node. If this is not the case, the center of the bounding box of this node is taken.
Once the location of the start point has been computed, the position of the start point with respect to the bounding box of the end node is verified ([2]). There are nine possible cases (the eight quadrants defined by toBBox, plus the case where the start point is inside toBBox), each defining a unique location.
Version 6.1
Copyright © 2016, Rogue Wave Software, Inc. All Rights Reserved.