Package jsynoptic.builtin

Source Code of jsynoptic.builtin.ConnectionShape$ConnectionShapePropertiesNames

/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 1999-2003, by :
*     Corporate:
*         Astrium SAS
*         EADS CRC
*     Individual:
*         Claude Cazenave
*     Nicolas Brodu
*
*
* $Id: ConnectionShape.java,v 1.16 2009/01/08 15:37:13 ogor Exp $
*
* Changes
* -------
*
*/
package jsynoptic.builtin;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;

import javax.swing.undo.CompoundEdit;

import jsynoptic.builtin.ui.ConnectionPropertiesPanel;

import simtools.diagram.DiagramSelection;
import simtools.diagram.ShapePointsSelection;
import simtools.diagram.Resizable;
import simtools.diagram.ElementSelection;
import simtools.diagram.TranslatableShapePointsInterface;
import simtools.diagram.gate.Connection;
import simtools.diagram.gate.ConnectionPathEdit;
import simtools.diagram.gate.Path;
import simtools.diagram.gate.ConnectionPathSelection;
import simtools.diagram.gate.Gate;
import simtools.diagram.gate.RightAnglePath;
import simtools.diagram.gate.StraightPath;
import simtools.shapes.AbstractShape;
import simtools.ui.JPropertiesPanel;
import simtools.ui.MenuResourceBundle;
import simtools.ui.ResourceFinder;

/**
* A Connection is a list of segments
*
* @author Claude Cazenave
*/
public class ConnectionShape extends Abstract1DShape implements
Connection,
Resizable,
TranslatableShapePointsInterface,
Serializable {
   
    public static MenuResourceBundle resources = ResourceFinder.getMenu(ConnectionShape.class);

    static final long serialVersionUID = -961863327687064518L;

    static Polygon arrow = new Polygon(new int[] {10,0,10},new int[] {5,0,-5},3);

    /**
     * x vertices
     * @deprecated see {@link Path} instead
     */
    protected double[] _xv;
   
   
    /**
     * y vertices
     * @deprecated see {@link Path} instead
     */
    protected double[] _yv;

    /**
     * Display an arrow on last extremity
     * @deprecated
     */
    protected boolean displayLastArrow;

    /**
     * Display an arrow on first extremity
     * @deprecated
     */
    protected boolean displayFirstArrow;

   
    /**
     * First arrow transfrom used to draw the arrow polygon
     */
    protected AffineTransform firstArrowTransform;

    /**
     * Last arrow transfrom used to draw the arrow polygon
     */
    protected AffineTransform lastArrowTransform;


    /**
     * The gate attached to the first bound
     */
    protected Gate fisrtGate = null;

    /**
     * The gate attached to the last bound
     */
    protected Gate lastGate = null;


    /**
     * The connection path.
     * Manage the connection nodes
     */
    protected Path path;
   
   
    /**
     * Constructs a new Link instance
     */
    public ConnectionShape(int x, int y, int w, int h) {
        this(x, y, w, h, null, null);
    }

    /**
     * Constructs a new Link instance
     */
    public ConnectionShape(int x, int y, int w, int h, Gate fisrtGate, Gate lastGate) {
        super(x, y, w, h);
       
        //Gates
        this.fisrtGate = fisrtGate;
        this.lastGate = lastGate;

        // Path
        setPath( new RightAnglePath(new Point(x, y), new Point(x+w, y+h)) );

        // Arrows
        firstArrowTransform = null;
        lastArrowTransform = null;
    }
   
    /**
     * For background compatibility.
     * Create a connection with a Straight Path from a list of nodes
     * Constructs a new Link instance
     */
    public ConnectionShape(double[] vx, double[] vy) {
        super(0, 0, 100, 100);

       //Gates
       this.fisrtGate = null;
       this.lastGate = null;

       // Path
       setPath( new StraightPath(vx, vy));

       // Arrows
       firstArrowTransform = null;
       lastArrowTransform = null;
    }


    /* (non-Javadoc)
     * @see simtools.shapes.AbstractShape#cloneShape()
     */
    protected AbstractShape cloneShape() {
        ConnectionShape cs = (ConnectionShape)super.cloneShape();

        // clone the path
        cs.path = path.clonePath();

        // clone arrows
        if(firstArrowTransform!=null){
            cs.firstArrowTransform=(AffineTransform)firstArrowTransform.clone();
        }
        if(lastArrowTransform!=null){
            cs.lastArrowTransform=(AffineTransform)lastArrowTransform.clone();
        }

        // Cloned connection is not connected to the original connection gates
        cs.fisrtGate = null;
        cs.lastGate = null;

        return cs;
    }

    /* (non-Javadoc)
     * @see jsynoptic.builtin.Abstract2DShape#getPanel(java.util.List)
     */
    public JPropertiesPanel getPanel(List properties) {
        if (properties == null){
            return null;
        }

        if (properties.containsAll(Arrays.asList(new ConnectionShapePropertiesNames().getPropertyNames()))){
            return new ConnectionPropertiesPanel(Builtin.resources.getString("Connection"));

        } else {
            return super.getPanel(properties);
        }
    }


    /* (non-Javadoc)
     * @see jsynoptic.builtin.Abstract1DShape#getCollectiveActions(simtools.diagram.DiagramSelection, double, double, java.lang.Object, int)
     */
    public LinkedHashMap getCollectiveActions(DiagramSelection sel, double x, double y, Object o, int context) {
        LinkedHashMap res = super.getCollectiveActions(sel, x, y, o, context);
       
        res.put(resources.getString("RightAnglePath"), resources.getIcon("RightAnglePathIcon"));
        res.put(resources.getString("StraightPath"), resources.getIcon("StraightPathIcon"));
      
        return res;
    }

    /* (non-Javadoc)
     * @see jsynoptic.builtin.Abstract1DShape#doAction(double, double, java.lang.Object, java.lang.String, javax.swing.undo.CompoundEdit)
     */
    public boolean doAction(double x, double y, Object o, String action, CompoundEdit undoableEdit) {

        boolean res = false;
       
        if (action.equals(resources.getString("RightAnglePath"))) {
            if (path instanceof StraightPath){
                // Save old params
                Rectangle dirtyArea = getBounds();
                ConnectionPathEdit ce = new ConnectionPathEdit(this);
               
                setPath(new RightAnglePath(path.getNode(0), path.getNode(path.getNodeNumber()-1)))
                ce.pathHasChanged();
                dirtyArea.add(getBounds());
               
                dirtyArea.x -=10;
                dirtyArea.y -=10;
                dirtyArea.width +=20;
                dirtyArea.height +=20;
               
                notifyChange(dirtyArea);
                res = true;
               
                if (undoableEdit != null) {
                    undoableEdit.addEdit(ce);
                }
               
            }
           
         

        } else  if (action.equals(resources.getString("StraightPath"))) {
            if (path instanceof RightAnglePath){
                // Save old params
                Rectangle dirtyArea = getBounds();
               
                ConnectionPathEdit ce = new ConnectionPathEdit(this);
                setPath(new StraightPath(path.getNode(0), path.getNode(path.getNodeNumber()-1)));
                ce.pathHasChanged();
                dirtyArea.add(getBounds());
               
                dirtyArea.x -=10;
                dirtyArea.y -=10;
                dirtyArea.width +=20;
                dirtyArea.height +=20;
               
                notifyChange(dirtyArea);
                res = true;
               
                if (undoableEdit != null) {
                    undoableEdit.addEdit(ce);
                }
            }
          

        }  else {
            res = super.doAction(x, y, o, action, undoableEdit);
        }
        return res;
    }

    /* (non-Javadoc)
     * @see simtools.shapes.AbstractShape#getShapeName()
     */
    public String getShapeName(){
        return Builtin.resources.getString("Connection");
    }

    public Object getPropertyValue(String name) {
        Object res = super.getPropertyValue(name);
     
        if(name.equalsIgnoreCase("STROKE_COLOR")) {
            res = drawColor;
    
        } else if(name.equalsIgnoreCase("DISPLAY_FIRST_ARROW")) {
            res = new Boolean(firstArrowTransform!=null);
     
        } else if(name.equalsIgnoreCase("DISPLAY_LAST_ARROW")) {
            res = new Boolean(lastArrowTransform!=null);
     
        } else if(name.equalsIgnoreCase("CONNECTION_PATH")) {
            res = path;
        }
        return res;
    }

    public void setPropertyValue(String name, Object value) {

        if(name.equalsIgnoreCase("DISPLAY_FIRST_ARROW")) {
            if(value instanceof Boolean) {
                if(((Boolean)value).booleanValue()){
                    if(firstArrowTransform==null){
                        firstArrowTransform=new AffineTransform();
                        setBounds();
                    }
                }
                else{
                    firstArrowTransform = null;
                }
            }
        } else if(name.equalsIgnoreCase("DISPLAY_LAST_ARROW")) {
            if(value instanceof Boolean) {
                if(((Boolean)value).booleanValue()){
                    if(lastArrowTransform==null){
                        lastArrowTransform=new AffineTransform();
                        setBounds();
                    }
                }
                else{
                    lastArrowTransform=null;
                }
            }
        } else if(name.equalsIgnoreCase("CONNECTION_PATH")) {
            if(value instanceof Path) {
                setPath((Path) path);  
            }
        }
        super.setPropertyValue(name, value);
    }


    /* (non-Javadoc)
     * @see jsynoptic.builtin.Abstract1DShape#translate(int, int)
     */
    public void translate(int dx, int dy) {
        path.translatePath(dx, dy);
        setBounds();
    }

   
    protected void setBounds() {
       
       
        // TODO set bounds with the path...
      /*  bounds2D= path.getBounds();
        _ox= (int)bounds2D.getMinX();
        _oy= (int)bounds.getMinY();
        _w = (int)bounds.getWidth();
        _h = (int)bounds.getHeight();
       
        if(_w==0){
            _w=1;
        }
        if(_h==0){
            _h=1;
        }*/
        Point p = path.getNode(0);
        _ox=(int)p.x;
        _oy=(int)p.y;
        int n=path.getNodeNumber();
        for(int i=1;i<n;i++) {
            p = path.getNode(i);
            if (_ox>(int)p.x) {
                _ox=(int)p.x;
            }
            if (_oy>p.y) {
                _oy=(int)p.y;
            }
        }
        _w=0;
        _h=0;
        for(int i=0;i<n;i++) {
            p = path.getNode(i);
           
            if ((_w+_ox)<p.x) {
                _w=(int)p.x-_ox;
            }
            if ((_h+_oy)<p.y) {
                _h=(int)p.y-_oy;
            }
        }
        if(_w==0){
            _w=1;
        }
        if(_h==0){
            _h=1;
        }
        _y=_h;
      
        if (firstArrowTransform!=null && path.getNodeNumber()>1){
            Point p0 = path.getNode(0);
            Point p1 = path.getNode(1);
            double  theta = Math.atan2((p1.y - p0.y),(p1.x - p0.x));

            firstArrowTransform.setToTranslation(-p0.x, -p0.y);
            firstArrowTransform.rotate(theta);
        }
        if (lastArrowTransform!=null && path.getNodeNumber()>1){
            Point pn1 = path.getNode(0);
            Point pn2 = path.getNode(1);
            double  theta = Math.atan2((pn2.y - pn1.y),(pn2.x - pn1.x));

            lastArrowTransform.setToTranslation(-pn1.x, -pn1.y);
            lastArrowTransform.rotate(theta);
        }
       
        updateBounds();
    }

    /**
     * return the first segment number wich intersects with
     * the provided rectangle or -1 if none
     */
    public int intersects(int ox,int oy, int fx, int fy) {
        if ((fx<_ox)|| (fy<_oy)|| (ox>(_ox+_w))|| (oy>(_oy+_h))) {
            return -1;
        }
        return 0;
    }

    //
    // Shape Interface
    //
    public boolean contains(double ox, double oy) {
        return path.contains(ox, oy)
    }

    public boolean intersects(double x, double y, double w, double h) {
        int ox=(int)x;
        int oy=(int)y;
        int fx=(int)(x+w);
        int fy=(int)(y+h);
        return intersects(ox,oy,fx,fy)>0;
    }

    public void draw(Graphics2D g) {
        Color oldColor = g.getColor();
        Color oldBackground = g.getBackground();
        Stroke oldStroke = g.getStroke();

        Object antialiasHint = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                AbstractShape.ANTI_ALIASING
                ? RenderingHints.VALUE_ANTIALIAS_ON
                        : RenderingHints.VALUE_ANTIALIAS_OFF);

        AffineTransform oldTransform=null;
        if(transform!=null){
            oldTransform=g.getTransform();
            g.transform(transform.getTransform());
        }

      
       
        drawHook(g,false);
        //stroke   
        g.setStroke(stroke);

        Color c = getDrawColor();

        if (c!=null) {
            g.setColor(c);
           
            // Draw lines
            path.drawPath(g);

            // draw arrows
            if (firstArrowTransform!=null){
                Shape s = firstArrowTransform.createTransformedShape(arrow);
                g.fill(s);
                g.draw(s);
            }

            if (lastArrowTransform!=null){
                Shape s = lastArrowTransform.createTransformedShape(arrow);
                g.fill(s);
                g.draw(s);
           
        }

        drawHook(g,true);

        if(oldTransform!=null){
            g.setTransform(oldTransform);
        }

        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antialiasHint);
        g.setBackground(oldBackground);
        g.setColor(oldColor);
        g.setStroke(oldStroke);
    }

    /* (non-Javadoc)
     * @see simtools.diagram.LineInterface#pointsNumber()
     */
    public int getPointsNumber() { 
        // Node and Segment translator points
        return path.getNodeNumber() * 2 -1;  
    }


    /* (non-Javadoc)
     * @see simtools.diagram.SelectableShapePointsInterface#getPoint(int)
     */
    public Point getPoint(int index) {
        Point res;
        if (index % 2 == 0){
            res = path.getNode(index /2);

        } else{
            Point p1 = path.getNode(index/2);
            Point p2 = path.getNode(index/2 + 1);
            res = new Point( (p1.x + p2.x )/2, (p1.y + p2.y )/2 );
        }
        return res;
    }


    /* (non-Javadoc)
     * @see simtools.diagram.LineInterface#translatePoint(int, int, int)
     */
    public int translatePoint(int pointIndex, int dx, int dy) {

        if (pointIndex % 2 == 0){   // translate a node
            pointIndex = path.translateNode(pointIndex / 2, dx, dy) * 2 ;   
           
        } else {    // translate a segment
            pointIndex =  path.translateSegment( (pointIndex / 2) , (dx!=0)? dx : dy) * 2 + 1;
        }
        setBounds();

        return pointIndex;
    }

    /* (non-Javadoc)
     * @see jsynoptic.builtin.Abstract1DShape#getDelegateShape()
     */
    protected Shape getDelegateShape() {
        return this;
    }

    //
    // Serialization
    //
    private void readObject(ObjectInputStream s) throws IOException,
    ClassNotFoundException {
        // read persitent fields
        s.defaultReadObject();

        // backward compatiblity
        if(displayFirstArrow){
            firstArrowTransform=new AffineTransform();
        }
        if(displayLastArrow){
            lastArrowTransform=new AffineTransform();
        }
        if (path == null){
           setPath(new StraightPath(_xv, _yv));
        }
        _xv = null;
        _yv = null;

        // update bounds
        setBounds();
    }


    public String[] getPropertyNames(){
        if (_propertyNames==null)
            _propertyNames = new ConnectionShapePropertiesNames().getPropertyNames();
        return _propertyNames;
    }


    public static class ConnectionShapePropertiesNames extends Abstract1DShapePropertiesNames{

        private static transient String[] props = new String[] { "DISPLAY_FIRST_ARROW", "DISPLAY_LAST_ARROW", "CONNECTION_PATH" };

        public ConnectionShapePropertiesNames(){
            super();
            for (int i=0;i<props.length;i++){
                propertyNames.add(props[i]);
            }
        }
    }


    /* Connect a connector bound to a gate.
     * @param gate - The gate to be attached
     * @param onfirstBound - If true attach the first bound, otherwise attach the last bound.
     */
    public void connect(Gate gate, boolean onfirstBound) {

        // Proceed to the connection only if the target gate allows the connection with the other gate
        if (gate != null && gate.allowConnection(onfirstBound? lastGate : fisrtGate)){
            gate.connectTo(this);

            if (onfirstBound){
                fisrtGate = gate;
                path.lockFirstNode(true);
               
            }else {
                lastGate = gate;
                path.lockLastNode(true);
            }
        }
    }

    /**
     * Disconnect the bound from its attached gate
     * @param firstBound
     */
    public void disconnect(Gate gate){
        if (isConnected(gate)){
            gate.disconnectFrom(this);

            if (gate.equals(fisrtGate)){
                fisrtGate = null;
                path.lockFirstNode(false);
               
            } else {
                lastGate = null;
                path.lockLastNode(false);
            }
           
        }
    }
    public Gate getLastEndGate() {
        return lastGate;
    }

    public Gate getFirstEndGate() {
        return fisrtGate;
    }


    /* (non-Javadoc)
     * @see simtools.diagram.gate.Connection#isConnected(boolean)
     */
    public boolean isConnected(Gate gate) {
        return (gate!= null && ( gate==fisrtGate || gate==lastGate));
    }

    /* (non-Javadoc)
     * @see simtools.diagram.gate.Connection#getPath()
     */
    public Path getPath() {
        return path;
    }
   
    public void setPath(Path path){
      this.path = path;
      this.path.lockFirstNode(fisrtGate != null);
      this.path.lockLastNode(lastGate != null);
     
      setBounds();
    }

    /* (non-Javadoc)
     * @see simtools.diagram.SelectableShapePointsInterface#createSelection()
     */
    public ElementSelection createSelection(Point shapeOrigin, DiagramSelection ds) {
        return new ConnectionPathSelection(this,shapeOrigin);
    }

    /* (non-Javadoc)
     * @see simtools.diagram.gate.Connection#updateConnectionEnds()
     */
    public void gatePositionHasChanged(Gate gate) {
        boolean isDirty = false;

        if (gate == fisrtGate){
            Point fn = path.getNode(0);
            path.translateNode(0,fisrtGate.getAnchor().x - fn.x, fisrtGate.getAnchor().y -  fn.y);
            isDirty = true;

        } else if(gate == lastGate){
            Point ln = path.getNode(path.getNodeNumber()-1);
            path.translateNode(path.getNodeNumber()-1,lastGate.getAnchor().x - ln.x, lastGate.getAnchor().y - ln.y);
            isDirty = true;
        }

        if (isDirty){
            setBounds();
        }
    }
   
    public String toString(){
        return path.toString();
    }
}
TOP

Related Classes of jsynoptic.builtin.ConnectionShape$ConnectionShapePropertiesNames

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.