001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.uml.ui.products.ad.viewfactory;
043:
044: import java.awt.Shape;
045: import java.awt.geom.Ellipse2D;
046: import java.awt.geom.GeneralPath;
047: import java.awt.Rectangle;
048: import java.awt.Color;
049:
050: import org.netbeans.modules.uml.ui.support.viewfactorysupport.IDrawInfo;
051: import org.netbeans.modules.uml.ui.support.viewfactorysupport.DrawEngineArrowheadKindEnum; //import com.tomsawyer.util.TSConstPoint;
052: import com.tomsawyer.drawing.geometry.TSConstPoint;
053: import com.tomsawyer.editor.TSEColor;
054: import com.tomsawyer.editor.graphics.TSEGraphics;
055:
056: public class ETCirclePlusArrow extends ETArrowHead {
057: public ETCirclePlusArrow() {
058: super (DrawEngineArrowheadKindEnum.DEAK_CIRCLE_WITH_PLUS);
059: }
060:
061: /* (non-Javadoc)
062: * @see org.netbeans.modules.uml.ui.products.ad.viewfactory.ETArrowHead#isOpenRegion()
063: */
064: protected boolean isOpenRegion() {
065: return false;
066: }
067:
068: public boolean draw(IDrawInfo pInfo, TSConstPoint fromPt,
069: TSConstPoint toPt, TSEColor color) {
070: Rectangle dvRect = getCircleBounds(pInfo, fromPt, toPt);
071: return drawCircle(pInfo, dvRect, TSEColor.white)
072: && drawCross(pInfo, dvRect, color);
073: }
074:
075: /*
076: * Draw the circle section of the shape.
077: */
078: protected boolean drawCircle(IDrawInfo pInfo, Rectangle dvRect,
079: TSEColor color) {
080: Shape shape = getCircle(dvRect);
081: TSEGraphics dc = pInfo.getTSEGraphics();
082: boolean didDraw;
083: if (shape != null) {
084: if (isFilled() || isOpenRegion() == false) {
085: Color prevColor = dc.getColor();
086: dc.setColor(color);
087: dc.fill(shape);
088: dc.setColor(prevColor);
089: }
090: dc.draw(shape);
091: didDraw = true;
092: } else
093: didDraw = false;
094:
095: return didDraw;
096: }
097:
098: /*
099: * Draw the cross section of the shape.
100: */
101: protected boolean drawCross(IDrawInfo pInfo, Rectangle dvRect,
102: TSEColor color) {
103: Shape shape = getCross(dvRect);
104: TSEGraphics dc = pInfo.getTSEGraphics();
105: boolean didDraw;
106: if (shape != null) {
107: dc.draw(shape);
108: didDraw = true;
109: } else
110: didDraw = false;
111:
112: return didDraw;
113: }
114:
115: /* (non-Javadoc)
116: * @see org.netbeans.modules.uml.ui.support.viewfactorysupport.IETArrowHead#getDefaultHeight()
117: */
118: public int getDefaultHeight() {
119: return 14; // Just a guess.
120: }
121:
122: /* (non-Javadoc)
123: * @see org.netbeans.modules.uml.ui.support.viewfactorysupport.IETArrowHead#getDefaultWidth()
124: */
125: public int getDefaultWidth() {
126: return getDefaultHeight(); // We have to be a circle.
127: }
128:
129: /* (non-Javadoc)
130: * @see org.netbeans.modules.uml.ui.products.ad.viewfactory.ETArrowHead#getShape(org.netbeans.modules.uml.ui.support.viewfactorysupport.IDrawInfo, null, null)
131: */
132: public Shape getShape(IDrawInfo pInfo, TSConstPoint fromPt,
133: TSConstPoint toPt) {
134: Rectangle dvRect = getCircleBounds(pInfo, fromPt, toPt);
135: if (dvRect == null)
136: return null;
137:
138: GeneralPath finalShape = new GeneralPath(
139: GeneralPath.WIND_EVEN_ODD);
140:
141: Shape circle = getCircle(dvRect);
142: Shape cross = getCross(dvRect);
143:
144: if (finalShape != null && circle != null && cross != null) {
145: // Build the final comp, object.
146: finalShape.append(circle, false);
147: finalShape.append(cross, false);
148: }
149: return finalShape;
150: }
151:
152: /*
153: * Returns the Circle shape given the circle device rectangle.
154: */
155: protected Shape getCircle(Rectangle dvRect) {
156: if (dvRect == null)
157: return null;
158:
159: double max = Math.max(dvRect.getWidth(), dvRect.getHeight());
160: return new Ellipse2D.Double(dvRect.getX(), dvRect.getY(), max,
161: max);
162: }
163:
164: /*
165: * Returns the device rectangle the contains the circle.
166: */
167: protected Rectangle getCircleBounds(IDrawInfo pInfo,
168: TSConstPoint fromPt, TSConstPoint toPt) {
169: // We use the filled diamond to detrimine the rectangle, it beats recalculating
170: // all those vectors.
171: ETArrowHead diamond = new ETFilledDiamond();
172: if (diamond != null) {
173: diamond.setWidth(this .getWidth());
174: diamond.setHeight(this .getHeight() / 2);
175:
176: Shape pShape = diamond.getShape(pInfo, fromPt, toPt);
177: return pShape != null ? pShape.getBounds() : null;
178: }
179: return null;
180: }
181:
182: /*
183: * Returns the cross shape given the circle bounding rectangle.
184: */
185: protected Shape getCross(Rectangle dvRect) {
186: int diamiter = (int) Math.max(dvRect.getWidth(), dvRect
187: .getHeight());
188: if (diamiter == 0)
189: return null;
190:
191: GeneralPath polyline = new GeneralPath(
192: GeneralPath.WIND_EVEN_ODD);
193:
194: int radius = diamiter / 2;
195:
196: // Horizontal.
197: polyline.moveTo((int) dvRect.x, (int) (dvRect.y + radius));
198: polyline.lineTo((int) (dvRect.x + diamiter),
199: (int) (dvRect.y + radius));
200:
201: // Vert.
202: polyline.moveTo((int) (dvRect.x + radius), (int) dvRect.y);
203: polyline.lineTo((int) (dvRect.x + radius),
204: (int) (dvRect.y + diamiter));
205: return polyline;
206: }
207: }
|