Add Blockly.utils.Metrics @record (#3913)

* Add Blockly.utils.Metrics
This commit is contained in:
Sam El-Husseini
2020-05-21 15:03:17 -07:00
committed by GitHub
parent 3aa1963be8
commit e3babee1f3
17 changed files with 398 additions and 187 deletions

View File

@@ -21,17 +21,16 @@ this.BLOCKLY_DIR = (function(root) {
this.BLOCKLY_BOOT = function(root) {
// Execute after Closure has loaded.
goog.addDependency('../../core/block.js', ['Blockly.Block'], ['Blockly.Blocks', 'Blockly.Connection', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Extensions', 'Blockly.Input', 'Blockly.Workspace', 'Blockly.fieldRegistry', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.string'], {});
goog.addDependency('../../core/block.js', ['Blockly.Block'], ['Blockly.ASTNode', 'Blockly.Blocks', 'Blockly.Connection', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Extensions', 'Blockly.Input', 'Blockly.Workspace', 'Blockly.fieldRegistry', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.string'], {'lang': 'es5'});
goog.addDependency('../../core/block_animations.js', ['Blockly.blockAnimations'], ['Blockly.utils.dom'], {});
goog.addDependency('../../core/block_drag_surface.js', ['Blockly.BlockDragSurfaceSvg'], ['Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/block_dragger.js', ['Blockly.BlockDragger'], ['Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Events.Ui', 'Blockly.InsertionMarkerManager', 'Blockly.blockAnimations', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/block_events.js', ['Blockly.Events.BlockBase', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Events.Change', 'Blockly.Events.Create', 'Blockly.Events.Delete', 'Blockly.Events.Move'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/block_svg.js', ['Blockly.BlockSvg'], ['Blockly.ASTNode', 'Blockly.Block', 'Blockly.ContextMenu', 'Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Events.Ui', 'Blockly.Msg', 'Blockly.RenderedConnection', 'Blockly.TabNavigateCursor', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.blockAnimations', 'Blockly.blockRendering.IPathObject', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
goog.addDependency('../../core/blockly.js', ['Blockly'], ['Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Procedures', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Variables', 'Blockly.WidgetDiv', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.constants', 'Blockly.inject', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.colour'], {});
goog.addDependency('../../core/blockly.js', ['Blockly'], ['Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Procedures', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Variables', 'Blockly.WidgetDiv', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.constants', 'Blockly.inject', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.colour'], {});
goog.addDependency('../../core/blocks.js', ['Blockly.Blocks'], [], {});
goog.addDependency('../../core/bubble.js', ['Blockly.Bubble'], ['Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.Workspace', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/bubble_dragger.js', ['Blockly.BubbleDragger'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.CommentMove', 'Blockly.utils', 'Blockly.utils.Coordinate'], {});
goog.addDependency('../../core/category_registry.js', ['Blockly.categoryRegistry'], [], {});
goog.addDependency('../../core/comment.js', ['Blockly.Comment'], ['Blockly.Bubble', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.Ui', 'Blockly.Icon', 'Blockly.Warning', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/components/component.js', ['Blockly.Component', 'Blockly.Component.Error'], ['Blockly.utils.IdGenerator', 'Blockly.utils.dom', 'Blockly.utils.style'], {});
goog.addDependency('../../core/components/tree/basenode.js', ['Blockly.tree.BaseNode'], ['Blockly.Component', 'Blockly.utils.KeyCodes', 'Blockly.utils.aria', 'Blockly.utils.object', 'Blockly.utils.style'], {});
@@ -71,6 +70,7 @@ goog.addDependency('../../core/icon.js', ['Blockly.Icon'], ['Blockly.utils', 'Bl
goog.addDependency('../../core/inject.js', ['Blockly.inject'], ['Blockly.BlockDragSurfaceSvg', 'Blockly.Component', 'Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Grid', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ScrollbarPair', 'Blockly.Tooltip', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.WorkspaceSvg', 'Blockly.user.keyMap', 'Blockly.utils', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/input.js', ['Blockly.Input'], ['Blockly.Connection', 'Blockly.FieldLabel'], {});
goog.addDependency('../../core/insertion_marker_manager.js', ['Blockly.InsertionMarkerManager'], ['Blockly.Events', 'Blockly.blockAnimations'], {'lang': 'es5'});
goog.addDependency('../../core/interfaces/i_bounded_element.js', ['Blockly.IBoundedElement'], [], {});
goog.addDependency('../../core/interfaces/i_copyable.js', ['Blockly.ICopyable'], ['Blockly.ISelectable'], {});
goog.addDependency('../../core/interfaces/i_deletable.js', ['Blockly.IDeletable'], [], {});
goog.addDependency('../../core/interfaces/i_movable.js', ['Blockly.IMovable'], [], {});
@@ -90,7 +90,7 @@ goog.addDependency('../../core/menuitem.js', ['Blockly.MenuItem'], ['Blockly.uti
goog.addDependency('../../core/msg.js', ['Blockly.Msg'], ['Blockly.utils.global'], {});
goog.addDependency('../../core/mutator.js', ['Blockly.Mutator'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.Ui', 'Blockly.Icon', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.object', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/names.js', ['Blockly.Names'], ['Blockly.Msg'], {});
goog.addDependency('../../core/options.js', ['Blockly.Options'], ['Blockly.Theme', 'Blockly.Themes.Classic', 'Blockly.Xml', 'Blockly.user.keyMap', 'Blockly.utils.toolbox', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/options.js', ['Blockly.Options'], ['Blockly.Theme', 'Blockly.Themes.Classic', 'Blockly.Xml', 'Blockly.user.keyMap', 'Blockly.utils.Metrics', 'Blockly.utils.toolbox', 'Blockly.utils.userAgent'], {});
goog.addDependency('../../core/procedures.js', ['Blockly.Procedures'], ['Blockly.Blocks', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.Msg', 'Blockly.Names', 'Blockly.Workspace', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/rendered_connection.js', ['Blockly.RenderedConnection'], ['Blockly.Connection', 'Blockly.Events', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
goog.addDependency('../../core/renderers/common/block_rendering.js', ['Blockly.blockRendering'], ['Blockly.utils.object'], {});
@@ -132,7 +132,7 @@ goog.addDependency('../../core/renderers/zelos/measurables/rows.js', ['Blockly.z
goog.addDependency('../../core/renderers/zelos/path_object.js', ['Blockly.zelos.PathObject'], ['Blockly.blockRendering.PathObject', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider'], {});
goog.addDependency('../../core/renderers/zelos/renderer.js', ['Blockly.zelos.Renderer'], ['Blockly.InsertionMarkerManager', 'Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider', 'Blockly.zelos.Drawer', 'Blockly.zelos.MarkerSvg', 'Blockly.zelos.PathObject', 'Blockly.zelos.RenderInfo'], {});
goog.addDependency('../../core/requires.js', ['Blockly.requires'], ['Blockly', 'Blockly.Comment', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldLabelSerializable', 'Blockly.FieldMultilineInput', 'Blockly.FieldNumber', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.FlyoutButton', 'Blockly.Generator', 'Blockly.HorizontalFlyout', 'Blockly.Mutator', 'Blockly.Themes.Classic', 'Blockly.Themes.Dark', 'Blockly.Themes.Deuteranopia', 'Blockly.Themes.HighContrast', 'Blockly.Themes.Tritanopia', 'Blockly.Toolbox', 'Blockly.Trashcan', 'Blockly.VariablesDynamic', 'Blockly.VerticalFlyout', 'Blockly.Warning', 'Blockly.ZoomControls', 'Blockly.geras.Renderer', 'Blockly.thrasos.Renderer', 'Blockly.zelos.Renderer'], {});
goog.addDependency('../../core/scrollbar.js', ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['Blockly.Touch', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/scrollbar.js', ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['Blockly.Touch', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/theme.js', ['Blockly.Theme'], ['Blockly.utils', 'Blockly.utils.colour', 'Blockly.utils.object'], {});
goog.addDependency('../../core/theme/classic.js', ['Blockly.Themes.Classic'], ['Blockly.Theme'], {});
goog.addDependency('../../core/theme/dark.js', ['Blockly.Themes.Dark'], ['Blockly.Theme'], {});
@@ -143,7 +143,6 @@ goog.addDependency('../../core/theme/tritanopia.js', ['Blockly.Themes.Tritanopia
goog.addDependency('../../core/theme/zelos.js', ['Blockly.Themes.Zelos'], ['Blockly.Theme'], {});
goog.addDependency('../../core/theme_manager.js', ['Blockly.ThemeManager'], ['Blockly.Theme'], {});
goog.addDependency('../../core/toolbox.js', ['Blockly.Toolbox'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Touch', 'Blockly.navigation', 'Blockly.tree.TreeControl', 'Blockly.tree.TreeNode', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
goog.addDependency('../../core/toolbox_category.js', ['Blockly.ToolboxCategory'], ['Blockly.Toolbox'], {});
goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.utils.string'], {});
goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.utils', 'Blockly.utils.global', 'Blockly.utils.string'], {});
goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object'], {});
@@ -158,6 +157,7 @@ goog.addDependency('../../core/utils/global.js', ['Blockly.utils.global'], [], {
goog.addDependency('../../core/utils/idgenerator.js', ['Blockly.utils.IdGenerator'], [], {});
goog.addDependency('../../core/utils/keycodes.js', ['Blockly.utils.KeyCodes'], [], {});
goog.addDependency('../../core/utils/math.js', ['Blockly.utils.math'], [], {});
goog.addDependency('../../core/utils/metrics.js', ['Blockly.utils.Metrics'], [], {});
goog.addDependency('../../core/utils/object.js', ['Blockly.utils.object'], [], {});
goog.addDependency('../../core/utils/rect.js', ['Blockly.utils.Rect'], [], {});
goog.addDependency('../../core/utils/size.js', ['Blockly.utils.Size'], [], {});
@@ -182,7 +182,7 @@ goog.addDependency('../../core/workspace_comment_svg.js', ['Blockly.WorkspaceCom
goog.addDependency('../../core/workspace_drag_surface_svg.js', ['Blockly.WorkspaceDragSurfaceSvg'], ['Blockly.utils', 'Blockly.utils.dom'], {});
goog.addDependency('../../core/workspace_dragger.js', ['Blockly.WorkspaceDragger'], ['Blockly.utils.Coordinate'], {});
goog.addDependency('../../core/workspace_events.js', ['Blockly.Events.FinishedLoading'], ['Blockly.Events', 'Blockly.Events.Ui', 'Blockly.utils.object'], {'lang': 'es5'});
goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ConnectionDB', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.MarkerManager', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ThemeManager', 'Blockly.Themes.Classic', 'Blockly.TouchGesture', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.constants', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ConnectionDB', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.MarkerManager', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ThemeManager', 'Blockly.Themes.Classic', 'Blockly.TouchGesture', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.constants', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
goog.addDependency('../../core/ws_comment_events.js', ['Blockly.Events.CommentBase', 'Blockly.Events.CommentChange', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/xml.js', ['Blockly.Xml'], ['Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.FinishedLoading', 'Blockly.Events.VarCreate', 'Blockly.utils', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.xml'], {});
goog.addDependency('../../core/zoom_controls.js', ['Blockly.ZoomControls'], ['Blockly.Css', 'Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.utils.dom'], {'lang': 'es5'});

View File

@@ -26,6 +26,7 @@ goog.require('Blockly.Tooltip');
goog.require('Blockly.Touch');
goog.require('Blockly.utils');
goog.require('Blockly.utils.colour');
goog.require('Blockly.utils.Size');
goog.require('Blockly.Variables');
goog.require('Blockly.WidgetDiv');
goog.require('Blockly.WorkspaceSvg');
@@ -107,13 +108,11 @@ Blockly.EventData;
/**
* Returns the dimensions of the specified SVG image.
* @param {!SVGElement} svg SVG image.
* @return {!Object} Contains width and height properties.
* @return {!Blockly.utils.Size} Contains width and height properties.
*/
Blockly.svgSize = function(svg) {
return {
width: svg.cachedWidth_,
height: svg.cachedHeight_
};
svg = /** @type {?} */ (svg);
return new Blockly.utils.Size(svg.cachedWidth_, svg.cachedHeight_);
};
/**

View File

@@ -21,6 +21,8 @@ goog.require('Blockly.utils.math');
goog.require('Blockly.utils.userAgent');
goog.require('Blockly.Workspace');
goog.requireType('Blockly.utils.Metrics');
/**
* Class for UI bubble.
@@ -489,8 +491,8 @@ Blockly.Bubble.prototype.layoutBubble_ = function() {
* workspace (what percentage of the bubble is visible).
* @param {!{x: number, y: number}} relativeMin The position of the top-left
* corner of the bubble relative to the anchor point.
* @param {!Object} metrics The metrics of the workspace the bubble will
* appear in.
* @param {!Blockly.utils.Metrics} metrics The metrics of the workspace the
* bubble will appear in.
* @return {number} The percentage of the bubble that is visible.
* @private
*/
@@ -535,10 +537,10 @@ Blockly.Bubble.prototype.getOverlap_ = function(relativeMin, metrics) {
* Calculate what the optimal horizontal position of the top-left corner of the
* bubble is (relative to the anchor point) so that the most area of the
* bubble is shown.
* @param {!Object} metrics The metrics of the workspace the bubble will
* appear in.
* @param {!Blockly.utils.Metrics} metrics The metrics of the workspace the
* bubble will appear in.
* @return {number} The optimal horizontal position of the top-left corner
* of the bubble.
* of the bubble.
* @private
*/
Blockly.Bubble.prototype.getOptimalRelativeLeft_ = function(metrics) {
@@ -593,10 +595,10 @@ Blockly.Bubble.prototype.getOptimalRelativeLeft_ = function(metrics) {
* Calculate what the optimal vertical position of the top-left corner of
* the bubble is (relative to the anchor point) so that the most area of the
* bubble is shown.
* @param {!Object} metrics The metrics of the workspace the bubble will
* appear in.
* @param {!Blockly.utils.Metrics} metrics The metrics of the workspace the
* bubble will appear in.
* @return {number} The optimal vertical position of the top-left corner
* of the bubble.
* of the bubble.
* @private
*/
Blockly.Bubble.prototype.getOptimalRelativeTop_ = function(metrics) {

View File

@@ -30,6 +30,7 @@ goog.require('Blockly.WorkspaceSvg');
goog.require('Blockly.Xml');
goog.requireType('Blockly.IBlocklyActionable');
goog.requireType('Blockly.utils.Metrics');
/**
@@ -37,10 +38,13 @@ goog.requireType('Blockly.IBlocklyActionable');
* @param {!Blockly.Options} workspaceOptions Dictionary of options for the
* workspace.
* @constructor
* @abstract
* @implements {Blockly.IBlocklyActionable}
*/
Blockly.Flyout = function(workspaceOptions) {
workspaceOptions.getMetrics = this.getMetrics_.bind(this);
workspaceOptions.getMetrics =
/** @type {function():!Blockly.utils.Metrics} */ (
this.getMetrics_.bind(this));
workspaceOptions.setMetrics = this.setMetrics_.bind(this);
/**
@@ -108,6 +112,13 @@ Blockly.Flyout = function(workspaceOptions) {
* @const
*/
this.tabWidth_ = this.workspace_.getRenderer().getConstants().TAB_WIDTH;
/**
* The target workspace
* @type {?Blockly.WorkspaceSvg}
* @package
*/
this.targetWorkspace = null;
};
/**
@@ -235,11 +246,14 @@ Blockly.Flyout.prototype.createDom = function(tagName) {
* create new blocks.
*/
Blockly.Flyout.prototype.init = function(targetWorkspace) {
this.targetWorkspace_ = targetWorkspace;
this.targetWorkspace = targetWorkspace;
this.workspace_.targetWorkspace = targetWorkspace;
// Add scrollbar.
this.scrollbar_ = new Blockly.Scrollbar(this.workspace_,
/**
* @type {!Blockly.Scrollbar}
* @package
*/
this.scrollbar = new Blockly.Scrollbar(this.workspace_,
this.horizontalLayout_, false, 'blocklyFlyoutScrollbar');
this.hide();
@@ -248,7 +262,7 @@ Blockly.Flyout.prototype.init = function(targetWorkspace) {
Blockly.bindEventWithChecks_(this.svgGroup_, 'wheel', this, this.wheel_));
if (!this.autoClose) {
this.filterWrapper_ = this.filterForCapacity_.bind(this);
this.targetWorkspace_.addChangeListener(this.filterWrapper_);
this.targetWorkspace.addChangeListener(this.filterWrapper_);
}
// Dragging the flyout up and down.
@@ -258,10 +272,10 @@ Blockly.Flyout.prototype.init = function(targetWorkspace) {
// A flyout connected to a workspace doesn't have its own current gesture.
this.workspace_.getGesture =
this.targetWorkspace_.getGesture.bind(this.targetWorkspace_);
this.targetWorkspace.getGesture.bind(this.targetWorkspace);
// Get variables from the main workspace rather than the target workspace.
this.workspace_.setVariableMap(this.targetWorkspace_.getVariableMap());
this.workspace_.setVariableMap(this.targetWorkspace.getVariableMap());
this.workspace_.createPotentialVariableMap();
};
@@ -275,12 +289,12 @@ Blockly.Flyout.prototype.dispose = function() {
this.hide();
Blockly.unbindEvent_(this.eventWrappers_);
if (this.filterWrapper_) {
this.targetWorkspace_.removeChangeListener(this.filterWrapper_);
this.targetWorkspace.removeChangeListener(this.filterWrapper_);
this.filterWrapper_ = null;
}
if (this.scrollbar_) {
this.scrollbar_.dispose();
this.scrollbar_ = null;
if (this.scrollbar) {
this.scrollbar.dispose();
this.scrollbar = null;
}
if (this.workspace_) {
this.workspace_.getThemeManager().unsubscribe(this.svgBackground_);
@@ -293,7 +307,7 @@ Blockly.Flyout.prototype.dispose = function() {
this.svgGroup_ = null;
}
this.svgBackground_ = null;
this.targetWorkspace_ = null;
this.targetWorkspace = null;
};
/**
@@ -370,7 +384,7 @@ Blockly.Flyout.prototype.updateDisplay_ = function() {
this.svgGroup_.style.display = show ? 'block' : 'none';
// Update the scrollbar's visibility too since it should mimic the
// flyout's visibility.
this.scrollbar_.setContainerVisible(show);
this.scrollbar.setContainerVisible(show);
};
/**
@@ -395,14 +409,14 @@ Blockly.Flyout.prototype.positionAt_ = function(width, height, x, y) {
}
// Update the scrollbar (if one exists).
if (this.scrollbar_) {
if (this.scrollbar) {
// Set the scrollbars origin to be the top left of the flyout.
this.scrollbar_.setOrigin(x, y);
this.scrollbar_.resize();
this.scrollbar.setOrigin(x, y);
this.scrollbar.resize();
// Set the position again so that if the metrics were the same (and the
// resize failed) our position is still updated.
this.scrollbar_.setPosition_(
this.scrollbar_.position_.x, this.scrollbar_.position_.y);
this.scrollbar.setPosition(
this.scrollbar.position.x, this.scrollbar.position.y);
}
};
@@ -556,7 +570,8 @@ Blockly.Flyout.prototype.createButton_ = function(btnInfo, isLabel) {
throw Error('Missing require for Blockly.FlyoutButton');
}
var curButton = new Blockly.FlyoutButton(this.workspace_,
this.targetWorkspace_, btnInfo, isLabel);
/** @type {!Blockly.WorkspaceSvg} */ (this.targetWorkspace), btnInfo,
isLabel);
return curButton;
};
@@ -564,11 +579,12 @@ Blockly.Flyout.prototype.createButton_ = function(btnInfo, isLabel) {
* Create a block from the xml and permanently disable any blocks that were
* defined as disabled.
* @param {!Element} blockXml The xml of the block.
* @return {!Blockly.Block} The block created from the blockXml.
* @return {!Blockly.BlockSvg} The block created from the blockXml.
* @private
*/
Blockly.Flyout.prototype.createBlock_ = function(blockXml) {
var curBlock = Blockly.Xml.domToBlock(blockXml, this.workspace_);
var curBlock = /** @type {!Blockly.BlockSvg} */ (
Blockly.Xml.domToBlock(blockXml, this.workspace_));
if (!curBlock.isEnabled()) {
// Record blocks that were initially disabled.
// Do not enable these blocks as a result of capacity filtering.
@@ -651,7 +667,7 @@ Blockly.Flyout.prototype.clearOldBlocks_ = function() {
/**
* Add listeners to a block that has been added to the flyout.
* @param {!SVGElement} root The root node of the SVG group the block is in.
* @param {!Blockly.Block} block The block to add listeners for.
* @param {!Blockly.BlockSvg} block The block to add listeners for.
* @param {!SVGElement} rect The invisible rectangle under the block that acts
* as a mat for that block.
* @protected
@@ -673,14 +689,14 @@ Blockly.Flyout.prototype.addBlockListeners_ = function(root, block, rect) {
/**
* Handle a mouse-down on an SVG block in a non-closing flyout.
* @param {!Blockly.Block} block The flyout block to copy.
* @param {!Blockly.BlockSvg} block The flyout block to copy.
* @return {!Function} Function to call when block is clicked.
* @private
*/
Blockly.Flyout.prototype.blockMouseDown_ = function(block) {
var flyout = this;
return function(e) {
var gesture = flyout.targetWorkspace_.getGesture(e);
var gesture = flyout.targetWorkspace.getGesture(e);
if (gesture) {
gesture.setStartBlock(block);
gesture.handleFlyoutStart(e, flyout);
@@ -694,7 +710,7 @@ Blockly.Flyout.prototype.blockMouseDown_ = function(block) {
* @private
*/
Blockly.Flyout.prototype.onMouseDown_ = function(e) {
var gesture = this.targetWorkspace_.getGesture(e);
var gesture = this.targetWorkspace.getGesture(e);
if (gesture) {
gesture.handleFlyoutStart(e, this);
}
@@ -722,8 +738,8 @@ Blockly.Flyout.prototype.isBlockCreatable_ = function(block) {
Blockly.Flyout.prototype.createBlock = function(originalBlock) {
var newBlock = null;
Blockly.Events.disable();
var variablesBeforeCreation = this.targetWorkspace_.getAllVariables();
this.targetWorkspace_.setResizesEnabled(false);
var variablesBeforeCreation = this.targetWorkspace.getAllVariables();
this.targetWorkspace.setResizesEnabled(false);
try {
newBlock = this.placeNewBlock_(originalBlock);
// Close the flyout.
@@ -732,7 +748,7 @@ Blockly.Flyout.prototype.createBlock = function(originalBlock) {
Blockly.Events.enable();
}
var newVariables = Blockly.Variables.getAddedVariables(this.targetWorkspace_,
var newVariables = Blockly.Variables.getAddedVariables(this.targetWorkspace,
variablesBeforeCreation);
if (Blockly.Events.isEnabled()) {
@@ -775,7 +791,7 @@ Blockly.Flyout.prototype.initFlyoutButton_ = function(button, x, y) {
/**
* Create and place a rectangle corresponding to the given block.
* @param {!Blockly.Block} block The block to associate the rect to.
* @param {!Blockly.BlockSvg} block The block to associate the rect to.
* @param {number} x The x position of the cursor during this layout pass.
* @param {number} y The y position of the cursor during this layout pass.
* @param {!{height: number, width: number}} blockHW The height and width of the
@@ -834,7 +850,7 @@ Blockly.Flyout.prototype.filterForCapacity_ = function() {
var blocks = this.workspace_.getTopBlocks(false);
for (var i = 0, block; (block = blocks[i]); i++) {
if (this.permanentlyDisabled_.indexOf(block) == -1) {
var enable = this.targetWorkspace_
var enable = this.targetWorkspace
.isCapacityAvailable(Blockly.utils.getBlockTypeCounts(block));
while (block) {
block.setEnabled(enable);
@@ -863,7 +879,7 @@ Blockly.Flyout.prototype.reflow = function() {
* @package
*/
Blockly.Flyout.prototype.isScrollable = function() {
return this.scrollbar_ ? this.scrollbar_.isVisible() : false;
return this.scrollbar ? this.scrollbar.isVisible() : false;
};
/**
@@ -873,7 +889,7 @@ Blockly.Flyout.prototype.isScrollable = function() {
* @private
*/
Blockly.Flyout.prototype.placeNewBlock_ = function(oldBlock) {
var targetWorkspace = this.targetWorkspace_;
var targetWorkspace = this.targetWorkspace;
var svgRootOld = oldBlock.getSvgRoot();
if (!svgRootOld) {
throw Error('oldBlock is not rendered.');
@@ -935,3 +951,44 @@ Blockly.Flyout.prototype.onBlocklyAction = function(action) {
var cursor = this.workspace_.getCursor();
return cursor.onBlocklyAction(action);
};
/**
* Return the deletion rectangle for this flyout in viewport coordinates.
* @return {Blockly.utils.Rect} Rectangle in which to delete.
*/
Blockly.Flyout.prototype.getClientRect;
/**
* Position the flyout.
* @return {void}
*/
Blockly.Flyout.prototype.position;
/**
* Determine if a drag delta is toward the workspace, based on the position
* and orientation of the flyout. This is used in determineDragIntention_ to
* determine if a new block should be created or if the flyout should scroll.
* @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
* moved from the position at mouse down, in pixel units.
* @return {boolean} True if the drag is toward the workspace.
* @package
*/
Blockly.Flyout.prototype.isDragTowardWorkspace;
/**
* Return an object with all the metrics required to size scrollbars for the
* flyout.
* @return {Blockly.utils.Metrics} Contains size and position metrics of the
* flyout.
* @protected
*/
Blockly.Flyout.prototype.getMetrics_;
/**
* Sets the translation of the flyout to match the scrollbars.
* @param {!{x:number,y:number}} xyRatio Contains a y property which is a float
* between 0 and 1 specifying the degree of scrolling and a
* similar x property.
* @protected
*/
Blockly.Flyout.prototype.setMetrics_;

View File

@@ -37,7 +37,7 @@ Blockly.FlyoutDragger = function(flyout) {
* @type {!Blockly.Scrollbar}
* @private
*/
this.scrollbar_ = flyout.scrollbar_;
this.scrollbar_ = flyout.scrollbar;
/**
* Whether the flyout scrolls horizontally. If false, the flyout scrolls

View File

@@ -20,6 +20,8 @@ goog.require('Blockly.utils.object');
goog.require('Blockly.utils.Rect');
goog.require('Blockly.WidgetDiv');
goog.requireType('Blockly.utils.Metrics');
/**
* Class for a flyout.
@@ -29,10 +31,6 @@ goog.require('Blockly.WidgetDiv');
* @constructor
*/
Blockly.HorizontalFlyout = function(workspaceOptions) {
workspaceOptions.getMetrics = /** @type {function():!Object} */ (
this.getMetrics_.bind(this));
workspaceOptions.setMetrics = this.setMetrics_.bind(this);
Blockly.HorizontalFlyout.superClass_.constructor.call(this, workspaceOptions);
/**
* Flyout should be laid out horizontally.
@@ -56,8 +54,9 @@ Blockly.utils.object.inherits(Blockly.HorizontalFlyout, Blockly.Flyout);
* .viewLeft: Offset of the left edge of visible rectangle from parent,
* .contentLeft: Offset of the left-most content from the x=0 coordinate,
* .absoluteLeft: Left-edge of view.
* @return {Object} Contains size and position metrics of the flyout.
* @private
* @return {Blockly.utils.Metrics} Contains size and position metrics of the
* flyout.
* @protected
*/
Blockly.HorizontalFlyout.prototype.getMetrics_ = function() {
if (!this.isVisible()) {
@@ -84,14 +83,16 @@ Blockly.HorizontalFlyout.prototype.getMetrics_ = function() {
var viewWidth = this.width_ - 2 * this.SCROLLBAR_PADDING;
var metrics = {
viewHeight: viewHeight,
viewWidth: viewWidth,
contentHeight: (optionBox.height + 2 * this.MARGIN) * this.workspace_.scale,
contentWidth: (optionBox.width + 2 * this.MARGIN) * this.workspace_.scale,
viewTop: -this.workspace_.scrollY,
viewLeft: -this.workspace_.scrollX,
contentTop: 0,
contentLeft: 0,
viewHeight: viewHeight,
viewWidth: viewWidth,
viewTop: -this.workspace_.scrollY,
viewLeft: -this.workspace_.scrollX,
absoluteTop: absoluteTop,
absoluteLeft: absoluteLeft
};
@@ -100,10 +101,10 @@ Blockly.HorizontalFlyout.prototype.getMetrics_ = function() {
/**
* Sets the translation of the flyout to match the scrollbars.
* @param {!Object} xyRatio Contains a y property which is a float
* @param {!{x:number,y:number}} xyRatio Contains a y property which is a float
* between 0 and 1 specifying the degree of scrolling and a
* similar x property.
* @private
* @protected
*/
Blockly.HorizontalFlyout.prototype.setMetrics_ = function(xyRatio) {
var metrics = this.getMetrics_();
@@ -127,7 +128,7 @@ Blockly.HorizontalFlyout.prototype.position = function() {
if (!this.isVisible()) {
return;
}
var targetWorkspaceMetrics = this.targetWorkspace_.getMetrics();
var targetWorkspaceMetrics = this.targetWorkspace.getMetrics();
if (!targetWorkspaceMetrics) {
// Hidden components will return null.
return;
@@ -142,7 +143,7 @@ Blockly.HorizontalFlyout.prototype.position = function() {
// X is always 0 since this is a horizontal flyout.
var x = 0;
// If this flyout is the toolbox flyout.
if (this.targetWorkspace_.toolboxPosition == this.toolboxPosition_) {
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
// If there is a toolbox.
if (targetWorkspaceMetrics.toolboxHeight) {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
@@ -220,7 +221,7 @@ Blockly.HorizontalFlyout.prototype.setBackgroundPath_ = function(width,
* Scroll the flyout to the top.
*/
Blockly.HorizontalFlyout.prototype.scrollToStart = function() {
this.scrollbar_.set(this.RTL ? Infinity : 0);
this.scrollbar.set(this.RTL ? Infinity : 0);
};
/**
@@ -238,7 +239,7 @@ Blockly.HorizontalFlyout.prototype.wheel_ = function(e) {
var limit = metrics.contentWidth - metrics.viewWidth;
pos = Math.min(pos, limit);
pos = Math.max(pos, 0);
this.scrollbar_.set(pos);
this.scrollbar.set(pos);
// When the flyout moves from a wheel event, hide WidgetDiv and DropDownDiv.
Blockly.WidgetDiv.hide();
Blockly.DropDownDiv.hideWithoutAnimation();
@@ -257,7 +258,7 @@ Blockly.HorizontalFlyout.prototype.wheel_ = function(e) {
* @private
*/
Blockly.HorizontalFlyout.prototype.layout_ = function(contents, gaps) {
this.workspace_.scale = this.targetWorkspace_.scale;
this.workspace_.scale = this.targetWorkspace.scale;
var margin = this.MARGIN;
var cursorX = margin + this.tabWidth_;
var cursorY = margin;
@@ -354,7 +355,7 @@ Blockly.HorizontalFlyout.prototype.getClientRect = function() {
* @private
*/
Blockly.HorizontalFlyout.prototype.reflowInternal_ = function() {
this.workspace_.scale = this.targetWorkspace_.scale;
this.workspace_.scale = this.targetWorkspace.scale;
var flyoutHeight = 0;
var blocks = this.workspace_.getTopBlocks(false);
for (var i = 0, block; (block = blocks[i]); i++) {

View File

@@ -21,6 +21,8 @@ goog.require('Blockly.utils.Rect');
goog.require('Blockly.utils.userAgent');
goog.require('Blockly.WidgetDiv');
goog.requireType('Blockly.utils.Metrics');
/**
* Class for a flyout.
@@ -30,10 +32,6 @@ goog.require('Blockly.WidgetDiv');
* @constructor
*/
Blockly.VerticalFlyout = function(workspaceOptions) {
workspaceOptions.getMetrics = /** @type {function():!Object} */ (
this.getMetrics_.bind(this));
workspaceOptions.setMetrics = this.setMetrics_.bind(this);
Blockly.VerticalFlyout.superClass_.constructor.call(this, workspaceOptions);
/**
* Flyout should be laid out vertically.
@@ -57,8 +55,9 @@ Blockly.utils.object.inherits(Blockly.VerticalFlyout, Blockly.Flyout);
* .viewLeft: Offset of the left edge of visible rectangle from parent,
* .contentLeft: Offset of the left-most content from the x=0 coordinate,
* .absoluteLeft: Left-edge of view.
* @return {Object} Contains size and position metrics of the flyout.
* @private
* @return {Blockly.utils.Metrics} Contains size and position metrics of the
* flyout.
* @protected
*/
Blockly.VerticalFlyout.prototype.getMetrics_ = function() {
if (!this.isVisible()) {
@@ -84,14 +83,16 @@ Blockly.VerticalFlyout.prototype.getMetrics_ = function() {
}
var metrics = {
viewHeight: viewHeight,
viewWidth: viewWidth,
contentHeight: optionBox.height * this.workspace_.scale + 2 * this.MARGIN,
contentWidth: optionBox.width * this.workspace_.scale + 2 * this.MARGIN,
viewTop: -this.workspace_.scrollY + optionBox.y,
viewLeft: -this.workspace_.scrollX,
contentTop: optionBox.y,
contentLeft: optionBox.x,
viewHeight: viewHeight,
viewWidth: viewWidth,
viewTop: -this.workspace_.scrollY + optionBox.y,
viewLeft: -this.workspace_.scrollX,
absoluteTop: absoluteTop,
absoluteLeft: absoluteLeft
};
@@ -100,10 +101,10 @@ Blockly.VerticalFlyout.prototype.getMetrics_ = function() {
/**
* Sets the translation of the flyout to match the scrollbars.
* @param {!Object} xyRatio Contains a y property which is a float
* @param {!{x:number,y:number}} xyRatio Contains a y property which is a float
* between 0 and 1 specifying the degree of scrolling and a
* similar x property.
* @private
* @protected
*/
Blockly.VerticalFlyout.prototype.setMetrics_ = function(xyRatio) {
var metrics = this.getMetrics_();
@@ -125,7 +126,7 @@ Blockly.VerticalFlyout.prototype.position = function() {
if (!this.isVisible()) {
return;
}
var targetWorkspaceMetrics = this.targetWorkspace_.getMetrics();
var targetWorkspaceMetrics = this.targetWorkspace.getMetrics();
if (!targetWorkspaceMetrics) {
// Hidden components will return null.
return;
@@ -140,7 +141,7 @@ Blockly.VerticalFlyout.prototype.position = function() {
// Y is always 0 since this is a vertical flyout.
var y = 0;
// If this flyout is the toolbox flyout.
if (this.targetWorkspace_.toolboxPosition == this.toolboxPosition_) {
if (this.targetWorkspace.toolboxPosition == this.toolboxPosition_) {
// If there is a category toolbox.
if (targetWorkspaceMetrics.toolboxWidth) {
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
@@ -208,7 +209,7 @@ Blockly.VerticalFlyout.prototype.setBackgroundPath_ = function(width, height) {
* Scroll the flyout to the top.
*/
Blockly.VerticalFlyout.prototype.scrollToStart = function() {
this.scrollbar_.set(0);
this.scrollbar.set(0);
};
/**
@@ -225,7 +226,7 @@ Blockly.VerticalFlyout.prototype.wheel_ = function(e) {
var limit = metrics.contentHeight - metrics.viewHeight;
pos = Math.min(pos, limit);
pos = Math.max(pos, 0);
this.scrollbar_.set(pos);
this.scrollbar.set(pos);
// When the flyout moves from a wheel event, hide WidgetDiv and DropDownDiv.
Blockly.WidgetDiv.hide();
Blockly.DropDownDiv.hideWithoutAnimation();
@@ -244,7 +245,7 @@ Blockly.VerticalFlyout.prototype.wheel_ = function(e) {
* @private
*/
Blockly.VerticalFlyout.prototype.layout_ = function(contents, gaps) {
this.workspace_.scale = this.targetWorkspace_.scale;
this.workspace_.scale = this.targetWorkspace.scale;
var margin = this.MARGIN;
var cursorX = this.RTL ? margin : margin + this.tabWidth_;
var cursorY = margin;
@@ -333,7 +334,7 @@ Blockly.VerticalFlyout.prototype.getClientRect = function() {
* @private
*/
Blockly.VerticalFlyout.prototype.reflowInternal_ = function() {
this.workspace_.scale = this.targetWorkspace_.scale;
this.workspace_.scale = this.targetWorkspace.scale;
var flyoutWidth = 0;
var blocks = this.workspace_.getTopBlocks(false);
for (var i = 0, block; (block = blocks[i]); i++) {

View File

@@ -314,7 +314,7 @@ Blockly.Gesture.prototype.updateIsDraggingFromFlyout_ = function() {
}
if (!this.flyout_.isScrollable() ||
this.flyout_.isDragTowardWorkspace(this.currentDragDeltaXY_)) {
this.startWorkspace_ = this.flyout_.targetWorkspace_;
this.startWorkspace_ = this.flyout_.targetWorkspace;
this.startWorkspace_.updateScreenCalculationsIfScrolled();
// Start the event group now, so that the same event group is used for block
// creation and block dragging.

View File

@@ -29,6 +29,8 @@ goog.require('Blockly.utils.userAgent');
goog.require('Blockly.WorkspaceDragSurfaceSvg');
goog.require('Blockly.WorkspaceSvg');
goog.requireType('Blockly.utils.Metrics');
/**
* Inject a Blockly editor into the specified container element (usually a div).

View File

@@ -27,6 +27,8 @@ goog.require('Blockly.utils.xml');
goog.require('Blockly.WorkspaceSvg');
goog.require('Blockly.Xml');
goog.requireType('Blockly.utils.Metrics');
/**
* Class for a mutator dialog.
@@ -405,15 +407,26 @@ Blockly.Mutator.prototype.workspaceChanged_ = function(e) {
* .viewWidth: Width of the visible rectangle,
* .absoluteTop: Top-edge of view.
* .absoluteLeft: Left-edge of view.
* @return {!Object} Contains size and position metrics of mutator dialog's
* workspace.
* @return {!Blockly.utils.Metrics} Contains size and position metrics of
* mutator dialog's workspace.
* @private
*/
Blockly.Mutator.prototype.getFlyoutMetrics_ = function() {
// The mutator workspace only uses a subset of Blockly.utils.Metrics
// properties as features such as scroll and zoom are unsupported.
var unsupported = 0;
return {
contentHeight: unsupported,
contentWidth: unsupported,
contentTop: unsupported,
contentLeft: unsupported,
viewHeight: this.workspaceHeight_,
viewWidth: this.workspaceWidth_ - this.workspace_.getFlyout().getWidth(),
absoluteTop: 0,
viewTop: unsupported,
viewLeft: unsupported,
absoluteTop: unsupported,
absoluteLeft: this.workspace_.RTL ? 0 :
this.workspace_.getFlyout().getWidth()
};

View File

@@ -15,8 +15,9 @@ goog.provide('Blockly.Options');
goog.require('Blockly.Theme');
goog.require('Blockly.Themes.Classic');
goog.require('Blockly.user.keyMap');
goog.require('Blockly.utils.userAgent');
goog.require('Blockly.utils.Metrics');
goog.require('Blockly.utils.toolbox');
goog.require('Blockly.utils.userAgent');
goog.require('Blockly.Xml');
@@ -185,15 +186,15 @@ Blockly.BlocklyOptions = function() {};
/**
* If set, sets the translation of the workspace to match the scrollbars.
* @param {!Object} xyRatio Contains an x and/or y property which is a float
* between 0 and 1 specifying the degree of scrolling.
* @param {!{x:number,y:number}} xyRatio Contains an x and/or y property which
* is a float between 0 and 1 specifying the degree of scrolling.
* @return {void}
*/
Blockly.Options.prototype.setMetrics;
/**
* Return an object with the metrics required to size the workspace.
* @return {!Object} Contains size and position metrics.
* @return {!Blockly.utils.Metrics} Contains size and position metrics.
*/
Blockly.Options.prototype.getMetrics;

View File

@@ -17,6 +17,7 @@ goog.require('Blockly.Touch');
goog.require('Blockly.utils');
goog.require('Blockly.utils.Coordinate');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.Metrics');
/**
@@ -26,7 +27,7 @@ goog.require('Blockly.utils.dom');
/**
* Class for a pair of scrollbars. Horizontal and vertical.
* @param {!Blockly.Workspace} workspace Workspace to bind the scrollbars to.
* @param {!Blockly.WorkspaceSvg} workspace Workspace to bind the scrollbars to.
* @constructor
*/
Blockly.ScrollbarPair = function(workspace) {
@@ -44,14 +45,14 @@ Blockly.ScrollbarPair = function(workspace) {
},
null);
Blockly.utils.dom.insertAfter(this.corner_, workspace.getBubbleCanvas());
};
/**
* Previously recorded metrics from the workspace.
* @type {Object}
* @private
*/
Blockly.ScrollbarPair.prototype.oldHostMetrics_ = null;
/**
* Previously recorded metrics from the workspace.
* @type {?Blockly.utils.Metrics}
* @private
*/
this.oldHostMetrics_ = null;
};
/**
* Dispose of this pair of scrollbars.
@@ -117,12 +118,12 @@ Blockly.ScrollbarPair.prototype.resize = function() {
if (!this.oldHostMetrics_ ||
this.oldHostMetrics_.viewWidth != hostMetrics.viewWidth ||
this.oldHostMetrics_.absoluteLeft != hostMetrics.absoluteLeft) {
this.corner_.setAttribute('x', this.vScroll.position_.x);
this.corner_.setAttribute('x', this.vScroll.position.x);
}
if (!this.oldHostMetrics_ ||
this.oldHostMetrics_.viewHeight != hostMetrics.viewHeight ||
this.oldHostMetrics_.absoluteTop != hostMetrics.absoluteTop) {
this.corner_.setAttribute('y', this.hScroll.position_.y);
this.corner_.setAttribute('y', this.hScroll.position.y);
}
// Cache the current metrics to potentially short-cut the next resize event.
@@ -144,8 +145,8 @@ Blockly.ScrollbarPair.prototype.set = function(x, y) {
// Combining them speeds up rendering.
var xyRatio = {};
var hHandlePosition = x * this.hScroll.ratio_;
var vHandlePosition = y * this.vScroll.ratio_;
var hHandlePosition = x * this.hScroll.ratio;
var vHandlePosition = y * this.vScroll.ratio;
var hBarLength = this.hScroll.scrollViewSize_;
var vBarLength = this.vScroll.scrollViewSize_;
@@ -179,7 +180,7 @@ Blockly.ScrollbarPair.prototype.getRatio_ = function(handlePosition, viewSize) {
* Class for a pure SVG scrollbar.
* This technique offers a scrollbar that is guaranteed to work, but may not
* look or behave like the system's scrollbars.
* @param {!Blockly.Workspace} workspace Workspace to bind the scrollbar to.
* @param {!Blockly.WorkspaceSvg} workspace Workspace to bind the scrollbar to.
* @param {boolean} horizontal True if horizontal, false if vertical.
* @param {boolean=} opt_pair True if scrollbar is part of a horiz/vert pair.
* @param {string=} opt_class A class to be applied to this scrollbar.
@@ -191,6 +192,12 @@ Blockly.Scrollbar = function(workspace, horizontal, opt_pair, opt_class) {
this.horizontal_ = horizontal;
this.oldHostMetrics_ = null;
/**
* @type {?number}
* @package
*/
this.ratio = null;
this.createDom_(opt_class);
/**
@@ -198,9 +205,9 @@ Blockly.Scrollbar = function(workspace, horizontal, opt_pair, opt_class) {
* to the scrollbar's origin. This is usually relative to the injection div
* origin.
* @type {Blockly.utils.Coordinate}
* @private
* @package
*/
this.position_ = new Blockly.utils.Coordinate(0, 0);
this.position = new Blockly.utils.Coordinate(0, 0);
// Store the thickness in a temp variable for readability.
var scrollbarThickness = Blockly.Scrollbar.scrollbarThickness;
@@ -295,10 +302,10 @@ if (Blockly.Touch.TOUCH_ENABLED) {
}
/**
* @param {Object} first An object containing computed measurements of a
* workspace.
* @param {Object} second Another object containing computed measurements of a
* workspace.
* @param {Blockly.utils.Metrics} first An object containing computed
* measurements of a workspace.
* @param {Blockly.utils.Metrics} second Another object containing computed
* measurements of a workspace.
* @return {boolean} Whether the two sets of metrics are equivalent.
* @private
*/
@@ -392,23 +399,23 @@ Blockly.ScrollbarPair.prototype.setContainerVisible = function(visible) {
* scrollbar's origin. This sets the scrollbar's location within the workspace.
* @param {number} x The new x coordinate.
* @param {number} y The new y coordinate.
* @private
* @package
*/
Blockly.Scrollbar.prototype.setPosition_ = function(x, y) {
this.position_.x = x;
this.position_.y = y;
Blockly.Scrollbar.prototype.setPosition = function(x, y) {
this.position.x = x;
this.position.y = y;
var tempX = this.position_.x + this.origin_.x;
var tempY = this.position_.y + this.origin_.y;
var tempX = this.position.x + this.origin_.x;
var tempY = this.position.y + this.origin_.y;
var transform = 'translate(' + tempX + 'px,' + tempY + 'px)';
Blockly.utils.dom.setCssTransform(this.outerSvg_, transform);
};
/**
* Recalculate the scrollbar's location and its length.
* @param {Object=} opt_metrics A data structure of from the describing all the
* required dimensions. If not provided, it will be fetched from the host
* object.
* @param {Blockly.utils.Metrics=} opt_metrics A data structure of from the
* describing all the required dimensions. If not provided, it will be
* fetched from the host object.
*/
Blockly.Scrollbar.prototype.resize = function(opt_metrics) {
// Determine the location, height and width of the host element.
@@ -450,8 +457,8 @@ Blockly.Scrollbar.prototype.resize = function(opt_metrics) {
/**
* Recalculate a horizontal scrollbar's location and length.
* @param {!Object} hostMetrics A data structure describing all the
* required dimensions, possibly fetched from the host object.
* @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all
* the required dimensions, possibly fetched from the host object.
* @private
*/
Blockly.Scrollbar.prototype.resizeHorizontal_ = function(hostMetrics) {
@@ -463,8 +470,8 @@ Blockly.Scrollbar.prototype.resizeHorizontal_ = function(hostMetrics) {
/**
* Recalculate a horizontal scrollbar's location on the screen and path length.
* This should be called when the layout or size of the window has changed.
* @param {!Object} hostMetrics A data structure describing all the
* required dimensions, possibly fetched from the host object.
* @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all
* the required dimensions, possibly fetched from the host object.
*/
Blockly.Scrollbar.prototype.resizeViewHorizontal = function(hostMetrics) {
var viewSize = hostMetrics.viewWidth - 1;
@@ -482,7 +489,7 @@ Blockly.Scrollbar.prototype.resizeViewHorizontal = function(hostMetrics) {
// Horizontal toolbar should always be just above the bottom of the workspace.
var yCoordinate = hostMetrics.absoluteTop + hostMetrics.viewHeight -
Blockly.Scrollbar.scrollbarThickness - 0.5;
this.setPosition_(xCoordinate, yCoordinate);
this.setPosition(xCoordinate, yCoordinate);
// If the view has been resized, a content resize will also be necessary. The
// reverse is not true.
@@ -492,8 +499,8 @@ Blockly.Scrollbar.prototype.resizeViewHorizontal = function(hostMetrics) {
/**
* Recalculate a horizontal scrollbar's location within its path and length.
* This should be called when the contents of the workspace have changed.
* @param {!Object} hostMetrics A data structure describing all the
* required dimensions, possibly fetched from the host object.
* @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all
* the required dimensions, possibly fetched from the host object.
*/
Blockly.Scrollbar.prototype.resizeContentHorizontal = function(hostMetrics) {
if (!this.pair_) {
@@ -503,24 +510,24 @@ Blockly.Scrollbar.prototype.resizeContentHorizontal = function(hostMetrics) {
this.setVisible(this.scrollViewSize_ < hostMetrics.contentWidth);
}
this.ratio_ = this.scrollViewSize_ / hostMetrics.contentWidth;
if (this.ratio_ == -Infinity || this.ratio_ == Infinity ||
isNaN(this.ratio_)) {
this.ratio_ = 0;
this.ratio = this.scrollViewSize_ / hostMetrics.contentWidth;
if (this.ratio == -Infinity || this.ratio == Infinity ||
isNaN(this.ratio)) {
this.ratio = 0;
}
var handleLength = hostMetrics.viewWidth * this.ratio_;
var handleLength = hostMetrics.viewWidth * this.ratio;
this.setHandleLength_(Math.max(0, handleLength));
var handlePosition = (hostMetrics.viewLeft - hostMetrics.contentLeft) *
this.ratio_;
this.ratio;
this.setHandlePosition(this.constrainHandle_(handlePosition));
};
/**
* Recalculate a vertical scrollbar's location and length.
* @param {!Object} hostMetrics A data structure describing all the
* required dimensions, possibly fetched from the host object.
* @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all
* the required dimensions, possibly fetched from the host object.
* @private
*/
Blockly.Scrollbar.prototype.resizeVertical_ = function(hostMetrics) {
@@ -532,8 +539,8 @@ Blockly.Scrollbar.prototype.resizeVertical_ = function(hostMetrics) {
/**
* Recalculate a vertical scrollbar's location on the screen and path length.
* This should be called when the layout or size of the window has changed.
* @param {!Object} hostMetrics A data structure describing all the
* required dimensions, possibly fetched from the host object.
* @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all
* the required dimensions, possibly fetched from the host object.
*/
Blockly.Scrollbar.prototype.resizeViewVertical = function(hostMetrics) {
var viewSize = hostMetrics.viewHeight - 1;
@@ -549,7 +556,7 @@ Blockly.Scrollbar.prototype.resizeViewVertical = function(hostMetrics) {
Blockly.Scrollbar.scrollbarThickness - 1;
}
var yCoordinate = hostMetrics.absoluteTop + 0.5;
this.setPosition_(xCoordinate, yCoordinate);
this.setPosition(xCoordinate, yCoordinate);
// If the view has been resized, a content resize will also be necessary. The
// reverse is not true.
@@ -559,8 +566,8 @@ Blockly.Scrollbar.prototype.resizeViewVertical = function(hostMetrics) {
/**
* Recalculate a vertical scrollbar's location within its path and length.
* This should be called when the contents of the workspace have changed.
* @param {!Object} hostMetrics A data structure describing all the
* required dimensions, possibly fetched from the host object.
* @param {!Blockly.utils.Metrics} hostMetrics A data structure describing all
* the required dimensions, possibly fetched from the host object.
*/
Blockly.Scrollbar.prototype.resizeContentVertical = function(hostMetrics) {
if (!this.pair_) {
@@ -568,17 +575,17 @@ Blockly.Scrollbar.prototype.resizeContentVertical = function(hostMetrics) {
this.setVisible(this.scrollViewSize_ < hostMetrics.contentHeight);
}
this.ratio_ = this.scrollViewSize_ / hostMetrics.contentHeight;
if (this.ratio_ == -Infinity || this.ratio_ == Infinity ||
isNaN(this.ratio_)) {
this.ratio_ = 0;
this.ratio = this.scrollViewSize_ / hostMetrics.contentHeight;
if (this.ratio == -Infinity || this.ratio == Infinity ||
isNaN(this.ratio)) {
this.ratio = 0;
}
var handleLength = hostMetrics.viewHeight * this.ratio_;
var handleLength = hostMetrics.viewHeight * this.ratio;
this.setHandleLength_(Math.max(0, handleLength));
var handlePosition = (hostMetrics.viewTop - hostMetrics.contentTop) *
this.ratio_;
this.ratio;
this.setHandlePosition(this.constrainHandle_(handlePosition));
};
@@ -844,7 +851,7 @@ Blockly.Scrollbar.prototype.onScroll_ = function() {
* scrollbar handle.
*/
Blockly.Scrollbar.prototype.set = function(value) {
this.setHandlePosition(this.constrainHandle_(value * this.ratio_));
this.setHandlePosition(this.constrainHandle_(value * this.ratio));
this.onScroll_();
};

124
core/utils/metrics.js Normal file
View File

@@ -0,0 +1,124 @@
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview Workspace metrics definitions.
* @author samelh@google.com (Sam El-Husseini)
*/
'use strict';
goog.provide('Blockly.utils.Metrics');
/**
* @record
*/
Blockly.utils.Metrics = function() {};
/**
* Height of the visible portion of the workspace.
* @type {number}
*/
Blockly.utils.Metrics.prototype.viewHeight;
/**
* Width of the visible portion of the workspace.
* @type {number}
*/
Blockly.utils.Metrics.prototype.viewWidth;
/**
* Height of the content.
* @type {number}
*/
Blockly.utils.Metrics.prototype.contentHeight;
/**
* Width of the content.
* @type {number}
*/
Blockly.utils.Metrics.prototype.contentWidth;
/**
* Top-edge of the visible portion of the workspace, relative to the workspace
* origin.
* @type {number}
*/
Blockly.utils.Metrics.prototype.viewTop;
/**
* Left-edge of the visible portion of the workspace, relative to the workspace
* origin.
* @type {number}
*/
Blockly.utils.Metrics.prototype.viewLeft;
/**
* Top-edge of the content, relative to the workspace origin.
* @type {number}
*/
Blockly.utils.Metrics.prototype.contentTop;
/**
* Left-edge of the content relative to the workspace origin.
* @type {number}
*/
Blockly.utils.Metrics.prototype.contentLeft;
/**
* Top-edge of the visible portion of the workspace, relative to the blocklyDiv.
* @type {number}
*/
Blockly.utils.Metrics.prototype.absoluteTop;
/**
* Left-edge of the visible portion of the workspace, relative to the
* blocklyDiv.
* @type {number}
*/
Blockly.utils.Metrics.prototype.absoluteLeft;
/**
* Height of the Blockly div (the view + the toolbox, simple of otherwise).
* @type {number|undefined}
*/
Blockly.utils.Metrics.prototype.svgHeight;
/**
* Width of the Blockly div (the view + the toolbox, simple or otherwise).
* @type {number|undefined}
*/
Blockly.utils.Metrics.prototype.svgWidth;
/**
* Width of the toolbox, if it exists. Otherwise zero.
* @type {number|undefined}
*/
Blockly.utils.Metrics.prototype.toolboxWidth;
/**
* Height of the toolbox, if it exists. Otherwise zero.
* @type {number|undefined}
*/
Blockly.utils.Metrics.prototype.toolboxHeight;
/**
* Top, bottom, left or right. Use TOOLBOX_AT constants to compare.
* @type {number|undefined}
*/
Blockly.utils.Metrics.prototype.toolboxPosition;
/**
* Width of the flyout if it is always open. Otherwise zero.
* @type {number|undefined}
*/
Blockly.utils.Metrics.prototype.flyoutWidth;
/**
* Height of the flyout if it is always open. Otherwise zero.
* @type {number|undefined}
*/
Blockly.utils.Metrics.prototype.flyoutHeight;

View File

@@ -30,6 +30,7 @@ goog.require('Blockly.TouchGesture');
goog.require('Blockly.utils');
goog.require('Blockly.utils.Coordinate');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.Metrics');
goog.require('Blockly.utils.object');
goog.require('Blockly.utils.Rect');
goog.require('Blockly.utils.toolbox');
@@ -58,10 +59,10 @@ goog.requireType('Blockly.IBoundedElement');
Blockly.WorkspaceSvg = function(options,
opt_blockDragSurface, opt_wsDragSurface) {
Blockly.WorkspaceSvg.superClass_.constructor.call(this, options);
/** @type {function():!Object} */
/** @type {function():!Blockly.utils.Metrics} */
this.getMetrics =
options.getMetrics || Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_;
/** @type {function(!Object):void} */
/** @type {function(!{x:number, y:number}):void} */
this.setMetrics =
options.setMetrics || Blockly.WorkspaceSvg.setTopLevelWorkspaceMetrics_;
@@ -1967,8 +1968,8 @@ Blockly.WorkspaceSvg.prototype.zoomCenter = function(type) {
// when the size of the flyout increases) you need the center of the
// *blockly div* to stay in the same pixel-position.
// Note: This only works because of how scrollCenter positions blocks.
var x = metrics.svgWidth / 2;
var y = metrics.svgHeight / 2;
var x = metrics.svgWidth ? metrics.svgWidth / 2 : 0;
var y = metrics.svgHeight ? metrics.svgHeight / 2 : 0;
} else {
var x = (metrics.viewWidth / 2) + metrics.absoluteLeft;
var y = (metrics.viewHeight / 2) + metrics.absoluteTop;
@@ -2217,11 +2218,10 @@ Blockly.WorkspaceSvg.prototype.scroll = function(x, y) {
// the content's top-left to the view's top-left, matching the
// directionality of the scrollbars.
// TODO (#2299): Change these to not use the internal ratio_ property.
this.scrollbar.hScroll.setHandlePosition(-(x + metrics.contentLeft) *
this.scrollbar.hScroll.ratio_);
this.scrollbar.hScroll.ratio);
this.scrollbar.vScroll.setHandlePosition(-(y + metrics.contentTop) *
this.scrollbar.vScroll.ratio_);
this.scrollbar.vScroll.ratio);
}
// We have to shift the translation so that when the canvas is at 0, 0 the
// workspace origin is not underneath the toolbox.
@@ -2235,8 +2235,8 @@ Blockly.WorkspaceSvg.prototype.scroll = function(x, y) {
* @param {Blockly.Toolbox|Blockly.Flyout} elem The element to get the
* dimensions of, or null. It should be a toolbox or flyout, and should
* implement getWidth() and getHeight().
* @return {!Object} An object containing width and height attributes, which
* will both be zero if elem did not exist.
* @return {!Blockly.utils.Size} An object containing width and height
* attributes, which will both be zero if elem did not exist.
* @private
*/
Blockly.WorkspaceSvg.getDimensionsPx_ = function(elem) {
@@ -2246,10 +2246,7 @@ Blockly.WorkspaceSvg.getDimensionsPx_ = function(elem) {
width = elem.getWidth();
height = elem.getHeight();
}
return {
width: width,
height: height
};
return new Blockly.utils.Size(width, height);
};
/**
@@ -2370,8 +2367,8 @@ Blockly.WorkspaceSvg.getContentDimensionsBounded_ = function(ws, svgSize) {
* .flyoutHeight: Height of the flyout if it is always open. Otherwise zero.
* .toolboxPosition: Top, bottom, left or right. Use TOOLBOX_AT constants to
* compare.
* @return {!Object} Contains size and position metrics of a top level
* workspace.
* @return {!Blockly.utils.Metrics} Contains size and position metrics of a top
* level workspace.
* @private
* @this {Blockly.WorkspaceSvg}
*/
@@ -2441,11 +2438,10 @@ Blockly.WorkspaceSvg.getTopLevelWorkspaceMetrics_ = function() {
toolboxWidth: toolboxDimensions.width,
toolboxHeight: toolboxDimensions.height,
toolboxPosition: this.toolboxPosition,
flyoutWidth: flyoutDimensions.width,
flyoutHeight: flyoutDimensions.height,
toolboxPosition: this.toolboxPosition
flyoutHeight: flyoutDimensions.height
};
return metrics;
};

View File

@@ -35,7 +35,7 @@ Minimap.init = function(workspace, minimap) {
// New code starts from here.
// Get the absolutePosition.
var absolutePosition = (this.handlePosition_ / this.ratio_);
var absolutePosition = (this.handlePosition_ / this.ratio);
// Firing the scroll change listener.
Minimap.onScrollChange(absolutePosition, this.horizontal_);
@@ -50,7 +50,7 @@ Minimap.init = function(workspace, minimap) {
// New code starts from here.
// Get the absolutePosition.
var absolutePosition = (this.handlePosition_ / this.ratio_);
var absolutePosition = (this.handlePosition_ / this.ratio);
// Firing the scroll change listener.
Minimap.onScrollChange(absolutePosition, this.horizontal_);

View File

@@ -28,7 +28,6 @@ function typings() {
"core/",
"core/components",
"core/components/tree",
"core/components/menu",
"core/keyboard_nav",
"core/renderers/common",
"core/renderers/measurables",
@@ -66,9 +65,9 @@ function typings() {
'typings/templates/blockly-header.template',
'typings/templates/blockly-interfaces.template',
`${tmpDir}/core/**`,
`${tmpDir}/core/interfaces/**`,
`${tmpDir}/core/components/**`,
`${tmpDir}/core/components/tree/**`,
`${tmpDir}/core/components/menu/**`,
`${tmpDir}/core/keyboard_nav/**`,
`${tmpDir}/core/renderers/common/**`,
`${tmpDir}/core/renderers/measurables/**`,

View File

@@ -51,19 +51,6 @@ declare module Blockly {
startHats?: boolean;
}
interface Metrics {
absoluteLeft: number;
absoluteTop: number;
contentHeight: number;
contentLeft: number;
contentTop: number;
contentWidth: number;
viewHeight: number;
viewLeft: number;
viewTop: number;
viewWidth: number;
}
/**
* Set the Blockly locale.
* Note: this method is only available in the npm release of Blockly.
@@ -72,3 +59,25 @@ declare module Blockly {
*/
function setLocale(msg: {[key: string]: string;}): void;
}
declare module Blockly.utils {
interface Metrics {
viewHeight: number;
viewWidth: number;
contentHeight: number;
contentWidth: number;
viewTop: number;
viewLeft: number;
contentTop: number;
contentLeft: number;
absoluteTop: number;
absoluteLeft: number;
svgHeight?: number;
svgWidth?: number;
toolboxWidth?: number;
toolboxHeight?: number;
flyoutWidth?: number;
flyoutHeight?: number;
toolboxPosition?: number;
}
}