mirror of
https://github.com/google/blockly.git
synced 2026-01-10 02:17:09 +01:00
Adding Positionable interface (#4669)
* Adding IPositionable interface.
This commit is contained in:
@@ -93,6 +93,7 @@ goog.addDependency('../../core/interfaces/i_deletearea.js', ['Blockly.IDeleteAre
|
||||
goog.addDependency('../../core/interfaces/i_flyout.js', ['Blockly.IFlyout'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_metrics_manager.js', ['Blockly.IMetricsManager'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_movable.js', ['Blockly.IMovable'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_positionable.js', ['Blockly.IPositionable'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_registrable.js', ['Blockly.IRegistrable'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_registrable_field.js', ['Blockly.IRegistrableField'], [], {});
|
||||
goog.addDependency('../../core/interfaces/i_selectable.js', ['Blockly.ISelectable'], [], {});
|
||||
@@ -174,7 +175,7 @@ goog.addDependency('../../core/toolbox/toolbox_item.js', ['Blockly.ToolboxItem']
|
||||
goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.browserEvents', 'Blockly.utils.string'], {});
|
||||
goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.constants', 'Blockly.utils', 'Blockly.utils.global', 'Blockly.utils.string'], {});
|
||||
goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.Events', 'Blockly.Events.TrashcanOpen', 'Blockly.Scrollbar', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.Events', 'Blockly.Events.TrashcanOpen', 'Blockly.IPositionable', 'Blockly.Scrollbar', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/utils.js', ['Blockly.utils'], ['Blockly.Msg', 'Blockly.constants', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.colour', 'Blockly.utils.global', 'Blockly.utils.string', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {});
|
||||
goog.addDependency('../../core/utils/aria.js', ['Blockly.utils.aria'], [], {});
|
||||
goog.addDependency('../../core/utils/colour.js', ['Blockly.utils.colour'], [], {});
|
||||
@@ -209,9 +210,9 @@ goog.addDependency('../../core/workspace_comment_render_svg.js', ['Blockly.Works
|
||||
goog.addDependency('../../core/workspace_comment_svg.js', ['Blockly.WorkspaceCommentSvg'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove', 'Blockly.Events.Selected', 'Blockly.WorkspaceComment', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object'], {});
|
||||
goog.addDependency('../../core/workspace_drag_surface_svg.js', ['Blockly.WorkspaceDragSurfaceSvg'], ['Blockly.utils', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {});
|
||||
goog.addDependency('../../core/workspace_dragger.js', ['Blockly.WorkspaceDragger'], ['Blockly.utils.Coordinate'], {});
|
||||
goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ConnectionDB', 'Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.ThemeChange', 'Blockly.Events.ViewportChange', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.MarkerManager', 'Blockly.MetricsManager', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ThemeManager', 'Blockly.Themes.Classic', 'Blockly.TouchGesture', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ConnectionDB', 'Blockly.ContextMenu', 'Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.ThemeChange', 'Blockly.Events.ViewportChange', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.MarkerManager', 'Blockly.MetricsManager', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ThemeManager', 'Blockly.Themes.Classic', 'Blockly.TouchGesture', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {});
|
||||
goog.addDependency('../../core/xml.js', ['Blockly.Xml'], ['Blockly.Events', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.xml'], {});
|
||||
goog.addDependency('../../core/zoom_controls.js', ['Blockly.ZoomControls'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.Click', 'Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es5'});
|
||||
goog.addDependency('../../core/zoom_controls.js', ['Blockly.ZoomControls'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.Click', 'Blockly.IPositionable', 'Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es5'});
|
||||
goog.addDependency("base.js", [], []);
|
||||
|
||||
// Load Blockly.
|
||||
|
||||
43
core/interfaces/i_positionable.js
Normal file
43
core/interfaces/i_positionable.js
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2021 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview The interface for a positionable ui element.
|
||||
* @author kozbial@google.com (Monica Kozbial)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.IPositionable');
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a component that is positioned on top of the workspace.
|
||||
* @interface
|
||||
*/
|
||||
Blockly.IPositionable = function() {};
|
||||
|
||||
/**
|
||||
* Positions the element. Called when the window is resized.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion} viewMetrics The workspace
|
||||
* viewMetrics.
|
||||
* @param {!Blockly.MetricsManager.AbsoluteMetrics} absoluteMetrics The absolute
|
||||
* metrics for the workspace.
|
||||
* @param {!Blockly.MetricsManager.ToolboxMetrics} toolboxMetrics The toolbox
|
||||
* metrics for the workspace.
|
||||
* @param {!Array<Blockly.utils.Rect>} savedPositions List of rectangles that
|
||||
* are already on the workspace.
|
||||
*/
|
||||
Blockly.IPositionable.prototype.position;
|
||||
|
||||
/**
|
||||
* Returns the bounding rectangle of the UI element in pixel units relative to
|
||||
* the Blockly injection div.
|
||||
* @returns {!Blockly.utils.Rect} The plugin’s bounding box.
|
||||
*/
|
||||
Blockly.IPositionable.prototype.getBoundingRectangle;
|
||||
|
||||
|
||||
@@ -16,8 +16,10 @@ goog.require('Blockly.browserEvents');
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.TrashcanOpen');
|
||||
goog.require('Blockly.IPositionable');
|
||||
goog.require('Blockly.Scrollbar');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.math');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
@@ -34,6 +36,7 @@ goog.requireType('Blockly.WorkspaceSvg');
|
||||
* @param {!Blockly.WorkspaceSvg} workspace The workspace to sit in.
|
||||
* @constructor
|
||||
* @implements {Blockly.IDeleteArea}
|
||||
* @implements {Blockly.IPositionable}
|
||||
*/
|
||||
Blockly.Trashcan = function(workspace) {
|
||||
/**
|
||||
@@ -431,38 +434,74 @@ Blockly.Trashcan.prototype.emptyContents = function() {
|
||||
* Position the trashcan.
|
||||
* It is positioned in the opposite corner to the corner the
|
||||
* categories/toolbox starts at.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion} viewMetrics The workspace
|
||||
* viewMetrics.
|
||||
* @param {!Blockly.MetricsManager.AbsoluteMetrics} absoluteMetrics The absolute
|
||||
* metrics for the workspace.
|
||||
* @param {!Blockly.MetricsManager.ToolboxMetrics} toolboxMetrics The toolbox
|
||||
* metrics for the workspace.
|
||||
* @param {!Array<Blockly.utils.Rect>} savedPositions List of rectangles that
|
||||
* are already on the workspace.
|
||||
*/
|
||||
Blockly.Trashcan.prototype.position = function() {
|
||||
Blockly.Trashcan.prototype.position = function(
|
||||
viewMetrics, absoluteMetrics, toolboxMetrics, savedPositions) {
|
||||
// Not yet initialized.
|
||||
if (!this.verticalSpacing_) {
|
||||
return;
|
||||
}
|
||||
var metrics = this.workspace_.getMetrics();
|
||||
if (!metrics) {
|
||||
// There are no metrics available (workspace is probably not visible).
|
||||
return;
|
||||
}
|
||||
if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_LEFT ||
|
||||
|
||||
if (toolboxMetrics.position == Blockly.TOOLBOX_AT_LEFT ||
|
||||
(this.workspace_.horizontalLayout && !this.workspace_.RTL)) {
|
||||
// Toolbox starts in the left corner.
|
||||
this.left_ = metrics.viewWidth + metrics.absoluteLeft -
|
||||
this.left_ = viewMetrics.width + absoluteMetrics.left -
|
||||
this.WIDTH_ - this.MARGIN_SIDE_ - Blockly.Scrollbar.scrollbarThickness;
|
||||
} else {
|
||||
// Toolbox starts in the right corner.
|
||||
this.left_ = this.MARGIN_SIDE_ + Blockly.Scrollbar.scrollbarThickness;
|
||||
}
|
||||
|
||||
if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) {
|
||||
this.top_ = this.verticalSpacing_;
|
||||
} else {
|
||||
this.top_ = metrics.viewHeight + metrics.absoluteTop -
|
||||
(this.BODY_HEIGHT_ + this.LID_HEIGHT_) - this.verticalSpacing_;
|
||||
var height = this.BODY_HEIGHT_ + this.LID_HEIGHT_;
|
||||
// Upper corner placement
|
||||
var minTop = this.top_ = this.verticalSpacing_;
|
||||
// Bottom corner placement
|
||||
var maxTop = viewMetrics.height + absoluteMetrics.top - height -
|
||||
this.verticalSpacing_;
|
||||
var placeBottom = toolboxMetrics.position !== Blockly.TOOLBOX_AT_BOTTOM;
|
||||
this.top_ = placeBottom ? maxTop : minTop;
|
||||
|
||||
// Check for collision and bump if needed.
|
||||
var boundingRect = this.getBoundingRectangle();
|
||||
for (var i = 0, otherEl; (otherEl = savedPositions[i]); i++) {
|
||||
if (boundingRect.intersects(otherEl)) {
|
||||
if (placeBottom) {
|
||||
// Bump up
|
||||
this.top_ = otherEl.top - height - this.MARGIN_BOTTOM_;
|
||||
} else {
|
||||
this.top_ = otherEl.bottom + this.MARGIN_BOTTOM_;
|
||||
}
|
||||
// Recheck other savedPositions
|
||||
boundingRect = this.getBoundingRectangle();
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
// Clamp top value within valid range.
|
||||
this.top_ = Blockly.utils.math.clamp(minTop, this.top_, maxTop);
|
||||
|
||||
this.svgGroup_.setAttribute('transform',
|
||||
'translate(' + this.left_ + ',' + this.top_ + ')');
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the bounding rectangle of the UI element in pixel units relative to
|
||||
* the Blockly injection div.
|
||||
* @returns {!Blockly.utils.Rect} The plugin’s bounding box.
|
||||
*/
|
||||
Blockly.Trashcan.prototype.getBoundingRectangle = function() {
|
||||
var bottom = this.top_ + this.BODY_HEIGHT_ + this.LID_HEIGHT_;
|
||||
var right = this.left_ + this.WIDTH_;
|
||||
return new Blockly.utils.Rect(this.top_, bottom, this.left_, right);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the deletion rectangle for this trash can.
|
||||
* @return {Blockly.utils.Rect} Rectangle in which to delete.
|
||||
|
||||
@@ -52,3 +52,15 @@ Blockly.utils.Rect = function(top, bottom, left, right) {
|
||||
Blockly.utils.Rect.prototype.contains = function(x, y) {
|
||||
return x >= this.left && x <= this.right && y >= this.top && y <= this.bottom;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests whether this rectangle intersects the provided rectangle.
|
||||
* Assumes that the coordinate system increases going down and left.
|
||||
* @param {Blockly.utils.Rect} other The other rectangle to check for
|
||||
* intersection with.
|
||||
* @return {boolean} Whether this rectangle intersects the provided rectangle.
|
||||
*/
|
||||
Blockly.utils.Rect.prototype.intersects = function(other) {
|
||||
return !(this.left > other.right || this.right < other.left ||
|
||||
this.top > other.bottom || this.bottom < other.top);
|
||||
};
|
||||
|
||||
@@ -55,6 +55,7 @@ goog.requireType('Blockly.IASTNodeLocationSvg');
|
||||
goog.requireType('Blockly.IBoundedElement');
|
||||
goog.requireType('Blockly.IFlyout');
|
||||
goog.requireType('Blockly.IMetricsManager');
|
||||
goog.requireType('Blockly.IPositionable');
|
||||
goog.requireType('Blockly.IToolbox');
|
||||
goog.requireType('Blockly.Marker');
|
||||
goog.requireType('Blockly.ScrollbarPair');
|
||||
@@ -1077,12 +1078,27 @@ Blockly.WorkspaceSvg.prototype.resize = function() {
|
||||
if (this.flyout_) {
|
||||
this.flyout_.position();
|
||||
}
|
||||
/** @type {Array<Blockly.IPositionable>} */
|
||||
var positionableEls = [];
|
||||
if (this.trashcan) {
|
||||
this.trashcan.position();
|
||||
positionableEls.push(this.trashcan);
|
||||
}
|
||||
if (this.zoomControls_) {
|
||||
this.zoomControls_.position();
|
||||
positionableEls.push(this.zoomControls_);
|
||||
}
|
||||
if (positionableEls) {
|
||||
var metricsManager = this.getMetricsManager();
|
||||
var viewMetrics = metricsManager.getViewMetrics();
|
||||
var absoluteMetrics = metricsManager.getAbsoluteMetrics();
|
||||
var toolboxMetrics = metricsManager.getToolboxMetrics();
|
||||
var savedPositions = [];
|
||||
for (var i = 0, uiElement; (uiElement = positionableEls[i]); i++) {
|
||||
uiElement.position(
|
||||
viewMetrics, absoluteMetrics, toolboxMetrics, savedPositions);
|
||||
savedPositions.push(uiElement.getBoundingRectangle());
|
||||
}
|
||||
}
|
||||
|
||||
if (this.scrollbar) {
|
||||
this.scrollbar.resize();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@ goog.require('Blockly.Events.Click');
|
||||
goog.require('Blockly.Scrollbar');
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
goog.require('Blockly.utils.Svg');
|
||||
goog.require('Blockly.IPositionable');
|
||||
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
@@ -29,6 +31,7 @@ goog.requireType('Blockly.WorkspaceSvg');
|
||||
* Class for a zoom controls.
|
||||
* @param {!Blockly.WorkspaceSvg} workspace The workspace to sit in.
|
||||
* @constructor
|
||||
* @implements {Blockly.IPositionable}
|
||||
*/
|
||||
Blockly.ZoomControls = function(workspace) {
|
||||
/**
|
||||
@@ -194,44 +197,82 @@ Blockly.ZoomControls.prototype.dispose = function() {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the bounding rectangle of the UI element in pixel units relative to
|
||||
* the Blockly injection div.
|
||||
* @returns {!Blockly.utils.Rect} The plugin’s bounding box.
|
||||
*/
|
||||
Blockly.ZoomControls.prototype.getBoundingRectangle = function() {
|
||||
var bottom = this.top_ + this.HEIGHT_;
|
||||
var right = this.left_ + this.WIDTH_;
|
||||
return new Blockly.utils.Rect(this.top_, bottom, this.left_, right);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Position the zoom controls.
|
||||
* It is positioned in the opposite corner to the corner the
|
||||
* categories/toolbox starts at.
|
||||
* @param {!Blockly.MetricsManager.ContainerRegion} viewMetrics The workspace
|
||||
* viewMetrics.
|
||||
* @param {!Blockly.MetricsManager.AbsoluteMetrics} absoluteMetrics The absolute
|
||||
* metrics for the workspace.
|
||||
* @param {!Blockly.MetricsManager.ToolboxMetrics} toolboxMetrics The toolbox
|
||||
* metrics for the workspace.
|
||||
* @param {!Array<Blockly.utils.Rect>} savedPositions List of rectangles that
|
||||
* are already on the workspace.
|
||||
*/
|
||||
Blockly.ZoomControls.prototype.position = function() {
|
||||
Blockly.ZoomControls.prototype.position = function(
|
||||
viewMetrics, absoluteMetrics, toolboxMetrics, savedPositions) {
|
||||
// Not yet initialized.
|
||||
if (!this.verticalSpacing_) {
|
||||
return;
|
||||
}
|
||||
var metrics = this.workspace_.getMetrics();
|
||||
if (!metrics) {
|
||||
// There are no metrics available (workspace is probably not visible).
|
||||
return;
|
||||
}
|
||||
if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_LEFT ||
|
||||
if (toolboxMetrics.position == Blockly.TOOLBOX_AT_LEFT ||
|
||||
(this.workspace_.horizontalLayout && !this.workspace_.RTL)) {
|
||||
// Toolbox starts in the left corner.
|
||||
this.left_ = metrics.viewWidth + metrics.absoluteLeft -
|
||||
this.left_ = viewMetrics.width + absoluteMetrics.left -
|
||||
this.WIDTH_ - this.MARGIN_SIDE_ - Blockly.Scrollbar.scrollbarThickness;
|
||||
} else {
|
||||
// Toolbox starts in the right corner.
|
||||
this.left_ = this.MARGIN_SIDE_ + Blockly.Scrollbar.scrollbarThickness;
|
||||
}
|
||||
|
||||
if (metrics.toolboxPosition == Blockly.TOOLBOX_AT_BOTTOM) {
|
||||
this.top_ = this.verticalSpacing_;
|
||||
// Upper corner placement
|
||||
var minTop = this.top_ = this.verticalSpacing_;
|
||||
// Bottom corner placement
|
||||
var maxTop = viewMetrics.height + absoluteMetrics.top -
|
||||
this.HEIGHT_ - this.verticalSpacing_;
|
||||
var placeBottom = toolboxMetrics.position !== Blockly.TOOLBOX_AT_BOTTOM;
|
||||
this.top_ = placeBottom ? maxTop : minTop;
|
||||
if (placeBottom) {
|
||||
this.zoomInGroup_.setAttribute('transform', 'translate(0, 43)');
|
||||
this.zoomOutGroup_.setAttribute('transform', 'translate(0, 77)');
|
||||
} else {
|
||||
this.zoomInGroup_.setAttribute('transform', 'translate(0, 34)');
|
||||
if (this.zoomResetGroup_) {
|
||||
this.zoomResetGroup_.setAttribute('transform', 'translate(0, 77)');
|
||||
}
|
||||
} else {
|
||||
this.top_ = metrics.viewHeight + metrics.absoluteTop -
|
||||
this.HEIGHT_ - this.verticalSpacing_;
|
||||
this.zoomInGroup_.setAttribute('transform', 'translate(0, 43)');
|
||||
this.zoomOutGroup_.setAttribute('transform', 'translate(0, 77)');
|
||||
}
|
||||
|
||||
// Check for collision and bump if needed.
|
||||
var boundingRect = this.getBoundingRectangle();
|
||||
for (var i = 0, otherEl; (otherEl = savedPositions[i]); i++) {
|
||||
if (boundingRect.intersects(otherEl)) {
|
||||
if (placeBottom) {
|
||||
// Bump up
|
||||
this.top_ = otherEl.top - this.HEIGHT_ - this.MARGIN_BOTTOM_;
|
||||
} else {
|
||||
this.top_ = otherEl.bottom + this.MARGIN_BOTTOM_;
|
||||
}
|
||||
// Recheck other savedPositions
|
||||
boundingRect = this.getBoundingRectangle();
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
// Clamp top value within valid range.
|
||||
this.top_ = Blockly.utils.math.clamp(minTop, this.top_, maxTop);
|
||||
|
||||
this.svgGroup_.setAttribute('transform',
|
||||
'translate(' + this.left_ + ',' + this.top_ + ')');
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user