/* ****************************************************************************** * 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.internal.decorations; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Rectangle; import org.xmind.gef.draw2d.geometry.PrecisionPoint; import org.xmind.gef.draw2d.graphics.Path; import org.xmind.ui.decorations.AbstractTopicDecoration; public class DiamondTopicDecoration extends AbstractTopicDecoration { public DiamondTopicDecoration() { } public DiamondTopicDecoration(String id) { super(id); } protected void sketch(IFigure figure, Path shape, Rectangle box, int purpose) { float cx = box.x + box.width * 0.5f; float cy = box.y + box.height * 0.5f; shape.moveTo(cx, box.y); shape.lineTo(box.x, cy); shape.lineTo(cx, box.bottom()); shape.lineTo(box.right(), cy); shape.close(); } public PrecisionPoint getAnchorLocation(IFigure figure, double refX, double refY, double expansion) { Rectangle r = getOutlineBox(figure); double w = r.width * 0.5; double h = r.height * 0.5; double cx = r.x + w; double cy = r.y + h; double px = refX - cx; double py = refY - cy; if (px == 0) return new PrecisionPoint(refX, (py > 0) ? cy + h + expansion : cy - h - expansion); if (py == 0) return new PrecisionPoint( (px > 0) ? cx + w + expansion : cx - w - expansion, refY); double x = 0; double y = 0; Insets ins = figure.getInsets(); if (Math.abs(h * px) == Math.abs(w * py)) { x = (px * (w - ins.left)) / Math.abs(px); y = (py * (h - ins.bottom)) / Math.abs(py); } else if (px > 0 && py < 0) { x = (h * w * px) / (h * px - w * py); y = (h * w * py) / (h * px - w * py); } else if (px > 0 && py > 0) { x = (h * w * px) / (h * px + w * py); y = (h * w * py) / (h * px + w * py); } else if (px < 0 && py > 0) { x = (h * w * px) / (w * py - h * px); y = (h * w * py) / (w * py - h * px); } else if (px < 0 && py < 0) { x = -(h * w * px) / (h * px + w * py); y = -(h * w * py) / (h * px + w * py); } double scale = 0.5 / Math.max(Math.abs(px) / r.width, Math.abs(py) / r.height); px *= scale; py *= scale; double d = Math.hypot(px, py); if (d != 0) { double s = expansion / d; px = px * s; py = py * s; } return new PrecisionPoint(x + cx + px, y + cy + py); } public Insets getPreferredInsets(IFigure figure, int width, int height) { double w = width * 0.5; double h = height * 0.5; double d = Math.sqrt(h * w); int m = (int) Math.round(d) + 1; return new Insets(m + getLineWidth()); } }