Decompose functions in flyout. Does not change behaviour.

This commit is contained in:
rachel-fenichel 2016-04-20 14:14:53 -07:00
parent 52eb6adcc2
commit c8f98a7ded

View file

@ -264,20 +264,8 @@ Blockly.Flyout.prototype.position = function() {
if (this.RTL) {
edgeWidth *= -1;
}
var path = ['M ' + (this.RTL ? this.width_ : 0) + ',0'];
path.push('h', edgeWidth);
path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0,
this.RTL ? 0 : 1,
this.RTL ? -this.CORNER_RADIUS : this.CORNER_RADIUS,
this.CORNER_RADIUS);
path.push('v', Math.max(0, metrics.viewHeight - this.CORNER_RADIUS * 2));
path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0,
this.RTL ? 0 : 1,
this.RTL ? this.CORNER_RADIUS : -this.CORNER_RADIUS,
this.CORNER_RADIUS);
path.push('h', -edgeWidth);
path.push('z');
this.svgBackground_.setAttribute('d', path.join(' '));
this.setBackgroundPath_(edgeWidth, metrics.viewHeight);
var x = metrics.absoluteLeft;
if (this.RTL) {
@ -296,6 +284,37 @@ Blockly.Flyout.prototype.position = function() {
}
};
/**
* Create and set the path for the visible boundaries of the flyout.
* @param {number} width The width of the flyout, not including the
* rounded corners.
* @param {number} height The height of the flyout, not including
* rounded corners.
* @private
*/
Blockly.Flyout.prototype.setBackgroundPath_ = function(width, height) {
var path = ['M ' + (this.RTL ? this.width_ : 0) + ',0'];
// Top.
path.push('h', width);
// Rounded corner.
path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0,
this.RTL ? 0 : 1,
this.RTL ? -this.CORNER_RADIUS : this.CORNER_RADIUS,
this.CORNER_RADIUS);
// Side closest to the workspace.
path.push('v', Math.max(0, height - this.CORNER_RADIUS * 2));
// Rounded corner.
path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0,
this.RTL ? 0 : 1,
this.RTL ? this.CORNER_RADIUS : -this.CORNER_RADIUS,
this.CORNER_RADIUS);
// Bottom.
path.push('h', -width);
// Side away from the workspace.
path.push('z');
this.svgBackground_.setAttribute('d', path.join(' '));
};
/**
* Scroll the flyout to the top.
*/
@ -363,18 +382,7 @@ Blockly.Flyout.prototype.hide = function() {
*/
Blockly.Flyout.prototype.show = function(xmlList) {
this.hide();
// Delete any blocks from a previous showing.
var blocks = this.workspace_.getTopBlocks(false);
for (var i = 0, block; block = blocks[i]; i++) {
if (block.workspace == this.workspace_) {
block.dispose(false, false);
}
}
// Delete any background buttons from a previous showing.
for (var i = 0, rect; rect = this.buttons_[i]; i++) {
goog.dom.removeNode(rect);
}
this.buttons_.length = 0;
this.clearOldBlocks_();
if (xmlList == Blockly.Variables.NAME_TYPE) {
// Special category for variables.
@ -406,6 +414,38 @@ Blockly.Flyout.prototype.show = function(xmlList) {
}
}
this.layoutBlocks_(blocks, gaps, margin);
// IE 11 is an incompetant browser that fails to fire mouseout events.
// When the mouse is over the background, deselect all blocks.
var deselectAll = function(e) {
var blocks = this.workspace_.getTopBlocks(false);
for (var i = 0, block; block = blocks[i]; i++) {
block.removeSelect();
}
};
this.listeners_.push(Blockly.bindEvent_(this.svgBackground_, 'mouseover',
this, deselectAll));
this.width_ = 0;
this.reflow();
this.filterForCapacity_();
// Fire a resize event to update the flyout's scrollbar.
Blockly.fireUiEventNow(window, 'resize');
this.reflowWrapper_ = this.reflow.bind(this);
this.workspace_.addChangeListener(this.reflowWrapper_);
};
/**
* Lay out the blocks in the flyout.
* @param {!Array<Blockly.BlockSvg>} blocks The blocks to lay out.
* @param {!Array<number>} gaps The visible gaps between blocks.
* @param {number} margin The margin around the edges of the flyout.
* @private
*/
Blockly.Flyout.prototype.layoutBlocks_ = function(blocks, gaps, margin) {
// Lay out the blocks vertically.
var cursorY = margin;
for (var i = 0, block; block = blocks[i]; i++) {
@ -434,47 +474,57 @@ Blockly.Flyout.prototype.show = function(xmlList) {
block.flyoutRect_ = rect;
this.buttons_[i] = rect;
if (this.autoClose) {
this.listeners_.push(Blockly.bindEvent_(root, 'mousedown', null,
this.createBlockFunc_(block)));
this.listeners_.push(Blockly.bindEvent_(rect, 'mousedown', null,
this.createBlockFunc_(block)));
} else {
this.listeners_.push(Blockly.bindEvent_(root, 'mousedown', null,
this.blockMouseDown_(block)));
this.listeners_.push(Blockly.bindEvent_(rect, 'mousedown', null,
this.blockMouseDown_(block)));
}
this.listeners_.push(Blockly.bindEvent_(root, 'mouseover', block,
block.addSelect));
this.listeners_.push(Blockly.bindEvent_(root, 'mouseout', block,
block.removeSelect));
this.listeners_.push(Blockly.bindEvent_(rect, 'mouseover', block,
block.addSelect));
this.listeners_.push(Blockly.bindEvent_(rect, 'mouseout', block,
block.removeSelect));
this.addBlockListeners_(root, block, rect);
}
};
// IE 11 is an incompetant browser that fails to fire mouseout events.
// When the mouse is over the background, deselect all blocks.
var deselectAll = function(e) {
var blocks = this.workspace_.getTopBlocks(false);
for (var i = 0, block; block = blocks[i]; i++) {
block.removeSelect();
/**
* Delete blocks and background buttons from a previous showing of the flyout.
* @private
*/
Blockly.Flyout.prototype.clearOldBlocks_ = function() {
// Delete any blocks from a previous showing.
var blocks = this.workspace_.getTopBlocks(false);
for (var i = 0, block; block = blocks[i]; i++) {
if (block.workspace == this.workspace_) {
block.dispose(false, false);
}
};
this.listeners_.push(Blockly.bindEvent_(this.svgBackground_, 'mouseover',
this, deselectAll));
}
// Delete any background buttons from a previous showing.
for (var j = 0, rect; rect = this.buttons_[j]; j++) {
goog.dom.removeNode(rect);
}
this.buttons_.length = 0;
};
this.width_ = 0;
this.reflow();
this.filterForCapacity_();
// Fire a resize event to update the flyout's scrollbar.
Blockly.fireUiEventNow(window, 'resize');
this.reflowWrapper_ = this.reflow.bind(this);
this.workspace_.addChangeListener(this.reflowWrapper_);
/**
* Add listeners to a block that has been added to the flyout.
* @param {!Element} root The root node of the SVG group the block is in.
* @param {!Blockly.Block} block The block to add listeners for.
* @param {!Element} rect The invisible rectangle under the block that acts as
* a button for that block.
* @private
*/
Blockly.Flyout.prototype.addBlockListeners_ = function(root, block, rect) {
if (this.autoClose) {
this.listeners_.push(Blockly.bindEvent_(root, 'mousedown', null,
this.createBlockFunc_(block)));
this.listeners_.push(Blockly.bindEvent_(rect, 'mousedown', null,
this.createBlockFunc_(block)));
} else {
this.listeners_.push(Blockly.bindEvent_(root, 'mousedown', null,
this.blockMouseDown_(block)));
this.listeners_.push(Blockly.bindEvent_(rect, 'mousedown', null,
this.blockMouseDown_(block)));
}
this.listeners_.push(Blockly.bindEvent_(root, 'mouseover', block,
block.addSelect));
this.listeners_.push(Blockly.bindEvent_(root, 'mouseout', block,
block.removeSelect));
this.listeners_.push(Blockly.bindEvent_(rect, 'mouseover', block,
block.addSelect));
this.listeners_.push(Blockly.bindEvent_(rect, 'mouseout', block,
block.removeSelect));
};
/**
@ -656,37 +706,7 @@ Blockly.Flyout.prototype.createBlockFunc_ = function(originBlock) {
return;
}
Blockly.Events.disable();
// Create the new block by cloning the block in the flyout (via XML).
var xml = Blockly.Xml.blockToDom(originBlock);
var block = Blockly.Xml.domToBlock(xml, workspace);
// Place it in the same spot as the flyout copy.
var svgRootOld = originBlock.getSvgRoot();
if (!svgRootOld) {
throw 'originBlock is not rendered.';
}
var xyOld = Blockly.getSvgXY_(svgRootOld, workspace);
// Scale the scroll (getSvgXY_ did not do this).
if (flyout.RTL) {
var width = workspace.getMetrics().viewWidth - flyout.width_;
xyOld.x += width / workspace.scale - width;
} else {
xyOld.x += flyout.workspace_.scrollX / flyout.workspace_.scale -
flyout.workspace_.scrollX;
}
xyOld.y += flyout.workspace_.scrollY / flyout.workspace_.scale -
flyout.workspace_.scrollY;
var svgRootNew = block.getSvgRoot();
if (!svgRootNew) {
throw 'block is not rendered.';
}
var xyNew = Blockly.getSvgXY_(svgRootNew, workspace);
// Scale the scroll (getSvgXY_ did not do this).
xyNew.x += workspace.scrollX / workspace.scale - workspace.scrollX;
xyNew.y += workspace.scrollY / workspace.scale - workspace.scrollY;
if (workspace.toolbox_ && !workspace.scrollbar) {
xyNew.x += workspace.toolbox_.width / workspace.scale;
}
block.moveBy(xyOld.x - xyNew.x, xyOld.y - xyNew.y);
var block = flyout.placeNewBlock_(originBlock, workspace);
Blockly.Events.enable();
if (Blockly.Events.isEnabled()) {
Blockly.Events.setGroup(true);
@ -704,6 +724,48 @@ Blockly.Flyout.prototype.createBlockFunc_ = function(originBlock) {
};
};
/**
* Copy a block from the flyout to the workspace and position it correctly.
* @param {!Blockly.Block} originBlock The flyout block to copy.
* @param {!Blockly.Workspace} workspace The main workspace.
* @return {!Blockly.Block} The new block in the main workspace.
* @private
*/
Blockly.Flyout.prototype.placeNewBlock_ = function(originBlock, workspace) {
// Create the new block by cloning the block in the flyout (via XML).
var xml = Blockly.Xml.blockToDom(originBlock);
var block = Blockly.Xml.domToBlock(xml, workspace);
// Place it in the same spot as the flyout copy.
var svgRootOld = originBlock.getSvgRoot();
if (!svgRootOld) {
throw 'originBlock is not rendered.';
}
var xyOld = Blockly.getSvgXY_(svgRootOld, workspace);
// Scale the scroll (getSvgXY_ did not do this).
if (this.RTL) {
var width = workspace.getMetrics().viewWidth - this.width_;
xyOld.x += width / workspace.scale - width;
} else {
xyOld.x += this.workspace_.scrollX / this.workspace_.scale -
this.workspace_.scrollX;
}
xyOld.y += this.workspace_.scrollY / this.workspace_.scale -
this.workspace_.scrollY;
var svgRootNew = block.getSvgRoot();
if (!svgRootNew) {
throw 'block is not rendered.';
}
var xyNew = Blockly.getSvgXY_(svgRootNew, workspace);
// Scale the scroll (getSvgXY_ did not do this).
xyNew.x += workspace.scrollX / workspace.scale - workspace.scrollX;
xyNew.y += workspace.scrollY / workspace.scale - workspace.scrollY;
if (workspace.toolbox_ && !workspace.scrollbar) {
xyNew.x += workspace.toolbox_.width / workspace.scale;
}
block.moveBy(xyOld.x - xyNew.x, xyOld.y - xyNew.y);
return block;
};
/**
* Filter the blocks on the flyout to disable the ones that are above the
* capacity limit.