From bb5939f77cbfb3d2ec266979631875494afa30e4 Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Wed, 11 Dec 2019 14:12:36 -0800 Subject: [PATCH] [zelos] Multi-line rendering (#3501) * Add isMultiRow property and computation for padding with multirow blocks. --- core/renderers/common/info.js | 8 +++++ core/renderers/zelos/info.js | 55 +++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/core/renderers/common/info.js b/core/renderers/common/info.js index bf7fd3c1a..bc3a78022 100644 --- a/core/renderers/common/info.js +++ b/core/renderers/common/info.js @@ -138,6 +138,13 @@ Blockly.blockRendering.RenderInfo = function(renderer, block) { */ this.rows = []; + /** + * The total number of input rows added onto the block. + * @type {number} + * @protected + */ + this.inputRowNum_ = 1; + /** * An array of measurable objects containing hidden icons. * @type {!Array.} @@ -224,6 +231,7 @@ Blockly.blockRendering.RenderInfo.prototype.createRows_ = function() { // Finish this row and create a new one. this.rows.push(activeRow); activeRow = new Blockly.blockRendering.InputRow(this.constants_); + this.inputRowNum_ ++; } // All of the fields in an input go on the same row. diff --git a/core/renderers/zelos/info.js b/core/renderers/zelos/info.js index 6c17ac4a6..57a35b3d0 100644 --- a/core/renderers/zelos/info.js +++ b/core/renderers/zelos/info.js @@ -84,6 +84,13 @@ Blockly.zelos.RenderInfo = function(renderer, block) { */ this.isInline = true; + /** + * Whether the block should be rendered as a multi-line block, either because + * it's not inline or because it has been collapsed. + * @type {boolean} + */ + this.isMultiRow = !block.getInputsInline() || block.isCollapsed(); + /** * An object with rendering information about the right connection shape. * @type {Blockly.zelos.RightConnectionShape} @@ -117,6 +124,28 @@ Blockly.zelos.RenderInfo.prototype.measure = function() { this.finalize_(); }; +/** + * @override + */ +Blockly.zelos.RenderInfo.prototype.shouldStartNewRow_ = function(input, + lastInput) { + // If this is the first input, just add to the existing row. + // That row is either empty or has some icons in it. + if (!lastInput) { + return false; + } + // A statement input or an input following one always gets a new row. + if (input.type == Blockly.NEXT_STATEMENT || + lastInput.type == Blockly.NEXT_STATEMENT) { + return true; + } + // Value and dummy inputs get new row if inputs are not inlined. + if (input.type == Blockly.INPUT_VALUE || input.type == Blockly.DUMMY_INPUT) { + return !this.isInline || this.isMultiRow; + } + return false; +}; + /** * @override */ @@ -253,6 +282,7 @@ Blockly.zelos.RenderInfo.prototype.finalizeOutputConnection_ = function() { row.yPos = yCursor; yCursor += row.height; } + this.height = yCursor; // Adjust the height of the output connection. var connectionHeight = this.outputConnection.shape.height(yCursor); @@ -300,12 +330,14 @@ Blockly.zelos.RenderInfo.prototype.finalizeHorizontalAlignment_ = function() { // Maintain a minimum block width, split negative spacing between left // and right edge. totalNegativeSpacing = this.width - minBlockWidth; - row.getFirstSpacer().width = -totalNegativeSpacing / 2; - row.getLastSpacer().width = -totalNegativeSpacing / 2; - } else { - row.getFirstSpacer().width = -leftNegPadding; - row.getLastSpacer().width = -rightNegPadding; + leftNegPadding = totalNegativeSpacing / 2; + rightNegPadding = totalNegativeSpacing / 2; } + // Add a negative spacer on the start and end of the block. + row.elements.unshift(new Blockly.blockRendering.InRowSpacer(this.constants_, + -leftNegPadding)); + row.elements.push(new Blockly.blockRendering.InRowSpacer(this.constants_, + -rightNegPadding)); } if (totalNegativeSpacing) { this.width -= totalNegativeSpacing; @@ -338,6 +370,19 @@ Blockly.zelos.RenderInfo.prototype.getNegativeSpacing_ = function(elem) { var outerShape = this.outputConnection.shape.type; var constants = /** @type {!Blockly.zelos.ConstantProvider} */ (this.constants_); + if (this.isMultiRow && this.inputRowNum_ > 1) { + switch (outerShape) { + case constants.SHAPES.ROUND: + // Special case for multi-row round reporter blocks. + var radius = this.height / 2; + var topPadding = this.constants_.SMALL_PADDING; + var roundPadding = radius * + (1 - Math.sin(Math.acos((radius - topPadding) / radius))); + return connectionWidth - roundPadding; + default: + return 0; + } + } if (Blockly.blockRendering.Types.isInlineInput(elem)) { var innerShape = elem.connectedBlock ? elem.connectedBlock.pathObject.outputShapeType :