blob: f926add0ec024c0e9d37042ab41066ea66170f40 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012, 2013, 2014 Red Hat, Inc.
* All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
*
* @author Bob Brodt
******************************************************************************/
package org.eclipse.bpmn2.modeler.core.utils;
import java.util.List;
import org.eclipse.bpmn2.BaseElement;
import org.eclipse.bpmn2.di.BPMNPlane;
import org.eclipse.bpmn2.di.BPMNShape;
import org.eclipse.bpmn2.modeler.core.adapters.ExtendedPropertiesProvider;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.datatypes.IDimension;
import org.eclipse.graphiti.datatypes.ILocation;
import org.eclipse.graphiti.mm.algorithms.AbstractText;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.algorithms.styles.Color;
import org.eclipse.graphiti.mm.algorithms.styles.Point;
import org.eclipse.graphiti.mm.pictograms.Anchor;
import org.eclipse.graphiti.mm.pictograms.AnchorContainer;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.services.IGaService;
import org.eclipse.graphiti.services.ILayoutService;
import org.eclipse.graphiti.services.IPeService;
/**
*
*/
public class GraphicsUtil {
static final IGaService gaService = Graphiti.getGaService();
static final IPeService peService = Graphiti.getPeService();
public interface IShapeFilter {
boolean matches(Shape shape);
}
/**
* Shape Filter that matches only Container Shapes and not Labels
*/
public class ContainerShapeFilter implements GraphicsUtil.IShapeFilter {
public boolean matches(Shape shape) {
return shape instanceof ContainerShape && !FeatureSupport.isLabelShape(shape);
}
}
/**
* Code copied from {@link java.awt.geom.Rectangle2D#intersectsLine(double, double, double, double)}
* in an attempt to avoid loading the java.awt package here...
*/
public static final class RectangleIntersectsLine {
private static final int OUT_LEFT = 1;
private static final int OUT_TOP = 2;
private static final int OUT_RIGHT = 4;
private static final int OUT_BOTTOM = 8;
private static int outcode(double pX, double pY, double rectX, double rectY, double rectWidth, double rectHeight) {
int out = 0;
if (rectWidth <= 0) {
out |= OUT_LEFT | OUT_RIGHT;
} else if (pX < rectX) {
out |= OUT_LEFT;
} else if (pX > rectX + rectWidth) {
out |= OUT_RIGHT;
}
if (rectHeight <= 0) {
out |= OUT_TOP | OUT_BOTTOM;
} else if (pY < rectY) {
out |= OUT_TOP;
} else if (pY > rectY + rectHeight) {
out |= OUT_BOTTOM;
}
return out;
}
public static boolean intersectsLine(double lineX1, double lineY1, double lineX2, double lineY2, double rectX, double rectY, double rectWidth, double rectHeight) {
int out1, out2;
if ((out2 = outcode(lineX2, lineY2, rectX, rectY, rectWidth, rectHeight)) == 0) {
return true;
}
while ((out1 = outcode(lineX1, lineY1, rectX, rectY, rectWidth, rectHeight)) != 0) {
if ((out1 & out2) != 0) {
return false;
}
if ((out1 & (OUT_LEFT | OUT_RIGHT)) != 0) {
double x = rectX;
if ((out1 & OUT_RIGHT) != 0) {
x += rectWidth;
}
lineY1 = lineY1 + (x - lineX1) * (lineY2 - lineY1) / (lineX2 - lineX1);
lineX1 = x;
} else {
double y = rectY;
if ((out1 & OUT_BOTTOM) != 0) {
y += rectHeight;
}
lineX1 = lineX1 + (y - lineY1) * (lineX2 - lineX1) / (lineY2 - lineY1);
lineY1 = y;
}
}
return true;
}
}
public static class LineSegment {
private Point start;
private Point end;
public LineSegment() {
this(0,0,0,0);
}
public LineSegment(Point start, Point end) {
this(start.getX(),start.getY(), end.getX(),end.getY());
}
public LineSegment(int x1, int y1, int x2, int y2) {
start = Graphiti.getCreateService().createPoint(x1, y1);
end = Graphiti.getCreateService().createPoint(x2, y2);
}
public void setStart(Point p) {
setStart(p.getX(),p.getY());
}
public void setStart(int x, int y) {
start.setX(x);
start.setY(y);
}
public void setEnd(Point p) {
setEnd(p.getX(),p.getY());
}
public void setEnd(int x, int y) {
end.setX(x);
end.setY(y);
}
public Point getStart() {
return start;
}
public Point getEnd() {
return end;
}
public Point getMiddle() {
int x = start.getX() + Math.abs(start.getX() - end.getX()) / 2;
int y = start.getY() + Math.abs(start.getY() - end.getY()) / 2;
return Graphiti.getCreateService().createPoint(x,y);
}
public double getDistance(Point p) {
// for vertical and horizontal line segments, the distance to a point
// is the orthogonal distance if the point lies between the start and end
// points of the line segment
if (isHorizontal()) {
if (p.getX()>=start.getX() && p.getX()<=end.getX())
return Math.abs(start.getY() - p.getY());
}
if (isVertical()) {
if (p.getY()>=start.getY() && p.getY()<=end.getY())
return Math.abs(start.getX() - p.getX());
}
// otherwise, the distance is the minimum of the distances
// of the point to the two endpoints of the line segment
double d1 = getDistanceToStart(p);
double d2 = getDistanceToEnd(p);
return Math.min(d1, d2);
}
public boolean isHorizontal() {
return Math.abs(start.getY() - end.getY()) <= 1;
}
public boolean isVertical() {
return Math.abs(start.getX() - end.getX()) <= 1;
}
public boolean isSlanted() {
return !isHorizontal() && !isVertical();
}
public double getDistanceToStart(Point p) {
return Math.hypot(start.getX()-p.getX(), start.getY()-p.getY());
}
public double getDistanceToEnd(Point p) {
return Math.hypot(end.getX()-p.getX(), end.getY()-p.getY());
}
public String toString() {
return "[" + start.getX() + "," + start.getY() +"]" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
" [" + end.getX() + "," + end.getY() +"]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
/**
* Set the location of the PE given absolute Diagram coordinates. If the PE
* is a child of a ContainerShape, adjust the coordinates so that they are
* relative to the ContainerShape.
*
* @param pe the PictogramElement to move
* @param x the absolute Diagram-relative X coordinate
* @param y the absolute Diagram-relative Y coordinate
*/
public static void setLocationRelativeToDiagram(PictogramElement pe, int x, int y) {
GraphicsAlgorithm ga = pe.getGraphicsAlgorithm();
Object o = pe.eContainer();
if (o instanceof ContainerShape && !(o instanceof Diagram)) {
ILocation containerLoc = peService.getLocationRelativeToDiagram((Shape)o);
x -= containerLoc.getX();
y -= containerLoc.getY();
}
gaService.setLocation(ga, x, y);
}
public static boolean contains(Shape parent, Shape child) {
IDimension size = GraphicsUtil.calculateSize(child);
ILocation loc = Graphiti.getLayoutService().getLocationRelativeToDiagram(child);
return GraphicsUtil.contains(parent, GraphicsUtil.createPoint(loc.getX(), loc.getY()))
&& GraphicsUtil.contains(parent, GraphicsUtil.createPoint(loc.getX() + size.getWidth(), loc.getY()))
&& GraphicsUtil.contains(parent, GraphicsUtil.createPoint(loc.getX() + size.getWidth(), loc.getY() + size.getHeight()))
&& GraphicsUtil.contains(parent, GraphicsUtil.createPoint(loc.getX(), loc.getY() + size.getHeight()));
}
public static boolean contains(Shape shape, Point point) {
IDimension size = GraphicsUtil.calculateSize(shape);
ILocation loc = Graphiti.getLayoutService().getLocationRelativeToDiagram(shape);
int x = point.getX();
int y = point.getY();
return x>loc.getX() && x<loc.getX() + size.getWidth() &&
y>loc.getY() && y<loc.getY() + size.getHeight();
}
public static boolean intersects(Shape shape1, Shape shape2) {
ILayoutService layoutService = Graphiti.getLayoutService();
ILocation loc2 = layoutService.getLocationRelativeToDiagram(shape2);
int x2 = loc2.getX();
int y2 = loc2.getY();
int w2 = ShapeDecoratorUtil.getShapeWidth(shape2);
int h2 = ShapeDecoratorUtil.getShapeHeight(shape2);
return GraphicsUtil.intersects(shape1, x2, y2, w2, h2);
}
public static boolean intersects(Shape shape1, Shape shape2, int space) {
ILayoutService layoutService = Graphiti.getLayoutService();
ILocation loc2 = layoutService.getLocationRelativeToDiagram(shape2);
int x2 = loc2.getX() - space;
int y2 = loc2.getY() - space;
int w2 = ShapeDecoratorUtil.getShapeWidth(shape2) + 2*space;
int h2 = ShapeDecoratorUtil.getShapeHeight(shape2) + 2*space;
return GraphicsUtil.intersects(shape1, x2, y2, w2, h2);
}
public static boolean intersects(Shape shape1, int x2, int y2, int w2, int h2) {
ILayoutService layoutService = Graphiti.getLayoutService();
ILocation loc1 = layoutService.getLocationRelativeToDiagram(shape1);
int x1 = loc1.getX();
int y1 = loc1.getY();
int w1 = ShapeDecoratorUtil.getShapeWidth(shape1);
int h1 = ShapeDecoratorUtil.getShapeHeight(shape1);
return GraphicsUtil.intersects(x1, y1, w1, h1, x2, y2, w2, h2);
}
public static boolean intersects(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
if(x2<=x1 || y1<=y2) {
int t1, t2, t3, t4;
t1 = x1; x1 = x2; x2 = t1;
t2 = y1; y1 = y2; y2 = t2;
t3 = w1; w1 = w2; w2 = t3;
t4 = h1; h1 = h2; h2 = t4;
}
if( y2 + h2 < y1 || y1 + h1 < y2 || x2 + w2 < x1 || x1 + w1 < x2 ) {
return false;
}
return true;
}
public static boolean intersects(Shape shape, Connection connection) {
Point p1 = GraphicsUtil.createPoint(connection.getStart());
Point p3 = GraphicsUtil.createPoint(connection.getEnd());
if (connection instanceof FreeFormConnection) {
FreeFormConnection ffc = (FreeFormConnection) connection;
Point p2 = p1;
for (Point p : ffc.getBendpoints()) {
if (GraphicsUtil.intersectsLine(shape, p1, p))
return true;
p2 = p1 = p;
}
if (GraphicsUtil.intersectsLine(shape, p2, p3))
return true;
}
else if (GraphicsUtil.intersectsLine(shape, p1, p3))
return true;
return false;
}
public static boolean intersectsLine(Shape shape, Point p1, Point p2) {
ILocation loc = peService.getLocationRelativeToDiagram(shape);
IDimension size = GraphicsUtil.calculateSize(shape);
// adjust the shape rectangle so that a point touching one of the edges
// is not considered to be "intersecting"
if (size.getWidth()>2) {
loc.setX(loc.getX()+1);
size.setWidth(size.getWidth()-2);
}
if (size.getHeight()>2) {
loc.setY(loc.getY()+1);
size.setHeight(size.getHeight()-2);
}
return GraphicsUtil.RectangleIntersectsLine.intersectsLine(
p1.getX(), p1.getY(), p2.getX(), p2.getY(),
loc.getX(), loc.getY(), size.getWidth(), size.getHeight());
// java.awt.Rectangle rect = new java.awt.Rectangle(loc.getX(), loc.getY(), size.getWidth(), size.getHeight());
// return rect.intersectsLine(start.getX(), start.getY(), end.getX(), end.getY());
}
public static boolean intersects(Point p1Start, Point p1End, Point p2Start, Point p2End) {
return GraphicsUtil.isLineIntersectingLine(
p1Start.getX(), p1Start.getY(),
p1End.getX(), p1End.getY(),
p2Start.getX(), p2Start.getY(),
p2End.getX(), p2End.getY()
);
}
/**
* Check if two line segments intersects. Integer domain.
*
* @param x0, y0, x1, y1 End points of first line to check.
* @param x2, yy, x3, y3 End points of second line to check.
* @return True if the two lines intersects.
*/
public static boolean isLineIntersectingLine(int x0, int y0, int x1,
int y1, int x2, int y2, int x3, int y3) {
int s1 = GraphicsUtil.sameSide(x0, y0, x1, y1, x2, y2, x3, y3);
int s2 = GraphicsUtil.sameSide(x2, y2, x3, y3, x0, y0, x1, y1);
return s1 <= 0 && s2 <= 0;
}
/**
* Check if two points are on the same side of a given line. Algorithm from
* Sedgewick page 350.
*
* @param x0, y0, x1, y1 The line.
* @param px0, py0 First point.
* @param px1, py1 Second point.
* @return <0 if points on opposite sides. =0 if one of the points is
* exactly on the line >0 if points on same side.
*/
static int sameSide(int x0, int y0, int x1, int y1,
int px0, int py0, int px1, int py1) {
int sameSide = 0;
int dx = x1 - x0;
int dy = y1 - y0;
int dx1 = px0 - x0;
int dy1 = py0 - y0;
int dx2 = px1 - x1;
int dy2 = py1 - y1;
// Cross product of the vector from the endpoint of the line to the
// point
int c1 = dx * dy1 - dy * dx1;
int c2 = dx * dy2 - dy * dx2;
if (c1 != 0 && c2 != 0)
sameSide = c1 < 0 != c2 < 0 ? -1 : 1;
else if (dx == 0 && dx1 == 0 && dx2 == 0)
sameSide = !GraphicsUtil.isBetween(y0, y1, py0) && !GraphicsUtil.isBetween(y0, y1, py1) ? 1
: 0;
else if (dy == 0 && dy1 == 0 && dy2 == 0)
sameSide = !GraphicsUtil.isBetween(x0, x1, px0) && !GraphicsUtil.isBetween(x0, x1, px1) ? 1
: 0;
return sameSide;
}
/**
* Return true if c is between a and b.
*/
static boolean isBetween(int a, int b, int c) {
return b > a ? c >= a && c <= b : c >= b && c <= a;
}
public static Color clone(Color c) {
return c;
}
public static boolean pointsEqual(Point p1, Point p2) {
return p1.getX()==p2.getX() && p1.getY()==p2.getY();
}
public static Point createPoint(Point p) {
return gaService.createPoint(p.getX(), p.getY());
}
public static Point createPoint(int x, int y) {
return gaService.createPoint(x, y);
}
public static Point createPoint(Anchor a) {
return GraphicsUtil.createPoint(peService.getLocationRelativeToDiagram(a));
}
public static Point createPoint(AnchorContainer ac) {
if (ac instanceof Shape)
return GraphicsUtil.createPoint(peService.getLocationRelativeToDiagram((Shape)ac));
if (ac instanceof Connection)
return createPoint(Graphiti.getPeService().getConnectionMidpoint((Connection)ac, 0.5));
return null;
}
public static Point getShapeCenter(AnchorContainer shape) {
Point p = createPoint(shape);
IDimension size = GraphicsUtil.calculateSize(shape);
p.setX( p.getX() + size.getWidth()/2 );
p.setY( p.getY() + size.getHeight()/2 );
return p;
}
public static Point createPoint(ILocation loc) {
return createPoint(loc.getX(), loc.getY());
}
public static Point getMidpoint(Point p1, Point p2) {
int dx = p2.getX() - p1.getX();
int dy = p2.getY() - p1.getY();
int x = p1.getX() + dx/2;
int y = p1.getY() + dy/2;
return createPoint(x,y);
}
public static double getLength(ILocation start, ILocation end) {
double a = (double)(start.getX() - end.getX());
double b = (double)(start.getY() - end.getY());
return Math.sqrt(a*a + b*b);
}
public static double getLength(List<Point> points) {
double length = 0;
int size = points.size();
if (size>=2) {
Point p1 = points.get(0);
for (int i=1; i<size-1; ++i) {
Point p2 = points.get(i);
length += GraphicsUtil.getLength(p1,p2);
p1 = p2;
}
}
return length;
}
public static double getLength(Point p1, Point p2) {
double a = (double)(p1.getX() - p2.getX());
double b = (double)(p1.getY() - p2.getY());
return Math.sqrt(a*a + b*b);
}
/**
* Check if the line segment defined by the two Points is vertical.
*
* @param p1
* @param p2
* @return true if the line segment is vertical
*/
public final static boolean isVertical(Point p1, Point p2) {
return Math.abs(p1.getX() - p2.getX()) == 0;
}
/**
* Check if the line segment defined by the two Points is horizontal.
*
* @param p1
* @param p2
* @return true if the line segment is horizontal
*/
public final static boolean isHorizontal(Point p1, Point p2) {
return Math.abs(p1.getY() - p2.getY()) == 0;
}
/**
* Check if the line segment defined by the two Points is neither horizontal nor vertical.
*
* @param p1
* @param p2
* @return true if the line segment is slanted
*/
public final static boolean isSlanted(Point p1, Point p2) {
return !isHorizontal(p1, p2) && !isVertical(p1,p2);
}
public static Point getVertMidpoint(Point start, Point end, double fract) {
Point m = createPoint(start);
int d = (int)(fract * (double)(end.getY() - start.getY()));
m.setY(start.getY()+d);
return m;
}
public static Point getHorzMidpoint(Point start, Point end, double fract) {
Point m = createPoint(start);
int d = (int)(fract * (double)(end.getX() - start.getX()));
m.setX(start.getX()+d);
return m;
}
public static IDimension calculateSize(PictogramElement shape) {
GraphicsAlgorithm ga = shape.getGraphicsAlgorithm();
if (ga!=null)
return gaService.calculateSize(ga);
IDimension dim = null;
if (shape instanceof ContainerShape) {
ContainerShape cs = (ContainerShape)shape;
for (Shape s : cs.getChildren()) {
ga = s.getGraphicsAlgorithm();
if (ga!=null) {
IDimension d = gaService.calculateSize(ga);
if (dim==null)
dim = d;
else {
if (d.getWidth() > dim.getWidth())
dim.setWidth(d.getWidth());
if (d.getHeight() > dim.getHeight())
dim.setHeight(d.getHeight());
}
}
}
}
return dim;
}
public static boolean debug = false;
public static void dump(String label, List<? extends Shape> shapes) {
if (shapes!=null) {
if (debug) {
System.out.println(label);
for (Shape shape : shapes)
GraphicsUtil.dump(1, "",shape,0,0); //$NON-NLS-1$
System.out.println(""); //$NON-NLS-1$
}
}
}
public static void dump(String label, Anchor anchor) {
if (debug) {
System.out.print(label+" "); //$NON-NLS-1$
ILocation loc = peService.getLocationRelativeToDiagram(anchor);
System.out.print(" at "+loc.getX()+", "+loc.getY()); //$NON-NLS-1$ //$NON-NLS-2$
GraphicsUtil.dump(" parent=", (ContainerShape)anchor.getParent()); //$NON-NLS-1$
}
}
public static void dump(String label, ContainerShape shape) {
ILocation loc = peService.getLocationRelativeToDiagram(shape);
GraphicsUtil.dump(0, label,shape,loc.getX(),loc.getY());
}
public static void dump(String label, Connection c) {
if (debug) {
BaseElement be = BusinessObjectUtil.getFirstBaseElement(c);
if (be==null)
System.out.print(label+" connection="); //$NON-NLS-1$
else
System.out.print(label+be.eClass().getName()+"=");
AnchorContainer source = (AnchorContainer) c.getStart().getParent();
AnchorContainer target = (AnchorContainer) c.getEnd().getParent();
String sourceName = GraphicsUtil.getDebugText(source);
String targetName = GraphicsUtil.getDebugText(target);
System.out.println(sourceName+" -> "+targetName); //$NON-NLS-1$
}
}
public static void dump(int level, String label, ContainerShape shape) {
ILocation loc = peService.getLocationRelativeToDiagram(shape);
GraphicsUtil.dump(level, label,shape,loc.getX(),loc.getY());
}
public static void dump(Shape shape) {
ILocation loc = peService.getLocationRelativeToDiagram(shape);
String label = "";
if (FeatureSupport.isLabelShape(shape) && shape.getGraphicsAlgorithm() instanceof AbstractText) {
AbstractText text = (AbstractText) shape.getGraphicsAlgorithm();
label = "Label: " + text.getValue();
}
GraphicsUtil.dump(0, label,shape,loc.getX(),loc.getY());
}
public static void dump(int level, String label, Shape shape, int x, int y) {
if (debug) {
String text = GraphicsUtil.getDebugText(shape);
for (int i=0; i<level; ++i)
System.out.print(" "); //$NON-NLS-1$
System.out.print(label+" "+text); //$NON-NLS-1$
if (x>0 || y>0) {
System.out.println(" at "+x+", "+y); //$NON-NLS-1$ //$NON-NLS-2$
}
else
System.out.println(""); //$NON-NLS-1$
}
}
public static String getDebugText(PictogramElement pe) {
EObject be = BusinessObjectUtil.getBusinessObjectForPictogramElement(pe);
String id = ""; //$NON-NLS-1$
String text = "";
if (be instanceof BaseElement) {
id = " " + ((BaseElement)be).getId(); //$NON-NLS-1$
}
if (be!=null)
text = be.eClass().getName()+id+": "+ExtendedPropertiesProvider.getTextValue(be); //$NON-NLS-1$
else
text = id + pe.toString();
return text;
}
public static void dump(String label) {
if (debug) {
System.out.println(label);
}
}
public static LineSegment[] getEdges(Shape shape) {
ILocation loc = peService.getLocationRelativeToDiagram(shape);
IDimension size = calculateSize(shape);
LineSegment top = new LineSegment(loc.getX(),loc.getY(),
loc.getX()+size.getWidth(), loc.getY());
LineSegment left = new LineSegment(loc.getX(),loc.getY(), loc.getX(),
loc.getY()+size.getHeight());
LineSegment bottom = new LineSegment(loc.getX(), loc.getY()+size.getHeight(),
loc.getX()+size.getWidth(), loc.getY()+size.getHeight());
LineSegment right = new LineSegment(loc.getX()+size.getWidth(), loc.getY(),
loc.getX()+size.getWidth(), loc.getY()+size.getHeight());
return new LineSegment[] {top, bottom, left, right};
}
public static LineSegment findNearestEdge(Shape shape, Point p) {
LineSegment edges[] = getEdges(shape);
LineSegment top = edges[0];
LineSegment bottom = edges[1];
LineSegment left = edges[2];
LineSegment right = edges[3];
double minDist;
double dist;
LineSegment result;
minDist = GraphicsUtil.getLength(p, top.getMiddle());
result = top;
dist = GraphicsUtil.getLength(p, bottom.getMiddle());
if (dist<minDist) {
minDist = dist;
result = bottom;
}
dist = GraphicsUtil.getLength(p, left.getMiddle());
if (dist<minDist) {
minDist = dist;
result = left;
}
dist = GraphicsUtil.getLength(p, right.getMiddle());
if (dist<minDist) {
minDist = dist;
result = right;
}
return result;
}
public static LineSegment findNearestOrthogonalEdge(Shape shape, Point p) {
LineSegment edges[] = getEdges(shape);
LineSegment top = edges[0];
LineSegment bottom = edges[1];
LineSegment left = edges[2];
LineSegment right = edges[3];
double minDist;
double dist;
LineSegment result;
minDist = top.getDistance(p);
result = top;
dist = bottom.getDistance(p);
if (dist<minDist) {
minDist = dist;
result = bottom;
}
dist = left.getDistance(p);
if (dist<minDist) {
minDist = dist;
result = left;
}
dist = right.getDistance(p);
if (dist<minDist) {
minDist = dist;
result = right;
}
return result;
}
public static LineSegment findNearestEdge(Shape shape, Point p1, Point p2) {
LineSegment edges[] = getEdges(shape);
LineSegment top = edges[0];
LineSegment bottom = edges[1];
LineSegment left = edges[2];
LineSegment right = edges[3];
double minDist;
double dist;
LineSegment result;
minDist = top.getDistance(p1) + top.getDistance(p2);
result = top;
dist = bottom.getDistance(p1) + bottom.getDistance(p2);
if (dist<minDist) {
minDist = dist;
result = bottom;
}
dist = left.getDistance(p1) + left.getDistance(p2);
if (dist<minDist) {
minDist = dist;
result = left;
}
dist = right.getDistance(p1) + right.getDistance(p2);
if (dist<minDist) {
minDist = dist;
result = right;
}
return result;
}
public static void sendToFront(Shape shape) {
peService.sendToFront(shape);
BPMNShape bpmnShape = BusinessObjectUtil.getFirstElementOfType(shape, BPMNShape.class);
if (bpmnShape!=null) {
BPMNPlane plane = (BPMNPlane)bpmnShape.eContainer();
plane.getPlaneElement().remove(bpmnShape);
plane.getPlaneElement().add(bpmnShape);
}
}
public static void sendToBack(Shape shape) {
peService.sendToBack(shape);
BPMNShape bpmnShape = BusinessObjectUtil.getFirstElementOfType(shape, BPMNShape.class);
if (bpmnShape!=null) {
BPMNPlane plane = (BPMNPlane)bpmnShape.eContainer();
plane.getPlaneElement().remove(bpmnShape);
plane.getPlaneElement().add(0,bpmnShape);
}
}
public static Shape findShapeAt(ContainerShape containerShape, Point p, IShapeFilter filter) {
for (Shape c : containerShape.getChildren()) {
if (c.isActive()) {
if (c instanceof ContainerShape) {
Shape cc = findShapeAt((ContainerShape) c, p, filter);
if (cc!=null)
return cc;
}
if (contains(c, p)) {
if (filter.matches(c)) {
return c;
}
}
}
}
return null;
}
/**
* Check if the given Point is with a given distance of the given Location.
*
* @param p - the Point to check
* @param loc - the target Location
* @param dist - the maximum distance horizontally and vertically from the given Location
* @return true if the point lies within the rectangular area of the Location.
*/
public static boolean isPointNear(Point p, ILocation loc, int dist) {
int x = p.getX();
int y = p.getY();
int lx = loc.getX();
int ly = loc.getY();
return lx-dist <= x && x <= lx+dist && ly-dist <= y && y <= ly+dist;
}
public static boolean isPointNear(Point p1, Point p2, int dist) {
int x = p1.getX();
int y = p1.getY();
int lx = p2.getX();
int ly = p2.getY();
return lx-dist <= x && x <= lx+dist && ly-dist <= y && y <= ly+dist;
}
/**
* This method computes a bounding rectangle around a group of PictorgramElements
*
* @param pes
* @return
*/
public static Rectangle getBoundingRectangle(List<? extends PictogramElement> pes) {
int xMin = Integer.MAX_VALUE;
int yMin = Integer.MAX_VALUE;
int xMax = Integer.MIN_VALUE;
int yMax = Integer.MIN_VALUE;
for (PictogramElement pe : pes) {
if (pe instanceof Shape) {
GraphicsAlgorithm peGa = pe.getGraphicsAlgorithm();
IDimension size = calculateSize(pe);
if (peGa.getX()<xMin)
xMin = peGa.getX();
if (peGa.getY()<yMin)
yMin = peGa.getY();
if (peGa.getX() + size.getWidth()>xMax)
xMax = peGa.getX() + size.getWidth();
if (peGa.getY() + size.getHeight()>yMax)
yMax = peGa.getY() + size.getHeight();
}
}
return new Rectangle(xMin, yMin, xMax-xMin, yMax-yMin);
}
/**
* This method computes a bounding rectangle around a group of PictorgramElements with absolute
* x,y coordinates relative to the Diagram
* @param pes
* @return
*/
public static Rectangle getBoundingRectangleAbsolute(List<? extends PictogramElement> pes) {
int xMin = Integer.MAX_VALUE;
int yMin = Integer.MAX_VALUE;
int xMax = Integer.MIN_VALUE;
int yMax = Integer.MIN_VALUE;
for (PictogramElement pe : pes) {
if (pe instanceof Shape) {
ILocation loc = Graphiti.getPeService().getLocationRelativeToDiagram((Shape)pe);
IDimension size = calculateSize(pe);
if (loc.getX()<xMin)
xMin = loc.getX();
if (loc.getY()<yMin)
yMin = loc.getY();
if (loc.getX() + size.getWidth()>xMax)
xMax = loc.getX() + size.getWidth();
if (loc.getY() + size.getHeight()>yMax)
yMax = loc.getY() + size.getHeight();
}
}
return new Rectangle(xMin, yMin, xMax-xMin, yMax-yMin);
}
}