view java/src/uk/ac/qmul/eecs/ccmi/simpletemplate/RectangularNode.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) 2002 Cay S. Horstmann (http://horstmann.com)
 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.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;

/**
   A rectangular shaped diagram node.
*/
@SuppressWarnings("serial")
public class RectangularNode extends SimpleShapeNode{
	
	public RectangularNode(String nodeType, NodeProperties properties){
		super(nodeType, properties);
		bounds = dataDisplayBounds;
	}
	
	@Override
	public ShapeType getShapeType() {
		return ShapeType.Rectangle;
	}
	
	@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;
				}
		
		bounds.setFrame(bounds.getX() + dx,
			bounds.getY() + dy, 
			bounds.getWidth(), 
			bounds.getHeight());
		super.translateImplementation(p, dx, dy);
	}

	@Override
	protected void reshapeInnerProperties(List<String> insidePropertyTypes){
		super.reshapeInnerProperties(insidePropertyTypes);
		bounds.setFrame(dataDisplayBounds);
	}
	
	@Override
	public void decode(Document doc, Element nodeTag) throws IOException{
		super.decode(doc, nodeTag);
		bounds.setFrame(dataDisplayBounds);
	}
	
	@Override
	public Rectangle2D getBounds(){
		return (Rectangle2D)bounds.clone();
	}

	@Override
	public Point2D getConnectionPoint(Direction d){
		return calculateConnectionPoint(d, getBounds());
	}
	
	public static  Point2D calculateConnectionPoint(Direction d, Rectangle2D bounds){
		double slope = bounds.getHeight() / bounds.getWidth();
		double ex = d.getX();
		double ey = d.getY();
		double x = bounds.getCenterX();
		double y = bounds.getCenterY();
      
		if (ex != 0 && -slope <= ey / ex && ey / ex <= slope){  
			// intersects at left or right boundary
			if (ex > 0){
				x = bounds.getMaxX();
				y += (bounds.getWidth() / 2) * ey / ex;
			}else{
				x = bounds.getX();
				y -= (bounds.getWidth() / 2) * ey / ex;
			}
		}else if (ey != 0){  
			// intersects at top or bottom
			if (ey > 0){
				x += (bounds.getHeight() / 2) * ex / ey;
				y = bounds.getMaxY();
			}else{
				x -= (bounds.getHeight() / 2) * ex / ey;
				y = bounds.getY();
			}
		}
		return new Point2D.Double(x, y);
	}

	public Shape getShape(){
		return bounds;
	}
   
	@Override
	public InputStream getSound(){
		return sound;
	}
	
	public Object clone(){
		RectangularNode cloned = (RectangularNode)super.clone();
		cloned.bounds = (Rectangle2D.Double)bounds.clone();
		return cloned;
	}	
   
	private Rectangle2D.Double bounds;
	private static InputStream sound;
	
	static{
		sound = RectangularNode.class.getResourceAsStream("audio/Rectangle.mp3");
		SoundFactory.getInstance().loadSound(sound);
	}
}