Merge pull request #2825 from rachel-fenichel/block_widths

Correctly calculate widths of blocks with children on external inputs.
This commit is contained in:
Rachel Fenichel
2019-08-15 14:35:15 -07:00
committed by GitHub
3 changed files with 94 additions and 9 deletions

View File

@@ -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);
};

View File

@@ -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) {
@@ -698,12 +699,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 &&
@@ -724,5 +729,7 @@ Blockly.blockRendering.RenderInfo.prototype.finalize_ = function() {
}
}
this.widthWithChildren = widestRowWithConnectedBlocks + this.startX;
this.height = yCursor;
};

View File

@@ -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);