diff --git a/editor/svg-editor.css b/editor/svg-editor.css index c40ffaa3..d171a165 100644 --- a/editor/svg-editor.css +++ b/editor/svg-editor.css @@ -456,6 +456,28 @@ vertical-align: 12px; } +#cur_context_panel { + position: absolute; + top: 70px; + left: -10px; + right: -2px; + overflow: auto; + border: 1px solid #777; + border-bottom: none; + border-right: none; + padding-left: 5px; + font-size: 12px; +} + +#svg_editor #cur_context_panel a { + float: none; + text-decoration: none; +} + +#svg_editor #cur_context_panel a:hover { + text-decoration: underline; +} + #svg_editor #tools_top > div, #tools_top { line-height: 26px; } diff --git a/editor/svg-editor.html b/editor/svg-editor.html index 12346aed..42ff86ea 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -392,7 +392,9 @@ script type="text/javascript" src="locale/locale.min.js">
- +
+ +
diff --git a/editor/svg-editor.js b/editor/svg-editor.js index 8b602dc5..44f9e149 100644 --- a/editor/svg-editor.js +++ b/editor/svg-editor.js @@ -548,6 +548,8 @@ var multiselected = false; var editingsource = false; var docprops = false; + var cur_context = ''; + var orig_title = $('title:first').text(); var fillPaint = new $.jGraduate.Paint({solidColor: curConfig.initFill.color}); var strokePaint = new $.jGraduate.Paint({solidColor: curConfig.initStroke.color}); @@ -719,6 +721,51 @@ zoomDone(); } + $('#cur_context_panel').delegate('a', 'click', function() { + var link = $(this); + if(link.attr('data-root')) { + svgCanvas.leaveContext(); + } else { + svgCanvas.setContext(link.text()); + } + return false; + }); + + var contextChanged = function(win, context) { + $('#workarea,#sidepanels').css('top', context?100:75); + if(cur_context && !context) { + // Back to normal + workarea[0].scrollTop -= 25; + } else if(!cur_context && context) { + workarea[0].scrollTop += 25; + } + + var link_str = ''; + if(context) { + var str = ''; + link_str = '' + svgCanvas.getCurrentLayer() + ''; + + $(context).parentsUntil('#svgcontent > g').andSelf().each(function() { + if(this.id) { + str += ' > ' + this.id; + if(this !== context) { + link_str += ' > ' + this.id + ''; + } else { + link_str += ' > ' + this.id; + } + } + }); + + cur_context = str; + } else { + cur_context = null; + } + $('#cur_context_panel').toggle(!!context).html(link_str); + + + updateTitle(); + } + var flyout_funcs = {}; var setupFlyouts = function(holders) { @@ -1550,6 +1597,7 @@ svgCanvas.bind("saved", saveHandler); svgCanvas.bind("exported", exportHandler); svgCanvas.bind("zoomed", zoomChanged); + svgCanvas.bind("contextset", contextChanged); svgCanvas.bind("extension_added", extAdded); svgCanvas.textActions.setInputElem($("#text")[0]); @@ -2558,7 +2606,7 @@ hideSourceEditor(); zoomImage(); populateLayers(); - setTitle(svgCanvas.getDocumentTitle()); + updateTitle(); } if (!svgCanvas.setSvgString($('#svg_source_textarea').val())) { @@ -2572,16 +2620,19 @@ setSelectMode(); }; - var setTitle = function(title) { - var editor_title = $('title:first').text().split(':')[0]; - var new_title = editor_title + (title?': ' + title:''); + var updateTitle = function(title) { + title = title || svgCanvas.getDocumentTitle(); + var new_title = orig_title + (title?': ' + title:''); + if(cur_context) { + new_title = new_title + cur_context; + } $('title:first').text(new_title); } var saveDocProperties = function(){ // set title var new_title = $('#canvas_title').val(); - setTitle(new_title); + updateTitle(new_title); svgCanvas.setDocumentTitle(new_title); // update resolution @@ -2925,7 +2976,12 @@ var cancelOverlays = function() { $('#dialog_box').hide(); - if (!editingsource && !docprops) return; + if (!editingsource && !docprops) { + if(cur_context) { + svgCanvas.leaveContext(); + } + return; + }; if (editingsource) { var oldString = svgCanvas.getSvgString(); diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index 02273422..a244f95a 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -2080,10 +2080,10 @@ var getIntersectionList = this.getIntersectionList = function(rect) { if(!rect) { var rubberBBox = rubberBox.getBBox(); var bb = {}; - $.each(rubberBBox, function(key, val) { - // Can't set values to a real BBox object, so make a fake one - bb[key] = val / current_zoom; - }); + + for(var o in rubberBBox) { + bb[o] = rubberBBox[o] / current_zoom; + } rubberBBox = bb; } else { @@ -2414,6 +2414,7 @@ var getId, getNextId; return id; }; + // Function: call // Run the callback function associated with the given event // // Parameters: @@ -4294,7 +4295,7 @@ var getMouseTarget = this.getMouseTarget = function(evt) { // this makes it easier to indentify as being a selector grip return selectorManager.selectorParentGroup; } - + while (mouse_target.parentNode !== (current_group || current_layer)) { mouse_target = mouse_target.parentNode; } @@ -4786,6 +4787,7 @@ var getMouseTarget = this.getMouseTarget = function(evt) { if (elemsToAdd.length > 0) addToSelection(elemsToAdd); + break; case "resize": // we track the resize bounding box and translate/scale the selected element @@ -5371,28 +5373,16 @@ var getMouseTarget = this.getMouseTarget = function(evt) { return; } - // Enable all elements - enableElements(); + // Reset context + if(current_group) { + leaveContext(); + } - if(parent.tagName !== 'g' || parent === current_layer) { + if(parent.tagName !== 'g' || parent === current_layer || mouse_target === selectorManager.selectorParentGroup) { // Escape from in-group edit return; } - - // Edit inside this group - current_group = mouse_target; - - // Disable other elements - $(mouse_target).parentsUntil('#svgcontent').andSelf().siblings().each(function() { - var opac = this.getAttribute('opacity') || 1; - // Store the original's opacity - elData(this, 'orig_opac', opac); - this.setAttribute('opacity', opac * .33); - this.setAttribute('style', 'pointer-events: none'); - disabled_elems.push(this); - }); - - clearSelection(); + setContext(mouse_target); } // prevent links from being followed in the canvas @@ -7747,7 +7737,7 @@ var svgCanvasToString = this.svgCanvasToString = function() { // Move out of in-group editing mode if(current_group) { - enableElements(); + leaveContext(); selectOnly([current_group]); } @@ -8514,7 +8504,7 @@ this.importSvgString = function(xmlString) { var use_el = svgdoc.createElementNS(svgns, "use"); setHref(use_el, "#" + symbol.id); findDefs().appendChild(symbol); - current_layer.appendChild(use_el); + (current_group || current_layer).appendChild(use_el); use_el.id = getNextId(); clearSelection(); @@ -8547,7 +8537,7 @@ this.importSvgString = function(xmlString) { // Updates layer system var identifyLayers = function() { all_layers = []; - enableElements(); + leaveContext(); var numchildren = svgcontent.childNodes.length; // loop through all children of svgcontent var orphans = [], layernames = []; @@ -9028,9 +9018,10 @@ this.setLayerOpacity = function(layername, opacity) { } }; -// Function: enableElements -// Make any previously disabled elements enabled again -var enableElements = this.enableElements = function() { +// Function: leaveContext +// Return from a group context to the regular kind, make any previously +// disabled elements enabled again +var leaveContext = this.leaveContext = function() { var len = disabled_elems.length; if(len) { for(var i = 0; i < len; i++) { @@ -9046,10 +9037,35 @@ var enableElements = this.enableElements = function() { } disabled_elems = []; clearSelection(true); + call("contextset", null); } current_group = null; } +// Function: setContext +// Set the current context (for in-group editing) +var setContext = this.setContext = function(elem) { + if(typeof elem === 'string') { + elem = getElem(elem); + } + + // Edit inside this group + current_group = elem; + + // Disable other elements + $(elem).parentsUntil('#svgcontent').andSelf().siblings().each(function() { + var opac = this.getAttribute('opacity') || 1; + // Store the original's opacity + elData(this, 'orig_opac', opac); + this.setAttribute('opacity', opac * .33); + this.setAttribute('style', 'pointer-events: none'); + disabled_elems.push(this); + }); + + clearSelection(); + call("contextset", current_group); +} + // Group: Document functions // Function: clear @@ -10484,7 +10500,7 @@ this.pasteElements = function(type) { if(!getElem(elem.id)) copy.id = elem.id; pasted.push(copy); - current_layer.appendChild(copy); + (current_group || current_layer).appendChild(copy); batchCmd.addSubCommand(new InsertElementCommand(copy)); } @@ -10907,7 +10923,7 @@ this.cloneSelectedElements = function() { while (i--) { // clone each element and replace it within copiedElements var elem = copiedElements[i] = copyElem(copiedElements[i]); - current_layer.appendChild(elem); + (current_group || current_layer).appendChild(elem); batchCmd.addSubCommand(new InsertElementCommand(elem)); } @@ -11094,7 +11110,7 @@ this.setBackground = function(color, url) { this.cycleElement = function(next) { var cur_elem = selectedElements[0]; var elem = false; - var all_elems = getVisibleElements(current_layer); + var all_elems = getVisibleElements(current_group || current_layer); if (cur_elem == null) { var num = next?all_elems.length-1:0; elem = all_elems[num];