view java/src/uk/ac/qmul/eecs/ccmi/simpletemplate/EllipticalNode.java @ 0:9418ab7b7f3f

Initial import
author Fiore Martin <fiore@eecs.qmul.ac.uk>
date Fri, 16 Dec 2011 17:35:51 +0000
parents
children
line wrap: on
line source
/*  
 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
  
 Copyright (C) 2011  Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/  

package uk.ac.qmul.eecs.ccmi.simpletemplate;

import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import uk.ac.qmul.eecs.ccmi.diagrammodel.NodeProperties;
import uk.ac.qmul.eecs.ccmi.gui.Direction;
import uk.ac.qmul.eecs.ccmi.sound.SoundFactory;

/**
 *
 * An elliptical shaped diagram node.
 *
 */
@SuppressWarnings("serial")
public class EllipticalNode extends SimpleShapeNode {

	public EllipticalNode(String typeName, NodeProperties properties){
		super(typeName, properties);
		Rectangle2D r = getMinBounds();
		eShape = new Ellipse2D.Double(0,0,r.getWidth(),r.getHeight());
	}
	
	@Override
	public ShapeType getShapeType() {
		return ShapeType.Ellipse;
	}
	
	public static Rectangle2D getOutBounds(Rectangle2D r){
		double h = r.getHeight()/2;
		double w = r.getWidth()/2;
		
		double anglew = Math.atan(h/w);
		double angleh = Math.atan(w/h);
		
		double a = w + h * Math.tan(angleh)/2;
		double b = h + w * Math.tan(anglew)/2;
		
		return  new Rectangle2D.Double(
				r.getCenterX() - a,
				r.getCenterY() - b,
				2*a,
				2*b
				);
	}
	
	@Override
	protected void reshapeInnerProperties(List<String> insidePropertyTypes){
		super.reshapeInnerProperties(insidePropertyTypes);
		eShape.setFrame(super.anyInsideProperties() ? getOutBounds(dataDisplayBounds) : dataDisplayBounds );
	}
	
	@Override
	public void decode(Document doc, Element nodeTag) throws IOException{
		super.decode(doc, nodeTag);
		eShape.setFrame(super.anyInsideProperties() ? getOutBounds(dataDisplayBounds) : dataDisplayBounds );
	}
	
	@Override
	protected void translateImplementation(Point2D p,double dx, double dy){
		/* if we clicked on a property node, just move that one */
		for(List<PropertyNode> pnList : propertyNodesMap.values())
			for(PropertyNode pn : pnList)
				if(pn.contains(p)){
					pn.translate(dx, dy);
					return;
				}
		eShape.setFrame(eShape.getX() + dx,
		         eShape.getY() + dy, 
		         eShape.getWidth(), 
		         eShape.getHeight());
		super.translateImplementation(p,dx, dy);
	}
	
	@Override
	public Rectangle2D getBounds() {
		return eShape.getBounds2D();
	}
	
	@Override
	public Point2D getConnectionPoint(Direction d) {
		return calculateConnectionPoint(d, getBounds());
	}
		
	public static  Point2D calculateConnectionPoint(Direction d, Rectangle2D bounds){
        double a = bounds.getWidth() / 2;
        double b = bounds.getHeight() / 2;
        double x = d.getX();
        double y = d.getY();
        double cx = bounds.getCenterX();
        double cy = bounds.getCenterY();

        if (a != 0 && b != 0 && !(x == 0 && y == 0)){
            double t = Math.sqrt((x * x) / (a * a) + (y * y) / (b * b));
            return new Point2D.Double(cx + x / t, cy + y / t);
        }
        else{
            return new Point2D.Double(cx, cy);
        }
	}

	@Override
	public Shape getShape() {
		return eShape;
	}
	
	@Override
	public InputStream getSound(){
		return sound;
	}

	@Override
	public Object clone(){
		EllipticalNode n = (EllipticalNode)super.clone();
		n.eShape = (Ellipse2D.Double)eShape.clone();
		return n;
	}
	
	private Ellipse2D.Double eShape;
	private static InputStream sound;
	static{
		sound = EllipticalNode.class.getResourceAsStream("audio/Ellipse.mp3");
		SoundFactory.getInstance().loadSound(sound);
	}
}