View Javadoc

1   /*
2    WSMO Studio - a Semantic Web Service Editor
3    Copyright (c) 2004-2007, Ontotext Lab. / SIRMA Group
4    
5    This library is free software; you can redistribute it and/or modify it under
6    the terms of the GNU Lesser General Public License as published by the Free
7    Software Foundation; either version 2.1 of the License, or (at your option)
8    any later version.
9    This library is distributed in the hope that it will be useful, but WITHOUT
10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   details.
13   You should have received a copy of the GNU Lesser General Public License along
14   with this library; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16   */
17  
18  /***
19   * <p>Title: WSMO Studio</p>
20   * <p>Description: Semantic Web Service Editor</p>
21   * <p>Copyright:  Copyright (c) 2004-2007</p>
22   * <p>Company: Ontotext Lab. / SIRMA </p>
23   */
24  
25  package org.wsmostudio.bpmo.figures;
26  
27  import org.eclipse.draw2d.Graphics;
28  import org.eclipse.draw2d.PolylineConnection;
29  import org.eclipse.draw2d.geometry.*;
30  
31  public class RoundedPolyline extends PolylineConnection {
32      
33      private static final int stepLine = 6;
34      private static final int stepLineMin = 4;
35      
36      private boolean isDefaultBranch = false;
37      
38  	protected void outlineShape(Graphics g) {
39  		PointList originalPoints = getPoints();
40  		PointList newPoints = new PointList();
41  		newPoints.addPoint(originalPoints.getFirstPoint());
42  		for(int i = 1; i < originalPoints.size() - 1; i++) {
43  			Point refPoint = originalPoints.getPoint(i);
44  			Point prevPoint = originalPoints.getPoint(i-1);
45  			Point nextPoint = originalPoints.getPoint(i+1);
46  			
47  			int lengPrevious = Math.max(Math.abs(refPoint.x - prevPoint.x), 
48  					Math.abs(refPoint.y - prevPoint.y));
49  			int lengNext = Math.max(Math.abs(refPoint.x - nextPoint.x), 
50  					Math.abs(refPoint.y - nextPoint.y));
51  			int r = Math.min(Math.min(lengPrevious / 2, lengNext / 2), 20);
52  			
53  			int dxPrev = r * sign(prevPoint.x - refPoint.x); 
54  			int dyPrev = r * sign(prevPoint.y - refPoint.y); 
55  			int dxNext = r * sign(nextPoint.x - refPoint.x); 
56  			int dyNext = r * sign(nextPoint.y - refPoint.y); 
57  			
58  			Point prevLineEnd = new Point(refPoint.x + dxPrev, refPoint.y + dyPrev);
59  			newPoints.addPoint(prevLineEnd);
60  			Point nextLineStart = new Point(refPoint.x + dxNext, refPoint.y + dyNext);
61  			
62  			if (r < 3) { // too small radius
63  				g.drawLine(prevLineEnd, nextLineStart);
64  			}
65  			else {
66  				int arcCenterX = refPoint.x + dxNext + dxPrev;
67  				int arcCenterY = refPoint.y + dyNext + dyPrev;
68  
69  				double step = Math.min(Math.max(Math.PI / r, 0.08), 0.2);
70  				Point arcPoint = null;
71  				for(double rad = 0.0; rad <= Math.PI / 2 ; rad += step) {
72  					Point newArcPoint = new Point(arcCenterX - (int)Math.round(r * Math.cos(rad)) * sign(dxNext + dxPrev), 
73  							arcCenterY - (int)Math.round(r * Math.sin(rad)) * sign(dyNext + dyPrev));
74  					if (arcPoint != null) {
75  						g.drawLine(arcPoint, newArcPoint);
76  					}
77  					else {
78  						g.drawLine(newArcPoint, 
79  								(newArcPoint.getDistance(prevLineEnd) < newArcPoint.getDistance(nextLineStart)) ?
80  										prevLineEnd
81  										: nextLineStart);
82  					}
83  					arcPoint = newArcPoint;
84  				}
85  				g.drawLine(arcPoint, 
86  						(arcPoint.getDistance(prevLineEnd) < arcPoint.getDistance(nextLineStart)) ?
87  								prevLineEnd
88  								: nextLineStart);
89  			}
90  			newPoints.addPoint(nextLineStart);
91  		}
92  		newPoints.addPoint(originalPoints.getLastPoint());
93  		for (int i = 0; i < newPoints.size(); i += 2) {
94  			g.drawLine(newPoints.getPoint(i), newPoints.getPoint(i+1));
95  		}
96  		
97  		if (isDefaultBranch && newPoints.size() > 1) {
98  		   Point pt1 = newPoints.getPoint(0);
99             Point pt2 = newPoints.getPoint(1);
100            int dist = pt1.getDistance2(pt2);
101            if (dist > 40) {
102                int slashSize = (dist > 100)? stepLine : stepLineMin;
103                int dX = pt2.x - pt1.x;
104                int dY = pt2.y - pt1.y;
105                
106                int offsetX1 = slashSize * (sign(dX) + sign(dY));
107                int offsetY1 = slashSize * (sign(dY) - sign(dX));
108                Point refPoint1 = new Point(pt1.x + offsetX1, pt1.y + offsetY1);
109 
110                int offsetX2 = slashSize * (3 * sign(dX) - sign(dY));
111                int offsetY2 = slashSize * (3 * sign(dY) + sign(dX));
112                Point refPoint2 = new Point(pt1.x + offsetX2, pt1.y + offsetY2);
113 
114                g.drawLine(refPoint1, refPoint2);
115            }
116 		}
117 	}
118 	
119     public void setDefaultBranch(boolean value) {
120         this.isDefaultBranch = value;
121     }
122 
123 	public Rectangle getBounds() {
124 	    Rectangle rect = super.getBounds();
125 	    rect.union(rect.x - 3 * stepLine, rect.y - 3 * stepLine);
126         rect.union(rect.x + rect.width + 3 * stepLine, rect.y + rect.height + 3 * stepLine);
127 	    return rect;
128 	}
129 	private int sign(int test) {
130 		if (test > 0) {
131 			return 1;
132 		}
133 		if (test < 0) {
134 			return -1;
135 		}
136         return 0;
137 	}
138 }
139 
140 /*
141  * $Log$
142  * Revision 1.1  2007/08/07 13:41:00  alex_simov
143  * Connections have rounded edges (with Manhattan routing style)
144  *
145  */