From 7568015c8cff38ceda82e647f6178bead9d0b39d Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Tue, 1 Sep 2015 20:00:13 +0100 Subject: [PATCH] Scale the flyout as the workspace zooms. --- core/flyout.js | 35 +++++++++++------------------------ core/utils.js | 26 ++++++++++++-------------- core/workspace_svg.js | 20 +++++++++++++------- 3 files changed, 36 insertions(+), 45 deletions(-) diff --git a/core/flyout.js b/core/flyout.js index 6aa6624ab..c0ca62305 100644 --- a/core/flyout.js +++ b/core/flyout.js @@ -363,6 +363,7 @@ Blockly.Flyout.prototype.show = function(xmlList) { } this.buttons_.length = 0; + this.workspace_.scale = this.targetWorkspace_.scale; var margin = this.CORNER_RADIUS; this.svgGroup_.style.display = 'block'; @@ -630,34 +631,20 @@ Blockly.Flyout.prototype.createBlockFunc_ = function(originBlock) { throw 'originBlock is not rendered.'; } var xyOld = Blockly.getSvgXY_(svgRootOld, workspace); + // Scale the scroll (getSvgXY_ did not do this). + 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.'; } - if (workspace.scale == 1) { - // No scaling issues. - var xyNew = Blockly.getSvgXY_(svgRootNew, workspace); - block.moveBy(xyOld.x - xyNew.x, xyOld.y - xyNew.y); - } else { - // Scale the block while keeping the mouse location constant. - var mouseXY = Blockly.mouseToSvg(e, workspace.options.svg); - // Relative mouse position to the block. - var rMouseX = mouseXY.x - xyOld.x; - var rMouseY = mouseXY.y - xyOld.y; - // Fix scale. - xyOld.x /= workspace.scale; - xyOld.y /= workspace.scale; - // Calculate the position to create the block, fixing scale. - var xyCanvastoSvg = Blockly.getRelativeXY_(workspace.getCanvas()); - var xyNewtoCanvas = Blockly.getRelativeXY_(svgRootNew); - var newX = xyCanvastoSvg.x / workspace.scale + xyNewtoCanvas.x; - var newY = xyCanvastoSvg.y / workspace.scale + xyNewtoCanvas.y; - var placePositionX = xyOld.x - newX; - var placePositionY = xyOld.y - newY; - var dx = rMouseX - rMouseX / workspace.scale; - var dy = rMouseY - rMouseY / workspace.scale; - block.moveBy(placePositionX - dx, placePositionY - dy); - } + 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; + block.moveBy(xyOld.x - xyNew.x, xyOld.y - xyNew.y); if (flyout.autoClose) { flyout.hide(); } else { diff --git a/core/utils.js b/core/utils.js index f81026695..d02ca16fe 100644 --- a/core/utils.js +++ b/core/utils.js @@ -251,11 +251,11 @@ Blockly.isTargetInput_ = function(e) { * Return the coordinates of the top-left corner of this element relative to * its parent. Only for SVG elements and children (e.g. rect, g, path). * @param {!Element} element SVG element to find the coordinates of. - * @return {!Object} Object with .x and .y properties. + * @return {!goog.math.Coordinate} Object with .x and .y properties. * @private */ Blockly.getRelativeXY_ = function(element) { - var xy = {x: 0, y: 0}; + var xy = new goog.math.Coordinate(0, 0); // First, check for x and y attributes. var x = element.getAttribute('x'); if (x) { @@ -301,24 +301,22 @@ Blockly.getRelativeXY_.XY_REGEXP_ = Blockly.getSvgXY_ = function(element, workspace) { var x = 0; var y = 0; - // Evaluate if element isn't child of a canvas. - var inCanvas = goog.dom.contains(workspace.getCanvas(), element) || - goog.dom.contains(workspace.getBubbleCanvas(), element); + var scale = 1; + if (goog.dom.contains(workspace.getCanvas(), element) || + goog.dom.contains(workspace.getBubbleCanvas(), element)) { + // Before the SVG canvas, scale the coordinates. + scale = workspace.scale; + } do { // Loop through this block and every parent. var xy = Blockly.getRelativeXY_(element); if (element == workspace.getCanvas() || element == workspace.getBubbleCanvas()) { - inCanvas = false; - } - // Before the SVG canvas scale the coordinates. - if (inCanvas) { - x += xy.x * workspace.scale; - y += xy.y * workspace.scale; - } else { - x += xy.x; - y += xy.y; + // After the SVG canvas, don't scale the coordinates. + scale = 1; } + x += xy.x * scale; + y += xy.y * scale; element = element.parentNode; } while (element && element != workspace.options.svg); return new goog.math.Coordinate(x, y); diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 9bea8211e..0365a0e74 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -635,7 +635,6 @@ Blockly.WorkspaceSvg.prototype.moveDrag = function(e) { * @private */ Blockly.WorkspaceSvg.prototype.onMouseWheel_ = function(e) { - Blockly.hideChaff(true); // TODO: Remove terminateDrag and compensate for coordinate skew during zoom. Blockly.terminateDrag_(); var delta = e.deltaY > 0 ? -1 : 1; @@ -881,12 +880,19 @@ Blockly.WorkspaceSvg.prototype.zoom = function(x, y, type) { .translate(x * (1 - scaleChange), y * (1 - scaleChange)) .scale(scaleChange); // newScale and matrix.a should be identical (within a rounding error). - if (this.scale != matrix.a) { - this.scale = matrix.a; - this.scrollX = matrix.e - metrics.absoluteLeft; - this.scrollY = matrix.f - metrics.absoluteTop; - this.updateGridPattern_(); - this.scrollbar.resize(); + if (this.scale == matrix.a) { + return; // No change in zoom. + } + this.scale = matrix.a; + this.scrollX = matrix.e - metrics.absoluteLeft; + this.scrollY = matrix.f - metrics.absoluteTop; + this.updateGridPattern_(); + this.scrollbar.resize(); + Blockly.hideChaff(false); + if (this.flyout_) { + // No toolbox, resize flyout. + this.flyout_.workspace_.scale = this.scale; + this.flyout_.reflow(); } };