diff --git a/widgets/package-lock.json b/widgets/package-lock.json index 681517a5..ca2d096d 100644 --- a/widgets/package-lock.json +++ b/widgets/package-lock.json @@ -1,6 +1,6 @@ { "name": "@rwth-acis/syncmeta-widgets", - "version": "1.1.0", + "version": "1.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/widgets/package.json b/widgets/package.json index 6fd2f79c..fe0e7fdf 100755 --- a/widgets/package.json +++ b/widgets/package.json @@ -1,7 +1,7 @@ { "name": "@rwth-acis/syncmeta-widgets", "description": "SyncMeta is a near real-time collaborative modeling framework. This package only contains the used widgets. If you want to use the SyncMeta app in a docker container, see https://github.com/rwth-acis/syncmeta.", - "version": "1.1.1", + "version": "1.3.0", "author": { "name": "ACIS Group, RWTH Aachen", "email": "acis@dbis.rwth-aachen.de" diff --git a/widgets/src/js/attribute_widget.js b/widgets/src/js/attribute_widget.js index d09081bf..2d348fe5 100755 --- a/widgets/src/js/attribute_widget.js +++ b/widgets/src/js/attribute_widget.js @@ -20,7 +20,7 @@ requirejs([ $('#wrapper').find('h1').text('Got Response from Canvas! Connecting to Yjs....'); var iwc = IWCW.getInstance(CONFIG.WIDGET.NAME.ATTRIBUTE); iwc.setSpace(user); - + yjsSync().done(function (y, spaceTitle) { window.y = y; window.syncmetaLog = { @@ -69,7 +69,7 @@ requirejs([ } for (nodeId in json.nodes) { if (json.nodes.hasOwnProperty(nodeId)) { - var node = EntityManager.createNodeFromJSON(json.nodes[nodeId].type, nodeId, json.nodes[nodeId].left, json.nodes[nodeId].top, json.nodes[nodeId].width, json.nodes[nodeId].height, json.nodes[nodeId]); + var node = EntityManager.createNodeFromJSON(json.nodes[nodeId].type, nodeId, json.nodes[nodeId].left, json.nodes[nodeId].top, json.nodes[nodeId].width, json.nodes[nodeId].height, json.nodes[nodeId].zIndex, json.nodes[nodeId]); node.registerYType(); node.addToWrapper(wrapper); } @@ -136,4 +136,4 @@ requirejs([ -}); \ No newline at end of file +}); diff --git a/widgets/src/js/attribute_widget/AbstractNode.js b/widgets/src/js/attribute_widget/AbstractNode.js index b5827569..af27a222 100755 --- a/widgets/src/js/attribute_widget/AbstractNode.js +++ b/widgets/src/js/attribute_widget/AbstractNode.js @@ -25,10 +25,11 @@ define([ * @param {number} top y-coordinate of node position * @param {number} width Width of node * @param {number} height Height of node + * @param {boolean} containment containment * @param {string} viewId the identifier of the view the node belongs to * @constructor */ - function AbstractNode(id, type, left, top, width, height, viewId) { + function AbstractNode(id, type, left, top, width, height, containment, viewId) { var that = this; AbstractEntity.call(this, id); @@ -47,6 +48,13 @@ define([ */ var _type = type; + /** + * Type of node + * @containment {boolean} + * @private + */ + var _containment = containment; + /** * Label of edge * @type {attribute_widget.SingleValueAttribute} @@ -284,6 +292,14 @@ define([ return _type; }; + /** + * Get edge type + * @returns {boolean} + */ + this.getContainment = function () { + return _containment; + }; + /** * Get jQuery object of DOM node representing the node * @returns {jQuery} @@ -515,11 +531,11 @@ define([ AbstractNode.prototype.registerYType = function () { this._registerYType(); }; - + AbstractNode.prototype.remove = function(){ this._remove(); } return AbstractNode; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/attribute_widget/AttributeWrapper.js b/widgets/src/js/attribute_widget/AttributeWrapper.js index 446ed2ef..56a5ad8f 100755 --- a/widgets/src/js/attribute_widget/AttributeWrapper.js +++ b/widgets/src/js/attribute_widget/AttributeWrapper.js @@ -88,9 +88,9 @@ define([ var json = operation.getJSON(); if (json) { - node = EntityManager.createNodeFromJSON(type, operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight(), operation.getJSON()); + node = EntityManager.createNodeFromJSON(type, operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight(), operation.getContainment(), operation.getJSON()); } else { - node = EntityManager.createNode(type, operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight()); + node = EntityManager.createNode(type, operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight(), operation.getContainment()); } node.addToWrapper(that); } @@ -194,7 +194,7 @@ define([ switch (nodeEvent.name) { case 'jabberId': { var map = nodeEvent.object; - nodeAddCallback(new NodeAddOperation(map.get('id'), map.get('type'), map.get('left'), map.get('top'), map.get('width'), map.get('height'), map.get('zIndex'), map.get('json'), null, null, nodeEvent.value)); + nodeAddCallback(new NodeAddOperation(map.get('id'), map.get('type'), map.get('left'), map.get('top'), map.get('width'), map.get('height'), map.get('zIndex'), map.get('containment'), map.get('json'), null, null, nodeEvent.value)); break; } default: @@ -296,4 +296,4 @@ define([ return AttributeWrapper; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/attribute_widget/EntityManager.js b/widgets/src/js/attribute_widget/EntityManager.js index 6d4cd2aa..d1c0c17d 100755 --- a/widgets/src/js/attribute_widget/EntityManager.js +++ b/widgets/src/js/attribute_widget/EntityManager.js @@ -122,7 +122,7 @@ define(['lodash', var viewEdgeTypes = {}; var _edges = {}; - + //noinspection JSUnusedGlobalSymbols return { /** @@ -137,9 +137,9 @@ define(['lodash', * @param {object} json the json representation of the node * @returns {attribute_widget.AbstractNode} */ - createNode : function (type, id, left, top, width, height,json) { + createNode : function (type, id, left, top, width, height, containment, json) { var node; - + if (viewNodeTypes.hasOwnProperty(type) && viewId) { node = viewNodeTypes[type](id, left, top, width, height, json); } @@ -240,7 +240,7 @@ define(['lodash', */ createEdge : function (type, id, source, target) { var edge; - + if(viewId && viewEdgeTypes.hasOwnProperty(type)){ edge = viewEdgeTypes[type](id, source, target); } @@ -317,8 +317,8 @@ define(['lodash', * @param {object} json JSON representation * @returns {attribute_widget.AbstractNode} */ - createNodeFromJSON : function (type, id, left, top, width, height, json) { - var node = this.createNode(type, id, left, top, width, height, json); + createNodeFromJSON : function (type, id, left, top, width, height, containment, json) { + var node = this.createNode(type, id, left, top, width, height, containment, json); if (node) { node.getLabel().getValue().setValue(json.label.value.value); for (var attrId in json.attributes) { diff --git a/widgets/src/js/attribute_widget/NodeShapeNode.js b/widgets/src/js/attribute_widget/NodeShapeNode.js index f1e6f755..5c5bbabd 100755 --- a/widgets/src/js/attribute_widget/NodeShapeNode.js +++ b/widgets/src/js/attribute_widget/NodeShapeNode.js @@ -3,13 +3,14 @@ define([ 'jsplumb', 'lodash', 'attribute_widget/AbstractNode', + 'attribute_widget/BooleanAttribute', 'attribute_widget/SingleSelectionAttribute', 'attribute_widget/SingleValueAttribute', 'attribute_widget/IntegerAttribute', 'attribute_widget/SingleColorValueAttribute', 'attribute_widget/SingleCodeEditorValueAttribute', 'text!templates/attribute_widget/node_shape_node.html' -],/** @lends NodeShapeNode */function($,jsPlumb,_,AbstractNode,SingleSelectionAttribute,SingleValueAttribute,IntegerAttribute,SingleColorValueAttribute,SingleCodeEditorValueAttribute,nodeShapeNodeHtml) { +],/** @lends NodeShapeNode */function($,jsPlumb,_,AbstractNode,BooleanAttribute,SingleSelectionAttribute,SingleValueAttribute,IntegerAttribute,SingleColorValueAttribute,SingleCodeEditorValueAttribute,nodeShapeNodeHtml) { NodeShapeNode.TYPE = "Node Shape"; @@ -26,12 +27,13 @@ define([ * @param {number} top y-coordinate of node position * @param {number} width Width of node * @param {number} height Height of node + * @param {boolean} containment Height of node */ - function NodeShapeNode(id,left,top,width,height){ + function NodeShapeNode(id,left,top,width,height,containment){ var that = this; - AbstractNode.call(this,id,NodeShapeNode.TYPE,left,top,width,height); + AbstractNode.call(this,id,NodeShapeNode.TYPE,left,top,width,height,containment); /** * jQuery object of node template @@ -65,6 +67,7 @@ define([ this.addAttribute(new SingleColorValueAttribute(this.getEntityId()+"[color]","Color",this)); this.addAttribute(new IntegerAttribute(this.getEntityId()+"[defaultWidth]","Default Width",this)); this.addAttribute(new IntegerAttribute(this.getEntityId()+"[defaultHeight]","Default Height",this)); + this.addAttribute(new BooleanAttribute(this.getEntityId()+"[containment]","Containment",this)); this.addAttribute(new SingleCodeEditorValueAttribute(this.getEntityId()+"[customShape]","Custom Shape",this)); this.addAttribute(new SingleValueAttribute(this.getEntityId()+"[customAnchors]","Custom Anchors",this)); @@ -92,4 +95,4 @@ define([ return NodeShapeNode; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/AbstractClassNode.js b/widgets/src/js/canvas_widget/AbstractClassNode.js index 4f894e95..9fd8503a 100755 --- a/widgets/src/js/canvas_widget/AbstractClassNode.js +++ b/widgets/src/js/canvas_widget/AbstractClassNode.js @@ -80,11 +80,11 @@ define([ that.getLabel().getValue().registerYType(); attr.registerYMap(); }; - + this.unregisterCallbacks = function(){ that.getAttribute('[attributes]').unregisterCallbacks(); } - + _$node.find(".label").append(this.getLabel().get$node()); for(var attributeKey in _attributes){ @@ -106,7 +106,7 @@ define([ nodeId; //noinspection JSAccessibilityCheck - nodeId = canvas.createNode(require('canvas_widget/ObjectNode').TYPE,appearance.left,appearance.top,appearance.width,appearance.height,that.getZIndex(),that.toJSON()); + nodeId = canvas.createNode(require('canvas_widget/ObjectNode').TYPE,appearance.left,appearance.top,appearance.width,appearance.height,that.getZIndex(),that.getContainment(),that.toJSON()); var edges = that.getOutgoingEdges(), edge, edgeId; @@ -141,7 +141,7 @@ define([ nodeId; //noinspection JSAccessibilityCheck - nodeId = canvas.createNode(require('canvas_widget/RelationshipNode').TYPE,appearance.left,appearance.top,appearance.width,appearance.height,that.getZIndex(),that.toJSON()); + nodeId = canvas.createNode(require('canvas_widget/RelationshipNode').TYPE,appearance.left,appearance.top,appearance.width,appearance.height,that.getZIndex(),that.getContainment(),that.toJSON()); var edges = that.getOutgoingEdges(), edge, edgeId; @@ -176,7 +176,7 @@ define([ nodeId; //noinspection JSAccessibilityCheck - nodeId = canvas.createNode(require('canvas_widget/RelationshipGroupNode').TYPE,appearance.left,appearance.top,appearance.width,appearance.height,that.getZIndex(),that.toJSON()); + nodeId = canvas.createNode(require('canvas_widget/RelationshipGroupNode').TYPE,appearance.left,appearance.top,appearance.width,appearance.height,that.getZIndex(),that.getContainment(),that.toJSON()); var edges = that.getOutgoingEdges(), edge, edgeId; @@ -214,4 +214,4 @@ define([ return AbstractClassNode; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/AbstractClassNodeTool.js b/widgets/src/js/canvas_widget/AbstractClassNodeTool.js index 6cba5d19..231240af 100755 --- a/widgets/src/js/canvas_widget/AbstractClassNodeTool.js +++ b/widgets/src/js/canvas_widget/AbstractClassNodeTool.js @@ -15,9 +15,9 @@ define([ * @constructor */ function AbstractClassNodeTool(){ - NodeTool.call(this,AbstractClassNode.TYPE,null,null,AbstractClassNode.DEFAULT_WIDTH,AbstractClassNode.DEFAULT_HEIGHT); + NodeTool.call(this,AbstractClassNode.TYPE,null,null,null,AbstractClassNode.DEFAULT_WIDTH,AbstractClassNode.DEFAULT_HEIGHT); } return AbstractClassNodeTool; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/AbstractNode.js b/widgets/src/js/canvas_widget/AbstractNode.js index 11966404..8814561c 100755 --- a/widgets/src/js/canvas_widget/AbstractNode.js +++ b/widgets/src/js/canvas_widget/AbstractNode.js @@ -32,9 +32,12 @@ define([ * @param {number} top y-coordinate of node position * @param {number} width Width of node * @param {number} height Height of node + * @param {boolean} containment containment * @param {number} zIndex Position of node on z-axis */ - function AbstractNode(id, type, left, top, width, height, zIndex, json) { + function AbstractNode(id, type, left, top, width, height, zIndex, containment, json) { + + var that = this; /** @@ -59,6 +62,7 @@ define([ _ymap.set('width', width); _ymap.set('height', height); _ymap.set('zIndex', zIndex); + _ymap.set('containment', containment); _ymap.set('type', type); _ymap.set('id', id); if(json) _ymap.set('json', json); @@ -93,7 +97,8 @@ define([ left: left, top: top, width: width, - height: height + height: height, + containment: containment }; /** @@ -103,6 +108,13 @@ define([ */ var _zIndex = zIndex; + /** + * Type of node + * @containment {boolean} + * @private + */ + var _containment = containment; + /** * Canvas the node is drawn on * @type {canvas_widget.AbstractCanvas} @@ -416,6 +428,7 @@ define([ }; this.init = function () { + //Define Node Rightclick Menu $.contextMenu({ selector: "#" + id, @@ -520,7 +533,7 @@ define([ edge.triggerDeletion(); } } - var operation = new NodeDeleteOperation(id, that.getType(), _appearance.left, _appearance.top, _appearance.width, _appearance.height, _zIndex, that.toJSON()); + var operation = new NodeDeleteOperation(id, that.getType(), _appearance.left, _appearance.top, _appearance.width, _appearance.height, _zIndex, _appearance.containment, that.toJSON()); if (_ymap) { propagateNodeDeleteOperation(operation); y.share.nodes.delete(that.getEntityId()); @@ -566,7 +579,7 @@ define([ this.getZIndex = function () { return _zIndex; }; - + this.refreshTraceAwareness = function (color) { refreshTraceAwareness(color); }; @@ -675,6 +688,14 @@ define([ return _type; }; + /** + * Get edge type + * @returns {boolean} + */ + this.getContainment = function () { + return _containment; + }; + /** * Get jQuery object of DOM node representing the node * @returns {jQuery} @@ -1018,12 +1039,73 @@ define([ top: 0 }; + var lastDragPos = { + left: 0, + top: 0 + }; + //Enable Node Selection var drag = false; var $sizePreview = $("
").hide(); - _$node.on("click", function () { + var clickedNode = _$node.on("click", function () { _canvas.select(that); - }) + }); + + if(that.getContainment()) { + clickedNode.droppable({ + hoverClass: 'selected', + drop: function (event, ui) { + const EntityManager = require('canvas_widget/EntityManager'); + + var containerNode = EntityManager.getNodes()[$(this).attr("id")]; + var childNode = EntityManager.getNodes()[ui.draggable.attr("id")]; + var relations = EntityManager.getRelations(); + + var isConnected = false; + var relationshipType = null; + + _.each(containerNode.getOutgoingEdges(), function(edge) { + if(edge.getTarget().getEntityId() === childNode.getEntityId()) { + isConnected = true; + return false; + } + }); + + _.each(relations, function(relation, key) { + + _.each(relation, function(r) { + _.each(r.sourceTypes, function(source) { + if (containerNode.getType() === source) { + _.each(r.targetTypes, function(target) { + if (childNode.getType() === target) { + relationshipType = key + return false; + } + }); + } + }); + }); + }); + + if(!isConnected && relationshipType){ + _canvas.createEdge(relationshipType,$(this).attr("id"), ui.draggable.attr("id")); + } + + // // now, the attributes left and top of the node are not related to the top left corner of the + // // canvas anymore, but instead they are related to the top left corner of the parent element + // // => move node to correct left and right attribute + // const EntityManager = require('canvas_widget/EntityManager'); + // + // const containerLeft = that.getAppearance().left; + // const containerTop = that.getAppearance().top; + // + // const operation = new NodeMoveOperation(ui.draggable.attr("id"), -containerLeft, -containerTop); + // EntityManager.getNodes()[ui.draggable.attr("id")].propagateNodeMoveOperation(operation); + } + }); + } + + clickedNode //Enable Node Resizing .resizable({ containment: "parent", @@ -1053,7 +1135,7 @@ define([ that.propagateNodeResizeOperation(operation); _$node.resizable("option", "aspectRatio", false); _$node.resizable("option", "grid", ''); - + //TODO: check that! Already called in processNodeResizeOperation called by propagateNodeResizeOperation //_canvas.showGuidanceBox(); } @@ -1063,8 +1145,14 @@ define([ .draggable({ containment: 'parent', start: function (ev, ui) { + originalPos.top = ui.position.top; originalPos.left = ui.position.left; + + lastDragPos.top = ui.position.top; + lastDragPos.left = ui.position.left; + + //ui.position.top = 0; //ui.position.left = 0; _canvas.select(that); @@ -1074,10 +1162,27 @@ define([ drag = false; _$node.draggable("option", "grid", ev.ctrlKey ? [20, 20] : ''); }, - drag: function (ev) { + drag: function (ev, ui) { // ui.position.left = Math.round(ui.position.left / _canvas.getZoom()); // ui.position.top = Math.round(ui.position.top / _canvas.getZoom()); + var offsetX = Math.round((ui.position.left - lastDragPos.left) / _canvas.getZoom()); + var offsetY = Math.round((ui.position.top - lastDragPos.top) / _canvas.getZoom()); + + function setChildPosition(node) { + if(node.getContainment()) { + _.each(node.getOutgoingEdges(), function(edge){ + $('#' + edge.getTarget().getEntityId()).offset({ top: $('#' + edge.getTarget().getEntityId()).offset().top + offsetY, left: $('#' + edge.getTarget().getEntityId()).offset().left + offsetX}); + setChildPosition(edge.getTarget()) + }); + } + } + + setChildPosition(that); + + lastDragPos.top = ui.position.top; + lastDragPos.left = ui.position.left; + if (drag) repaint(); drag = true; @@ -1091,9 +1196,22 @@ define([ //_$node.css({top: originalPos.top / _canvas.getZoom(), left: originalPos.left / _canvas.getZoom()}); var offsetX = Math.round((ui.position.left - originalPos.left) / _canvas.getZoom()); var offsetY = Math.round((ui.position.top - originalPos.top) / _canvas.getZoom()); - var operation = new NodeMoveOperation(id, offsetX, offsetY); + + var operation = new NodeMoveOperation(that.getEntityId(), offsetX, offsetY); that.propagateNodeMoveOperation(operation); + function propagateChildPosition(node) { + if(node.getContainment()) { + _.each(node.getOutgoingEdges(), function(edge){ + var operation = new NodeMoveOperation(edge.getTarget().getEntityId(), offsetX, offsetY); + edge.getTarget().propagateNodeMoveOperation(operation); + propagateChildPosition(edge.getTarget()) + }); + } + } + + propagateChildPosition(that); + //Avoid node selection on drag stop _$node.draggable("option", "grid", ''); _canvas.showGuidanceBox(); @@ -1270,4 +1388,4 @@ define([ return AbstractNode; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/Canvas.js b/widgets/src/js/canvas_widget/Canvas.js index 5483c2d2..f321e10b 100755 --- a/widgets/src/js/canvas_widget/Canvas.js +++ b/widgets/src/js/canvas_widget/Canvas.js @@ -137,11 +137,13 @@ define([ var processNodeAddOperation = function (operation) { var node; if (operation.getJSON()) { - node = EntityManager.createNodeFromJSON(operation.getType(), operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight(), operation.getZIndex(), operation.getJSON()); + node = EntityManager.createNodeFromJSON(operation.getType(), operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight(), operation.getZIndex(), operation.getContainment(), operation.getJSON()); } else { - node = EntityManager.createNode(operation.getType(), operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight(), operation.getZIndex()); + node = EntityManager.createNode(operation.getType(), operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight(), operation.getZIndex(), operation.getContainment()); } + console.log(node.getContainment()); + if (operation.getDefaultLabel()) { node.getLabel().getValue().setValue(operation.getDefaultLabel()); } @@ -264,9 +266,9 @@ define([ //processNodeAddOperation if (operation.getJSON()) { - node = EntityManager.createNodeFromJSON(type, operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight(), operation.getZIndex(), operation.getJSON()); + node = EntityManager.createNodeFromJSON(type, operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight(), operation.getZIndex(), operation.getContainment(), operation.getJSON()); } else { - node = EntityManager.createNode(type, operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight(), operation.getZIndex()); + node = EntityManager.createNode(type, operation.getEntityId(), operation.getLeft(), operation.getTop(), operation.getWidth(), operation.getHeight(), operation.getZIndex(), operation.getContainment()); } if (operation.getDefaultLabel()) { @@ -864,12 +866,13 @@ define([ * @param {number} width Width of node * @param {number} height Height of node * @param {number} [zIndex] Position of node on z-axis + * @param {boolean} containment containment * @param {object} [json] representation of node * @param {string} identifier the identifier of the node, if null a new id is generated * @param defaultAttributeValues May be used to set default values for node attributes. * @return {number} id of new node */ - this.createNode = function (type, left, top, width, height, zIndex, json, identifier, historyFlag, defaultLabel, defaultAttributeValues) { + this.createNode = function (type, left, top, width, height, zIndex, containment, json, identifier, historyFlag, defaultLabel, defaultAttributeValues) { var id, oType = null; if (identifier) id = identifier; @@ -880,7 +883,8 @@ define([ if (EntityManager.getViewId() !== undefined && EntityManager.getLayer() === CONFIG.LAYER.MODEL) { oType = EntityManager.getViewNodeType(type).getTargetNodeType().TYPE; } - var operation = new NodeAddOperation(id, type, left, top, width, height, zIndex, json || null, EntityManager.getViewId(), oType, _iwcw.getUser()[CONFIG.NS.PERSON.JABBERID], defaultLabel, defaultAttributeValues); + + var operation = new NodeAddOperation(id, type, left, top, width, height, zIndex, containment, json || null, EntityManager.getViewId(), oType, _iwcw.getUser()[CONFIG.NS.PERSON.JABBERID], defaultLabel, defaultAttributeValues); propagateNodeAddOperation(operation); if (y) { @@ -1302,7 +1306,7 @@ define([ switch (event.name) { case NodeAddOperation.TYPE: { - operation = new NodeAddOperation(data.id, data.type, data.left, data.top, data.width, data.height, data.zIndex, data.json, data.viewId, data.oType, jabberId || data.jabberId, data.defaultLabel, data.defaultAttributeValues); + operation = new NodeAddOperation(data.id, data.type, data.left, data.top, data.width, data.height, data.zIndex, data.containment, data.json, data.viewId, data.oType, jabberId || data.jabberId, data.defaultLabel, data.defaultAttributeValues); remoteNodeAddCallback(operation); break; } @@ -1336,7 +1340,7 @@ define([ } case 'applyLayout':{ //remote user - DagreLayout.apply(); + DagreLayout.apply(); break; } //used by the syncmeta-plugin only @@ -1366,7 +1370,7 @@ define([ entity.highlight(event.value.color, event.value.label); } } - + break; } //used by the syncmeta-plugin only @@ -1399,8 +1403,8 @@ define([ } //local user. todo ugly coding style } else if(event.name === "applyLayout"){ - DagreLayout.apply(); - $('#save').click(); + DagreLayout.apply(); + $('#save').click(); } }); @@ -1429,7 +1433,7 @@ define([ { var node = EntityManager.findNode(event.name); if (node) - node.remoteNodeDeleteCallback(new NodeDeleteOperation(event.name)); + node.remoteNodeDeleteCallback(new NodeDeleteOperation(event.name)); break; } /* diff --git a/widgets/src/js/canvas_widget/EdgeShapeNodeTool.js b/widgets/src/js/canvas_widget/EdgeShapeNodeTool.js index bea1c619..079c4634 100755 --- a/widgets/src/js/canvas_widget/EdgeShapeNodeTool.js +++ b/widgets/src/js/canvas_widget/EdgeShapeNodeTool.js @@ -15,9 +15,9 @@ define([ * @constructor */ function EdgeShapeNodeTool(){ - NodeTool.call(this,EdgeShapeNode.TYPE,null,null,EdgeShapeNode.DEFAULT_WIDTH,EdgeShapeNode.DEFAULT_HEIGHT); + NodeTool.call(this,EdgeShapeNode.TYPE,null,null,null,EdgeShapeNode.DEFAULT_WIDTH,EdgeShapeNode.DEFAULT_HEIGHT); } return EdgeShapeNodeTool; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/EntityManager.js b/widgets/src/js/canvas_widget/EntityManager.js index 546087b6..ab6493fc 100755 --- a/widgets/src/js/canvas_widget/EntityManager.js +++ b/widgets/src/js/canvas_widget/EntityManager.js @@ -149,6 +149,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation _nodeTypes[node.label].TYPE = node.label; _nodeTypes[node.label].DEFAULT_WIDTH = node.shape.defaultWidth; _nodeTypes[node.label].DEFAULT_HEIGHT = node.shape.defaultHeight; + _nodeTypes[node.label].CONTAINMENT = node.shape.containment; _nodeTypes[node.label].SHAPE = $shape; /* nodeTypes[node.label] = Node(node.label, $shape, anchors, node.attributes, node.jsplumb); @@ -287,16 +288,16 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation * @param {object} json the json representation * @returns {canvas_widget.AbstractNode} */ - createNode : function (type, id, left, top, width, height, zIndex,json) { + createNode : function (type, id, left, top, width, height, zIndex, containment, json) { var node; AbstractEntity.maxZIndex = Math.max(AbstractEntity.maxZIndex, zIndex); AbstractEntity.minZIndex = Math.min(AbstractEntity.minZIndex, zIndex); - + if(_viewId && viewNodeTypes.hasOwnProperty(type)){ - node = viewNodeTypes[type](id, left, top, width, height, zIndex, json); + node = viewNodeTypes[type](id, left, top, width, height, zIndex, containment, json); } else if(nodeTypes.hasOwnProperty(type)) { - node = new nodeTypes[type](id, left, top, width, height, zIndex, json); + node = new nodeTypes[type](id, left, top, width, height, zIndex, containment, json); } _nodes[id] = node; return node; @@ -391,7 +392,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation //TODO: switch id and type createEdge: function(type,id,source,target){ var edge; - + if(_viewId && viewEdgeTypes.hasOwnProperty(type)){ edge = viewEdgeTypes[type](id,source,target); } @@ -514,8 +515,8 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation * @param {number} zIndex Position of node on z-axis * @returns {canvas_widget.AbstractNode} */ - createNodeFromJSON: function(type,id,left,top,width,height,zIndex,json){ - var node = this.createNode(type,id,left,top,width,height,zIndex,json); + createNodeFromJSON: function(type,id,left,top,width,height,zIndex,containment,json){ + var node = this.createNode(type,id,left,top,width,height,zIndex,containment,json); if(node){ node.getLabel().getValue().setValue(json.label.value.value); for(var attrId in json.attributes){ @@ -569,9 +570,9 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation * @returns {object} Menu items */ generateAddNodeMenu: function(canvas,left,top){ - function makeAddNodeCallback(nodeType,width,height){ + function makeAddNodeCallback(nodeType,width,height,containment){ return function(){ - canvas.createNode(nodeType,left,top,width,height); + canvas.createNode(nodeType,left,top,width,height,that.getZIndex(),containment); }; } var items = {}, @@ -594,7 +595,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation items[nodeType] = { name: '..' + nodeType, - callback: makeAddNodeCallback(nodeType,_nodeTypes[nodeType].DEFAULT_WIDTH,_nodeTypes[nodeType].DEFAULT_HEIGHT) + callback: makeAddNodeCallback(nodeType,_nodeTypes[nodeType].DEFAULT_WIDTH,_nodeTypes[nodeType].DEFAULT_HEIGHT,_nodeTypes[nodeType].CONTAINMENT) }; } } @@ -840,6 +841,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation color: "", defaultWidth: 200, defaultHeight: 60, + containment: false, customShape: startActivityNodeHtml, customAnchors: "" }, @@ -863,6 +865,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation color: "", defaultWidth: 50, defaultHeight: 50, + containment: false, customShape: activityFinalNodeHtml, customAnchors: [ "Perimeter", { shape:"Circle", anchorCount: 60} ] }, @@ -880,6 +883,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation color: "yellow", defaultWidth: 0, defaultHeight: 0, + containment: false, customShape: "", customAnchors: "" }, @@ -897,6 +901,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation color: "", defaultWidth: 100, defaultHeight: 50, + containment: false, customShape: callActivityNodeHtml, customAnchors: "" }, @@ -922,6 +927,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation color: "black", defaultWidth: 10, defaultHeight: 200, + containment: false, customShape: "", customAnchors: "" }, @@ -960,6 +966,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation color: "", defaultWidth: 100, defaultHeight: 50, + containment: false, customShape: _.template(actionNodeHtml)({label: node.label, icon: "plus"}), customAnchors: "" } @@ -979,6 +986,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation color: "", defaultWidth: 100, defaultHeight: 50, + containment: false, customShape: _.template(entityNodeHtml)({icon: "square", label: node.label}), customAnchors: "" } @@ -995,6 +1003,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation shape: "", defaultWidth: 130, defaultHeight: 50, + containment: false, customShape: _.template(setPropertyNodeHtml)(), customAnchors: "" } @@ -1067,6 +1076,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation color: "", defaultWidth: 100, defaultHeight: 50, + containment: false, customShape: _.template(actionNodeHtml)({label: edge.label, icon: "plus"}), customAnchors: "" } @@ -1086,6 +1096,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation color: "blue", defaultWidth: 100, defaultHeight: 50, + containment: false, customShape: _.template(entityNodeHtml)({icon: "exchange", label: edge.label}), customAnchors: "" } @@ -1105,6 +1116,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation shape: "", defaultWidth: 0, defaultHeight: 0, + containment: false, customShape: _.template(setPropertyNodeHtml)({type: setPropertyLabel, color: "white"}), customAnchors: "" } @@ -1225,9 +1237,9 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation var model; if(m) model = m; - else + else model = y.share.data.get('guidancemodel'); - if(!model) + if(!model) return null; var nodes = model.nodes; var edges = model.edges; @@ -1633,6 +1645,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation color: neighbor.getAttribute(neighbor.getEntityId()+"[color]").getValue().getValue(), defaultWidth: parseInt(neighbor.getAttribute(neighbor.getEntityId()+"[defaultWidth]").getValue().getValue()), defaultHeight: parseInt(neighbor.getAttribute(neighbor.getEntityId()+"[defaultHeight]").getValue().getValue()), + containment: neighbor.getAttribute(neighbor.getEntityId()+"[containment]").getValue().getValue(), customShape: neighbor.getAttribute(neighbor.getEntityId()+"[customShape]").getValue().getValue(), customAnchors: neighbor.getAttribute(neighbor.getEntityId()+"[customAnchors]").getValue().getValue() }; @@ -1642,7 +1655,7 @@ function (_, Util, AbstractEntity, Node, ObjectNode, AbstractClassNode, Relation metamodel.nodes[nodeId] = { label: node.getLabel().getValue().getValue(), attributes: attributes, - shape: shape || {shape: "rectangle", color: "white", customShape: "", customAnchors: "", defaultWidth: 0, defaultHeight: 0} + shape: shape || {shape: "rectangle", color: "white", containment: false, customShape: "", customAnchors: "", defaultWidth: 0, defaultHeight: 0} }; } } else if(node instanceof RelationshipNode){ diff --git a/widgets/src/js/canvas_widget/EnumNodeTool.js b/widgets/src/js/canvas_widget/EnumNodeTool.js index 84bd2f8d..34f8e7c7 100755 --- a/widgets/src/js/canvas_widget/EnumNodeTool.js +++ b/widgets/src/js/canvas_widget/EnumNodeTool.js @@ -16,9 +16,9 @@ define([ * @constructor */ function EnumNodeTool(){ - NodeTool.call(this,EnumNode.TYPE,null,null,EnumNode.DEFAULT_WIDTH,EnumNode.DEFAULT_HEIGHT); + NodeTool.call(this,EnumNode.TYPE,null,null,null,EnumNode.DEFAULT_WIDTH,EnumNode.DEFAULT_HEIGHT); } return EnumNodeTool; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/GenerateViewpointModel.js b/widgets/src/js/canvas_widget/GenerateViewpointModel.js index f34f83e6..69f6a839 100755 --- a/widgets/src/js/canvas_widget/GenerateViewpointModel.js +++ b/widgets/src/js/canvas_widget/GenerateViewpointModel.js @@ -21,7 +21,7 @@ define(['Util', for(var node_key in viewpointModel.nodes){ if(viewpointModel.nodes.hasOwnProperty(node_key)){ var vpNode = viewpointModel.nodes[node_key]; - EntityManager.createNodeFromJSON(vpNode.type, node_key, vpNode.left, vpNode.top, vpNode.widget, vpNode.height, vpNode.zIndex, vpNode); + EntityManager.createNodeFromJSON(vpNode.type, node_key, vpNode.left, vpNode.top, vpNode.widget, vpNode.height, vpNode.zIndex, vpNode.containment, vpNode); } } @@ -288,6 +288,7 @@ define(['Util', color : neighbor.getAttribute(neighbor.getEntityId() + "[color]").getValue().getValue(), defaultWidth : parseInt(neighbor.getAttribute(neighbor.getEntityId() + "[defaultWidth]").getValue().getValue()), defaultHeight : parseInt(neighbor.getAttribute(neighbor.getEntityId() + "[defaultHeight]").getValue().getValue()), + containment : neighbor.getAttribute(neighbor.getEntityId() + "[containment]").getValue().getValue(), customShape : neighbor.getAttribute(neighbor.getEntityId() + "[customShape]").getValue().getValue(), customAnchors : neighbor.getAttribute(neighbor.getEntityId() + "[customAnchors]").getValue().getValue() }; @@ -301,6 +302,7 @@ define(['Util', shape : shape || { shape : "rectangle", color : "white", + containment: false, customShape : "", customAnchors : "", defaultWidth : 0, diff --git a/widgets/src/js/canvas_widget/HistoryManager.js b/widgets/src/js/canvas_widget/HistoryManager.js index 28aee51c..f97506d1 100755 --- a/widgets/src/js/canvas_widget/HistoryManager.js +++ b/widgets/src/js/canvas_widget/HistoryManager.js @@ -8,15 +8,15 @@ define(['jqueryui', 'operations/ot/NodeResizeOperation' ], function($, NodeAddOperation, EdgeAddOperation, NodeDeleteOperation, EdgeDeleteOperation, NodeMoveOperation, NodeMoveZOperation, NodeResizeOperation) { function HistoryManager() { - + var bufferSize = 20; - + var _canvas = null; - var latestOp = null; + var latestOp = null; var undo = []; var redo = []; - + var $undo = $('#undo'); var $redo = $('#redo'); @@ -29,14 +29,14 @@ define(['jqueryui', entity = EntityManager.findNode(json.id); if (entity) { entity.triggerDeletion(true); - operation = new NodeDeleteOperation(json.id, json.type, json.left, json.top, json.width, json.height, json.zIndex, json.json); + operation = new NodeDeleteOperation(json.id, json.type, json.left, json.top, json.width, json.height, json.zIndex, json.containment, json.json); } break; } case NodeAddOperation.TYPE: { - _canvas.createNode(json.type, json.left, json.top, json.width, json.height, json.zIndex, json.json, json.id, true); - operation = new NodeAddOperation(json.id, json.type, json.left, json.top, json.width, json.height, json.zIndex, json.json); + _canvas.createNode(json.type, json.left, json.top, json.width, json.height, json.zIndex, json.containment, json.json, json.id, true); + operation = new NodeAddOperation(json.id, json.type, json.left, json.top, json.width, json.height, json.zIndex, json.containment, json.json); break; } case EdgeAddOperation.TYPE: { @@ -48,7 +48,7 @@ define(['jqueryui', entity = EntityManager.findEdge(json.id); if (entity) { entity.triggerDeletion(true); - operation = new EdgeDeleteOperation(json.id, json.type, json.source, json.target, json.json); + operation = new EdgeDeleteOperation(json.id, json.type, json.source, json.target, json.json); } break; } @@ -71,7 +71,7 @@ define(['jqueryui', data = operation.toJSON(); data.historyFlag = true; ymap.set(NodeMoveZOperation.TYPE, data); - + } break; } @@ -83,7 +83,7 @@ define(['jqueryui', data = operation.toJSON(); data.historyFlag = true; ymap.set(NodeResizeOperation.TYPE, data); - + } break; } @@ -93,7 +93,7 @@ define(['jqueryui', return { init:function(canvas){ - _canvas = canvas; + _canvas = canvas; }, add: function(operation) { if (operation.hasOwnProperty('inverse')) { @@ -120,7 +120,7 @@ define(['jqueryui', this.undo(); return; } else latestOp = operation; - + var inverseOp = operation.inverse(); var json = inverseOp.toJSON(); json.TYPE = inverseOp.constructor.name; @@ -171,7 +171,7 @@ define(['jqueryui', if (redo.length === 0) { $redo.prop('disabled', true); } - + }, getLatestOperation: function(){ return latestOp; @@ -185,4 +185,4 @@ define(['jqueryui', } } return new HistoryManager(); -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/JSONtoGraph.js b/widgets/src/js/canvas_widget/JSONtoGraph.js index 81902dd6..cfc67dc9 100755 --- a/widgets/src/js/canvas_widget/JSONtoGraph.js +++ b/widgets/src/js/canvas_widget/JSONtoGraph.js @@ -41,14 +41,15 @@ define(['jquery', 'lodash', 'canvas_widget/EntityManager'], function ($, _, Enti jsonNode.type, nodeId, map.get('left') ? map.get('left') : jsonNode.left, map.get('top') ? map.get('top') : jsonNode.top, map.get('width') ? map.get('width') : jsonNode.width, map.get('height') ? map.get('height') : jsonNode.height, - map.get('zIndex') ? map.get('zIndex') : jsonNode.zIndex, jsonNode); + map.get('zIndex') ? map.get('zIndex') : jsonNode.zIndex, map.get('containment') ? map.get('containment') : jsonNode.containment, jsonNode); } else { node = EntityManager.createNodeFromJSON( jsonNode.type, nodeId, jsonNode.left, jsonNode.top, jsonNode.width, jsonNode.height, - jsonNode.zIndex, jsonNode); + jsonNode.zIndex, jsonNode.containment, + jsonNode); } @@ -127,4 +128,4 @@ define(['jquery', 'lodash', 'canvas_widget/EntityManager'], function ($, _, Enti } return report; } -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/Node.js b/widgets/src/js/canvas_widget/Node.js index d9beadbf..00a38fdb 100755 --- a/widgets/src/js/canvas_widget/Node.js +++ b/widgets/src/js/canvas_widget/Node.js @@ -6,7 +6,7 @@ define([ 'canvas_widget/BooleanAttribute', 'canvas_widget/IntegerAttribute', 'canvas_widget/FileAttribute', - 'canvas_widget/QuizAttribute', + 'canvas_widget/QuizAttribute', 'canvas_widget/SingleSelectionAttribute', 'canvas_widget/SingleValueAttribute' ],/** @lends makeNode */function($,jsPlumb,_,AbstractNode,BooleanAttribute,IntegerAttribute,FileAttribute,QuizAttribute,SingleSelectionAttribute,SingleValueAttribute) { @@ -38,11 +38,12 @@ define([ * @param {number} width Width of node * @param {number} height Height of node * @param {number} zIndex Position of node on z-axis + * @param {boolean} containment containment */ - function Node(id,left,top,width,height,zIndex){ + function Node(id,left,top,width,height,zIndex,containment){ var that = this; - AbstractNode.call(this,id,type,left,top,width,height,zIndex); + AbstractNode.call(this,id,type,left,top,width,height,zIndex,containment); var currentViewType = null; @@ -102,7 +103,7 @@ define([ attrObj[attributeId] = new QuizAttribute(id + "[" + attribute.key.toLowerCase() + "]", attribute.key, that); if(attribute.key.toLowerCase() === 'label' || attribute.key.toLowerCase() === 'title' || attribute.key.toLowerCase() === "name"){ that.setLabel(attrObj[attributeId]); - } + } default: if(attribute.options){ attrObj[attributeId] = new SingleSelectionAttribute(id+"["+attribute.key.toLowerCase()+"]",attribute.key,that,attribute.options); @@ -245,7 +246,7 @@ define([ if(attr.hasOwnProperty(key)){ var val = attr[key].getValue(); if(val.hasOwnProperty('registerYType')){ - val.registerYType(); + val.registerYType(); } } } @@ -279,4 +280,4 @@ define([ return makeNode; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/NodeShapeNode.js b/widgets/src/js/canvas_widget/NodeShapeNode.js index 9df827a0..fc9ad0f6 100755 --- a/widgets/src/js/canvas_widget/NodeShapeNode.js +++ b/widgets/src/js/canvas_widget/NodeShapeNode.js @@ -3,13 +3,14 @@ define([ 'jsplumb', 'lodash', 'canvas_widget/AbstractNode', + 'canvas_widget/BooleanAttribute', 'canvas_widget/SingleSelectionAttribute', 'canvas_widget/SingleValueAttribute', 'canvas_widget/IntegerAttribute', 'canvas_widget/SingleColorValueAttribute', 'canvas_widget/SingleMultiLineValueAttribute', 'text!templates/canvas_widget/node_shape_node.html' -],/** @lends NodeShapeNode */function($, jsPlumb, _, AbstractNode, SingleSelectionAttribute, SingleValueAttribute, IntegerAttribute, SingleColorValueAttribute, SingleMultiLineValueAttribute, nodeShapeNodeHtml) { +],/** @lends NodeShapeNode */function($, jsPlumb, _, AbstractNode, BooleanAttribute, SingleSelectionAttribute, SingleValueAttribute, IntegerAttribute, SingleColorValueAttribute, SingleMultiLineValueAttribute, nodeShapeNodeHtml) { NodeShapeNode.TYPE = "Node Shape"; NodeShapeNode.DEFAULT_WIDTH = 150; @@ -29,11 +30,12 @@ define([ * @param {number} width Width of node * @param {number} height Height of node * @param {number} zIndex Position of node on z-axis + * @param {boolean} containment containment */ - function NodeShapeNode(id, left, top, width, height, zIndex, json) { + function NodeShapeNode(id, left, top, width, height, zIndex, containment, json) { var that = this; - AbstractNode.call(this, id, NodeShapeNode.TYPE, left, top, width, height, zIndex, json); + AbstractNode.call(this, id, NodeShapeNode.TYPE, left, top, width, height, zIndex, containment, json); /** * jQuery object of node template @@ -77,6 +79,7 @@ define([ var attrWidth = new IntegerAttribute(this.getEntityId() + "[defaultWidth]", "Default Width", this); var attrHeight = new IntegerAttribute(this.getEntityId() + "[defaultHeight]", "Default Height", this); var attrColor = new SingleColorValueAttribute(this.getEntityId() + "[color]", "Color", this); + var attrContaintment = new BooleanAttribute(this.getEntityId() + "[containment]", "Containment", this); var attrCustomShape = new SingleMultiLineValueAttribute(this.getEntityId() + "[customShape]", "Custom Shape", this); var attrAnchors = new SingleValueAttribute(this.getEntityId() + "[customAnchors]", "Custom Anchors", this); @@ -86,6 +89,7 @@ define([ this.addAttribute(attrColor); this.addAttribute(attrWidth); this.addAttribute(attrHeight); + this.addAttribute(attrContaintment); this.addAttribute(attrCustomShape); this.addAttribute(attrAnchors); @@ -102,6 +106,7 @@ define([ attrShapeSelect.getValue().registerYType(); attrWidth.getValue().registerYType(); attrHeight.getValue().registerYType(); + attrContaintment.getValue().registerYType(); that.getLabel().getValue().registerYType(); attrColor.getValue().registerYType(); attrAnchors.getValue().registerYType(); @@ -111,4 +116,4 @@ define([ return NodeShapeNode; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/NodeShapeNodeTool.js b/widgets/src/js/canvas_widget/NodeShapeNodeTool.js index ce6704ba..ee8c184f 100755 --- a/widgets/src/js/canvas_widget/NodeShapeNodeTool.js +++ b/widgets/src/js/canvas_widget/NodeShapeNodeTool.js @@ -15,9 +15,9 @@ define([ * @constructor */ function NodeShapeNodeTool(){ - NodeTool.call(this,NodeShapeNode.TYPE,null,null,NodeShapeNode.DEFAULT_WIDTH,NodeShapeNode.DEFAULT_HEIGHT); + NodeTool.call(this,NodeShapeNode.TYPE,null,null,null,NodeShapeNode.DEFAULT_WIDTH,NodeShapeNode.DEFAULT_HEIGHT); } return NodeShapeNodeTool; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/NodeTool.js b/widgets/src/js/canvas_widget/NodeTool.js index 1a1a548e..19926718 100755 --- a/widgets/src/js/canvas_widget/NodeTool.js +++ b/widgets/src/js/canvas_widget/NodeTool.js @@ -14,7 +14,7 @@ define([ * @memberof canvas_widget * @constructor */ - function NodeTool(name,className,description,defaultWidth,defaultHeight){ + function NodeTool(name,className,description,containment,defaultWidth,defaultHeight){ AbstractCanvasTool.call( this, name, @@ -46,7 +46,7 @@ define([ var nodeY = (ev.pageY - offsetCanvas.top) / zoom - _defaultHeight / 2; //if(this == ev.target){ - that.getCanvas().createNode(that.getName(),nodeX,nodeY,_defaultWidth,_defaultHeight, null, null, null, null, defaultLabel, defaultAttributeValues); + that.getCanvas().createNode(that.getName(),nodeX,nodeY,_defaultWidth,_defaultHeight, null, containment, null, null, null, defaultLabel, defaultAttributeValues); //that.canvas.callListeners(CONFIG.CANVAS.LISTENERS.NODEADD,that.name,ev.originalEvent.offsetX,ev.originalEvent.offsetY,_defaultWidth,_defaultHeight); //} that.getCanvas().resetTool(); @@ -88,4 +88,4 @@ define([ return NodeTool; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/ObjectNodeTool.js b/widgets/src/js/canvas_widget/ObjectNodeTool.js index e664216b..541f7f2b 100755 --- a/widgets/src/js/canvas_widget/ObjectNodeTool.js +++ b/widgets/src/js/canvas_widget/ObjectNodeTool.js @@ -14,9 +14,9 @@ define([ * @constructor */ function ObjectNodeTool(){ - NodeTool.call(this,ObjectNode.TYPE,null,null,ObjectNode.DEFAULT_WIDTH,ObjectNode.DEFAULT_HEIGHT); + NodeTool.call(this,ObjectNode.TYPE,null,null,null,ObjectNode.DEFAULT_WIDTH,ObjectNode.DEFAULT_HEIGHT); } return ObjectNodeTool; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/RelationshipGroupNodeTool.js b/widgets/src/js/canvas_widget/RelationshipGroupNodeTool.js index a3d19a7e..ccd7b984 100755 --- a/widgets/src/js/canvas_widget/RelationshipGroupNodeTool.js +++ b/widgets/src/js/canvas_widget/RelationshipGroupNodeTool.js @@ -15,9 +15,9 @@ define([ * @constructor */ function RelationshipGroupNodeTool(){ - NodeTool.call(this,RelationshipGroupNode.TYPE,null,null,RelationshipGroupNode.DEFAULT_WIDTH,RelationshipGroupNode.DEFAULT_HEIGHT); + NodeTool.call(this,RelationshipGroupNode.TYPE,null,null,null,RelationshipGroupNode.DEFAULT_WIDTH,RelationshipGroupNode.DEFAULT_HEIGHT); } return RelationshipGroupNodeTool; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/RelationshipNodeTool.js b/widgets/src/js/canvas_widget/RelationshipNodeTool.js index 9bf7e6db..23c11340 100755 --- a/widgets/src/js/canvas_widget/RelationshipNodeTool.js +++ b/widgets/src/js/canvas_widget/RelationshipNodeTool.js @@ -15,9 +15,9 @@ define([ * @constructor */ function RelationshipNodeTool(){ - NodeTool.call(this,RelationshipNode.TYPE,null,null,RelationshipNode.DEFAULT_WIDTH,RelationshipNode.DEFAULT_HEIGHT); + NodeTool.call(this,RelationshipNode.TYPE,null,null,null,RelationshipNode.DEFAULT_WIDTH,RelationshipNode.DEFAULT_HEIGHT); } return RelationshipNodeTool; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/viewpoint/ClosedViewGeneration.js b/widgets/src/js/canvas_widget/viewpoint/ClosedViewGeneration.js index dc203ceb..2a1d267c 100755 --- a/widgets/src/js/canvas_widget/viewpoint/ClosedViewGeneration.js +++ b/widgets/src/js/canvas_widget/viewpoint/ClosedViewGeneration.js @@ -31,7 +31,7 @@ define(['lodash', 'Util', 'graphlib', 'canvas_widget/EntityManager'], if (node.type === 'Node Shape' || node.type === 'Edge Shape' || node.type === 'Relation') { newNodeId = viewpointName + '_' + neighborId; if (!EntityManager.findNode(newNodeId)) - canvas.createNode(node.type, node.left, node.top, node.width, node.height, node.zIndex, node, newNodeId); + canvas.createNode(node.type, node.left, node.top, node.width, node.height, node.zIndex, node.containment, node, newNodeId); } else if (viewType.getType() === 'ViewObject' && node.type === 'Relationship') { var viewtypes = EntityManager.getNodesByType('ViewRelationship'); @@ -55,7 +55,7 @@ define(['lodash', 'Util', 'graphlib', 'canvas_widget/EntityManager'], if (newNodeId) { var edge = metaGraph.edge(originId, neighborId); if (!edge) { - //try the other direction + //try the other direction edge = metaGraph.edge(neighborId, originId); canvas.createEdge(edge.type, newNodeId, viewType.getEntityId(), edge, viewpointName + '_' + edge.id, viewpointName); } else { diff --git a/widgets/src/js/canvas_widget/viewpoint/ViewObjectNodeTool.js b/widgets/src/js/canvas_widget/viewpoint/ViewObjectNodeTool.js index 09ed7d8c..361c4720 100755 --- a/widgets/src/js/canvas_widget/viewpoint/ViewObjectNodeTool.js +++ b/widgets/src/js/canvas_widget/viewpoint/ViewObjectNodeTool.js @@ -14,9 +14,9 @@ define([ * @constructor */ function ViewObjectNodeTool(){ - NodeTool.call(this,ViewObjectNode.TYPE,null,null,ViewObjectNode.DEFAULT_WIDTH,ViewObjectNode.DEFAULT_HEIGHT); + NodeTool.call(this,ViewObjectNode.TYPE,null,null,null,ViewObjectNode.DEFAULT_WIDTH,ViewObjectNode.DEFAULT_HEIGHT); } return ViewObjectNodeTool; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/canvas_widget/viewpoint/ViewRelationshipNodeTool.js b/widgets/src/js/canvas_widget/viewpoint/ViewRelationshipNodeTool.js index 8f4fb0d8..dc06b3d1 100755 --- a/widgets/src/js/canvas_widget/viewpoint/ViewRelationshipNodeTool.js +++ b/widgets/src/js/canvas_widget/viewpoint/ViewRelationshipNodeTool.js @@ -15,9 +15,9 @@ define([ * @constructor */ function ViewRelationshipNodeTool(){ - NodeTool.call(this,ViewRelationshipNode.TYPE,null,null,ViewRelationshipNode.DEFAULT_WIDTH,ViewRelationshipNode.DEFAULT_HEIGHT); + NodeTool.call(this,ViewRelationshipNode.TYPE,null,null,null,ViewRelationshipNode.DEFAULT_WIDTH,ViewRelationshipNode.DEFAULT_HEIGHT); } return ViewRelationshipNodeTool; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/debug_widget.js b/widgets/src/js/debug_widget.js index a0234805..2268336b 100755 --- a/widgets/src/js/debug_widget.js +++ b/widgets/src/js/debug_widget.js @@ -93,7 +93,7 @@ requirejs(['jqueryui', 'lodash', 'lib/yjs-sync', 'canvas_widget/GenerateViewpoin $exportMetamodel.click(function () { var link = document.createElement('a'); link.download = "vls.json"; - link.href = 'data:,' + encodeURI(JSON.stringify(y.share.data.get('metamodel'), null, 4)); + link.href = 'data:,' + encodeURIComponent(JSON.stringify(y.share.data.get('metamodel'), null, 4)); link.click(); }); @@ -125,7 +125,7 @@ requirejs(['jqueryui', 'lodash', 'lib/yjs-sync', 'canvas_widget/GenerateViewpoin var ytext = map.set(attr[key].key.id, Y.Text); ytext.insert(0, attr[key].key.value); } - else { + else { var ytext = map.set(attr[key].value.id, Y.Text); ytext.insert(0, attr[key].value.value); } diff --git a/widgets/src/js/main_widget.js b/widgets/src/js/main_widget.js index d580b54c..8cadca9e 100755 --- a/widgets/src/js/main_widget.js +++ b/widgets/src/js/main_widget.js @@ -95,14 +95,14 @@ requirejs([ var userList = []; var canvas = new Canvas($("#canvas")); HistoryManager.init(canvas); - - //not working pretty well + + //not working pretty well window.onbeforeunload = function (event) { //y.share.userList.delete(_iwcw.getUser()[CONFIG.NS.PERSON.JABBERID]); //y.share.users.delete(y.db.userId); y.share.activity.set('UserLeftActivity', new ActivityOperation('UserLeftActivity', null, _iwcw.getUser()[CONFIG.NS.PERSON.JABBERID])); } - + y.share.join.observe(function (event) { if(userList.indexOf(event.name)===-1){ userList.push(event.name); @@ -111,10 +111,10 @@ requirejs([ if (!event.value && event.name !== _iwcw.getUser()[CONFIG.NS.PERSON.JABBERID]) { //send to activity widget that a remote user has joined. y.share.join.set(_iwcw.getUser()[CONFIG.NS.PERSON.JABBERID], true); - } else if (event.name === _iwcw.getUser()[CONFIG.NS.PERSON.JABBERID] && !event.value) { + } else if (event.name === _iwcw.getUser()[CONFIG.NS.PERSON.JABBERID] && !event.value) { canvas.resetTool(); $("#loading").hide(); - + if (CONFIG.TEST.CANVAS && (_iwcw.getUser()[CONFIG.NS.PERSON.TITLE] === CONFIG.TEST.USER || _iwcw.getUser()[CONFIG.NS.PERSON.MBOX] === CONFIG.TEST.EMAIL)) require(['./../test/CanvasWidgetTest'], function (CanvasWidgetTest) { CanvasWidgetTest(canvas); @@ -153,7 +153,7 @@ requirejs([ var metamodel = y.share.data.get('metamodel'); if(!metamodel) metamodel = '{}'; - else + else metamodel = JSON.stringify(metamodel); _iwcw.sendLocalNonOTOperation(CONFIG.WIDGET.NAME.PALETTE, new NonOTOperation('WaitForCanvasOperation', metamodel)); break; @@ -220,7 +220,7 @@ requirejs([ for (var nodeId in nodes) { if (nodes.hasOwnProperty(nodeId)) { node = nodes[nodeId]; - canvas.addTool(node.label, new NodeTool(node.label, null, null, node.shape.defaultWidth, node.shape.defaultHeight)); + canvas.addTool(node.label, new NodeTool(node.label, null, null, node.shape.containment, node.shape.defaultWidth, node.shape.defaultHeight)); } } } @@ -249,7 +249,7 @@ requirejs([ for (var nodeId in nodes) { if (nodes.hasOwnProperty(nodeId)) { node = nodes[nodeId]; - canvas.addTool(node.label, new NodeTool(node.label, null, null, node.shape.defaultWidth, node.shape.defaultHeight)); + canvas.addTool(node.label, new NodeTool(node.label, null, null, node.shape.containment, node.shape.defaultWidth, node.shape.defaultHeight)); } } } @@ -360,8 +360,8 @@ requirejs([ //Add View Types canvas.addTool(ViewObjectNode.TYPE, new ViewObjectNodeTool()); canvas.addTool(ViewRelationshipNode.TYPE, new ViewRelationshipNodeTool()); - - + + //Init control elements for views $("#btnCreateViewpoint").click(function () { ShowViewCreateMenu(); @@ -554,21 +554,21 @@ requirejs([ $("#zoomout").click(function () { canvas.setZoom(canvas.getZoom() - 0.1); }); - + $("#applyLayout").click(function(){ window.y.share.canvas.set('applyLayout', window.y.share.users.get(window.y.db.userId)); window.y.share.activity.set('ApplyLayoutActivity', new ActivityOperation('ApplyLayoutActivity', null, window.y.share.users.get(window.y.db.userId),"..applied Layout")); }); - + var $feedback = $("#feedback"); // Add code for PNG export - + // Work later on moving this functionality to Export Widget //var uri = canvas.toPNG(); // y.share.canvas.set('PngMap', uri); // Work later on moving this functionality to Export Widget - + // Export as PNG /*var $saveImage = $("#save_image"); $saveImage.show(); @@ -695,4 +695,3 @@ requirejs([ } }); - diff --git a/widgets/src/js/operations/OperationFactory.js b/widgets/src/js/operations/OperationFactory.js index 9fb64bb8..768b6230 100755 --- a/widgets/src/js/operations/OperationFactory.js +++ b/widgets/src/js/operations/OperationFactory.js @@ -163,6 +163,7 @@ define([ value.width, value.height, value.zIndex, + value.containment, value.json, value.viewId, value.oType, @@ -177,6 +178,7 @@ define([ value.width, value.height, value.zIndex, + value.containment, value.json ); break; @@ -279,4 +281,4 @@ define([ return new OperationFactory(); -}); \ No newline at end of file +}); diff --git a/widgets/src/js/operations/ot/NodeAddOperation.js b/widgets/src/js/operations/ot/NodeAddOperation.js index df7496bb..d60e2992 100755 --- a/widgets/src/js/operations/ot/NodeAddOperation.js +++ b/widgets/src/js/operations/ot/NodeAddOperation.js @@ -19,6 +19,7 @@ define([ * @param {number} width Width of node * @param {number} height Height of node * @param {number} zIndex Position of node on z-axis + * @param {boolean} containment containment * @param {object} json JSON representation of node * @param {string} viewId the identifier of the view * @param {string} oType the original Type, only set in views @@ -26,7 +27,7 @@ define([ * @param defaultAttributeValues May be used to set default attribute values for nodes. * @constructor */ - function NodeAddOperation(entityId,type,left,top,width,height,zIndex,json, viewId, oType,jabberId, defaultLabel, defaultAttributeValues){ + function NodeAddOperation(entityId,type,left,top,width,height,zIndex,containment,json, viewId, oType,jabberId, defaultLabel, defaultAttributeValues){ var that = this; EntityOperation.call(this,EntityOperation.TYPES.NodeAddOperation,entityId,CONFIG.ENTITY.NODE); @@ -89,6 +90,13 @@ define([ */ var _zIndex = zIndex; + /** + * is containment type + * @type {boolean} + * @private + */ + var _containment = containment; + /** * JSON representation of node * @type {Object} @@ -122,6 +130,7 @@ define([ width: _width, height: _height, zIndex: _zIndex, + containment: _containment, json: _json, viewId:_viewId, oType: _oType, @@ -184,6 +193,14 @@ define([ return _zIndex; }; + /** + * Get containment + * @returns {boolean} + */ + this.getContainment = function(){ + return _containment; + }; + /** * Get JSON representation of node * @return {Object} @@ -265,6 +282,7 @@ define([ this.getWidth(), this.getHeight(), this.getZIndex(), + this.getContainment(), json ); }; @@ -288,6 +306,7 @@ define([ width: this.getWidth(), height: this.getHeight(), zIndex: this.getZIndex(), + containment: this.getContainment(), json: this.getJSON(), viewId:this.getViewId(), oType: this.getOriginType(), diff --git a/widgets/src/js/operations/ot/NodeDeleteOperation.js b/widgets/src/js/operations/ot/NodeDeleteOperation.js index 4552fa46..3163371b 100755 --- a/widgets/src/js/operations/ot/NodeDeleteOperation.js +++ b/widgets/src/js/operations/ot/NodeDeleteOperation.js @@ -19,10 +19,11 @@ define([ * @param {number} width Width of node * @param {number} height Height of node * @param {number} zIndex Position of node on z-axis + * @param {boolean} containment containment * @param {object} json JSON representation of node * @constructor */ - function NodeDeleteOperation(entityId,type,left,top,width,height,zIndex,json){ + function NodeDeleteOperation(entityId,type,left,top,width,height,zIndex,containment,json){ var that = this; EntityOperation.call(this,EntityOperation.TYPES.NodeDeleteOperation,entityId,CONFIG.ENTITY.NODE); @@ -69,6 +70,13 @@ define([ */ var _zIndex = zIndex; + /** + * is containment type + * @type {boolean} + * @private + */ + var _containment = containment; + /** * JSON representation of node * @type {Object} @@ -90,6 +98,7 @@ define([ width: _width, height: _height, zIndex: _zIndex, + containment: _containment, json: _json }), CONFIG.OPERATION.TYPE.UPDATE, @@ -145,6 +154,14 @@ define([ return _zIndex; }; + /** + * is containment type + * @returns {boolean} + */ + this.getContainment = function(){ + return _containment; + }; + /** * Get JSON representation of node * @return {Object} @@ -232,6 +249,8 @@ define([ this.getWidth(), this.getHeight(), this.getZIndex(), + this.getContainment(), + this.getContainment(), json ); }; @@ -246,6 +265,7 @@ define([ width: this.getWidth(), height: this.getHeight(), zIndex: this.getZIndex(), + containment: this.getContainment(), json: this.getJSON() } }; @@ -262,4 +282,4 @@ define([ return NodeDeleteOperation; -}); \ No newline at end of file +}); diff --git a/widgets/src/js/plugin/plugin.js b/widgets/src/js/plugin/plugin.js index 1a346c81..5b564638 100755 --- a/widgets/src/js/plugin/plugin.js +++ b/widgets/src/js/plugin/plugin.js @@ -104,7 +104,7 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { * @param {Y.Map} ymap the ymap of the node/edge */ var createYTextsForEntityType = function(metamodel, entityId, entityType, type, ymap){ - var types = metamodel[entityType]; + var types = metamodel[entityType]; for(var key in types){ if(types.hasOwnProperty(key) && types[key].label === type){ var attrs = types[key].attributes; @@ -114,15 +114,15 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { } } } - } + } } - + return { /** * If are already connected to a syncmeta yjs space then use this funnction to init the plugin * Otherwise connect to yjs with the connect function - * @param {object} yInstance - the y instance + * @param {object} yInstance - the y instance */ init: function(yInstance) { ySyncMetaInstance = yInstance; @@ -396,7 +396,7 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { if (attr.constructor.name === "e") { var ytext = attr; - + var l = ytext.toString().length; if (l > 0) { ytext.delete(0, l); @@ -407,7 +407,7 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { setTimeout(function () { if (jabberId) ySyncMetaInstance.share.canvas.set('triggerSave', jabberId); - }, 500); + }, 500); } else ymap.set(attrId, { 'entityId': attrId, 'value': value, 'type': 'update', 'position': 0 }); @@ -418,7 +418,7 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { if (idx != -1) { var ymap = ySyncMetaInstance.share.nodes.get(entityId); - findAttr(ymap, attrId, value); + findAttr(ymap, attrId, value); } else { idx = ySyncMetaInstance.share.edges.keys().indexOf(entityId); if (idx != -1) { @@ -429,21 +429,21 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { return; } } - }, + }, /** - * Create a node + * Create a node * @param {String} type the type of the node * @param {integer} left the x-coordinate * @param {integer} top the y-coordinate - * @param {integer} width the width of the node + * @param {integer} width the width of the node * @param {integer} height the height of the node * @param {integer} zIndex the z-index of the node * @param {Object} json some json data * @returns returns the id of the created node as string */ - createNode: function (type, left, top, width, height, zIndex, json) { + createNode: function (type, left, top, width, height, zIndex, containment, json) { var metamodel = ySyncMetaInstance.share.data.get('metamodel'); - + var id = Util.generateRandomId(); var _ymap = ySyncMetaInstance.share.nodes.set(id, Y.Map); if(metamodel){ @@ -455,6 +455,7 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { _ymap.set(id+'[color]', Y.Text); _ymap.set(id+'[customAnchors]', Y.Text); _ymap.set(id+'[customShape]', Y.Text); + _ymap.set(id+'[containment]', Y.Text); }else if(type === 'Edge Shape'){ _ymap.set(id+'[color]', Y.Text); _ymap.set(id+'[overlay]', Y.Text); @@ -486,8 +487,8 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { setTimeout(function () { if (jabberId) ySyncMetaInstance.share.canvas.set('triggerSave', jabberId); - }, 500); - return id; + }, 500); + return id; }, /** * delete a node @@ -507,7 +508,7 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { var id = Util.generateRandomId(); setTimeout(function () { var metamodel = ySyncMetaInstance.share.data.get('metamodel'); - + var _ymap = ySyncMetaInstance.share.edges.set(id, Y.Map); if (metamodel) { createYTextsForEntityType(metamodel, id, "edges", type, _ymap); @@ -520,7 +521,7 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { _ymap.set('source', source); _ymap.set('target', target); _ymap.set('jabberId', jabberId); - //if source and target nodes are created previously just wait here for a + //if source and target nodes are created previously just wait here for a ySyncMetaInstance.share.canvas.set('EdgeAddOperation', { id: id, @@ -538,7 +539,7 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { ySyncMetaInstance.share.canvas.set('triggerSave', jabberId); }, 100); }, 200); - return id; + return id; }, /** * Delete a edge @@ -619,5 +620,3 @@ define(['lib/yjs-sync','Util'], function(yjsSync, Util) { */ } }); - - diff --git a/widgets/src/test/plugin_example/syncmeta-plugin-test.js b/widgets/src/test/plugin_example/syncmeta-plugin-test.js index ae68d935..2d651a01 100755 --- a/widgets/src/test/plugin_example/syncmeta-plugin-test.js +++ b/widgets/src/test/plugin_example/syncmeta-plugin-test.js @@ -126,4 +126,4 @@ $(function () { addToList('onNodeMove2: Moved: ' + e.id); }); }); -}); \ No newline at end of file +}); diff --git a/widgets/src/test/test_widget/EntityManagerTests.js b/widgets/src/test/test_widget/EntityManagerTests.js index 80061e98..af7846ba 100755 --- a/widgets/src/test/test_widget/EntityManagerTests.js +++ b/widgets/src/test/test_widget/EntityManagerTests.js @@ -35,7 +35,7 @@ define(['lodash', 'lib/vendor/test/chai', 'canvas_widget/EntityManager'], functi before(function(done) { objectNode = EntityManager.createNode('Object', '1234567890', 4000, 4000, 150, 100, 1000, null); - enumNode = EntityManager.createNodeFromJSON(json.type, id, json.left, json.top, json.width, json.height, json.zIndex, json); + enumNode = EntityManager.createNodeFromJSON(json.type, id, json.left, json.top, json.width, json.height, json.zIndex, null, json); biDirAsso = EntityManager.createEdge('Bi-Dir-Association', '1234567891', objectNode, enumNode); @@ -74,7 +74,7 @@ define(['lodash', 'lib/vendor/test/chai', 'canvas_widget/EntityManager'], functi //Check label expect(enumNode.getLabel().getValue().getValue()).to.be.equal("enum"); - //Check attributes + //Check attributes var attributes = enumNode.getAttribute('[attributes]'); expect(attributes).not.to.be.null; expect(attributes.constructor.name).to.be.equal('SingleValueListAttribute'); @@ -204,4 +204,4 @@ define(['lodash', 'lib/vendor/test/chai', 'canvas_widget/EntityManager'], functi }) } return EntityManagerTests; -}) \ No newline at end of file +})