diff --git a/core/blockly.js b/core/blockly.js index f3f99766c..76e6ef83a 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -406,6 +406,11 @@ Blockly.hideChaff = function(opt_allowToolbox) { * .contentLeft: Offset of the left-most content from the x=0 coordinate. * .absoluteTop: Top-edge of view. * .absoluteLeft: Left-edge of view. + * .toolboxWidth: Width of toolbox, if it exists. Otherwise zero. + * .toolboxHeight: Height of toolbox, if it exists. Otherwise zero. + * .flyoutWidth: Width of the flyout if it is always open. Otherwise zero. + * .flyoutHeight: Height of flyout if it is always open. Otherwise zero. + * .toolboxPosition: Top, bottom, left or right. * @return {Object} Contains size and position metrics of main workspace. * @private * @this Blockly.WorkspaceSvg @@ -415,10 +420,10 @@ Blockly.getMainWorkspaceMetrics_ = function() { if (this.toolbox_) { // If the toolbox is at the bottom it's laid out separately from the main // workspace, rather than overlapping. - if (this.toolbox_.toolboxPosition == Blockly.TOOLBOX_AT_TOP) { - svgSize.height -= this.toolbox_.height; + if (this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) { + svgSize.height -= this.toolbox_.getHeight(); } else { - svgSize.width -= this.toolbox_.width; + svgSize.width -= this.toolbox_.getWidth(); } } // Set the margin to match the flyout's margin so that the workspace does @@ -451,12 +456,12 @@ Blockly.getMainWorkspaceMetrics_ = function() { var bottomEdge = topEdge + blockBox.height; } var absoluteLeft = 0; - if (this.toolbox_ && this.toolbox_.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { - absoluteLeft = this.toolbox_.width; + if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { + absoluteLeft = this.toolbox_.getWidth(); } var absoluteTop = 0; - if (this.toolbox_ && this.toolbox_.toolboxPosition == Blockly.TOOLBOX_AT_TOP) { - absoluteTop = this.toolbox_.height; + if (this.toolbox_ && this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) { + absoluteTop = this.toolbox_.getHeight(); } var metrics = { @@ -469,7 +474,12 @@ Blockly.getMainWorkspaceMetrics_ = function() { contentTop: topEdge, contentLeft: leftEdge, absoluteTop: absoluteTop, - absoluteLeft: absoluteLeft + 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, + toolboxPosition: this.toolboxPosition }; return metrics; }; diff --git a/core/flyout.js b/core/flyout.js index bd92ae831..c59998812 100644 --- a/core/flyout.js +++ b/core/flyout.js @@ -134,13 +134,6 @@ Blockly.Flyout.prototype.width_ = 0; */ Blockly.Flyout.prototype.height_ = 0; -/** - * Vertical offset of flyout. - * @type {number} - * @private - */ -Blockly.Flyout.prototype.verticalOffset_ = 0; - /** * Creates the flyout's DOM. Only needs to be called once. * @return {!Element} The flyout's SVG group. @@ -213,6 +206,22 @@ Blockly.Flyout.prototype.dispose = function() { this.targetWorkspace_ = null; }; +/** + * Get the width of the flyout. + * @return {number} the width of the flyout. + */ +Blockly.Flyout.prototype.getWidth = function() { + return this.width_; +}; + +/** + * Get the height of the flyout. + * @return {number} the width of the flyout. + */ +Blockly.Flyout.prototype.getHeight = function() { + return this.height_; +}; + /** * Return an object with all the metrics required to size scrollbars for the * flyout. The following properties are computed: @@ -242,7 +251,7 @@ Blockly.Flyout.prototype.getMetrics_ = function() { var optionBox = {height: 0, y: 0}; } - var absoluteTop = this.verticalOffset_ + this.SCROLLBAR_PADDING; + var absoluteTop = this.SCROLLBAR_PADDING; if (this.horizontalLayout_) { if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_BOTTOM) { absoluteTop = 0; @@ -303,10 +312,6 @@ Blockly.Flyout.prototype.setMetrics_ = function(xyRatio) { this.workspace_.scrollY + metrics.absoluteTop); }; -Blockly.Flyout.prototype.setVerticalOffset = function(verticalOffset) { - this.verticalOffset_ = verticalOffset; -}; - /** * Move the toolbox to the edge of the workspace. */ @@ -326,8 +331,7 @@ Blockly.Flyout.prototype.position = function() { } this.setBackgroundPath_(edgeWidth, - this.horizontalLayout_ ? - this.height_ + this.verticalOffset_ : metrics.viewHeight); + this.horizontalLayout_ ? this.height_ : metrics.viewHeight); var x = metrics.absoluteLeft; if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_RIGHT) { @@ -875,8 +879,8 @@ Blockly.Flyout.placeNewBlock_ = function(originBlock, workspace, xyNew.y += workspace.scrollY / workspace.scale - workspace.scrollY; // If the flyout is collapsible and the workspace can't be scrolled. if (workspace.toolbox_ && !workspace.scrollbar) { - xyNew.x += workspace.toolbox_.width / workspace.scale; - xyNew.y += workspace.toolbox_.height / workspace.scale; + xyNew.x += workspace.toolbox_.getWidth() / workspace.scale; + xyNew.y += workspace.toolbox_.getHeight() / workspace.scale; } // Move the new block to where the old block is. @@ -919,7 +923,7 @@ Blockly.Flyout.prototype.getClientRect = function() { return new goog.math.Rect(-BIG_NUM, y - BIG_NUM, BIG_NUM * 2, BIG_NUM + height); } else if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_BOTTOM) { - return new goog.math.Rect(-BIG_NUM, y + this.verticalOffset_, BIG_NUM * 2, + return new goog.math.Rect(-BIG_NUM, y, BIG_NUM * 2, BIG_NUM + height); } else if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) { return new goog.math.Rect(x - BIG_NUM, -BIG_NUM, BIG_NUM + width, diff --git a/core/toolbox.js b/core/toolbox.js index df29e5c62..b2c28de10 100644 --- a/core/toolbox.js +++ b/core/toolbox.js @@ -202,6 +202,22 @@ Blockly.Toolbox.prototype.dispose = function() { this.lastCategory_ = null; }; +/** + * Get the width of the toolbox. + * @return {number} the width of the toolbox. + */ +Blockly.Toolbox.prototype.getWidth = function() { + return this.width; +}; + +/** + * Get the height of the toolbox. + * @return {number} the width of the toolbox. + */ +Blockly.Toolbox.prototype.getHeight = function() { + return this.height; +}; + /** * Move the toolbox to the edge. */ @@ -221,11 +237,9 @@ Blockly.Toolbox.prototype.position = function() { this.height = treeDiv.offsetHeight; if (this.toolboxPosition == Blockly.TOOLBOX_AT_TOP) { // Top treeDiv.style.top = svgPosition.y + 'px'; - this.flyout_.setVerticalOffset(treeDiv.offsetHeight); } else { // Bottom var topOfToolbox = svgPosition.y + svgSize.height; treeDiv.style.top = topOfToolbox + 'px'; - this.flyout_.setVerticalOffset(topOfToolbox); } } else { if (this.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) { // Right diff --git a/core/trashcan.js b/core/trashcan.js index a9e670c57..8d295f898 100644 --- a/core/trashcan.js +++ b/core/trashcan.js @@ -220,16 +220,26 @@ Blockly.Trashcan.prototype.position = function() { } if (this.workspace_.RTL) { this.left_ = this.MARGIN_SIDE_ + Blockly.Scrollbar.scrollbarThickness; - if (this.workspace_.toolbox_ && - this.workspace_.toolbox_.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { - this.left_ += metrics.absoluteLeft; + if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { + this.left_ += metrics.flyoutWidth; + if (this.workspace_.toolbox_) { + this.left_ += metrics.absoluteLeft; + } } } else { this.left_ = metrics.viewWidth + metrics.absoluteLeft - this.WIDTH_ - this.MARGIN_SIDE_ - Blockly.Scrollbar.scrollbarThickness; + + if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) { + this.left_ -= metrics.flyoutWidth; + } } this.top_ = metrics.viewHeight + metrics.absoluteTop - (this.BODY_HEIGHT_ + this.LID_HEIGHT_) - this.bottom_; + + if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) { + this.top_ -= metrics.flyoutHeight; + } this.svgGroup_.setAttribute('transform', 'translate(' + this.left_ + ',' + this.top_ + ')'); }; diff --git a/core/workspace.js b/core/workspace.js index 725e65f38..9919c0be6 100644 --- a/core/workspace.js +++ b/core/workspace.js @@ -45,6 +45,7 @@ Blockly.Workspace = function(opt_options) { this.RTL = !!this.options.RTL; /** @type {boolean} */ this.horizontalLayout = !!this.options.horizontalLayout; + this.toolboxPosition = this.options.toolboxPosition; /** @type {!Array.} */ this.topBlocks_ = []; /** @type {!Array.} */ diff --git a/core/zoom_controls.js b/core/zoom_controls.js index 922794706..51aa77b46 100644 --- a/core/zoom_controls.js +++ b/core/zoom_controls.js @@ -208,16 +208,25 @@ Blockly.ZoomControls.prototype.position = function() { } if (this.workspace_.RTL) { this.left_ = this.MARGIN_SIDE_ + Blockly.Scrollbar.scrollbarThickness; - if (this.workspace_.toolbox_ && - this.workspace_.toolbox_.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { - this.left_ += metrics.absoluteLeft; + if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_LEFT) { + this.left_ += metrics.flyoutWidth; + if (this.workspace_.toolbox_) { + this.left_ += metrics.absoluteLeft; + } } } else { this.left_ = metrics.viewWidth + metrics.absoluteLeft - this.WIDTH_ - this.MARGIN_SIDE_ - Blockly.Scrollbar.scrollbarThickness; + + if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_RIGHT) { + this.left_ -= metrics.flyoutWidth; + } } this.top_ = metrics.viewHeight + metrics.absoluteTop - this.HEIGHT_ - this.bottom_; + if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) { + this.top_ -= metrics.flyoutHeight; + } this.svgGroup_.setAttribute('transform', 'translate(' + this.left_ + ',' + this.top_ + ')'); };