// Copyright (c) 2006 - 2008, Markus Strauch. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF // THE POSSIBILITY OF SUCH DAMAGE. package net.sf.sdedit.drawable; import java.awt.Color; import java.awt.Graphics2D; import net.sf.sdedit.Constants; import net.sf.sdedit.config.Configuration; import net.sf.sdedit.diagram.Diagram; import net.sf.sdedit.diagram.Lifeline; import net.sf.sdedit.util.Direction; public abstract class SequenceElement extends Drawable implements Constants { private String[] label; private ExtensibleDrawable leftEndpoint; private ExtensibleDrawable leftLimit; private ExtensibleDrawable rightEndpoint; private ExtensibleDrawable rightLimit; protected final Diagram diagram; private Direction align; private int rightPadding; private int leftPadding; protected final Configuration configuration; protected SequenceElement(Diagram diagram, Lifeline boundary0, Lifeline boundary1, String[] label, Direction align, int y) { setTop(y); this.align = align; this.diagram = diagram; configuration = configuration(); this.label = label; findEndpoints(boundary0, boundary1); computePadding(); } protected final Diagram diagram() { return diagram; } protected final int rightPadding() { return rightPadding; } protected final int leftPadding() { return leftPadding; } protected final Configuration configuration() { return diagram.getConfiguration(); } /** * Returns {@linkplain Direction#RIGHT}, if the sequence element is * arranged to the right of its anchor, otherwise * {@linkplain Direction#LEFT}. For arrows the anchor is the caller * lifeline, for notes it is the lifeline to which the note is attached. * * @return {@linkplain Direction#RIGHT}, if the sequence element is * arranged to the right of its anchor, otherwise * {@linkplain Direction#LEFT} */ public final Direction getAlign() { return align; } private void computePadding() { int main = diagram.mainLifelineWidth; int sub = diagram.subLifelineWidth; Lifeline left = leftEndpoint.getLifeline(); if (left != null) { Lifeline rightMost = left.getRightmost(); if (left == rightMost) { leftPadding = 0; } else if (rightMost.getDirection() == Direction.CENTER) { leftPadding = main + (left.getSideLevel() - 1) * sub; } else if (left.getDirection() == Direction.LEFT) { leftPadding = main + (left.getSideLevel() - 1) * sub + rightMost.getSideLevel() * sub; } else { leftPadding = (rightMost.getSideLevel() - left.getSideLevel()) * sub; } } else { leftPadding = 0; } Lifeline right = rightEndpoint.getLifeline(); if (right != null) { Lifeline leftMost = right.getLeftmost(); if (right == leftMost) { rightPadding = 0; } else if (leftMost.getDirection() == Direction.CENTER) { rightPadding = main + (right.getSideLevel() - 1) * sub; } else if (right.getDirection() == Direction.RIGHT) { rightPadding = main + (right.getSideLevel() - 1) * sub + leftMost.getSideLevel() * sub; } else { rightPadding = (leftMost.getSideLevel() - right.getSideLevel()) * sub; } } else { rightPadding = 0; } } public int getSpace() { return 0; } public ExtensibleDrawable getLeftEndpoint() { return leftEndpoint; } public ExtensibleDrawable getRightEndpoint() { return rightEndpoint; } protected void setLeftEndpoint(ExtensibleDrawable leftEndpoint) { this.leftEndpoint = leftEndpoint; } protected void setRightEndpoint(ExtensibleDrawable rightEndpoint) { this.rightEndpoint = rightEndpoint; } protected int textWidth() { int width = 0; for (int i = 0; i < label.length; i++) { width = Math.max(width, diagram().getPaintDevice().getTextWidth( label[i])); } return width; } protected int textHeight() { return diagram().getPaintDevice().getTextHeight() * label.length; } private void findEndpoints(final Lifeline boundary0, final Lifeline boundary1) { if (boundary1 == null) { if (boundary0.getDirection() == Direction.LEFT) { leftEndpoint = boundary0.getLeftNeighbour().getView(); rightEndpoint = boundary0.getView(); } else { leftEndpoint = boundary0.getView(); if (boundary0.getPosition() < diagram.getNumberOfLifelines() - 1) { rightEndpoint = boundary0.getRightNeighbour().getView(); } else { rightEndpoint = diagram.getPaintDevice().getRightBound(); } } } else { if (boundary0.getPosition() < boundary1.getPosition()) { leftEndpoint = boundary0.getView(); rightEndpoint = boundary1.getView(); } else { leftEndpoint = boundary1.getView(); rightEndpoint = boundary0.getView(); } } } protected void drawMultilineString(Graphics2D g, int x, int y, boolean bottomOrTop, Color background) { drawMultilineString(g, label, x, y, diagram().getPaintDevice() .getTextHeight(), textWidth(), bottomOrTop, background); } public final ExtensibleDrawable getLeftLimit() { return leftLimit; } public final void setLeftLimit(ExtensibleDrawable leftLimit) { this.leftLimit = leftLimit; } public final ExtensibleDrawable getRightLimit() { return rightLimit; } public final void setRightLimit(ExtensibleDrawable rightLimit) { this.rightLimit = rightLimit; } }