/******************************************************************************* * Copyright (c) 2006-2012 * Software Technology Group, Dresden University of Technology * DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026 * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Software Technology Group - TU Dresden, Germany; * DevBoost GmbH - Berlin, Germany * - initial API and implementation ******************************************************************************/ /* * Copyright (c) 2006 Borland Software Corporation * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Dmitry Stadnik (Borland) - initial API and implementation */ package org.reuseware.application.taipan.figures; import org.eclipse.draw2d.AnchorListener; import org.eclipse.draw2d.ArrowLocator; import org.eclipse.draw2d.Connection; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.ConnectionLocator; import org.eclipse.draw2d.ConnectionRouter; import org.eclipse.draw2d.DelegatingLayout; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.RotatableDecoration; import org.eclipse.draw2d.Shape; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.Rectangle; /** * Generic shape-based connection. * * @author dstadnik */ public abstract class ShapeConnection extends Shape implements Connection, AnchorListener { private ConnectionAnchor startAnchor, endAnchor; private ConnectionRouter connectionRouter = ConnectionRouter.NULL; private RotatableDecoration startArrow, endArrow; private PointList points; public ShapeConnection() { setLayoutManager(new DelegatingLayout()); points = new PointList(); points.addPoint(new Point(0, 0)); points.addPoint(new Point(100, 100)); } protected Rectangle getShapeBounds() { return getPoints().getBounds().getExpanded(lineWidth / 2, lineWidth / 2); } public Rectangle getBounds() { if (bounds == null) { bounds = getShapeBounds(); for (int i = 0; i < getChildren().size(); i++) { IFigure child = (IFigure) getChildren().get(i); bounds.union(child.getBounds()); } } return bounds; } public void layout() { if (getSourceAnchor() != null && getTargetAnchor() != null) connectionRouter.route(this); Rectangle oldBounds = bounds; super.layout(); bounds = null; if (!getBounds().contains(oldBounds)) { getParent().translateToParent(oldBounds); getUpdateManager().addDirtyRegion(getParent(), oldBounds); } repaint(); fireFigureMoved(); } public void revalidate() { super.revalidate(); connectionRouter.invalidate(this); } public PointList getPoints() { return points; } public void setPoints(PointList points) { erase(); this.points = points; bounds = null; firePropertyChange(Connection.PROPERTY_POINTS, null, points); repaint(); } public void addNotify() { super.addNotify(); hookSourceAnchor(); hookTargetAnchor(); } private void hookSourceAnchor() { if (getSourceAnchor() != null) getSourceAnchor().addAnchorListener(this); } private void hookTargetAnchor() { if (getTargetAnchor() != null) getTargetAnchor().addAnchorListener(this); } public void removeNotify() { unhookSourceAnchor(); unhookTargetAnchor(); connectionRouter.remove(this); super.removeNotify(); } private void unhookSourceAnchor() { if (getSourceAnchor() != null) getSourceAnchor().removeAnchorListener(this); } private void unhookTargetAnchor() { if (getTargetAnchor() != null) getTargetAnchor().removeAnchorListener(this); } public void anchorMoved(ConnectionAnchor anchor) { revalidate(); } public ConnectionRouter getConnectionRouter() { return connectionRouter; } public void setConnectionRouter(ConnectionRouter cr) { if (cr == null) cr = ConnectionRouter.NULL; ConnectionRouter oldRouter = getConnectionRouter(); if (oldRouter != cr) { connectionRouter.remove(this); connectionRouter = cr; firePropertyChange(Connection.PROPERTY_CONNECTION_ROUTER, oldRouter, cr); revalidate(); } } public Object getRoutingConstraint() { if (getConnectionRouter() != null) return getConnectionRouter().getConstraint(this); else return null; } public void setRoutingConstraint(Object cons) { if (connectionRouter != null) connectionRouter.setConstraint(this, cons); revalidate(); } public ConnectionAnchor getSourceAnchor() { return startAnchor; } protected RotatableDecoration getSourceDecoration() { return startArrow; } public ConnectionAnchor getTargetAnchor() { return endAnchor; } protected RotatableDecoration getTargetDecoration() { return endArrow; } public void setSourceAnchor(ConnectionAnchor anchor) { if (anchor == startAnchor) return; unhookSourceAnchor(); startAnchor = anchor; if (getParent() != null) hookSourceAnchor(); revalidate(); } public void setSourceDecoration(RotatableDecoration dec) { if (startArrow == dec) return; if (startArrow != null) remove(startArrow); startArrow = dec; if (startArrow != null) add(startArrow, new ArrowLocator(this, ConnectionLocator.SOURCE)); } public void setTargetAnchor(ConnectionAnchor anchor) { if (anchor == endAnchor) return; unhookTargetAnchor(); endAnchor = anchor; if (getParent() != null) hookTargetAnchor(); revalidate(); } public void setTargetDecoration(RotatableDecoration dec) { if (endArrow == dec) return; if (endArrow != null) remove(endArrow); endArrow = dec; if (endArrow != null) add(endArrow, new ArrowLocator(this, ConnectionLocator.TARGET)); } }