mirror of
https://github.com/google/blockly.git
synced 2026-01-26 10:10:08 +01:00
Zelos horizontal tight nesting. (#3490)
* Reduce the amount of implicit spacing added by the connection shape by adding negative spacing to the first and last spacer in an output block
This commit is contained in:
@@ -430,13 +430,21 @@ Blockly.blockRendering.ConstantProvider = function() {
|
||||
*/
|
||||
this.CURSOR_STROKE_WIDTH = 4;
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Whether text input and colour fields fill up the entire source block.
|
||||
* @type {boolean}
|
||||
* @package
|
||||
*/
|
||||
this.FULL_BLOCK_FIELDS = false;
|
||||
|
||||
/**
|
||||
* Enum for connection shapes.
|
||||
* @enum {number}
|
||||
*/
|
||||
this.SHAPES = {
|
||||
PUZZLE: 1,
|
||||
NOTCH: 2
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -717,6 +725,7 @@ Blockly.blockRendering.ConstantProvider.prototype.makePuzzleTab = function() {
|
||||
var pathDown = makeMainPath(false);
|
||||
|
||||
return {
|
||||
type: this.SHAPES.PUZZLE,
|
||||
width: width,
|
||||
height: height,
|
||||
pathDown: pathDown,
|
||||
@@ -746,6 +755,7 @@ Blockly.blockRendering.ConstantProvider.prototype.makeNotch = function() {
|
||||
var pathRight = makeMainPath(-1);
|
||||
|
||||
return {
|
||||
type: this.SHAPES.NOTCH,
|
||||
width: width,
|
||||
height: height,
|
||||
pathLeft: pathLeft,
|
||||
|
||||
@@ -121,6 +121,11 @@ Blockly.blockRendering.Debug.prototype.drawSpacerElem = function(elem, rowHeight
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't render elements with negative spacing.
|
||||
if (elem.width < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var xPos = elem.xPos;
|
||||
if (isRtl) {
|
||||
xPos = -(xPos + elem.width);
|
||||
|
||||
@@ -159,6 +159,47 @@ Blockly.zelos.ConstantProvider = function() {
|
||||
*/
|
||||
this.CURSOR_RADIUS = 5;
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
* @override
|
||||
*/
|
||||
this.SHAPES = {
|
||||
HEXAGONAL: 1,
|
||||
ROUND: 2,
|
||||
SQUARE: 3,
|
||||
PUZZLE: 4,
|
||||
NOTCH: 5
|
||||
};
|
||||
|
||||
/**
|
||||
* Map of output/input shapes and the amount they should cause a block to be
|
||||
* padded. Outer key is the outer shape, inner key is the inner shape.
|
||||
* When a block with the outer shape contains an input block with the inner
|
||||
* shape on its left or right edge, the block elements are aligned such that
|
||||
* the padding specified is reached.
|
||||
* @package
|
||||
*/
|
||||
this.SHAPE_IN_SHAPE_PADDING = {
|
||||
1: { // Outer shape: hexagon.
|
||||
0: 5 * this.GRID_UNIT, // Field in hexagon.
|
||||
1: 2 * this.GRID_UNIT, // Hexagon in hexagon.
|
||||
2: 5 * this.GRID_UNIT, // Round in hexagon.
|
||||
3: 5 * this.GRID_UNIT // Square in hexagon.
|
||||
},
|
||||
2: { // Outer shape: round.
|
||||
0: 3 * this.GRID_UNIT, // Field in round.
|
||||
1: 3 * this.GRID_UNIT, // Hexagon in round.
|
||||
2: 1 * this.GRID_UNIT, // Round in round.
|
||||
3: 2 * this.GRID_UNIT // Square in round.
|
||||
},
|
||||
3: { // Outer shape: square.
|
||||
0: 2 * this.GRID_UNIT, // Field in square.
|
||||
1: 2 * this.GRID_UNIT, // Hexagon in square.
|
||||
2: 2 * this.GRID_UNIT, // Round in square.
|
||||
3: 2 * this.GRID_UNIT // Square in square.
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -348,6 +389,7 @@ Blockly.zelos.ConstantProvider.prototype.makeHexagonal = function() {
|
||||
}
|
||||
|
||||
return {
|
||||
type: this.SHAPES.HEXAGONAL,
|
||||
isDynamic: true,
|
||||
width: function(height) {
|
||||
return height / 2;
|
||||
@@ -386,6 +428,7 @@ Blockly.zelos.ConstantProvider.prototype.makeRounded = function() {
|
||||
}
|
||||
|
||||
return {
|
||||
type: this.SHAPES.ROUND,
|
||||
isDynamic: true,
|
||||
width: function(height) {
|
||||
return height / 2;
|
||||
@@ -499,6 +542,7 @@ Blockly.zelos.ConstantProvider.prototype.makeNotch = function() {
|
||||
var pathRight = makeMainPath(-1);
|
||||
|
||||
return {
|
||||
type: this.SHAPES.NOTCH,
|
||||
width: width,
|
||||
height: height,
|
||||
pathLeft: pathLeft,
|
||||
|
||||
@@ -67,6 +67,11 @@ Blockly.zelos.Drawer.prototype.draw = function() {
|
||||
this.block_.renderingDebugger.drawDebug(this.block_, this.info_);
|
||||
}
|
||||
this.recordSizeOnBlock_();
|
||||
if (this.info_.outputConnection) {
|
||||
// Store the output connection shape type for parent blocks to use during
|
||||
// rendering.
|
||||
pathObject.outputShapeType = this.info_.outputConnection.shape.type;
|
||||
}
|
||||
pathObject.endDrawing();
|
||||
};
|
||||
|
||||
|
||||
@@ -253,39 +253,130 @@ Blockly.zelos.RenderInfo.prototype.adjustXPosition_ = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalize the output connection info. In particular set the height of the
|
||||
* Finalize the output connection info. In particular, set the height of the
|
||||
* output connection to match that of the block. For the right side, add a
|
||||
* right connection shape element and have it match the dimensions of the
|
||||
* output connection.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.zelos.RenderInfo.prototype.finalizeOutputConnection_ = function() {
|
||||
// Dynamic output connections depend on the height of the block.
|
||||
if (!this.outputConnection || !this.outputConnection.isDynamicShape) {
|
||||
return;
|
||||
}
|
||||
var yCursor = 0;
|
||||
// Determine the block height.
|
||||
for (var i = 0, row; (row = this.rows[i]); i++) {
|
||||
row.yPos = yCursor;
|
||||
yCursor += row.height;
|
||||
}
|
||||
if (this.outputConnection && this.outputConnection.isDynamicShape) {
|
||||
// Dynamic output connections depend on the height of the block. Adjust the
|
||||
// height of the connection.
|
||||
var connectionHeight = this.outputConnection.shape.height(yCursor);
|
||||
var connectionWidth = this.outputConnection.shape.width(yCursor);
|
||||
|
||||
this.outputConnection.height = connectionHeight;
|
||||
this.outputConnection.width = connectionWidth;
|
||||
this.outputConnection.startX = connectionWidth;
|
||||
// Adjust the height of the output connection.
|
||||
var connectionHeight = this.outputConnection.shape.height(yCursor);
|
||||
var connectionWidth = this.outputConnection.shape.width(yCursor);
|
||||
|
||||
// Adjust right side measurable.
|
||||
this.rightSide.height = connectionHeight;
|
||||
this.rightSide.width = connectionWidth;
|
||||
this.rightSide.centerline = connectionHeight / 2;
|
||||
this.rightSide.xPos = this.width + connectionWidth;
|
||||
this.outputConnection.height = connectionHeight;
|
||||
this.outputConnection.width = connectionWidth;
|
||||
this.outputConnection.startX = connectionWidth;
|
||||
|
||||
this.startX = connectionWidth;
|
||||
this.width += connectionWidth * 2;
|
||||
this.widthWithChildren += connectionWidth * 2;
|
||||
// Adjust right side measurable.
|
||||
this.rightSide.height = connectionHeight;
|
||||
this.rightSide.width = connectionWidth;
|
||||
this.rightSide.centerline = connectionHeight / 2;
|
||||
this.rightSide.xPos = this.width + connectionWidth;
|
||||
|
||||
this.startX = connectionWidth;
|
||||
this.width += connectionWidth * 2;
|
||||
this.widthWithChildren += connectionWidth * 2;
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalize alignment of elements on the block. In particular, reduce the
|
||||
* implicit spacing created by the left and right output connection shapes by
|
||||
* adding setting negative spacing onto the leftmost and rightmost spacers.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.zelos.RenderInfo.prototype.finalizeAlignment_ = function() {
|
||||
if (!this.outputConnection) {
|
||||
return;
|
||||
}
|
||||
var totalNegativeSpacing = 0;
|
||||
for (var i = 0, row; (row = this.rows[i]); i++) {
|
||||
if (!Blockly.blockRendering.Types.isInputRow(row)) {
|
||||
continue;
|
||||
}
|
||||
var firstElem = row.elements[1];
|
||||
var lastElem = row.elements[row.elements.length - 2];
|
||||
var leftNegPadding = this.getNegativeSpacing_(firstElem);
|
||||
var rightNegPadding = this.getNegativeSpacing_(lastElem);
|
||||
totalNegativeSpacing = leftNegPadding + rightNegPadding;
|
||||
var minBlockWidth = this.constants_.MIN_BLOCK_WIDTH +
|
||||
this.outputConnection.width * 2;
|
||||
if (this.width - totalNegativeSpacing < minBlockWidth) {
|
||||
// Maintain a minimum block width, split negative spacing between left
|
||||
// and right edge.
|
||||
totalNegativeSpacing = this.width - minBlockWidth;
|
||||
row.getFirstSpacer().width = -totalNegativeSpacing / 2;
|
||||
row.getLastSpacer().width = -totalNegativeSpacing / 2;
|
||||
} else {
|
||||
row.getFirstSpacer().width = -leftNegPadding;
|
||||
row.getLastSpacer().width = -rightNegPadding;
|
||||
}
|
||||
}
|
||||
if (totalNegativeSpacing) {
|
||||
this.width -= totalNegativeSpacing;
|
||||
this.widthWithChildren -= totalNegativeSpacing;
|
||||
this.rightSide.xPos -= totalNegativeSpacing;
|
||||
for (var i = 0, row; (row = this.rows[i]); i++) {
|
||||
if (Blockly.blockRendering.Types.isTopRow(row) ||
|
||||
Blockly.blockRendering.Types.isBottomRow(row)) {
|
||||
row.elements[1].width -= totalNegativeSpacing;
|
||||
}
|
||||
row.width -= totalNegativeSpacing;
|
||||
row.widthWithConnectedBlocks -= totalNegativeSpacing;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the spacing to reduce the left and right edges by based on the
|
||||
* outer and inner connection shape.
|
||||
* @param {Blockly.blockRendering.Measurable} elem The first or last element on
|
||||
* a block.
|
||||
* @return {number} The amount of spacing to reduce the first or last spacer.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.zelos.RenderInfo.prototype.getNegativeSpacing_ = function(elem) {
|
||||
if (!elem) {
|
||||
return 0;
|
||||
}
|
||||
var connectionWidth = this.outputConnection.width;
|
||||
var outerShape = this.outputConnection.shape.type;
|
||||
var constants =
|
||||
/** @type {!Blockly.zelos.ConstantProvider} */ (this.constants_);
|
||||
if (Blockly.blockRendering.Types.isInlineInput(elem)) {
|
||||
var innerShape = elem.connectedBlock ?
|
||||
elem.connectedBlock.pathObject.outputShapeType :
|
||||
elem.shape.type;
|
||||
// Special case for hexagonal output.
|
||||
if (outerShape == constants.SHAPES.HEXAGONAL &&
|
||||
outerShape != innerShape) {
|
||||
return 0;
|
||||
}
|
||||
return connectionWidth -
|
||||
this.constants_.SHAPE_IN_SHAPE_PADDING[outerShape][innerShape];
|
||||
} else if (Blockly.blockRendering.Types.isField(elem)) {
|
||||
// Special case for text inputs.
|
||||
if (outerShape == constants.SHAPES.ROUND &&
|
||||
elem.field instanceof Blockly.FieldTextInput) {
|
||||
return connectionWidth - (2.75 * constants.GRID_UNIT);
|
||||
}
|
||||
return connectionWidth -
|
||||
this.constants_.SHAPE_IN_SHAPE_PADDING[outerShape][0];
|
||||
} else if (Blockly.blockRendering.Types.isIcon(elem)) {
|
||||
return this.constants_.SMALL_PADDING;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -293,5 +384,6 @@ Blockly.zelos.RenderInfo.prototype.finalizeOutputConnection_ = function() {
|
||||
*/
|
||||
Blockly.zelos.RenderInfo.prototype.finalize_ = function() {
|
||||
this.finalizeOutputConnection_();
|
||||
this.finalizeAlignment_();
|
||||
Blockly.zelos.RenderInfo.superClass_.finalize_.call(this);
|
||||
};
|
||||
|
||||
@@ -74,6 +74,13 @@ Blockly.zelos.PathObject = function(root, style, constants) {
|
||||
* @private
|
||||
*/
|
||||
this.remainingOutlines_ = null;
|
||||
|
||||
/**
|
||||
* The type of block's output connection shape. This is set when a block with
|
||||
* an output connection is drawn.
|
||||
* @package
|
||||
*/
|
||||
this.outputShapeType = null;
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.zelos.PathObject,
|
||||
Blockly.blockRendering.PathObject);
|
||||
|
||||
Reference in New Issue
Block a user