From 189c561f49a412d026800f37740d637a81d54d6d Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Tue, 3 Sep 2019 14:39:02 -0700 Subject: [PATCH] Rendering type checker (#2950) * Convert all rendering types to use a type enum flag. --- blockly_uncompressed.js | 30 +- core/renderers/common/block_rendering.js | 2 +- core/renderers/common/debugger.js | 9 +- core/renderers/common/drawer.js | 30 +- core/renderers/common/info.js | 30 +- core/renderers/geras/highlighter.js | 17 +- core/renderers/geras/info.js | 81 +++-- core/renderers/measurables/base.js | 122 +------ core/renderers/measurables/connections.js | 8 +- core/renderers/measurables/inputs.js | 9 +- core/renderers/measurables/row_elements.js | 22 +- core/renderers/measurables/rows.js | 40 +-- core/renderers/measurables/types.js | 363 +++++++++++++++++++++ core/renderers/thrasos/info.js | 81 +++-- core/renderers/zelos/drawer.js | 23 +- core/renderers/zelos/info.js | 72 ++-- core/renderers/zelos/measurables/rows.js | 12 +- 17 files changed, 623 insertions(+), 328 deletions(-) create mode 100644 core/renderers/measurables/types.js diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js index 00564bffc..f98d53b81 100644 --- a/blockly_uncompressed.js +++ b/blockly_uncompressed.js @@ -43,7 +43,7 @@ goog.addDependency("../../../" + dir + "/core/components/component.js", ['Blockl goog.addDependency("../../../" + dir + "/core/components/menu/menu.js", ['Blockly.Menu'], ['Blockly.Component', 'Blockly.utils.dom', 'Blockly.utils.aria']); goog.addDependency("../../../" + dir + "/core/components/menu/menuitem.js", ['Blockly.MenuItem'], ['Blockly.Component', 'Blockly.utils.dom', 'Blockly.utils.aria']); goog.addDependency("../../../" + dir + "/core/components/tree/basenode.js", ['Blockly.tree.BaseNode'], ['Blockly.Component', 'Blockly.utils.aria', 'Blockly.utils.KeyCodes', 'Blockly.utils.style']); -goog.addDependency("../../../" + dir + "/core/components/tree/treecontrol.js", ['Blockly.tree.TreeControl'], ['Blockly.tree.TreeNode', 'Blockly.tree.BaseNode', 'Blockly.utils.aria']); +goog.addDependency("../../../" + dir + "/core/components/tree/treecontrol.js", ['Blockly.tree.TreeControl'], ['Blockly.tree.TreeNode', 'Blockly.tree.BaseNode', 'Blockly.utils.aria', 'Blockly.utils.style']); goog.addDependency("../../../" + dir + "/core/components/tree/treenode.js", ['Blockly.tree.TreeNode'], ['Blockly.tree.BaseNode', 'Blockly.utils.KeyCodes']); goog.addDependency("../../../" + dir + "/core/connection.js", ['Blockly.Connection'], ['Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Xml']); goog.addDependency("../../../" + dir + "/core/connection_db.js", ['Blockly.ConnectionDB'], ['Blockly.Connection']); @@ -94,22 +94,23 @@ goog.addDependency("../../../" + dir + "/core/procedures.js", ['Blockly.Procedur goog.addDependency("../../../" + dir + "/core/rendered_connection.js", ['Blockly.RenderedConnection'], ['Blockly.Connection', 'Blockly.Events', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom']); goog.addDependency("../../../" + dir + "/core/renderers/common/block_rendering.js", ['Blockly.blockRendering'], ['Blockly.blockRendering.Debug', 'Blockly.blockRendering.Drawer', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.ConstantProvider', 'Blockly.geras.HighlightConstantProvider', 'Blockly.geras.Drawer', 'Blockly.geras.RenderInfo', 'Blockly.thrasos.RenderInfo', 'Blockly.zelos.Drawer', 'Blockly.zelos.RenderInfo', 'Blockly.zelos.ConstantProvider']); goog.addDependency("../../../" + dir + "/core/renderers/common/constants.js", ['Blockly.blockRendering.ConstantProvider'], ['Blockly.utils.svgPaths']); -goog.addDependency("../../../" + dir + "/core/renderers/common/debugger.js", ['Blockly.blockRendering.Debug'], ['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/common/drawer.js", ['Blockly.blockRendering.Drawer'], ['Blockly.blockRendering.Debug', '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/common/info.js", ['Blockly.blockRendering.RenderInfo'], ['Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.RenderedConnection']); +goog.addDependency("../../../" + dir + "/core/renderers/common/debugger.js", ['Blockly.blockRendering.Debug'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow']); +goog.addDependency("../../../" + dir + "/core/renderers/common/drawer.js", ['Blockly.blockRendering.Drawer'], ['Blockly.blockRendering.Debug', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow']); +goog.addDependency("../../../" + dir + "/core/renderers/common/info.js", ['Blockly.blockRendering.RenderInfo'], ['Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.RenderedConnection']); goog.addDependency("../../../" + dir + "/core/renderers/geras/drawer.js", ['Blockly.geras.Drawer'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Drawer', 'Blockly.geras.Highlighter', 'Blockly.geras.RenderInfo']); goog.addDependency("../../../" + dir + "/core/renderers/geras/highlight_constants.js", ['Blockly.geras.HighlightConstantProvider'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.utils.svgPaths']); -goog.addDependency("../../../" + dir + "/core/renderers/geras/highlighter.js", ['Blockly.geras.Highlighter'], ['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/geras/info.js", ['Blockly.geras', 'Blockly.geras.RenderInfo'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.RenderedConnection']); -goog.addDependency("../../../" + dir + "/core/renderers/measurables/base.js", ['Blockly.blockRendering.Measurable'], []); -goog.addDependency("../../../" + dir + "/core/renderers/measurables/connections.js", ['Blockly.blockRendering.Connection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection'], ['Blockly.blockRendering.Measurable', 'Blockly.RenderedConnection']); -goog.addDependency("../../../" + dir + "/core/renderers/measurables/inputs.js", ['Blockly.blockRendering.InputConnection', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.ExternalValueInput'], ['Blockly.blockRendering.Connection', 'Blockly.blockRendering.Measurable']); -goog.addDependency("../../../" + dir + "/core/renderers/measurables/row_elements.js", ['Blockly.blockRendering.Field', 'Blockly.blockRendering.Hat', 'Blockly.blockRendering.Icon', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.JaggedEdge', 'Blockly.blockRendering.RoundCorner', 'Blockly.blockRendering.SquareCorner'], ['Blockly.blockRendering.Measurable']); -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.InputConnection', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.RenderedConnection']); -goog.addDependency("../../../" + dir + "/core/renderers/thrasos/info.js", ['Blockly.thrasos', 'Blockly.thrasos.RenderInfo'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.RenderedConnection']); +goog.addDependency("../../../" + dir + "/core/renderers/geras/highlighter.js", ['Blockly.geras.Highlighter'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow']); +goog.addDependency("../../../" + dir + "/core/renderers/geras/info.js", ['Blockly.geras', 'Blockly.geras.RenderInfo'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.RenderedConnection']); +goog.addDependency("../../../" + dir + "/core/renderers/measurables/base.js", ['Blockly.blockRendering.Measurable'], ['Blockly.blockRendering.Types']); +goog.addDependency("../../../" + dir + "/core/renderers/measurables/connections.js", ['Blockly.blockRendering.Connection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection'], ['Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.RenderedConnection']); +goog.addDependency("../../../" + dir + "/core/renderers/measurables/inputs.js", ['Blockly.blockRendering.InputConnection', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.ExternalValueInput'], ['Blockly.blockRendering.Connection', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types']); +goog.addDependency("../../../" + dir + "/core/renderers/measurables/row_elements.js", ['Blockly.blockRendering.Field', 'Blockly.blockRendering.Hat', 'Blockly.blockRendering.Icon', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.JaggedEdge', 'Blockly.blockRendering.RoundCorner', 'Blockly.blockRendering.SquareCorner'], ['Blockly.blockRendering.Types', 'Blockly.blockRendering.Measurable']); +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.InputConnection', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.Types', 'Blockly.RenderedConnection']); +goog.addDependency("../../../" + dir + "/core/renderers/measurables/types.js", ['Blockly.blockRendering.Types'], []); +goog.addDependency("../../../" + dir + "/core/renderers/thrasos/info.js", ['Blockly.thrasos', 'Blockly.thrasos.RenderInfo'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.RenderedConnection']); goog.addDependency("../../../" + dir + "/core/renderers/zelos/constants.js", ['Blockly.zelos.ConstantProvider'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.utils.svgPaths']); -goog.addDependency("../../../" + dir + "/core/renderers/zelos/drawer.js", ['Blockly.zelos.Drawer'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Drawer', 'Blockly.zelos.RenderInfo']); -goog.addDependency("../../../" + dir + "/core/renderers/zelos/info.js", ['Blockly.zelos', 'Blockly.zelos.RenderInfo'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.RenderedConnection', 'Blockly.zelos.BottomRow', 'Blockly.zelos.TopRow']); +goog.addDependency("../../../" + dir + "/core/renderers/zelos/drawer.js", ['Blockly.zelos.Drawer'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Drawer', 'Blockly.blockRendering.Types', 'Blockly.zelos.RenderInfo']); +goog.addDependency("../../../" + dir + "/core/renderers/zelos/info.js", ['Blockly.zelos', 'Blockly.zelos.RenderInfo'], ['Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.RenderedConnection', 'Blockly.zelos.BottomRow', 'Blockly.zelos.TopRow']); goog.addDependency("../../../" + dir + "/core/renderers/zelos/measurables/rows.js", ['Blockly.zelos.BottomRow', 'Blockly.zelos.TopRow'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.TopRow']); 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'], []); @@ -290,6 +291,7 @@ goog.require('Blockly.blockRendering.SpacerRow'); goog.require('Blockly.blockRendering.SquareCorner'); goog.require('Blockly.blockRendering.StatementInput'); goog.require('Blockly.blockRendering.TopRow'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.constants'); goog.require('Blockly.fieldRegistry'); goog.require('Blockly.geras'); diff --git a/core/renderers/common/block_rendering.js b/core/renderers/common/block_rendering.js index 7834431b6..67dd186c4 100644 --- a/core/renderers/common/block_rendering.js +++ b/core/renderers/common/block_rendering.js @@ -44,7 +44,7 @@ goog.require('Blockly.zelos.RenderInfo'); goog.require('Blockly.zelos.ConstantProvider'); // TODO (#2702): Pick an API for choosing a renderer. -Blockly.blockRendering.rendererName = 'geras'; +Blockly.blockRendering.rendererName = 'zelos'; Blockly.blockRendering.useDebugger = false; diff --git a/core/renderers/common/debugger.js b/core/renderers/common/debugger.js index 39c777166..f2739d804 100644 --- a/core/renderers/common/debugger.js +++ b/core/renderers/common/debugger.js @@ -28,6 +28,7 @@ goog.provide('Blockly.blockRendering.Debug'); goog.require('Blockly.blockRendering.RenderInfo'); goog.require('Blockly.blockRendering.Measurable'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.blockRendering.BottomRow'); goog.require('Blockly.blockRendering.InputRow'); goog.require('Blockly.blockRendering.Row'); @@ -173,7 +174,7 @@ Blockly.blockRendering.Debug.prototype.drawRenderedElem = function(elem, isRtl) } - if (elem.isInput && this.config_.connections) { + if (Blockly.blockRendering.Types.isInput(elem) && this.config_.connections) { this.drawConnection(elem.connection); } }; @@ -246,7 +247,7 @@ Blockly.blockRendering.Debug.prototype.drawRenderedRow = function(row, cursorY, }, this.svgRoot_)); - if (row.type == 'top row' || row.type == 'bottom row') { + if (Blockly.blockRendering.Types.isTopOrBottomRow(row)) { return; } @@ -276,7 +277,7 @@ Blockly.blockRendering.Debug.prototype.drawRenderedRow = function(row, cursorY, */ Blockly.blockRendering.Debug.prototype.drawRowWithElements = function(row, cursorY, isRtl) { for (var i = 0, elem; (elem = row.elements[i]); i++) { - if (elem.isSpacer()) { + if (Blockly.blockRendering.Types.isSpacer(elem)) { this.drawSpacerElem(elem, row.height, isRtl); } else { this.drawRenderedElem(elem, isRtl); @@ -346,7 +347,7 @@ Blockly.blockRendering.Debug.prototype.drawDebug = function(block, info) { var cursorY = 0; for (var i = 0, row; (row = info.rows[i]); i++) { - if (row.type == 'between-row spacer') { + if (Blockly.blockRendering.Types.isBetweenRowSpacer(row)) { this.drawSpacerRow(row, cursorY, info.RTL); } else { this.drawRowWithElements(row, cursorY, info.RTL); diff --git a/core/renderers/common/drawer.js b/core/renderers/common/drawer.js index 79e1962de..a4e4f1684 100644 --- a/core/renderers/common/drawer.js +++ b/core/renderers/common/drawer.js @@ -29,6 +29,7 @@ goog.provide('Blockly.blockRendering.Drawer'); goog.require('Blockly.blockRendering.Debug'); goog.require('Blockly.blockRendering.RenderInfo'); goog.require('Blockly.blockRendering.Measurable'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.blockRendering.BottomRow'); goog.require('Blockly.blockRendering.InputRow'); goog.require('Blockly.blockRendering.Row'); @@ -140,17 +141,17 @@ Blockly.blockRendering.Drawer.prototype.drawTop_ = function() { this.outlinePath_ += Blockly.utils.svgPaths.moveBy(topRow.xPos, this.info_.startY); for (var i = 0, elem; (elem = elements[i]); i++) { - if (elem.type == 'round corner') { + if (Blockly.blockRendering.Types.isLeftRoundedCorner(elem)) { this.outlinePath_ += this.constants_.OUTSIDE_CORNERS.topLeft; - } else if (elem.type == 'previous connection') { + } else if (Blockly.blockRendering.Types.isPreviousConnection(elem)) { this.outlinePath_ += elem.shape.pathLeft; - } else if (elem.type == 'hat') { + } else if (Blockly.blockRendering.Types.isHat(elem)) { this.outlinePath_ += this.constants_.START_HAT.path; - } else if (elem.isSpacer()) { + } else if (Blockly.blockRendering.Types.isSpacer(elem)) { this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('h', elem.width); } - // No branch for a 'square corner', because it's a no-op. + // No branch for a square corner, because it's a no-op. } this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('v', topRow.height); }; @@ -241,13 +242,13 @@ Blockly.blockRendering.Drawer.prototype.drawBottom_ = function() { Blockly.utils.svgPaths.lineOnAxis('v', bottomRow.height - bottomRow.overhangY); for (var i = elems.length - 1, elem; (elem = elems[i]); i--) { - if (elem.isNextConnection()) { + if (Blockly.blockRendering.Types.isNextConnection(elem)) { this.outlinePath_ += elem.shape.pathRight; - } else if (elem.isSquareCorner()) { + } else if (Blockly.blockRendering.Types.isLeftSquareCorner(elem)) { this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('H', bottomRow.xPos); - } else if (elem.isRoundedCorner()) { + } else if (Blockly.blockRendering.Types.isLeftRoundedCorner(elem)) { this.outlinePath_ += this.constants_.OUTSIDE_CORNERS.bottomLeft; - } else if (elem.isSpacer()) { + } else if (Blockly.blockRendering.Types.isSpacer(elem)) { this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('h', elem.width * -1); } } @@ -283,9 +284,10 @@ Blockly.blockRendering.Drawer.prototype.drawLeft_ = function() { Blockly.blockRendering.Drawer.prototype.drawInternals_ = function() { for (var i = 0, row; (row = this.info_.rows[i]); i++) { for (var j = 0, elem; (elem = row.elements[j]); j++) { - if (elem.isInlineInput()) { + if (Blockly.blockRendering.Types.isInlineInput(elem)) { this.drawInlineInput_(elem); - } else if (elem.isIcon() || elem.isField()) { + } else if (Blockly.blockRendering.Types.isIcon(elem) || + Blockly.blockRendering.Types.isField(elem)) { this.layoutField_(elem); } } @@ -299,9 +301,9 @@ Blockly.blockRendering.Drawer.prototype.drawInternals_ = function() { * @protected */ Blockly.blockRendering.Drawer.prototype.layoutField_ = function(fieldInfo) { - if (fieldInfo.isField()) { + if (Blockly.blockRendering.Types.isField(fieldInfo)) { var svgGroup = fieldInfo.field.getSvgRoot(); - } else if (fieldInfo.isIcon()) { + } else if (Blockly.blockRendering.Types.isIcon(fieldInfo)) { var svgGroup = fieldInfo.icon.iconGroup_; } @@ -315,7 +317,7 @@ Blockly.blockRendering.Drawer.prototype.layoutField_ = function(fieldInfo) { scale = 'scale(-1 1)'; } } - if (fieldInfo.isIcon()) { + if (Blockly.blockRendering.Types.isIcon(fieldInfo)) { svgGroup.setAttribute('display', 'block'); svgGroup.setAttribute('transform', 'translate(' + xPos + ',' + yPos + ')'); fieldInfo.icon.computeIconLocation(); diff --git a/core/renderers/common/info.js b/core/renderers/common/info.js index 74a818357..1d0d7b34e 100644 --- a/core/renderers/common/info.js +++ b/core/renderers/common/info.js @@ -27,6 +27,7 @@ goog.provide('Blockly.blockRendering.RenderInfo'); goog.require('Blockly.blockRendering.Measurable'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.blockRendering.BottomRow'); goog.require('Blockly.blockRendering.InputRow'); goog.require('Blockly.blockRendering.Row'); @@ -283,7 +284,8 @@ Blockly.blockRendering.RenderInfo.prototype.addElemSpacing_ = function() { var oldElems = row.elements; row.elements = []; // No spacing needed before the corner on the top row or the bottom row. - if (row.type != 'top row' && row.type != 'bottom row') { + if (!Blockly.blockRendering.Types.isTopRow(row) && + !Blockly.blockRendering.Types.isBottomRow(row)) { // There's a spacer before the first element in the row. row.elements.push(new Blockly.blockRendering.InRowSpacer( this.getInRowSpacing_(null, oldElems[0]))); @@ -308,12 +310,12 @@ Blockly.blockRendering.RenderInfo.prototype.addElemSpacing_ = function() { */ Blockly.blockRendering.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { // Between inputs and the end of the row. - if (prev && prev.isInput && !next) { - if (prev.isExternalInput()) { + if (prev && Blockly.blockRendering.Types.isInput(prev) && !next) { + if (Blockly.blockRendering.Types.isExternalInput(prev)) { return this.constants_.NO_PADDING; - } else if (prev.isInlineInput()) { + } else if (Blockly.blockRendering.Types.isInlineInput(prev)) { return this.constants_.LARGE_PADDING; - } else if (prev.isStatementInput()) { + } else if (Blockly.blockRendering.Types.isStatementInput(prev)) { return this.constants_.NO_PADDING; } } @@ -448,8 +450,8 @@ Blockly.blockRendering.RenderInfo.prototype.addRowSpacing_ = function() { /** * Create a spacer row to go between prev and next, and set its size. - * @param {?Blockly.blockRendering.Row} prev The previous row, or null. - * @param {?Blockly.blockRendering.Row} next The next row, or null. + * @param {!Blockly.blockRendering.Row} prev The previous row. + * @param {!Blockly.blockRendering.Row} next The next row. * @return {!Blockly.blockRendering.SpacerRow} The newly created spacer row. * @protected */ @@ -465,8 +467,8 @@ Blockly.blockRendering.RenderInfo.prototype.makeSpacerRow_ = function(prev, next /** * Calculate the width of a spacer row. - * @param {Blockly.blockRendering.Row} _prev The row before the spacer. - * @param {Blockly.blockRendering.Row} _next The row after the spacer. + * @param {!Blockly.blockRendering.Row} _prev The row before the spacer. + * @param {!Blockly.blockRendering.Row} _next The row after the spacer. * @return {number} The desired width of the spacer row between these two rows. * @protected */ @@ -477,8 +479,8 @@ Blockly.blockRendering.RenderInfo.prototype.getSpacerRowWidth_ = function( /** * Calculate the height of a spacer row. - * @param {Blockly.blockRendering.Row} _prev The row before the spacer. - * @param {Blockly.blockRendering.Row} _next The row after the spacer. + * @param {!Blockly.blockRendering.Row} _prev The row before the spacer. + * @param {!Blockly.blockRendering.Row} _next The row after the spacer. * @return {number} The desired height of the spacer row between these two rows. * @protected */ @@ -489,8 +491,8 @@ Blockly.blockRendering.RenderInfo.prototype.getSpacerRowHeight_ = function( /** * Calculate the centerline of an element in a rendered row. - * @param {Blockly.blockRendering.Row} row The row containing the element. - * @param {Blockly.blockRendering.Measurable} elem The element to place. + * @param {!Blockly.blockRendering.Row} row The row containing the element. + * @param {!Blockly.blockRendering.Measurable} elem The element to place. * @return {number} The desired centerline of the given element, as an offset * from the top left of the block. * @protected @@ -498,7 +500,7 @@ Blockly.blockRendering.RenderInfo.prototype.getSpacerRowHeight_ = function( Blockly.blockRendering.RenderInfo.prototype.getElemCenterline_ = function(row, elem) { var result = row.yPos; - if (elem.isNextConnection()) { + if (Blockly.blockRendering.Types.isNextConnection(elem)) { result += (row.height - row.overhangY + elem.height / 2); } else { result += (row.height / 2); diff --git a/core/renderers/geras/highlighter.js b/core/renderers/geras/highlighter.js index 0cc718d92..a60c019d5 100644 --- a/core/renderers/geras/highlighter.js +++ b/core/renderers/geras/highlighter.js @@ -29,6 +29,7 @@ goog.provide('Blockly.geras.Highlighter'); goog.require('Blockly.blockRendering.RenderInfo'); goog.require('Blockly.blockRendering.Measurable'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.blockRendering.BottomRow'); goog.require('Blockly.blockRendering.InputRow'); goog.require('Blockly.blockRendering.Row'); @@ -84,16 +85,16 @@ Blockly.geras.Highlighter.prototype.drawTopCorner = function(row) { this.steps_.push( Blockly.utils.svgPaths.moveBy(row.xPos, this.info_.startY)); for (var i = 0, elem; (elem = row.elements[i]); i++) { - if (elem.type == 'square corner') { + if (Blockly.blockRendering.Types.isLeftSquareCorner(elem)) { this.steps_.push(this.highlightConstants_.START_POINT); - } else if (elem.type == 'round corner') { + } else if (Blockly.blockRendering.Types.isLeftRoundedCorner(elem)) { this.steps_.push( this.outsideCornerPaths_.topLeft(this.RTL_)); - } else if (elem.type == 'previous connection') { + } else if (Blockly.blockRendering.Types.isPreviousConnection(elem)) { this.steps_.push(this.notchPaths_.pathLeft); - } else if (elem.type == 'hat') { + } else if (Blockly.blockRendering.Types.isHat(elem)) { this.steps_.push(this.startPaths_.path(this.RTL_)); - } else if (elem.isSpacer() && elem.width != 0) { + } else if (Blockly.blockRendering.Types.isSpacer(elem) && elem.width != 0) { // The end point of the spacer needs to be offset by the highlight amount. // So instead of using the spacer's width for a relative horizontal, use // its width and position for an absolute horizontal move. @@ -179,12 +180,12 @@ Blockly.geras.Highlighter.prototype.drawBottomRow = function(row) { this.steps_.push('V', height - this.highlightOffset_); } else { var cornerElem = this.info_.bottomRow.elements[0]; - if (cornerElem.type == 'square corner') { + if (Blockly.blockRendering.Types.isLeftSquareCorner(cornerElem)) { this.steps_.push( Blockly.utils.svgPaths.moveTo( row.xPos + this.highlightOffset_, height - this.highlightOffset_)); - } else if (cornerElem.type == 'round corner') { + } else if (Blockly.blockRendering.Types.isLeftRoundedCorner(cornerElem)) { this.steps_.push(Blockly.utils.svgPaths.moveTo(row.xPos, height)); this.steps_.push(this.outsideCornerPaths_.bottomLeft()); } @@ -210,7 +211,7 @@ Blockly.geras.Highlighter.prototype.drawLeft = function() { if (!this.RTL_) { var topRow = this.info_.topRow; - if (topRow.elements[0].isRoundedCorner()) { + if (Blockly.blockRendering.Types.isLeftRoundedCorner(topRow.elements[0])) { this.steps_.push('V', this.outsideCornerPaths_.height); } else { this.steps_.push('V', topRow.startY + this.highlightOffset_); diff --git a/core/renderers/geras/info.js b/core/renderers/geras/info.js index e119efabd..53322a32d 100644 --- a/core/renderers/geras/info.js +++ b/core/renderers/geras/info.js @@ -30,6 +30,7 @@ goog.provide('Blockly.geras.RenderInfo'); goog.require('Blockly.blockRendering.RenderInfo'); goog.require('Blockly.blockRendering.Measurable'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.blockRendering.BottomRow'); goog.require('Blockly.blockRendering.InputRow'); goog.require('Blockly.blockRendering.Row'); @@ -89,14 +90,14 @@ Blockly.geras.RenderInfo.prototype.shouldStartNewRow_ = function(input, lastInpu Blockly.geras.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { if (!prev) { // Between an editable field and the beginning of the row. - if (next.isField() && next.isEditable) { + if (next && Blockly.blockRendering.Types.isField(next) && next.isEditable) { return this.constants_.MEDIUM_PADDING; } // Inline input at the beginning of the row. - if (next.isInput && next.isInlineInput()) { + if (next && Blockly.blockRendering.Types.isInlineInput(next)) { return this.constants_.MEDIUM_LARGE_PADDING; } - if (next.isStatementInput()) { + if (next && Blockly.blockRendering.Types.isStatementInput(next)) { return this.constants_.STATEMENT_INPUT_PADDING_LEFT; } // Anything else at the beginning of the row. @@ -104,28 +105,28 @@ Blockly.geras.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between a non-input and the end of the row. - if (!prev.isInput && !next) { + if (!Blockly.blockRendering.Types.isInput(prev) && !next) { // Between an editable field and the end of the row. - if (prev.isField() && prev.isEditable) { + if (Blockly.blockRendering.Types.isField(prev) && prev.isEditable) { return this.constants_.MEDIUM_PADDING; } // Padding at the end of an icon-only row to make the block shape clearer. - if (prev.isIcon()) { + if (Blockly.blockRendering.Types.isIcon(prev)) { return (this.constants_.LARGE_PADDING * 2) + 1; } - if (prev.isHat()) { + if (Blockly.blockRendering.Types.isHat(prev)) { return this.constants_.NO_PADDING; } // Establish a minimum width for a block with a previous or next connection. - if (prev.isPreviousConnection() || prev.isNextConnection()) { + if (Blockly.blockRendering.Types.isPreviousOrNextConnection(prev)) { return this.constants_.LARGE_PADDING; } // Between rounded corner and the end of the row. - if (prev.isRoundedCorner()) { + if (Blockly.blockRendering.Types.isLeftRoundedCorner(prev)) { return this.constants_.MIN_BLOCK_WIDTH; } // Between a jagged edge and the end of the row. - if (prev.isJaggedEdge()) { + if (Blockly.blockRendering.Types.isJaggedEdge(prev)) { return this.constants_.NO_PADDING; } // Between noneditable fields and icons and the end of the row. @@ -133,31 +134,32 @@ Blockly.geras.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Between inputs and the end of the row. - if (prev.isInput && !next) { - if (prev.isExternalInput()) { + if (Blockly.blockRendering.Types.isInput(prev) && !next) { + if (Blockly.blockRendering.Types.isExternalInput(prev)) { return this.constants_.NO_PADDING; - } else if (prev.isInlineInput()) { + } else if (Blockly.blockRendering.Types.isInlineInput(prev)) { return this.constants_.LARGE_PADDING; - } else if (prev.isStatementInput()) { + } else if (Blockly.blockRendering.Types.isStatementInput(prev)) { return this.constants_.NO_PADDING; } } // Spacing between a non-input and an input. - if (!prev.isInput && next.isInput) { + if (!Blockly.blockRendering.Types.isInput(prev) && + next && Blockly.blockRendering.Types.isInput(next)) { // Between an editable field and an input. if (prev.isEditable) { - if (next.isInlineInput()) { + if (Blockly.blockRendering.Types.isInlineInput(next)) { return this.constants_.SMALL_PADDING; - } else if (next.isExternalInput()) { + } else if (Blockly.blockRendering.Types.isExternalInput(next)) { return this.constants_.SMALL_PADDING; } } else { - if (next.isInlineInput()) { + if (Blockly.blockRendering.Types.isInlineInput(next)) { return this.constants_.MEDIUM_LARGE_PADDING; - } else if (next.isExternalInput()) { + } else if (Blockly.blockRendering.Types.isExternalInput(next)) { return this.constants_.MEDIUM_LARGE_PADDING; - } else if (next.isStatementInput()) { + } else if (Blockly.blockRendering.Types.isStatementInput(next)) { return this.constants_.LARGE_PADDING; } } @@ -165,12 +167,14 @@ Blockly.geras.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between an icon and an icon or field. - if (prev.isIcon() && !next.isInput) { + if (Blockly.blockRendering.Types.isIcon(prev) && + !Blockly.blockRendering.Types.isInput(next)) { return this.constants_.LARGE_PADDING; } // Spacing between an inline input and a field. - if (prev.isInlineInput() && !next.isInput) { + if (Blockly.blockRendering.Types.isInlineInput(prev) && + !Blockly.blockRendering.Types.isInput(next)) { // Editable field after inline input. if (next.isEditable) { return this.constants_.MEDIUM_PADDING; @@ -180,15 +184,15 @@ Blockly.geras.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } } - if (prev.isSquareCorner()) { + if (Blockly.blockRendering.Types.isLeftSquareCorner(prev) && next) { // Spacing between a hat and a corner - if (next.isHat()) { + if (Blockly.blockRendering.Types.isHat(next)) { return this.constants_.NO_PADDING; } // Spacing between a square corner and a previous or next connection - if (next.isPreviousConnection()) { + if (Blockly.blockRendering.Types.isPreviousConnection(next)) { return next.notchOffset; - } else if (next.isNextConnection()) { + } else if (Blockly.blockRendering.Types.isNextConnection(next)) { // Next connections are shifted slightly to the left (in both LTR and RTL) // to make the dark path under the previous connection show through. var offset = (this.RTL ? 1 : -1) * @@ -198,10 +202,10 @@ Blockly.geras.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between a rounded corner and a previous or next connection. - if (prev.isRoundedCorner()) { - if (next.isPreviousConnection()) { + if (Blockly.blockRendering.Types.isLeftRoundedCorner(prev) && next) { + if (Blockly.blockRendering.Types.isPreviousConnection(next)) { return next.notchOffset - this.constants_.CORNER_RADIUS; - } else if (next.isNextConnection()) { + } else if (Blockly.blockRendering.Types.isNextConnection(next)) { // Next connections are shifted slightly to the left (in both LTR and RTL) // to make the dark path under the previous connection show through. var offset = (this.RTL ? 1 : -1) * @@ -211,12 +215,14 @@ Blockly.geras.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between two fields of the same editability. - if (!prev.isInput && !next.isInput && (prev.isEditable == next.isEditable)) { + if (!Blockly.blockRendering.Types.isInput(prev) && + !Blockly.blockRendering.Types.isInput(next) && + (prev.isEditable == next.isEditable)) { return this.constants_.LARGE_PADDING; } // Spacing between anything and a jagged edge. - if (next.isJaggedEdge()) { + if (next && Blockly.blockRendering.Types.isJaggedEdge(next)) { return this.constants_.LARGE_PADDING; } @@ -262,11 +268,13 @@ Blockly.geras.RenderInfo.prototype.addAlignmentPadding_ = function(row, missingS */ Blockly.geras.RenderInfo.prototype.getSpacerRowHeight_ = function(prev, next) { // If we have an empty block add a spacer to increase the height. - if (prev.type == 'top row' && next.type == 'bottom row') { + if (Blockly.blockRendering.Types.isTopRow(prev) && + Blockly.blockRendering.Types.isBottomRow(next)) { return this.constants_.EMPTY_BLOCK_SPACER_HEIGHT; } // Top and bottom rows act as a spacer so we don't need any extra padding. - if (prev.type == 'top row' || next.type == 'bottom row') { + if (Blockly.blockRendering.Types.isTopRow(prev) || + Blockly.blockRendering.Types.isBottomRow(next)) { return this.constants_.NO_PADDING; } if (prev.hasExternalInput && next.hasExternalInput) { @@ -289,14 +297,15 @@ Blockly.geras.RenderInfo.prototype.getSpacerRowHeight_ = function(prev, next) { */ Blockly.geras.RenderInfo.prototype.getElemCenterline_ = function(row, elem) { var result = row.yPos; - if (elem.isField() || elem.isIcon()) { + if (Blockly.blockRendering.Types.isField(elem) || + Blockly.blockRendering.Types.isIcon(elem)) { result += (elem.height / 2); if (row.hasInlineInput || row.hasStatement) { result += this.constants_.TALL_INPUT_FIELD_OFFSET_Y; } - } else if (elem.isInlineInput()) { + } else if (Blockly.blockRendering.Types.isInlineInput(elem)) { result += elem.height / 2; - } else if (elem.isNextConnection()) { + } else if (Blockly.blockRendering.Types.isNextConnection(elem)) { result += (row.height - row.overhangY + elem.height / 2); } else { result += (row.height / 2); diff --git a/core/renderers/measurables/base.js b/core/renderers/measurables/base.js index 7f0a2dfd0..00f7f5e52 100644 --- a/core/renderers/measurables/base.js +++ b/core/renderers/measurables/base.js @@ -27,6 +27,7 @@ goog.provide('Blockly.blockRendering.Measurable'); +goog.require('Blockly.blockRendering.Types'); /** * The base class to represent a part of a block that takes up space during @@ -36,10 +37,9 @@ goog.provide('Blockly.blockRendering.Measurable'); * @constructor */ Blockly.blockRendering.Measurable = function() { - this.isInput = false; this.width = 0; this.height = 0; - this.type = null; + this.type = Blockly.blockRendering.Types.NONE; this.xPos = 0; this.centerline = 0; @@ -47,121 +47,3 @@ Blockly.blockRendering.Measurable = function() { this.constants_ = Blockly.blockRendering.getConstants(); this.notchOffset = this.constants_.NOTCH_OFFSET_LEFT; }; - -// TODO: We may remove these helper functions if all of them end up being direct -// checks against types. - -/** - * Whether this stores information about a field. - * @return {boolean} True if this object stores information about a field. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isField = function() { - return this.type == 'field'; -}; - -/** - * Whether this stores information about a hat. - * @return {boolean} True if this object stores information about a hat. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isHat = function() { - return this.type == 'hat'; -}; - -/** - * Whether this stores information about an icon. - * @return {boolean} True if this object stores information about an icon. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isIcon = function() { - return this.type == 'icon'; -}; - -/** - * Whether this stores information about a spacer. - * @return {boolean} True if this object stores information about a spacer. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isSpacer = function() { - return this.type == 'between-row spacer' || this.type == 'in-row spacer'; -}; - -/** - * Whether this stores information about an external input. - * @return {boolean} True if this object stores information about an external - * input. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isExternalInput = function() { - return this.type == 'external value input'; -}; - -/** - * Whether this stores information about a inline input. - * @return {boolean} True if this object stores information about a inline - * input. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isInlineInput = function() { - return this.type == 'inline input'; -}; - -/** - * Whether this stores information about a statement input. - * @return {boolean} True if this object stores information about a statement - * input. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isStatementInput = function() { - return this.type == 'statement input'; -}; - -/** - * Whether this stores information about a previous connection. - * @return {boolean} True if this object stores information about a previous - * connection. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isPreviousConnection = function() { - return this.type == 'previous connection'; -}; - -/** - * Whether this stores information about a next connection. - * @return {boolean} True if this object stores information about an next - * connection. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isNextConnection = function() { - return this.type == 'next connection'; -}; - -/** - * Whether this stores information about a rounded corner. - * @return {boolean} True if this object stores information about an rounded - * corner. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isRoundedCorner = function() { - return this.type == 'round corner'; -}; - -/** - * Whether this stores information about a square corner. - * @return {boolean} True if this object stores information about an square - * corner. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isSquareCorner = function() { - return this.type == 'square corner'; -}; - -/** - * Whether this stores information about a jagged edge. - * @return {boolean} True if this object stores information about a jagged edge. - * @package - */ -Blockly.blockRendering.Measurable.prototype.isJaggedEdge = function() { - return this.type == 'jagged edge'; -}; diff --git a/core/renderers/measurables/connections.js b/core/renderers/measurables/connections.js index 4059d7f34..082c9400e 100644 --- a/core/renderers/measurables/connections.js +++ b/core/renderers/measurables/connections.js @@ -29,6 +29,7 @@ goog.provide('Blockly.blockRendering.OutputConnection'); goog.provide('Blockly.blockRendering.PreviousConnection'); goog.require('Blockly.blockRendering.Measurable'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.RenderedConnection'); /** @@ -44,6 +45,7 @@ Blockly.blockRendering.Connection = function(connectionModel) { Blockly.blockRendering.Connection.superClass_.constructor.call(this); this.connectionModel = connectionModel; this.shape = this.constants_.shapeFor(connectionModel); + this.type |= Blockly.blockRendering.Types.CONNECTION; }; goog.inherits(Blockly.blockRendering.Connection, Blockly.blockRendering.Measurable); @@ -60,7 +62,7 @@ goog.inherits(Blockly.blockRendering.Connection, Blockly.blockRendering.OutputConnection = function(connectionModel) { Blockly.blockRendering.OutputConnection.superClass_.constructor.call(this, connectionModel); - this.type = 'output connection'; + this.type |= Blockly.blockRendering.Types.OUTPUT_CONNECTION; this.height = this.shape.height; this.width = this.shape.width; this.connectionOffsetY = this.constants_.TAB_OFFSET_FROM_TOP; @@ -81,7 +83,7 @@ goog.inherits(Blockly.blockRendering.OutputConnection, Blockly.blockRendering.PreviousConnection = function(connectionModel) { Blockly.blockRendering.PreviousConnection.superClass_.constructor.call(this, connectionModel); - this.type = 'previous connection'; + this.type |= Blockly.blockRendering.Types.PREVIOUS_CONNECTION; this.height = this.shape.height; this.width = this.shape.width; @@ -101,7 +103,7 @@ goog.inherits(Blockly.blockRendering.PreviousConnection, Blockly.blockRendering.NextConnection = function(connectionModel) { Blockly.blockRendering.NextConnection.superClass_.constructor.call(this, connectionModel); - this.type = 'next connection'; + this.type |= Blockly.blockRendering.Types.NEXT_CONNECTION; this.height = this.shape.height; this.width = this.shape.width; }; diff --git a/core/renderers/measurables/inputs.js b/core/renderers/measurables/inputs.js index feadeeede..81aff973f 100644 --- a/core/renderers/measurables/inputs.js +++ b/core/renderers/measurables/inputs.js @@ -31,6 +31,7 @@ goog.provide('Blockly.blockRendering.ExternalValueInput'); goog.require('Blockly.blockRendering.Connection'); goog.require('Blockly.blockRendering.Measurable'); +goog.require('Blockly.blockRendering.Types'); /** @@ -45,7 +46,7 @@ Blockly.blockRendering.InputConnection = function(input) { Blockly.blockRendering.InputConnection.superClass_.constructor.call(this, input.connection); - this.isInput = true; + this.type |= Blockly.blockRendering.Types.INPUT; this.input = input; this.align = input.align; this.connectedBlock = input.connection && input.connection.targetBlock() ? @@ -80,7 +81,7 @@ goog.inherits(Blockly.blockRendering.InputConnection, Blockly.blockRendering.InlineInput = function(input) { Blockly.blockRendering.InlineInput.superClass_.constructor.call(this, input); - this.type = 'inline input'; + this.type |= Blockly.blockRendering.Types.INLINE_INPUT; if (!this.connectedBlock) { this.height = this.constants_.EMPTY_INLINE_INPUT_HEIGHT; @@ -113,7 +114,7 @@ goog.inherits(Blockly.blockRendering.InlineInput, Blockly.blockRendering.StatementInput = function(input) { Blockly.blockRendering.StatementInput.superClass_.constructor.call(this, input); - this.type = 'statement input'; + this.type |= Blockly.blockRendering.Types.STATEMENT_INPUT; if (!this.connectedBlock) { this.height = this.constants_.EMPTY_STATEMENT_INPUT_HEIGHT; @@ -142,7 +143,7 @@ goog.inherits(Blockly.blockRendering.StatementInput, Blockly.blockRendering.ExternalValueInput = function(input) { Blockly.blockRendering.ExternalValueInput.superClass_.constructor.call(this, input); - this.type = 'external value input'; + this.type |= Blockly.blockRendering.Types.EXTERNAL_VALUE_INPUT; if (!this.connectedBlock) { this.height = this.shape.height; diff --git a/core/renderers/measurables/row_elements.js b/core/renderers/measurables/row_elements.js index 21827ce55..07bf6f944 100644 --- a/core/renderers/measurables/row_elements.js +++ b/core/renderers/measurables/row_elements.js @@ -6,6 +6,7 @@ goog.provide('Blockly.blockRendering.InRowSpacer'); goog.provide('Blockly.blockRendering.JaggedEdge'); goog.provide('Blockly.blockRendering.RoundCorner'); goog.provide('Blockly.blockRendering.SquareCorner'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.blockRendering.Measurable'); @@ -21,7 +22,7 @@ Blockly.blockRendering.Icon = function(icon) { Blockly.blockRendering.Icon.superClass_.constructor.call(this); this.icon = icon; this.isVisible = icon.isVisible(); - this.type = 'icon'; + this.type |= Blockly.blockRendering.Types.ICON; var size = icon.getCorrectedSize(); this.height = size.height; @@ -38,7 +39,7 @@ goog.inherits(Blockly.blockRendering.Icon, Blockly.blockRendering.Measurable); */ Blockly.blockRendering.JaggedEdge = function() { Blockly.blockRendering.JaggedEdge.superClass_.constructor.call(this); - this.type = 'jagged edge'; + this.type |= Blockly.blockRendering.Types.JAGGED_EDGE; this.height = this.constants_.JAGGED_TEETH.height; this.width = this.constants_.JAGGED_TEETH.width; }; @@ -60,7 +61,7 @@ Blockly.blockRendering.Field = function(field, parentInput) { this.field = field; this.isEditable = field.isCurrentlyEditable(); this.flipRtl = field instanceof Blockly.FieldImage && field.getFlipRtl(); - this.type = 'field'; + this.type |= Blockly.blockRendering.Types.FIELD; var size = this.field.getSize(); this.height = size.height; @@ -78,7 +79,7 @@ goog.inherits(Blockly.blockRendering.Field, Blockly.blockRendering.Measurable); */ Blockly.blockRendering.Hat = function() { Blockly.blockRendering.Hat.superClass_.constructor.call(this); - this.type = 'hat'; + this.type |= Blockly.blockRendering.Types.HAT; this.height = this.constants_.START_HAT.height; this.width = this.constants_.START_HAT.width; this.startY = this.height; @@ -96,7 +97,10 @@ goog.inherits(Blockly.blockRendering.Hat, Blockly.blockRendering.Measurable); */ Blockly.blockRendering.SquareCorner = function(opt_position) { Blockly.blockRendering.SquareCorner.superClass_.constructor.call(this); - this.type = 'square corner' + (opt_position ? ' ' + opt_position : ''); + this.type = ((!opt_position || opt_position == 'left') ? + Blockly.blockRendering.Types.LEFT_SQUARE_CORNER : + Blockly.blockRendering.Types.RIGHT_SQUARE_CORNER) | + Blockly.blockRendering.Types.CORNER; this.height = this.constants_.NOTCH.height; this.width = this.constants_.NO_PADDING; @@ -114,7 +118,10 @@ goog.inherits(Blockly.blockRendering.SquareCorner, */ Blockly.blockRendering.RoundCorner = function(opt_position) { Blockly.blockRendering.RoundCorner.superClass_.constructor.call(this); - this.type = 'round corner' + (opt_position ? ' ' + opt_position : ''); + this.type = ((!opt_position || opt_position == 'left') ? + Blockly.blockRendering.Types.LEFT_ROUND_CORNER : + Blockly.blockRendering.Types.RIGHT_ROUND_CORNER) | + Blockly.blockRendering.Types.CORNER; this.width = this.constants_.CORNER_RADIUS; // The rounded corner extends into the next row by 4 so we only take the // height that is aligned with this row. @@ -134,7 +141,8 @@ goog.inherits(Blockly.blockRendering.RoundCorner, */ Blockly.blockRendering.InRowSpacer = function(width) { Blockly.blockRendering.InRowSpacer.superClass_.constructor.call(this); - this.type = 'in-row spacer'; + this.type |= Blockly.blockRendering.Types.SPACER | + Blockly.blockRendering.Types.IN_ROW_SPACER; this.width = width; this.height = this.constants_.SPACER_DEFAULT_HEIGHT; }; diff --git a/core/renderers/measurables/rows.js b/core/renderers/measurables/rows.js index 808f3b104..6a3b08d3e 100644 --- a/core/renderers/measurables/rows.js +++ b/core/renderers/measurables/rows.js @@ -35,6 +35,7 @@ goog.require('Blockly.blockRendering.InRowSpacer'); goog.require('Blockly.blockRendering.Measurable'); goog.require('Blockly.blockRendering.NextConnection'); goog.require('Blockly.blockRendering.PreviousConnection'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.RenderedConnection'); /** @@ -47,9 +48,9 @@ Blockly.blockRendering.Row = function() { /** * The type of this rendering object. * @package - * @type {string} + * @type {number} */ - this.type = 'row'; + this.type = Blockly.blockRendering.Types.ROW; /** * An array of elements contained in this row. @@ -166,7 +167,7 @@ Blockly.blockRendering.Row.prototype.measure = function() { */ Blockly.blockRendering.Row.prototype.getLastInput = function() { for (var i = this.elements.length - 1, elem; (elem = this.elements[i]); i--) { - if (elem.isInput) { + if (Blockly.blockRendering.Types.isInput(elem)) { return /** @type {Blockly.blockRendering.InputConnection} */ (elem); } } @@ -181,7 +182,7 @@ Blockly.blockRendering.Row.prototype.getLastInput = function() { */ Blockly.blockRendering.Row.prototype.getFirstSpacer = function() { for (var i = 0, elem; (elem = this.elements[i]); i++) { - if (elem.isSpacer) { + if (Blockly.blockRendering.Types.isSpacer(elem)) { return /** @type {Blockly.blockRendering.InRowSpacer} */ (elem); } } @@ -196,7 +197,7 @@ Blockly.blockRendering.Row.prototype.getFirstSpacer = function() { */ Blockly.blockRendering.Row.prototype.getLastSpacer = function() { for (var i = this.elements.length - 1, elem; (elem = this.elements[i]); i--) { - if (elem.isSpacer) { + if (Blockly.blockRendering.Types.isSpacer(elem)) { return /** @type {Blockly.blockRendering.InRowSpacer} */ (elem); } } @@ -217,7 +218,7 @@ Blockly.blockRendering.Row.prototype.getLastSpacer = function() { Blockly.blockRendering.TopRow = function() { Blockly.blockRendering.TopRow.superClass_.constructor.call(this); - this.type = 'top row'; + this.type |= Blockly.blockRendering.Types.TOP_ROW; /** * The starting point for drawing the row, in the y direction. @@ -303,8 +304,8 @@ Blockly.blockRendering.TopRow.prototype.measure = function() { this.height = this.minHeight; for (var e = 0, elem; (elem = this.elements[e]); e++) { this.width += elem.width; - if (!(elem.isSpacer())) { - if (elem.type == 'hat') { + if (!(Blockly.blockRendering.Types.isSpacer(elem))) { + if (Blockly.blockRendering.Types.isHat(elem)) { this.startY = elem.startY; this.height = this.height + elem.height; } @@ -324,7 +325,7 @@ Blockly.blockRendering.TopRow.prototype.measure = function() { */ Blockly.blockRendering.BottomRow = function() { Blockly.blockRendering.BottomRow.superClass_.constructor.call(this); - this.type = 'bottom row'; + this.type |= Blockly.blockRendering.Types.BOTTOM_ROW; /** * Whether this row has a next connection. @@ -403,8 +404,8 @@ Blockly.blockRendering.BottomRow.prototype.measure = function() { this.height = this.minHeight; for (var e = 0, elem; (elem = this.elements[e]); e++) { this.width += elem.width; - if (!(elem.isSpacer())) { - if (elem.type == 'next connection') { + if (!(Blockly.blockRendering.Types.isSpacer(elem))) { + if (Blockly.blockRendering.Types.isNextConnection(elem)) { this.height = this.height + elem.height; this.overhangY = elem.height; } @@ -422,7 +423,8 @@ Blockly.blockRendering.BottomRow.prototype.measure = function() { * @extends {Blockly.blockRendering.Row} */ Blockly.blockRendering.SpacerRow = function(height, width) { - this.type = 'between-row spacer'; + this.type |= Blockly.blockRendering.Types.SPACER | + Blockly.blockRendering.Types.BETWEEN_ROW_SPACER; this.width = width; this.height = height; this.followsStatement = false; @@ -447,7 +449,7 @@ Blockly.blockRendering.SpacerRow.prototype.measure = function() { */ Blockly.blockRendering.InputRow = function() { Blockly.blockRendering.InputRow.superClass_.constructor.call(this); - this.type = 'input row'; + this.type |= Blockly.blockRendering.Types.INPUT_ROW; /** * The total width of all blocks connected to this row. @@ -469,15 +471,15 @@ Blockly.blockRendering.InputRow.prototype.measure = function() { var connectedBlockWidths = 0; for (var e = 0, elem; (elem = this.elements[e]); e++) { this.width += elem.width; - if (elem.isInput) { - if (elem.type == 'statement input') { + if (Blockly.blockRendering.Types.isInput(elem)) { + if (Blockly.blockRendering.Types.isStatementInput(elem)) { connectedBlockWidths += elem.connectedBlockWidth; - } else if (elem.type == 'external value input' && + } else if (Blockly.blockRendering.Types.isExternalInput(elem) && elem.connectedBlockWidth != 0) { connectedBlockWidths += (elem.connectedBlockWidth - elem.connectionWidth); } } - if (!(elem.isSpacer())) { + if (!(Blockly.blockRendering.Types.isSpacer(elem))) { this.height = Math.max(this.height, elem.height); } } @@ -494,10 +496,10 @@ Blockly.blockRendering.InputRow.prototype.getLastSpacer = function() { if (this.hasExternalInput || this.hasStatement) { var elems = this.elements; for (var i = elems.length - 1, elem; (elem = elems[i]); i--) { - if (elem.isSpacer()) { + if (Blockly.blockRendering.Types.isSpacer(elem)) { continue; } - if (elem.isInput) { + if (Blockly.blockRendering.Types.isInput(elem)) { var spacer = elems[i - 1]; return /** @type {Blockly.blockRendering.InRowSpacer} */ (spacer); } diff --git a/core/renderers/measurables/types.js b/core/renderers/measurables/types.js new file mode 100644 index 000000000..6bdc5dcc2 --- /dev/null +++ b/core/renderers/measurables/types.js @@ -0,0 +1,363 @@ +/** + * @license + * Visual Blocks Editor + * + * Copyright 2019 Google Inc. + * https://developers.google.com/blockly/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Measurable types. + * @author samelh@google.com (Sam El-Husseini) + */ + +'use strict'; + +goog.provide('Blockly.blockRendering.Types'); + + +/** + * Types of rendering elements. + * @enum {number} + * @package + */ +Blockly.blockRendering.Types = { + NONE: 0, // None + FIELD: 1 << 0, // Field. + HAT: 1 << 1, // Hat. + ICON: 1 << 2, // Icon. + SPACER: 1 << 3, // Spacer. + BETWEEN_ROW_SPACER: 1 << 4, // Between Row Spacer. + IN_ROW_SPACER: 1 << 5, // In Row Spacer. + EXTERNAL_VALUE_INPUT: 1 << 6, // External Value Input. + INPUT: 1 << 7, // Input + INLINE_INPUT: 1 << 8, // Inline Input. + STATEMENT_INPUT: 1 << 9, // Statement Input. + CONNECTION: 1 << 10, // Connection. + PREVIOUS_CONNECTION: 1 << 11, // Previous Connection. + NEXT_CONNECTION: 1 << 12, // Next Connection. + OUTPUT_CONNECTION: 1 << 13, // Output Connection. + CORNER: 1 << 14, // Corner. + LEFT_SQUARE_CORNER: 1 << 15, // Square Corner. + LEFT_ROUND_CORNER: 1 << 16, // Round Corner. + RIGHT_SQUARE_CORNER: 1 << 17, // Right Square Corner. + RIGHT_ROUND_CORNER: 1 << 18, // Right Round Corner. + JAGGED_EDGE: 1 << 19, // Jagged Edge. + ROW: 1 << 20, // Row + TOP_ROW: 1 << 21, // Top Row. + BOTTOM_ROW: 1 << 22, // Bototm Row. + INPUT_ROW: 1 << 23, // Input Row. +}; + +/** + * A Left Corner Union Type. + * @type {number} + * @const + * @package + */ +Blockly.blockRendering.Types.LEFT_CORNER = + Blockly.blockRendering.Types.LEFT_SQUARE_CORNER | + Blockly.blockRendering.Types.LEFT_ROUND_CORNER; + +/** + * A Right Corner Union Type. + * @type {number} + * @const + * @package + */ +Blockly.blockRendering.Types.RIGHT_CORNER = + Blockly.blockRendering.Types.RIGHT_SQUARE_CORNER | + Blockly.blockRendering.Types.RIGHT_ROUND_CORNER; + +/** + * Next flag value to use for custom rendering element types. + * This must be updated to reflect the next enum flag value + * to use if additional elements are added to + * `Blockly.blockRendering.Types`. + * @type {number} + * @private + */ +Blockly.blockRendering.Types.nextTypeValue_ = 1 << 24; + +/** + * Get the enum flag value of an existing type or register a new type. + * @param {!string} type The name of the type. + * @return {!number} The enum flag value assosiated with that type. + * @package + */ +Blockly.blockRendering.Types.getType = function(type) { + if (!Blockly.blockRendering.Types.hasOwnProperty(type)) { + Blockly.blockRendering.Types[type] = + Blockly.blockRendering.Types.nextTypeValue_; + Blockly.blockRendering.Types.nextTypeValue_ <<= 1; + } + return Blockly.blockRendering.Types[type]; +}; + +/** + * Whether a measurable stores information about a field. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a field. + * @package + */ +Blockly.blockRendering.Types.isField = function(elem) { + return elem.type & Blockly.blockRendering.Types.FIELD; +}; + +/** + * Whether a measurable stores information about a hat. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a hat. + * @package + */ +Blockly.blockRendering.Types.isHat = function(elem) { + return elem.type & Blockly.blockRendering.Types.HAT; +}; + +/** + * Whether a measurable stores information about an icon. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about an icon. + * @package + */ +Blockly.blockRendering.Types.isIcon = function(elem) { + return elem.type & Blockly.blockRendering.Types.ICON; +}; + +/** + * Whether a measurable stores information about a spacer. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a spacer. + * @package + */ +Blockly.blockRendering.Types.isSpacer = function(elem) { + return elem.type & Blockly.blockRendering.Types.SPACER; +}; + +/** + * Whether a measurable stores information about an in-row spacer. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about an + * in-row spacer. + * @package + */ +Blockly.blockRendering.Types.isInRowSpacer = function(elem) { + return elem.type & Blockly.blockRendering.Types.IN_ROW_SPACER; +}; + +/** + * Whether a measurable stores information about an input. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about an input. + * @package + */ +Blockly.blockRendering.Types.isInput = function(elem) { + return elem.type & Blockly.blockRendering.Types.INPUT; +}; + +/** + * Whether a measurable stores information about an external input. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about an + * external input. + * @package + */ +Blockly.blockRendering.Types.isExternalInput = function(elem) { + return elem.type & Blockly.blockRendering.Types.EXTERNAL_VALUE_INPUT; +}; + +/** + * Whether a measurable stores information about an inline input. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about an + * inline input. + * @package + */ +Blockly.blockRendering.Types.isInlineInput = function(elem) { + return elem.type & Blockly.blockRendering.Types.INLINE_INPUT; +}; + +/** + * Whether a measurable stores information about a statement input. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a + * statement input. + * @package + */ +Blockly.blockRendering.Types.isStatementInput = function(elem) { + return elem.type & Blockly.blockRendering.Types.STATEMENT_INPUT; +}; + +/** + * Whether a measurable stores information about a previous connection. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a + * previous connection. + * @package + */ +Blockly.blockRendering.Types.isPreviousConnection = function(elem) { + return elem.type & Blockly.blockRendering.Types.PREVIOUS_CONNECTION; +}; + +/** + * Whether a measurable stores information about a next connection. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a + * next connection. + * @package + */ +Blockly.blockRendering.Types.isNextConnection = function(elem) { + return elem.type & Blockly.blockRendering.Types.NEXT_CONNECTION; +}; + +/** + * Whether a measurable stores information about a previous or next connection. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a previous or + * next connection. + * @package + */ +Blockly.blockRendering.Types.isPreviousOrNextConnection = function(elem) { + return elem.type & (Blockly.blockRendering.Types.PREVIOUS_CONNECTION | + Blockly.blockRendering.Types.NEXT_CONNECTION); +}; + +/** + * Whether a measurable stores information about a left round corner. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a + * left round corner. + * @package + */ +Blockly.blockRendering.Types.isLeftRoundedCorner = function(elem) { + return elem.type & Blockly.blockRendering.Types.LEFT_ROUND_CORNER; +}; + +/** + * Whether a measurable stores information about a right round corner. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a + * right round corner. + * @package + */ +Blockly.blockRendering.Types.isRightRoundedCorner = function(elem) { + return elem.type & Blockly.blockRendering.Types.RIGHT_ROUND_CORNER; +}; + +/** + * Whether a measurable stores information about a left square corner. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a + * left square corner. + * @package + */ +Blockly.blockRendering.Types.isLeftSquareCorner = function(elem) { + return elem.type & Blockly.blockRendering.Types.LEFT_SQUARE_CORNER; +}; + +/** + * Whether a measurable stores information about a right square corner. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a + * right square corner. + * @package + */ +Blockly.blockRendering.Types.isRightSquareCorner = function(elem) { + return elem.type & Blockly.blockRendering.Types.RIGHT_SQUARE_CORNER; +}; + +/** + * Whether a measurable stores information about a corner. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a + * corner. + * @package + */ +Blockly.blockRendering.Types.isCorner = function(elem) { + return elem.type & Blockly.blockRendering.Types.CORNER; +}; + +/** + * Whether a measurable stores information about a jagged edge. + * @param {!Blockly.blockRendering.Measurable} elem The element to check. + * @return {number} 1 if the object stores information about a jagged edge. + * @package + */ +Blockly.blockRendering.Types.isJaggedEdge = function(elem) { + return elem.type & Blockly.blockRendering.Types.JAGGED_EDGE; +}; + +/** + * Whether a measurable stores information about a row. + * @param {!Blockly.blockRendering.Row} row The row to check. + * @return {number} 1 if the object stores information about a row. + * @package + */ +Blockly.blockRendering.Types.isRow = function(row) { + return row.type & Blockly.blockRendering.Types.ROW; +}; + +/** + * Whether a measurable stores information about a between-row spacer. + * @param {!Blockly.blockRendering.Row} row The row to check. + * @return {number} 1 if the object stores information about a + * between-row spacer. + * @package + */ +Blockly.blockRendering.Types.isBetweenRowSpacer = function(row) { + return row.type & Blockly.blockRendering.Types.BETWEEN_ROW_SPACER; +}; + +/** + * Whether a measurable stores information about a top row. + * @param {!Blockly.blockRendering.Row} row The row to check. + * @return {number} 1 if the object stores information about a top row. + * @package + */ +Blockly.blockRendering.Types.isTopRow = function(row) { + return row.type & Blockly.blockRendering.Types.TOP_ROW; +}; + +/** + * Whether a measurable stores information about a bottom row. + * @param {!Blockly.blockRendering.Row} row The row to check. + * @return {number} 1 if the object stores information about a bottom row. + * @package + */ +Blockly.blockRendering.Types.isBottomRow = function(row) { + return row.type & Blockly.blockRendering.Types.BOTTOM_ROW; +}; + +/** + * Whether a measurable stores information about a top or bottom row. + * @param {!Blockly.blockRendering.Row} row The row to check. + * @return {number} 1 if the object stores information about a top or + * bottom row. + * @package + */ +Blockly.blockRendering.Types.isTopOrBottomRow = function(row) { + return row.type & (Blockly.blockRendering.Types.TOP_ROW | + Blockly.blockRendering.Types.BOTTOM_ROW); +}; + +/** + * Whether a measurable stores information about an input row. + * @param {!Blockly.blockRendering.Row} row The row to check. + * @return {number} 1 if the object stores information about an input row. + * @package + */ +Blockly.blockRendering.Types.isInputRow = function(row) { + return row.type & Blockly.blockRendering.Types.INPUT_ROW; +}; diff --git a/core/renderers/thrasos/info.js b/core/renderers/thrasos/info.js index 2275bd95a..69dacc466 100644 --- a/core/renderers/thrasos/info.js +++ b/core/renderers/thrasos/info.js @@ -30,6 +30,7 @@ goog.provide('Blockly.thrasos.RenderInfo'); goog.require('Blockly.blockRendering.RenderInfo'); goog.require('Blockly.blockRendering.Measurable'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.blockRendering.BottomRow'); goog.require('Blockly.blockRendering.InputRow'); goog.require('Blockly.blockRendering.Row'); @@ -89,14 +90,14 @@ Blockly.thrasos.RenderInfo.prototype.shouldStartNewRow_ = function(input, lastIn Blockly.thrasos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { if (!prev) { // Between an editable field and the beginning of the row. - if (next.isField() && next.isEditable) { + if (next && Blockly.blockRendering.Types.isField(next) && next.isEditable) { return this.constants_.MEDIUM_PADDING; } // Inline input at the beginning of the row. - if (next.isInput && next.isInlineInput()) { + if (next && Blockly.blockRendering.Types.isInlineInput(next)) { return this.constants_.MEDIUM_LARGE_PADDING; } - if (next.isStatementInput()) { + if (next && Blockly.blockRendering.Types.isStatementInput(next)) { return this.constants_.STATEMENT_INPUT_PADDING_LEFT; } // Anything else at the beginning of the row. @@ -104,28 +105,28 @@ Blockly.thrasos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between a non-input and the end of the row. - if (!prev.isInput && !next) { + if (!Blockly.blockRendering.Types.isInput(prev) && !next) { // Between an editable field and the end of the row. - if (prev.isField() && prev.isEditable) { + if (Blockly.blockRendering.Types.isField(prev) && prev.isEditable) { return this.constants_.MEDIUM_PADDING; } // Padding at the end of an icon-only row to make the block shape clearer. - if (prev.isIcon()) { + if (Blockly.blockRendering.Types.isIcon(prev)) { return (this.constants_.LARGE_PADDING * 2) + 1; } - if (prev.isHat()) { + if (Blockly.blockRendering.Types.isHat(prev)) { return this.constants_.NO_PADDING; } // Establish a minimum width for a block with a previous or next connection. - if (prev.isPreviousConnection() || prev.isNextConnection()) { + if (Blockly.blockRendering.Types.isPreviousOrNextConnection(prev)) { return this.constants_.LARGE_PADDING; } // Between rounded corner and the end of the row. - if (prev.isRoundedCorner()) { + if (Blockly.blockRendering.Types.isLeftRoundedCorner(prev)) { return this.constants_.MIN_BLOCK_WIDTH; } // Between a jagged edge and the end of the row. - if (prev.isJaggedEdge()) { + if (Blockly.blockRendering.Types.isJaggedEdge(prev)) { return this.constants_.NO_PADDING; } // Between noneditable fields and icons and the end of the row. @@ -133,31 +134,32 @@ Blockly.thrasos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Between inputs and the end of the row. - if (prev.isInput && !next) { - if (prev.isExternalInput()) { + if (Blockly.blockRendering.Types.isInput(prev) && !next) { + if (Blockly.blockRendering.Types.isExternalInput(prev)) { return this.constants_.NO_PADDING; - } else if (prev.isInlineInput()) { + } else if (Blockly.blockRendering.Types.isInlineInput(prev)) { return this.constants_.LARGE_PADDING; - } else if (prev.isStatementInput()) { + } else if (Blockly.blockRendering.Types.isStatementInput(prev)) { return this.constants_.NO_PADDING; } } // Spacing between a non-input and an input. - if (!prev.isInput && next.isInput) { + if (!Blockly.blockRendering.Types.isInput(prev) && + next && Blockly.blockRendering.Types.isInput(next)) { // Between an editable field and an input. if (prev.isEditable) { - if (next.isInlineInput()) { + if (Blockly.blockRendering.Types.isInlineInput(next)) { return this.constants_.SMALL_PADDING; - } else if (next.isExternalInput()) { + } else if (Blockly.blockRendering.Types.isExternalInput(next)) { return this.constants_.SMALL_PADDING; } } else { - if (next.isInlineInput()) { + if (Blockly.blockRendering.Types.isInlineInput(next)) { return this.constants_.MEDIUM_LARGE_PADDING; - } else if (next.isExternalInput()) { + } else if (Blockly.blockRendering.Types.isExternalInput(next)) { return this.constants_.MEDIUM_LARGE_PADDING; - } else if (next.isStatementInput()) { + } else if (Blockly.blockRendering.Types.isStatementInput(next)) { return this.constants_.LARGE_PADDING; } } @@ -165,12 +167,14 @@ Blockly.thrasos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between an icon and an icon or field. - if (prev.isIcon() && !next.isInput) { + if (Blockly.blockRendering.Types.isIcon(prev) && + !Blockly.blockRendering.Types.isInput(next)) { return this.constants_.LARGE_PADDING; } // Spacing between an inline input and a field. - if (prev.isInlineInput() && !next.isInput) { + if (Blockly.blockRendering.Types.isInlineInput(prev) && + !Blockly.blockRendering.Types.isInput(next)) { // Editable field after inline input. if (next.isEditable) { return this.constants_.MEDIUM_PADDING; @@ -180,15 +184,15 @@ Blockly.thrasos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } } - if (prev.isSquareCorner()) { + if (Blockly.blockRendering.Types.isLeftSquareCorner(prev) && next) { // Spacing between a hat and a corner - if (next.isHat()) { + if (Blockly.blockRendering.Types.isHat(next)) { return this.constants_.NO_PADDING; } // Spacing between a square corner and a previous or next connection - if (next.isPreviousConnection()) { + if (Blockly.blockRendering.Types.isPreviousConnection(next)) { return next.notchOffset; - } else if (next.isNextConnection()) { + } else if (Blockly.blockRendering.Types.isNextConnection(next)) { // Next connections are shifted slightly to the left (in both LTR and RTL) // to make the dark path under the previous connection show through. var offset = (this.RTL ? 1 : -1) * @@ -198,10 +202,10 @@ Blockly.thrasos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between a rounded corner and a previous or next connection. - if (prev.isRoundedCorner()) { - if (next.isPreviousConnection()) { + if (Blockly.blockRendering.Types.isLeftRoundedCorner(prev) && next) { + if (Blockly.blockRendering.Types.isPreviousConnection(next)) { return next.notchOffset - this.constants_.CORNER_RADIUS; - } else if (next.isNextConnection()) { + } else if (Blockly.blockRendering.Types.isNextConnection(next)) { // Next connections are shifted slightly to the left (in both LTR and RTL) // to make the dark path under the previous connection show through. var offset = (this.RTL ? 1 : -1) * @@ -211,12 +215,14 @@ Blockly.thrasos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between two fields of the same editability. - if (!prev.isInput && !next.isInput && (prev.isEditable == next.isEditable)) { + if (!Blockly.blockRendering.Types.isInput(prev) && + !Blockly.blockRendering.Types.isInput(next) && + (prev.isEditable == next.isEditable)) { return this.constants_.LARGE_PADDING; } // Spacing between anything and a jagged edge. - if (next.isJaggedEdge()) { + if (next && Blockly.blockRendering.Types.isJaggedEdge(next)) { return this.constants_.LARGE_PADDING; } @@ -260,13 +266,16 @@ Blockly.thrasos.RenderInfo.prototype.addAlignmentPadding_ = function(row, missin /** * @override */ -Blockly.thrasos.RenderInfo.prototype.getSpacerRowHeight_ = function(prev, next) { +Blockly.thrasos.RenderInfo.prototype.getSpacerRowHeight_ = function( + prev, next) { // If we have an empty block add a spacer to increase the height. - if (prev.type == 'top row' && next.type == 'bottom row') { + if (Blockly.blockRendering.Types.isTopRow(prev) && + Blockly.blockRendering.Types.isBottomRow(next)) { return this.constants_.EMPTY_BLOCK_SPACER_HEIGHT; } // Top and bottom rows act as a spacer so we don't need any extra padding. - if (prev.type == 'top row' || next.type == 'bottom row') { + if (Blockly.blockRendering.Types.isTopRow(prev) || + Blockly.blockRendering.Types.isBottomRow(next)) { return this.constants_.NO_PADDING; } if (prev.hasExternalInput && next.hasExternalInput) { @@ -289,11 +298,11 @@ Blockly.thrasos.RenderInfo.prototype.getSpacerRowHeight_ = function(prev, next) */ Blockly.thrasos.RenderInfo.prototype.getElemCenterline_ = function(row, elem) { var result = row.yPos; - if (elem.isField() && row.hasStatement) { + if (Blockly.blockRendering.Types.isField(elem) && row.hasStatement) { var offset = this.constants_.TALL_INPUT_FIELD_OFFSET_Y + elem.height / 2; result += offset; - } else if (elem.isNextConnection()) { + } else if (Blockly.blockRendering.Types.isNextConnection(elem)) { result += (row.height - row.overhangY + elem.height / 2); } else { result += (row.height / 2); diff --git a/core/renderers/zelos/drawer.js b/core/renderers/zelos/drawer.js index c75768aa0..eac5c0153 100644 --- a/core/renderers/zelos/drawer.js +++ b/core/renderers/zelos/drawer.js @@ -28,6 +28,7 @@ goog.provide('Blockly.zelos.Drawer'); goog.require('Blockly.blockRendering.ConstantProvider'); goog.require('Blockly.blockRendering.Drawer'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.zelos.RenderInfo'); @@ -59,20 +60,20 @@ Blockly.zelos.Drawer.prototype.drawTop_ = function() { this.outlinePath_ += Blockly.utils.svgPaths.moveBy(topRow.xPos, this.info_.startY); for (var i = 0, elem; (elem = elements[i]); i++) { - if (elem.type == 'round corner') { + if (Blockly.blockRendering.Types.isLeftRoundedCorner(elem)) { this.outlinePath_ += this.constants_.OUTSIDE_CORNERS.topLeft; - } else if (elem.type == 'round corner right') { + } else if (Blockly.blockRendering.Types.isRightRoundedCorner(elem)) { this.outlinePath_ += this.constants_.OUTSIDE_CORNERS.topRight; - } else if (elem.type == 'previous connection') { + } else if (Blockly.blockRendering.Types.isPreviousConnection(elem)) { this.outlinePath_ += elem.shape.pathLeft; - } else if (elem.type == 'hat') { + } else if (Blockly.blockRendering.Types.isHat(elem)) { this.outlinePath_ += this.constants_.START_HAT.path; - } else if (elem.isSpacer()) { + } else if (Blockly.blockRendering.Types.isSpacer(elem)) { this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('h', elem.width); } - // No branch for a 'square corner', because it's a no-op. + // No branch for a square corner because it's a no-op. } this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('v', topRow.height); }; @@ -92,15 +93,15 @@ Blockly.zelos.Drawer.prototype.drawBottom_ = function() { Blockly.utils.svgPaths.lineOnAxis('v', bottomRow.height - bottomRow.overhangY); for (var i = elems.length - 1, elem; (elem = elems[i]); i--) { - if (elem.isNextConnection()) { + if (Blockly.blockRendering.Types.isNextConnection(elem)) { this.outlinePath_ += elem.shape.pathRight; - } else if (elem.isSquareCorner()) { + } else if (Blockly.blockRendering.Types.isLeftSquareCorner(elem)) { this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('H', bottomRow.xPos); - } else if (elem.isRoundedCorner()) { + } else if (Blockly.blockRendering.Types.isLeftRoundedCorner(elem)) { this.outlinePath_ += this.constants_.OUTSIDE_CORNERS.bottomLeft; - } else if (elem.type == 'round corner right') { + } else if (Blockly.blockRendering.Types.isRightRoundedCorner(elem)) { this.outlinePath_ += this.constants_.OUTSIDE_CORNERS.bottomRight; - } else if (elem.isSpacer()) { + } else if (Blockly.blockRendering.Types.isSpacer(elem)) { this.outlinePath_ += Blockly.utils.svgPaths.lineOnAxis('h', elem.width * -1); } } diff --git a/core/renderers/zelos/info.js b/core/renderers/zelos/info.js index 3ae1efc8b..3da55b363 100644 --- a/core/renderers/zelos/info.js +++ b/core/renderers/zelos/info.js @@ -35,6 +35,7 @@ goog.require('Blockly.blockRendering.InputRow'); goog.require('Blockly.blockRendering.Row'); goog.require('Blockly.blockRendering.SpacerRow'); goog.require('Blockly.blockRendering.TopRow'); +goog.require('Blockly.blockRendering.Types'); goog.require('Blockly.blockRendering.InlineInput'); goog.require('Blockly.blockRendering.ExternalValueInput'); @@ -87,14 +88,14 @@ goog.inherits(Blockly.zelos.RenderInfo, Blockly.blockRendering.RenderInfo); Blockly.zelos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { if (!prev) { // Between an editable field and the beginning of the row. - if (next.isField() && next.isEditable) { + if (next && Blockly.blockRendering.Types.isField(next) && next.isEditable) { return this.constants_.MEDIUM_PADDING; } // Inline input at the beginning of the row. - if (next.isInput && next.isInlineInput()) { + if (next && Blockly.blockRendering.Types.isInlineInput(next)) { return this.constants_.MEDIUM_LARGE_PADDING; } - if (next.isStatementInput()) { + if (next && Blockly.blockRendering.Types.isStatementInput(next)) { return this.constants_.STATEMENT_INPUT_PADDING_LEFT; } // Anything else at the beginning of the row. @@ -102,32 +103,32 @@ Blockly.zelos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between a non-input and the end of the row. - if (!prev.isInput && !next) { + if (!Blockly.blockRendering.Types.isInput(prev) && !next) { // Between an editable field and the end of the row. - if (prev.isField() && prev.isEditable) { + if (Blockly.blockRendering.Types.isField(prev) && prev.isEditable) { return this.constants_.MEDIUM_PADDING; } // Padding at the end of an icon-only row to make the block shape clearer. - if (prev.isIcon()) { + if (Blockly.blockRendering.Types.isIcon(prev)) { return (this.constants_.LARGE_PADDING * 2) + 1; } - if (prev.isHat()) { + if (Blockly.blockRendering.Types.isHat(prev)) { return this.constants_.NO_PADDING; } // Establish a minimum width for a block with a previous or next connection. - if (prev.isPreviousConnection() || prev.isNextConnection()) { + if (Blockly.blockRendering.Types.isPreviousOrNextConnection(prev)) { return this.constants_.LARGE_PADDING; } // Between rounded corner and the end of the row. - if (prev.isRoundedCorner()) { + if (Blockly.blockRendering.Types.isLeftRoundedCorner(prev)) { return this.constants_.MIN_BLOCK_WIDTH; } // Between a right rounded corner and the end of the row. - if (prev.type == 'round corner right') { + if (Blockly.blockRendering.Types.isRightRoundedCorner(prev)) { return this.constants_.NO_PADDING; } // Between a jagged edge and the end of the row. - if (prev.isJaggedEdge()) { + if (Blockly.blockRendering.Types.isJaggedEdge(prev)) { return this.constants_.NO_PADDING; } // Between noneditable fields and icons and the end of the row. @@ -135,31 +136,32 @@ Blockly.zelos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Between inputs and the end of the row. - if (prev.isInput && !next) { - if (prev.isExternalInput()) { + if (Blockly.blockRendering.Types.isInput(prev) && !next) { + if (Blockly.blockRendering.Types.isExternalInput(prev)) { return this.constants_.NO_PADDING; - } else if (prev.isInlineInput()) { + } else if (Blockly.blockRendering.Types.isInlineInput(prev)) { return this.constants_.LARGE_PADDING; - } else if (prev.isStatementInput()) { + } else if (Blockly.blockRendering.Types.isStatementInput(prev)) { return this.constants_.NO_PADDING; } } // Spacing between a non-input and an input. - if (!prev.isInput && next.isInput) { + if (!Blockly.blockRendering.Types.isInput(prev) && + next && Blockly.blockRendering.Types.isInput(next)) { // Between an editable field and an input. if (prev.isEditable) { - if (next.isInlineInput()) { + if (Blockly.blockRendering.Types.isInlineInput(next)) { return this.constants_.SMALL_PADDING; - } else if (next.isExternalInput()) { + } else if (Blockly.blockRendering.Types.isExternalInput(next)) { return this.constants_.SMALL_PADDING; } } else { - if (next.isInlineInput()) { + if (Blockly.blockRendering.Types.isInlineInput(next)) { return this.constants_.MEDIUM_LARGE_PADDING; - } else if (next.isExternalInput()) { + } else if (Blockly.blockRendering.Types.isExternalInput(next)) { return this.constants_.MEDIUM_LARGE_PADDING; - } else if (next.isStatementInput()) { + } else if (Blockly.blockRendering.Types.isStatementInput(next)) { return this.constants_.LARGE_PADDING; } } @@ -167,12 +169,14 @@ Blockly.zelos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between an icon and an icon or field. - if (prev.isIcon() && !next.isInput) { + if (Blockly.blockRendering.Types.isIcon(prev) && + !Blockly.blockRendering.Types.isInput(next)) { return this.constants_.LARGE_PADDING; } // Spacing between an inline input and a field. - if (prev.isInlineInput() && !next.isInput) { + if (Blockly.blockRendering.Types.isInlineInput(prev) && + !Blockly.blockRendering.Types.isInput(next)) { // Editable field after inline input. if (next.isEditable) { return this.constants_.MEDIUM_PADDING; @@ -182,15 +186,15 @@ Blockly.zelos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } } - if (prev.isSquareCorner()) { + if (Blockly.blockRendering.Types.isLeftSquareCorner(prev) && next) { // Spacing between a hat and a corner - if (next.isHat()) { + if (Blockly.blockRendering.Types.isHat(next)) { return this.constants_.NO_PADDING; } // Spacing between a square corner and a previous or next connection - if (next.isPreviousConnection()) { + if (Blockly.blockRendering.Types.isPreviousConnection(next)) { return next.notchOffset; - } else if (next.isNextConnection()) { + } else if (Blockly.blockRendering.Types.isNextConnection(next)) { // Next connections are shifted slightly to the left (in both LTR and RTL) // to make the dark path under the previous connection show through. var offset = (this.RTL ? 1 : -1) * @@ -200,10 +204,10 @@ Blockly.zelos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between a rounded corner and a previous or next connection. - if (prev.isRoundedCorner()) { - if (next.isPreviousConnection()) { + if (Blockly.blockRendering.Types.isLeftRoundedCorner(prev) && next) { + if (Blockly.blockRendering.Types.isPreviousConnection(next)) { return next.notchOffset - this.constants_.CORNER_RADIUS; - } else if (next.isNextConnection()) { + } else if (Blockly.blockRendering.Types.isNextConnection(next)) { // Next connections are shifted slightly to the left (in both LTR and RTL) // to make the dark path under the previous connection show through. var offset = (this.RTL ? 1 : -1) * @@ -213,12 +217,14 @@ Blockly.zelos.RenderInfo.prototype.getInRowSpacing_ = function(prev, next) { } // Spacing between two fields of the same editability. - if (!prev.isInput && !next.isInput && (prev.isEditable == next.isEditable)) { + if (!Blockly.blockRendering.Types.isInput(prev) && + !Blockly.blockRendering.Types.isInput(next) && + (prev.isEditable == next.isEditable)) { return this.constants_.LARGE_PADDING; } // Spacing between anything and a jagged edge. - if (next.isJaggedEdge()) { + if (next && Blockly.blockRendering.Types.isJaggedEdge(next)) { return this.constants_.LARGE_PADDING; } @@ -238,7 +244,7 @@ Blockly.zelos.RenderInfo.prototype.addAlignmentPadding_ = function(row, var lastSpacer = row.getLastSpacer(); // Skip the right corner element on the top and bottom row, so we don't have // any spacing after the right corner element. - if (row.type == 'top row' || row.type == 'bottom row') { + if (Blockly.blockRendering.Types.isTopOrBottomRow(row)) { lastSpacer = row.elements[row.elements.length - 3]; } if (lastSpacer) { diff --git a/core/renderers/zelos/measurables/rows.js b/core/renderers/zelos/measurables/rows.js index 0680d8267..ccea80074 100644 --- a/core/renderers/zelos/measurables/rows.js +++ b/core/renderers/zelos/measurables/rows.js @@ -75,10 +75,12 @@ Blockly.zelos.TopRow.prototype.hasLeftSquareCorner = function(_block) { }; /** - * Never render a right square corner. Always round. - * @override + * Returns whether or not the top row has a right square corner. + * @param {!Blockly.BlockSvg} _block The block whose top row this represents. + * @returns {boolean} Whether or not the top row has a left square corner. */ Blockly.zelos.TopRow.prototype.hasRightSquareCorner = function(_block) { + // Never render a right square corner. Always round. return false; }; @@ -123,9 +125,11 @@ Blockly.zelos.BottomRow.prototype.hasLeftSquareCorner = function(_block) { }; /** - * Never render a right square corner. Always round. - * @override + * Returns whether or not the bottom row has a right square corner. + * @param {!Blockly.BlockSvg} _block The block whose bottom row this represents. + * @returns {boolean} Whether or not the bottom row has a left square corner. */ Blockly.zelos.BottomRow.prototype.hasRightSquareCorner = function(_block) { + // Never render a right square corner. Always round. return false; };