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}