001/* The site for ports.
002
003 Copyright (c) 1998-2016 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.vergil.toolbox;
029
030import java.awt.geom.Rectangle2D;
031
032import javax.swing.SwingConstants;
033
034import diva.canvas.AbstractSite;
035import diva.canvas.Figure;
036import ptolemy.kernel.Port;
037
038/**
039 A site that locates itself on the bounds of a figure's shape, designed
040 for placing ports.
041
042 @version $Id$
043 @author Edward A. Lee
044 @since Ptolemy II 2.0
045 @Pt.ProposedRating Red (eal)
046 @Pt.AcceptedRating Red (johnr)
047 */
048public class PortSite extends AbstractSite {
049    /** Create a new site on the given figure with the given ID
050     *  port type, and port number.
051     *  @param figure The figure for the entity icon.
052     *  @param port The port, which is ignored by this method
053     *  @param number The number of the port within its kind, starting with 0.
054     *  @param count The number of ports of its kind.
055     *  @param direction One of SwingConstants.{WEST, NORTH, EAST, SOUTH}.
056     */
057    public PortSite(Figure figure, Port port, int number, int count,
058            int direction) {
059        _parentFigure = figure;
060        // Ignored _port = port;
061        _number = number;
062        _count = count;
063        _direction = direction;
064        _normal = _getNormal();
065    }
066
067    ///////////////////////////////////////////////////////////////////
068    ////                         public methods                    ////
069
070    /** Get the figure to which this site is attached.
071     */
072    @Override
073    public Figure getFigure() {
074        return _parentFigure;
075    }
076
077    /** Return the ID for this site, which is the number of the port.
078     *  @return The number of the port.
079     */
080    @Override
081    public int getID() {
082        return _number;
083    }
084
085    /** Get the normal of the site.
086     */
087    @Override
088    public double getNormal() {
089        return _normal;
090    }
091
092    /** Get the x-coordinate of the site.
093     */
094    @Override
095    public double getX() {
096        Rectangle2D bounds = _parentFigure.getShape().getBounds();
097        if (_direction == SwingConstants.WEST) {
098            // Port is on the left.
099            return bounds.getX();
100        } else if (_direction == SwingConstants.EAST) {
101            // Port is on the right.
102            return bounds.getX() + bounds.getWidth();
103        } else {
104            // Port is on the top or bottom side.
105            int halfCount = _count / 2;
106            double offset = bounds.getWidth() / 2.0 - halfCount * _snap;
107
108            // If there are an even number of ports, skip the middle
109            // position to get symmetry.
110            boolean skipOne = _count / 2 * 2 == _count;
111
112            if (skipOne && _number >= _count / 2) {
113                offset += _snap;
114            }
115
116            return bounds.getX() + _snap * _number + offset;
117        }
118    }
119
120    /** Get the y-coordinate of the site.
121     */
122    @Override
123    public double getY() {
124        Rectangle2D bounds = _parentFigure.getShape().getBounds();
125        if (_direction == SwingConstants.SOUTH) {
126            // Port is on the bottom.
127            return bounds.getY() + bounds.getHeight();
128        } else if (_direction == SwingConstants.NORTH) {
129            // Port is on the top.
130            return bounds.getY();
131        } else {
132            // Port is on the left or right.
133            int halfCount = _count / 2;
134            double offset = bounds.getHeight() / 2.0 - halfCount * _snap;
135
136            // If there are an even number of ports, skip the middle
137            // position to get symmetry.
138            boolean skipOne = _count / 2 * 2 == _count;
139
140            if (skipOne && _number >= _count / 2) {
141                offset += _snap;
142            }
143            return bounds.getY() + _snap * _number + offset;
144        }
145    }
146
147    @Override
148    public String toString() {
149        return "BoundsSite[" + getX() + "," + getY() + "," + getNormal() + "]";
150    }
151
152    ///////////////////////////////////////////////////////////////////
153    ////                         private methods                   ////
154
155    /** Get the normal of the site.
156     */
157    private double _getNormal() {
158        if (_direction == SwingConstants.NORTH) {
159            return -Math.PI / 2;
160        } else if (_direction == SwingConstants.EAST) {
161            return 0.0;
162        } else if (_direction == SwingConstants.WEST) {
163            return Math.PI;
164        } else {
165            return Math.PI / 2;
166        }
167    }
168
169    ///////////////////////////////////////////////////////////////////
170    ////                         private variables                 ////
171
172    /** The number of ports of the kind as this one. */
173    private int _count;
174
175    /** The direction of the port. */
176    private int _direction;
177
178    /** The normal. */
179    private double _normal;
180
181    /** The number of this port within the ones of the same kind. */
182    private int _number;
183
184    /** The parent figure. */
185    private Figure _parentFigure;
186
187    /** The snap resolution.  FIXME: This should not be here. */
188    private double _snap = 10.0;
189}