X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scenegraph%2Fsrc%2Forg%2Fsimantics%2Fscenegraph%2Fg2d%2Fnodes%2FEdgeNode.java;fp=bundles%2Forg.simantics.scenegraph%2Fsrc%2Forg%2Fsimantics%2Fscenegraph%2Fg2d%2Fnodes%2FEdgeNode.java;h=fe6c2d7016b526f9db4afdfbac5b17baa0774e0a;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/EdgeNode.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/EdgeNode.java new file mode 100644 index 000000000..fe6c2d701 --- /dev/null +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/EdgeNode.java @@ -0,0 +1,215 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.scenegraph.g2d.nodes; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.utils.InitValueSupport; + +public class EdgeNode extends G2DNode implements InitValueSupport { + + private static final long serialVersionUID = 1294351381209071074L; + + public static enum ArrowType { None, Stroke, Fill, Both } + + protected Color color = null; + protected Stroke stroke = null; + protected Shape shape = null; + protected Point2D firstdir = null; + protected Point2D lastdir = null; + protected Point2D first = null; + protected Point2D last = null; + protected double firstsize = 0; + protected double lastsize = 0; + protected ArrowType first_at = null; + protected ArrowType last_at = null; + protected Shape firstShape = null; + protected Shape lastShape = null; + + private transient Rectangle2D bounds; + + @SyncField({"color", "stroke", "shape", "firstdir", "lastdir", "first", "last", "firstsize", "lastsize", "first_at", "last_at"}) + public void init(Shape shape, Stroke stroke, Color color, Point2D firstdir, Point2D lastdir, Point2D first, Point2D last, double firstsize, double lastsize, ArrowType first_at, ArrowType last_at, Shape firstShape, Shape lastShape) { + this.color = color; + this.stroke = stroke; + this.shape = shape; + this.firstdir = firstdir; + this.lastdir = lastdir; + this.first = first; + this.last = last; + this.firstsize = firstsize; + this.lastsize = lastsize; + this.first_at = first_at; + this.last_at = last_at; + this.firstShape = firstShape; + this.lastShape = lastShape; + + if (shape != null) { + this.bounds = shape.getBounds2D(); + } + } + + @Override + public void render(Graphics2D g) { + if(color != null) g.setColor(color); + if(stroke == null || shape == null) return; + + if(alphaComposite != null) { + g.setComposite(alphaComposite); + } + + Stroke effectiveStroke = stroke; + if(dynamicStroke != null) { + effectiveStroke = dynamicStroke; + } + + Color effectiveColor = color; + if(dynamicColor != null) { + effectiveColor = dynamicColor; + } + + g.setStroke(effectiveStroke); + + // NICENESS + //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + //g.draw(shape); + + // Draw line "halo" +// float f = ((BasicStroke)effectiveStroke).getLineWidth() * 3f; +// Color background = Color.WHITE; // FIXME +// g.setColor(background); +// g.setStroke(new BasicStroke(f)); +// g.draw(shape); + + // Draw line + g.setColor(effectiveColor); + g.setStroke(effectiveStroke); + g.draw(shape); + + // Draw line ends if necessary. + boolean drawArrows = first_at != ArrowType.None || last_at != ArrowType.None; + if (!drawArrows) + return; + + AffineTransform at = g.getTransform(); + + g.setStroke(ARROW_STROKE); + + if (first_at != ArrowType.None) { + double theta = Math.atan2(firstdir.getY(), firstdir.getX()) - Math.PI/2; + g.translate(first.getX(), first.getY()); + g.rotate(theta); + g.scale(firstsize, firstsize); + + if (first_at == ArrowType.Fill) + g.fill(FILLED_ARROW); + else if (first_at == ArrowType.Stroke) + g.draw(NORMAL_ARROW); + + g.setTransform(at); + } + + if (last_at != ArrowType.None) { + double theta = Math.atan2(lastdir.getY(), lastdir.getX()) - Math.PI/2; + g.translate(last.getX(), last.getY()); + g.rotate(theta); + g.scale(lastsize, lastsize); + + if (last_at == ArrowType.Fill) + g.fill(FILLED_ARROW); + else if (last_at == ArrowType.Stroke) + g.draw(NORMAL_ARROW); + + g.setTransform(at); + } + } + + + public transient final static GeneralPath NORMAL_ARROW; + public transient final static GeneralPath FILLED_ARROW; + public transient static final Stroke ARROW_STROKE = new BasicStroke(1.0f); + + static { + FILLED_ARROW = new GeneralPath(); + FILLED_ARROW.moveTo(-0.5f, 1f); + FILLED_ARROW.lineTo( 0f, 0f); + FILLED_ARROW.lineTo( 0.5f, 1f); + FILLED_ARROW.closePath(); + + NORMAL_ARROW = new GeneralPath(); + NORMAL_ARROW.moveTo(-0.5f, 1f); + NORMAL_ARROW.lineTo( 0f, 0f); + NORMAL_ARROW.lineTo( 0.5f, 1f); + } + + @Override + public Rectangle2D getBoundsInLocal() { + return bounds; + } + + protected Composite alphaComposite = null; + protected Stroke dynamicStroke = null; + protected Color dynamicColor = null; + + @PropertySetter("alpha") + @SyncField("alphaComposite") + public void setAlphaComposite(Composite alphaComposite) { + this.alphaComposite = alphaComposite; + } + + @PropertySetter("width") + @SyncField("dynamicStroke") + public void setDynamicStroke(Stroke stroke) { + this.dynamicStroke = stroke; + } + + @PropertySetter("color") + @SyncField("dynamicColor") + public void setDynamicColor(Color color) { + this.dynamicColor = color; + } + +// public void setValue(String key, Object value) { +// +// if ("alpha".equals(key)) { +// Float val = Float.parseFloat((String)value); +// alphaComposite = AlphaComposite.getInstance(AlphaComposite. SRC_OVER, val); +// } else if ("width".equals(key)) { +// dynamicStroke = new BasicStroke(Float.parseFloat((String)value)); +// } else if ("color".equals(key)) { +// try { +// dynamicColor = new Color(Integer.parseInt(value.toString(), 16)); +// } catch (Throwable t) { +// t.printStackTrace(); +// } +// } +// } + + @Override + public void initValues() { + dynamicStroke = null; + dynamicColor = null; + alphaComposite = null; + } + +}