Connection Pins
Connection pins allow you to control the exact location of link end points on grapher nodes. When a link is attached to a connection pin, the connecting point stays the same, regardless of the relative position of its start and end nodes.
The following items are described in this section:
Connection Pin Management Class
The
IlvGrapherPin abstract class is designed to handle a collection of connection pins. Its first purpose is to maintain the association between links and pins. To do so, pins are referenced by indexes. You can connect a link to a given connection pin with the
IlvGrapherPin::setPinIndex method:
IlvLinkImage* link = …;
//== Recover the IlvGrapherPin instance associated with the starting node
IlvGrapherPin* pin = IlvGrapherPin::Get(link->getFrom());
//== Connect the link to the pin whose index is 0
pin->setPinIndex(link,0,IlTrue);
Likewise, you can recover the index of the connection pin to which a link is attached, by using the
IlvGrapherPin::getPinIndex method.
The second purpose of the
IlvGrapherPin class is to provide an interface to query the coordinates of the connecting points available for a given node. Each concrete subclass must provide an implementation for the
getCardinal and
getLocation methods:
virtual IlUInt getCardinal(const IlvGraphic* node, const IlvTransformer* t) const; |
This method returns the number of connection pins handled by the instance for the specified node node when displayed with the transformer t.
virtual IlBoolean getLocation(IlUInt pinIndex, const IlvGraphic* node, const IlvTransformer* t, IlvPoint& where) const; |
This method returns, in the where parameter, the coordinates of the connection pin specified by the index pinIndex on the node node, when displayed with the transformer t.
Other methods of this interface (
getClosest,
IlvGrapherPin::getLinkLocation, and so on) have a default implementation that can be overloaded. For example, the
getClosest method considers all available connection pins and uses the
getLocation method. You can change this method to:
provide a faster implementation (
getLocation may contain computations that can be done only once in
getClosest),
return the first unused pin instead of the closest one in terms of distance.
An All-Purpose IlvGrapherPin Subclass
The
IlvGenericPin class is a predefined concrete subclass of
IlvGrapherPin that makes it possible to dynamically define the connection pins on a node. New connection pins are specified by their desired location on the node when this node is displayed through a given transformer. Once this position is stored, the
IlvGenericPin class will use the shape of the object to accurately locate the connecting point regardless of the applied transformer.
Here is an example of how to use this class to add connection pins on the four corners of a node bounding box:
IlvGraphic* node = ...;
//== Create an empty instance of IlvGenericPin
IlvGenericPin* pin = new IlvGenericPin();
//== Add the four connecting points
IlvRect bbox;
node->boundingBox(bbox,0);
pin->addPin(node,IlvPoint(bbox.x(),bbox.y()),0);
pin->addPin(node,IlvPoint(bbox.x()+bbox.w()-1,bbox.y()),0);
pin->addPin(node,IlvPoint(bbox.x()+bbox.w()-1,bbox.y()+bbox.h()-1),0);
pin->addPin(node,IlvPoint(bbox.x(),bbox.y()+bbox.h()-1),0);
//== Attach the IlvGenericPin instance to the node
pin->set(node);
Note: The points in this example are given in the object coordinate system when no transformer is applied. |
Extending the IlvGrapherPin Class
An example of a concrete
IlvGrapherPin subclass that handles a single connection pin located at the center of a node bounding box is presented here. This class, called
CenterPin, is declared as follows:
#include <ilviews/grapher/pin.h>
class CenterPin
: public IlvGrapherPin
{
public:
CenterPin() {}
virtual IlUInt getCardinal(const IlvGraphic*,
const IlvTransformer*) const;
virtual IlBoolean getLocation(IlUInt,
const IlvGraphic*,
const IlvTransformer* t,
IlvPoint&) const;
DeclarePropertyInfoRO();
DeclarePropertyIOConstructors(CenterPin);
};
The constructor of the
CenterPin class does nothing since this class does not store any information. The
DeclarePropertyInfoRO and
DeclarePropertyIOConstructors macros are used to make the
CenterPin class persistent. Only the
getCardinal and
getLocation methods are overloaded since the implementation of the other
IlvGrapherPin methods does not need to be changed. The source file for the
CenterPin class defines the following methods:
#include <centerpin.h>
// -------------------------------------------------------------------------
// - IO Constructors
CenterPin::CenterPin(IlvInputFile& input, IlvSymbol* s)
: IlvGrapherPin(input, s) {}
CenterPin::CenterPin(const CenterPin& src)
: IlvGrapherPin(src) {}
// -------------------------------------------------------------------------
IlUInt
CenterPin::getCardinal(const IlvGraphic*,
const IlvTransformer*) const
{
return 1;
}
// -------------------------------------------------------------------------
IlBoolean
CenterPin::getLocation(IlUInt,
const IlvGraphic* node,
const IlvTransformer* t,
IlvPoint& where) const
{
IlvRect bbox;
node->boundingBox(bbox, t);
where.move(bbox.centerx(), bbox.centery());
return IlTrue;
}
// -------------------------------------------------------------------------
// - Macros to register the class and make it persistent
IlvPredefinedPropertyIOMembers(CenterPin)
IlvRegisterPropertyClass(CenterPin, IlvGrapherPin);
The implementation of the getCardinal method is straightforward and returns 1 for any node and transformer. The getLocation method simply queries the transformed bounding box of the node and returns its center. (The index of the connection pin is not used since this class defines only one connection pin.) The declaration of the CenterPin class is provided in the file <ILVHOME>/samples/grapher/include/centerpin.h. Its implementation can be found in the file <ILVHOME>/samples/grapher/src/centerpin.cpp.
Version 6.0
Copyright © 2015, Rogue Wave Software, Inc. All Rights Reserved.