diff --git a/public/svg-edit/editor/extensions/ext-connector.js b/public/svg-edit/editor/extensions/ext-connector.js index 7083217f..9f9b95cf 100644 --- a/public/svg-edit/editor/extensions/ext-connector.js +++ b/public/svg-edit/editor/extensions/ext-connector.js @@ -228,8 +228,12 @@ $(function() { if(conn) { this.setAttribute('class', conn_sel.substr(1)); var conn_data = conn.split(' '); + var sbb = svgCanvas.getStrokedBBox([getElem(conn_data[0])]); + var ebb = svgCanvas.getStrokedBBox([getElem(conn_data[1])]); $(this).data('c_start',conn_data[0]) - .data('c_end',conn_data[1]); + .data('c_end',conn_data[1]) + .data('start_bb', sbb) + .data('end_bb', ebb); svgCanvas.getEditorNS(true); } }); @@ -311,7 +315,6 @@ $(function() { "style": "pointer-events:none" } }); - $(cur_line).data('start_bb', bb); } return { diff --git a/public/svg-edit/editor/svg-editor.js b/public/svg-edit/editor/svg-editor.js index ef242952..215f04dc 100644 --- a/public/svg-edit/editor/svg-editor.js +++ b/public/svg-edit/editor/svg-editor.js @@ -246,7 +246,8 @@ function svg_edit_setup() { } // Update selectedElement if element is no longer part of the image. // This occurs for the text elements in Firefox - else if(elem && selectedElement && selectedElement.parentNode == null) { + else if(elem && selectedElement && selectedElement.parentNode == null + || elem && elem.tagName == "path") { selectedElement = elem; } } @@ -738,7 +739,6 @@ function svg_edit_setup() { if(elem != null && !elem.parentNode) elem = null; var currentLayer = svgCanvas.getCurrentLayer(); var currentMode = svgCanvas.getMode(); - // No need to update anything else in rotate mode if (currentMode == 'rotate' && elem != null) { var ang = svgCanvas.getRotationAngle(elem); @@ -747,7 +747,6 @@ function svg_edit_setup() { return; } var is_node = currentMode == 'pathedit'; //elem ? (elem.id && elem.id.indexOf('pathpointgrip') == 0) : false; - $('#selected_panel, #multiselected_panel, #g_panel, #rect_panel, #circle_panel,\ #ellipse_panel, #line_panel, #text_panel, #image_panel').hide(); if (elem != null) { @@ -2779,7 +2778,7 @@ function svg_edit_setup() { updateCanvas(true); }); -// var revnums = "svg-editor.js ($Rev: 1423 $) "; +// var revnums = "svg-editor.js ($Rev: 1430 $) "; // revnums += svgCanvas.getVersion(); // $('#copyright')[0].setAttribute("title", revnums); return svgCanvas; diff --git a/public/svg-edit/editor/svgcanvas.js b/public/svg-edit/editor/svgcanvas.js index 4b10c0bd..a3b3a8e1 100644 --- a/public/svg-edit/editor/svgcanvas.js +++ b/public/svg-edit/editor/svgcanvas.js @@ -1357,6 +1357,7 @@ function BatchCommand(text) { if (node.nodeName == 'path' && attrName == 'd') { // Convert to absolute node.setAttribute('d',pathActions.convertPath(node)); + pathActions.fixEnd(node); } // for the style attribute, rewrite it in terms of XML presentational attributes if (attrName == "style") { @@ -3720,94 +3721,726 @@ function BatchCommand(text) { var pathActions = function() { + var pathData = {}; + var current_path; + var path; + var segData = { + 2: ['x','y'], + 4: ['x','y'], + 6: ['x','y','x1','y1','x2','y2'], + 8: ['x','y','x1','y1'], + 10: ['x','y','r1','r2','angle','largeArcFlag','sweepFlag'], + 12: ['x'], + 14: ['y'] + }; + + function retPath() { + return path; + } + + function resetD(p) { + p.setAttribute("d", pathActions.convertPath(p)); + } + + function insertItemBefore(elem, newseg, index) { + // Support insertItemBefore on paths for FF2 + var list = elem.pathSegList; + var len = list.numberOfItems; + var arr = []; + for(var i=0; i= len ? null : segs[i+1]; + var prev_seg = (i-1) < 0 ? null : segs[i-1]; + + if(seg.type === 2) { + if(prev_seg && prev_seg.type !== 1) { + // New sub-path, last one is open, + // so add a grip to last sub-path's first point + var start_seg = segs[start_i]; + start_seg.next = segs[start_i+1]; + start_seg.next.prev = start_seg; + start_seg.addGrip(); + } + // Remember that this is a starter seg + start_i = i; + } else if(next_seg && next_seg.type === 1) { + // This is the last real segment of a closed sub-path + // Next is first seg after "M" + seg.next = segs[start_i+1]; + + // First seg after "M"'s prev is this + seg.next.prev = seg; + seg.mate = segs[start_i]; + seg.addGrip(); + if(!p.first_seg) { + p.first_seg = seg; + } + } else if(!next_seg) { + if(seg.type !== 1) { + // Last seg, doesn't close so add a grip + // to last sub-path's first point + var start_seg = segs[start_i]; + start_seg.next = segs[start_i+1]; + start_seg.next.prev = start_seg; + start_seg.addGrip(); + seg.addGrip(); + + if(!p.first_seg) { + // Open path, so set first as real first and add grip + p.first_seg = segs[start_i]; + } + } + } else if(seg.type !== 1){ + // Regular segment, so add grip and its "next" + seg.addGrip(); + + // Don't set its "next" if it's an "M" + if(next_seg && next_seg.type !== 2) { + seg.next = next_seg; + seg.next.prev = seg; + } + } + } + return p; + } + + this.init(); + + // Update position of all points + this.update = function() { + if(canvas.getRotationAngle(p.elem)) { + var tlist = canvas.getTransformList(path.elem); + p.matrix = transformListToTransform(tlist).matrix; + p.imatrix = p.matrix.inverse(); + } + + p.eachSeg(function(i) { + this.item = elem.pathSegList.getItem(i); + this.update(); + }); + + return p; + } + + this.eachSeg = function(fn) { + var len = p.segs.length + for(var i=0; i < len; i++) { + fn.call(p.segs[i], i); + } + } + + this.addSeg = function(index) { + // Adds a new segment + var seg = p.segs[index]; + var prev = seg.prev; + + var new_x = (seg.item.x + prev.item.x) / 2; + var new_y = (seg.item.y + prev.item.y) / 2; + + var list = elem.pathSegList; + var newseg = elem.createSVGPathSegLinetoAbs(new_x, new_y); + if(support.pathInsertItemBefore) { + list.insertItemBefore(newseg, index); + } else { + insertItemBefore(elem, newseg, index); + } + + } + + this.deleteSeg = function(index) { + var seg = p.segs[index]; + var list = elem.pathSegList; + + seg.show(false); + var next = seg.next; + if(seg.mate) { + // Make the next point be the "M" point + var pt = [next.item.x, next.item.y]; + replacePathSeg(2, next.index, pt); + + // Reposition last node + replacePathSeg(4, seg.index, pt); + + list.removeItem(seg.mate.index); + } else if(!seg.prev) { + // First node of open path, make next point the M + var item = seg.item; + var pt = [next.item.x, next.item.y]; + replacePathSeg(2, seg.next.index, pt); + list.removeItem(index); + + } else { + list.removeItem(index); + } + } + + this.endChanges = function(text) { + if(isWebkit) resetD(p.elem); + var cmd = new ChangeElementCommand(elem, {d: p.last_d}, text); + addCommandToHistory(cmd); + call("changed", [elem]); + } + + + this.addPtsToSelection = function(indexes) { + if(!$.isArray(indexes)) indexes = [indexes]; + for(var i=0; i< indexes.length; i++) { + var index = indexes[i]; + var seg = p.segs[index]; + if(seg.ptgrip) { + if($.inArray(index, p.selected_pts) == -1 && index >= 0) { + p.selected_pts.push(index); + } + } + }; + p.selected_pts.sort(); + var i = p.selected_pts.length, + grips = new Array(i); + // Loop through points to be selected and highlight each + while(i--) { + var pt = p.selected_pts[i]; + var seg = p.segs[pt]; + seg.select(true); + grips[i] = seg.ptgrip; + } + pathActions.canDeleteNodes = true; + call("selected", grips); + } + + this.removePtFromSelection = function(index) { + var pos = $.inArray(index, p.selected_pts); + if(pos == -1) { + return; + } + p.segs[index].select(false); + p.selected_pts.splice(pos, 1); + } + + + this.clearSelection = function() { + p.eachSeg(function(i) { + this.select(false); + }); + p.selected_pts = []; + } + + this.selectPt = function(pt, ctrl_num) { + p.clearSelection(); + p.addPtsToSelection(pt); + if(ctrl_num) { + p.dragctrl = ctrl_num; + + if(link_control_pts) { + p.segs[pt].setLinked(ctrl_num); + } + } + } + + this.storeD = function() { + this.last_d = elem.getAttribute('d'); + } + + this.show = function(y) { + // Shows this path's segment grips + p.eachSeg(function() { + this.show(y); + }); + if(y) { + p.selectPt(p.first_seg.index); + } + return p; + } + + // Move selected points + this.movePts = function(d_x, d_y) { + var i = p.selected_pts.length; + while(i--) { + var seg = p.segs[p.selected_pts[i]]; + seg.move(d_x, d_y); + } + } + + this.moveCtrl = function(d_x, d_y) { + var seg = p.segs[p.selected_pts[0]]; + seg.moveCtrl(p.dragctrl, d_x, d_y); + if(link_control_pts) { + seg.setLinked(p.dragctrl); + } + } + + this.setSegType = function(new_type) { + p.storeD(); + var i = p.selected_pts.length; + var text; + while(i--) { + var sel_pt = p.selected_pts[i]; + + // Selected seg + var cur = p.segs[sel_pt]; + var prev = cur.prev; + if(!prev) continue; + + if(!new_type) { // double-click, so just toggle + text = "Toggle Path Segment Type"; + + // Toggle segment to curve/straight line + var old_type = cur.type; + + new_type = (old_type == 6) ? 4 : 6; + } + + new_type = new_type-0; + + var cur_x = cur.item.x; + var cur_y = cur.item.y; + var prev_x = prev.item.x; + var prev_y = prev.item.y; + var points; + switch ( new_type ) { + case 6: + if(cur.olditem) { + var old = cur.olditem; + points = [cur_x,cur_y, old.x1,old.y1, old.x2,old.y2]; + } else { + var diff_x = cur_x - prev_x; + var diff_y = cur_y - prev_y; + // get control points from straight line segment + var ct1_x = (prev_x + (diff_y/2)); + var ct1_y = (prev_y - (diff_x/2)); + var ct2_x = (cur_x + (diff_y/2)); + var ct2_y = (cur_y - (diff_x/2)); + points = [cur_x,cur_y, ct1_x,ct1_y, ct2_x,ct2_y]; + } + break; + case 4: + points = [cur_x,cur_y]; + + // Store original prevve segment nums + cur.olditem = cur.item; + break; + } + + cur.setType(new_type, points); + } + path.endChanges(text); + return; + } + + } + + function getPath(elem) { + var p = pathData[elem.id]; + if(!p) p = pathData[elem.id] = new Path(elem); + return p; + } + + var pathFuncs = [], current_path = null, current_path_pts = [], - current_path_pt = -1, - current_path_pt_drag = -1, - current_path_oldd = null, - current_ctrl_pt_drag = -1, link_control_pts = false, - selected_pts = [], - is_closed = false, hasMoved = false; - - var getD = function() { - return current_path.getAttribute('d'); - }; - - var endChanges = function(d, text) { - var cmd = new ChangeElementCommand(current_path, {d:d}, text); - addCommandToHistory(cmd); - call("changed", [current_path]); - } - - var resetPointGrips = function() { - if(!current_path) return; - var sr = svgroot.suspendRedraw(100); - removeAllPointGripsFromPath(); - recalcPathPoints(); - addAllPointGripsToPath(); - svgroot.unsuspendRedraw(sr); - }; - - var setPointContainerTransform = function(value) { - var conts = $('#pathpointgrip_container,#ctrlpointgrip_container'); - $.each(conts,function() { - if(!value) { - this.removeAttribute("transform"); - } else { - this.setAttribute("transform", value); - } - }); - } - - var recalcPathPoints = function() { - current_path_pts = []; - var segList = current_path.pathSegList; - var curx = segList.getItem(0).x, cury = segList.getItem(0).y; - current_path_pts.push(curx * current_zoom); - current_path_pts.push(cury * current_zoom); - var len = segList.numberOfItems; - for (var i = 1; i < len; ++i) { - var l = segList.getItem(i); - var x = l.x, y = l.y; - // paths can now be closed, skip Z segments - if (l.pathSegType == 1) { - break; - } - var type = l.pathSegType; - // current_path_pts just holds the absolute coords - if (type == 4) { - curx = x; - cury = y; - } // type 4 (abs line) - else if (type == 5) { - curx += x; - cury += y; - } // type 5 (rel line) - else if (type == 6) { - curx = x; - cury = y; - } // type 6 (abs curve) - else if (type == 7) { - curx += x; - cury += y; - } // type 7 (rel curve) - current_path_pts.push(curx * current_zoom); - current_path_pts.push(cury * current_zoom); - } // for each segment - } - - var removeAllPointGripsFromPath = function() { - // loop through and hide all pointgrips - $('#pathpointgrip_container > *').attr("display", "none"); - - var line = getElem("path_stretch_line"); - if (line) line.setAttribute("display", "none"); - - $('#ctrlpointgrip_container *').attr('display','none'); - }; // This function converts a polyline (created by the fh_path tool) into // a path element and coverts every three line segments into a single bezier @@ -3847,22 +4480,22 @@ function BatchCommand(text) { prevArr[3] = newpts[0].y; d[d.length-1] = prevArr.join(','); ct1 = newpts[1]; - } - } - + } + } + d.push([ct1.x,ct1.y,ct2.x,ct2.y,end.x,end.y].join(',')); - + curpos = end; prevCtlPt = ct2; - } + } // handle remaining line segments d.push("L"); for(;i < N;++i) { var pt = points.getItem(i); d.push([pt.x,pt.y].join(",")); - } + } d = d.join(" "); - + // create new path element element = addSvgElementFromJson({ "element": "path", @@ -3877,431 +4510,16 @@ function BatchCommand(text) { "stroke-opacity": cur_shape.stroke_opacity, "fill-opacity": cur_shape.fill_opacity, "style": "pointer-events:inherit" - } + } }); call("changed",[element]); - } + } return element; }; - // - var addNodeToSelection = function(points) { -// var point = points; - - - if(!$.isArray(points)) points = [points]; - - for(var i=0; i< points.length; i++) { - var pt = points[i]; - if($.inArray(pt, selected_pts) == -1 && pt >= 0) { - selected_pts.push(pt); - } - } - selected_pts.sort(); - - var i = selected_pts.length, - last_pt = current_path_pts.length/2 - 1, - grips = new Array(i); - - // Check if amount of selected nodes are allowed to be deleted - var tot_pts = current_path_pts.length/2 - (is_closed?1:0); - pathActions.canDeleteNodes = (tot_pts - i >= 2); - - $('#pathpointgrip_container circle').attr('stroke','#00F'); - - // Loop through points to be selected and highlight each - while(i--) { - var point = selected_pts[i]; - - $('#pathpointgrip_' + point).attr('stroke','#0FF'); - grips[i] = $('#pathpointgrip_' + point)[0]; - $('#ctrlpointgrip_container circle').attr('fill', '#EEE'); - $('#ctrlpointgrip_' + point + 'c1, #ctrlpointgrip_' + point + 'c2').attr('fill','#0FF'); - $('#segline_' + point).attr('display','inline'); - } - - if(selected_pts.length <= 1) {//if(current_path_pt == -1) { - current_path_pt = selected_pts[0]; - } - - updateSegLines(); - - call("selected", grips); - }; - - var removeNodeFromSelection = function(point) { - - var pos = $.inArray(point, selected_pts); - if(pos == -1) { - return; - } else { - selected_pts.splice(pos, 1); - } - - $('#pathpointgrip_' + point).attr('stroke','#00F'); - // grips[i] = $('#pathpointgrip_' + point)[0]; - $('#ctrlpointgrip_container circle').attr('fill', '#EEE'); - $('#ctrlpointgrip_' + point + 'c1, #ctrlpointgrip_' + point + 'c2').attr('fill','#0FF'); - $('#segline_' + point).attr('display','none'); - - current_path_pt = selected_pts[0]; - - // TODO: Set grips -// call("selected", grips); - }; - - var removeAllNodesFromSelection = function() { - var i = selected_pts.length; - var last_pt = current_path_pts.length/2 - 1; - - $('#pathpointgrip_container circle').attr('stroke','#EEE'); - $('#ctrlpointgrip_container circle').attr('fill', '#EEE'); - selected_pts = []; -// current_path_pt = -1; -// call("selected", []); - }; - - var selectNode = function(point) { - removeAllNodesFromSelection(); - addNodeToSelection(point); - }; - - var addAllPointGripsToPath = function(pointToSelect) { - // loop through and show all pointgrips - var len = current_path_pts.length; - for (var i = 0; i < len; i += 2) { - var grip = getElem("pathpointgrip_"+i/2); - - // Skip last point if closed - if(!is_closed || i+2 < len) { - if (grip) { - assignAttributes(grip, { - 'cx': current_path_pts[i], - 'cy': current_path_pts[i+1], - 'display': 'inline' - }); - } - else { - addPointGripToPath(current_path_pts[i], current_path_pts[i+1],i/2); - } - } - - var index = i/2; - var item = current_path.pathSegList.getItem(index); - if(item.pathSegType == 6) { - index -= 1; - // Same code as when making a curve, needs to be in own function - var cur_x = getPathPoint(index)[0]; - var cur_y = getPathPoint(index)[1]; - var next_x = getPathPoint(index+1)[0]; - var next_y = getPathPoint(index+1)[1]; - addControlPointGrip(item.x1,item.y1, cur_x,cur_y, index+'c1'); - addControlPointGrip(item.x2,item.y2, next_x,next_y, index+'c2'); - } - } - // FIXME: we cannot just use the same transform as the path because we might be - // at a different zoom level - var angle = canvas.getRotationAngle(current_path); - if (angle) { - var bbox = canvas.getBBox(current_path); - var cx = (bbox.x + bbox.width/2) * current_zoom, - cy = (bbox.y + bbox.height/2) * current_zoom; - var xform = ["rotate(", angle, " ", cx, ",", cy, ")"].join(""); - setPointContainerTransform(xform); - } - if(pointToSelect != null) { - selectNode(pointToSelect); - } - }; - - var addPointGripToPath = function(x,y,index) { - // create the container of all the point grips - var pointGripContainer = getElem("pathpointgrip_container"); - if (!pointGripContainer) { - var parent = getElem("selectorParentGroup"); - pointGripContainer = parent.appendChild(document.createElementNS(svgns, "g")); - pointGripContainer.id = "pathpointgrip_container"; - } - - var pointGrip = getElem("pathpointgrip_"+index); - // create it - if (!pointGrip) { - pointGrip = document.createElementNS(svgns, "circle"); - assignAttributes(pointGrip, { - 'id': "pathpointgrip_" + index, - 'display': "none", - 'r': 4, - 'fill': "#0FF", - 'stroke': "#00F", - 'stroke-width': 2, - 'cursor': 'move', - 'style': 'pointer-events:all', - 'xlink:title': uiStrings.pathNodeTooltip - }); - pointGrip = pointGripContainer.appendChild(pointGrip); - - var grip = $('#pathpointgrip_'+index); - grip.dblclick(function() { - canvas.setSegType(); - }); - - // create segline - segLine = document.createElementNS(svgns, "path"); - assignAttributes(segLine, { - 'id': "segline_" + index, - 'display': 'none', - 'fill': "none", - 'stroke': "#0FF", - 'stroke-width': 2, - 'style':'pointer-events:none', - 'd': 'M0,0 0,0' - }); - segLine = pointGripContainer.appendChild(segLine); - } - - // set up the point grip element and display it - assignAttributes(pointGrip, { - 'cx': x, - 'cy': y, - 'display': "inline" - }); - }; - - var updateSegLines = function() { - // create segment lines - var len = current_path_pts.length/2 - (is_closed?1:0); - - for(var i=0; i= list.numberOfItems) { - segLine.setAttribute('display','none'); - continue; - } - - // Point is selected, so calculate and display - replacePathSeg(2, 0, getPathPoint(i, true), segLine); - - var seg = list.getItem(i+1); - var points = [seg.x, seg.y]; - if(seg.x1 != null && seg.x2 != null) { - points.splice(2, 0, seg.x1, seg.y1, seg.x2, seg.y2); - } - points = $.map(points, function(n){return n*current_zoom;}); - replacePathSeg(seg.pathSegType, 1, points, segLine); - segLine.setAttribute('display','inline'); - } else { - // Point is not selected, so just hide - segLine.setAttribute('display','none'); - } - } - } - - var updatePath = function(mouse_x, mouse_y, old_path_pts) { - var x = mouse_x / current_zoom, - y = mouse_y / current_zoom, - - i = current_path_pt_drag * 2, - last_index = current_path_pts.length/2 - 1, - is_first = current_path_pt_drag == 0, // || (is_closed && current_path_pt_drag == last_index); - is_last = !is_closed && current_path_pt_drag == last_index; - - // if the image is rotated, then we must modify the x,y mouse coordinates - // and rotate them into the shape's rotated coordinate system - // we also re-map mouse_x/y and x/y into the rotated coordinate system - var angle = canvas.getRotationAngle(current_path, true); - if (angle) { - // calculate the shape's old center that was used for rotation - var box = selectedBBoxes[0], - cx = (box.x + box.width/2) * current_zoom, - cy = (box.y + box.height/2) * current_zoom, - dx = mouse_x - cx, dy = mouse_y - cy, - r = Math.sqrt( dx*dx + dy*dy ), - theta = Math.atan2(dy,dx) - angle; - current_path_pts[i] = mouse_x = cx + r * Math.cos(theta); - current_path_pts[i+1] = mouse_y = cy + r * Math.sin(theta); - x = mouse_x / current_zoom; - y = mouse_y / current_zoom; - } - else { - current_path_pts[i] = x * current_zoom; - current_path_pts[i+1] = y * current_zoom; - } - - if(is_first && is_closed) { - // Update the first point - current_path_pts[0] = current_path_pts[i]; - current_path_pts[1] = current_path_pts[i+1]; - current_path_pt_drag = 0; - } - - var index = current_path_pt_drag, - abs_x = getPathPoint(index)[0], - abs_y = getPathPoint(index)[1], - - item = current_path.pathSegList.getItem(index), - x_diff = x - old_path_pts[index*2], - y_diff = y - old_path_pts[index*2 + 1]; - - var cur_type = item.pathSegType; - var points = []; - - if(cur_type == 6) { - points = [abs_x,abs_y, item.x1,item.y1, item.x2 + x_diff,item.y2 + y_diff]; - } else { - if(is_first) { - // Need absolute position for first point - points = getPathPoint(0); - } else { - points = [abs_x, abs_y]; - } - } - replacePathSeg(cur_type, index, points); - - var setSeg = function(index,first) { - var points, item = current_path.pathSegList.getItem(index); - var type = item.pathSegType; - if(first) { - item.x += x_diff; - item.y += y_diff; - } - - switch (type) { - case 1: - points = []; - break; - case 4: - points = [item.x, item.y]; - break; - case 6: - if(first) { - item.x1 -= x_diff; - item.y1 -= y_diff; - item.x2 += x_diff; - item.y2 += y_diff; - } - - points = [item.x, item.y, item.x1 + x_diff,item.y1 + y_diff, item.x2,item.y2]; - break; - default: - break; - } - replacePathSeg(type, index, points); - return type; - } - - if(is_closed || !is_last) { - var next_type = setSeg(index+1); - } else { - var next_type = 0; - } - - if(is_first && is_closed) { - var last_type = setSeg(last_index,1); - } - - // move the point grip - var grip = getElem("pathpointgrip_" + current_path_pt_drag); - if (grip) { - grip.setAttribute("cx", mouse_x); - grip.setAttribute("cy", mouse_y); - call("changed", [grip]); - } - - if(is_first) cur_type = last_type; - - if(cur_type != 4) { - var num = is_first?last_index:index, - id2 = (num-1)+'c2', - line = getElem("ctrlLine_"+id2); - if(line) { - // Don't do if first point on open path - if(!(!is_closed && current_path_pt_drag == 0)) { - var x2 = line.getAttribute('x2') - 0 + x_diff*current_zoom, - y2 = line.getAttribute('y2') - 0 + y_diff*current_zoom; - addControlPointGrip(x2,y2, mouse_x,mouse_y, id2, true); - } - } - } - - if(next_type != 4) { - var id1 = (current_path_pt_drag)+'c1'; - var line = getElem("ctrlLine_"+id1); - if(line) { - var x2 = line.getAttribute('x2') - 0 + x_diff*current_zoom, - y2 = line.getAttribute('y2') - 0 + y_diff*current_zoom; - addControlPointGrip(x2,y2, mouse_x,mouse_y, id1, true); - } - } - } - - var updateCurvedSegment = function(mouse_x, mouse_y, index, ctrl_num) { - var list = current_path.pathSegList; - if(index+1 >= list.numberOfItems) { - index = -1; - } - var c_item = list.getItem(index+1); - - // Only do curves - if(c_item.pathSegType != 6) return; - - ctrl_pt_drag = index + 'c' + ctrl_num; - - var x = mouse_x / current_zoom, - y = mouse_y / current_zoom; - - var angle = canvas.getRotationAngle(current_path, true); - - // TODO: Make sure this works for linked control points - if (angle) { - // calculate the shape's old center that was used for rotation - var box = selectedBBoxes[0], - cx = (box.x + box.width/2) * current_zoom, - cy = (box.y + box.height/2) * current_zoom, - dx = mouse_x - cx, dy = mouse_y - cy, - r = Math.sqrt( dx*dx + dy*dy ), - theta = Math.atan2(dy,dx) - angle; - mouse_x = cx + r * Math.cos(theta); - mouse_y = cy + r * Math.sin(theta); - x = mouse_x / current_zoom; - y = mouse_y / current_zoom; - } - - c_item['x' + ctrl_num] = x; - c_item['y' + ctrl_num] = y; - replacePathSeg(6, index+1, [c_item.x,c_item.y, c_item.x1,c_item.y1, c_item.x2,c_item.y2]); - - updateSegLines(); - - var grip = getElem("ctrlpointgrip_" + ctrl_pt_drag); - if(grip) { - grip.setAttribute("cx", mouse_x); - grip.setAttribute("cy", mouse_y); - - var line = getElem("ctrlLine_"+ctrl_pt_drag); - line.setAttribute("x2", mouse_x); - line.setAttribute("y2", mouse_y); - } - } - - var getPathPoint = function(index, raw_val) { - var len = current_path_pts.length; - var pt_num = len/2; - if(index < 0) { - index += pt_num; - } else if(index >= pt_num) { - index -= pt_num; - } - var z = raw_val?1:current_zoom; - return [current_path_pts[index*2] / z, current_path_pts[index*2 + 1] / z]; - } - // This replaces the segment at the given index. Type is given as number. - var replacePathSeg = function(type, index, pts, path) { - if(!path) path = current_path; + var replacePathSeg = function(type, index, pts, elem) { + var path = elem || retPath().elem; var func = 'createSVGPathSeg' + pathFuncs[type]; var seg = path[func].apply(path, pts); @@ -4326,72 +4544,6 @@ function BatchCommand(text) { } } - var addControlPointGrip = function(x, y, source_x, source_y, id, raw_val) { - if(!raw_val) { - x *= current_zoom; y *= current_zoom; - source_x *= current_zoom; source_y *= current_zoom; - } - - // create the container of all the control point grips - var ctrlPointGripContainer = getElem("ctrlpointgrip_container"); - if (!ctrlPointGripContainer) { - var parent = getElem("selectorParentGroup"); - ctrlPointGripContainer = parent.appendChild(document.createElementNS(svgns, "g")); - ctrlPointGripContainer.id = "ctrlpointgrip_container"; - } - ctrlPointGripContainer.setAttribute("display", "inline"); - - var ctrlLine = getElem("ctrlLine_"+id); - if (!ctrlLine) { - ctrlLine = document.createElementNS(svgns, "line"); - assignAttributes(ctrlLine, { - 'id': "ctrlLine_"+id, - 'stroke': "#555", - 'stroke-width': 1, - "style": "pointer-events:none" - }); - ctrlLine = ctrlPointGripContainer.appendChild(ctrlLine); - } - - assignAttributes(ctrlLine, { - 'x1': source_x, - 'y1': source_y, - 'x2': x, - 'y2': y, - 'display': "inline" - }); - - var pointGrip = getElem("ctrlpointgrip_"+id); - // create it - if (!pointGrip) { - pointGrip = document.createElementNS(svgns, "circle"); - assignAttributes(pointGrip, { - 'id': "ctrlpointgrip_" + id, - 'display': "none", - 'r': 4, - 'fill': "#0FF", - 'stroke': "#55F", - 'stroke-width': 1, - 'cursor': 'move', - 'style': 'pointer-events:all', - 'xlink:title': uiStrings.pathCtrlPtTooltip - }); - pointGrip = ctrlPointGripContainer.appendChild(pointGrip); - } - - assignAttributes(pointGrip, { - 'cx': x, - 'cy': y, - 'display': "inline" - }); - } - - var removeControlPointGrips = function(index) { - for(var i=1; i <= 2; i++) { - $("#ctrlpointgrip_" + index + "c" + i + ",#ctrlLine_" + index + "c" + i).attr("display", "none"); - } - } - // If the path was rotated, we must now pay the piper: // Every path point must be rotated into the rotated coordinate system of // its old center, then determine the new center, then rotate it back @@ -4400,8 +4552,10 @@ function BatchCommand(text) { // TODO: This is still using ye olde transform methods, can probably // be optimized or even taken care of by recalculateDimensions var recalcRotatedPath = function() { + var current_path = path.elem; var angle = canvas.getRotationAngle(current_path, true); if(!angle) return; + selectedBBoxes[0] = path.oldbbox; var box = canvas.getBBox(current_path), oldbox = selectedBBoxes[0], oldcx = oldbox.x + oldbox.width/2, @@ -4469,15 +4623,6 @@ function BatchCommand(text) { tlist = canvas.getTransformList(current_path); R_nc.setRotate((angle * 180.0 / Math.PI), newcx, newcy); tlist.replaceItem(R_nc,0); - - if(getElem("pathpointgrip_container")) { - var pcx = newcx * current_zoom, - pcy = newcy * current_zoom; - var xform = ["rotate(", (angle*180.0/Math.PI), " ", pcx, ",", pcy, ")"].join(""); - setPointContainerTransform(xform); - } - resetPointGrips(); - updateSegLines(); } return { @@ -4486,43 +4631,47 @@ function BatchCommand(text) { var pathFuncsStrs = ['Moveto','Lineto','CurvetoCubic','CurvetoQuadratic','Arc','LinetoHorizontal','LinetoVertical','CurvetoCubicSmooth','CurvetoQuadraticSmooth']; $.each(pathFuncsStrs,function(i,s){pathFuncs.push(s+'Abs');pathFuncs.push(s+'Rel');}); }, + getPath: function() { + return path; + }, mouseDown: function(evt, mouse_target, start_x, start_y) { - if(current_mode == "path") { - setPointContainerTransform(""); - return; - } + if(current_mode == "path") return; - // Make sure current_path isn't null at this point - if(!current_path) return; + // TODO: Make sure current_path isn't null at this point + if(!path) return; + + path.storeD(); - current_path_oldd = getD(); var id = evt.target.id; if (id.substr(0,14) == "pathpointgrip_") { // Select this point - current_path_pt = current_path_pt_drag = parseInt(id.substr(14)); + var cur_pt = path.cur_pt = parseInt(id.substr(14)); + path.dragging = [start_x, start_y]; + var seg = path.segs[cur_pt]; // only clear selection if shift is not pressed (otherwise, add // node to selection) if (!evt.shiftKey) { - if(selected_pts.length <= 1 || $.inArray(current_path_pt, selected_pts) == -1) { - removeAllNodesFromSelection(); + if(path.selected_pts.length <= 1 || !seg.selected) { + path.clearSelection(); } - addNodeToSelection(current_path_pt); - } else if($.inArray(current_path_pt, selected_pts) != -1) { - removeNodeFromSelection(current_path_pt); + path.addPtsToSelection(cur_pt); + } else if(seg.selected) { + path.removePtFromSelection(cur_pt); } else { - addNodeToSelection(current_path_pt); + path.addPtsToSelection(cur_pt); } } else if(id.indexOf("ctrlpointgrip_") == 0) { - current_ctrl_pt_drag = id.split('_')[1]; - var node_num = current_ctrl_pt_drag.split('c')[0]-0; - selectNode(node_num); - } + path.dragging = [start_x, start_y]; - if(current_path_pt_drag == -1 && current_ctrl_pt_drag == -1) { + var parts = id.split('_')[1].split('c'); + var cur_pt = parts[0]-0; + var ctrl_num = parts[1]-0; + path.selectPt(cur_pt, ctrl_num); + } -// start_x = x; -// start_y = y; + // Start selection box + if(!path.dragging) { if (rubberBox == null) { rubberBox = selectorManager.getRubberBandBox(); } @@ -4545,111 +4694,52 @@ function BatchCommand(text) { } return; } - // if we are dragging a point, let's move it - if (current_path_pt_drag != -1 && current_path) { - var old_path_pts = $.map(current_path_pts, function(n){return n/current_zoom;}); - var diff_x = mouse_x - current_path_pts[current_path_pt*2]; - var diff_y = mouse_y - current_path_pts[current_path_pt*2+1]; - - var rot = !!canvas.getRotationAngle(current_path); - if(rot) { - var m = canvas.getTransformList(current_path).getItem(0).matrix; - } - - for(var i=0; i= pt_count - 1) { - index = 0; - if(!is_closed) return; - } - } - - var pt = getPathPoint(pt_index, true), - new_x = pt[0] - (mouse_x - pt[0]), - new_y = pt[1] - (mouse_y - pt[1]); - updateCurvedSegment(new_x, new_y, index, ctrl_num, true); + if(path.dragctrl) { + path.moveCtrl(diff_x, diff_y); + } else { + path.movePts(diff_x, diff_y); } } else { - var len = current_path_pts.length, - sel_pts = []; - selected_pts = []; - var rot = !!canvas.getRotationAngle(current_path); - if(rot) { - var tlist = canvas.getTransformList(current_path), - m = transformListToTransform(tlist).matrix; - } + path.selected_pts = []; + path.eachSeg(function(i) { + var seg = this; + if(!seg.next && !seg.prev) return; - if(is_closed) len -= 2; - - for(var i=0; i sel_pt+1) { - segtype = list.getItem(sel_pt+1).pathSegType; - } else { - segtype = false; - } + var seg = path.segs[sel_pt]; return { - x: pt[0], - y: pt[1], - type: segtype - } + x: seg.item.x, + y: seg.item.y, + type: seg.type + }; }, linkControlPoints: function(linkPoints) { link_control_pts = linkPoints; }, clonePathNode: function() { - var d = getD(); - - var i = selected_pts.length, - nums = []; + path.storeD(); + + var sel_pts = path.selected_pts; + var segs = path.segs; + + var i = sel_pts.length; + var nums = []; + while(i--) { - var pt = selected_pts[i], list = current_path.pathSegList; - if(pt+1 >= list.numberOfItems) { - pt--; - } + var pt = sel_pts[i]; + path.addSeg(pt); - var next_item = list.getItem(pt+1); - - // Get point in between nodes - if(next_item.pathSegType % 2 == 0) { // even num, so abs - var cur_item = list.getItem(pt); - var new_x = (next_item.x + cur_item.x) / 2; - var new_y = (next_item.y + cur_item.y) / 2; - } else { - var new_x = next_item.x/2; - var new_y = next_item.y/2; - } - - var seg = current_path.createSVGPathSegLinetoAbs(new_x, new_y); - - if(support.pathInsertItemBefore) { - list.insertItemBefore(seg, pt+1); - } else { - var segList = current_path.pathSegList; - var len = segList.numberOfItems; - var arr = []; - for(var i=0; i 0 ? sel_pts[0]-1 : 1; - var grip = $('#pathpointgrip_' + sel_pt); - - var index = grip[0].id.split('_')[1] - 0; - - var last_index = current_path_pts.length/2 - 1; - - if(!is_closed && index == last_index) { - return; // Last point of unclosed path should do nothing - } else if(index >= last_index && is_closed) { - index = 0; - } - - var next_index = index+1; - var cur_x = getPathPoint(index)[0]; - var cur_y = getPathPoint(index)[1]; - var next_x = getPathPoint(next_index)[0]; - var next_y = getPathPoint(next_index)[1]; - - if(!new_type) { // double-click, so just toggle - var text = "Toggle Path Segment Type"; - - // Toggle segment to curve/straight line - var old_type = current_path.pathSegList.getItem(index+1).pathSegType; - - new_type = (old_type == 6) ? 4 : 6; - - } else { - new_type -= 0; - var text = "Change Path Segment Type"; - } - - var points; - - var bb = current_path.getBBox(); - var oldseg = current_path.pathSegList.getItem(next_index); - switch ( new_type ) { - case 6: - var diff_x = next_x - cur_x; - var diff_y = next_y - cur_y; - // get control points from straight line segment - var ct1_x = oldseg.c1_x || (cur_x + (diff_y/2)); - var ct1_y = oldseg.c1_y || (cur_y - (diff_x/2)); - var ct2_x = oldseg.c2_x || (next_x + (diff_y/2)); - var ct2_y = oldseg.c2_y || (next_y - (diff_x/2)); - points = [next_x,next_y, ct1_x,ct1_y, ct2_x,ct2_y]; - break; - case 4: - points = [next_x,next_y]; - removeControlPointGrips(index); - break; - } - - replacePathSeg(new_type, next_index, points); - - // if we changed to a straight line, store the old control points - var newseg = current_path.pathSegList.getItem(next_index); - if (newseg.pathSegType == 4 && oldseg.pathSegType == 6) { - newseg.c1_x = oldseg.x1; - newseg.c1_y = oldseg.y1; - newseg.c2_x = oldseg.x2; - newseg.c2_y = oldseg.y2; - } + path.clearSelection(); + + // TODO: Find right way to select point now + // path.selectPt(sel_pt); + if(window.opera) { // Opera repaints incorrectly + var cp = $(path.elem); cp.attr('d',cp.attr('d')); } - - addAllPointGripsToPath(); - // recalculateDimensions(current_path); - updateSegLines(); - recalcRotatedPath(); - - endChanges(old_d, text); + path.endChanges("Delete path node(s)"); + }, + smoothPolylineIntoPath: smoothPolylineIntoPath, + setSegType: function(v) { + path.setSegType(v); }, moveNode: function(attr, newValue) { - newValue *= current_zoom; - var num = (attr == 'x')?0:1; - var old_path_pts = $.map(current_path_pts, function(n){return n/current_zoom;}); - var d = getD(); + var sel_pts = path.selected_pts; + if(!sel_pts.length) return; - current_path_pts[current_path_pt*2 + num] = newValue-0; - current_path_pt_drag = current_path_pt; - updatePath(current_path_pts[current_path_pt*2], current_path_pts[current_path_pt*2 + 1], old_path_pts); - updateSegLines(); - endChanges(d, "Move path point"); + path.storeD(); + + // Get first selected point + var seg = path.segs[sel_pts[0]]; + var diff = {x:0, y:0}; + diff[attr] = newValue - seg.item[attr]; + + seg.move(diff.x, diff.y); + path.endChanges("Move path point"); + }, + fixEnd: function(elem) { + // Adds an extra segment if the last seg before a Z doesn't end + // at its M point + // M0,0 L0,100 L100,100 z + var segList = elem.pathSegList; + var len = segList.numberOfItems; + var last_m; + for (var i = 0; i < len; ++i) { + var item = segList.getItem(i); + if(item.pathSegType === 2) { + last_m = item; + } + + if(item.pathSegType === 1) { + var prev = segList.getItem(i-1); + if(prev.x != last_m.x && prev.y != last_m.y) { + // Add an L segment here + var newseg = elem.createSVGPathSegLinetoAbs(last_m.x, last_m.y); + if(support.pathInsertItemBefore) { + segList.insertItemBefore(newseg, i); + } else { + insertItemBefore(elem, newseg, i); + } + // Can this be done better? + pathActions.fixEnd(elem); + break; + } + + } + } + if(isWebkit) resetD(elem); }, // Convert a path to one with only absolute or relative values convertPath: function(path, toRel) { @@ -5613,7 +5554,7 @@ function BatchCommand(text) { nonce = n; if (extensions["Arrows"]) call("setarrownonce", n) ; } else { - svgcontent.setAttributeNS(xmlnsns, 'xmlns:se', se_ns); + svgcontent.setAttributeNS(xmlnsns, 'xml:se', se_ns); svgcontent.setAttributeNS(se_ns, 'se:nonce', nonce); } // change image href vals if possible @@ -5687,6 +5628,7 @@ function BatchCommand(text) { // reset transform lists svgTransformLists = {}; canvas.clearSelection(); + pathActions.clearData(); svgroot.appendChild(selectorManager.selectorParentGroup); addCommandToHistory(batchCmd); @@ -6900,9 +6842,9 @@ function BatchCommand(text) { this.changeSelectedAttribute("transform",newTransform,selectedElements); } var pointGripContainer = getElem("pathpointgrip_container"); - if(elem.nodeName == "path" && pointGripContainer) { - pathActions.setPointContainerTransform(elem.getAttribute("transform")); - } +// if(elem.nodeName == "path" && pointGripContainer) { +// pathActions.setPointContainerTransform(elem.getAttribute("transform")); +// } var selector = selectorManager.requestSelector(selectedElements[0]); selector.resize(); selector.updateGripCursors(val); @@ -7761,9 +7703,9 @@ function BatchCommand(text) { this.undo = function() { if (undoStackPointer > 0) { this.clearSelection(); - pathActions.clear(); var cmd = undoStack[--undoStackPointer]; cmd.unapply(); + pathActions.clear(); call("changed", cmd.elements()); } }; @@ -7772,6 +7714,7 @@ function BatchCommand(text) { this.clearSelection(); var cmd = undoStack[undoStackPointer++]; cmd.apply(); + pathActions.clear(); call("changed", cmd.elements()); } }; @@ -7965,7 +7908,7 @@ function BatchCommand(text) { // Function: getVersion // Returns a string which describes the revision number of SvgCanvas. this.getVersion = function() { - return "svgcanvas.js ($Rev: 1427 $)"; + return "svgcanvas.js ($Rev: 1431 $)"; }; this.setUiStrings = function(strs) { diff --git a/public/svg-edit/extensions/ext-arrows.js b/public/svg-edit/extensions/ext-arrows.js deleted file mode 100644 index 1245eb92..00000000 --- a/public/svg-edit/extensions/ext-arrows.js +++ /dev/null @@ -1,271 +0,0 @@ -/* - * ext-arrows.js - * - * Licensed under the Apache License, Version 2 - * - * Copyright(c) 2010 Alexis Deveria - * - */ - - -$(function() { - svgCanvas.addExtension("Arrows", function(S) { - var svgcontent = S.svgcontent, - addElem = S.addSvgElementFromJson, - selElems; - - var lang_list = { - "en":[ - {"id": "arrow_none", "textContent": "No arrow" } - ], - "fr":[ - {"id": "arrow_none", "textContent": "Sans flèche" } - ] - }; - - var pathdata = { - fw: {d:"m0,0l10,5l-10,5l5,-5l-5,-5z", refx:8, id:"se_arrow_fw"}, - bk: {d:"m10,0l-10,5l10,5l-5,-5l5,-5z", refx:2, id:"se_arrow_bk"} - } - function getLinked(elem, attr) { - var str = elem.getAttribute(attr); - if(!str) return null; - var m = str.match(/\(\#(.*)\)/); - if(!m || m.length !== 2) { - return null; - } - return S.getElem(m[1]); - } - - function showPanel(on) { - $('#arrow_panel').toggle(on); - - if(on) { - var el = selElems[0]; - var end = el.getAttribute("marker-end"); - var start = el.getAttribute("marker-start"); - var mid = el.getAttribute("marker-mid"); - var val; - - if(end && start) { - val = "both"; - } else if(end) { - val = "end"; - } else if(start) { - val = "start"; - } else if(mid) { - val = "mid"; - if(mid.indexOf("bk") != -1) { - val = "mid_bk"; - } - } - - if(!start && !mid && !end) { - val = "none"; - } - - $("#arrow_list").val(val); - } - } - - function resetMarker() { - var el = selElems[0]; - el.removeAttribute("marker-start"); - el.removeAttribute("marker-mid"); - el.removeAttribute("marker-end"); - } - - function addMarker(dir, type, id) { - // TODO: Make marker (or use?) per arrow type, since refX can be different - id = id || 'se_arrow_' + dir; - - var marker = S.getElem(id); - - var data = pathdata[dir]; - - if(type == "mid") { - data.refx = 5; - } - - if(!marker) { - marker = addElem({ - "element": "marker", - "attr": { - "viewBox": "0 0 10 10", - "id": id, - "refY": 5, - "markerUnits": "strokeWidth", - "markerWidth": 5, - "markerHeight": 5, - "orient": "auto", - "style": "pointer-events:none" // Currently needed for Opera - } - }); - var arrow = addElem({ - "element": "path", - "attr": { - "d": data.d, - "fill": "#000000" - } - }); - marker.appendChild(arrow); - S.findDefs().appendChild(marker); - } - - marker.setAttribute('refX', data.refx); - - return marker; - } - - function setArrow() { - var type = this.value; - resetMarker(); - - if(type == "none") { - return; - } - - // Set marker on element - var dir = "fw"; - if(type == "mid_bk") { - type = "mid"; - dir = "bk"; - } else if(type == "both") { - addMarker("bk", type); - svgCanvas.changeSelectedAttribute("marker-start", "url(#" + pathdata.bk.id + ")"); - type = "end"; - dir = "fw"; - } else if (type == "start") { - dir = "bk"; - } - - addMarker(dir, type); - svgCanvas.changeSelectedAttribute("marker-"+type, "url(#" + pathdata[dir].id + ")"); - S.call("changed", selElems); - } - - function colorChanged(elem) { - var color = elem.getAttribute('stroke'); - - var mtypes = ['start','mid','end']; - var defs = S.findDefs(); - - $.each(mtypes, function(i, type) { - var marker = getLinked(elem, 'marker-'+type); - if(!marker) return; - - var cur_color = $(marker).children().attr('fill'); - var cur_d = $(marker).children().attr('d'); - var new_marker = null; - if(cur_color === color) return; - - var all_markers = $(defs).find('marker'); - // Different color, check if already made - all_markers.each(function() { - var attrs = $(this).children().attr(['fill', 'd']); - if(attrs.fill === color && attrs.d === cur_d) { - // Found another marker with this color and this path - new_marker = this; - } - }); - - if(!new_marker) { - // Create a new marker with this color - var last_id = marker.id; - var dir = last_id.indexOf('_fw') !== -1?'fw':'bk'; - - new_marker = addMarker(dir, type, 'se_arrow_' + dir + all_markers.length); - - $(new_marker).children().attr('fill', color); - } - - $(elem).attr('marker-'+type, "url(#" + new_marker.id + ")"); - - // Check if last marker can be removed - var remove = true; - $(S.svgcontent).find('line, polyline, path, polygon').each(function() { - var elem = this; - $.each(mtypes, function(j, mtype) { - if($(elem).attr('marker-' + mtype) === "url(#" + marker.id + ")") { - return remove = false; - } - }); - if(!remove) return false; - }); - - // Not found, so can safely remove - if(remove) { - $(marker).remove(); - } - - }); - - } - - return { - name: "Arrows", - context_tools: [{ - type: "select", - panel: "arrow_panel", - title: "Select arrow type", - id: "arrow_list", - options: { - none: "No arrow", - end: "---->", - start: "<----", - both: "<--->", - mid: "-->--", - mid_bk: "--<--" - }, - defval: "none", - events: { - change: setArrow - } - }], - callback: function() { - $('#arrow_panel').hide(); - }, - addLangData: function(lang) { - return { - data: lang_list[lang] - }; - }, - selectedChanged: function(opts) { - - // Use this to update the current selected elements - selElems = opts.elems; - - var i = selElems.length; - var marker_elems = ['line','path','polyline','polygon']; - - while(i--) { - var elem = selElems[i]; - if(elem && $.inArray(elem.tagName, marker_elems) != -1) { - if(opts.selectedElement && !opts.multiselected) { - showPanel(true); - } else { - showPanel(false); - } - } else { - showPanel(false); - } - } - }, - elementChanged: function(opts) { - var elem = opts.elems[0]; - if(elem && ( - elem.getAttribute("marker-start") || - elem.getAttribute("marker-mid") || - elem.getAttribute("marker-end") - )) { - // var start = elem.getAttribute("marker-start"); - // var mid = elem.getAttribute("marker-mid"); - // var end = elem.getAttribute("marker-end"); - // Has marker, so see if it should match color - colorChanged(elem); - } - - } - }; - }); -}); diff --git a/public/svg-edit/extensions/ext-connector.js b/public/svg-edit/extensions/ext-connector.js deleted file mode 100644 index a0e050e7..00000000 --- a/public/svg-edit/extensions/ext-connector.js +++ /dev/null @@ -1,574 +0,0 @@ -/* - * ext-connector.js - * - * Licensed under the Apache License, Version 2 - * - * Copyright(c) 2010 Alexis Deveria - * - */ - -$(function() { - svgCanvas.addExtension("Connector", function(S) { - var svgcontent = S.svgcontent, - svgroot = S.svgroot, - getNextId = S.getNextId, - getElem = S.getElem, - addElem = S.addSvgElementFromJson, - selManager = S.selectorManager, - started = false, - start_x, - start_y, - cur_line, - start_elem, - end_elem, - connections = [], - conn_sel = ".se_connector", - se_ns, -// connect_str = "-SE_CONNECT-", - selElems = []; - - var lang_list = { - "en":[ - {"id": "mode_connect", "title": "Connect two objects" } - ], - "fr":[ - {"id": "mode_connect", "title": "Connecter deux objets"} - ] - }; - - function showPanel(on) { - var conn_rules = $('#connector_rules'); - if(!conn_rules.length) { - conn_rules = $('