Added convert-to-group option for SVG elements, added label (title) field for groups/SVGs
git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1643 eee81c28-f429-11dd-99c0-75d572ba1dddmaster
parent
1a9b08bed6
commit
b2f2df4eac
|
@ -227,6 +227,12 @@ script type="text/javascript" src="locale/locale.min.js"></script-->
|
|||
|
||||
<div id="g_panel">
|
||||
<div class="tool_sep"></div>
|
||||
|
||||
<label id="group_title" title="Group identification label">
|
||||
<span>label:</span>
|
||||
<input id="g_title" data-attr="title" size="10" type="text"/>
|
||||
</label>
|
||||
|
||||
<div class="push_button" id="tool_ungroup" title="Ungroup Elements [G]"></div>
|
||||
</div>
|
||||
|
||||
|
@ -353,6 +359,10 @@ script type="text/javascript" src="locale/locale.min.js"></script-->
|
|||
<input id="text" type="text" size="35"/>
|
||||
</div>
|
||||
|
||||
<div id="gsvg_panel">
|
||||
<!-- Add viewBox field here? -->
|
||||
</div>
|
||||
|
||||
<div id="path_node_panel">
|
||||
<div class="tool_sep"></div>
|
||||
<div class="tool_button" id="tool_node_link" title="Link Control Points"></div>
|
||||
|
|
|
@ -207,7 +207,15 @@
|
|||
|
||||
var extFunc = function() {
|
||||
$.each(curConfig.extensions, function() {
|
||||
$.getScript(curConfig.extPath + this);
|
||||
var extname = this;
|
||||
$.getScript(curConfig.extPath + extname, function(d) {
|
||||
// Fails locally in Chrome 5
|
||||
if(!d) {
|
||||
var s = document.createElement('script');
|
||||
s.src = curConfig.extPath + extname;
|
||||
document.querySelector('head').appendChild(s);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1277,7 +1285,7 @@
|
|||
}
|
||||
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();
|
||||
#ellipse_panel, #line_panel, #text_panel, #image_panel, #gsvg_panel').hide();
|
||||
if (elem != null) {
|
||||
var elname = elem.nodeName;
|
||||
|
||||
|
@ -1366,13 +1374,14 @@
|
|||
circle: ['cx','cy','r'],
|
||||
ellipse: ['cx','cy','rx','ry'],
|
||||
line: ['x1','y1','x2','y2'],
|
||||
text: []
|
||||
text: [],
|
||||
gsvg: []
|
||||
};
|
||||
|
||||
var el_name = elem.tagName;
|
||||
|
||||
if($(elem).data('gsvg')) {
|
||||
el_name = 'svg';
|
||||
$('#gsvg_panel').show();
|
||||
}
|
||||
|
||||
if(panels[el_name]) {
|
||||
|
@ -1411,6 +1420,11 @@
|
|||
var href = elem.getAttributeNS(xlinkNS, "href");
|
||||
setImageURL(href);
|
||||
} // image
|
||||
else if(el_name == 'g') {
|
||||
console.log('is group');
|
||||
var title = svgCanvas.getTitle();
|
||||
$('#g_title').val(title);
|
||||
}
|
||||
}
|
||||
} // if (elem != null)
|
||||
else if (multiselected) {
|
||||
|
@ -1606,6 +1620,11 @@
|
|||
setImageURL(this.value);
|
||||
});
|
||||
|
||||
$('#g_title').change(function() {
|
||||
svgCanvas.setGroupTitle(this.value);
|
||||
$(this).width(17 + this.value.length * 5);
|
||||
});
|
||||
|
||||
$('.attr_changer').change(function() {
|
||||
var attr = this.getAttribute("data-attr");
|
||||
var val = this.value;
|
||||
|
|
|
@ -3280,6 +3280,22 @@ var recalculateDimensions = this.recalculateDimensions = function(selected) {
|
|||
|
||||
var m = transformListToTransform(childTlist).matrix;
|
||||
|
||||
// Convert a matrix to a scale if applicable
|
||||
// if(hasMatrixTransform(childTlist) && childTlist.numberOfItems == 1) {
|
||||
// if(m.b==0 && m.c==0 && m.e==0 && m.f==0) {
|
||||
// childTlist.removeItem(0);
|
||||
// var translateOrigin = svgroot.createSVGTransform(),
|
||||
// scale = svgroot.createSVGTransform(),
|
||||
// translateBack = svgroot.createSVGTransform();
|
||||
// translateOrigin.setTranslate(0, 0);
|
||||
// scale.setScale(m.a, m.d);
|
||||
// translateBack.setTranslate(0, 0);
|
||||
// childTlist.appendItem(translateBack);
|
||||
// childTlist.appendItem(scale);
|
||||
// childTlist.appendItem(translateOrigin);
|
||||
// }
|
||||
// }
|
||||
|
||||
var angle = getRotationAngle(child);
|
||||
var old_start_transform = start_transform;
|
||||
var childxforms = [];
|
||||
|
@ -3444,6 +3460,8 @@ var recalculateDimensions = this.recalculateDimensions = function(selected) {
|
|||
start_transform = child.getAttribute("transform");
|
||||
var childTlist = getTransformList(child);
|
||||
|
||||
if (!childTlist) continue;
|
||||
|
||||
var em = matrixMultiply(m, transformListToTransform(childTlist).matrix);
|
||||
var e2m = svgroot.createSVGTransform();
|
||||
e2m.setMatrix(em);
|
||||
|
@ -7827,6 +7845,89 @@ var uniquifyElems = this.uniquifyElems = function(g) {
|
|||
obj_num++;
|
||||
}
|
||||
|
||||
// Function: svgToGroup
|
||||
// Converts a child SVG element to a group
|
||||
var svgToGroup = this.svgToGroup = function(elem) {
|
||||
if(!elem) {
|
||||
elem = selectedElements[0];
|
||||
}
|
||||
if(elem.tagName == 'g') {
|
||||
// Use the gsvg as the new group
|
||||
var svg = elem.firstChild;
|
||||
var pt = $(svg).attr(['x', 'y']);
|
||||
|
||||
$(elem.firstChild.firstChild).unwrap();
|
||||
$(elem).removeData('gsvg');
|
||||
|
||||
var tlist = getTransformList(elem);
|
||||
var xform = svgroot.createSVGTransform();
|
||||
xform.setTranslate(pt.x, pt.y);
|
||||
tlist.appendItem(xform);
|
||||
recalculateDimensions(elem);
|
||||
call("selected", [elem]);
|
||||
// addToSelection(elem]);
|
||||
return;
|
||||
// elem = $(elem).data('gsvg');
|
||||
}
|
||||
if(elem.tagName != 'svg') return;
|
||||
|
||||
var g = svgdoc.createElementNS(svgns, "g");
|
||||
while (elem.hasChildNodes())
|
||||
g.appendChild(elem.firstChild);
|
||||
// if (ts)
|
||||
// g.setAttribute("transform", ts);
|
||||
|
||||
var parent = elem.parentNode;
|
||||
|
||||
if(parent) parent.removeChild(elem);
|
||||
|
||||
uniquifyElems(g);
|
||||
|
||||
// now give the g itself a new id
|
||||
g.id = getNextId();
|
||||
|
||||
current_layer.appendChild(g);
|
||||
|
||||
// change image href vals if possible
|
||||
// $(svgcontent).find('image').each(function() {
|
||||
// var image = this;
|
||||
// preventClickDefault(image);
|
||||
// var val = this.getAttributeNS(xlinkns, "href");
|
||||
// if(val.indexOf('data:') === 0) {
|
||||
// // Check if an SVG-edit data URI
|
||||
// var m = val.match(/svgedit_url=(.*?);/);
|
||||
// if(m) {
|
||||
// var url = decodeURIComponent(m[1]);
|
||||
// $(new Image()).load(function() {
|
||||
// image.setAttributeNS(xlinkns,'xlink:href',url);
|
||||
// }).attr('src',url);
|
||||
// }
|
||||
// }
|
||||
// // Add to encodableImages if it loads
|
||||
// canvas.embedImage(val);
|
||||
// });
|
||||
|
||||
|
||||
var batchCmd = new BatchCommand();
|
||||
|
||||
if(parent) {
|
||||
batchCmd.addSubCommand(new RemoveElementCommand(elem, parent));
|
||||
batchCmd.addSubCommand(new InsertElementCommand(g));
|
||||
}
|
||||
|
||||
// recalculate dimensions on the top-level children so that unnecessary transforms
|
||||
// are removed
|
||||
walkTreePost(svgcontent, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}});
|
||||
|
||||
// batchCmd.addSubCommand(new InsertElementCommand(svgcontent));
|
||||
|
||||
// reset transform lists
|
||||
// svgTransformLists = {};
|
||||
clearSelection();
|
||||
addToSelection([g]);
|
||||
addCommandToHistory(batchCmd);
|
||||
}
|
||||
|
||||
//
|
||||
// Function: setSvgString
|
||||
// This function sets the current drawing as the input SVG XML.
|
||||
|
@ -8084,62 +8185,15 @@ this.importSvgString = function(xmlString, toElements) {
|
|||
return;
|
||||
}
|
||||
|
||||
var g = svgToGroup(importedNode);
|
||||
|
||||
|
||||
// TODO: Find way to add this in a recalculateDimensions-parsable way
|
||||
// if (vb[0] != 0 || vb[1] != 0)
|
||||
// ts = "translate(" + (-vb[0]) + "," + (-vb[1]) + ") " + ts;
|
||||
|
||||
// add all children of the imported <svg> to the <g> we create
|
||||
var g = svgdoc.createElementNS(svgns, "g");
|
||||
while (importedNode.hasChildNodes())
|
||||
g.appendChild(importedNode.firstChild);
|
||||
if (ts)
|
||||
g.setAttribute("transform", ts);
|
||||
|
||||
uniquifyElems(g);
|
||||
|
||||
// now give the g itself a new id
|
||||
g.id = getNextId();
|
||||
|
||||
current_layer.appendChild(g);
|
||||
|
||||
// change image href vals if possible
|
||||
// $(svgcontent).find('image').each(function() {
|
||||
// var image = this;
|
||||
// preventClickDefault(image);
|
||||
// var val = this.getAttributeNS(xlinkns, "href");
|
||||
// if(val.indexOf('data:') === 0) {
|
||||
// // Check if an SVG-edit data URI
|
||||
// var m = val.match(/svgedit_url=(.*?);/);
|
||||
// if(m) {
|
||||
// var url = decodeURIComponent(m[1]);
|
||||
// $(new Image()).load(function() {
|
||||
// image.setAttributeNS(xlinkns,'xlink:href',url);
|
||||
// }).attr('src',url);
|
||||
// }
|
||||
// }
|
||||
// // Add to encodableImages if it loads
|
||||
// canvas.embedImage(val);
|
||||
// });
|
||||
|
||||
|
||||
// recalculate dimensions on the top-level children so that unnecessary transforms
|
||||
// are removed
|
||||
walkTreePost(svgcontent, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}});
|
||||
|
||||
|
||||
batchCmd.addSubCommand(new InsertElementCommand(svgcontent));
|
||||
|
||||
// reset zoom - TODO: why?
|
||||
// current_zoom = 1;
|
||||
|
||||
// identify layers
|
||||
// identifyLayers();
|
||||
|
||||
// reset transform lists
|
||||
svgTransformLists = {};
|
||||
clearSelection();
|
||||
|
||||
addCommandToHistory(batchCmd);
|
||||
call("changed", [svgcontent]);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
|
@ -8640,9 +8694,13 @@ this.setConfig = function(opts) {
|
|||
}
|
||||
|
||||
// Function: getDocumentTitle
|
||||
// Returns the current document title or an empty string if not found
|
||||
this.getDocumentTitle = function() {
|
||||
var childs = svgcontent.childNodes;
|
||||
// Returns the current group/SVG's title contents
|
||||
this.getTitle = function(elem) {
|
||||
elem = elem || selectedElements[0];
|
||||
if(!elem) return;
|
||||
elem = $(elem).data('gsvg') || elem;
|
||||
|
||||
var childs = elem.childNodes;
|
||||
for (var i=0; i<childs.length; i++) {
|
||||
if(childs[i].nodeName == 'title') {
|
||||
return childs[i].textContent;
|
||||
|
@ -8651,6 +8709,43 @@ this.getDocumentTitle = function() {
|
|||
return '';
|
||||
}
|
||||
|
||||
// Function: setGroupTitle
|
||||
// Sets the group/SVG's title content
|
||||
// TODO: Combine this with setDocumentTitle
|
||||
this.setGroupTitle = function(val) {
|
||||
var elem = selectedElements[0];
|
||||
elem = $(elem).data('gsvg') || elem;
|
||||
|
||||
var ts = $(elem).children('title');
|
||||
|
||||
var batchCmd = new BatchCommand("Set Label");
|
||||
|
||||
if(!val.length) {
|
||||
// Remove title element
|
||||
batchCmd.addSubCommand(new RemoveElementCommand(ts[i], elem));
|
||||
ts.remove();
|
||||
} else if(ts.length) {
|
||||
// Change title contents
|
||||
var title = ts[0];
|
||||
batchCmd.addSubCommand(new ChangeElementCommand(title, {'#text': title.textContent}));
|
||||
title.textContent = val;
|
||||
} else {
|
||||
// Add title element
|
||||
title = svgdoc.createElementNS(svgns, "title");
|
||||
title.textContent = val;
|
||||
$(elem).prepend(title);
|
||||
batchCmd.addSubCommand(new InsertElementCommand(title));
|
||||
}
|
||||
|
||||
addCommandToHistory(batchCmd);
|
||||
}
|
||||
|
||||
// Function: getDocumentTitle
|
||||
// Returns the current document title or an empty string if not found
|
||||
this.getDocumentTitle = function() {
|
||||
return canvas.getTitle(svgcontent);
|
||||
}
|
||||
|
||||
// Function: setDocumentTitle
|
||||
// Adds/updates a title element for the document with the given name.
|
||||
// This is an undoable action
|
||||
|
@ -9915,6 +10010,12 @@ this.groupSelectedElements = function() {
|
|||
this.ungroupSelectedElement = function() {
|
||||
var g = selectedElements[0];
|
||||
if (g.tagName == "g") {
|
||||
if($(g).data('gsvg')) {
|
||||
// Is gsvg, so actually convert to group
|
||||
svgToGroup(g);
|
||||
return;
|
||||
}
|
||||
|
||||
var batchCmd = new BatchCommand("Ungroup Elements");
|
||||
var parent = g.parentNode;
|
||||
var anchor = g.previousSibling;
|
||||
|
@ -9941,6 +10042,14 @@ this.ungroupSelectedElement = function() {
|
|||
var elem = g.firstChild;
|
||||
var oldNextSibling = elem.nextSibling;
|
||||
var oldParent = elem.parentNode;
|
||||
|
||||
// Remove child title elements
|
||||
if(elem.tagName == 'title') {
|
||||
batchCmd.addSubCommand(new RemoveElementCommand(elem, oldParent));
|
||||
oldParent.removeChild(elem);
|
||||
continue;
|
||||
}
|
||||
|
||||
children[i++] = elem = parent.insertBefore(elem, anchor);
|
||||
batchCmd.addSubCommand(new MoveElementCommand(elem, oldNextSibling, oldParent));
|
||||
|
||||
|
@ -9989,6 +10098,9 @@ this.ungroupSelectedElement = function() {
|
|||
|
||||
var chtlist = getTransformList(elem);
|
||||
|
||||
// Hopefully not a problem to add this. Necessary for elements like <desc/>
|
||||
if(!chtlist) continue;
|
||||
|
||||
if (glist.numberOfItems) {
|
||||
// TODO: if the group's transform is just a rotate, we can always transfer the
|
||||
// rotate() down to the children (collapsing consecutive rotates and factoring
|
||||
|
|
Loading…
Reference in New Issue