From 9b8636661f163d4c4aea9820a88958d04ba9221d Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Mon, 19 Aug 2019 15:08:23 -0700 Subject: [PATCH] Make rows populate themselves --- blockly_uncompressed.js | 6 +- .../block_render_draw.js | 10 +- .../block_render_info.js | 68 +++-------- .../block_rendering_rewrite/measurables.js | 51 ++++++-- core/renderers/measurables/rows.js | 113 +++++++++++------- 5 files changed, 134 insertions(+), 114 deletions(-) diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js index a2370c789..6a3db4bf0 100644 --- a/blockly_uncompressed.js +++ b/blockly_uncompressed.js @@ -102,12 +102,13 @@ goog.addDependency("../../../" + dir + "/core/rendered_connection.js", ['Blockly goog.addDependency("../../../" + dir + "/core/renderers/block_rendering_rewrite/block_render_draw.js", ['Blockly.blockRendering.Drawer'], ['Blockly.blockRendering.constants', 'Blockly.blockRendering.Debug', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Highlighter', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow']); goog.addDependency("../../../" + dir + "/core/renderers/block_rendering_rewrite/block_render_draw_debug.js", ['Blockly.blockRendering.Debug'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Highlighter', 'Blockly.blockRendering.constants', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow']); goog.addDependency("../../../" + dir + "/core/renderers/block_rendering_rewrite/block_render_draw_highlight.js", ['Blockly.blockRendering.Highlighter'], ['Blockly.blockRendering.highlightConstants', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow']); -goog.addDependency("../../../" + dir + "/core/renderers/block_rendering_rewrite/block_render_info.js", ['Blockly.blockRendering.RenderInfo'], ['Blockly.blockRendering.constants', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow']); +goog.addDependency("../../../" + dir + "/core/renderers/block_rendering_rewrite/block_render_info.js", ['Blockly.blockRendering.RenderInfo'], ['Blockly.blockRendering.constants', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection']); goog.addDependency("../../../" + dir + "/core/renderers/block_rendering_rewrite/block_rendering.js", ['Blockly.blockRendering'], ['Blockly.blockRendering.Debug', 'Blockly.blockRendering.Drawer', 'Blockly.blockRendering.RenderInfo']); goog.addDependency("../../../" + dir + "/core/renderers/block_rendering_rewrite/block_rendering_constants.js", ['Blockly.blockRendering.constants'], ['Blockly.utils.svgPaths']); goog.addDependency("../../../" + dir + "/core/renderers/block_rendering_rewrite/highlight_constants.js", ['Blockly.blockRendering.highlightConstants'], ['Blockly.blockRendering.constants', 'Blockly.utils.svgPaths']); -goog.addDependency("../../../" + dir + "/core/renderers/block_rendering_rewrite/measurables.js", ['Blockly.blockRendering.Input', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.PreviousConnection'], ['Blockly.blockRendering.constants', 'Blockly.blockRendering.Measurable']); +goog.addDependency("../../../" + dir + "/core/renderers/block_rendering_rewrite/measurables.js", ['Blockly.blockRendering.Input', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.OutputConnection'], ['Blockly.blockRendering.constants', 'Blockly.blockRendering.Measurable']); goog.addDependency("../../../" + dir + "/core/renderers/measurables/base.js", ['Blockly.blockRendering.Measurable'], ['Blockly.blockRendering.constants']); +goog.addDependency("../../../" + dir + "/core/renderers/measurables/connections.js", [], []); goog.addDependency("../../../" + dir + "/core/renderers/measurables/rows.js", ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow'], ['Blockly.blockRendering.constants', 'Blockly.blockRendering.Input', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.RenderedConnection']); goog.addDependency("../../../" + dir + "/core/scrollbar.js", ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['Blockly.Touch', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom']); goog.addDependency("../../../" + dir + "/core/theme.js", ['Blockly.Theme'], []); @@ -1908,6 +1909,7 @@ goog.require('Blockly.blockRendering.Input'); goog.require('Blockly.blockRendering.InputRow'); goog.require('Blockly.blockRendering.Measurable'); goog.require('Blockly.blockRendering.NextConnection'); +goog.require('Blockly.blockRendering.OutputConnection'); goog.require('Blockly.blockRendering.PreviousConnection'); goog.require('Blockly.blockRendering.RenderInfo'); goog.require('Blockly.blockRendering.Row'); diff --git a/core/renderers/block_rendering_rewrite/block_render_draw.js b/core/renderers/block_rendering_rewrite/block_render_draw.js index a806459ac..a58973f1b 100644 --- a/core/renderers/block_rendering_rewrite/block_render_draw.js +++ b/core/renderers/block_rendering_rewrite/block_render_draw.js @@ -452,10 +452,10 @@ Blockly.blockRendering.Drawer.prototype.positionExternalValueConnection_ = funct */ Blockly.blockRendering.Drawer.prototype.positionPreviousConnection_ = function() { var topRow = this.info_.topRow; - if (topRow.hasPreviousConnection) { + if (topRow.connection) { var x = topRow.xPos + Blockly.blockRendering.constants.NOTCH_OFFSET_LEFT; var connX = (this.info_.RTL ? -x : x); - topRow.connection.setOffsetInBlock(connX, 0); + topRow.connection.connectionModel.setOffsetInBlock(connX, 0); } }; @@ -466,11 +466,11 @@ Blockly.blockRendering.Drawer.prototype.positionPreviousConnection_ = function() Blockly.blockRendering.Drawer.prototype.positionNextConnection_ = function() { var bottomRow = this.info_.bottomRow; - if (bottomRow.hasNextConnection) { - var connInfo = bottomRow.getNextConnection(); + if (bottomRow.connection) { + var connInfo = bottomRow.connection; var x = connInfo.xPos; // Already contains info about startX var connX = (this.info_.RTL ? -x : x) + 0.5; - bottomRow.connection.setOffsetInBlock( + connInfo.connectionModel.setOffsetInBlock( connX, (connInfo.centerline - connInfo.height / 2) + Blockly.blockRendering.constants.DARK_PATH_OFFSET); } diff --git a/core/renderers/block_rendering_rewrite/block_render_info.js b/core/renderers/block_rendering_rewrite/block_render_info.js index 1c89663ee..9ed465fbf 100644 --- a/core/renderers/block_rendering_rewrite/block_render_info.js +++ b/core/renderers/block_rendering_rewrite/block_render_info.js @@ -35,6 +35,11 @@ goog.require('Blockly.blockRendering.Row'); goog.require('Blockly.blockRendering.SpacerRow'); goog.require('Blockly.blockRendering.TopRow'); +goog.require('Blockly.blockRendering.PreviousConnection'); +goog.require('Blockly.blockRendering.NextConnection'); +goog.require('Blockly.blockRendering.OutputConnection'); + + /** * An object containing all sizing information needed to draw this block. * @@ -55,7 +60,7 @@ Blockly.blockRendering.RenderInfo = function(block) { * @type {Blockly.blockRendering.OutputConnection} */ this.outputConnection = !block.outputConnection ? null : - new Blockly.blockRendering.OutputConnection(); + new Blockly.blockRendering.OutputConnection(block.outputConnection); /** * Whether the block should be rendered as a single line, either because it's @@ -124,13 +129,13 @@ Blockly.blockRendering.RenderInfo = function(block) { * An object with rendering information about the top row of the block. * @type {!Blockly.blockRendering.TopRow} */ - this.topRow = new Blockly.blockRendering.TopRow(this.block_); + this.topRow = new Blockly.blockRendering.TopRow(); /** * An object with rendering information about the bottom row of the block. * @type {!Blockly.blockRendering.BottomRow} */ - this.bottomRow = new Blockly.blockRendering.BottomRow(this.block_); + this.bottomRow = new Blockly.blockRendering.BottomRow(); // The position of the start point for drawing, relative to the block's // location. @@ -163,13 +168,11 @@ Blockly.blockRendering.RenderInfo.prototype.measure_ = function() { /** * Create rows of Measurable objects representing all renderable parts of the * block. - * @param {!Blockly.BlockSvg} block The block to create rows from. * @private */ Blockly.blockRendering.RenderInfo.prototype.createRows_ = function() { - this.populateTopRow_(); + this.topRow.populate(this.block_); this.rows.push(this.topRow); - var activeRow = new Blockly.blockRendering.InputRow(); // Icons always go on the first row, before anything else. @@ -217,54 +220,10 @@ Blockly.blockRendering.RenderInfo.prototype.createRows_ = function() { if (activeRow.elements.length) { this.rows.push(activeRow); } - this.populateBottomRow_(); + this.bottomRow.populate(this.block_); this.rows.push(this.bottomRow); }; -/** - * Create the top row and fill the elements list with all non-spacer elements - * created. - */ -Blockly.blockRendering.RenderInfo.prototype.populateTopRow_ = function() { - var hasHat = this.block_.hat ? this.block_.hat === 'cap' : Blockly.BlockSvg.START_HAT; - var hasPrevious = !!this.block_.previousConnection; - var prevBlock = this.block_.getPreviousBlock(); - var squareCorner = !!this.block_.outputConnection || - hasHat || (prevBlock && prevBlock.getNextBlock() == this.block_); - - if (squareCorner) { - this.topRow.elements.push(new Blockly.blockRendering.SquareCorner()); - } else { - this.topRow.elements.push(new Blockly.blockRendering.RoundCorner()); - } - - if (hasHat) { - var hat = new Blockly.blockRendering.Hat(); - this.topRow.elements.push(hat); - this.startY = hat.startY; - } else if (hasPrevious) { - this.topRow.elements.push(new Blockly.blockRendering.PreviousConnection()); - } -}; - -/** - * Create the bottom row and fill the elements list with all non-spacer elements - * created. - */ -Blockly.blockRendering.RenderInfo.prototype.populateBottomRow_ = function() { - var squareCorner = !!this.block_.outputConnection || !!this.block_.getNextBlock(); - - if (squareCorner) { - this.bottomRow.elements.push(new Blockly.blockRendering.SquareCorner()); - } else { - this.bottomRow.elements.push(new Blockly.blockRendering.RoundCorner()); - } - - if (this.bottomRow.hasNextConnection) { - this.bottomRow.elements.push(new Blockly.blockRendering.NextConnection()); - } -}; - /** * Add an input element to the active row, if needed, and record the type of the @@ -617,9 +576,9 @@ Blockly.blockRendering.RenderInfo.prototype.addRowSpacing_ = function() { /** * Create a spacer row to go between prev and next, and set its size. - * @param {?Blockly.blockRendering.Measurable} prev The previous row, or null. - * @param {?Blockly.blockRendering.Measurable} next The next row, or null. - * @return {!Blockly.BlockSvg.SpacerRow} The newly created spacer row. + * @param {?Blockly.blockRendering.Row} prev The previous row, or null. + * @param {?Blockly.blockRendering.Row} next The next row, or null. + * @return {!Blockly.blockRendering.SpacerRow} The newly created spacer row. * @private */ Blockly.blockRendering.RenderInfo.prototype.makeSpacerRow_ = function(prev, next) { @@ -742,4 +701,5 @@ Blockly.blockRendering.RenderInfo.prototype.finalize_ = function() { this.widthWithChildren = widestRowWithConnectedBlocks + this.startX; this.height = yCursor; + this.startY = this.topRow.startY; }; diff --git a/core/renderers/block_rendering_rewrite/measurables.js b/core/renderers/block_rendering_rewrite/measurables.js index 1aef7fd23..6905df843 100644 --- a/core/renderers/block_rendering_rewrite/measurables.js +++ b/core/renderers/block_rendering_rewrite/measurables.js @@ -3,6 +3,7 @@ goog.provide('Blockly.blockRendering.Input'); goog.provide('Blockly.blockRendering.InRowSpacer'); goog.provide('Blockly.blockRendering.NextConnection'); goog.provide('Blockly.blockRendering.PreviousConnection'); +goog.provide('Blockly.blockRendering.OutputConnection'); goog.require('Blockly.blockRendering.constants'); goog.require('Blockly.blockRendering.Measurable'); @@ -189,52 +190,80 @@ goog.inherits(Blockly.blockRendering.ExternalValueInput, Blockly.blockRendering.Input); /** - * An object containing information about the space an output connection takes - * up during rendering. + * The base class to represent a connection and the space that it takes up on + * the block. + * @param {Blockly.RenderedConnection} connectionModel The connection object on + * the block that this represents. * @package * @constructor * @extends {Blockly.blockRendering.Measurable} */ -Blockly.blockRendering.OutputConnection = function() { - Blockly.blockRendering.OutputConnection.superClass_.constructor.call(this); +Blockly.blockRendering.Connection = function(connectionModel) { + Blockly.blockRendering.Connection.superClass_.constructor.call(this); + this.connectionModel = connectionModel; +}; +goog.inherits(Blockly.blockRendering.Connection, + Blockly.blockRendering.Measurable); + +/** + * An object containing information about the space an output connection takes + * up during rendering. + * @param {Blockly.RenderedConnection} connectionModel The connection object on + * the block that this represents. + * @package + * @constructor + * @extends {Blockly.blockRendering.Measurable} + */ +Blockly.blockRendering.OutputConnection = function(connectionModel) { + Blockly.blockRendering.OutputConnection.superClass_.constructor.call(this, + connectionModel); this.type = 'output connection'; this.height = this.connectionShape.height; this.width = this.connectionShape.width; this.connectionOffsetY = Blockly.blockRendering.constants.TAB_OFFSET_FROM_TOP; this.startX = this.width; }; -goog.inherits(Blockly.blockRendering.OutputConnection, Blockly.blockRendering.Measurable); +goog.inherits(Blockly.blockRendering.OutputConnection, + Blockly.blockRendering.Connection); /** * An object containing information about the space a previous connection takes * up during rendering. + * @param {Blockly.RenderedConnection} connectionModel The connection object on + * the block that this represents. * @package * @constructor * @extends {Blockly.blockRendering.Measurable} */ -Blockly.blockRendering.PreviousConnection = function() { - Blockly.blockRendering.PreviousConnection.superClass_.constructor.call(this); +Blockly.blockRendering.PreviousConnection = function(connectionModel) { + Blockly.blockRendering.PreviousConnection.superClass_.constructor.call(this, + connectionModel); this.type = 'previous connection'; this.height = this.notchShape.height; this.width = this.notchShape.width; }; -goog.inherits(Blockly.blockRendering.PreviousConnection, Blockly.blockRendering.Measurable); +goog.inherits(Blockly.blockRendering.PreviousConnection, + Blockly.blockRendering.Connection); /** * An object containing information about the space a next connection takes * up during rendering. + * @param {Blockly.RenderedConnection} connectionModel The connection object on + * the block that this represents. * @package * @constructor * @extends {Blockly.blockRendering.Measurable} */ -Blockly.blockRendering.NextConnection = function() { - Blockly.blockRendering.NextConnection.superClass_.constructor.call(this); +Blockly.blockRendering.NextConnection = function(connectionModel) { + Blockly.blockRendering.NextConnection.superClass_.constructor.call(this, + connectionModel); this.type = 'next connection'; this.height = this.notchShape.height; this.width = this.notchShape.width; }; -goog.inherits(Blockly.blockRendering.NextConnection, Blockly.blockRendering.Measurable); +goog.inherits(Blockly.blockRendering.NextConnection, + Blockly.blockRendering.Connection); /** * An object containing information about the space a hat takes up during diff --git a/core/renderers/measurables/rows.js b/core/renderers/measurables/rows.js index 62aed3bec..7245665a8 100644 --- a/core/renderers/measurables/rows.js +++ b/core/renderers/measurables/rows.js @@ -219,13 +219,15 @@ Blockly.blockRendering.Row.prototype.getLastSpacer = function() { * block as well as sizing information for the top row. * Elements in a top row can consist of corners, hats, spacers, and previous * connections. + * After this constructor is called, the row will contain all non-spacer + * elements it needs. * @param {!Blockly.BlockSvg} block The block for which this represents the top * row. * @package * @constructor * @extends {Blockly.blockRendering.Row} */ -Blockly.blockRendering.TopRow = function(block) { +Blockly.blockRendering.TopRow = function() { Blockly.blockRendering.TopRow.superClass_.constructor.call(this); this.type = 'top row'; @@ -244,16 +246,47 @@ Blockly.blockRendering.TopRow = function(block) { * @package * @type {boolean} */ - this.hasPreviousConnection = !!block.previousConnection; + this.hasPreviousConnection = false; /** * The previous connection on the block, if any. * TODO: Should this be the connection measurable instead? It would add some * indirection but would mean we aren't mixing connections and connection * measurables. - * @type {Blockly.RenderedConnection} + * @type {Blockly.BlockRendering.PreviousConnection} */ - this.connection = block.previousConnection; + this.connection = null; +}; +goog.inherits(Blockly.blockRendering.TopRow, Blockly.blockRendering.Row); + +/** + * Create all non-spacer elements that belong on the top row. + * @param {!Blockly.BlockSvg} block The block whose top row this represents. + * @package + */ +Blockly.blockRendering.TopRow.prototype.populate = function(block) { + var hasHat = block.hat ? block.hat === 'cap' : Blockly.BlockSvg.START_HAT; + var hasPrevious = !!block.previousConnection; + var prevBlock = block.getPreviousBlock(); + var squareCorner = !!block.outputConnection || + hasHat || (prevBlock && prevBlock.getNextBlock() == block); + + if (squareCorner) { + this.elements.push(new Blockly.blockRendering.SquareCorner()); + } else { + this.elements.push(new Blockly.blockRendering.RoundCorner()); + } + + if (hasHat) { + var hat = new Blockly.blockRendering.Hat(); + this.elements.push(hat); + this.startY = hat.startY; + } else if (hasPrevious) { + this.hasPreviousConnection = true; + this.connection = new Blockly.blockRendering.PreviousConnection( + /** @type {Blockly.RenderedConnection} */ (block.previousConnection)); + this.elements.push(this.connection); + } var precedesStatement = block.inputList.length && block.inputList[0].type == Blockly.NEXT_STATEMENT; @@ -266,21 +299,6 @@ Blockly.blockRendering.TopRow = function(block) { this.minHeight = Blockly.blockRendering.constants.MEDIUM_PADDING; } }; -goog.inherits(Blockly.blockRendering.TopRow, Blockly.blockRendering.Row); - -/** - * Convenience method to get the measurable representing the previous - * connection, if one exists. - * @return {Blockly.blockRendering.PreviousConnection} The measurable that - * represents the previous connection on this block, or null. - * @package - */ -Blockly.blockRendering.TopRow.prototype.getPreviousConnection = function() { - if (this.hasPreviousConnection) { - return /** @type {Blockly.blockRendering.PreviousConnection} */ (this.elements[2]); - } - return null; -}; /** * @override @@ -312,26 +330,23 @@ Blockly.blockRendering.TopRow.prototype.measure = function() { * @constructor * @extends {Blockly.blockRendering.Row} */ -Blockly.blockRendering.BottomRow = function(block) { +Blockly.blockRendering.BottomRow = function() { Blockly.blockRendering.BottomRow.superClass_.constructor.call(this); this.type = 'bottom row'; /** - * Whether the block has a next connection. + * Whether this row has a next connection. * @package * @type {boolean} */ - this.hasNextConnection = !!block.nextConnection; + this.hasNextConnection = false; /** - * The next connection on the block, if any. - * TODO: Should this be the connection measurable instead? It would add some - * indirection but would mean we aren't mixing connections and connection - * measurables. + * The next connection on the row, if any. * @package - * @type {Blockly.RenderedConnection} + * @type {Blockly.blockRendering.NextConnection} */ - this.connection = block.nextConnection; + this.connection = null; /** * The amount that the bottom of the block extends below the horizontal edge, @@ -341,6 +356,22 @@ Blockly.blockRendering.BottomRow = function(block) { */ this.overhangY = 0; + /** + * True if the width of this row does not depend on its contents. + * @type {boolean} + */ + this.hasFixedWidth = false; +}; +goog.inherits(Blockly.blockRendering.BottomRow, Blockly.blockRendering.Row); + +/** + * Create all non-spacer elements that belong on the bottom row. + * @param {!Blockly.BlockSvg} block The block whose bottom row this represents. + * @package + */ +Blockly.blockRendering.BottomRow.prototype.populate = function(block) { + this.hasNextConnection = !!block.nextConnection; + var followsStatement = block.inputList.length && block.inputList[block.inputList.length - 1].type == Blockly.NEXT_STATEMENT; @@ -353,22 +384,20 @@ Blockly.blockRendering.BottomRow = function(block) { } else { this.minHeight = this.notchShape.height; } -}; -goog.inherits(Blockly.blockRendering.BottomRow, - Blockly.blockRendering.Row); -/** - * Convenience method to get the measurable representing the next - * connection, if one exists. - * @return {Blockly.blockRendering.NextConnection} The measurable that - * represents the next connection on this block, or null. - * @package - */ -Blockly.blockRendering.BottomRow.prototype.getNextConnection = function() { - if (this.hasNextConnection) { - return /** @type {Blockly.blockRendering.NextConnection} */ (this.elements[2]); + var squareCorner = !!block.outputConnection || !!block.getNextBlock(); + + if (squareCorner) { + this.elements.push(new Blockly.blockRendering.SquareCorner()); + } else { + this.elements.push(new Blockly.blockRendering.RoundCorner()); + } + + if (this.hasNextConnection) { + this.connection = new Blockly.blockRendering.NextConnection( + /** @type {Blockly.RenderedConnection} */ (block.nextConnection)); + this.elements.push(this.connection); } - return null; }; /**