mirror of
https://github.com/google/blockly.git
synced 2026-01-10 10:27:08 +01:00
Create WorkspaceViewport class (#1291)
* Create WorkspaceViewport class * Update comments * Move workspace viewport functions back to the workspace for now * whitespace
This commit is contained in:
@@ -1415,6 +1415,7 @@ Blockly.WorkspaceSvg.prototype.zoom = function(x, y, amount) {
|
||||
.translate(x * (1 - scaleChange), y * (1 - scaleChange))
|
||||
.scale(scaleChange);
|
||||
// newScale and matrix.a should be identical (within a rounding error).
|
||||
// ScrollX and scrollY are in pixels.
|
||||
this.scrollX = matrix.e - metrics.absoluteLeft;
|
||||
this.scrollY = matrix.f - metrics.absoluteTop;
|
||||
}
|
||||
@@ -1504,6 +1505,118 @@ Blockly.WorkspaceSvg.prototype.setScale = function(newScale) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the dimensions of the given workspace component, in pixels.
|
||||
* @param {Blockly.Toolbox|Blockly.Flyout} elem The element to get the
|
||||
* dimensions of, or null. It should be a toolbox or flyout, and should
|
||||
* implement getWidth() and getHeight().
|
||||
* @return {!Object} An object containing width and height attributes, which
|
||||
* will both be zero if elem did not exist.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceSvg.getDimensionsPx_ = function(elem) {
|
||||
var width = 0;
|
||||
var height = 0;
|
||||
if (elem) {
|
||||
width = elem.getWidth();
|
||||
height = elem.getHeight();
|
||||
}
|
||||
return {
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the content dimensions of the given workspace, taking into account
|
||||
* whether or not it is scrollable and what size the workspace div is on screen.
|
||||
* @param {!Blockly.WorkspaceSvg} ws The workspace to measure.
|
||||
* @param {!Object} svgSize An object containing height and width attributes in
|
||||
* CSS pixels. Together they specify the size of the visible workspace, not
|
||||
* including areas covered up by the toolbox.
|
||||
* @return {!Object} The dimensions of the contents of the given workspace, as
|
||||
* an object containing at least
|
||||
* - height and width in pixels
|
||||
* - left and top in pixels relative to the workspace origin.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceSvg.getContentDimensions_ = function(ws, svgSize) {
|
||||
if (ws.scrollbar) {
|
||||
return Blockly.WorkspaceSvg.getContentDimensionsBounded_(ws, svgSize);
|
||||
} else {
|
||||
return Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the bounding box for all workspace contents, in pixels.
|
||||
* @param {!Blockly.WorkspaceSvg} ws The workspace to inspect.
|
||||
* @return {!Object} The dimensions of the contents of the given workspace, as
|
||||
* an object containing
|
||||
* - height and width in pixels
|
||||
* - left, right, top and bottom in pixels relative to the workspace origin.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceSvg.getContentDimensionsExact_ = function(ws) {
|
||||
// Block bounding box is in workspace coordinates.
|
||||
var blockBox = ws.getBlocksBoundingBox();
|
||||
var scale = ws.scale;
|
||||
|
||||
// Convert to pixels.
|
||||
var width = blockBox.width * scale;
|
||||
var height = blockBox.height * scale;
|
||||
var left = blockBox.x * scale;
|
||||
var top = blockBox.y * scale;
|
||||
|
||||
return {
|
||||
left: left,
|
||||
top: top,
|
||||
right: left + width,
|
||||
bottom: top + height,
|
||||
width: width,
|
||||
height: height
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the size of a scrollable workspace, which should include room for a
|
||||
* half screen border around the workspace contents.
|
||||
* @param {!Blockly.WorkspaceSvg} ws The workspace to measure.
|
||||
* @param {!Object} svgSize An object containing height and width attributes in
|
||||
* CSS pixels. Together they specify the size of the visible workspace, not
|
||||
* including areas covered up by the toolbox.
|
||||
* @return {!Object} The dimensions of the contents of the given workspace, as
|
||||
* an object containing
|
||||
* - height and width in pixels
|
||||
* - left and top in pixels relative to the workspace origin.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceSvg.getContentDimensionsBounded_ = function(ws, svgSize) {
|
||||
var content = Blockly.WorkspaceSvg.getContentDimensionsExact_(ws);
|
||||
|
||||
// View height and width are both in pixels, and are the same as the svg size.
|
||||
var viewWidth = svgSize.width;
|
||||
var viewHeight = svgSize.height;
|
||||
var halfWidth = viewWidth / 2;
|
||||
var halfHeight = viewHeight / 2;
|
||||
|
||||
// Add a border around the content that is at least half a screenful wide.
|
||||
// Ensure border is wide enough that blocks can scroll over entire screen.
|
||||
var left = Math.min(content.left - halfWidth, content.right - viewWidth);
|
||||
var right = Math.max(content.right + halfWidth, content.left + viewWidth);
|
||||
|
||||
var top = Math.min(content.top - halfHeight, content.bottom - viewHeight);
|
||||
var bottom = Math.max(content.bottom + halfHeight, content.top + viewHeight);
|
||||
|
||||
var dimensions = {
|
||||
left: left,
|
||||
top: top,
|
||||
height: bottom - top,
|
||||
width: right - left
|
||||
};
|
||||
return dimensions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return an object with all the metrics required to size scrollbars for a
|
||||
* top level workspace. The following properties are computed:
|
||||
@@ -1529,70 +1642,59 @@ Blockly.WorkspaceSvg.prototype.setScale = function(newScale) {
|
||||
* @this Blockly.WorkspaceSvg
|
||||
*/
|
||||
Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_ = function() {
|
||||
|
||||
var toolboxDimensions =
|
||||
Blockly.WorkspaceSvg.getDimensionsPx_(this.toolbox_);
|
||||
var flyoutDimensions =
|
||||
Blockly.WorkspaceSvg.getDimensionsPx_(this.flyout_);
|
||||
|
||||
// Contains height and width in CSS pixels.
|
||||
// svgSize is equivalent to the size of the injectionDiv at this point.
|
||||
var svgSize = Blockly.svgSize(this.getParentSvg());
|
||||
if (this.toolbox_) {
|
||||
if (this.toolboxPosition == Blockly.TOOLBOX_AT_TOP ||
|
||||
this.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) {
|
||||
svgSize.height -= this.toolbox_.getHeight();
|
||||
svgSize.height -= toolboxDimensions.height;
|
||||
} else if (this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT ||
|
||||
this.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) {
|
||||
svgSize.width -= this.toolbox_.getWidth();
|
||||
svgSize.width -= toolboxDimensions.width;
|
||||
}
|
||||
}
|
||||
// Set the margin to match the flyout's margin so that the workspace does
|
||||
// not jump as blocks are added.
|
||||
var MARGIN = Blockly.Flyout.prototype.CORNER_RADIUS - 1;
|
||||
var viewWidth = svgSize.width - MARGIN;
|
||||
var viewHeight = svgSize.height - MARGIN;
|
||||
|
||||
var blockBox = this.getBlocksBoundingBox();
|
||||
// svgSize is now the space taken up by the Blockly workspace, not including
|
||||
// the toolbox.
|
||||
var contentDimensions =
|
||||
Blockly.WorkspaceSvg.getContentDimensions_(this, svgSize);
|
||||
|
||||
// Fix scale.
|
||||
var contentWidth = blockBox.width * this.scale;
|
||||
var contentHeight = blockBox.height * this.scale;
|
||||
var contentX = blockBox.x * this.scale;
|
||||
var contentY = blockBox.y * this.scale;
|
||||
if (this.scrollbar) {
|
||||
// Add a border around the content that is at least half a screenful wide.
|
||||
// Ensure border is wide enough that blocks can scroll over entire screen.
|
||||
var leftEdge = Math.min(contentX - viewWidth / 2,
|
||||
contentX + contentWidth - viewWidth);
|
||||
var rightEdge = Math.max(contentX + contentWidth + viewWidth / 2,
|
||||
contentX + viewWidth);
|
||||
var topEdge = Math.min(contentY - viewHeight / 2,
|
||||
contentY + contentHeight - viewHeight);
|
||||
var bottomEdge = Math.max(contentY + contentHeight + viewHeight / 2,
|
||||
contentY + viewHeight);
|
||||
} else {
|
||||
var leftEdge = blockBox.x;
|
||||
var rightEdge = leftEdge + blockBox.width;
|
||||
var topEdge = blockBox.y;
|
||||
var bottomEdge = topEdge + blockBox.height;
|
||||
}
|
||||
var absoluteLeft = 0;
|
||||
if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) {
|
||||
absoluteLeft = this.toolbox_.getWidth();
|
||||
absoluteLeft = toolboxDimensions.width;
|
||||
}
|
||||
var absoluteTop = 0;
|
||||
if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) {
|
||||
absoluteTop = this.toolbox_.getHeight();
|
||||
absoluteTop = toolboxDimensions.height;
|
||||
}
|
||||
|
||||
var metrics = {
|
||||
contentHeight: contentDimensions.height,
|
||||
contentWidth: contentDimensions.width,
|
||||
contentTop: contentDimensions.top,
|
||||
contentLeft: contentDimensions.left,
|
||||
|
||||
viewHeight: svgSize.height,
|
||||
viewWidth: svgSize.width,
|
||||
contentHeight: bottomEdge - topEdge,
|
||||
contentWidth: rightEdge - leftEdge,
|
||||
viewTop: -this.scrollY,
|
||||
viewLeft: -this.scrollX,
|
||||
contentTop: topEdge,
|
||||
contentLeft: leftEdge,
|
||||
viewTop: -this.scrollY, // Must be in pixels, somehow.
|
||||
viewLeft: -this.scrollX, // Must be in pixels, somehow.
|
||||
|
||||
absoluteTop: absoluteTop,
|
||||
absoluteLeft: absoluteLeft,
|
||||
toolboxWidth: this.toolbox_ ? this.toolbox_.getWidth() : 0,
|
||||
toolboxHeight: this.toolbox_ ? this.toolbox_.getHeight() : 0,
|
||||
flyoutWidth: this.flyout_ ? this.flyout_.getWidth() : 0,
|
||||
flyoutHeight: this.flyout_ ? this.flyout_.getHeight() : 0,
|
||||
|
||||
toolboxWidth: toolboxDimensions.width,
|
||||
toolboxHeight: toolboxDimensions.height,
|
||||
|
||||
flyoutWidth: flyoutDimensions.width,
|
||||
flyoutHeight: flyoutDimensions.height,
|
||||
|
||||
toolboxPosition: this.toolboxPosition
|
||||
};
|
||||
return metrics;
|
||||
|
||||
Reference in New Issue
Block a user