view java/src/uk/ac/qmul/eecs/ccmi/simpletemplate/EdgeDrawSupport.java @ 0:78b7fc5391a2

first import, outcome of NIME 2014 hackaton
author Fiore Martin <f.martin@qmul.ac.uk>
date Tue, 08 Jul 2014 16:28:59 +0100
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.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JLabel;

import uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramTreeNode;
import uk.ac.qmul.eecs.ccmi.gui.GraphPanel;


/**
 * Provides static methods to draw a {@code SimpleShapeEdge} on a {@code Graphics}  
 *
 */
public abstract class EdgeDrawSupport {
	/**
	 *  Draws a string in proximity of a edge.
	 *  @param g2 the graphics context
	 *  @param p an endpoint of the segment along which to
	 *  draw the string
	 *  @param q the other endpoint of the segment along which to
	 *  draw the string
	 *  @param arrow the arrow head painted on the edge end where the string 
	 *   is to be painted  
	 *  @param s the string to draw
	 *  @param center true if the string should be centered
	 *  along the segment 
	 */

	public static void drawString(Graphics2D g2, 
			Point2D p, Point2D q, ArrowHead arrow, String s, boolean center){
		if (s == null || s.length() == 0) return;
		label.setText("<html>" + s + "</html>");
		label.setFont(g2.getFont());
		Dimension d = label.getPreferredSize();      
		label.setBounds(0, 0, d.width, d.height);

		Rectangle2D b = getStringBounds(g2, p, q, arrow, s, center);

		Color oldColor = g2.getColor();
		g2.setColor(g2.getBackground());
		g2.fill(b);
		g2.setColor(oldColor);

		g2.translate(b.getX(), b.getY());
		label.paint(g2);
		g2.translate(-b.getX(), -b.getY());        
	}

	/**
	 * Draws a graphical marker when the edge has notes associated to it 
	 * @see uk.ac.qmul.eecs.ccmi.diagrammodel.TreeModel#setNotes(DiagramTreeNode, String, Object)  
	 * 
	 * @param g2 the graphics context
	 * @param p an endpoint of the segment along which to draw the string
	 *  @param q the other endpoint of the segment along which to draw the string
	 */
	public static void drawMarker(Graphics2D g2, Point2D p, Point2D q){
		Point2D attach = q;
		if (p.getX() > q.getX()){ 
			drawMarker(g2, q, p);
			return;
		}
		attach = new Point2D.Double((p.getX() + q.getX()) / 2,
				(p.getY() + q.getY()) / 2);
		Color oldColor = g2.getColor();
		g2.setColor(GraphPanel.GRABBER_COLOR);
		g2.fill(new Rectangle2D.Double(attach.getX() - MARKER_SIZE / 2, attach.getY() - MARKER_SIZE / 2, MARKER_SIZE, MARKER_SIZE));
		g2.setColor(oldColor);
	}

	/*
	   Computes the attachment point for drawing a string.
	   return the point at which to draw the string
	 */
	private static Point2D getAttachmentPoint(Graphics2D g2, 
			Point2D p, Point2D q, ArrowHead arrow, Dimension d, boolean center){    
		final int GAP = 3;
		double xoff = GAP;
		double yoff = -GAP - d.getHeight();
		Point2D attach = q;
		if (center){
			if (p.getX() > q.getX()){ 
				return getAttachmentPoint(g2, q, p, arrow, d, center); 
			}
			attach = new Point2D.Double((p.getX() + q.getX()) / 2, 
					(p.getY() + q.getY()) / 2);
			if (p.getY() < q.getY())
				yoff =  - GAP - d.getHeight();
			else if (p.getY() == q.getY())
				xoff = -d.getWidth() / 2;
			else
				yoff = GAP;
		}
		else 
		{
			if (p.getX() < q.getX()){
				xoff = -GAP - d.getWidth();
			}
			if (p.getY() > q.getY()){
				yoff = GAP;
			}
			if (arrow != null){
				Rectangle2D arrowBounds = arrow.getPath(p, q).getBounds2D();
				if (p.getX() < q.getX()){
					xoff -= arrowBounds.getWidth();
				}
				else{
					xoff += arrowBounds.getWidth();
				}
			}
		}
		return new Point2D.Double(attach.getX() + xoff, attach.getY() + yoff);
	}

	/*
	 * Computes the extent of a string that is drawn along a line segment.
	 * The rectangle enclosing the string
	 */
	private static Rectangle2D getStringBounds(Graphics2D g2, 
			Point2D p, Point2D q, ArrowHead arrow, String s, boolean center){
		if (g2 == null) return new Rectangle2D.Double();
		if (s == null || s.equals("")) return new Rectangle2D.Double(q.getX(), q.getY(), 0, 0);
		label.setText("<html>" + s + "</html>");
		label.setFont(g2.getFont());
		Dimension d = label.getPreferredSize();
		Point2D a = getAttachmentPoint(g2, p, q, arrow, d, center);
		return new Rectangle2D.Double(a.getX(), a.getY(), d.getWidth(), d.getHeight());
	}

	/* size of the marker when an edge as notes */
	private static final int MARKER_SIZE = 7;
	private static JLabel label = new JLabel();
}