diff options
Diffstat (limited to 'index.html')
-rw-r--r-- | index.html | 1082 |
1 files changed, 825 insertions, 257 deletions
@@ -16,6 +16,9 @@ <script type="text/javascript" src="details.js"></script> <script type="text/javascript" src="setup.js"></script> <script type="text/javascript"> + + // Stores edgeState for every recently created edge in updateFixedTerminalPoint() function + var edgeState = {}; function main(container, outline, toolbar, sidebar, status) { // Checks if the browser is supported if (!mxClient.isBrowserSupported()) { @@ -154,7 +157,7 @@ { menu.addItem('Delete', 'images/delete2.png', function() { - editor.execute('delete'); + editor.execute('deleteBlock'); }); var edgeformat = menu.addItem('Format', null, null); @@ -252,42 +255,424 @@ var config = mxUtils.load('config/keyhandler-commons.xml').getDocumentElement(); editor.configure(config); + graph.isCellSelectable = function(cell) + { + if(cell.isConnectable() == true && cell.isEdge() == false) { + return false; + } + return true; + }; + + graph.resizeCell = function(cell, bounds, recurse) { + if(cell.getStyle() == 'Split') { + return null; + } + else { + return mxGraph.prototype.resizeCell.apply(this, arguments); + } + } /* For a new edge on the graph, check if that edge satisfies one of the port constraints. + Possible edge cases with source & target : + 1) Source : Port, Target : Port + 2) Source : Edge, Target : Port + 3) Source : Port, Target : Edge + 4) Source : Edge, Target : Edge */ graph.addEdge = function(edge, parent, source, target, index) { - var edgeSource = source; + if(source.isEdge() == true && target.isEdge() == true) { + alert("Illegal connection! - Link to link connection"); + return null; + } + + // If the edge is legit, return the edge. + if(source.isEdge() == true) { + graph.getModel().beginUpdate(); + try + { + var edgeSource = source; + + // While the source of the edge is an edge, find the final port + while (edgeSource.isEdge() == true) { + edgeSource = edgeSource.source; + } + + // If the edge violates any of the port constraints, don't create the edge + if(edgeSource.value == "ExplicitOutputPort" && target.value != "ExplicitInputPort") { + alert("Explicit data output port must be connected to explicit data input port"); + return null; + } + else if(edgeSource.value == "ExplicitInputPort" && target.value != "ExplicitOutputPort") { + alert("Explicit data input port must be connected to explicit data output port"); + return null; + } + else if(edgeSource.value == "ImplicitOutputPort" && target.value != "ImplicitInputPort") { + alert("Implicit data output port must be connected to implicit data input port"); + return null; + } + else if(edgeSource.value == "ImplicitInputPort" && target.value != "ImplicitOutputPort") { + alert("Implicit data input port must be connected to implicit data output port"); + return null; + } + else if(edgeSource.value == "CommandPort" && target.value != "ControlPort") { + alert("Command port must be connected to control port"); + return null; + } + else if(edgeSource.value == "ControlPort" && target.value != "CommandPort") { + alert("Control port must be connected to command port"); + return null; + } + + // Create the splitBlock + // (x-5, y-5.5) is the offset to correct the position of split-block + var cell = graph.insertVertex(graph.getDefaultParent(), null, '', source.sourcePoint.x-5, source.sourcePoint.y-5.5, 10, 10,'Split', false); + + + + // Get the source state + var sourceState = graph.view.getState(source); + var waypoints = source.waypoints; + var waypoints1 = []; + + // Add the absolute points for source edge to waypoints variable + for(i in sourceState.absolutePoints) { + waypoints1.push(sourceState.absolutePoints[i]); + } + + // Remove source and target points + waypoints1.shift(); + waypoints1.pop(); + + // Store the waypoints to the source edge + waypoints = waypoints1; + + // Find the index in the waypoints nearest to the split-block + var seg = mxUtils.findNearestSegment(sourceState, source.sourcePoint.x, source.sourcePoint.y); + var sourceTarget = source.target; + + // Set the type of ports for split-block according to type of source edge + if (edgeSource.value == 'ExplicitOutputPort') { + createPorts(graph, cell, ['E'], [], ['E'], ['E']); + } + else if (edgeSource.value == 'ImplicitOutputPort') { + createPorts(graph, cell, ['I'], [], ['I', 'I'], []); + } + else { + createPorts(graph, cell, ['CONTROL'], [], ['COMMAND', 'COMMAND'], []); + } + + // Source edge is replaced with first edge and futureSource edges + cell.name = 'SPLIT_f'; + var firstEdge = graph.insertEdge(parent, null, '', cell.getChildAt(1), sourceTarget); + var thirdEdge = graph.insertEdge(parent, null, '', cell.getChildAt(2), target); + var futureSource = graph.insertEdge(parent, null, '', source.source, cell.getChildAt(0)); + + // Hide all the ports of a split-block + cell.getChildAt(0).setVisible(false); + cell.getChildAt(1).setVisible(false); + cell.getChildAt(2).setVisible(false); + + // Remove the current source + graph.removeCells([source], true); + + // Set the newly made futureSource as the source + source = futureSource; + + /* + * If there are any waypoints, divide them for the two newly created edges. + * The two newly created edges are inherited from the source edge + */ + if(waypoints != null) { + var waypoints1 = []; + for(var i = 0; i < seg; i++) { + waypoints1.push(waypoints[i]); + } + + var waypoints2 = []; + for(var i = seg; i < waypoints.length; i++) { + waypoints2.push(waypoints[i]); + } + + source.geometry.points = waypoints1; + firstEdge.geometry.points = waypoints2; + } - // If the source of the edge is also an edge, find the port. - while (edgeSource.isEdge() == true) { - edgeSource = edgeSource.source; + // Find the waypoints of the current edge, and set the waypoints for the new thirdEdge + var waypoints3 = edgeState.absolutePoints; + if(waypoints3 != null && waypoints3.length > 1) { + // Remove last absolute point + waypoints3.pop(); + } + + thirdEdge.geometry.points = waypoints3; + + // Connectable for the ports and the split-block should be false + cell.getChildAt(0).setConnectable(false); + cell.getChildAt(1).setConnectable(false); + cell.getChildAt(2).setConnectable(false); + cell.setConnectable(false); + + // Get the parent of the splitBlock + var parent = graph.model.getParent(cell); + + graph.model.beginUpdate(); + try { + /* + * Adds the split-block to the parent at the last index + * Enables split-block to appear over it's associated edges + */ + graph.model.add(parent, cell, graph.model.getChildCount(parent) - 1); + } + finally { + graph.model.endUpdate(); + } + + graph.refresh(); + } + finally + { + graph.getModel().endUpdate(); } - // If the edge violates any port constraints, return null. - if (!((edgeSource.getEdgeCount() == 0 && edgeSource.isVertex() && - target.getEdgeCount() == 0 && target.isVertex()) || - (edgeSource.getEdgeCount() <= 1 && source.isEdge()))) { - alert("Port is already connected, please select an please select an unconnected port or a valid link"); - } else if (edgeSource.value == "ExplicitOutputPort" && target.value != "ExplicitInputPort") { + /* + * Remove the current edge, as we have already created + * thirdEdge as it's replacement, to enable waypoints. + */ + return null; + } + + // If the edge is legit, return the edge. + if(target.isEdge() == true) { + graph.getModel().beginUpdate(); + try + { + var edgeSource = target; + + // While the source of the edge is an edge, find the final port + while (edgeSource.isEdge() == true) { + edgeSource = edgeSource.source; + } + + // If the edge violates any of the port constraints, don't create the edge + if(source.value == "ExplicitOutputPort" && edgeSource.value != "ExplicitInputPort") { alert("Explicit data output port must be connected to explicit data input port"); - } else if (edgeSource.value == "ExplicitInputPort" && target.value != "ExplicitOutputPort") { + return null; + } + else if(source.value == "ExplicitInputPort" && edgeSource.value != "ExplicitOutputPort") { alert("Explicit data input port must be connected to explicit data output port"); - } else if (edgeSource.value == "ImplicitOutputPort" && target.value != "ImplicitInputPort") { + return null; + } + else if(source.value == "ImplicitOutputPort" && edgeSource.value != "ImplicitInputPort") { alert("Implicit data output port must be connected to implicit data input port"); - } else if (edgeSource.value == "ImplicitInputPort" && target.value != "ImplicitOutputPort") { + return null; + } + else if(source.value == "ImplicitInputPort" && edgeSource.value != "ImplicitOutputPort") { alert("Implicit data input port must be connected to implicit data output port"); - } else if (edgeSource.value == "CommandPort" && target.value != "ControlPort") { + return null; + } + else if(source.value == "CommandPort" && edgeSource.value != "ControlPort") { alert("Command port must be connected to control port"); - } else if (edgeSource.value == "ControlPort" && target.value != "CommandPort") { + return null; + } + else if(source.value == "ControlPort" && edgeSource.value != "CommandPort") { alert("Control port must be connected to command port"); - } else { - // If the edge is legit, return the edge. - return mxGraph.prototype.addEdge.apply(this, arguments); + return null; + } + + // Create the splitBlock + // (x-5, y-5.5) is the offset to correct the position of split-block + var cell = graph.insertVertex(graph.getDefaultParent(), null, '', target.sourcePoint.x-5, target.sourcePoint.y-5, 10, 10,'Split', false); + + // Get the source state + var sourceState = graph.view.getState(target); + var waypoints = target.waypoints; + var waypoints1 = []; + + // Add the absolute points for source edge to waypoints variable + for(i in sourceState.absolutePoints) { + waypoints1.push(sourceState.absolutePoints[i]); + } + waypoints1.shift(); + waypoints1.pop(); + waypoints = waypoints1; + + // Find the index in the waypoints nearest to the split-block + var seg = mxUtils.findNearestSegment(sourceState, target.sourcePoint.x, target.sourcePoint.y); + var sourceTarget = target.target; + + if (edgeSource.value == 'ExplicitOutputPort') { + createPorts(graph, cell, ['E'], [], ['E'], ['E']); + + } + else if (edgeSource.value == 'ImplicitOutputPort') { + createPorts(graph, cell, ['I'], [], ['I', 'I'], []); + } + else { + createPorts(graph, cell, ['CONTROL'], [], ['COMMAND', 'COMMAND'], []); + } + + // Source edge is replaced with first edge and futureSource edges + cell.name = 'SPLIT_f'; + var firstEdge = graph.insertEdge(parent, null, '', cell.getChildAt(1), sourceTarget); + var thirdEdge = graph.insertEdge(parent, null, '', cell.getChildAt(2), source); + var futureSource = graph.insertEdge(parent, null, '', target.source, cell.getChildAt(0)); + + // Hide all the ports of a split-block + cell.getChildAt(0).setVisible(false); + cell.getChildAt(1).setVisible(false); + cell.getChildAt(2).setVisible(false); + + // Remove the current source + graph.removeCells([target], true); + target = futureSource; + + /* + * If there are any waypoints, divide them for the two newly created edges. + * The two newly created edges are inherited from the source edge + */ + if(waypoints != null) { + var waypoints1 = []; + for(var i = 0; i < seg; i++) { + waypoints1.push(waypoints[i]); + } + + var waypoints2 = []; + for(var i = seg; i < waypoints.length; i++) { + waypoints2.push(waypoints[i]); + } + + target.geometry.points = waypoints1; + firstEdge.geometry.points = waypoints2; + } + + // Find the waypoints of the current edge, and set the waypoints for the new thirdEdge + var waypoints3 = edgeState.absolutePoints; + if(waypoints3 != null && waypoints3.length > 1) { + waypoints3.pop(); + } + waypoints3.reverse(); + thirdEdge.geometry.points = waypoints3; + + // Connectable for the ports and the split-block should be false + cell.getChildAt(0).setConnectable(false); + cell.getChildAt(1).setConnectable(false); + cell.getChildAt(2).setConnectable(false); + cell.setConnectable(false); + + // Get the parent of the splitBlock + var parent = graph.model.getParent(cell); + + graph.model.beginUpdate(); + try { + /* + * Adds the split-block to the parent at the last index + * Enables split-block to appear over it's associated edges + */ + graph.model.add(parent, cell, graph.model.getChildCount(parent) - 1); + } + finally { + graph.model.endUpdate(); + } + + graph.refresh(); + } + finally + { + graph.getModel().endUpdate(); } + /* + * Remove the current edge, as we have already created + * thirdEdge as it's replacement, to enable waypoints. + */ return null; + } + + // If the newly created edge is related to a splitBlock, make the edge. + if(source.parent.name == 'SPLIT_f' || target.parent.name == 'SPLIT_f') { + return mxGraph.prototype.addEdge.apply(this, arguments); + } + + var edgeSource = source; + + // If the source of the edge is also an edge, find the port. + while (edgeSource.isEdge() == true) { + edgeSource = edgeSource.source; + } + + // For port-to-port edges with port constraint violations, don't create that edge + if(source.getEdgeCount() > 0 || target.getEdgeCount() > 0) { + alert("Port is already connected, please select an please select an unconnected port or a valid link"); + } + else if(edgeSource.value == "ExplicitOutputPort" && target.value != "ExplicitInputPort") { + alert("Explicit data output port must be connected to explicit data input port"); + } + else if(edgeSource.value == "ExplicitInputPort" && target.value != "ExplicitOutputPort") { + alert("Explicit data input port must be connected to explicit data output port"); + } + else if(edgeSource.value == "ImplicitOutputPort" && target.value != "ImplicitInputPort") { + alert("Implicit data output port must be connected to implicit data input port"); + } + else if(edgeSource.value == "ImplicitInputPort" && target.value != "ImplicitOutputPort") { + alert("Implicit data input port must be connected to implicit data output port"); + } + else if(edgeSource.value == "CommandPort" && target.value != "ControlPort") { + alert("Command port must be connected to control port"); + } + else if(edgeSource.value == "ControlPort" && target.value != "CommandPort") { + alert("Control port must be connected to command port"); + } + else { + + /* + * For reverse edges, (that is, edges from input port to outport) : + * If the source is input port, and target is an output port + * NOTE: Manipulation of source object and target object + * with respect to current edge is not possible, + * as mxGraph.prototype.addEdge(@parameters) function is + * called just before the creation of the edge. + * Hence, the following code creates a identical new edge + * to replace the current edge. + */ + + if((source.value.indexOf('Input') != -1 && target.value.indexOf('Output') != -1) + || (target.value == 'CommandPort' && source.value == 'ControlPort')) { + + // Begin graph DOM update + graph.getModel().beginUpdate(); + + try { + + // Insert new edge in place of current edge + var newEdge = graph.insertEdge(parent, null, '', target, source); + + // Get points for the current edge from the global edgeState object + var waypoints = edgeState.absolutePoints; + + // Reverse waypoint array + waypoints.reverse(); + + // Set the points for the new edge + newEdge.geometry.points = waypoints; + } + finally { + graph.getModel().endUpdate(); + } + + // Return null for the current edge, + + /* + * Return null for the current edge, + * since we have created a new edge above to replace it + */ + return null; + } + // If the edge is legit, return the edge. + return mxGraph.prototype.addEdge.apply(this, arguments); + } + return null; } // Shows a "modal" window when double clicking a vertex. @@ -412,13 +797,26 @@ // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // https://jgraph.github.io/mxgraph/docs/js-api/files/model/mxCell-js.html // Uncomment this block to see XML tags work - /*graph.convertValueToString = function(cell) + graph.convertValueToString = function(cell) { + if (mxUtils.isNode(cell.value)) { - return cell.getAttribute('label', ''); + var stylesheet = graph.getStylesheet(); + var style = stylesheet.styles[cell.value.getAttribute('style')]; + var displayedLabel = style['displayedLabel']; + if(displayedLabel != null) { + var displayParameter = cell.blockInstance.instance.displayParameter; + for(i in displayParameter) { + displayedLabel = displayedLabel.replace("%s", displayParameter[i].toString()); + } + return displayedLabel; + } + else { + return cell.getAttribute('label', ''); + } } - };*/ + }; var cellLabelChanged = graph.cellLabelChanged; graph.cellLabelChanged = function(cell, newValue, autoSize) { @@ -470,50 +868,137 @@ Used Preorder traversal for edges. */ editor.addAction('deleteBlock', function(editor, cell) { - var cells = []; - var selectionCells = graph.getSelectionCells(); - for (var k = 0; k < selectionCells.length; k++) { - var portCount = selectionCells[k].getChildCount(); - cells.push(selectionCells[k]); - // Finds all the port with edges of the selected cell, and calls getEdgeId() for - // each edge object of that port. - for (var i = 0; i < portCount; i++) { - var edgeCount = selectionCells[k].getChildAt(i).getEdgeCount(); - if (edgeCount != 0) { - getEdgeId(selectionCells[k].getChildAt(i)); - - for (var j = 0; j < edgeCount; j++) { - var edgeObject = selectionCells[k].getChildAt(i).getEdgeAt(j); - getEdgeId(edgeObject); - } - } + graph.getModel().beginUpdate(); + try { + + // getEdgeId(@edgeObject) finds all the associated edges and split-block, and deletes them + function getEdgeId(edgeObject) { + + var cellStack = []; + if(edgeObject != null && edgeObject.isEdge() == true) { + cellStack.push(edgeObject); + while(cellStack.length != 0) { + var tempEdgeObject = cellStack.pop(); + if (tempEdgeObject.edge == true && (cells.indexOf(tempEdgeObject) == -1)) { + cells.push(tempEdgeObject); } - } + // If the edge is associated with a split-block(source is a split-block) + if(tempEdgeObject.source.parent.name == "SPLIT_f") { + if(tempEdgeObject.source == tempEdgeObject.source.parent.getChildAt(1)) { - /* getEdgeId() find all the associated edges from an edge. - Pushes the object of that edge into an array of mxCell objects. - */ - function getEdgeId(edgeObject) { - var cellStack = []; - if (edgeObject != null && edgeObject.isEdge() == true) { - cellStack.push(edgeObject); - while (cellStack.length != 0) { - var tempEdgeObject = cellStack.pop(); - if (tempEdgeObject.edge == true && (cells.indexOf(tempEdgeObject) == -1)) { - cells.push(tempEdgeObject); + var sourceEdge = tempEdgeObject.source.parent.getChildAt(0).getEdgeAt(0); + var target = tempEdgeObject.source.parent.getChildAt(2).getEdgeAt(0).target; + + // If the state of the edge is not null + if(graph.view.getState(sourceEdge) != null) { + + // Find waypoints for the first edge related to split-block + var waypoints1 = graph.view.getState(sourceEdge).absolutePoints; + + // Find the waypoints for the second edge related to split-block + var waypoints2 = graph.view.getState(tempEdgeObject.source.parent.getChildAt(2).getEdgeAt(0)).absolutePoints; + waypoints2.shift(); + for(i in waypoints2) { + waypoints1.push(waypoints2[i]); } - for (var j = 0; j < tempEdgeObject.getEdgeCount(); j++) { - cellStack.push(tempEdgeObject.getEdgeAt(j)); + var geometry = graph.getModel().getGeometry(sourceEdge); + var cloneGeometry = geometry.clone(); + + cloneGeometry.points = waypoints1; + graph.getModel().setGeometry(sourceEdge, cloneGeometry); + graph.refresh(); + + // Shift the target for the first edge related to splitBlock + graph.getModel().setTerminal(sourceEdge, target, false); + } + cells.push(tempEdgeObject.source.parent); + } + else { + var sourceEdge = tempEdgeObject.source.parent.getChildAt(0).getEdgeAt(0); + var target = tempEdgeObject.source.parent.getChildAt(1).getEdgeAt(0).target; + + // If the state of the edge is not null + if(graph.view.getState(sourceEdge) != null) { + + // Find waypoints for the first edge related to split-block + var waypoints1 = graph.view.getState(sourceEdge).absolutePoints; + + // Find the waypoints for the second edge related to split-block + var waypoints2 = graph.view.getState(tempEdgeObject.source.parent.getChildAt(1).getEdgeAt(0)).absolutePoints; + waypoints1.pop(); + waypoints2.shift(); + for(i in waypoints2) { + waypoints1.push(waypoints2[i]); } + var geometry = graph.getModel().getGeometry(sourceEdge); + var cloneGeometry = geometry.clone(); + + cloneGeometry.points = waypoints1; + graph.getModel().setGeometry(sourceEdge, cloneGeometry); + graph.refresh(); + + // Shift the target for the first edge related to splitBlock + graph.getModel().setTerminal(sourceEdge, target, false); + } + cells.push(tempEdgeObject.source.parent); } + + } + + // If the edge is associated with a split-block(target is a split-block) + if(tempEdgeObject.target.parent.name == "SPLIT_f") { + if(cells.indexOf(tempEdgeObject.target.parent) == -1) { + cells.push(tempEdgeObject.target.parent); + } + cellStack.push(tempEdgeObject.target.parent.getChildAt(1).getEdgeAt(0)); + cellStack.push(tempEdgeObject.target.parent.getChildAt(2).getEdgeAt(0)); } + } } + } + + var cells = []; + + // Get all selected cells + var selectionCells = graph.getSelectionCells(); + + // For each cell in the selection + for (var k = 0; k < selectionCells.length; k++) { + + // If the cell is an edge, directly call getEdgeId(@parameter) for deletion + if(selectionCells[k].isEdge() == true) { + getEdgeId(selectionCells[k]); + } + + // If the cell is a vertex, select the cell + else { + var portCount = selectionCells[k].getChildCount(); + cells.push(selectionCells[k]); + for (var i = 0; i < portCount; i++) { + var edgeCount = selectionCells[k].getChildAt(i).getEdgeCount(); + if (edgeCount != 0) { + + /* + * For every edge associated with the current selected cell, + * call the getEdgeId(@parameter), parameter is an edgeObject for deletion + */ + + for (var j = 0; j < edgeCount; j++) { + var edgeObject = selectionCells[k].getChildAt(i).getEdgeAt(j); + getEdgeId(edgeObject); + } + } + } + } + } + + graph.removeCells(cells, true); + } + finally { + graph.getModel().endUpdate(); + } - // The mxCells to be deleted are first highlighted, - // and then the selection is deleted in a single go. - graph.getSelectionModel().setCells(cells); - editor.execute('delete'); }); addToolbarButton(editor, toolbar, 'toggle', 'Expand All', 'images/navigate_plus.png'); @@ -525,7 +1010,7 @@ toolbar.appendChild(spacer.cloneNode(true)); - addToolbarButton(editor, toolbar, 'delete', '', 'images/delete2.png'); + addToolbarButton(editor, toolbar, 'deleteBlock', 'Delete', 'images/delete2.png'); addToolbarButton(editor, toolbar, 'undo', '', 'images/undo.png'); addToolbarButton(editor, toolbar, 'redo', '', 'images/redo.png'); toolbar.appendChild(spacer.cloneNode(true)); @@ -540,7 +1025,7 @@ Maverick This method is used for loading the stylesheet from the file. Reference: http://www.w3schools.com/xsl/xsl_client.asp - */ + */ function loadXMLDoc(filename) { if (window.ActiveXObject) { @@ -557,92 +1042,122 @@ } - /* - Maverick - The Export buttons in toolbar call this function with varying - arguments. - The third argument is used to decide which button is being - pressed. - exportXML : 2 arguments - exportXcos: 3 arguments - */ - function displayXMLorXcos() { - var textarea = document.createElement('textarea'); - textarea.style.width = '400px'; - textarea.style.height = '400px'; - var enc = new mxCodec(mxUtils.createXmlDocument()); - /*var array=[],key; - for (key in diagRoot.model.cells) { - - if(diagRoot.model.cells[key].connectable == false) - { - array.push(diagRoot.model.cells[key].inst); - diagRoot.model.cells[key].inst=null; - } - }*/ - var node = enc.encode(diagRoot); - - var str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + mxUtils.getPrettyXml(node); - - textarea.value = str; - /*var j = 0; - for (key in diagRoot.model.cells) { - - if(diagRoot.model.cells[key].connectable == false) - { - diagRoot.model.cells[key].inst=array[j++]; - } - }*/ - if (arguments[2] == null) { - showModalWindow(graph, 'XML', textarea, 410, 440); - } else { - - return mxUtils.getPrettyXml(node); - } - } - - // Defines a new export action - editor.addAction('exportXML', function(editor, cell) { - //Only two parameters passed here. - displayXMLorXcos(editor, cell); - }); - - /* Maverick - Reference: http://www.w3schools.com/xsl/xsl_client.asp - */ - - editor.addAction('exportXcos', function(editor, cell) { - //Mind the 3 parameters. - var xmlFromExportXML = displayXMLorXcos(editor, cell, true); - if (xmlFromExportXML == null) alert('First create the XML file.'); - else { - - var xml = mxUtils.parseXml(xmlFromExportXML); - - var xsl = loadXMLDoc("finalmodsheet.xsl"); - - xsltProcessor = new XSLTProcessor(); - xsltProcessor.importStylesheet(xsl); - resultDocument = xsltProcessor.transformToDocument(xml); - - - var textarea = document.createElement('textarea'); - textarea.style.width = '400px'; - textarea.style.height = '400px'; - /* - Maverick - Using resultDocument.documentElement to remove an additional tag "<#document>" created by the XSLTProcessor. - */ - var str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n" + mxUtils.getPrettyXml(resultDocument.documentElement); - - textarea.value = str.replace(/\n\n/g, "\n"); - showModalWindow(graph, 'Xcos', textarea, 410, 440); - } - }); - - addToolbarButton(editor, toolbar, 'exportXML', 'Export XML', 'images/export1.png'); - - addToolbarButton(editor, toolbar, 'exportXcos', 'Export Xcos', 'images/export1.png'); + /* + Maverick + The Export buttons in toolbar call this function with varying + arguments. + The third argument is used to deciFde which button is being + pressed. + exportXML : 2 arguments + exportXcos: 3 arguments + */ + function displayXMLorXcos() { + var textarea = document.createElement('textarea'); + textarea.style.width = '400px'; + textarea.style.height = '400px'; + + var enc = new mxCodec(mxUtils.createXmlDocument()); + var node = enc.encode(diagRoot); + + var str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + mxUtils.getPrettyXml(node); + + textarea.value = str; + + if (arguments[2] == null) { + showModalWindow(graph, 'XML', textarea, 410, 440); + } else { + + return mxUtils.getPrettyXml(node); + } + } + + function getXcosDiagram(editor, cell) { + //Mind the 3 parameters. + var xmlFromExportXML = displayXMLorXcos(editor, cell, true); + if (xmlFromExportXML === null) + alert('First create the XML file.'); + else { + + var xml = mxUtils.parseXml(xmlFromExportXML); + + var xsl = loadXMLDoc("finalmodsheet.xsl"); + + xsltProcessor = new XSLTProcessor(); + xsltProcessor.importStylesheet(xsl); + resultDocument = xsltProcessor.transformToDocument(xml); + /* + Maverick + Using resultDocument.documentElement to remove an additional tag "<#document>" created by the XSLTProcessor. + */ + var str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n" + mxUtils.getPrettyXml(resultDocument.documentElement); + + str = str.replace(/\n\n/g, "\n"); + return str; + } + } + + // Defines a new export action + editor.addAction('exportXML', function (editor, cell) { + //Only two parameters passed here. + displayXMLorXcos(editor, cell); + }); + + /* Maverick + Reference: http://www.w3schools.com/xsl/xsl_client.asp + */ + + editor.addAction('exportXcos', function (editor, cell) { + var textarea = document.createElement('textarea'); + textarea.style.width = '400px'; + textarea.style.height = '400px'; + textarea.value = getXcosDiagram(editor, cell); + showModalWindow(graph, 'Xcos', textarea, 410, 440); + }); + + addToolbarButton(editor, toolbar, 'exportXML', 'Export XML', 'images/export1.png'); + addToolbarButton(editor, toolbar, 'exportXcos', 'Export Xcos', 'images/export1.png'); + + toolbar.appendChild(spacer.cloneNode(true)); + + addToolbarButton(editor, toolbar, 'simulate', 'Simulate', 'images/ScilabExecute.png'); + + editor.addAction('simulate', function (editor, cell) { + var diagram = getXcosDiagram(editor, cell); + + var blob = new Blob([diagram], {type: 'text/plain'}); + var xhr = new XMLHttpRequest(); + xhr.open('POST','ScilabServlet', true); + xhr.onload = function() { + // Create basic structure for the form + var content = document.createElement('div'); + content.setAttribute("id", "contentProperties"); + + // Heading of content + var heading = document.createElement('h2'); + heading.innerHTML = "Set Scope Parameters"; + heading.id = "headingProperties"; + content.appendChild(heading); + + var paragraph = document.createElement("p"); + paragraph.innerHTML = xhr.responseText; + content.appendChild(paragraph); + + + //var img = document.createElement("img"); + //img.src = "data:image/;base64,"+xhr.responseText; + //content.appendChild(img); + + var wind = showModalWindow(graph, 'Properties', content, 1000, 1000); + }; + xhr.onreadystatechange = function(){ + console.log("state: " + xhr.readyState); + }; + xhr.upload.onprogress = function() { + console.log("uploading..."); + }; + xhr.setRequestHeader("Content-Type", "text/plain"); + xhr.send(blob); + }); // Adds toolbar buttons into the status bar at the bottom // of the window. @@ -759,6 +1274,9 @@ */ function styleToObject(style) { + if(style.indexOf(';') == -1) { + style = style + ';'; + } var defaultStyle = style.substring(0, style.indexOf(';')); var styleObject = { @@ -1017,7 +1535,6 @@ var details = cell.blockInstance.instance.set(propertiesObject); //window[name]("set",cell.value,propertiesObject); var enc = new mxCodec(); var node = enc.encode(details); - node.setAttribute('label', getData(details.exprs)[0]); cell.value = node; /* Maverick @@ -1166,7 +1683,7 @@ var trigger = document.getElementById(button); var styleObject = styleToObject(style); var previousValue = 1; - if ('fontStyle' in styleObjesct) { + if ('fontStyle' in styleObject) { previousValue = styleObject['fontStyle']; // To get a bit mask: @@ -1494,7 +2011,11 @@ btn.onclick = function() { var input = document.getElementById('color').value; var style = graph.getModel().getStyle(cell); - var styleObject = styleToObject(style); + + if(style != null) { + var styleObject = styleToObject(style); + } + if (selectProperty == "edgeStrokeColor") { styleObject['strokeColor'] = input; } else if (selectProperty == "bgColor") { @@ -1506,8 +2027,12 @@ } else if (selectProperty == "edgeTextColor") { styleObject['fontColor'] = input; } - style = objectToStyle(styleObject); - graph.getModel().setStyle(cell, style); + + if(style != null) { + style = objectToStyle(styleObject); + graph.getModel().setStyle(cell, style); + } + wind.destroy(); }; myform.appendChild(btn); @@ -1559,10 +2084,6 @@ } } - function getImgHTML(name) { - return '<img src="' + 'blocks/' + name + '.svg' + '" height="80" width="80">'; - } - function addToolbarButton(editor, toolbar, action, label, image, isTransparent) { var button = document.createElement('button'); button.style.fontSize = '10'; @@ -1625,12 +2146,10 @@ var doc = mxUtils.createXmlDocument(); model.beginUpdate(); try { - var label = getImgHTML(name); // Will not exist for all blocks var details_instance = new window[name](); var details = details_instance.define(); var enc = new mxCodec(mxUtils.createXmlDocument()); var node = enc.encode(details); - node.setAttribute('label', label); var temp = enc.encode(parent); node.setAttribute('parent', temp.getAttribute('id')); var i, arr = []; @@ -1673,6 +2192,7 @@ } } v1 = graph.insertVertex(parent, null, node, x, y, 80, 80, name); + // @Chhavi: Additional attribute to store the block's instance v1.blockInstance = createInstanceTag(details_instance); createPorts(graph, v1, inputPorts, controlPorts, outputPorts, commandPorts); @@ -1801,6 +2321,13 @@ var root = req.getDocumentElement(); var dec = new mxCodec(root.ownerDocument); dec.decode(root, graph.stylesheet); + + // Set the width and height of image for all blocks to 80 (height) x 80 (width) + var style = new Object(); + style[mxConstants.STYLE_IMAGE_WIDTH] = '80'; + style[mxConstants.STYLE_IMAGE_HEIGHT] = '80'; + style['imageAlign'] = 'center'; + graph.getStylesheet().putDefaultVertexStyle(style); }; </script> <!-- @@ -1809,6 +2336,9 @@ <script type="text/javascript"> // Computes the position of edge to edge connection points. mxGraphView.prototype.updateFixedTerminalPoint = function(edge, terminal, source, constraint) { + + // Store the edge state for every newly created edge in edgeState variable + edgeState = edge; var pt = null; if (constraint != null) { @@ -2006,92 +2536,122 @@ Implements a perpendicular wires connection edge style --> <script type="text/javascript"> - mxEdgeStyle.WireConnector = function(state, source, target, hints, result) { - // Creates array of all way- and terminalpoints - var pts = state.absolutePoints; - var horizontal = true; - var hint = null; - - // Gets the initial connection from the source terminal or edge - if (source != null && state.view.graph.model.isEdge(source.cell)) { + mxEdgeStyle.WireConnector = function(state, source, target, hints, result) { + state.cell.waypoints = state.cell.geometry.points; + // Creates array of all way- and terminalpoints + var pts = state.absolutePoints; + var horizontal = true; + var hint = null; + + // Gets the initial connection from the source terminal or edge + if (source != null && state.view.graph.model.isEdge(source.cell)) { horizontal = state.style['sourceConstraint'] == 'horizontal'; - } else if (source != null) { - horizontal = source.style['portConstraint'] != 'vertical'; - - // Checks the direction of the shape and rotates - var direction = source.style[mxConstants.STYLE_DIRECTION]; - - if (direction == 'north' || direction == 'south') { - horizontal = !horizontal; - } - } - - // Adds the first point - var pt = pts[0]; - - if (pt == null && source != null) { - pt = new mxPoint(state.view.getRoutingCenterX(source), state.view.getRoutingCenterY(source)); - } else if (pt != null) { - pt = pt.clone(); - } - - var first = pt; - - // Adds the waypoints - if (hints != null && hints.length > 0) { - for (var i = 0; i < hints.length; i++) { - horizontal = !horizontal; - hint = state.view.transformControlPoint(state, hints[i]); - - if (horizontal) { - if (pt.y != hint.y) { - pt.y = hint.y; - result.push(pt.clone()); - } - } else if (pt.x != hint.x) { - pt.x = hint.x; - result.push(pt.clone()); - } - } - } else { - hint = pt; - } - - // Adds the last point - pt = pts[pts.length - 1]; - - if (pt == null && target != null) { - pt = new mxPoint(state.view.getRoutingCenterX(target), state.view.getRoutingCenterY(target)); + } + // If the source terminal is a Split Block, set the horizontal false + else if(source != null && source.cell.name == 'SPLIT_f') { + if(state.cell.source != null) { + // If the port is the third child of splitBlock, only then set the horizontal as false + if(state.cell.source == state.cell.source.parent.getChildAt(2)) { + horizontal = state.style['sourceConstraint'] == 'horizontal'; + } } - - if (horizontal) { - if (pt.y != hint.y && first.x != pt.x) { - result.push(new mxPoint(pt.x, hint.y)); - } - } else if (pt.x != hint.x && first.y != pt.y) { - result.push(new mxPoint(hint.x, pt.y)); + } + else if (source != null) { + horizontal = source.style['portConstraint'] != 'vertical'; + + // Checks the direction of the shape and rotates + var direction = source.style[mxConstants.STYLE_DIRECTION]; + + if (direction == 'north' || direction == 'south') { + horizontal = !horizontal; + } + } + + // Adds the first point + var pt = pts[0]; + + /* @jiteshjha splitBlock + */ + if(state.cell.getGeometry().getTerminalPoint(true) != null) { + source.cell['sourcePoint'] = state.cell.getGeometry().getTerminalPoint(true); + } + + if (pt == null && source != null) { + pt = new mxPoint(state.view.getRoutingCenterX(source), state.view.getRoutingCenterY(source)); + } else if (pt != null) { + pt = pt.clone(); + } + + var first = pt; + if(state.cell.getGeometry().getTerminalPoint(false) != null) { + target.cell['sourcePoint'] = state.cell.getGeometry().getTerminalPoint(false); + } + + // Adds the waypoints + if (hints != null && hints.length > 0) { + + + for (var i = 0; i < hints.length; i++) { + horizontal = !horizontal; + hint = state.view.transformControlPoint(state, hints[i]); + + if (horizontal) { + if (pt.y != hint.y) { + pt.y = hint.y; + result.push(pt.clone()); + } + } else if (pt.x != hint.x) { + pt.x = hint.x; + result.push(pt.clone()); + } + } + } else { + hint = pt; + } + + // Adds the last point + pt = pts[pts.length - 1]; + if (pt == null && target != null) { + pt = new mxPoint(state.view.getRoutingCenterX(target), state.view.getRoutingCenterY(target)); + + } + + if (horizontal) { + if (pt.y != hint.y && first.x != pt.x) { + result.push(new mxPoint(pt.x, hint.y)); + } + } else if (pt.x != hint.x && first.y != pt.y) { + result.push(new mxPoint(hint.x, pt.y)); + } + + // If the target of the edge is a splitBlock, push final coordinate as vertical. + if(state.cell.target != null) { + if(state.cell.target.parent.name == "SPLIT_f") { + result.pop(); + result.push(new mxPoint(hint.x, pt.y)); } - }; + } + }; - mxStyleRegistry.putValue('wireEdgeStyle', mxEdgeStyle.WireConnector); + mxStyleRegistry.putValue('wireEdgeStyle', mxEdgeStyle.WireConnector); - // This connector needs an mxEdgeSegmentHandler - mxGraphCreateHandler = mxGraph.prototype.createHandler; - mxGraph.prototype.createHandler = function(state) { - var result = null; + // This connector needs an mxEdgeSegmentHandler + mxGraphCreateHandler = mxGraph.prototype.createHandler; + mxGraph.prototype.createHandler = function(state) { + var result = null; - if (state != null) { - if (this.model.isEdge(state.cell)) { - var style = this.view.getEdgeStyle(state); + if (state != null) { + if (this.model.isEdge(state.cell)) { + var style = this.view.getEdgeStyle(state); - if (style == mxEdgeStyle.WireConnector) { - return new mxEdgeSegmentHandler(state); - } - } - } + if (style == mxEdgeStyle.WireConnector) { + return new mxEdgeSegmentHandler(state); + } + } + } - return mxGraphCreateHandler.apply(this, arguments); - }; + return mxGraphCreateHandler.apply(this, arguments); + }; </script> </head> @@ -2142,32 +2702,40 @@ </body> <!-- It's good if this part happens after the entire page has loaded--> <script type="text/javascript"> + // Preload all images - var dir = ["blocks", "images"]; - var fileextension = "."; - var blockImages = []; - $.each(dir, function(index, value) { - $.ajax({ // http://stackoverflow.com/a/18480589 - url: value, - success: function(data) { - $(data).find("a:contains(" + fileextension + ")").each(function() { - var filename = this.href.replace(window.location.host, ""); - filename = filename.replace("https://", value); - filename = filename.replace("http://", value); - blockImages.push(filename); - }); - // Prevent multi-threading and have function within call! - function preload(sources) { - var images = []; - for (var i = 0, length = sources.length; i < length; ++i) { - images[i] = new Image(); - images[i].src = sources[i]; - } + var directory = ["/blocks/", "/images/", "/palettes/"]; + for(folder in directory) { + $.ajax({ + type: "POST", + + // Invoke filenames.php + url: "filenames.php", + + // Receive the resultant filenames from the php script in JSON format + dataType: "json", + + // Add url for the required folder + data: { + url: directory[folder] + }, + success: function (data) { + function preload(sources) { + + /* + * @Parameter: sources will have the required filenames in the mentioned folder + * For each image url, make a new image to enable preloading + */ + for (i in sources) { + var image = new Image(); + image.src = sources[i]; } - preload(blockImages); } - }); - }); + preload(data); + } + }); + } + //Find out more here: http://stackoverflow.com/questions/12843418/jquery-ui-accordion-expand-collapse-all $(window).load(function() { var headers = $('#sidebarContainer .accordion-header'); |