From cda961e7ba887a90d27cfbfbd879ed2fa4e07394 Mon Sep 17 00:00:00 2001 From: Jeff Schiller Date: Tue, 22 Sep 2009 01:00:24 +0000 Subject: [PATCH] More work on Issue 73: Can now create and delete layers with undo/redo git-svn-id: http://svg-edit.googlecode.com/svn/trunk@670 eee81c28-f429-11dd-99c0-75d572ba1ddd --- editor/svg-editor.css | 11 ++++ editor/svg-editor.js | 33 +++++++++++- editor/svgcanvas.js | 116 ++++++++++++++++++++++++++++++------------ 3 files changed, 125 insertions(+), 35 deletions(-) diff --git a/editor/svg-editor.css b/editor/svg-editor.css index 55fc2f1a..0d83f95d 100644 --- a/editor/svg-editor.css +++ b/editor/svg-editor.css @@ -107,6 +107,17 @@ body { cursor: pointer; } +#svg_editor .layer_buttonpressed { + width: 15px; + height: 15px; + padding: 1px; + border-right: 1px solid #FFFFFF; + border-bottom: 1px solid #FFFFFF; + border-left: 1px solid #808080; + border-top: 1px solid #808080; + cursor: pointer; +} + #svg_editor #layerlist { margin: 0px; width: 110px; diff --git a/editor/svg-editor.js b/editor/svg-editor.js index 67dd7b4c..2be7ddc1 100644 --- a/editor/svg-editor.js +++ b/editor/svg-editor.js @@ -653,13 +653,18 @@ function svg_edit_setup() { }; var clickUndo = function(){ - if (svgCanvas.getUndoStackSize() > 0) + if (svgCanvas.getUndoStackSize() > 0) { svgCanvas.undo(); + console.log('yooya'); + populateLayers(); + } }; var clickRedo = function(){ - if (svgCanvas.getRedoStackSize() > 0) + if (svgCanvas.getRedoStackSize() > 0) { svgCanvas.redo(); + populateLayers(); + } }; var clickGroup = function(){ @@ -1068,9 +1073,33 @@ function svg_edit_setup() { }).mouseout(function() { $(this).removeClass('tool_flyout_button_current'); }); + + $('.layer_button').mousedown(function() { + $(this).addClass('layer_buttonpressed'); + }).mouseout(function() { + $(this).removeClass('layer_buttonpressed'); + }).mouseup(function() { + $(this).removeClass('layer_buttonpressed'); + }); + + $('#layer_new').click(function() { + svgCanvas.createLayer("New Layer"); + updateContextPanel(); + populateLayers(); + $('#layerlist option:last').attr("selected", "selected"); + }); + + $('#layer_delete').click(function() { + if (svgCanvas.deleteCurrentLayer()) { + updateContextPanel(); + populateLayers(); + $('#layerlist option:last').attr("selected", "selected"); + } + }); var populateLayers = function(){ var layerlen = svgCanvas.getNumLayers(); + console.log('layerlen=' + layerlen); $('#layerlist').empty(); for (var layer = 0; layer < layerlen; ++layer) { var name = svgCanvas.getLayer(layer); diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index afb78586..84bff35a 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -1,13 +1,9 @@ /* Issue 73 (Layers) TODO: +- consider getting rid of the element and using @id like AI (easier to browse the DOM in FB) - create API for SvgCanvas that allows the client to: - change layer order - - create a layer - - delete a layer -- when New/Delete are clicked, fire off a function -- when creating a new layer, create a <g> with a <title>, set the current layer to the new one -- when deleting a layer, delete all children of the <g> and then delete the <g> - ensure New/Delete are undo-able - create a mouseover region on the sidepanels that is resizable and affects all children within - default the side panel to closed @@ -125,11 +121,19 @@ function InsertElementCommand(elem, text) { this.text = text || ("Create " + elem.tagName); this.parent = elem.parentNode; - this.apply = function() { this.elem = this.parent.insertBefore(this.elem, this.elem.nextSibling); }; + this.apply = function() { + this.elem = this.parent.insertBefore(this.elem, this.elem.nextSibling); + if (this.parent == svgzoom) { + canvas.identifyLayers(); + } + }; this.unapply = function() { this.parent = this.elem.parentNode; this.elem = this.elem.parentNode.removeChild(this.elem); + if (this.parent == svgzoom) { + canvas.identifyLayers(); + } }; this.elements = function() { return [this.elem]; }; @@ -143,9 +147,17 @@ function RemoveElementCommand(elem, parent, text) { this.apply = function() { this.parent = this.elem.parentNode; this.elem = this.parent.removeChild(this.elem); + if (this.parent == svgzoom) { + canvas.identifyLayers(); + } }; - this.unapply = function() { this.elem = this.parent.insertBefore(this.elem, this.elem.nextSibling); }; + this.unapply = function() { + this.elem = this.parent.insertBefore(this.elem, this.elem.nextSibling); + if (this.parent == svgzoom) { + canvas.identifyLayers(); + } + }; this.elements = function() { return [this.elem]; }; } @@ -160,10 +172,16 @@ function MoveElementCommand(elem, oldNextSibling, oldParent, text) { this.apply = function() { this.elem = this.newParent.insertBefore(this.elem, this.newNextSibling); + if (this.newParent == svgzoom) { + canvas.identifyLayers(); + } }; this.unapply = function() { this.elem = this.oldParent.insertBefore(this.elem, this.oldNextSibling); + if (this.oldParent == svgzoom) { + canvas.identifyLayers(); + } }; this.elements = function() { return [this.elem]; }; @@ -2585,24 +2603,7 @@ function BatchCommand(text) { current_zoom = 1; // identify layers - all_layers = []; - var numchildren = svgzoom.childNodes.length; - // loop through all children of svgzoom - for (var i = 0; i < numchildren; ++i) { - var child = svgzoom.childNodes.item(i); - // for each g, find its layer name - if (child && child.tagName == "g") { - var name = getLayerName(child); - // store layer and name in global variable - if (name) { - all_layers.push( [name,child] ); - current_layer = child; - walkTree(child, function(e){e.setAttribute("style", "pointer-events:none");}); - } - } - } - console.dir(all_layers); - walkTree(current_layer, function(e){e.setAttribute("style","pointer-events:all");}); + canvas.identifyLayers(); selectorManager.update(); @@ -2616,10 +2617,63 @@ function BatchCommand(text) { return true; }; + this.identifyLayers = function() { + all_layers = []; + var numchildren = svgzoom.childNodes.length; + // loop through all children of svgzoom + for (var i = 0; i < numchildren; ++i) { + var child = svgzoom.childNodes.item(i); + // for each g, find its layer name + if (child && child.tagName == "g") { + var name = getLayerName(child); + // store layer and name in global variable + if (name) { + all_layers.push( [name,child] ); + current_layer = child; + walkTree(child, function(e){e.setAttribute("style", "pointer-events:none");}); + } + } + } + walkTree(current_layer, function(e){e.setAttribute("style","pointer-events:all");}); + }; // Layer API Functions // TODO: change layer order - // TODO: create a layer - // TODO: delete a layer + + this.createLayer = function(name) { + var batchCmd = new BatchCommand("Create Layer"); + current_layer = svgdoc.createElementNS(svgns, "g"); + var layer_title = svgdoc.createElementNS(svgns, "title"); + layer_title.appendChild(svgdoc.createTextNode(name)); + current_layer.appendChild(layer_title); + current_layer = svgzoom.appendChild(current_layer); + all_layers.push([name,current_layer]); + batchCmd.addSubCommand(new InsertElementCommand(current_layer)); + addCommandToHistory(batchCmd); + }; + + this.deleteCurrentLayer = function() { + if (current_layer && all_layers.length > 1) { + var batchCmd = new BatchCommand("Delete Layer"); + var new_layers = []; + for(var i = 0; i < all_layers.length; ++i) { + if (all_layers[i][1] != current_layer) { + new_layers.push([all_layers[i][0], all_layers[i][1]]); + } + else { + // actually delete from the DOM and store in our Undo History + var parent = current_layer.parentNode; + batchCmd.addSubCommand(new RemoveElementCommand(current_layer, parent)); + parent.removeChild(current_layer); + } + } + all_layers = new_layers; + current_layer = all_layers[all_layers.length-1][1]; + addCommandToHistory(batchCmd); + return true; + } + return false; + }; + this.getNumLayers = function() { return all_layers.length; }; @@ -2641,6 +2695,7 @@ function BatchCommand(text) { for (var i = 0; i < all_layers.length; ++i) { if (name == all_layers[i][0]) { if (current_layer != all_layers[i][1]) { + canvas.clearSelection(); walkTree(current_layer,function(e){e.setAttribute("style","pointer-events:none");}); current_layer = all_layers[i][1]; walkTree(current_layer,function(e){e.setAttribute("style","pointer-events:all");}); @@ -2718,13 +2773,8 @@ function BatchCommand(text) { } } // create empty first layer - current_layer = svgdoc.createElementNS(svgns, "g"); - var layer_title = svgdoc.createElementNS(svgns, "title"); - layer_title.appendChild(svgdoc.createTextNode("Layer 1")); - current_layer.appendChild(layer_title); - current_layer = svgzoom.appendChild(current_layer); all_layers = []; - all_layers[0] = ["Layer 1",current_layer]; + canvas.createLayer("Layer 1"); // clear the undo stack resetUndoStack();