From 7b5e6eee63c91cdfcf37c317546d3c33631114f6 Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Wed, 14 Aug 2019 14:09:20 -0700 Subject: [PATCH] Correctly calculate widths of blocks with children on external inputs. --- .../block_render_draw_debug.js | 91 +++++++++++++++++-- .../block_render_info.js | 7 ++ .../block_rendering_rewrite/measurables.js | 5 +- 3 files changed, 94 insertions(+), 9 deletions(-) diff --git a/core/renderers/block_rendering_rewrite/block_render_draw_debug.js b/core/renderers/block_rendering_rewrite/block_render_draw_debug.js index 90f389910..454d06706 100644 --- a/core/renderers/block_rendering_rewrite/block_render_draw_debug.js +++ b/core/renderers/block_rendering_rewrite/block_render_draw_debug.js @@ -47,8 +47,22 @@ Blockly.blockRendering.Debug = function() { * @type {!SVGElement} */ this.svgRoot_ = null; + + /** + * @type {Object} Configuration object containing booleans to enable and + * disable debug rendering of specific rendering components. + */ + this.config_ = { + rowSpacers: true, + elemSpacers: true, + rows: true, + elems: true, + connections: true, + blockBounds: true + }; }; + /** * Remove all elements the this object created on the last pass. * @package @@ -69,6 +83,10 @@ Blockly.blockRendering.Debug.prototype.clearElems = function() { * @package */ Blockly.blockRendering.Debug.prototype.drawSpacerRow = function(row, cursorY, isRtl) { + if (!this.config_.rowSpacers) { + return; + } + this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect', { 'class': 'rowSpacerRect blockRenderDebug', @@ -88,6 +106,10 @@ Blockly.blockRendering.Debug.prototype.drawSpacerRow = function(row, cursorY, is * @package */ Blockly.blockRendering.Debug.prototype.drawSpacerElem = function(elem, rowHeight, isRtl) { + if (!this.config_.elemSpacers) { + return; + } + var xPos = elem.xPos; if (isRtl) { xPos = -(xPos + elem.width); @@ -112,6 +134,10 @@ Blockly.blockRendering.Debug.prototype.drawSpacerElem = function(elem, rowHeight * @package */ Blockly.blockRendering.Debug.prototype.drawRenderedElem = function(elem, isRtl) { + if (!this.config_.elems) { + return; + } + var xPos = elem.xPos; if (isRtl) { xPos = -(xPos + elem.width); @@ -140,6 +166,10 @@ Blockly.blockRendering.Debug.prototype.drawRenderedElem = function(elem, isRtl) * @package */ Blockly.blockRendering.Debug.prototype.drawConnection = function(conn) { + if (!this.config_.connections) { + return; + } + var colour; var size; var fill; @@ -180,6 +210,10 @@ Blockly.blockRendering.Debug.prototype.drawConnection = function(conn) { * @package */ Blockly.blockRendering.Debug.prototype.drawRenderedRow = function(row, cursorY, isRtl) { + if (!this.config_.rows) { + return; + } + this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect', { 'class': 'elemRenderingRect blockRenderDebug', @@ -189,6 +223,23 @@ Blockly.blockRendering.Debug.prototype.drawRenderedRow = function(row, cursorY, 'height': row.height, }, this.svgRoot_)); + + if (row.type == 'top row' || row.type == 'bottom row') { + return; + } + this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect', + { + 'class': 'blockRenderDebug', + 'x': isRtl ? -(row.xPos + row.widthWithConnectedBlocks) : row.xPos, + 'y': cursorY , + 'width': row.widthWithConnectedBlocks, + 'height': row.height, + 'stroke': this.randomColour_, + 'fill': 'none', + 'stroke-width': '1px', + 'stroke-dasharray': '3,3' + }, + this.svgRoot_)); }; /** @@ -212,13 +263,17 @@ Blockly.blockRendering.Debug.prototype.drawRowWithElements = function(row, curso /** * Draw a debug rectangle around the entire block. - * @param {number} width The width of the block. - * @param {number} height The height of the block. - * @param {boolean} isRtl Whether the block is rendered RTL. + * @param {!Blockly.blockRendering.RenderInfo} info Rendering information about + * the block to debug. * @package */ -Blockly.blockRendering.Debug.prototype.drawBoundingBox = function(width, height, isRtl) { - var xPos = isRtl ? -width : 0; +Blockly.blockRendering.Debug.prototype.drawBoundingBox = function(info) { + if (!this.config_.blockBounds) { + return; + } + + // Bounding box without children. + var xPos = info.RTL ? -info.width : 0; var yPos = 0; this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect', @@ -226,11 +281,28 @@ Blockly.blockRendering.Debug.prototype.drawBoundingBox = function(width, height, 'class': 'blockBoundingBox blockRenderDebug', 'x': xPos, 'y': yPos, - 'width': width, - 'height': height, + 'width': info.width, + 'height': info.height, + }, + this.svgRoot_)); + + // Bounding box with children. + xPos = info.RTL ? -info.widthWithChildren : 0; + this.debugElements_.push(Blockly.utils.dom.createSvgElement('rect', + { + 'class': 'blockRenderDebug', + 'x': xPos, + 'y': yPos, + 'width': info.widthWithChildren, + 'height': info.height, + 'stroke': '#DF57BC', + 'fill': 'none', + 'stroke-width': '1px', + 'stroke-dasharray': '3,3' }, this.svgRoot_)); }; + /** * Do all of the work to draw debug information for the whole block. * @param {!Blockly.BlockSvg} block The block to draw debug information for. @@ -239,9 +311,12 @@ Blockly.blockRendering.Debug.prototype.drawBoundingBox = function(width, height, * @package */ Blockly.blockRendering.Debug.prototype.drawDebug = function(block, info) { + this.config_.rowSpacers = false; this.clearElems(); this.svgRoot_ = block.getSvgRoot(); + this.randomColour_ = '#' + Math.floor(Math.random() * 16777215).toString(16); + var cursorY = 0; for (var r = 0; r < info.rows.length; r++) { var row = info.rows[r]; @@ -263,5 +338,5 @@ Blockly.blockRendering.Debug.prototype.drawDebug = function(block, info) { this.drawConnection(block.outputConnection); } - this.drawBoundingBox(info.width, info.height, info.isRtl); + this.drawBoundingBox(info); }; diff --git a/core/renderers/block_rendering_rewrite/block_render_info.js b/core/renderers/block_rendering_rewrite/block_render_info.js index 5f1c22267..3623aa761 100644 --- a/core/renderers/block_rendering_rewrite/block_render_info.js +++ b/core/renderers/block_rendering_rewrite/block_render_info.js @@ -565,6 +565,7 @@ Blockly.blockRendering.RenderInfo.prototype.addAlignmentPadding_ = function(row, if (row.hasExternalInput || row.hasStatement) { // Get the spacer right before the input socket. lastSpacer = elems[elems.length - 3]; + row.widthWithConnectedBlocks += missingSpace; } // Decide where the extra padding goes. if (input.align == Blockly.ALIGN_LEFT) { @@ -701,12 +702,16 @@ Blockly.blockRendering.RenderInfo.prototype.finalize_ = function() { // Performance note: this could be combined with the draw pass, if the time // that this takes is excessive. But it shouldn't be, because it only // accesses and sets properties that already exist on the objects. + var widestRowWithConnectedBlocks = 0; var yCursor = 0; for (var r = 0; r < this.rows.length; r++) { var row = this.rows[r]; row.yPos = yCursor; row.xPos = this.startX; yCursor += row.height; + + widestRowWithConnectedBlocks = + Math.max(widestRowWithConnectedBlocks, row.widthWithConnectedBlocks); // Add padding to the bottom row if block height is less than minimum var heightWithoutHat = yCursor - this.topRow.startY; if (row == this.bottomRow && @@ -727,5 +732,7 @@ Blockly.blockRendering.RenderInfo.prototype.finalize_ = function() { } } + this.widthWithChildren = widestRowWithConnectedBlocks + this.startX; + this.height = yCursor; }; diff --git a/core/renderers/block_rendering_rewrite/measurables.js b/core/renderers/block_rendering_rewrite/measurables.js index 379ad42ea..09d4233bc 100644 --- a/core/renderers/block_rendering_rewrite/measurables.js +++ b/core/renderers/block_rendering_rewrite/measurables.js @@ -426,6 +426,7 @@ Blockly.blockRendering.Row = function() { this.elements = []; this.width = 0; this.height = 0; + this.widthWithConnectedBlocks = 0; this.hasExternalInput = false; this.hasStatement = false; @@ -454,7 +455,8 @@ Blockly.blockRendering.Row.prototype.measure = function() { if (elem.isInput) { if (elem.type == 'statement input') { connectedBlockWidths += elem.connectedBlockWidth; - } else if (elem.type == 'external value input') { + } else if (elem.type == 'external value input' && + elem.connectedBlockWidth != 0) { connectedBlockWidths += (elem.connectedBlockWidth - elem.connectionWidth); } } @@ -494,6 +496,7 @@ Blockly.blockRendering.BetweenRowSpacer = function(height, width) { this.width = width; this.height = height; this.followsStatement = false; + this.widthWithConnectedBlocks = 0; }; goog.inherits(Blockly.blockRendering.BetweenRowSpacer, Blockly.blockRendering.Measurable);