Fixed issue 226 and issue 393, allowing the cloning and merging of layers

git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1672 eee81c28-f429-11dd-99c0-75d572ba1ddd
master
Alexis Deveria 2010-08-19 18:30:19 +00:00
parent 3130f85ac6
commit 8345aa43d1
6 changed files with 200 additions and 50 deletions

View File

@ -36,7 +36,7 @@ if(jQuery)( function() {
$(this).mouseup( function(e) { $(this).mouseup( function(e) {
var srcElement = $(this); var srcElement = $(this);
$(this).unbind('mouseup'); $(this).unbind('mouseup');
if( evt.button == 2 ) { if( evt.button == 2 || o.allowLeft) {
e.stopPropagation(); e.stopPropagation();
// Hide context menus that may be showing // Hide context menus that may be showing
$(".contextMenu").hide(); $(".contextMenu").hide();
@ -51,8 +51,8 @@ if(jQuery)( function() {
var x_off = $(window).width() - menu.width(), var x_off = $(window).width() - menu.width(),
y_off = $(window).height() - menu.height(); y_off = $(window).height() - menu.height();
if(x > x_off) x = x_off-5; if(x > x_off) x = x_off-15;
if(y > y_off) y = y_off-5; if(y > y_off) y = y_off-15;
// Show the menu // Show the menu
$(document).unbind('click'); $(document).unbind('click');

View File

@ -540,6 +540,18 @@
</svg> </svg>
</g> </g>
<g id="context_menu">
<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg">
<path stroke-width="0" id="svg_11" d="m4.5,46.5l52,0l-26,38l-26,-38z" stroke="#000" fill="#000"/>
<g id="svg_16">
<line stroke-width="10" id="svg_12" y2="27.5" x2="117.5" y1="27.5" x1="59.5" stroke="#000" fill="#000"/>
<line id="svg_13" stroke-width="10" y2="51.5" x2="117.5" y1="51.5" x1="59.5" stroke="#000" fill="#000"/>
<line id="svg_14" stroke-width="10" y2="73.5" x2="117.5" y1="73.5" x1="59.5" stroke="#000" fill="#000"/>
<line id="svg_15" stroke-width="10" y2="97.5" x2="117.5" y1="97.5" x1="59.5" stroke="#000" fill="#000"/>
</g>
</svg>
</g>
<g id="move_bottom"> <g id="move_bottom">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23"> <svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23">
<defs> <defs>

View File

@ -190,7 +190,7 @@
padding: 0px; padding: 0px;
padding-left: 2px; padding-left: 2px;
padding-right: 2px; padding-right: 2px;
width: 106px; width: 123px;
height: 20px; height: 20px;
border-right: 1px solid #FFFFFF; border-right: 1px solid #FFFFFF;
border-bottom: 1px solid #FFFFFF; border-bottom: 1px solid #FFFFFF;
@ -212,6 +212,10 @@
margin-right: 3px; margin-right: 3px;
} }
#svg_editor .layer_button:last-child {
margin-right: 0;
}
#svg_editor .layer_buttonpressed { #svg_editor .layer_buttonpressed {
width: 14px; width: 14px;
height: 14px; height: 14px;
@ -226,7 +230,7 @@
#svg_editor #layerlist { #svg_editor #layerlist {
margin: 1px; margin: 1px;
padding: 0px; padding: 0px;
width: 110px; width: 127px;
border-collapse: collapse; border-collapse: collapse;
border: 1px solid #808080; border: 1px solid #808080;
background-color: #FFFFFF; background-color: #FFFFFF;

View File

@ -62,6 +62,7 @@ script type="text/javascript" src="locale/locale.min.js"></script-->
<div id="layer_rename" class="layer_button" title="Rename Layer"></div> <div id="layer_rename" class="layer_button" title="Rename Layer"></div>
<div id="layer_up" class="layer_button" title="Move Layer Up"></div> <div id="layer_up" class="layer_button" title="Move Layer Up"></div>
<div id="layer_down" class="layer_button" title="Move Layer Down"></div> <div id="layer_down" class="layer_button" title="Move Layer Down"></div>
<div id="layer_moreopts" class="layer_button" title="More Options"></div>
</fieldset> </fieldset>
<table id="layerlist"> <table id="layerlist">
@ -674,5 +675,13 @@ script type="text/javascript" src="locale/locale.min.js"></script-->
<li class="separator"><a href="#delete">Delete</a></li> <li class="separator"><a href="#delete">Delete</a></li>
</ul> </ul>
<ul id="cmenu_layers" class="contextMenu">
<li><a href="#dupe">Duplicate Layer...</a></li>
<li><a href="#delete">Delete Layer</a></li>
<li><a href="#merge_down">Merge Down</a></li>
<li><a href="#merge_all">Merge All</a></li>
</ul>
</body> </body>
</html> </html>

View File

@ -355,6 +355,7 @@
'#layer_up':'go_up', '#layer_up':'go_up',
'#layer_down':'go_down', '#layer_down':'go_down',
'#layer_moreopts':'context_menu',
'#layerlist td.layervis':'eye', '#layerlist td.layervis':'eye',
'#tool_source_save,#tool_docprops_save':'ok', '#tool_source_save,#tool_docprops_save':'ok',
@ -443,6 +444,7 @@
default_img_url = curConfig.imgPath + "logo.png", default_img_url = curConfig.imgPath + "logo.png",
workarea = $("#workarea"), workarea = $("#workarea"),
canv_menu = $("#cmenu_canvas"), canv_menu = $("#cmenu_canvas"),
layer_menu = $("#cmenu_layers"),
show_save_warning = false, show_save_warning = false,
exportWindow = null, exportWindow = null,
tool_scale = 1; tool_scale = 1;
@ -3174,30 +3176,24 @@
}); });
$('#layer_new').click(function() { $('#layer_new').click(function() {
var curNames = new Array(svgCanvas.getNumLayers()); var i = svgCanvas.getNumLayers();
for (var i = 0; i < curNames.length; ++i) { curNames[i] = svgCanvas.getLayer(i); } do {
var uniqName = uiStrings.layer + " " + ++i;
} while(svgCanvas.hasLayer(uniqName));
var j = (curNames.length+1);
var uniqName = uiStrings.layer + " " + j;
while ($.inArray(uniqName, curNames) != -1) {
j++;
uniqName = uiStrings.layer + " " + j;
}
$.prompt(uiStrings.enterUniqueLayerName,uniqName, function(newName) { $.prompt(uiStrings.enterUniqueLayerName,uniqName, function(newName) {
if (!newName) return; if (!newName) return;
if ($.inArray(newName, curNames) != -1) { if (svgCanvas.hasLayer(newName)) {
$.alert(uiStrings.dupeLayerName); $.alert(uiStrings.dupeLayerName);
return; return;
} }
svgCanvas.createLayer(newName); svgCanvas.createLayer(newName);
updateContextPanel(); updateContextPanel();
populateLayers(); populateLayers();
$('#layerlist tr.layer').removeClass("layersel");
$('#layerlist tr.layer:first').addClass("layersel");
}); });
}); });
$('#layer_delete').click(function() { function deleteLayer() {
if (svgCanvas.deleteCurrentLayer()) { if (svgCanvas.deleteCurrentLayer()) {
updateContextPanel(); updateContextPanel();
populateLayers(); populateLayers();
@ -3207,32 +3203,48 @@
$('#layerlist tr.layer').removeClass("layersel"); $('#layerlist tr.layer').removeClass("layersel");
$('#layerlist tr.layer:first').addClass("layersel"); $('#layerlist tr.layer:first').addClass("layersel");
} }
}); }
$('#layer_up').click(function() { function cloneLayer() {
// find index position of selected option var name = svgCanvas.getCurrentLayer() + ' copy';
var curIndex = $('#layerlist tr.layersel').prevAll().length;
if (curIndex > 0) { $.prompt(uiStrings.enterUniqueLayerName, name, function(newName) {
var total = $('#layerlist tr.layer').length; if (!newName) return;
curIndex--; if (svgCanvas.hasLayer(newName)) {
$.alert(uiStrings.dupeLayerName);
return;
}
svgCanvas.cloneLayer(newName);
updateContextPanel();
populateLayers();
});
}
function mergeLayer() {
if($('#layerlist tr.layersel').index() == svgCanvas.getNumLayers()-1) return;
svgCanvas.mergeLayer();
updateContextPanel();
populateLayers();
}
function moveLayer(pos) {
var curIndex = $('#layerlist tr.layersel').index();
var total = svgCanvas.getNumLayers();
if(curIndex > 0 || curIndex < total-1) {
curIndex += pos;
svgCanvas.setCurrentLayerPosition(total-curIndex-1); svgCanvas.setCurrentLayerPosition(total-curIndex-1);
populateLayers(); populateLayers();
$('#layerlist tr.layer').removeClass("layersel");
$('#layerlist tr.layer:eq('+curIndex+')').addClass("layersel");
} }
}
$('#layer_delete').click(deleteLayer);
$('#layer_up').click(function() {
moveLayer(-1);
}); });
$('#layer_down').click(function() { $('#layer_down').click(function() {
// find index position of selected option moveLayer(1);
var curIndex = $('#layerlist tr.layersel').prevAll().length;
var total = $('#layerlist tr.layer').length;
if (curIndex < total-1) {
curIndex++;
svgCanvas.setCurrentLayerPosition(total-curIndex-1);
populateLayers();
$('#layerlist tr.layer').removeClass("layersel");
$('#layerlist tr.layer:eq('+curIndex+')').addClass("layersel");
}
}); });
$('#layer_rename').click(function() { $('#layer_rename').click(function() {
@ -3240,22 +3252,13 @@
var oldName = $('#layerlist tr.layersel td.layername').text(); var oldName = $('#layerlist tr.layersel td.layername').text();
$.prompt(uiStrings.enterNewLayerName,"", function(newName) { $.prompt(uiStrings.enterNewLayerName,"", function(newName) {
if (!newName) return; if (!newName) return;
if (oldName == newName) { if (oldName == newName || svgCanvas.hasLayer(newName)) {
$.alert(uiStrings.layerHasThatName);
return;
}
var curNames = new Array(svgCanvas.getNumLayers());
for (var i = 0; i < curNames.length; ++i) { curNames[i] = svgCanvas.getLayer(i); }
if ($.inArray(newName, curNames) != -1) {
$.alert(uiStrings.layerHasThatName); $.alert(uiStrings.layerHasThatName);
return; return;
} }
svgCanvas.renameCurrentLayer(newName); svgCanvas.renameCurrentLayer(newName);
populateLayers(); populateLayers();
$('#layerlist tr.layer').removeClass("layersel");
$('#layerlist tr.layer:eq('+curIndex+')').addClass("layersel");
}); });
}); });
@ -3377,7 +3380,7 @@
} }
// handle selection of layer // handle selection of layer
$('#layerlist td.layername') $('#layerlist td.layername')
.click(function(evt){ .mouseup(function(evt){
$('#layerlist tr.layer').removeClass("layersel"); $('#layerlist tr.layer').removeClass("layersel");
var row = $(this.parentNode); var row = $(this.parentNode);
row.addClass("layersel"); row.addClass("layersel");
@ -3752,6 +3755,40 @@
} }
}); });
var lmenu_func = function(action, el, pos) {
switch ( action ) {
case 'dupe':
cloneLayer();
break;
case 'delete':
deleteLayer();
break;
case 'merge_down':
mergeLayer();
break;
case 'merge_all':
svgCanvas.mergeAllLayers();
updateContextPanel();
populateLayers();
break;
}
}
$("#layerlist").contextMenu({
menu: 'cmenu_layers',
inSpeed: 0
},
lmenu_func
);
$("#layer_moreopts").contextMenu({
menu: 'cmenu_layers',
inSpeed: 0,
allowLeft: true
},
lmenu_func
);
$('.contextMenu li').mousedown(function(ev) { $('.contextMenu li').mousedown(function(ev) {
ev.preventDefault(); ev.preventDefault();
}) })

View File

@ -8344,6 +8344,36 @@ this.createLayer = function(name) {
call("changed", [new_layer]); call("changed", [new_layer]);
}; };
// Function: cloneLayer
// Creates a new top-level layer in the drawing with the given name, copies all the current layer's contents
// to it, and then clears the selection This function then calls the 'changed' handler.
// This is an undoable action.
//
// Parameters:
// name - The given name
this.cloneLayer = function(name) {
var batchCmd = new BatchCommand("Duplicate Layer");
var new_layer = svgdoc.createElementNS(svgns, "g");
var layer_title = svgdoc.createElementNS(svgns, "title");
layer_title.textContent = name;
new_layer.appendChild(layer_title);
$(current_layer).after(new_layer);
var childs = current_layer.childNodes;
for(var i = 0; i < childs.length; i++) {
var ch = childs[i];
if(ch.localName == 'title') continue;
new_layer.appendChild(copyElem(ch));
}
clearSelection();
identifyLayers();
batchCmd.addSubCommand(new InsertElementCommand(new_layer));
addCommandToHistory(batchCmd);
canvas.setCurrentLayer(name);
call("changed", [new_layer]);
};
// Function: deleteCurrentLayer // Function: deleteCurrentLayer
// Deletes the current layer from the drawing and then clears the selection. This function // Deletes the current layer from the drawing and then clears the selection. This function
// then calls the 'changed' handler. This is an undoable action. // then calls the 'changed' handler. This is an undoable action.
@ -8364,6 +8394,15 @@ this.deleteCurrentLayer = function() {
return false; return false;
}; };
// Function: hasLayer
// Check if layer with given name already exists
this.hasLayer = function(name) {
for(var i = 0; i < all_layers.length; i++) {
if(all_layers[i][0] == name) return true;
}
return false;
};
// Function: getNumLayers // Function: getNumLayers
// Returns the number of layers in the current drawing. // Returns the number of layers in the current drawing.
// //
@ -8615,6 +8654,55 @@ this.moveSelectedToLayer = function(layername) {
return true; return true;
}; };
this.mergeLayer = function(skipHistory) {
var batchCmd = new BatchCommand("Merge Layer");
var prev = $(current_layer).prev()[0];
if(!prev) return;
var childs = current_layer.childNodes;
var len = childs.length;
batchCmd.addSubCommand(new RemoveElementCommand(current_layer, svgcontent));
while(current_layer.firstChild) {
var ch = current_layer.firstChild;
if(ch.localName == 'title') {
batchCmd.addSubCommand(new RemoveElementCommand(ch, current_layer));
current_layer.removeChild(ch);
continue;
}
var oldNextSibling = ch.nextSibling;
prev.appendChild(ch);
batchCmd.addSubCommand(new MoveElementCommand(ch, oldNextSibling, current_layer));
}
// Remove current layer
svgcontent.removeChild(current_layer);
if(!skipHistory) {
clearSelection();
identifyLayers();
call("changed", [svgcontent]);
addCommandToHistory(batchCmd);
}
current_layer = prev;
return batchCmd;
}
this.mergeAllLayers = function() {
var batchCmd = new BatchCommand("Merge all Layers");
current_layer = all_layers[all_layers.length-1][1];
while($(svgcontent).children('g').length > 1) {
batchCmd.addSubCommand(canvas.mergeLayer(true));
}
clearSelection();
identifyLayers();
call("changed", [svgcontent]);
addCommandToHistory(batchCmd);
}
// Function: getLayerOpacity // Function: getLayerOpacity
// Returns the opacity of the given layer. If the input name is not a layer, null is returned. // Returns the opacity of the given layer. If the input name is not a layer, null is returned.
// //