/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.ui.decorations; import org.eclipse.draw2d.ColorConstants; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.PositionConstants; import org.xmind.gef.draw2d.IAnchor; import org.xmind.gef.draw2d.decoration.IShadowedDecoration; import org.xmind.gef.draw2d.decoration.PathConnectionDecoration; import org.xmind.gef.draw2d.geometry.PrecisionPoint; import org.xmind.ui.style.Styles; public abstract class AbstractSummaryDecoration extends PathConnectionDecoration implements ISummaryDecoration, IShadowedDecoration { private int direction = PositionConstants.EAST; private IAnchor conclusionAnchor = null; private PrecisionPoint conclusionPoint = null; protected AbstractSummaryDecoration() { super(); } protected AbstractSummaryDecoration(String id) { super(id); } public int getDirection() { return direction; } public void setDirection(IFigure figure, int direction) { if (direction == this.direction) return; this.direction = direction; if (figure != null) { figure.revalidate(); repaint(figure); } invalidate(); } protected boolean isHorizontal() { return (getDirection() & PositionConstants.EAST_WEST) != 0; } public IAnchor getNodeAnchor() { return conclusionAnchor; } public void setNodeAnchor(IFigure figure, IAnchor anchor) { if (anchor == this.conclusionAnchor) return; this.conclusionAnchor = anchor; if (figure != null) { figure.revalidate(); repaint(figure); } invalidate(); } public void invalidate() { super.invalidate(); conclusionPoint = null; } protected void reroute(IFigure figure, PrecisionPoint sourcePos, PrecisionPoint targetPos, boolean validating) { PrecisionPoint oldConclusionPoint = this.conclusionPoint; PrecisionPoint newConclusionPoint = new PrecisionPoint(); reroute(figure, sourcePos, targetPos, newConclusionPoint); this.conclusionPoint = newConclusionPoint; if (!validating && figure != null) { if (!newConclusionPoint.equals(oldConclusionPoint)) { figure.revalidate(); repaint(figure); } } } protected void reroute(IFigure figure, PrecisionPoint sourcePos, PrecisionPoint targetPos, PrecisionPoint conclusionPoint) { IAnchor sa = getSourceAnchor(); IAnchor ta = getTargetAnchor(); IAnchor ca = getNodeAnchor(); if (sa != null) { sourcePos.setLocation(sa.getLocation(getDirection(), getSpacing())); } if (ta != null) { targetPos.setLocation(ta.getLocation(getDirection(), getSpacing())); } if (ca != null) { conclusionPoint.setLocation(ca.getLocation( invertDirection(getDirection()), getSpacing())); } else { double cx = (sourcePos.x + targetPos.x) / 2; double cy = (sourcePos.y + targetPos.y) / 2; switch (getDirection()) { case PositionConstants.NORTH: conclusionPoint.setLocation(cx, cy - getWidth()); break; case PositionConstants.SOUTH: conclusionPoint.setLocation(cx, cy + getWidth()); break; case PositionConstants.EAST: conclusionPoint.setLocation(cx + getWidth(), cy); break; case PositionConstants.WEST: conclusionPoint.setLocation(cx - getWidth(), cy); break; } } } protected static int invertDirection(int dir) { switch (dir) { case PositionConstants.NORTH: return PositionConstants.SOUTH; case PositionConstants.SOUTH: return PositionConstants.NORTH; case PositionConstants.EAST: return PositionConstants.WEST; case PositionConstants.WEST: return PositionConstants.EAST; } return dir; } protected int getSpacing() { return Styles.DEFAULT_SUMMARY_SPACING; } protected int getWidth() { return Styles.DEFAULT_SUMMARY_WIDTH; } public int getPreferredWidth(IFigure figure) { checkValidation(figure); int s = getSpacing(); return getWidth() + s + s; } @Override protected int getLineWidthForChecking() { return super.getLineWidthForChecking() * 2 + 10; } public PrecisionPoint getConclusionPoint(IFigure figure) { checkValidation(figure); return conclusionPoint; } protected boolean isPositionValid() { return super.isPositionValid() && conclusionPoint != null; } public void paintShadow(IFigure figure, Graphics graphics) { if (!isVisible()) return; checkValidation(figure); graphics.setAlpha(getAlpha()); graphics.setForegroundColor(ColorConstants.black); graphics.setLineWidth(getLineWidth()); graphics.setLineStyle(getLineStyle()); drawLine(figure, graphics); } }