diff --git a/core/block_render_svg.js b/core/block_render_svg.js index aa17738c8..017bc3402 100644 --- a/core/block_render_svg.js +++ b/core/block_render_svg.js @@ -279,6 +279,7 @@ Blockly.BlockSvg.prototype.render = function(opt_bubble) { var inputRows = this.renderCompute_(cursorX); this.renderDraw_(cursorX, inputRows); + this.renderMoveConnections_(); if (opt_bubble !== false) { // Render all blocks above this one (propagate a reflow). @@ -517,10 +518,6 @@ Blockly.BlockSvg.prototype.renderDraw_ = function(iconWidth, inputRows) { } } - // Fetch the block's coordinates on the surface for use in anchoring - // the connections. - var connectionsXY = this.getRelativeToSurfaceXY(); - // Assemble the block's path. var steps = []; var inlineSteps = []; @@ -530,12 +527,11 @@ Blockly.BlockSvg.prototype.renderDraw_ = function(iconWidth, inputRows) { var highlightSteps = []; var highlightInlineSteps = []; - this.renderDrawTop_(steps, highlightSteps, connectionsXY, - inputRows.rightEdge); + this.renderDrawTop_(steps, highlightSteps, inputRows.rightEdge); var cursorY = this.renderDrawRight_(steps, highlightSteps, inlineSteps, - highlightInlineSteps, connectionsXY, inputRows, iconWidth); - this.renderDrawBottom_(steps, highlightSteps, connectionsXY, cursorY); - this.renderDrawLeft_(steps, highlightSteps, connectionsXY); + highlightInlineSteps, inputRows, iconWidth); + this.renderDrawBottom_(steps, highlightSteps, cursorY); + this.renderDrawLeft_(steps, highlightSteps); var pathString = steps.join(' ') + '\n' + inlineSteps.join(' '); this.svgPath_.setAttribute('d', pathString); @@ -550,16 +546,51 @@ Blockly.BlockSvg.prototype.renderDraw_ = function(iconWidth, inputRows) { } }; +/** + * Update all of the connections on this block with the new locations calculated + * in renderCompute. Also move all of the connected blocks based on the new + * connection locations. + * @private + */ +Blockly.BlockSvg.prototype.renderMoveConnections_ = function() { + var blockTL = this.getRelativeToSurfaceXY(); + // Don't tighten previous or output connecitons because they are inferior + // connections. + if (this.previousConnection) { + this.previousConnection.moveToOffset(blockTL); + } + if (this.outputConnection) { + this.outputConnection.moveToOffset(blockTL); + } + + for (var i = 0; i < this.inputList.length; i++) { + var conn = this.inputList[i].connection; + if (conn) { + conn.moveToOffset(blockTL); + if (conn.isConnected()) { + conn.tighten_(); + } + } + } + + if (this.nextConnection) { + this.nextConnection.moveToOffset(blockTL); + if (this.nextConnection.isConnected()) { + this.nextConnection.tighten_(); + } + } + +}; + /** * Render the top edge of the block. * @param {!Array.} steps Path of block outline. * @param {!Array.} highlightSteps Path of block highlights. - * @param {!Object} connectionsXY Location of block. * @param {number} rightEdge Minimum width of block. * @private */ Blockly.BlockSvg.prototype.renderDrawTop_ = - function(steps, highlightSteps, connectionsXY, rightEdge) { + function(steps, highlightSteps, rightEdge) { /* eslint-disable indent */ // Position the cursor at the top-left starting point. if (this.squareTopLeftCorner_) { @@ -587,12 +618,10 @@ Blockly.BlockSvg.prototype.renderDrawTop_ = highlightSteps.push('H', Blockly.BlockSvg.NOTCH_WIDTH - 15); steps.push(Blockly.BlockSvg.NOTCH_PATH_LEFT); highlightSteps.push(Blockly.BlockSvg.NOTCH_PATH_LEFT_HIGHLIGHT); - // Create previous block connection. - var connectionX = connectionsXY.x + (this.RTL ? + + var connectionX = (this.RTL ? -Blockly.BlockSvg.NOTCH_WIDTH : Blockly.BlockSvg.NOTCH_WIDTH); - var connectionY = connectionsXY.y; - this.previousConnection.moveTo(connectionX, connectionY); - // This connection will be tightened when the parent renders. + this.previousConnection.setOffsetInBlock(connectionX, 0); } steps.push('H', rightEdge); highlightSteps.push('H', rightEdge - 0.5); @@ -605,7 +634,6 @@ Blockly.BlockSvg.prototype.renderDrawTop_ = * @param {!Array.} highlightSteps Path of block highlights. * @param {!Array.} inlineSteps Inline block outlines. * @param {!Array.} highlightInlineSteps Inline block highlights. - * @param {!Object} connectionsXY Location of block. * @param {!Array.>} inputRows 2D array of objects, each * containing position information. * @param {number} iconWidth Offset of first row due to icons. @@ -613,7 +641,7 @@ Blockly.BlockSvg.prototype.renderDrawTop_ = * @private */ Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, highlightSteps, - inlineSteps, highlightInlineSteps, connectionsXY, inputRows, iconWidth) { + inlineSteps, highlightInlineSteps, inputRows, iconWidth) { var cursorX; var cursorY = 0; var connectionX, connectionY; @@ -694,20 +722,16 @@ Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, highlightSteps, } // Create inline input connection. if (this.RTL) { - connectionX = connectionsXY.x - cursorX - + connectionX = -cursorX - Blockly.BlockSvg.TAB_WIDTH + Blockly.BlockSvg.SEP_SPACE_X + input.renderWidth + 1; } else { - connectionX = connectionsXY.x + cursorX + + connectionX = cursorX + Blockly.BlockSvg.TAB_WIDTH - Blockly.BlockSvg.SEP_SPACE_X - input.renderWidth - 1; } - connectionY = connectionsXY.y + cursorY + - Blockly.BlockSvg.INLINE_PADDING_Y + 1; - input.connection.moveTo(connectionX, connectionY); - if (input.connection.isConnected()) { - input.connection.tighten_(); - } + connectionY = cursorY + Blockly.BlockSvg.INLINE_PADDING_Y + 1; + input.connection.setOffsetInBlock(connectionX, connectionY); } } @@ -749,12 +773,10 @@ Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, highlightSteps, ',-2.1'); } // Create external input connection. - connectionX = connectionsXY.x + - (this.RTL ? -inputRows.rightEdge - 1 : inputRows.rightEdge + 1); - connectionY = connectionsXY.y + cursorY; - input.connection.moveTo(connectionX, connectionY); + connectionX = this.RTL ? -inputRows.rightEdge - 1 : + inputRows.rightEdge + 1; + input.connection.setOffsetInBlock(connectionX, cursorY); if (input.connection.isConnected()) { - input.connection.tighten_(); this.width = Math.max(this.width, inputRows.rightEdge + input.connection.targetBlock().getHeightWidth().width - Blockly.BlockSvg.TAB_WIDTH + 1); @@ -832,11 +854,10 @@ Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, highlightSteps, highlightSteps.push('H', inputRows.rightEdge - 0.5); } // Create statement connection. - connectionX = connectionsXY.x + (this.RTL ? -cursorX : cursorX + 1); - connectionY = connectionsXY.y + cursorY + 1; - input.connection.moveTo(connectionX, connectionY); + connectionX = this.RTL ? -cursorX : cursorX + 1; + input.connection.setOffsetInBlock(connectionX, cursorY + 1); + if (input.connection.isConnected()) { - input.connection.tighten_(); this.width = Math.max(this.width, inputRows.statementEdge + input.connection.targetBlock().getHeightWidth().width); } @@ -867,12 +888,11 @@ Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, highlightSteps, * Render the bottom edge of the block. * @param {!Array.} steps Path of block outline. * @param {!Array.} highlightSteps Path of block highlights. - * @param {!Object} connectionsXY Location of block. * @param {number} cursorY Height of block. * @private */ Blockly.BlockSvg.prototype.renderDrawBottom_ = - function(steps, highlightSteps, connectionsXY, cursorY) { + function(steps, highlightSteps, cursorY) { /* eslint-disable indent */ this.height += cursorY + 1; // Add one for the shadow. if (this.nextConnection) { @@ -881,15 +901,11 @@ Blockly.BlockSvg.prototype.renderDrawBottom_ = // Create next block connection. var connectionX; if (this.RTL) { - connectionX = connectionsXY.x - Blockly.BlockSvg.NOTCH_WIDTH; + connectionX = -Blockly.BlockSvg.NOTCH_WIDTH; } else { - connectionX = connectionsXY.x + Blockly.BlockSvg.NOTCH_WIDTH; - } - var connectionY = connectionsXY.y + cursorY + 1; - this.nextConnection.moveTo(connectionX, connectionY); - if (this.nextConnection.isConnected()) { - this.nextConnection.tighten_(); + connectionX = Blockly.BlockSvg.NOTCH_WIDTH; } + this.nextConnection.setOffsetInBlock(connectionX, cursorY + 1); this.height += 4; // Height of tab. } @@ -919,16 +935,12 @@ Blockly.BlockSvg.prototype.renderDrawBottom_ = * Render the left edge of the block. * @param {!Array.} steps Path of block outline. * @param {!Array.} highlightSteps Path of block highlights. - * @param {!Object} connectionsXY Location of block. * @private */ -Blockly.BlockSvg.prototype.renderDrawLeft_ = - function(steps, highlightSteps, connectionsXY) { - /* eslint-disable indent */ +Blockly.BlockSvg.prototype.renderDrawLeft_ = function(steps, highlightSteps) { if (this.outputConnection) { // Create output connection. - this.outputConnection.moveTo(connectionsXY.x, connectionsXY.y); - // This connection will be tightened when the parent renders. + this.outputConnection.setOffsetInBlock(0, 0); steps.push('V', Blockly.BlockSvg.TAB_HEIGHT); steps.push('c 0,-10 -' + Blockly.BlockSvg.TAB_WIDTH + ',8 -' + Blockly.BlockSvg.TAB_WIDTH + ',-7.5 s ' + Blockly.BlockSvg.TAB_WIDTH + @@ -954,4 +966,4 @@ Blockly.BlockSvg.prototype.renderDrawLeft_ = } } steps.push('z'); -}; /* eslint-enable indent */ +}; diff --git a/core/rendered_connection.js b/core/rendered_connection.js index 113639e61..20186b098 100644 --- a/core/rendered_connection.js +++ b/core/rendered_connection.js @@ -37,6 +37,7 @@ goog.require('Blockly.Connection'); */ Blockly.RenderedConnection = function(source, type) { Blockly.RenderedConnection.superClass_.constructor.call(this, source, type); + this.offsetInBlock_ = new goog.math.Coordinate(0, 0); }; goog.inherits(Blockly.RenderedConnection, Blockly.Connection); @@ -123,6 +124,27 @@ Blockly.RenderedConnection.prototype.moveBy = function(dx, dy) { this.moveTo(this.x_ + dx, this.y_ + dy); }; +/** + * Move this connection to the location given by its offset within the block and + * the coordinate of the block's top left corner. + * @param {!goog.math.Coordinate} blockTL The coordinate of the top left corner + * of the block. + */ +Blockly.RenderedConnection.prototype.moveToOffset = function(blockTL) { + this.moveTo(blockTL.x + this.offsetInBlock_.x, + blockTL.y + this.offsetInBlock_.y); +}; + +/** + * Set the offset of this connection relative to the top left of its block. + * @param {number} x The new relative x. + * @param {number} y The new relative y. + */ +Blockly.RenderedConnection.prototype.setOffsetInBlock = function(x, y) { + this.offsetInBlock_.x = x; + this.offsetInBlock_.y = y; +}; + /** * Move the blocks on either side of this connection right next to each other. * @private