001/* A site for instances of PortTerminal. */
002
003/*
004 Copyright (c) 2006-2014 The Regents of the University of California.
005 All rights reserved.
006
007 Permission is hereby granted, without written agreement and without
008 license or royalty fees, to use, copy, modify, and distribute this
009 software and its documentation for any purpose, provided that the above
010 copyright notice and the following two paragraphs appear in all copies
011 of this software.
012
013 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
014 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
015 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
016 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
017 SUCH DAMAGE.
018
019 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
020 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
021 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
022 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
023 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
024 ENHANCEMENTS, OR MODIFICATIONS.
025 */
026
027package ptolemy.vergil.actor;
028
029import java.awt.geom.Point2D;
030import java.awt.geom.Rectangle2D;
031
032import diva.canvas.AbstractSite;
033import diva.canvas.CanvasUtilities;
034import diva.canvas.Figure;
035
036///////////////////////////////////////////////////////////////////
037//// PortConnectSite
038
039/**
040 A site for instances of PortTerminal. For non-muiltiports, a PortTerminal
041 will have exactly one of these sites, and it will be the connect site
042 for the terminal.  Multiports, however, will generate distinct site for
043 each connection to the multiport.
044 <p>
045 The normal for this site (the direction in which connections are made
046 to it) is fixed when the site is constructed, and cannot be changed
047 after that.
048
049 @author Edward A. Lee
050 @version $Id$
051 @since Ptolemy II 5.2
052 @see PortTerminal
053 @Pt.ProposedRating Yellow (eal)
054 @Pt.AcceptedRating Red (eal)
055 */
056public class PortConnectSite extends AbstractSite {
057    /** Create a port connect site for the specified figure
058     *  and id. An id of zero is the default site at the port
059     *  icon. Larger ids are reserved for sites that are
060     *  used to distinguish multiple connections to a multiport.
061     *  @param figure The parent figure.
062     *  @param terminal The port terminal.
063     *  @param id The ID.
064     *  @param normal The normal for this connect site.
065     */
066    public PortConnectSite(Figure figure, PortTerminal terminal, int id,
067            double normal) {
068        _parentFigure = figure;
069        _terminal = terminal;
070        _id = id;
071        _hasNormal = true;
072        _normal = CanvasUtilities.moduloAngle(normal);
073    }
074
075    ///////////////////////////////////////////////////////////////////
076    ////                         public methods                    ////
077
078    /** Return the parent figure specified in the constructor.
079     *  @return The parent figure.
080     */
081    @Override
082    public Figure getFigure() {
083        return _parentFigure;
084    }
085
086    /** Return the ID specified in the constructor.
087     *  The default ID is zero. When additional instances of this
088     *  site are associated with an instance of PortTerminal, they
089     *  each get a unique ID starting with 1 and increasing by 1.
090     *  The ID determines the position of the site relative to the
091     *  port.
092     *  @return The ID of the site.
093     */
094    @Override
095    public int getID() {
096        return _id;
097    }
098
099    /** Get the position of this site.
100     *  @param normal The normal.
101     *  @return The position of this site.
102     */
103    @Override
104    public Point2D getPoint(double normal) {
105        Rectangle2D bounds = _parentFigure.getShape().getBounds2D();
106
107        double x = bounds.getX();
108        double y = bounds.getY();
109        double width = bounds.getWidth();
110        double height = bounds.getHeight();
111
112        double xout;
113        double yout;
114
115        if (normal < CanvasUtilities.NORTHWEST
116                || normal > CanvasUtilities.SOUTHWEST) {
117            // On the left edge.
118            if (_id > 0) {
119                int numberOfLinks = _terminal.getNumberOfLinks();
120                xout = x - (numberOfLinks - _id)
121                        * IOPortController.MULTIPORT_CONNECTION_SPACING;
122                yout = y + height / 2 - (numberOfLinks - _id)
123                        * IOPortController.MULTIPORT_CONNECTION_SPACING;
124            } else {
125                xout = x;
126                yout = y + height / 2;
127            }
128        } else if (normal < CanvasUtilities.NORTHEAST) {
129            // On the top edge.
130            if (_id > 0) {
131                int numberOfLinks = _terminal.getNumberOfLinks();
132                yout = y - (numberOfLinks - _id)
133                        * IOPortController.MULTIPORT_CONNECTION_SPACING;
134                xout = x + width / 2 - (numberOfLinks - _id)
135                        * IOPortController.MULTIPORT_CONNECTION_SPACING;
136            } else {
137                xout = x + width / 2;
138                yout = y;
139            }
140        } else if (normal < CanvasUtilities.SOUTHEAST) {
141            // On the right edge.
142            if (_id > 0) {
143                xout = x + width + (_id - 1)
144                        * IOPortController.MULTIPORT_CONNECTION_SPACING;
145                yout = y + height / 2 + (_id - 1)
146                        * IOPortController.MULTIPORT_CONNECTION_SPACING;
147            } else {
148                xout = x + width;
149                yout = y + height / 2;
150            }
151        } else {
152            // On the bottom edge.
153            if (_id > 0) {
154                yout = y + height + (_id - 1)
155                        * IOPortController.MULTIPORT_CONNECTION_SPACING;
156                xout = x + width / 2 + (_id - 1)
157                        * IOPortController.MULTIPORT_CONNECTION_SPACING;
158            } else {
159                xout = x + width / 2;
160                yout = y + height;
161            }
162        }
163
164        return new Point2D.Double(xout, yout);
165    }
166
167    /** Get the terminal to which this site belongs.
168     *  @return The terminal to which this site belongs.
169     */
170    public PortTerminal getTerminal() {
171        return _terminal;
172    }
173
174    /** Get the horizontal position of this site with
175     *  the normal that was set up by the constructor.
176     *  @return The horizontal position of this site.
177     */
178    @Override
179    public double getX() {
180        return getPoint().getX();
181    }
182
183    /** Get the vertical position of this site with
184     *  the normal that was set up by the constructor.
185     *  @return The vertical position of this site.
186     */
187    @Override
188    public double getY() {
189        return getPoint().getY();
190    }
191
192    /** Do nothing. The normal is fixed at the time this is constructed.
193     *  @param normal The normal.
194     */
195    @Override
196    public void setNormal(double normal) {
197        // Do nothing.
198    }
199
200    /** Return a string representation of this connect site.
201     *  @return The name of the port and the ID.
202     */
203    @Override
204    public String toString() {
205        return "PortConnectSite for connection number " + _id + " of port "
206                + _terminal.getPort().getFullName();
207    }
208
209    ///////////////////////////////////////////////////////////////////
210    ////                         private variables                 ////
211
212    /** The ID. */
213    private int _id = 0;
214
215    /** The parent figure. */
216    private Figure _parentFigure;
217
218    /** The port terminal. */
219    private PortTerminal _terminal;
220}