Home » Modeling » Graphiti » Connections inside ContainerShapes
Connections inside ContainerShapes [message #716846] |
Thu, 18 August 2011 15:14 |
|
Hi all,
It appears as if all Connections have the Diagram as parent. I'm trying to create connections inside a ContainerShape such that when resizing the container, the connection lines are clipped to the container bounds.
Failing that, is there a way to put another Diagram inside a ContainerShape?
Thanks!
|
|
| |
Re: Connections inside ContainerShapes [message #717159 is a reply to message #717109] |
Fri, 19 August 2011 13:19 |
|
Hi Michael,
Thanks for the quick response. Just to give you some context here: I'm working on the BPMN2 Modeler (http://www.eclipse.org/bpmn2-modeler) specifically the sub-process element. A sub-process can have a "collapsed" and "expanded" state; when collapsed, the figure looks exactly like any other task figure in the editor except it has a "+" activator button which, when clicked, changes its state to expanded. In the expanded state, it *should* behave very much like the top-level diagram except that it should still have the same visuals as before (i.e. no grid lines, gradient background, etc.). Sub-processes can contain tasks and connections and when it is resized, the task figures are correctly clipped but the connections are not (as you already know). This makes for a very confusing user experience as the sub-process figure is rearranged to achieve an optimal layout.
I tried adding a Diagram as a child of the sub-process' ContainerShape and then adding the connections to that Diagram, but this does not appear to have any effect (the connections still are not clipped).
I've also considered using a drilldown feature, but this makes for an even more confusing user experience - an expanded sub-process is intended to be viewed within the context of the entire process and additional editor tabs or windows defeat that purpose.
I suppose an acceptable solution would be to constrain the minimum size of an expanded sub-process so that all of its child elements are visible...any other suggestions?
Thanks again,
Bob
|
|
| | | |
Re: Connections inside ContainerShapes [message #1082050 is a reply to message #924275] |
Thu, 08 August 2013 02:45 |
|
After playing around with this some more, I have a solution. I've created a class, ConnectionLayerClippingStrategy which implements a clipping strategy for the Connection Layer in the GraphicalViewer. This is hooked in to the viewer any time after GraphicalViewer.setContents() is called, which typically happens in DiagramBehavior.initializeGraphicalViewer().
The class looks like this:
public class ConnectionLayerClippingStrategy implements IClippingStrategy {
protected Diagram diagram;
protected GraphicalViewer graphicalViewer;
public static void applyTo(GraphicalViewer graphicalViewer) {
ScalableFreeformRootEditPart rootEditPart = (ScalableFreeformRootEditPart) graphicalViewer.getRootEditPart();
Figure connectionLayer = (Figure) rootEditPart.getLayer(LayerConstants.CONNECTION_LAYER);
if (connectionLayer.getClippingStrategy()==null) {
EditPart editPart = graphicalViewer.getContents();
Diagram diagram = (Diagram)editPart.getModel();
IClippingStrategy clippingStrategy = new ConnectionLayerClippingStrategy(graphicalViewer, diagram);
connectionLayer.setClippingStrategy(clippingStrategy);
}
}
public ConnectionLayerClippingStrategy(GraphicalViewer graphicalViewer, Diagram diagram) {
this.diagram = diagram;
this.graphicalViewer = graphicalViewer;
}
@Override
public Rectangle[] getClip(IFigure childFigure) {
// search for the Graphiti Connection PictogramElement that represents this childFigure
// NOTE: there may be a better way to do this, but I wanted to stay away from Graphiti
// 0.9.2 vs 0.10.0 version differences as much as possible.
for (Object value : graphicalViewer.getEditPartRegistry().values()) {
GraphicalEditPart part = (GraphicalEditPart)value;
if (part.getFigure() == childFigure) {
Object model = part.getModel();
if (model instanceof Connection) {
// This is a Connection PE. In my case the Connection MAY have
// a ContainerShape attached to a ConnectionDecorator and I need
// to have the connection clipped within the bounds of the ContainerShape
// so that it is drawn on top of the Connection instead of underneath it.
Connection connection = (Connection)model;
ContainerShape messageShape = findMessageShape(connection);
if (messageShape!=null) {
Rectangle inner = getClip(messageShape)[0];
Rectangle outer = childFigure.getBounds();
// calculate the clipping rectangles
return getClip(outer,inner);
}
}
}
}
return new Rectangle[] {childFigure.getBounds()};
}
private Rectangle[] getClip(Rectangle outer, Rectangle inner) {
if (outer.width > inner.width) {
if (outer.height > inner.height) {
Rectangle[] clip = new Rectangle[4];
clip[0] = new Rectangle(
outer.x, outer.y,
outer.width, inner.y - outer.y);
clip[1] = new Rectangle(
outer.x, inner.y,
inner.x - outer.x,
inner.height
);
clip[2] = new Rectangle(
inner.x + inner.width, inner.y,
(outer.x + outer.width) - (inner.x + inner.width),
inner.height
);
clip[3] = new Rectangle(
outer.x, inner.y + inner.height,
outer.width, (outer.y + outer.height) - (inner.y + inner.height));
return clip;
}
}
return new Rectangle[] {outer};
}
private Rectangle[] getClip(ContainerShape pe) {
GraphicsAlgorithm ga = pe.getGraphicsAlgorithm();
return new Rectangle[] { new Rectangle(ga.getX(), ga.getY(), ga.getWidth(), ga.getHeight()) };
}
private ContainerShape findMessageShape(Connection connection) {
// do some fancy searching stuff here and return a ContainerShape if one is
// attached to the Connection, or null if not.
}
}
Then, right after the GraphicalViewer.setContents() is called, the clipping strategy is hooked in like so:
ConnectionLayerClippingStrategy.applyTo(getGraphicalViewer());
Here's a screenshot of what this looks like:
That's all there's to it
Cheers,
Bob
|
|
|
Goto Forum:
Current Time: Fri Apr 19 04:38:24 GMT 2024
Powered by FUDForum. Page generated in 0.02062 seconds
|