Updating logic to handle rendering collapsed blocks.

This commit is contained in:
kozbial
2019-07-31 13:55:19 -07:00
parent 9cc0cb6881
commit b1d86a57aa
6 changed files with 134 additions and 13 deletions

View File

@@ -60,6 +60,7 @@ Blockly.blockRendering.Drawer = function(block, info) {
* @private
*/
Blockly.blockRendering.Drawer.prototype.draw_ = function() {
this.hideHiddenIcons_();
this.drawOutline_();
this.drawInternals_();
this.block_.setPaths_(this.pathObject_);
@@ -83,6 +84,17 @@ Blockly.blockRendering.Drawer.prototype.recordSizeOnBlock_ = function() {
this.block_.startHat_ = this.info_.topRow.startHat;
};
/**
* Hide icons that were marked as hidden.
* @private
*/
Blockly.blockRendering.Drawer.prototype.hideHiddenIcons_ = function() {
for (var i = 0; i < this.info_.hiddenIcons.length; i++) {
var iconInfo = this.info_.hiddenIcons[i];
iconInfo.icon.iconGroup_.setAttribute('display', 'none');
}
};
/**
* Create the outline of the block. This is a single continuous path.
* @private
@@ -91,7 +103,9 @@ Blockly.blockRendering.Drawer.prototype.drawOutline_ = function() {
this.drawTop_();
for (var r = 1; r < this.info_.rows.length - 1; r++) {
var row = this.info_.rows[r];
if (row.hasStatement) {
if (!row.isSpacer() && this.info_.isCollapsed) {
this.drawJaggedEdge_(row)
} else if (row.hasStatement) {
this.drawStatementInput_(row);
} else if (row.hasExternalInput) {
this.drawValueInput_(row);
@@ -136,6 +150,18 @@ Blockly.blockRendering.Drawer.prototype.drawTop_ = function() {
this.steps_.push('v', topRow.height);
};
/**
* Add steps for the jagged edge of a row on a collapsed block.
* @param {!Blockly.blockRendering.Row} row The row to draw the side of.
* @private
*/
Blockly.blockRendering.Drawer.prototype.drawJaggedEdge_ = function(row) {
this.highlighter_.drawJaggedEdge_(row);
this.steps_.push(Blockly.blockRendering.constants.JAGGED_TEETH);
var remainder = row.height - Blockly.blockRendering.constants.JAGGED_TEETH_HEIGHT;
this.steps_.push('v', remainder);
console.log('remainder: ' + remainder);
};
/**
* Add steps for an external value input, rendered as a notch in the side

View File

@@ -91,6 +91,20 @@ Blockly.blockRendering.Highlighter.prototype.drawTopCorner = function(row) {
this.steps_.push('H', row.width - this.highlightOffset_);
};
Blockly.blockRendering.Highlighter.prototype.drawJaggedEdge_ = function(row) {
if (this.info_.RTL) {
var remainder =
row.height - Blockly.blockRendering.constants.JAGGED_TEETH_HEIGHT - this.highlightOffset_;
this.steps_.push('H', row.width - this.highlightOffset_);
var steps =
Blockly.utils.svgPaths.lineTo(5.1, 2.6) +
Blockly.utils.svgPaths.moveBy(-10.2, 6.8) +
Blockly.utils.svgPaths.lineTo(5.1, 2.6) +
Blockly.utils.svgPaths.lineOnAxis('v', remainder);
this.steps_.push(steps);
}
};
Blockly.blockRendering.Highlighter.prototype.drawValueInput = function(row) {
var input = row.getLastInput();
var steps = '';

View File

@@ -59,6 +59,12 @@ Blockly.blockRendering.RenderInfo = function(block) {
*/
this.isInline = block.getInputsInline() && !block.isCollapsed();
/**
* Whether the block is collapsed.
* @type {boolean}
*/
this.isCollapsed = block.isCollapsed();
/**
* Whether the block is an insertion marker. Insertion markers are the same
* shape as normal blocks, but don't show fields.
@@ -103,6 +109,12 @@ Blockly.blockRendering.RenderInfo = function(block) {
*/
this.rows = [];
/**
* An array of measureable objects containing hidden icons.
* @type {Array}
*/
this.hiddenIcons = [];
this.topRow = null;
this.bottomRow = null;
@@ -145,16 +157,25 @@ Blockly.blockRendering.RenderInfo.prototype.createRows_ = function() {
var icons = this.block_.getIcons();
if (icons.length) {
for (var i = 0; i < icons.length; i++) {
activeRow.elements.push(
new Blockly.blockRendering.Icon(icons[i]));
var icon = icons[i];
var iconInfo = new Blockly.blockRendering.Icon(icon);
if (this.isCollapsed && icon.collapseHidden) {
this.hiddenIcons.push(iconInfo);
} else {
activeRow.elements.push(iconInfo);
}
}
}
var lastInput = undefined;
// Loop across all of the inputs on the block, creating objects for anything
// that needs to be rendered and breaking the block up into visual rows.
for (var i = 0; i < this.block_.inputList.length; i++) {
var input = this.block_.inputList[i];
if (this.shouldStartNewRow_(input, this.block_.inputList[i - 1])) {
if (!input.isVisible()) {
continue;
}
if (this.shouldStartNewRow_(input, lastInput)) {
// Finish this row and create a new one.
this.rows.push(activeRow);
activeRow = new Blockly.blockRendering.Row();
@@ -166,6 +187,11 @@ Blockly.blockRendering.RenderInfo.prototype.createRows_ = function() {
activeRow.elements.push(new Blockly.blockRendering.Field(field, input));
}
this.addInput_(input, activeRow);
lastInput = input;
}
if (this.isCollapsed) {
activeRow.elements.push(new Blockly.blockRendering.JaggedEdge());
}
if (activeRow.elements.length) {
@@ -285,7 +311,6 @@ Blockly.blockRendering.RenderInfo.prototype.addElemSpacing_ = function() {
row.elements.push(new Blockly.blockRendering.InRowSpacer(
this.getInRowSpacing_(null, oldElems[0])));
}
for (var e = 0; e < oldElems.length; e++) {
row.elements.push(oldElems[e]);
var spacing = this.getInRowSpacing_(oldElems[e], oldElems[e + 1]);
@@ -321,7 +346,7 @@ Blockly.blockRendering.RenderInfo.prototype.getInRowSpacing_ = function(prev, ne
return Blockly.blockRendering.constants.LARGE_PADDING;
}
// Spacing between a field or icon and the end of the row.
// Spacing between a non-input and the end of the row.
if (!prev.isInput && !next) {
// Between an editable field and the end of the row.
if (prev.isField() && prev.isEditable) {
@@ -342,6 +367,10 @@ Blockly.blockRendering.RenderInfo.prototype.getInRowSpacing_ = function(prev, ne
if (prev.isRoundedCorner()) {
return Blockly.blockRendering.constants.MIN_BLOCK_WIDTH;
}
// Between a jagged edge and the end of the row.
if (prev.isJaggedEdge()) {
return Blockly.blockRendering.constants.NO_PADDING;
}
// Between noneditable fields and icons and the end of the row.
return Blockly.blockRendering.constants.LARGE_PADDING;
}
@@ -357,7 +386,7 @@ Blockly.blockRendering.RenderInfo.prototype.getInRowSpacing_ = function(prev, ne
}
}
// Spacing between a field or icon and an input.
// Spacing between a non-input and an input.
if (!prev.isInput && next.isInput) {
// Between an editable field and an input.
if (prev.isEditable) {
@@ -411,7 +440,7 @@ Blockly.blockRendering.RenderInfo.prototype.getInRowSpacing_ = function(prev, ne
}
}
// Spacing between a rounded corner and a previous or next connection
// Spacing between a rounded corner and a previous or next connection.
if (prev.isRoundedCorner()){
if (next.isPreviousConnection()) {
return Blockly.blockRendering.constants.NOTCH_OFFSET_ROUNDED_CORNER_PREV;
@@ -429,6 +458,10 @@ Blockly.blockRendering.RenderInfo.prototype.getInRowSpacing_ = function(prev, ne
return Blockly.blockRendering.constants.LARGE_PADDING;
}
if (next.isJaggedEdge()) {
return Blockly.blockRendering.constants.LARGE_PADDING;
}
return Blockly.blockRendering.constants.MEDIUM_PADDING;
};

View File

@@ -141,6 +141,28 @@ Blockly.blockRendering.constants.START_POINT = Blockly.utils.svgPaths.moveBy(0,
Blockly.blockRendering.constants.TOP_LEFT_CORNER_START =
'm 0,' + Blockly.blockRendering.constants.CORNER_RADIUS;
/**
* SVG path for drawing jagged teeth at the end of collapsed blocks.
* @const
*/
Blockly.blockRendering.constants.JAGGED_TEETH = Blockly.utils.svgPaths.line(
[
Blockly.utils.svgPaths.point(6, 3),
Blockly.utils.svgPaths.point(-12, 6),
Blockly.utils.svgPaths.point(6, 3)
]);
/**
* Height of SVG path for jagged teeth at the end of collapsed blocks.
* @const
*/
Blockly.blockRendering.constants.JAGGED_TEETH_HEIGHT = 12;
/**
* Width of SVG path for jagged teeth at the end of collapsed blocks.
* @const
*/
Blockly.blockRendering.constants.JAGGED_TEETH_WIDTH = 6;
/**
* Information about the hat on a start block.
*/

View File

@@ -140,7 +140,6 @@ Blockly.blockRendering.highlightConstants.OUTSIDE_CORNER = (function() {
};
})();
Blockly.blockRendering.highlightConstants.PUZZLE_TAB = (function() {
var width = Blockly.blockRendering.constants.TAB_WIDTH;
var height = Blockly.blockRendering.constants.TAB_HEIGHT;

View File

@@ -127,6 +127,16 @@ Blockly.blockRendering.Measurable.prototype.isRoundedCorner = function() {
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';
};
/**
* The base class to represent an input that takes up space on a block
* during rendering
@@ -178,6 +188,21 @@ Blockly.blockRendering.Icon = function(icon) {
};
goog.inherits(Blockly.blockRendering.Icon, Blockly.blockRendering.Measurable);
/**
* An object containing information about the jagged edge of a collapsed block
* takes up during rendering
* @package
* @constructor
*/
Blockly.blockRendering.JaggedEdge = function() {
Blockly.blockRendering.JaggedEdge.superClass_.constructor.call(this);
this.type = 'jagged edge';
this.height = Blockly.blockRendering.constants.JAGGED_TEETH_HEIGHT;
this.width = Blockly.blockRendering.constants.JAGGED_TEETH_WIDTH;
};
goog.inherits(Blockly.blockRendering.JaggedEdge, Blockly.blockRendering.Measurable);
/**
* An object containing information about the space a field takes up during
* rendering
@@ -409,9 +434,11 @@ Blockly.blockRendering.Row.prototype.measure = function() {
};
Blockly.blockRendering.Row.prototype.getLastInput = function() {
// There's always a spacer after the last input, unless there are no inputs.
if (this.elements.length > 1) {
var elem = this.elements[this.elements.length - 2];
for (var i = this.elements.length - 1; i >= 0; i--) {
var elem = this.elements[i];
if (elem.isSpacer()) {
continue;
}
if (elem.isInput) {
return elem;
} else if (elem.isField()) {
@@ -468,7 +495,7 @@ Blockly.blockRendering.TopRow = function(block) {
// This is the minimum height for the row. If one of its elements has a greater
// height it will be overwritten in the compute pass.
if (precedesStatement) {
if (precedesStatement && !block.isCollapsed()) {
this.height = Blockly.blockRendering.constants.LARGE_PADDING;
} else {
this.height = Blockly.blockRendering.constants.MEDIUM_PADDING;