From 80d8d55315c0bc1ba5a106156269a622dee87f5b Mon Sep 17 00:00:00 2001 From: picklesrus Date: Wed, 3 Feb 2016 15:28:29 -0800 Subject: [PATCH] Cache delete area rectangle bounds in the on mouse down event to avoid getting it for every mouse move event. The delete areas won't change while the user is dragging blocks around. Also switch calculations for delete area inclusion to be done in client coordinates so we don't have to convert to svg coordinates on every mouse move event. This should speed up dragging blocks a bunch. --- core/block_svg.js | 2 +- core/flyout.js | 17 ++++++++--------- core/toolbox.js | 15 ++++++++------- core/trashcan.js | 16 ++++++++-------- core/workspace_svg.js | 9 ++++----- 5 files changed, 29 insertions(+), 30 deletions(-) diff --git a/core/block_svg.js b/core/block_svg.js index e7c12ae43..66fb6a640 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -455,6 +455,7 @@ Blockly.BlockSvg.prototype.onMouseDown_ = function(e) { Blockly.terminateDrag_(); this.select(); Blockly.hideChaff(); + this.workspace.recordDeleteAreas(); if (Blockly.isRightButton(e)) { // Right-click. this.showContextMenu_(e); @@ -761,7 +762,6 @@ Blockly.BlockSvg.prototype.onMouseMove_ = function(e) { this.disconnectUiEffect(); } this.setDragging_(true); - this.workspace.recordDeleteAreas(); } } if (Blockly.dragMode_ == 2) { diff --git a/core/flyout.js b/core/flyout.js index 0e87d3914..0d4d4c200 100644 --- a/core/flyout.js +++ b/core/flyout.js @@ -694,20 +694,19 @@ Blockly.Flyout.prototype.filterForCapacity_ = function() { * Return the deletion rectangle for this flyout. * @return {goog.math.Rect} Rectangle in which to delete. */ -Blockly.Flyout.prototype.getRect = function() { +Blockly.Flyout.prototype.getClientRect = function() { + var flyoutRect = this.svgGroup_.getBoundingClientRect(); // BIG_NUM is offscreen padding so that blocks dragged beyond the shown flyout // area are still deleted. Must be larger than the largest screen size, // but be smaller than half Number.MAX_SAFE_INTEGER (not available on IE). var BIG_NUM = 1000000000; - var mainWorkspace = Blockly.mainWorkspace; - var x = Blockly.getSvgXY_(this.svgGroup_, mainWorkspace).x; - if (!this.RTL) { - x -= BIG_NUM; + if (this.RTL) { + var width = flyoutRect.left + flyoutRect.width + BIG_NUM; + return new goog.math.Rect(flyoutRect.left, -BIG_NUM, width, BIG_NUM * 2); } - // Fix scale if nested in zoomed workspace. - var scale = this.targetWorkspace_ == mainWorkspace ? 1 : mainWorkspace.scale; - return new goog.math.Rect(x, -BIG_NUM, - BIG_NUM + this.width_ * scale, BIG_NUM * 2); + // LTR + var width = BIG_NUM + flyoutRect.width + flyoutRect.left; + return new goog.math.Rect(-BIG_NUM, -BIG_NUM, width, BIG_NUM * 2); }; /** diff --git a/core/toolbox.js b/core/toolbox.js index 227e8e0c4..1e67dd382 100644 --- a/core/toolbox.js +++ b/core/toolbox.js @@ -287,20 +287,21 @@ Blockly.Toolbox.prototype.clearSelection = function() { * Return the deletion rectangle for this toolbar. * @return {goog.math.Rect} Rectangle in which to delete. */ -Blockly.Toolbox.prototype.getRect = function() { +Blockly.Toolbox.prototype.getClientRect = function() { // BIG_NUM is offscreen padding so that blocks dragged beyond the toolbox // area are still deleted. Must be smaller than Infinity, but larger than // the largest screen size. var BIG_NUM = 10000000; // Assumes that the toolbox is on the SVG edge. If this changes // (e.g. toolboxes in mutators) then this code will need to be more complex. + var toolboxRect = this.HtmlDiv.getBoundingClientRect(); if (this.workspace_.RTL) { - var svgSize = Blockly.svgSize(this.workspace_.getParentSvg()); - var x = svgSize.width - this.width; - } else { - var x = -BIG_NUM; - } - return new goog.math.Rect(x, -BIG_NUM, BIG_NUM + this.width, 2 * BIG_NUM); + var width = toolboxRect.left + toolboxRect.width + BIG_NUM; + return new goog.math.Rect(toolboxRect.left, -BIG_NUM, width, BIG_NUM * 2); + } + // LTR + var width = BIG_NUM + toolboxRect.width + toolboxRect.left; + return new goog.math.Rect(-BIG_NUM, -BIG_NUM, width, BIG_NUM * 2); }; // Extending Closure's Tree UI. diff --git a/core/trashcan.js b/core/trashcan.js index b7a0781d8..ec59d092a 100644 --- a/core/trashcan.js +++ b/core/trashcan.js @@ -81,7 +81,7 @@ Blockly.Trashcan.prototype.MARGIN_SIDE_ = 20; * @type {number} * @private */ -Blockly.Trashcan.prototype.MARGIN_HOTSPOT_ = 25; +Blockly.Trashcan.prototype.MARGIN_HOTSPOT_ = 10; /** * Current open/close state of the lid. @@ -234,13 +234,13 @@ Blockly.Trashcan.prototype.position = function() { * Return the deletion rectangle for this trash can. * @return {goog.math.Rect} Rectangle in which to delete. */ -Blockly.Trashcan.prototype.getRect = function() { - var trashXY = Blockly.getSvgXY_(this.svgGroup_, this.workspace_); - return new goog.math.Rect( - trashXY.x - this.MARGIN_HOTSPOT_, - trashXY.y - this.MARGIN_HOTSPOT_, - this.WIDTH_ + 2 * this.MARGIN_HOTSPOT_, - this.BODY_HEIGHT_ + this.LID_HEIGHT_ + 2 * this.MARGIN_HOTSPOT_); +Blockly.Trashcan.prototype.getClientRect = function() { + var trashRect = this.svgGroup_.getBoundingClientRect(); + return new goog.math.Rect(trashRect.left - this.MARGIN_HOTSPOT_, + trashRect.top - this.MARGIN_HOTSPOT_, + trashRect.width + 2 * this.MARGIN_HOTSPOT_, + trashRect.height + 2 * this.MARGIN_HOTSPOT_); + }; /** diff --git a/core/workspace_svg.js b/core/workspace_svg.js index 7d03b44ed..b2f18d8d7 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -525,14 +525,14 @@ Blockly.WorkspaceSvg.prototype.paste = function(xmlBlock) { */ Blockly.WorkspaceSvg.prototype.recordDeleteAreas = function() { if (this.trashcan) { - this.deleteAreaTrash_ = this.trashcan.getRect(); + this.deleteAreaTrash_ = this.trashcan.getClientRect(); } else { this.deleteAreaTrash_ = null; } if (this.flyout_) { - this.deleteAreaToolbox_ = this.flyout_.getRect(); + this.deleteAreaToolbox_ = this.flyout_.getClientRect(); } else if (this.toolbox_) { - this.deleteAreaToolbox_ = this.toolbox_.getRect(); + this.deleteAreaToolbox_ = this.toolbox_.getClientRect(); } else { this.deleteAreaToolbox_ = null; } @@ -546,8 +546,7 @@ Blockly.WorkspaceSvg.prototype.recordDeleteAreas = function() { */ Blockly.WorkspaceSvg.prototype.isDeleteArea = function(e) { var isDelete = false; - var mouseXY = Blockly.mouseToSvg(e, Blockly.mainWorkspace.getParentSvg()); - var xy = new goog.math.Coordinate(mouseXY.x, mouseXY.y); + var xy = new goog.math.Coordinate(e.clientX, e.clientY); if (this.deleteAreaTrash_) { if (this.deleteAreaTrash_.contains(xy)) { this.trashcan.setOpen_(true);