use of org.csstudio.opibuilder.model.ConnectionModel in project yamcs-studio by yamcs.
the class WidgetConnectionEditPart method getIntersectionPoints.
PointList getIntersectionPoints(PolylineJumpConnection connection) {
intersectionMap = new HashMap<Point, PointList>();
PointList pointsInConnection = getPointListOfConnectionForConnection(connection);
ConnectionModel widgetModel = getWidgetModel();
// Skip calculating intersections if line_jump_add is set to none
if (widgetModel.getLineJumpAdd().equals(LineJumpAdd.NONE)) {
return pointsInConnection;
}
PointList intersections = new PointList();
int lineJumpSize = connection.getLineJumpSize();
DisplayModel rootDisplayModel = widgetModel.getRootDisplayModel();
while (rootDisplayModel.getParentDisplayModel() != null) {
rootDisplayModel = rootDisplayModel.getParentDisplayModel();
}
List<ConnectionModel> connectionList = rootDisplayModel.getConnectionList();
for (int i = 0; (i + 1) < pointsInConnection.size(); ) {
Point x1y1 = pointsInConnection.getPoint(i);
Point x2y2 = pointsInConnection.getPoint(i + 1);
/* The Manhattan connection in CS-Studio always has at least 3 segments, even if
* they are invisible to the user, because he sees a straight line. But if these
* invisible segments fall exactly where this connection intersects another
* connection, this may confuse the logic into thinking that the line jump
* should not be drawn because of the limitation that the line jump cannot be
* drawn too close to the bend in the connection.
* To overcome this problem, we do not simply follow the line segments, but
* check whether subsequent line segments are actually in the same line
* (vertically or horizontally). If this is the case, we join such segments
* until we reach an actual bend or the end of the connection.
* To achieve this we need to manipulate the index to skip the joined
* segments.
*/
// increase 'i' once for the next point (simple case)
i++;
for (int j = (i + 1); j < pointsInConnection.size(); j++) {
// we may increase 'i' some more if we detect joined segments
Point p = pointsInConnection.getPoint(j);
if ((p.x() == x1y1.x()) || (p.y() == x1y1.y())) {
x2y2 = p;
i = j;
} else {
break;
}
}
int x1 = x1y1.x;
int y1 = x1y1.y;
int x2 = x2y2.x;
int y2 = x2y2.y;
intersections.addPoint(x1y1);
ArrayList<Point> intersectionPointsList = new ArrayList<Point>();
// line is horizontal
if (y1 - y2 == 0) {
// Property is not set to horizontal. Skip
if (!(widgetModel.getLineJumpAdd().equals(LineJumpAdd.HORIZONTAL_LINES))) {
continue;
}
}
// line is vertical
if (x1 - x2 == 0) {
// Property is not set to vertical. Skip
if (!(widgetModel.getLineJumpAdd().equals(LineJumpAdd.VERTICAL_LINES))) {
continue;
}
}
// skip for slanting lines
if (x1 - x2 != 0 && y1 - y2 != 0) {
continue;
}
for (ConnectionModel connModel : connectionList) {
if (connModel != getModel()) {
WidgetConnectionEditPart widgetConnectionEditPart = (WidgetConnectionEditPart) getViewer().getEditPartRegistry().get(connModel);
if (widgetConnectionEditPart == null) {
continue;
}
PolylineJumpConnection connectionFigure = widgetConnectionEditPart.getConnectionFigure();
PointList pointListOfConnection = getPointListOfConnectionForConnection(connectionFigure);
for (int j = 0; (j + 1) < pointListOfConnection.size(); j++) {
Point x3y3 = pointListOfConnection.getPoint(j);
Point x4y4 = pointListOfConnection.getPoint(j + 1);
int x3 = x3y3.x;
int y3 = x3y3.y;
int x4 = x4y4.x;
int y4 = x4y4.y;
// Edge Case: Check if lines are parallel
if ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4) != 0) {
// Calculate intersection point https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
double itx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4);
itx = itx / (((x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4)));
double ity = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4);
ity = ity / (((x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4)));
Point intersectionPoint = new Point(itx, ity);
// Ignore
if (intersectionPoint.getDistance(x1y1) < lineJumpSize || intersectionPoint.getDistance(x2y2) < lineJumpSize) {
continue;
}
// Check if intersection point is in both line segments
Polyline line1 = new Polyline();
line1.addPoint(new Point(x1, y1));
line1.addPoint(new Point(x2, y2));
Polyline line2 = new Polyline();
line2.addPoint(new Point(x3, y3));
line2.addPoint(new Point(x4, y4));
if (line1.containsPoint((int) itx, (int) ity) && line2.containsPoint((int) itx, (int) ity)) {
if (lineJumpSize > 0) {
Point intersectionPoint1 = null;
// Get point between intersection point and start point
double d = x1y1.getDistance(intersectionPoint);
double dt = lineJumpSize;
// Edge Case: Intersection point is start point
if (((int) d) == 0) {
intersectionPoint1 = x1y1;
} else {
double t = dt / d;
double xit1 = (((1 - t) * intersectionPoint.x) + t * x1);
double yit1 = (((1 - t) * intersectionPoint.y) + t * y1);
intersectionPoint1 = new Point(xit1, yit1);
}
intersectionPointsList.add(intersectionPoint1);
// Get point between intersection point and end point
Point intersectionPoint2 = null;
d = intersectionPoint.getDistance(x2y2);
// Edge Case: Intersection point is end point
if (((int) d) == 0) {
intersectionPoint2 = x2y2;
} else {
double t = dt / d;
double xit2 = (((1 - t) * intersectionPoint.x) + t * x2);
double yit2 = (((1 - t) * intersectionPoint.y) + t * y2);
intersectionPoint2 = new Point(xit2, yit2);
}
// Edge Case: It may happen that this points are out of bounds.
// This will happen when line intersection is very near to end points.
// If so correct it.
Polyline line3 = new Polyline();
line3.addPoint(x1y1);
line3.addPoint(x2y2);
if (!line3.containsPoint(intersectionPoint1)) {
intersectionPoint1 = x1y1;
}
if (!line3.containsPoint(intersectionPoint2)) {
intersectionPoint2 = x2y2;
}
intersectionPointsList.add(intersectionPoint2);
PointList currentIntersectionPoints = new PointList();
currentIntersectionPoints.addPoint(intersectionPoint1);
currentIntersectionPoints.addPoint(intersectionPoint2);
intersectionMap.put(intersectionPoint, currentIntersectionPoints);
}
}
}
}
}
}
// Edge Case: While calculating intersection points, iterating on connections does
// not guarantee order. Sort so that points are in order.
Collections.sort(intersectionPointsList, new Comparator<Point>() {
@Override
public int compare(Point x1_, Point x2_) {
int result = Double.compare(x1_.getDistance(x1y1), x2_.getDistance(x1y1));
return result;
}
});
for (Point p : intersectionPointsList) {
intersections.addPoint(p);
}
}
if (pointsInConnection.size() > 0) {
intersections.addPoint(pointsInConnection.getLastPoint());
}
return intersections;
}
use of org.csstudio.opibuilder.model.ConnectionModel in project yamcs-studio by yamcs.
the class WidgetNodeEditPolicy method getReconnectSourceCommand.
@Override
protected Command getReconnectSourceCommand(ReconnectRequest request) {
ConnectionModel connection = (ConnectionModel) request.getConnectionEditPart().getModel();
AbstractWidgetModel newSource = getWidgetEditPart().getWidgetModel();
ConnectionAnchor anchor = getWidgetEditPart().getTargetConnectionAnchor(request);
String newTerminal = getWidgetEditPart().getTerminalNameFromAnchor(anchor);
ConnectionReconnectCommand cmd = new ConnectionReconnectCommand(connection);
cmd.setNewSource(newSource);
cmd.setNewSourceTerminal(newTerminal);
// clear point list
return cmd.chain(new SetWidgetPropertyCommand(connection, ConnectionModel.PROP_POINTS, new PointList()));
}
use of org.csstudio.opibuilder.model.ConnectionModel in project yamcs-studio by yamcs.
the class XMLUtil method fillWidgets.
/**
* Convert XML Element to a widget model.
*
* @param element
* @param displayModel
* the root display model. If root of the element is a display, use this display model as root model
* instead of creating a new one. If this is null, a new one will be created.
* @throws Exception
*/
@SuppressWarnings("rawtypes")
public static AbstractWidgetModel fillWidgets(Element element, DisplayModel displayModel) throws Exception {
if (element == null)
return null;
AbstractWidgetModel rootWidgetModel = null;
// Determine root widget model
if (element.getName().equals(XMLTAG_DISPLAY)) {
if (displayModel != null)
rootWidgetModel = displayModel;
else
rootWidgetModel = new DisplayModel(null);
} else if (element.getName().equals(XMLTAG_WIDGET)) {
String typeId = element.getAttributeValue(XMLATTR_TYPEID);
WidgetDescriptor desc = WidgetsService.getInstance().getWidgetDescriptor(typeId);
if (desc != null)
rootWidgetModel = desc.getWidgetModel();
if (rootWidgetModel == null) {
String errorMessage = NLS.bind("Fail to load the widget: {0}\n " + "The widget may not exist, as a consequence, the widget will be ignored.", typeId);
ErrorHandlerUtil.handleError(errorMessage, new Exception("Widget does not exist."));
return null;
}
} else if (element.getName().equals(XMLTAG_CONNECTION)) {
rootWidgetModel = new ConnectionModel(displayModel);
} else {
String errorMessage = "Unknown Tag: " + element.getName();
ConsoleService.getInstance().writeError(errorMessage);
return null;
}
setPropertiesFromXML(element, rootWidgetModel);
if (rootWidgetModel instanceof AbstractContainerModel) {
AbstractContainerModel container = (AbstractContainerModel) rootWidgetModel;
List children = element.getChildren();
Iterator iterator = children.iterator();
while (iterator.hasNext()) {
Element subElement = (Element) iterator.next();
if (subElement.getName().equals(XMLTAG_WIDGET))
container.addChild(fillWidgets(subElement, displayModel));
}
}
if (displayModel != null)
rootWidgetModel.processVersionDifference(displayModel.getBOYVersion());
return rootWidgetModel;
}
Aggregations