Added support for multiple segment lines on selection, mass segment type changes, and multi-selection on node cloning

git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1272 eee81c28-f429-11dd-99c0-75d572ba1ddd
master
Alexis Deveria 2010-01-21 20:12:49 +00:00
parent 3df4a5d616
commit b3a3a6af26
1 changed files with 188 additions and 196 deletions

View File

@ -3254,6 +3254,7 @@ function BatchCommand(text) {
current_ctrl_pt_drag = -1, current_ctrl_pt_drag = -1,
link_control_pts = false, link_control_pts = false,
selected_pts = [], selected_pts = [],
is_closed = false,
hasMoved = false; hasMoved = false;
var getD = function() { var getD = function() {
@ -3348,8 +3349,7 @@ function BatchCommand(text) {
} }
selected_pts.sort(); selected_pts.sort();
var is_closed = pathIsClosed(), var i = selected_pts.length,
i = selected_pts.length,
last_pt = current_path_pts.length/2 - 1, last_pt = current_path_pts.length/2 - 1,
grips = new Array(i); grips = new Array(i);
@ -3367,14 +3367,14 @@ function BatchCommand(text) {
grips[i] = $('#pathpointgrip_' + point)[0]; grips[i] = $('#pathpointgrip_' + point)[0];
$('#ctrlpointgrip_container circle').attr('fill', '#EEE'); $('#ctrlpointgrip_container circle').attr('fill', '#EEE');
$('#ctrlpointgrip_' + point + 'c1, #ctrlpointgrip_' + point + 'c2').attr('fill','#0FF'); $('#ctrlpointgrip_' + point + 'c1, #ctrlpointgrip_' + point + 'c2').attr('fill','#0FF');
$('#segline_' + point).attr('display','inline');
} }
if(selected_pts.length <= 1) {//if(current_path_pt == -1) { if(selected_pts.length <= 1) {//if(current_path_pt == -1) {
current_path_pt = selected_pts[0]; current_path_pt = selected_pts[0];
} }
updateSegLine(); updateSegLines();
updateSegLine(true);
call("selected", grips); call("selected", grips);
}; };
@ -3392,10 +3392,9 @@ function BatchCommand(text) {
// grips[i] = $('#pathpointgrip_' + point)[0]; // grips[i] = $('#pathpointgrip_' + point)[0];
$('#ctrlpointgrip_container circle').attr('fill', '#EEE'); $('#ctrlpointgrip_container circle').attr('fill', '#EEE');
$('#ctrlpointgrip_' + point + 'c1, #ctrlpointgrip_' + point + 'c2').attr('fill','#0FF'); $('#ctrlpointgrip_' + point + 'c1, #ctrlpointgrip_' + point + 'c2').attr('fill','#0FF');
$('#segline_' + point).attr('display','none');
current_path_pt = selected_pts[0]; current_path_pt = selected_pts[0];
updateSegLine();
updateSegLine(true);
// TODO: Set grips // TODO: Set grips
// call("selected", grips); // call("selected", grips);
@ -3419,13 +3418,12 @@ function BatchCommand(text) {
var addAllPointGripsToPath = function(pointToSelect) { var addAllPointGripsToPath = function(pointToSelect) {
// loop through and show all pointgrips // loop through and show all pointgrips
var closed = pathIsClosed();
var len = current_path_pts.length; var len = current_path_pts.length;
for (var i = 0; i < len; i += 2) { for (var i = 0; i < len; i += 2) {
var grip = getElem("pathpointgrip_"+i/2); var grip = getElem("pathpointgrip_"+i/2);
// Skip last point if closed // Skip last point if closed
if(!closed || i+2 < len) { if(!is_closed || i+2 < len) {
if (grip) { if (grip) {
assignAttributes(grip, { assignAttributes(grip, {
'cx': current_path_pts[i], 'cx': current_path_pts[i],
@ -3496,6 +3494,19 @@ function BatchCommand(text) {
grip.dblclick(function() { grip.dblclick(function() {
canvas.setSegType(); 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 // set up the point grip element and display it
@ -3506,53 +3517,37 @@ function BatchCommand(text) {
}); });
}; };
var pathIsClosed = function() { var updateSegLines = function() {
if(!current_path) return; // create segment lines
return getD().substr(-1,1).toLowerCase() == 'z'; var len = current_path_pts.length/2 - (is_closed?1:0);
}
var updateSegLine = function(next_node) { for(var i=0; i<len; i++) {
// create segment line var segLine = getElem("segline_"+i);
var segLine = getElem("segline"); if(!segLine) continue;
if(!segLine) {
var pointGripContainer = $('#pathpointgrip_container')[0];
segLine = document.createElementNS(svgns, "path");
assignAttributes(segLine, {
'id': "segline",
'fill': "none",
'stroke': "#0FF",
'stroke-width': 2,
'style':'pointer-events:none'
});
segLine = pointGripContainer.appendChild(segLine);
}
if(selected_pts.length != 1) {
segLine.setAttribute('display','none');
return;
}
if(!segLine.getAttribute('d')) { if($.inArray(i, selected_pts) != -1) {
var pt = getPathPoint(current_path_pt); // Point is selected, so calculate and display
segLine.setAttribute('d', 'M' + pt.join(',') + ' 0,0'); replacePathSeg(2, 0, getPathPoint(i, true), segLine);
}
segLine.setAttribute('display','inline');
if(current_path_pt+1 >= current_path.pathSegList.numberOfItems) { var seg = current_path.pathSegList.getItem(i+1);
segLine.setAttribute('display','none');
return;
}
if(!next_node) {
// Replace "M" val
replacePathSeg(2, 0, getPathPoint(current_path_pt, true), segLine);
} else {
var seg = current_path.pathSegList.getItem(current_path_pt+1);
var points = [seg.x, seg.y]; var points = [seg.x, seg.y];
if(seg.x1 != null && seg.x2 != null) { if(seg.x1 != null && seg.x2 != null) {
points.splice(2, 0, seg.x1, seg.y1, seg.x2, seg.y2); points.splice(2, 0, seg.x1, seg.y1, seg.x2, seg.y2);
} }
points = $.map(points, function(n){return n*current_zoom;}); points = $.map(points, function(n){return n*current_zoom;});
replacePathSeg(seg.pathSegType, 1, points, segLine); replacePathSeg(seg.pathSegType, 1, points, segLine);
segLine.setAttribute('display','inline');
} else {
// Point is not selected, so just hide
segLine.setAttribute('display','none');
}
// if(current_path_pt+1 >= current_path.pathSegList.numberOfItems) {
// segLine.setAttribute('display','none');
// return;
// }
} }
} }
@ -3560,8 +3555,6 @@ function BatchCommand(text) {
var x = mouse_x / current_zoom, var x = mouse_x / current_zoom,
y = mouse_y / current_zoom, y = mouse_y / current_zoom,
is_closed = pathIsClosed(),
i = current_path_pt_drag * 2, i = current_path_pt_drag * 2,
last_index = current_path_pts.length/2 - 1, last_index = current_path_pts.length/2 - 1,
is_first = current_path_pt_drag == 0, // || (is_closed && current_path_pt_drag == last_index); is_first = current_path_pt_drag == 0, // || (is_closed && current_path_pt_drag == last_index);
@ -3694,14 +3687,6 @@ function BatchCommand(text) {
addControlPointGrip(x2,y2, mouse_x,mouse_y, id1, true); addControlPointGrip(x2,y2, mouse_x,mouse_y, id1, true);
} }
} }
if(selected_pts.length > 1) {
getElem("segline").setAttribute('display','none');
} else {
updateSegLine();
if(next_type != 4) {
updateSegLine(true);
}
}
} }
var updateCurvedSegment = function(mouse_x, mouse_y, index, ctrl_num) { var updateCurvedSegment = function(mouse_x, mouse_y, index, ctrl_num) {
@ -3740,7 +3725,7 @@ function BatchCommand(text) {
c_item['y' + ctrl_num] = y; 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]); replacePathSeg(6, index+1, [c_item.x,c_item.y, c_item.x1,c_item.y1, c_item.x2,c_item.y2]);
updateSegLine(true); updateSegLines();
var grip = getElem("ctrlpointgrip_" + ctrl_pt_drag); var grip = getElem("ctrlpointgrip_" + ctrl_pt_drag);
if(grip) { if(grip) {
@ -3943,8 +3928,7 @@ function BatchCommand(text) {
setPointContainerTransform(xform); setPointContainerTransform(xform);
} }
resetPointGrips(); resetPointGrips();
updateSegLine(true); updateSegLines();
updateSegLine();
} }
return { return {
@ -3980,11 +3964,6 @@ function BatchCommand(text) {
} else { } else {
addNodeToSelection(current_path_pt); addNodeToSelection(current_path_pt);
} }
// justSelected = current_path_pt;
updateSegLine();
} else if(id.indexOf("ctrlpointgrip_") == 0) { } else if(id.indexOf("ctrlpointgrip_") == 0) {
current_ctrl_pt_drag = id.split('_')[1]; current_ctrl_pt_drag = id.split('_')[1];
var node_num = current_ctrl_pt_drag.split('c')[0]-0; var node_num = current_ctrl_pt_drag.split('c')[0]-0;
@ -4056,7 +4035,6 @@ function BatchCommand(text) {
pt_count = current_path_pts.length/2; pt_count = current_path_pts.length/2;
updateCurvedSegment(mouse_x, mouse_y, index, ctrl_num); updateCurvedSegment(mouse_x, mouse_y, index, ctrl_num);
if(link_control_pts) { if(link_control_pts) {
var is_closed = pathIsClosed();
if(ctrl_num == 1) { if(ctrl_num == 1) {
ctrl_num = 2; ctrl_num = 2;
index--; index--;
@ -4092,7 +4070,7 @@ function BatchCommand(text) {
m = transformListToTransform(tlist).matrix; m = transformListToTransform(tlist).matrix;
} }
if(pathIsClosed()) len -= 2; if(is_closed) len -= 2;
for(var i=0; i<len; i+=2) { for(var i=0; i<len; i+=2) {
var x = current_path_pts[i], var x = current_path_pts[i],
@ -4118,6 +4096,7 @@ function BatchCommand(text) {
removeAllNodesFromSelection(); removeAllNodesFromSelection();
selectNode(sel_pts); selectNode(sel_pts);
} }
updateSegLines();
}, },
mouseUp: function(evt, element, mouse_x, mouse_y) { mouseUp: function(evt, element, mouse_x, mouse_y) {
var tempJustSelected = justSelected; var tempJustSelected = justSelected;
@ -4251,7 +4230,7 @@ function BatchCommand(text) {
} }
// If connected, last point should equal first // If connected, last point should equal first
if(pathIsClosed()) { if(is_closed) {
current_path_pts[current_path_pts.length-2] = getPathPoint(0,true)[0]; current_path_pts[current_path_pts.length-2] = getPathPoint(0,true)[0];
current_path_pts[current_path_pts.length-1] = getPathPoint(0,true)[1]; current_path_pts[current_path_pts.length-1] = getPathPoint(0,true)[1];
} }
@ -4294,6 +4273,8 @@ function BatchCommand(text) {
}, },
toEditMode: function(element) { toEditMode: function(element) {
current_path = element; current_path = element;
is_closed = getD().substr(-1,1).toLowerCase() == 'z';
current_mode = "pathedit"; current_mode = "pathedit";
// This resets the pathedit selection in case it // This resets the pathedit selection in case it
@ -4401,8 +4382,7 @@ function BatchCommand(text) {
zoomChange: function() { zoomChange: function() {
if(current_mode == "pathedit") { if(current_mode == "pathedit") {
resetPointGrips(); resetPointGrips();
updateSegLine(true); updateSegLines();
updateSegLine();
} }
}, },
modeChange: function() { modeChange: function() {
@ -4419,12 +4399,13 @@ function BatchCommand(text) {
} }
}, },
getNodePoint: function() { getNodePoint: function() {
if(current_path_pt != -1) { var sel_pt = selected_pts.length ? selected_pts[0] : 0;
var pt = getPathPoint(current_path_pt);
var pt = getPathPoint(sel_pt);
var list = current_path.pathSegList; var list = current_path.pathSegList;
var segtype; var segtype;
if(list.numberOfItems > current_path_pt+1) { if(list.numberOfItems > sel_pt+1) {
segtype = list.getItem(current_path_pt+1).pathSegType; segtype = list.getItem(sel_pt+1).pathSegType;
} else { } else {
segtype = false; segtype = false;
} }
@ -4433,9 +4414,6 @@ function BatchCommand(text) {
y: pt[1], y: pt[1],
type: segtype type: segtype
} }
} else {
return false;
}
}, },
linkControlPoints: function(linkPoints) { linkControlPoints: function(linkPoints) {
link_control_pts = linkPoints; link_control_pts = linkPoints;
@ -4443,8 +4421,10 @@ function BatchCommand(text) {
clonePathNode: function() { clonePathNode: function() {
var d = getD(); var d = getD();
var pt = current_path_pt, list = current_path.pathSegList; var i = selected_pts.length,
nums = [];
while(i--) {
var pt = selected_pts[i], list = current_path.pathSegList;
if(pt+1 >= list.numberOfItems) { if(pt+1 >= list.numberOfItems) {
pt--; pt--;
} }
@ -4493,8 +4473,17 @@ function BatchCommand(text) {
// Update path_pts // Update path_pts
current_path_pts.splice(pt*2 + 2, 0, abs_x, abs_y); current_path_pts.splice(pt*2 + 2, 0, abs_x, abs_y);
// TODO: This should select the new path points but breaks
// when doing several times seleting many nodes
nums.push(pt + i);
nums.push(pt + i + 1);
}
resetPointGrips(); resetPointGrips();
selectNode(pt+1);
removeAllNodesFromSelection();
addNodeToSelection(nums);
endChanges(d, "Clone path node(s)"); endChanges(d, "Clone path node(s)");
@ -4502,8 +4491,6 @@ function BatchCommand(text) {
}, },
deletePathNode: function() { deletePathNode: function() {
if(!pathActions.canDeleteNodes) return; if(!pathActions.canDeleteNodes) return;
var is_closed = pathIsClosed();
var len = selected_pts.length; var len = selected_pts.length;
var d = getD(); var d = getD();
@ -4532,6 +4519,7 @@ function BatchCommand(text) {
} else { } else {
current_path_pts.splice(pt*2, 2); current_path_pts.splice(pt*2, 2);
} }
removeNodeFromSelection(pt);
list.removeItem(pt); list.removeItem(pt);
} }
@ -4542,7 +4530,7 @@ function BatchCommand(text) {
var cp = $(current_path); cp.attr('d',cp.attr('d')); var cp = $(current_path); cp.attr('d',cp.attr('d'));
} }
if(pt == last_pt && !is_closed) { if(pt == last_pt-1) {
pt--; pt--;
} }
@ -4552,13 +4540,17 @@ function BatchCommand(text) {
}, },
setPointContainerTransform: setPointContainerTransform, setPointContainerTransform: setPointContainerTransform,
setSegType: function(new_type) { setSegType: function(new_type) {
var grip = $('#pathpointgrip_' + current_path_pt);
var old_d = getD(); var old_d = getD();
var i = selected_pts.length;
while(i--) {
var sel_pt = selected_pts[i];
var grip = $('#pathpointgrip_' + sel_pt);
var index = grip[0].id.split('_')[1] - 0; var index = grip[0].id.split('_')[1] - 0;
var last_index = current_path_pts.length/2 - 1; var last_index = current_path_pts.length/2 - 1;
var is_closed = pathIsClosed();
if(!is_closed && index == last_index) { if(!is_closed && index == last_index) {
return; // Last point of unclosed path should do nothing return; // Last point of unclosed path should do nothing
@ -4608,7 +4600,7 @@ function BatchCommand(text) {
} }
replacePathSeg(new_type, next_index, points); replacePathSeg(new_type, next_index, points);
}
// d attribute needs to be manually updated for Webkit // d attribute needs to be manually updated for Webkit
if(isWebkit && current_path) { if(isWebkit && current_path) {
var fixed_d = pathActions.convertPath(current_path); var fixed_d = pathActions.convertPath(current_path);
@ -4617,7 +4609,7 @@ function BatchCommand(text) {
addAllPointGripsToPath(); addAllPointGripsToPath();
// recalculateDimensions(current_path); // recalculateDimensions(current_path);
updateSegLine(true); updateSegLines();
recalcRotatedPath(); recalcRotatedPath();
endChanges(old_d, text); endChanges(old_d, text);
@ -4631,7 +4623,7 @@ function BatchCommand(text) {
current_path_pts[current_path_pt*2 + num] = newValue-0; current_path_pts[current_path_pt*2 + num] = newValue-0;
current_path_pt_drag = current_path_pt; 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); 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"); endChanges(d, "Move path point");
}, },
// Convert a path to one with only absolute or relative values // Convert a path to one with only absolute or relative values