/* * CopyOfStsActorCompartmentLayout.java * * This file is part of the STS-Tool project. * Copyright (c) 2011-2012 "University of Trento - DISI" All rights reserved. * * Is strictly forbidden to remove this copyright notice from this source code. * * Disclaimer of Warranty: * STS-Tool (this software) is provided "as-is" and without warranty of any kind, * express, implied or otherwise, including without limitation, any warranty of * merchantability or fitness for a particular purpose. * In no event shall the copyright holder 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. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License version 3 * as published by the Free Software Foundation with the addition of the * following permission added to Section 15 as permitted in Section 7(a): * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY * "University of Trento - DISI","University of Trento - DISI" DISCLAIMS THE * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * See the GNU Affero General Public License for more details. * You should have received a copy of the GNU Affero General Public License * along with this program; if not, see http://www.gnu.org/licenses or write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA, 02110-1301 USA, or download the license from the following URL: * http://www.sts-tool.eu/License.php * * For more information, please contact STS-Tool group at this * address: ststool@disi.unitn.it * */ package eu.aniketos.wp1.ststool.diagram.custom.figure.nodes.layouts; import java.util.Iterator; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.XYLayout; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.draw2d.geometry.Rectangle; /** * Layout used to manage the compartment figure * */ public class CopyOfStsActorCompartmentLayout extends XYLayout { private IFigure nodeFigure = null; private IFigure compartmentFigure = null; private boolean collapsed; /** * @param figure * The node figure */ public void setNodeFigure(IFigure figure){ nodeFigure = figure; } /** * @param the * compartment Figure */ public void setCompartmentFigure(IFigure figure){ compartmentFigure = figure; } /** * @param collapsed * true - if the layout should collapse the compartment */ public void setCollapsed(boolean collapsed){ this.collapsed = collapsed; } /** * Manage the layout of the node and compartment other figure will be set to a size of 0,0 * * @see org.eclipse.draw2d.XYLayout#layout(IFigure) */ @Override public void layout(IFigure parent){ Iterator children = parent.getChildren().iterator(); IFigure f; while (children.hasNext()) { f = (IFigure) children.next(); Rectangle bounds = null; if (nodeFigure != null && nodeFigure == f) {//nodeFigure Point p = getOrigin(parent).getCopy(); if (!collapsed) { p = findUpperLeftPointForNode(compartmentFigure.getBounds().getCopy(), nodeFigure.getBounds().getCopy()); Point origin = compartmentFigure.getBounds().getTopLeft().getCopy(); if (p.x < origin.x) p.x = origin.x; if (p.y < origin.y) p.y = origin.y; } bounds = new Rectangle(p, f.getPreferredSize()); //bounds = new Rectangle(getOrigin(parent).getCopy(), new Dimension(10,10)); f.setBounds(bounds); } else if (compartmentFigure != null && compartmentFigure == f) { //Rectangle parentbounds=parent.getClientArea(); bounds = new Rectangle(getOrigin(parent), parent.getClientArea().getSize()); f.setBounds(bounds); } else { bounds = new Rectangle(0, 0, 0, 0); } f.setBounds(bounds); } } /** * Calculate the minimum size of the container checking if the container is collapsed * * @see org.eclipse.draw2d.XYLayout#getMinimumSize(IFigure, int, int) */ @Override public Dimension getMinimumSize(IFigure container,int wHint,int hHint){ if (nodeFigure != null && compartmentFigure != null) { if (collapsed) { return nodeFigure.getPreferredSize(); } else { Dimension d = Dimension.max(nodeFigure.getPreferredSize(), compartmentFigure.getPreferredSize()); d.width += 30; d.height += 30; return d; } } return new Dimension(0, 0); } /** * Calculate the preferred size of the container checking if the container is collapsed * * @see org.eclipse.draw2d.XYLayout#getPreferredSize(IFigure, int, int) */ @Override public Dimension getPreferredSize(IFigure container,int wHint,int hHint){ return getMinimumSize(container, wHint, hHint); } private static Point findUpperLeftPointForNode(Rectangle ellipse,Rectangle node){ Point nodeCenter = findCenterPointForNode(ellipse); return new Point(nodeCenter.x - node.width / 2, nodeCenter.y - node.height / 2); } private static Point findCenterPointForNode(Rectangle ellipse){ Dimension elipseRadius = new Dimension(ellipse.getSize().width / 2, ellipse.getSize().height / 2); PointList pl = ellipseIntersectLine(elipseRadius, ellipse.getCenter(), ellipse.getTopLeft(), ellipse.getCenter()); return pl.getLastPoint(); } private static PointList ellipseIntersectLine(Dimension ellipseRadius,Point ellipseCenter,Point lineP1,Point lineP2){ double orizontalRadius = ellipseRadius.preciseWidth(); double verticalRadius = ellipseRadius.preciseHeight(); double centerX = ellipseCenter.preciseX(); double centerY = ellipseCenter.preciseY(); double x1 = lineP1.x(); double y1 = lineP1.y(); double x2 = lineP2.x(); double y2 = lineP2.y(); double aa, bb, cc, m = 0; // if (x1 != x2) { m = (y2 - y1) / (x2 - x1); double c = y1 - m * x1; // aa = verticalRadius * verticalRadius + orizontalRadius * orizontalRadius * m * m; bb = 2 * orizontalRadius * orizontalRadius * c * m - 2 * orizontalRadius * orizontalRadius * centerY * m - 2 * centerX * verticalRadius * verticalRadius; cc = verticalRadius * verticalRadius * centerX * centerX + orizontalRadius * orizontalRadius * c * c - 2 * orizontalRadius * orizontalRadius * centerY * c + orizontalRadius * orizontalRadius * centerY * centerY - orizontalRadius * orizontalRadius * verticalRadius * verticalRadius; } else { // // vertical line case // aa = orizontalRadius * orizontalRadius; bb = -2.0F * centerY * orizontalRadius * orizontalRadius; cc = -orizontalRadius * orizontalRadius * verticalRadius * verticalRadius + verticalRadius * verticalRadius * (x1 - centerX) * (x1 - centerX); } double d = bb * bb - 4 * aa * cc; // // intersection points : (xi1,yi1) and (xi2,yi2) // double xi1, xi2, yi1, yi2; if (d >= 0.0) { if (x1 != x2) { xi1 = (-bb + Math.sqrt(d)) / (2 * aa); xi2 = (-bb - Math.sqrt(d)) / (2 * aa); yi1 = y1 + m * (xi1 - x1); yi2 = y1 + m * (xi2 - x1); } else { yi1 = (-bb + Math.sqrt(d)) / (2 * aa); yi2 = (-bb - Math.sqrt(d)) / (2 * aa); xi1 = x1; xi2 = x1; } } else { return new PointList(); // no intersections } return new PointList(new int[] { (int) xi1, (int) yi1, (int) xi2, (int) yi2 }); } /* * private Point ellipseIntersectLine(double orizontalRadius, double * verticalRadius, double centerX, double centerY,double x1 , double y1 , * double x2 , double y2){ * * double aa, bb, cc, m = 0; * double xi1, xi2, yi1, yi2; * * // * if (x1 != x2) { * m = (y2 - y1) / (x2 - x1); * double c = y1 - m * x1; * // * aa = verticalRadius * verticalRadius + orizontalRadius * orizontalRadius * * m * m; * bb = 2 * orizontalRadius * orizontalRadius * c * m - 2 * orizontalRadius * * orizontalRadius * centerY * m - 2 * centerX * verticalRadius * * verticalRadius; * cc = verticalRadius * verticalRadius * centerX * centerX + orizontalRadius * * orizontalRadius * c * c - 2 * orizontalRadius * orizontalRadius * * centerY * c + orizontalRadius * orizontalRadius * centerY * centerY - * orizontalRadius * orizontalRadius * verticalRadius * verticalRadius; * } else { * // * // vertical line case * // * aa = orizontalRadius * orizontalRadius; * bb = -2.0F * centerY * orizontalRadius * orizontalRadius; * cc = -orizontalRadius * orizontalRadius * verticalRadius * verticalRadius * + verticalRadius * verticalRadius * (x1 - centerX) * (x1 - centerX); * } * * double d = bb * bb - 4 * aa * cc; * // * // intersection points : (xi1,yi1) and (xi2,yi2) * // * if (d >= 0.0) { * if (x1 != x2) { * xi1 = (-bb + Math.sqrt(d)) / (2 * aa); * xi2 = (-bb - Math.sqrt(d)) / (2 * aa); * yi1 = y1 + m * (xi1 - x1); * yi2 = y1 + m * (xi2 - x1); * } else { * yi1 = (-bb + Math.sqrt(d)) / (2 * aa); * yi2 = (-bb - Math.sqrt(d)) / (2 * aa); * xi1 = x1; * xi2 = x1; * } * } else { * return null; // no intersections * } * return new Point((int)xi2,(int)yi2); * } */ }