From 4e27f43026124bf7631dcb61d1bdedf3f97f9c07 Mon Sep 17 00:00:00 2001 From: Jeff Schiller Date: Wed, 10 Jun 2009 03:12:19 +0000 Subject: [PATCH] Fix Issue 14: manual merge of text-enabled branch into trunk to enable text element creation/editing git-svn-id: http://svg-edit.googlecode.com/svn/trunk@85 eee81c28-f429-11dd-99c0-75d572ba1ddd --- editor/svg-editor.css | 9 +-- editor/svg-editor.html | 31 +++++++++- editor/svg-editor.js | 40 ++++++++++++ editor/svgcanvas.js | 134 ++++++++++++++++++++++++++++++++++------- 4 files changed, 183 insertions(+), 31 deletions(-) diff --git a/editor/svg-editor.css b/editor/svg-editor.css index 8b3430cd..c651edd9 100644 --- a/editor/svg-editor.css +++ b/editor/svg-editor.css @@ -57,10 +57,6 @@ height: 16px; } -#svg_editor div#tools { - float: left; -} - #svg_editor div#workarea { float: left; } @@ -71,11 +67,12 @@ float: left; } -#tools { +.tools_panel { background: #E8E8E8; - height: 580px; border: 1px solid #808080; padding: 4px; + float:left; + clear:both; } .tool_button, .tool_button_current { diff --git a/editor/svg-editor.html b/editor/svg-editor.html index da25622c..5154b756 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -29,7 +29,7 @@
-
+
Select
@@ -97,7 +97,7 @@

-
+
opacity
+ + + + + + + + +
+
+
diff --git a/editor/svg-editor.js b/editor/svg-editor.js index 443790be..f77a19e6 100644 --- a/editor/svg-editor.js +++ b/editor/svg-editor.js @@ -3,8 +3,20 @@ var palette = ["#000000","#202020","#404040","#606060","#808080","#a0a0a0","#c0c function svg_edit_setup() { var svgCanvas = new SvgCanvas(document.getElementById("svgcanvas")); + var setSelectMode = function() { + $('.tool_button_current').removeClass('tool_button_current').addClass('tool_button'); + $('#tool_select').addClass('tool_button_current'); + $('#styleoverrides').text('*{cursor:move;pointer-events:all} svg{cursor:default}'); + svgCanvas.setMode('select'); + } + + var textBeingEntered = false; + var selectedChanged = function(window,elem) { if (elem != null) { + + // set the mode of the editor to select + setSelectMode(); // update fill color var fillColor = elem.getAttribute("fill"); @@ -56,9 +68,24 @@ function svg_edit_setup() { strokeDashArray = "none"; } $('#stroke_style').val(strokeDashArray); + + if (elem.tagName == "text") { + $('.text_tool').removeAttr('disabled'); + $('#font_family').val(elem.getAttribute("font-family")); + $('#font_size').val(elem.getAttribute("font-size")); + $('#text').val(elem.textContent); + $('#text').focus(); + $('#text').select(); + } + else { + $('.text_tool').attr('disabled', "disabled"); + } } } + $('#text').focus( function(){ textBeingEntered = true; } ); + $('#text').blur( function(){ textBeingEntered = false; } ); + // bind the selected event to our function that handles updates to the UI svgCanvas.bind("selected", selectedChanged); @@ -92,6 +119,18 @@ function svg_edit_setup() { $('#group_opacity').change(function(){ svgCanvas.setOpacity(this.options[this.selectedIndex].value); }); + + $('#font_size').change(function(){ + svgCanvas.setFontSize(this.options[this.selectedIndex].value); + }); + + $('#font_family').change(function(){ + svgCanvas.setFontFamily(this.options[this.selectedIndex].value); + }); + + $('#text').keyup(function(){ + svgCanvas.setTextContent(this.value); + }); $('.palette_item').click(function(){ color = $(this).css('background-color'); @@ -210,6 +249,7 @@ function svg_edit_setup() { $('#tool_save').click(clickSave); $('#workarea').keyup(function(event){ + if( textBeingEntered ) { return; } switch (event.keyCode) { case 37: // left-arrow break; diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index 9d690961..429f0a09 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -29,6 +29,8 @@ function SvgCanvas(c) var current_opacity = 1; var current_stroke_opacity = 1; var current_fill_opacity = 1; + var current_font_size = "12pt"; + var current_font_family = "serif"; var freehand_min_x = null; var freehand_max_x = null; var freehand_min_y = null; @@ -119,18 +121,16 @@ function SvgCanvas(c) // remove selected outline from previously selected element if (selected != null && selectedOutline != null) { - svgroot.removeChild(selectedOutline); - selectedOutline = null; + // remove from DOM and store reference in JS + selectedOutline = svgroot.removeChild(selectedOutline); } selected = newSelected; if (selected != null) { - var bbox = selected.getBBox(); - // ideally we should create this element once during init, then remove from the DOM - // and re-append to end of documentElement. This will also allow us to do some - // interesting things like animate the stroke-dashoffset using a SMIL child - selectedOutline = addSvgElementFromJson({ + // we create this element for the first time here + if (selectedOutline == null) { + selectedOutline = addSvgElementFromJson({ "element": "rect", "attr": { "id": "selectedBox", @@ -138,14 +138,17 @@ function SvgCanvas(c) "stroke": "blue", "stroke-width": "1", "stroke-dasharray": "5,5", - "x": bbox.x-1, - "y": bbox.y-1, - "width": bbox.width+2, - "height": bbox.height+2, + "width": 1, + "height": 1, // need to specify this style so that the selectedOutline is not selectable "style": "pointer-events:none", } - }); + }); + // TODO: add SMIL animate child on stroke-dashoffset here + } + // recalculate size and then re-append to bottom of document + recalculateSelectedOutline(); + svgroot.appendChild(selectedOutline); // set all our current styles to the selected styles current_fill = selected.getAttribute("fill"); @@ -154,10 +157,29 @@ function SvgCanvas(c) current_stroke_opacity = selected.getAttribute("stroke-opacity"); current_stroke_width = selected.getAttribute("stroke-width"); current_stroke_style = selected.getAttribute("stroke-dasharray"); + if (selected.tagName == "text") { + current_font_size = selected.getAttribute("font-size"); + current_font_family = selected.getAttribute("font-family"); + } } call("selected", selected); } + + var recalculateSelectedOutline = function() { + if (selected != null && selectedOutline != null) { + var bbox = selected.getBBox(); + var sw = selected.getAttribute("stroke-width"); + var offset = 1; + if (sw != null && sw != "") { + offset += parseInt(sw)/2; + } + selectedOutline.setAttribute("x", bbox.x-offset); + selectedOutline.setAttribute("y", bbox.y-offset); + selectedOutline.setAttribute("width", bbox.width+(offset<<1)); + selectedOutline.setAttribute("height", bbox.height+(offset<<1)); + } + } var mouseDown = function(evt) { @@ -278,6 +300,27 @@ function SvgCanvas(c) } }); break; + case "text": + started = true; + var newText = addSvgElementFromJson({ + "element": "text", + "attr": { + "x": x, + "y": y, + "id": getId(), + "fill": current_fill, + "stroke": current_stroke, + "stroke-width": current_stroke_width, + "stroke-dasharray": current_stroke_style, + "stroke-opacity": current_stroke_opacity, + "fill-opacity": current_fill_opacity, + "opacity": current_opacity / 2, + "font-size": current_font_size, + "font-family": current_font_family, + } + }); + newText.textContent = "text"; + break; case "delete": var t = evt.target; if (t == svgroot) return; @@ -293,7 +336,6 @@ function SvgCanvas(c) var x = evt.pageX - container.offsetLeft; var y = evt.pageY - container.offsetTop; var shape = svgdoc.getElementById(getId()); - if (!shape) return; // Error? switch (current_mode) { case "select": @@ -306,7 +348,11 @@ function SvgCanvas(c) selected.setAttributeNS(null, "transform", "translate(" + dx + "," + dy + ")"); selectedOutline.setAttributeNS(null, "transform", "translate(" + dx + "," + dy + ")"); } - break; + break; + case "text": + shape.setAttribute("x", x); + shape.setAttribute("y", y); + break; case "line": shape.setAttributeNS(null, "x2", x); shape.setAttributeNS(null, "y2", y); @@ -477,18 +523,20 @@ function SvgCanvas(c) })); } break; + case "text": + keep = true; + selectElement(element); + break; } d_attr = null; obj_num++; - if (element != null) { - if (!keep) { - element.parentNode.removeChild(element); - element = null; - } else { - element.setAttribute("opacity", current_opacity); - cleanupElement(element); - call("changed",element); - } + if (!keep) { + element.parentNode.removeChild(element); + element = null; + } else if (element != null) { + element.setAttribute("opacity", current_opacity); + cleanupElement(element); + call("changed",element); } } @@ -557,6 +605,7 @@ function SvgCanvas(c) current_stroke_width = val; if (selected != null) { selected.setAttribute("stroke-width", val); + recalculateSelectedOutline(); call("changed", selected); } } @@ -627,6 +676,45 @@ function SvgCanvas(c) events[event] = f; } + this.getFontFamily = function() { + return current_font_family; + } + + this.setFontFamily = function(val) { + current_font_family = val; + if (selected != null) { + selected.setAttribute("font-family", val); + recalculateSelectedOutline(); + call("changed", selected); + } + } + + this.getFontSize = function() { + return current_font_size; + } + + this.setFontSize = function(val) { + current_font_size = val; + if (selected != null) { + selected.setAttribute("font-size", val); + recalculateSelectedOutline(); + call("changed", selected); + } + } + + this.getText = function() { + if (selected == null) { return ""; } + return selected.textContent; + } + + this.setTextContent = function(val) { + if (selected != null) { + selected.textContent = val; + recalculateSelectedOutline(); + call("changed", selected); + } + } + $(container).mouseup(mouseUp); $(container).mousedown(mouseDown); $(container).mousemove(mouseMove);