Search in sources :

Example 16 with ConnectionModel

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;
}
Also used : PointList(org.eclipse.draw2d.geometry.PointList) ArrayList(java.util.ArrayList) Point(org.eclipse.draw2d.geometry.Point) Point(org.eclipse.draw2d.geometry.Point) DisplayModel(org.csstudio.opibuilder.model.DisplayModel) Polyline(org.eclipse.draw2d.Polyline) ConnectionModel(org.csstudio.opibuilder.model.ConnectionModel)

Example 17 with ConnectionModel

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()));
}
Also used : SetWidgetPropertyCommand(org.csstudio.opibuilder.commands.SetWidgetPropertyCommand) PointList(org.eclipse.draw2d.geometry.PointList) ConnectionAnchor(org.eclipse.draw2d.ConnectionAnchor) AbstractWidgetModel(org.csstudio.opibuilder.model.AbstractWidgetModel) ConnectionModel(org.csstudio.opibuilder.model.ConnectionModel) ConnectionReconnectCommand(org.csstudio.opibuilder.commands.ConnectionReconnectCommand)

Example 18 with ConnectionModel

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;
}
Also used : AbstractWidgetModel(org.csstudio.opibuilder.model.AbstractWidgetModel) AbstractContainerModel(org.csstudio.opibuilder.model.AbstractContainerModel) DisplayModel(org.csstudio.opibuilder.model.DisplayModel) LineAwareElement(org.csstudio.opibuilder.persistence.LineAwareXMLParser.LineAwareElement) Element(org.jdom.Element) Iterator(java.util.Iterator) WidgetDescriptor(org.csstudio.opibuilder.util.WidgetDescriptor) ConnectionModel(org.csstudio.opibuilder.model.ConnectionModel) ArrayList(java.util.ArrayList) List(java.util.List) JDOMException(org.jdom.JDOMException) IOException(java.io.IOException)

Aggregations

ConnectionModel (org.csstudio.opibuilder.model.ConnectionModel)18 AbstractWidgetModel (org.csstudio.opibuilder.model.AbstractWidgetModel)10 PointList (org.eclipse.draw2d.geometry.PointList)8 ArrayList (java.util.ArrayList)7 AbstractContainerModel (org.csstudio.opibuilder.model.AbstractContainerModel)6 DisplayModel (org.csstudio.opibuilder.model.DisplayModel)4 SetWidgetPropertyCommand (org.csstudio.opibuilder.commands.SetWidgetPropertyCommand)3 LineAwareElement (org.csstudio.opibuilder.persistence.LineAwareXMLParser.LineAwareElement)3 Point (org.eclipse.draw2d.geometry.Point)3 Element (org.jdom.Element)3 IOException (java.io.IOException)2 Iterator (java.util.Iterator)2 List (java.util.List)2 ConnectionReconnectCommand (org.csstudio.opibuilder.commands.ConnectionReconnectCommand)2 AbstractBaseEditPart (org.csstudio.opibuilder.editparts.AbstractBaseEditPart)2 ConnectionAnchor (org.eclipse.draw2d.ConnectionAnchor)2 Polyline (org.eclipse.draw2d.Polyline)2 Rectangle (org.eclipse.draw2d.geometry.Rectangle)2 JDOMException (org.jdom.JDOMException)2 HashMap (java.util.HashMap)1