From aca074891d2c6f9009f9176f7ede96e4bf457b0d Mon Sep 17 00:00:00 2001 From: rachel-fenichel Date: Mon, 27 Jun 2016 17:27:08 -0700 Subject: [PATCH] Fix some problems with flyout rendering (#461) --- core/flyout.js | 68 +++++++++++++++++------------------------------ core/scrollbar.js | 2 +- 2 files changed, 25 insertions(+), 45 deletions(-) diff --git a/core/flyout.js b/core/flyout.js index 85aaee983..e8aa2f872 100644 --- a/core/flyout.js +++ b/core/flyout.js @@ -286,8 +286,8 @@ Blockly.Flyout.prototype.getMetrics_ = function() { contentWidth: (optionBox.width + 2 * this.MARGIN) * this.workspace_.scale, viewTop: -this.workspace_.scrollY, viewLeft: -this.workspace_.scrollX, - contentTop: 0, // TODO: #349 - contentLeft: 0, // TODO: #349 + contentTop: optionBox.y, + contentLeft: optionBox.x, absoluteTop: absoluteTop, absoluteLeft: absoluteLeft }; @@ -426,9 +426,8 @@ Blockly.Flyout.prototype.setBackgroundPathVertical_ = function(width, height) { * rounded corners. * @private */ -Blockly.Flyout.prototype.setBackgroundPathHorizontal_ = - function(width, height) { - /* eslint-disable indent */ +Blockly.Flyout.prototype.setBackgroundPathHorizontal_ = function(width, + height) { var atTop = this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP; // Start at top left. var path = ['M 0,' + (atTop ? 0 : this.CORNER_RADIUS)]; @@ -461,7 +460,7 @@ Blockly.Flyout.prototype.setBackgroundPathHorizontal_ = path.push('z'); } this.svgBackground_.setAttribute('d', path.join(' ')); -}; /* eslint-enable indent */ +}; /** * Scroll the flyout to the top. @@ -588,7 +587,6 @@ Blockly.Flyout.prototype.show = function(xmlList) { } this.reflow(); - this.offsetHorizontalRtlBlocks(this.workspace_.getTopBlocks(false)); this.filterForCapacity_(); // Correctly position the flyout's scrollbar when it opens. @@ -605,9 +603,12 @@ Blockly.Flyout.prototype.show = function(xmlList) { * @private */ Blockly.Flyout.prototype.layoutBlocks_ = function(blocks, gaps) { - var margin = this.MARGIN * this.workspace_.scale; + var margin = this.MARGIN; var cursorX = this.RTL ? margin : margin + Blockly.BlockSvg.TAB_WIDTH; var cursorY = margin; + if (this.horizontalLayout_ && this.RTL) { + blocks = blocks.reverse(); + } for (var i = 0, block; block = blocks[i]; i++) { var allBlocks = block.getDescendants(); for (var j = 0, child; child = allBlocks[j]; j++) { @@ -623,8 +624,13 @@ Blockly.Flyout.prototype.layoutBlocks_ = function(blocks, gaps) { if (this.horizontalLayout_) { cursorX += tab; } - block.moveBy((this.horizontalLayout_ && this.RTL) ? -cursorX : cursorX, - cursorY); + + if (this.horizontalLayout_ && this.RTL) { + block.moveBy(cursorX + blockHW.width - tab, cursorY); + } else { + block.moveBy(cursorX, cursorY); + } + if (this.horizontalLayout_) { cursorX += (blockHW.width + gaps[i] - tab); } else { @@ -1074,10 +1080,9 @@ Blockly.Flyout.prototype.reflowVertical = function(blocks) { if (this.RTL) { // With the flyoutWidth known, right-align the blocks. var oldX = block.getRelativeToSurfaceXY().x; - var dx = flyoutWidth - this.MARGIN; - dx /= this.workspace_.scale; - dx -= Blockly.BlockSvg.TAB_WIDTH; - block.moveBy(dx - oldX, 0); + var newX = flyoutWidth / this.workspace_.scale - this.MARGIN; + newX -= Blockly.BlockSvg.TAB_WIDTH; + block.moveBy(newX - oldX, 0); } if (block.flyoutRect_) { block.flyoutRect_.setAttribute('width', blockHW.width); @@ -1109,41 +1114,16 @@ Blockly.Flyout.prototype.reflowVertical = function(blocks) { * Reflow blocks and their buttons. */ Blockly.Flyout.prototype.reflow = function() { + if (this.reflowWrapper_) { + this.workspace_.removeChangeListener(this.reflowWrapper_); + } var blocks = this.workspace_.getTopBlocks(false); if (this.horizontalLayout_) { this.reflowHorizontal(blocks); } else { this.reflowVertical(blocks); } -}; - -/** - * In the horizontal RTL case all of the blocks will be laid out to the left of - * the origin, but we won't know how big the workspace is until the layout pass - * is done. - * Now that it's done, shunt all the blocks to be right of the origin. - * @param {!Array} blocks The blocks to reposition. - */ -Blockly.Flyout.prototype.offsetHorizontalRtlBlocks = function(blocks) { - if (this.horizontalLayout_ && this.RTL) { - // We don't know this workspace's view width yet. - this.position(); - try { - var optionBox = this.workspace_.getCanvas().getBBox(); - } catch (e) { - // Firefox has trouble with hidden elements (Bug 528969). - optionBox = {height: 0, y: 0, width: 0, x: 0}; - } - - var offset = Math.max(-optionBox.x + this.MARGIN, - this.width_ / this.workspace_.scale); - - for (var i = 0, block; block = blocks[i]; i++) { - block.moveBy(offset, 0); - if (block.flyoutRect_) { - block.flyoutRect_.setAttribute('x', - offset + Number(block.flyoutRect_.getAttribute('x'))); - } - } + if (this.reflowWrapper_) { + this.workspace_.addChangeListener(this.reflowWrapper_); } }; diff --git a/core/scrollbar.js b/core/scrollbar.js index 6381b928f..da2dd942d 100644 --- a/core/scrollbar.js +++ b/core/scrollbar.js @@ -694,7 +694,7 @@ Blockly.Scrollbar.prototype.onMouseUpHandle_ = function() { * @private */ Blockly.Scrollbar.prototype.constrainHandle_ = function(value) { - if (value <= 0 || isNaN(value)) { + if (value <= 0 || isNaN(value) || this.scrollViewSize_ < this.handleLength_) { value = 0; } else { value = Math.min(value, this.scrollViewSize_ - this.handleLength_);