From 2549e8ddd6c6a29ec4d3330a964cd11948ab3b0c Mon Sep 17 00:00:00 2001 From: Jeff Schiller Date: Sat, 10 Oct 2009 21:46:06 +0000 Subject: [PATCH] Fix Issue 227: Move elements to a different layer. Also document all of the Layer API functions of SvgCanvas. git-svn-id: http://svg-edit.googlecode.com/svn/trunk@796 eee81c28-f429-11dd-99c0-75d572ba1ddd --- editor/locale/lang.en.js | 6 ++- editor/svg-editor.html | 8 +++ editor/svg-editor.js | 46 +++++++++++++++-- editor/svgcanvas.js | 106 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 160 insertions(+), 6 deletions(-) diff --git a/editor/locale/lang.en.js b/editor/locale/lang.en.js index 967def19..346d5699 100644 --- a/editor/locale/lang.en.js +++ b/editor/locale/lang.en.js @@ -113,5 +113,9 @@ {"id":"straight_segments","textContent":"Straight"}, {"id":"curve_segments","textContent":"Curve"}, {"id":"tool_node_clone","title":"Clone Node"}, -{"id":"tool_node_delete","title":"Delete Node"} +{"id":"tool_node_delete","title":"Delete Node"}, +{"id":"selLayerLabel","textContent":"layer:"}, +{"id":"selLayerNames","title":"Move selected elements to a different layer"} +{"id":"mselLayerLabel","textContent":"layer:"}, +{"id":"mselLayerNames","title":"Move selected elements to a different layer"} ]; diff --git a/editor/svg-editor.html b/editor/svg-editor.html index 51d0ef3c..19f5d4b1 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -117,6 +117,10 @@ script type="text/javascript" src="locale/locale.min.js"> angle: + layer: + @@ -139,6 +143,10 @@ script type="text/javascript" src="locale/locale.min.js"> | + layer: + Group diff --git a/editor/svg-editor.js b/editor/svg-editor.js index 4929117d..9846c0a7 100644 --- a/editor/svg-editor.js +++ b/editor/svg-editor.js @@ -190,6 +190,7 @@ function svg_edit_setup() { // updates the context panel tools based on the selected element var updateContextPanel = function() { var elem = selectedElement; + var currentLayer = svgCanvas.getCurrentLayer(); // No need to update anything else in rotate mode if (svgCanvas.getMode() == 'rotate' && elem != null) { @@ -205,6 +206,18 @@ function svg_edit_setup() { var is_node = (elem.id && elem.id.indexOf('polypointgrip') == 0); if(!is_node) { + // update the selected elements' layer + var opts = $('#selLayerNames option'); + for (var i = 0; i < opts.length; ++i) { + var opt = opts[i]; + if (currentLayer == opt.textContent) { + opt.setAttribute('selected', 'selected'); + } + else { + opt.removeAttribute('selected'); + } + } + $('#selected_panel').show(); } else { $('#poly_node_panel').show(); @@ -231,7 +244,6 @@ function svg_edit_setup() { var el_name = elem.tagName; if(panels[el_name]) { - var cur_panel = panels[el_name]; @@ -261,14 +273,26 @@ function svg_edit_setup() { if (svgCanvas.addedNew) { $('#text').focus().select(); } - } + } // text else if(el_name == 'image') { var xlinkNS="http://www.w3.org/1999/xlink"; $('#image_url').val(elem.getAttributeNS(xlinkNS, "href")); - } + } // image } } // if (elem != null) else if (multiselected) { + // update the selected layer + var opts = $('#mselLayerNames option'); + for (var i = 0; i < opts.length; ++i) { + var opt = opts[i]; + if (currentLayer == opt.textContent) { + opt.setAttribute('selected', 'selected'); + } + else { + opt.removeAttribute('selected'); + } + } + $('#multiselected_panel').show(); } @@ -343,7 +367,15 @@ function svg_edit_setup() { $('select').change(function(){$(this).blur();}); $('#group_opacity').change(function(){ - svgCanvas.setOpacity(this.options[this.selectedIndex].value); + svgCanvas.setOpacity(); + }); + + // fired when user wants to move elements to another layer + $('#selLayerNames,#mselLayerNames').change(function(){ + var destLayer = this.options[this.selectedIndex].value; + if (destLayer) { + svgCanvas.moveSelectedToLayer(destLayer); + } }); $('#font_size').change(function(){ @@ -1214,7 +1246,11 @@ function svg_edit_setup() { var populateLayers = function(){ var layerlist = $('#layerlist tbody'); + var selLayerNames = $('#selLayerNames'); + var mselLayerNames = $('#mselLayerNames'); layerlist.empty(); + selLayerNames.empty(); + mselLayerNames.empty(); var layer = svgCanvas.getNumLayers(); // we get the layers in the reverse z-order (the layer rendered on top is listed first) while (layer--) { @@ -1226,6 +1262,8 @@ function svg_edit_setup() { else { layerlist.append("" + name + ""); } + selLayerNames.append(""); + mselLayerNames.append(""); } // if we only have one layer, then always make sure that layer is selected // (This is really only required upon first initialization) diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index 265ab6a1..98ea5371 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -3192,6 +3192,15 @@ function BatchCommand(text) { return all_layers.length; }; + // Function: getLayer + // This function returns the name of the ith layer. If the index is out of range, + // then an empty string is returned. + // + // Parameters: + // i - the zero-based index of the layer you are querying. + // + // Returns: + // The name of the ith layer this.getLayer = function(i) { if (i >= 0 && i < canvas.getNumLayers()) { return all_layers[i][0]; @@ -3199,6 +3208,12 @@ function BatchCommand(text) { return ""; }; + // Function: getCurrentLayer + // This function returns the name of the currently selected layer. If an error occurs, + // an empty string is returned. + // + // Returns: + // The name of the currently active layer. this.getCurrentLayer = function() { for (var i = 0; i < all_layers.length; ++i) { if (all_layers[i][1] == current_layer) { @@ -3208,6 +3223,15 @@ function BatchCommand(text) { return ""; }; + // Function: setCurrentLayer + // This function sets the current layer. If the name is not a valid layer name, then this + // function returns false. Otherwise it returns true. This is not an undo-able action. + // + // Parameters: + // name - the name of the layer you want to switch to. + // + // Returns: + // true if the current layer was switched, otherwise false this.setCurrentLayer = function(name) { name = toXml(name); for (var i = 0; i < all_layers.length; ++i) { @@ -3224,6 +3248,17 @@ function BatchCommand(text) { return false; }; + // Function: renameCurrentLayer + // This function renames the current layer. This is an undo-able action. If the layer name + // is not valid (i.e. unique), then this function does nothing and returns false, otherwise + // it returns true. + // + // Parameters: + // newname - the new name you want to give the current layer. This name must be unique + // among all layer names. + // + // Returns: + // true if the rename succeeded, false otherwise. this.renameCurrentLayer = function(newname) { if (current_layer) { var oldLayer = current_layer; @@ -3259,6 +3294,17 @@ function BatchCommand(text) { return false; }; + // Function: setCurrentLayerPosition + // This function changes the position of the current layer to the new value. This is an + // undo-able action. If the new index is not valid, this function does nothing and returns + // false, otherwise it returns true. + // + // Parameters: + // newpos - The zero-based index of the new position of the layer. This should be between + // 0 and (number of layers - 1) + // + // Returns: + // true if the current layer position was changed, false otherwise. this.setCurrentLayerPosition = function(newpos) { if (current_layer && newpos >= 0 && newpos < all_layers.length) { for (var oldpos = 0; oldpos < all_layers.length; ++oldpos) { @@ -3290,10 +3336,18 @@ function BatchCommand(text) { } } - // TODO: if i differs, then MoveElementCommand return false; }; + // Function: getLayerVisibility + // This function returns whether the layer is visible. If the layer name is not valid, then + // this function returns false. + // + // Parameters: + // layername - the name of the layer which you want to query. + // + // Returns: + // The visibility state of the layer, or false if the layer name was invalid. this.getLayerVisibility = function(layername) { // find the layer var layer = null; @@ -3307,6 +3361,16 @@ function BatchCommand(text) { return (layer.getAttribute("display") != "none"); }; + // Function: setLayerVisibility + // This function sets the visibility of the layer. This is an undo-able action. If the + // layer name is not valid, this function return false, otherwise it returns true. + // + // Parameters: + // layername - the name of the layer to change the visibility + // bVisible - true/false, whether the layer should be visible + // + // Returns: + // true if the layer's visibility was set, false otherwise this.setLayerVisibility = function(layername, bVisible) { // find the layer var layer = null; @@ -3331,6 +3395,46 @@ function BatchCommand(text) { return true; }; + // Function: moveSelectedToLayer + // This function moves the selected elements to layername. This is an undo-able action. + // If the name is not a valid layer name, then false is returned. Otherwise it returns true. + // + // Parameters: + // layername - the name of the layer you want to which you want to move the selected elements + // + // Returns: + // true if the selected elements were moved to the layer, false otherwise. + this.moveSelectedToLayer = function(layername) { + // find the layer + var layer = null; + for (var i = 0; i < all_layers.length; ++i) { + if (all_layers[i][0] == layername) { + layer = all_layers[i][1]; + break; + } + } + if (!layer) return false; + + var batchCmd = new BatchCommand("Move Elements to Layer"); + + // loop for each selected element and move it + var selElems = selectedElements; + var i = selElems.length; + while (i--) { + var elem = selElems[i]; + if (!elem) continue; + var oldNextSibling = elem.nextSibling; + // TODO: this is pretty brittle! + var oldLayer = elem.parentNode; + layer.appendChild(elem); + batchCmd.addSubCommand(new MoveElementCommand(elem, oldNextSibling, oldLayer)); + } + + addCommandToHistory(batchCmd); + + return true; + }; + // used internally var getLayerName = function(g) { return $("title",g).text();