Started on Issue 310: Move to Plugin Architecture, as well as Issue 200: flowchart (just connector lines for now)
git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1277 eee81c28-f429-11dd-99c0-75d572ba1ddd
This commit is contained in:
243
editor/ext-connector.js
Normal file
243
editor/ext-connector.js
Normal file
@@ -0,0 +1,243 @@
|
||||
$(function() {
|
||||
svgCanvas.addExtension("Connector", function(vars) {
|
||||
|
||||
var svgcontent = vars.content;
|
||||
var getNextId = vars.getNextId;
|
||||
var addElem = vars.addSvgElementFromJson;
|
||||
var selManager = vars.selectorManager;
|
||||
var started = false,
|
||||
start_x,
|
||||
start_y,
|
||||
cur_line,
|
||||
start_elem,
|
||||
end_elem,
|
||||
connections = [],
|
||||
conn_class = "se_connect",
|
||||
connect_str = "-SE_CONNECT-",
|
||||
selElems;
|
||||
|
||||
// Init code
|
||||
// (function() {
|
||||
//
|
||||
//
|
||||
// }());
|
||||
|
||||
|
||||
return {
|
||||
name: "Connector",
|
||||
svgicons: "images/conn.svg",
|
||||
buttons: [{
|
||||
id: "mode_connect",
|
||||
type: "mode",
|
||||
icon: "images/cut.png",
|
||||
events: {
|
||||
'click': function() {
|
||||
svgCanvas.setMode("connector");
|
||||
}
|
||||
}
|
||||
}],
|
||||
mouseDown: function(opts) {
|
||||
var e = opts.event;
|
||||
|
||||
start_x = opts.start_x,
|
||||
start_y = opts.start_y;
|
||||
var mode = svgCanvas.getMode();
|
||||
|
||||
if(mode == "connector") {
|
||||
|
||||
if(started) return;
|
||||
|
||||
if(e.target.parentNode.parentNode == svgcontent) {
|
||||
// Connectable element
|
||||
start_elem = e.target;
|
||||
|
||||
// Get center of source element
|
||||
var bb = svgCanvas.getStrokedBBox([start_elem]);
|
||||
var x = bb.x + bb.width/2;
|
||||
var y = bb.y + bb.height/2;
|
||||
|
||||
started = true;
|
||||
cur_line = addElem({
|
||||
"element": "line",
|
||||
"attr": {
|
||||
"x1": x,
|
||||
"y1": y,
|
||||
"x2": start_x,
|
||||
"y2": start_y,
|
||||
"id": getNextId(),
|
||||
"stroke": '#000',
|
||||
"stroke-width": 1,
|
||||
"fill": "none",
|
||||
"opacity": .5,
|
||||
"style": "pointer-events:none"
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
started: true
|
||||
};
|
||||
} else if(mode == "select") {
|
||||
|
||||
// Check if selected elements have connections
|
||||
var elems = opts.selectedElements;
|
||||
var i = elems.length;
|
||||
var connectors = $(svgcontent).find("." + conn_class);
|
||||
if(!connectors.length) return;
|
||||
|
||||
connections = [];
|
||||
|
||||
while(i--) {
|
||||
var elem = elems[i];
|
||||
if(!elem) continue;
|
||||
if(elem.getAttribute('class') == conn_class) continue;
|
||||
var elem_id = elem.id;
|
||||
connectors.each(function() {
|
||||
var con_id = this.id;
|
||||
if(con_id.indexOf(elem_id) != -1) {
|
||||
var is_start = true;
|
||||
if(con_id.indexOf(connect_str + elem_id) != -1) {
|
||||
// Found connector (selected is end elem)
|
||||
is_start = false;
|
||||
}
|
||||
|
||||
var bb = svgCanvas.getStrokedBBox([elem]);
|
||||
var x = bb.x + bb.width/2;
|
||||
var y = bb.y + bb.height/2;
|
||||
|
||||
connections.push({
|
||||
elem: elem,
|
||||
connector: this,
|
||||
is_start: is_start,
|
||||
start_x: x,
|
||||
start_y: y
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
mouseMove: function(opts) {
|
||||
var zoom = svgCanvas.getZoom();
|
||||
var e = opts.event;
|
||||
var x = opts.mouse_x/zoom;
|
||||
var y = opts.mouse_y/zoom;
|
||||
|
||||
var diff_x = x - start_x,
|
||||
diff_y = y - start_y;
|
||||
|
||||
var mode = svgCanvas.getMode();
|
||||
|
||||
if(mode == "connector" && started) {
|
||||
cur_line.setAttributeNS(null, "x2", x);
|
||||
cur_line.setAttributeNS(null, "y2", y);
|
||||
} else if(mode == "select") {
|
||||
var slen = selElems.length;
|
||||
|
||||
while(slen--) {
|
||||
var elem = selElems[slen];
|
||||
// Look for selected connector elements
|
||||
if(elem && elem.getAttribute('class') == conn_class) {
|
||||
// Remove the "translate" transform given to move
|
||||
svgCanvas.getTransformList(elem).clear();
|
||||
}
|
||||
}
|
||||
|
||||
if(connections.length) {
|
||||
// Update line with element
|
||||
var i = connections.length;
|
||||
|
||||
while(i--) {
|
||||
var conn = connections[i];
|
||||
var line = conn.connector;
|
||||
var elem = conn.elem;
|
||||
var n = conn.is_start ? 1 : 2;
|
||||
line.setAttributeNS(null, "x"+n, conn.start_x + diff_x);
|
||||
line.setAttributeNS(null, "y"+n, conn.start_y + diff_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mouseUp: function(opts) {
|
||||
var zoom = svgCanvas.getZoom();
|
||||
var e = opts.event,
|
||||
x = opts.mouse_x/zoom,
|
||||
y = opts.mouse_y/zoom;
|
||||
|
||||
if(svgCanvas.getMode() == "connector") {
|
||||
if(e.target.parentNode.parentNode != svgcontent) {
|
||||
// Not a valid target element, so remove line
|
||||
$(cur_line).remove();
|
||||
started = false;
|
||||
return {
|
||||
keep: false,
|
||||
element: null,
|
||||
started: started
|
||||
}
|
||||
} else if(e.target == start_elem) {
|
||||
// Start line through click
|
||||
started = true;
|
||||
return {
|
||||
keep: true,
|
||||
element: null,
|
||||
started: started
|
||||
}
|
||||
} else {
|
||||
// Valid end element
|
||||
end_elem = e.target;
|
||||
var line_id = start_elem.id + connect_str + end_elem.id;
|
||||
var alt_line_id = end_elem.id + connect_str + start_elem.id;
|
||||
|
||||
// Don't create connector if one already exists
|
||||
if($('#'+line_id + ', #' + alt_line_id).length) {
|
||||
$(cur_line).remove();
|
||||
return {
|
||||
keep: false,
|
||||
element: null,
|
||||
started: false
|
||||
}
|
||||
}
|
||||
|
||||
var bb = svgCanvas.getStrokedBBox([end_elem]);
|
||||
var x = bb.x + bb.width/2;
|
||||
var y = bb.y + bb.height/2;
|
||||
cur_line.setAttributeNS(null, "x2", x);
|
||||
cur_line.setAttributeNS(null, "y2", y);
|
||||
cur_line.id = line_id;
|
||||
console.log('cur_line',cur_line.id);
|
||||
cur_line.setAttribute("class", conn_class);
|
||||
svgCanvas.addToSelection([cur_line]);
|
||||
svgCanvas.moveToBottomSelectedElement();
|
||||
|
||||
started = false;
|
||||
return {
|
||||
keep: true,
|
||||
element: cur_line,
|
||||
started: started
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
selectedChanged: function(opts) {
|
||||
|
||||
// Use this to update the current selected elements
|
||||
selElems = opts.elems;
|
||||
|
||||
var i = selElems.length;
|
||||
|
||||
// var to_hide = $('#tool_clone, #tool_topath, div.toolset:has(#angle), #line_panel');
|
||||
|
||||
while(i--) {
|
||||
var elem = selElems[i];
|
||||
if(elem && elem.getAttribute('class') == conn_class) {
|
||||
selManager.requestSelector(elem).showGrips(false);
|
||||
|
||||
if(opts.selectedElement && !opts.multiselected) {
|
||||
// TODO: Set up context tools and hide most regular line tools
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user