/******************************************************************************* * Copyright (c) 2006-2012 * Software Technology Group, Dresden University of Technology * DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026 * * 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: * Software Technology Group - TU Dresden, Germany; * DevBoost GmbH - Berlin, Germany * - initial API and implementation ******************************************************************************/ /* * @(#)SlantedLiner.java 1.1 2007-02-01 * * Copyright (c) 1996-2007 by the original authors of JHotDraw * and all its contributors. * All rights reserved. * * The copyright of this software is owned by the authors and * contributors of the JHotDraw project ("the copyright holders"). * You may not use, copy or modify this software, except in * accordance with the license agreement you entered into with * the copyright holders. For details see accompanying license terms. */ package org.jhotdraw.draw; import org.jhotdraw.xml.DOMInput; import org.jhotdraw.xml.DOMOutput; import org.jhotdraw.xml.DOMStorable; import java.util.*; import java.awt.*; import java.awt.geom.*; import org.jhotdraw.geom.*; /** * SlantedLiner. * * * @author Werner Randelshofer * @version 1.1 2007-02-01 Added support for connections that connect to * the same Figure on both ends. * <br>1.0 24. Januar 2006 Created. */ public class SlantedLiner implements Liner, DOMStorable { private double slantSize; /** Creates a new instance. */ public SlantedLiner() { this(20); } public SlantedLiner(double slantSize) { this.slantSize = slantSize; } public Collection<Handle> createHandles(BezierPath path) { return null; } public void lineout(ConnectionFigure figure) { BezierPath path = ((LineConnectionFigure) figure).getBezierPath(); Connector start = figure.getStartConnector(); Connector end = figure.getEndConnector(); if (start == null || end == null || path == null) { return; } // Special treatment if the connection connects the same figure if (figure.getStartFigure() == figure.getEndFigure()) { // Ensure path has exactly four nodes while (path.size() < 5) { path.add(1, new BezierPath.Node(0,0)); } while (path.size() > 5) { path.remove(1); } Point2D.Double sp = start.findStart(figure); Point2D.Double ep = end.findEnd(figure); Rectangle2D.Double sb = start.getBounds(); Rectangle2D.Double eb = end.getBounds(); int soutcode = sb.outcode(sp); if (soutcode == 0) { soutcode = Geom.outcode(sb, eb); } int eoutcode = eb.outcode(ep); if (eoutcode == 0) { eoutcode = Geom.outcode(sb, eb); } path.get(0).moveTo(sp); path.get(path.size() - 1).moveTo(ep); switch (soutcode) { case Geom.OUT_TOP : eoutcode = Geom.OUT_LEFT; break; case Geom.OUT_RIGHT : eoutcode = Geom.OUT_TOP; break; case Geom.OUT_BOTTOM : eoutcode = Geom.OUT_RIGHT; break; case Geom.OUT_LEFT : eoutcode = Geom.OUT_BOTTOM; break; default : eoutcode = Geom.OUT_TOP; soutcode = Geom.OUT_RIGHT; break; } path.get(1).moveTo(sp.x + slantSize, sp.y); if ((soutcode & Geom.OUT_RIGHT) != 0) { path.get(1).moveTo(sp.x + slantSize, sp.y); } else if ((soutcode & Geom.OUT_LEFT) != 0) { path.get(1).moveTo(sp.x - slantSize, sp.y); } else if ((soutcode & Geom.OUT_BOTTOM) != 0) { path.get(1).moveTo(sp.x, sp.y + slantSize); } else { path.get(1).moveTo(sp.x, sp.y - slantSize); } if ((eoutcode & Geom.OUT_RIGHT) != 0) { path.get(3).moveTo(ep.x + slantSize, ep.y); } else if ((eoutcode & Geom.OUT_LEFT) != 0) { path.get(3).moveTo(ep.x - slantSize, ep.y); } else if ((eoutcode & Geom.OUT_BOTTOM) != 0) { path.get(3).moveTo(ep.x, ep.y + slantSize); } else { path.get(3).moveTo(ep.x, ep.y - slantSize); } switch (soutcode) { case Geom.OUT_RIGHT : path.get(2).moveTo(path.get(1).x[0], path.get(3).y[0]); break; case Geom.OUT_TOP : path.get(2).moveTo(path.get(1).y[0], path.get(3).x[0]); break; case Geom.OUT_LEFT : path.get(2).moveTo(path.get(1).x[0], path.get(3).y[0]); break; case Geom.OUT_BOTTOM : default : path.get(2).moveTo(path.get(1).y[0], path.get(3).x[0]); break; } // Regular treatment if the connection connects to two different figures } else { // Ensure path has exactly four nodes while (path.size() < 4) { path.add(1, new BezierPath.Node(0,0)); } while (path.size() > 4) { path.remove(1); } Point2D.Double sp = start.findStart(figure); Point2D.Double ep = end.findEnd(figure); Rectangle2D.Double sb = start.getBounds(); Rectangle2D.Double eb = end.getBounds(); int soutcode = sb.outcode(sp); if (soutcode == 0) { if (sp.x <= sb.x) { soutcode = Geom.OUT_LEFT; } else if (sp.y <= sb.y) { soutcode = Geom.OUT_TOP; } else if (sp.x >= sb.x + sb.width) { soutcode = Geom.OUT_RIGHT; } else if (sp.y >= sb.y + sb.height) { soutcode = Geom.OUT_BOTTOM; } else { soutcode = Geom.outcode(sb, eb); } } int eoutcode = eb.outcode(ep); if (eoutcode == 0) { if (ep.x <= eb.x) { eoutcode = Geom.OUT_LEFT; } else if (ep.y <= eb.y) { eoutcode = Geom.OUT_TOP; } else if (ep.x >= eb.x + eb.width) { eoutcode = Geom.OUT_RIGHT; } else if (ep.y >= eb.y + eb.height) { eoutcode = Geom.OUT_BOTTOM; } else { eoutcode = Geom.outcode(sb, eb); } } path.get(0).moveTo(sp); path.get(path.size() - 1).moveTo(ep); if ((soutcode & Geom.OUT_RIGHT) != 0) { path.get(1).moveTo(sp.x + slantSize, sp.y); } else if ((soutcode & Geom.OUT_LEFT) != 0) { path.get(1).moveTo(sp.x - slantSize, sp.y); } else if ((soutcode & Geom.OUT_BOTTOM) != 0) { path.get(1).moveTo(sp.x, sp.y + slantSize); } else { path.get(1).moveTo(sp.x, sp.y - slantSize); } if ((eoutcode & Geom.OUT_RIGHT) != 0) { path.get(2).moveTo(ep.x + slantSize, ep.y); } else if ((eoutcode & Geom.OUT_LEFT) != 0) { path.get(2).moveTo(ep.x - slantSize, ep.y); } else if ((eoutcode & Geom.OUT_BOTTOM) != 0) { path.get(2).moveTo(ep.x, ep.y + slantSize); } else { path.get(2).moveTo(ep.x, ep.y - slantSize); } } // Ensure all path nodes are straight for (BezierPath.Node node : path) { node.setMask(BezierPath.C0_MASK); } path.invalidatePath(); } public void read(DOMInput in) { slantSize = in.getAttribute("slant", 20d); } public void write(DOMOutput out) { out.addAttribute("slant", slantSize); } public Liner clone() { try { return (Liner) super.clone(); } catch (CloneNotSupportedException ex) { InternalError error = new InternalError(ex.getMessage()); error.initCause(ex); throw error; } } }