[kepler-dev] Duplicate Vergil classes

Christopher Brooks cxh at eecs.berkeley.edu
Thu Jun 2 13:11:26 PDT 2005


Hi Shawn,

Is there anyway we can modify the parent class in the Ptolemy II cvs
repository so that you extend ptolemy.vergil.actor.IOPortController
instead of doing a wholesale copy of the class?

If you don't yet have write access to the Ptolemy II cvs repository,
I'm more than willing to give it to you so you could add extension
points to Ptolemy II. 

The reason is that we have gotten in to quite a bit of trouble
maintenance-wise when we have duplicated code.  The JNI and Single
Window code from Thales caused Edward no end of grief when
he went to update the copied base classes.

Anyway, the up shot is that I'm more than willing to help out
if we can avoid duplicate code.

_Christopher



--------

    bowers      05/06/02 12:55:03
    
      Added:       src/exp/ptolemy/vergil/actor IOPortController.java
      Log:
      for adding semantic types to ports
      
      Revision  Changes    Path
      1.1                  kepler/src/exp/ptolemy/vergil/actor/IOPortController
   .java
      
      Index: IOPortController.java
      ===================================================================
      /* The node controller for ports contained in entities.
      
      Copyright (c) 1998-2005 The Regents of the University of California.
      All rights reserved.
      Permission is hereby granted, without written agreement and without
      license or royalty fees, to use, copy, modify, and distribute this
      software and its documentation for any purpose, provided that the above
      copyright notice and the following two paragraphs appear in all copies
      of this software.
      
      IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
      FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
      ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
      THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
      SUCH DAMAGE.
      
      THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
      INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
      MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
      PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
      CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
      ENHANCEMENTS, OR MODIFICATIONS.
      
      PT_COPYRIGHT_VERSION_2
      COPYRIGHTENDKEY
      */
      
      package ptolemy.vergil.actor;
      
      
      import org.kepler.sms.gui.SemanticTypeEditor; // added by bowers
      
      import java.awt.Color;
      import java.awt.Frame;		// added by bowers
      import java.awt.Shape;
      import java.awt.event.ActionEvent;
      import java.awt.geom.AffineTransform;
      import java.awt.geom.Ellipse2D;
      
      import javax.swing.JOptionPane;	// added by bowers
      import javax.swing.SwingUtilities;
      
      import ptolemy.actor.IOPort;
      import ptolemy.actor.gui.DebugListenerTableau;
      import ptolemy.actor.gui.Effigy;
      import ptolemy.actor.gui.Tableau;
      import ptolemy.actor.gui.TextEffigy;
      import ptolemy.actor.parameters.ParameterPort;
      import ptolemy.data.type.Typeable;
      import ptolemy.kernel.Port;
      import ptolemy.kernel.util.IllegalActionException;
      import ptolemy.kernel.util.KernelException;
      import ptolemy.kernel.util.NamedObj;
      import ptolemy.kernel.util.StringAttribute;
      import ptolemy.util.MessageHandler;
      import ptolemy.vergil.basic.BasicGraphController;
      import ptolemy.vergil.basic.BasicGraphFrame;
      import ptolemy.vergil.kernel.AttributeController;
      import ptolemy.vergil.toolbox.FigureAction;
      import ptolemy.vergil.toolbox.MenuActionFactory;
      import diva.canvas.CanvasUtilities;
      import diva.canvas.Figure;
      import diva.canvas.Site;
      import diva.canvas.connector.FixedNormalSite;
      import diva.canvas.connector.PerimeterSite;
      import diva.canvas.connector.TerminalFigure;
      import diva.canvas.interactor.CompositeInteractor;
      import diva.canvas.toolbox.BasicFigure;
      import diva.canvas.toolbox.SVGUtilities;
      import diva.graph.GraphController;
      import diva.graph.NodeRenderer;
      import diva.util.java2d.Polygon2D;
      import diva.util.java2d.ShapeUtilities;
      
      
      /////////////////////////////////////////////////////////////////////////
   /
      //// IOPortController
      
      /**
         This class provides interaction with nodes that represent Ptolemy II
         ports on an actor.  It provides a double click binding and context
         menu entry to edit the parameters of the port ("Configure") and a
         command to get documentation.
         It can have one of two access levels, FULL or PARTIAL.
         If the access level is FULL, the the context menu also
         contains a command to rename the node.
         Note that whether the port is an input or output or multiport cannot
         be controlled via this interface.  The "Configure Ports" command of
         the container should be invoked instead.
      
         @author Steve Neuendorffer and Edward A. Lee
         @version $Id: IOPortController.java,v 1.1 2005/06/02 19:55:03 bowers E
   xp $
         @since Ptolemy II 2.0
         @Pt.ProposedRating Red (eal)
         @Pt.AcceptedRating Red (johnr)
      */
      public class IOPortController extends AttributeController {
          /** Create a port controller associated with the specified graph
           *  controller.  The controller is given full access.
           *  @param controller The associated graph controller.
           */
          public IOPortController(GraphController controller) {
              this(controller, FULL);
          }
      
          /** Create a port controller associated with the
           *  specified graph controller.
           *  @param controller The associated graph controller.
           *  @param access The access level.
           */
          public IOPortController(GraphController controller, Access access) {
              super(controller, access);
              setNodeRenderer(new EntityPortRenderer());
      
      	// "Semantic Types" ; added by bowers
      	//if (access == FULL) {
      	    // Add to the context menu.
      	//_portDialogFactory = new PortDialogFactory();
                  _menuFactory.addMenuItemFactory(new MenuActionFactory(
                                                          new SemanticTypeActio
   n()));
      	    //}
      
      
      
      
              // "Listen to Actor"
              _menuFactory.addMenuItemFactory(new MenuActionFactory(
                                                      new ListenToPortAction())
   );
      
              // Ports of entities do not use a selection interactor with
              // the same selection model as the rest of the first level figure
   s.
              // If this were allowed, then the port would be able to be delete
   d.
              CompositeInteractor interactor = new CompositeInteractor();
              setNodeInteractor(interactor);
              interactor.addInteractor(_menuCreator);
          }
      
          ///////////////////////////////////////////////////////////////////
          ////                         inner classes                     ////
      
          /**
           * Render the ports of components as triangles. Multiports are render
   ed
           * hollow, while single ports are rendered filled.
           */
          public class EntityPortRenderer implements NodeRenderer {
              /**  Render a visual representation of the given node. If the
               * StringAttribute _color of the node is set then use that color 
   to
               * render the node. If the StringAttribute _explanation of the no
   de is
               * set then use it to set the tooltip.
               * @see diva.graph.NodeRenderer#render(java.lang.Object)
               */
              public Figure render(Object n) {
                  final Port port = (Port) n;
      
                  // If the port has an attribute called "_hide", then
                  // do not render it.
                  if (_isPropertySet(port, "_hide")) {
                      return null;
                  }
      
                  boolean isInput = false;
                  boolean isOutput = false;
                  boolean isInputOutput = false;
      
                  // Figure out what type of port we're dealing with.
                  // If ports are not IOPorts, then draw then as ports with
                  // no direction.
                  if (port instanceof IOPort) {
                      isInput = ((IOPort) port).isInput();
                      isOutput = ((IOPort) port).isOutput();
                      isInputOutput = isInput && isOutput;
                  }
      
                  // The shape that the port will have. These are all
                  // created as oriented to the West, i.e. the left side of
                  // the actor.
                  Shape shape;
      
                  if (isInputOutput) {
                      Polygon2D.Double polygon = new Polygon2D.Double();
                      polygon.moveTo(0, -4);
                      polygon.lineTo(-4, -4);
                      polygon.lineTo(-2, 0);
                      polygon.lineTo(-4, 4);
                      polygon.lineTo(4, 4);
                      polygon.lineTo(2, 0);
                      polygon.lineTo(4, -4);
                      polygon.lineTo(0, -4);
                      polygon.closePath();
                      shape = polygon;
                  } else if (isInput) {
                      Polygon2D.Double polygon = new Polygon2D.Double();
                      polygon.moveTo(-4, 0);
                      polygon.lineTo(-4, 4);
                      polygon.lineTo(4, 0);
                      polygon.lineTo(-4, -4);
                      polygon.lineTo(-4, 0);
                      polygon.closePath();
                      shape = polygon;
                  } else if (isOutput) {
                      Polygon2D.Double polygon = new Polygon2D.Double();
                      polygon.moveTo(4, 0);
                      polygon.lineTo(4, -4);
                      polygon.lineTo(-4, 0);
                      polygon.lineTo(4, 4);
                      polygon.lineTo(4, 0);
                      polygon.closePath();
                      shape = polygon;
                  } else {
                      shape = new Ellipse2D.Double(-4, -4, 8, 8);
                  }
      
                  Color fill;
                  float lineWidth = (float) 1.5;
      
                  if (port instanceof ParameterPort) {
                      fill = Color.lightGray;
                      lineWidth = (float) 0.0;
                  } else if (port instanceof IOPort && ((IOPort) port).isMultip
   ort()) {
                      fill = Color.white;
                  } else {
                      fill = Color.black;
                  }
      
                  StringAttribute _colorAttr = (StringAttribute) (port.getAttri
   bute(
                                                                          "_col
   or"));
      
                  if (_colorAttr != null) {
                      String _color = _colorAttr.getExpression();
                      fill = SVGUtilities.getColor(_color);
                  }
      
                  ActorGraphModel model = (ActorGraphModel) getController()
                      .getGraphModel();
      
                  // Wrap the figure in a TerminalFigure to set the direction t
   hat
                  // connectors exit the port. Note that this direction is the
                  // same direction that is used to layout the port in the
                  // Entity Controller.
                  StringAttribute cardinal = (StringAttribute) port.getAttribut
   e(
                          "_cardinal");
      
                  int direction;
                  double rotation;
      
                  //             if (!(port instanceof IOPort)) {
                  //                 direction = SwingUtilities.SOUTH;
                  //             } else if (((IOPort)port).isInput() &&
                  // ((IOPort)port).isOutput()) {
                  //                 direction = SwingUtilities.SOUTH;
                  //             } else if (((IOPort)port).isInput()) {
                  //                 direction = SwingUtilities.WEST;
                  //             } else if (((IOPort)port).isOutput()) {
                  //                 direction = SwingUtilities.EAST;
                  //             } else {
                  //                 // should never happen
                  //                 direction = SwingUtilities.SOUTH;
                  //             }
                  if (cardinal == null) {
                      if (isInputOutput) {
                          direction = SwingUtilities.SOUTH;
                          rotation = -90;
                      } else if (isInput) {
                          direction = SwingUtilities.WEST;
                          rotation = 0;
                      } else if (isOutput) {
                          direction = SwingUtilities.EAST;
                          rotation = 180;
                      } else {
                          // should never happen
                          direction = SwingUtilities.SOUTH;
                          rotation = -90;
                      }
                  } else if (cardinal.getExpression().equalsIgnoreCase("NORTH")
   ) {
                      direction = SwingUtilities.NORTH;
                      rotation = 90;
                  } else if (cardinal.getExpression().equalsIgnoreCase("SOUTH")
   ) {
                      direction = SwingUtilities.SOUTH;
                      rotation = -90;
                  } else if (cardinal.getExpression().equalsIgnoreCase("EAST"))
    {
                      direction = SwingUtilities.EAST;
                      rotation = 180;
                  } else if (cardinal.getExpression().equalsIgnoreCase("WEST"))
    {
                      direction = SwingUtilities.WEST;
                      rotation = 0;
                  } else { // this shouldn't happen either
                      direction = SwingUtilities.SOUTH;
                      rotation = -90;
                  }
      
                  // Transform the port shape so it is facing the right way.
                  AffineTransform transform = AffineTransform.getRotateInstance
   (Math
                          .toRadians(rotation));
                  shape = ShapeUtilities.transformModify(shape, transform);
      
                  Figure figure = new BasicFigure(shape, fill, (float) 1.5) {
                          // Override this because we want to show the type.
                          // It doesn't work to set it once because the type
                          // has not been resolved, and anyway, it may
                          // change.
                          public String getToolTipText() {
                              String tipText = port.getName();
                              StringAttribute _explAttr = (StringAttribute) (po
   rt
                                      .getAttribute("_explanation"));
      
                              if (_explAttr != null) {
                                  tipText = _explAttr.getExpression();
                              } else if (port instanceof Typeable) {
                                  try {
                                      tipText = tipText + ", type:"
                                          + ((Typeable) port).getType();
                                  } catch (IllegalActionException ex) {
                                  }
                              }
      
                              return tipText;
                          }
                      };
      
                  // Have to do this also, or the awt doesn't display any
                  // tooltip at all.
                  figure.setToolTipText(port.getName());
      
                  double normal = CanvasUtilities.getNormal(direction);
                  Site tsite = new PerimeterSite(figure, 0);
                  tsite.setNormal(normal);
                  tsite = new FixedNormalSite(tsite);
                  figure = new TerminalFigure(figure, tsite);
                  return figure;
              }
          }
      
      
          // added by bowers
          private class SemanticTypeAction extends FigureAction {
              public SemanticTypeAction() {
                  super("Edit Semantic Type");
                  putValue("tooltip",
      		     "Configure Component Semantic Type");
              }	
      
              public void actionPerformed(ActionEvent event) {
                  // Find the target.
                  super.actionPerformed(event);
      
                  NamedObj object = getTarget();
      
      	    Frame frame = getFrame();
      	    SemanticTypeEditor editor = new SemanticTypeEditor(null, object);
      	    editor.setVisible(true);
              }
          } // SemanticTypeAction
      
      
      
          // An action to listen to debug messages of the port.
          private class ListenToPortAction extends FigureAction {
              public ListenToPortAction() {
                  super("Listen to Port");
              }
      
              public void actionPerformed(ActionEvent e) {
                  if (_configuration == null) {
                      MessageHandler.error(
                              "Cannot listen to port without a configuration.")
   ;
                      return;
                  }
      
                  // Determine which entity was selected for the listen to
                  // port action.
                  super.actionPerformed(e);
      
                  NamedObj object = getTarget();
      
                  try {
                      BasicGraphController controller = (BasicGraphController) 
   getController();
                      BasicGraphFrame frame = controller.getFrame();
                      Tableau tableau = frame.getTableau();
      
                      // effigy is of the whole model.
                      Effigy effigy = (Effigy) tableau.getContainer();
      
                      // We want to open a new window that behaves as a
                      // child of the model window.  So, we create a new text
                      // effigy inside this one.  Specify model's effigy as
                      // a container for this new effigy.
                      Effigy textEffigy = new TextEffigy(effigy,
                              effigy.uniqueName("debugListener" + object.getNam
   e()));
      
                      DebugListenerTableau debugTableau = new DebugListenerTabl
   eau(textEffigy,
                              textEffigy.uniqueName("debugListener"
                                      + object.getName()));
                      debugTableau.setDebuggable(object);
                  } catch (KernelException ex) {
                      MessageHandler.error("Failed to create debug listener.", 
   ex);
                  }
              }
          }
      }
      
      
      
    _______________________________________________
    Kepler-cvs mailing list
    Kepler-cvs at ecoinformatics.org
    http://mercury.nceas.ucsb.edu/ecoinformatics/mailman/listinfo/kepler-cvs
--------


More information about the Kepler-dev mailing list