diff --git a/core/renderers/common/constants.js b/core/renderers/common/constants.js
index 1ec8c8fdc..bfc753f09 100644
--- a/core/renderers/common/constants.js
+++ b/core/renderers/common/constants.js
@@ -60,6 +60,12 @@ Blockly.blockRendering.ConstantProvider = function() {
this.EMPTY_BLOCK_SPACER_HEIGHT = 16;
+ /**
+ * The minimum height of a dummy input row.
+ * @type {number}
+ */
+ this.DUMMY_INPUT_MIN_HEIGHT = this.TAB_HEIGHT;
+
/**
* Rounded corner radius.
* @type {number}
diff --git a/core/renderers/common/info.js b/core/renderers/common/info.js
index f47b8c136..eed3591f1 100644
--- a/core/renderers/common/info.js
+++ b/core/renderers/common/info.js
@@ -376,8 +376,11 @@ Blockly.blockRendering.RenderInfo.prototype.addInput_ = function(input, activeRo
} else if (input.type == Blockly.DUMMY_INPUT) {
// Dummy inputs have no visual representation, but the information is still
// important.
+ activeRow.minHeight = Math.max(activeRow.minHeight,
+ this.constants_.DUMMY_INPUT_MIN_HEIGHT);
activeRow.hasDummyInput = true;
}
+ activeRow.align = input.align;
};
/**
diff --git a/core/renderers/geras/info.js b/core/renderers/geras/info.js
index 31b99e6b7..3df571bf2 100644
--- a/core/renderers/geras/info.js
+++ b/core/renderers/geras/info.js
@@ -115,8 +115,49 @@ Blockly.geras.RenderInfo.prototype.addInput_ = function(input, activeRow) {
} else if (input.type == Blockly.DUMMY_INPUT) {
// Dummy inputs have no visual representation, but the information is still
// important.
+ activeRow.minHeight = Math.max(activeRow.minHeight,
+ this.constants_.DUMMY_INPUT_MIN_HEIGHT);
activeRow.hasDummyInput = true;
}
+ activeRow.align = input.align;
+};
+
+/**
+ * @override
+ */
+Blockly.geras.RenderInfo.prototype.addElemSpacing_ = function() {
+ var hasExternalInputs = false;
+ for (var i = 0, row; (row = this.rows[i]); i++) {
+ if (row.hasExternalInput) {
+ hasExternalInputs = true;
+ }
+ }
+ for (var i = 0, row; (row = this.rows[i]); i++) {
+ var oldElems = row.elements;
+ row.elements = [];
+ // No spacing needed before the corner on the top row or the bottom row.
+ if (row.startsWithElemSpacer()) {
+ // There's a spacer before the first element in the row.
+ row.elements.push(new Blockly.blockRendering.InRowSpacer(
+ this.constants_, this.getInRowSpacing_(null, oldElems[0])));
+ }
+ for (var e = 0; e < oldElems.length - 1; e++) {
+ row.elements.push(oldElems[e]);
+ var spacing = this.getInRowSpacing_(oldElems[e], oldElems[e + 1]);
+ row.elements.push(
+ new Blockly.blockRendering.InRowSpacer(this.constants_, spacing));
+ }
+ row.elements.push(oldElems[oldElems.length - 1]);
+ if (row.endsWithElemSpacer()) {
+ var spacing = this.getInRowSpacing_(oldElems[oldElems.length - 1], null);
+ if (hasExternalInputs && row.hasDummyInput) {
+ spacing += this.constants_.TAB_WIDTH;
+ }
+ // There's a spacer after the last element in the row.
+ row.elements.push(new Blockly.blockRendering.InRowSpacer(
+ this.constants_, spacing));
+ }
+ }
};
/**
@@ -274,22 +315,19 @@ Blockly.geras.RenderInfo.prototype.addAlignmentPadding_ = function(row, missingS
row.widthWithConnectedBlocks += missingSpace;
}
- var input = row.getLastInput();
- if (input) {
- // Decide where the extra padding goes.
- if (input.align == Blockly.ALIGN_LEFT) {
- // Add padding to the end of the row.
- lastSpacer.width += missingSpace;
- } else if (input.align == Blockly.ALIGN_CENTRE) {
- // Split the padding between the beginning and end of the row.
- firstSpacer.width += missingSpace / 2;
- lastSpacer.width += missingSpace / 2;
- } else if (input.align == Blockly.ALIGN_RIGHT) {
- // Add padding at the beginning of the row.
- firstSpacer.width += missingSpace;
- }
+ // Decide where the extra padding goes.
+ if (row.align == Blockly.ALIGN_LEFT) {
+ // Add padding to the end of the row.
+ lastSpacer.width += missingSpace;
+ } else if (row.align == Blockly.ALIGN_CENTRE) {
+ // Split the padding between the beginning and end of the row.
+ firstSpacer.width += missingSpace / 2;
+ lastSpacer.width += missingSpace / 2;
+ } else if (row.align == Blockly.ALIGN_RIGHT) {
+ // Add padding at the beginning of the row.
+ firstSpacer.width += missingSpace;
} else {
- // Default to left-aligning if there's no input to say where to align.
+ // Default to left-aligning.
lastSpacer.width += missingSpace;
}
row.width += missingSpace;
@@ -321,6 +359,9 @@ Blockly.geras.RenderInfo.prototype.getSpacerRowHeight_ = function(prev, next) {
if (!prev.hasStatement && next.hasDummyInput) {
return this.constants_.LARGE_PADDING;
}
+ if (prev.hasDummyInput) {
+ return this.constants_.LARGE_PADDING;
+ }
return this.constants_.MEDIUM_PADDING;
};
diff --git a/core/renderers/thrasos/info.js b/core/renderers/thrasos/info.js
index 48ed1f9ed..b8772cbb9 100644
--- a/core/renderers/thrasos/info.js
+++ b/core/renderers/thrasos/info.js
@@ -70,6 +70,44 @@ Blockly.thrasos.RenderInfo.prototype.getRenderer = function() {
return /** @type {!Blockly.thrasos.Renderer} */ (this.renderer_);
};
+/**
+ * @override
+ */
+Blockly.thrasos.RenderInfo.prototype.addElemSpacing_ = function() {
+ var hasExternalInputs = false;
+ for (var i = 0, row; (row = this.rows[i]); i++) {
+ if (row.hasExternalInput) {
+ hasExternalInputs = true;
+ }
+ }
+ for (var i = 0, row; (row = this.rows[i]); i++) {
+ var oldElems = row.elements;
+ row.elements = [];
+ // No spacing needed before the corner on the top row or the bottom row.
+ if (row.startsWithElemSpacer()) {
+ // There's a spacer before the first element in the row.
+ row.elements.push(new Blockly.blockRendering.InRowSpacer(
+ this.constants_, this.getInRowSpacing_(null, oldElems[0])));
+ }
+ for (var e = 0; e < oldElems.length - 1; e++) {
+ row.elements.push(oldElems[e]);
+ var spacing = this.getInRowSpacing_(oldElems[e], oldElems[e + 1]);
+ row.elements.push(
+ new Blockly.blockRendering.InRowSpacer(this.constants_, spacing));
+ }
+ row.elements.push(oldElems[oldElems.length - 1]);
+ if (row.endsWithElemSpacer()) {
+ var spacing = this.getInRowSpacing_(oldElems[oldElems.length - 1], null);
+ if (hasExternalInputs && row.hasDummyInput) {
+ spacing += this.constants_.TAB_WIDTH;
+ }
+ // There's a spacer after the last element in the row.
+ row.elements.push(new Blockly.blockRendering.InRowSpacer(
+ this.constants_, spacing));
+ }
+ }
+};
+
/**
* @override
*/
@@ -211,23 +249,20 @@ Blockly.thrasos.RenderInfo.prototype.addAlignmentPadding_ = function(row, missin
if (row.hasExternalInput || row.hasStatement) {
row.widthWithConnectedBlocks += missingSpace;
}
-
- var input = row.getLastInput();
- if (input) {
- // Decide where the extra padding goes.
- if (input.align == Blockly.ALIGN_LEFT) {
- // Add padding to the end of the row.
- lastSpacer.width += missingSpace;
- } else if (input.align == Blockly.ALIGN_CENTRE) {
- // Split the padding between the beginning and end of the row.
- firstSpacer.width += missingSpace / 2;
- lastSpacer.width += missingSpace / 2;
- } else if (input.align == Blockly.ALIGN_RIGHT) {
- // Add padding at the beginning of the row.
- firstSpacer.width += missingSpace;
- }
+
+ // Decide where the extra padding goes.
+ if (row.align == Blockly.ALIGN_LEFT) {
+ // Add padding to the end of the row.
+ lastSpacer.width += missingSpace;
+ } else if (row.align == Blockly.ALIGN_CENTRE) {
+ // Split the padding between the beginning and end of the row.
+ firstSpacer.width += missingSpace / 2;
+ lastSpacer.width += missingSpace / 2;
+ } else if (row.align == Blockly.ALIGN_RIGHT) {
+ // Add padding at the beginning of the row.
+ firstSpacer.width += missingSpace;
} else {
- // Default to left-aligning if there's no input to say where to align.
+ // Default to left-aligning.
lastSpacer.width += missingSpace;
}
row.width += missingSpace;
@@ -257,7 +292,7 @@ Blockly.thrasos.RenderInfo.prototype.getSpacerRowHeight_ = function(
if (prev.hasStatement && next.hasStatement) {
return this.constants_.LARGE_PADDING;
}
- if (next.hasDummyInput) {
+ if (prev.hasDummyInput || next.hasDummyInput) {
return this.constants_.LARGE_PADDING;
}
return this.constants_.MEDIUM_PADDING;
diff --git a/tests/blocks/test_blocks.js b/tests/blocks/test_blocks.js
index 537adb0f5..6f9e0af33 100644
--- a/tests/blocks/test_blocks.js
+++ b/tests/blocks/test_blocks.js
@@ -31,6 +31,29 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
"nextStatement": null,
"style": "math_blocks"
},
+ {
+ "type": "test_basic_dummy",
+ "message0": "dummy input %1",
+ "args0": [
+ {
+ "type": "input_dummy"
+ }
+ ],
+ "style": "math_blocks"
+ },
+ {
+ "type": "test_basic_multiple_dummy",
+ "message0": "first dummy %1 second dummy %2",
+ "args0": [
+ {
+ "type": "input_dummy"
+ },
+ {
+ "type": "input_dummy"
+ }
+ ],
+ "style": "math_blocks"
+ },
{
"type": "test_basic_row",
"message0": "row block %1",
@@ -124,6 +147,64 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
"colour": 200,
"tooltip": "Hello world."
},
+ {
+ "type": "test_align_dummy_right",
+ "message0": "text %1 long text %2",
+ "args0": [
+ {
+ "type": "input_dummy",
+ "align": "RIGHT",
+ },
+ {
+ "type": "input_dummy",
+ "align": "RIGHT",
+ },
+ ],
+ "style": "math_blocks"
+ },
+ {
+ "type": "test_align_all",
+ "message0": "text %1 long text %2 text %3 much longer text",
+ "args0": [
+ {
+ "type": "input_dummy",
+ "align": "LEFT",
+ },
+ {
+ "type": "input_dummy",
+ "align": "CENTRE",
+ },
+ {
+ "type": "input_dummy",
+ "align": "RIGHT",
+ },
+ ],
+ "style": "math_blocks"
+ },
+ {
+ "type": "test_align_with_external_input",
+ "message0": "text %1 long text %2 text %3 much longer text %4",
+ "args0": [
+ {
+ "type": "input_dummy",
+ "align": "RIGHT",
+ },
+ {
+ "type": "input_dummy",
+ "align": "CENTRE",
+ },
+ {
+ "type": "input_dummy",
+ "align": "LEFT",
+ },
+ {
+ "type": "input_value",
+ "name": "VALUE"
+ },
+ ],
+ "inputsInline": false,
+ "style": "math_blocks"
+ },
{
"type": "test_dropdowns_long",
"message0": "long: %1",
diff --git a/tests/playground.html b/tests/playground.html
index d9969cc1b..742b5858f 100644
--- a/tests/playground.html
+++ b/tests/playground.html
@@ -1359,6 +1359,8 @@ var spaghettiXml = [
+
+
@@ -1367,6 +1369,11 @@ var spaghettiXml = [
+
+
+
+
+