From 8609d502c944d2d677241e9f7cc5b543920081fa Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 5 Apr 2018 11:33:01 -0700 Subject: [PATCH 1/5] Add a function to scroll the workspace to center on a given block --- core/workspace_svg.js | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 53ded712e..106ca5b9f 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -1486,6 +1486,7 @@ Blockly.WorkspaceSvg.prototype.zoomToFit = function() { Blockly.WorkspaceSvg.prototype.scrollCenter = function() { if (!this.scrollbar) { // Can't center a non-scrolling workspace. + console.warn('Tried to scroll a non-scrollable workspace.'); return; } var metrics = this.getMetrics(); @@ -1637,6 +1638,56 @@ Blockly.WorkspaceSvg.getContentDimensionsBounded_ = function(ws, svgSize) { return dimensions; }; +/** + * Scroll the workspace to center on the given block. + * @param {?string} id ID of block center on. + * @public + */ +Blockly.WorkspaceSvg.prototype.centerOnBlock = function(id) { + if (!this.scrollbar) { + console.warn('Tried to scroll a non-scrollable workspace.'); + return; + } + var block = this.getBlockById(id); + if (block) { + // XY is in workspace coordinates. + var xy = block.getRelativeToSurfaceXY(); + // Height/width is in workspace units. + var heightWidth = block.getHeightWidth(); + + // Center in workspace units. + var blockCenterX = xy.x + heightWidth.width / 2; + var blockCenterY = xy.y + heightWidth.height / 2; + + // Workspace scale, used to convert from workspace coordinates to pixels. + var scale = this.scale; + + // Center in pixels. 0, 0 is at the workspace origin. These numbers may + // be negative. + var pixelX = blockCenterX * scale; + var pixelY = blockCenterY * scale; + + var metrics = this.getMetrics(); + + // Scrolling to here would put the block in the top-left corner of the + // visible workspace. + var scrollToBlockX = pixelX - metrics.contentLeft; + var scrollToBlockY = pixelY - metrics.contentTop; + + // viewHeight and viewWidth are in pixels. + var halfViewWidth = metrics.viewWidth / 2; + var halfViewHeight = metrics.viewHeight / 2; + + // Put the block in the center of the visible workspace instead. + var scrollToCenterX = scrollToBlockX - halfViewWidth; + var scrollToCenterY = scrollToBlockY - halfViewHeight; + + Blockly.WidgetDiv.hide(true); + this.scrollbar.set(scrollToCenterX, scrollToCenterY); + } +}; + + /** * Return an object with all the metrics required to size scrollbars for a * top level workspace. The following properties are computed: From 2884bdfaa8d960beca9a287af2cee06dd992af38 Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 5 Apr 2018 17:42:37 -0700 Subject: [PATCH 2/5] Use hideChaff instead of WidgetDiv.hide; move function closer to similar functions. --- core/workspace_svg.js | 99 +++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 106ca5b9f..c023554e6 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -1498,6 +1498,55 @@ Blockly.WorkspaceSvg.prototype.scrollCenter = function() { this.scrollbar.set(x, y); }; +/** + * Scroll the workspace to center on the given block. + * @param {?string} id ID of block center on. + * @public + */ +Blockly.WorkspaceSvg.prototype.centerOnBlock = function(id) { + if (!this.scrollbar) { + console.warn('Tried to scroll a non-scrollable workspace.'); + return; + } + var block = this.getBlockById(id); + if (block) { + // XY is in workspace coordinates. + var xy = block.getRelativeToSurfaceXY(); + // Height/width is in workspace units. + var heightWidth = block.getHeightWidth(); + + // Center in workspace units. + var blockCenterX = xy.x + heightWidth.width / 2; + var blockCenterY = xy.y + heightWidth.height / 2; + + // Workspace scale, used to convert from workspace coordinates to pixels. + var scale = this.scale; + + // Center in pixels. 0, 0 is at the workspace origin. These numbers may + // be negative. + var pixelX = blockCenterX * scale; + var pixelY = blockCenterY * scale; + + var metrics = this.getMetrics(); + + // Scrolling to here would put the block in the top-left corner of the + // visible workspace. + var scrollToBlockX = pixelX - metrics.contentLeft; + var scrollToBlockY = pixelY - metrics.contentTop; + + // viewHeight and viewWidth are in pixels. + var halfViewWidth = metrics.viewWidth / 2; + var halfViewHeight = metrics.viewHeight / 2; + + // Put the block in the center of the visible workspace instead. + var scrollToCenterX = scrollToBlockX - halfViewWidth; + var scrollToCenterY = scrollToBlockY - halfViewHeight; + + Blockly.hideChaff(); + this.scrollbar.set(scrollToCenterX, scrollToCenterY); + } +}; + /** * Set the workspace's zoom factor. * @param {number} newScale Zoom factor. @@ -1638,56 +1687,6 @@ Blockly.WorkspaceSvg.getContentDimensionsBounded_ = function(ws, svgSize) { return dimensions; }; -/** - * Scroll the workspace to center on the given block. - * @param {?string} id ID of block center on. - * @public - */ -Blockly.WorkspaceSvg.prototype.centerOnBlock = function(id) { - if (!this.scrollbar) { - console.warn('Tried to scroll a non-scrollable workspace.'); - return; - } - var block = this.getBlockById(id); - if (block) { - // XY is in workspace coordinates. - var xy = block.getRelativeToSurfaceXY(); - // Height/width is in workspace units. - var heightWidth = block.getHeightWidth(); - - // Center in workspace units. - var blockCenterX = xy.x + heightWidth.width / 2; - var blockCenterY = xy.y + heightWidth.height / 2; - - // Workspace scale, used to convert from workspace coordinates to pixels. - var scale = this.scale; - - // Center in pixels. 0, 0 is at the workspace origin. These numbers may - // be negative. - var pixelX = blockCenterX * scale; - var pixelY = blockCenterY * scale; - - var metrics = this.getMetrics(); - - // Scrolling to here would put the block in the top-left corner of the - // visible workspace. - var scrollToBlockX = pixelX - metrics.contentLeft; - var scrollToBlockY = pixelY - metrics.contentTop; - - // viewHeight and viewWidth are in pixels. - var halfViewWidth = metrics.viewWidth / 2; - var halfViewHeight = metrics.viewHeight / 2; - - // Put the block in the center of the visible workspace instead. - var scrollToCenterX = scrollToBlockX - halfViewWidth; - var scrollToCenterY = scrollToBlockY - halfViewHeight; - - Blockly.WidgetDiv.hide(true); - this.scrollbar.set(scrollToCenterX, scrollToCenterY); - } -}; - - /** * Return an object with all the metrics required to size scrollbars for a * top level workspace. The following properties are computed: From 3a4adb3b0d8ce53da9242e5add090579b06f42d4 Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 5 Apr 2018 17:57:47 -0700 Subject: [PATCH 3/5] Scroll to the procedure definition from the procedure call context menu --- blocks/procedures.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/blocks/procedures.js b/blocks/procedures.js index b026be0f7..e166e9c5c 100644 --- a/blocks/procedures.js +++ b/blocks/procedures.js @@ -860,7 +860,10 @@ Blockly.Blocks['procedures_callnoreturn'] = { var workspace = this.workspace; option.callback = function() { var def = Blockly.Procedures.getDefinition(name, workspace); - def && def.select(); + if (def) { + workspace.centerOnBlock(def.id); + def.select(); + } }; options.push(option); }, From 5964278e7dd541f397c9862c61bdde3618f44b82 Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 5 Apr 2018 18:16:05 -0700 Subject: [PATCH 4/5] Handle RTL --- core/workspace_svg.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/workspace_svg.js b/core/workspace_svg.js index c023554e6..f534ce45a 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -1515,10 +1515,13 @@ Blockly.WorkspaceSvg.prototype.centerOnBlock = function(id) { // Height/width is in workspace units. var heightWidth = block.getHeightWidth(); - // Center in workspace units. - var blockCenterX = xy.x + heightWidth.width / 2; + // Find the enter of the block in workspace units. var blockCenterY = xy.y + heightWidth.height / 2; + // In RTL the block's position is the top right of the block, not top left. + var multiplier = this.RTL ? -1 : 1; + var blockCenterX = xy.x + (multiplier * heightWidth.width / 2); + // Workspace scale, used to convert from workspace coordinates to pixels. var scale = this.scale; From 112f48592f28879212f05c56869e5f6c3337a4ac Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 5 Apr 2018 18:19:56 -0700 Subject: [PATCH 5/5] Return early if there's no block --- core/workspace_svg.js | 79 ++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/core/workspace_svg.js b/core/workspace_svg.js index f534ce45a..d74586c31 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -1508,46 +1508,49 @@ Blockly.WorkspaceSvg.prototype.centerOnBlock = function(id) { console.warn('Tried to scroll a non-scrollable workspace.'); return; } + var block = this.getBlockById(id); - if (block) { - // XY is in workspace coordinates. - var xy = block.getRelativeToSurfaceXY(); - // Height/width is in workspace units. - var heightWidth = block.getHeightWidth(); - - // Find the enter of the block in workspace units. - var blockCenterY = xy.y + heightWidth.height / 2; - - // In RTL the block's position is the top right of the block, not top left. - var multiplier = this.RTL ? -1 : 1; - var blockCenterX = xy.x + (multiplier * heightWidth.width / 2); - - // Workspace scale, used to convert from workspace coordinates to pixels. - var scale = this.scale; - - // Center in pixels. 0, 0 is at the workspace origin. These numbers may - // be negative. - var pixelX = blockCenterX * scale; - var pixelY = blockCenterY * scale; - - var metrics = this.getMetrics(); - - // Scrolling to here would put the block in the top-left corner of the - // visible workspace. - var scrollToBlockX = pixelX - metrics.contentLeft; - var scrollToBlockY = pixelY - metrics.contentTop; - - // viewHeight and viewWidth are in pixels. - var halfViewWidth = metrics.viewWidth / 2; - var halfViewHeight = metrics.viewHeight / 2; - - // Put the block in the center of the visible workspace instead. - var scrollToCenterX = scrollToBlockX - halfViewWidth; - var scrollToCenterY = scrollToBlockY - halfViewHeight; - - Blockly.hideChaff(); - this.scrollbar.set(scrollToCenterX, scrollToCenterY); + if (!block) { + return; } + + // XY is in workspace coordinates. + var xy = block.getRelativeToSurfaceXY(); + // Height/width is in workspace units. + var heightWidth = block.getHeightWidth(); + + // Find the enter of the block in workspace units. + var blockCenterY = xy.y + heightWidth.height / 2; + + // In RTL the block's position is the top right of the block, not top left. + var multiplier = this.RTL ? -1 : 1; + var blockCenterX = xy.x + (multiplier * heightWidth.width / 2); + + // Workspace scale, used to convert from workspace coordinates to pixels. + var scale = this.scale; + + // Center in pixels. 0, 0 is at the workspace origin. These numbers may + // be negative. + var pixelX = blockCenterX * scale; + var pixelY = blockCenterY * scale; + + var metrics = this.getMetrics(); + + // Scrolling to here would put the block in the top-left corner of the + // visible workspace. + var scrollToBlockX = pixelX - metrics.contentLeft; + var scrollToBlockY = pixelY - metrics.contentTop; + + // viewHeight and viewWidth are in pixels. + var halfViewWidth = metrics.viewWidth / 2; + var halfViewHeight = metrics.viewHeight / 2; + + // Put the block in the center of the visible workspace instead. + var scrollToCenterX = scrollToBlockX - halfViewWidth; + var scrollToCenterY = scrollToBlockY - halfViewHeight; + + Blockly.hideChaff(); + this.scrollbar.set(scrollToCenterX, scrollToCenterY); }; /**