diff --git a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisualizationRequest.java b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisualizationRequest.java index 3a661ab4..e2d1f896 100644 --- a/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisualizationRequest.java +++ b/VWorkflows-Core/src/main/java/eu/mihosoft/vrl/workflow/VisualizationRequest.java @@ -57,6 +57,11 @@ public interface VisualizationRequest extends PropertyStorage{ */ static final String KEY_NODE_NOT_REMOVABLE = "visualization-request:skin:node-not-removable"; + /** + * Defines whether connector prefers top-down layout. + */ + static final String KEY_CONNECTOR_PREFER_TOP_DOWN = "visualization-request:connector:prefer-top-down"; + public void setStyle(String style); public String getStyle(); } diff --git a/VWorkflows-FX/src/main/java/eu/mihosoft/vrl/workflow/fx/FXFlowNodeSkin.java b/VWorkflows-FX/src/main/java/eu/mihosoft/vrl/workflow/fx/FXFlowNodeSkin.java index 74101de9..33672242 100644 --- a/VWorkflows-FX/src/main/java/eu/mihosoft/vrl/workflow/fx/FXFlowNodeSkin.java +++ b/VWorkflows-FX/src/main/java/eu/mihosoft/vrl/workflow/fx/FXFlowNodeSkin.java @@ -41,7 +41,6 @@ import eu.mihosoft.vrl.workflow.VisualizationRequest; import eu.mihosoft.vrl.workflow.skin.VNodeSkin; - import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleIntegerProperty; @@ -143,7 +142,7 @@ protected FlowNodeWindow createNodeWindow() { cShape.getNode().setCache(!flowNodeWindow.isResizing()); }); }); - + flowNodeWindow.resizingProperty().addListener((ov) -> { if (flowNodeWindow.isResizing()) { flowNodeWindow.setCache(false); @@ -177,7 +176,6 @@ private void init() { addConnector(connector); } - getModel().getConnectors().addListener( (ListChangeListener.Change change) -> { boolean numConnectorsHasChanged = false; @@ -192,7 +190,7 @@ private void init() { // // TODO update item // } // else - + if (change.wasRemoved()) { numConnectorsHasChanged = true; // removed @@ -335,12 +333,37 @@ private void layoutConnector(Connector c, boolean updateOthers) { ConnectorShape connectorShape = connectors.get(c); - connectorShape.getNode().setLayoutX(computeConnectorXValue(c) - connectorShape.getRadius() ); - connectorShape.getNode().setLayoutY(computeConnectorYValue(c) - connectorShape.getRadius() ); + connectorShape.getNode().setLayoutX(computeConnectorXValue(c) - connectorShape.getRadius()); + connectorShape.getNode().setLayoutY(computeConnectorYValue(c) - connectorShape.getRadius()); Collection conns = getModel().getFlow(). getConnections(c.getType()).getAllWith(c); + //----------------------------B + + Optional preferTD = c.getVisualizationRequest(). + get(VisualizationRequest.KEY_CONNECTOR_PREFER_TOP_DOWN); + boolean preferTopDown = preferTD.orElse(false); + + if (preferTopDown && conns.isEmpty()) { + int oldEdgeIndex = connectorToIndexMap.get(c); + + int newEdgeIndex = c.isInput() ? TOP : BOTTOM; + + connectorShape.getNode().setLayoutX(computeConnectorXValue(c)- connectorShape.getRadius()); + connectorShape.getNode().setLayoutY(computeConnectorYValue(c)- connectorShape.getRadius()); + + if (newEdgeIndex != oldEdgeIndex) { + shapeLists.get(oldEdgeIndex).remove(connectorShape); + shapeLists.get(newEdgeIndex).add(connectorShape); + connectorToIndexMap.put(c, newEdgeIndex); + + // update all other connectors + layoutConnectors(); + } + } + + //----------------------------E if (conns.isEmpty()) { return; } @@ -410,8 +433,10 @@ private void layoutConnector(Connector c, boolean updateOthers) { } } // end if switchEdges - connectorShape.getNode().setLayoutX(computeConnectorXValue(c) - connectorShape.getRadius()); - connectorShape.getNode().setLayoutY(computeConnectorYValue(c) - connectorShape.getRadius()); + connectorShape.getNode().setLayoutX(computeConnectorXValue(c) + - connectorShape.getRadius()); + connectorShape.getNode().setLayoutY(computeConnectorYValue(c) + - connectorShape.getRadius()); // System.out.println("c: " + c); if (updateOthers) { @@ -535,15 +560,21 @@ protected void addConnector(final Connector connector) { connectorNode.setManaged(false); connectors.put(connector, connectorShape); - +//--------------------B + Optional preferTD = connector.getVisualizationRequest(). + get(VisualizationRequest.KEY_CONNECTOR_PREFER_TOP_DOWN); + boolean preferTopDown = preferTD.orElse(false); + int inputDefault = preferTopDown ? TOP : LEFT; + int outputDefault = preferTopDown ? BOTTOM : RIGHT; +//--------------------E if (connector.isInput()) { // inputList.add(connectorNode); - shapeLists.get(LEFT).add(connectorShape); - connectorToIndexMap.put(connector, LEFT); + shapeLists.get(inputDefault).add(connectorShape); + connectorToIndexMap.put(connector, inputDefault); } else if (connector.isOutput()) { // outputList.add(connectorNode); - shapeLists.get(RIGHT).add(connectorShape); - connectorToIndexMap.put(connector, RIGHT); + shapeLists.get(outputDefault).add(connectorShape); + connectorToIndexMap.put(connector, outputDefault); } node.boundsInLocalProperty().addListener((ov, oldValue, newValue) -> {