mirror of
https://github.com/google/blockly.git
synced 2026-01-31 12:40:09 +01:00
Block highlighting
* Separate block selection (editing) from highlighting (execution). * Remove add/removeDragging functions. They clutter the API for no reason.
This commit is contained in:
@@ -830,12 +830,14 @@ Blockly.BlockSvg.prototype.setDragging_ = function(adding) {
|
||||
var group = this.getSvgRoot();
|
||||
group.translate_ = '';
|
||||
group.skew_ = '';
|
||||
this.addDragging();
|
||||
Blockly.draggingConnections_ =
|
||||
Blockly.draggingConnections_.concat(this.getConnections_(true));
|
||||
Blockly.addClass_(/** @type {!Element} */ (this.svgGroup_),
|
||||
'blocklyDragging');
|
||||
} else {
|
||||
this.removeDragging();
|
||||
Blockly.draggingConnections_ = [];
|
||||
Blockly.removeClass_(/** @type {!Element} */ (this.svgGroup_),
|
||||
'blocklyDragging');
|
||||
}
|
||||
// Recurse through all blocks attached under this one.
|
||||
for (var i = 0; i < this.childBlocks_.length; i++) {
|
||||
@@ -1430,6 +1432,21 @@ Blockly.BlockSvg.prototype.setDisabled = function(disabled) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set whether the block is highlighted or not.
|
||||
* @param {boolean} highlighted True if highlighted.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setHighlighted = function(highlighted) {
|
||||
if (highlighted) {
|
||||
this.svgPath_.setAttribute('filter',
|
||||
'url(#' + this.workspace.options.embossFilterId + ')');
|
||||
this.svgPathLight_.style.display = 'none';
|
||||
} else {
|
||||
this.svgPath_.removeAttribute('filter');
|
||||
this.svgPathLight_.style.display = 'block';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Select this block. Highlight it visually.
|
||||
*/
|
||||
@@ -1453,23 +1470,6 @@ Blockly.BlockSvg.prototype.removeSelect = function() {
|
||||
'blocklySelected');
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds the dragging class to this block.
|
||||
* Also disables the highlights/shadows to improve performance.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.addDragging = function() {
|
||||
Blockly.addClass_(/** @type {!Element} */ (this.svgGroup_),
|
||||
'blocklyDragging');
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the dragging class from this block.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.removeDragging = function() {
|
||||
Blockly.removeClass_(/** @type {!Element} */ (this.svgGroup_),
|
||||
'blocklyDragging');
|
||||
};
|
||||
|
||||
// Overrides of functions on Blockly.Block that take into account whether the
|
||||
// block has been rendered.
|
||||
|
||||
|
||||
@@ -104,19 +104,22 @@ Blockly.createDom_ = function(container, options) {
|
||||
</defs>
|
||||
*/
|
||||
var defs = Blockly.createSvgElement('defs', {}, svg);
|
||||
// Each filter/pattern needs a unique ID for the case of multiple Blockly
|
||||
// instances on a page. Browser behaviour becomes undefined otherwise.
|
||||
// https://neil.fraser.name/news/2015/11/01/
|
||||
var rnd = String(Math.random()).substring(2);
|
||||
/*
|
||||
<filter id="blocklyEmbossFilter837493">
|
||||
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur"/>
|
||||
<feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur" />
|
||||
<feSpecularLighting in="blur" surfaceScale="1" specularConstant="0.5"
|
||||
specularExponent="10" lighting-color="white"
|
||||
result="specOut">
|
||||
<fePointLight x="-5000" y="-10000" z="20000"/>
|
||||
<fePointLight x="-5000" y="-10000" z="20000" />
|
||||
</feSpecularLighting>
|
||||
<feComposite in="specOut" in2="SourceAlpha" operator="in"
|
||||
result="specOut"/>
|
||||
result="specOut" />
|
||||
<feComposite in="SourceGraphic" in2="specOut" operator="arithmetic"
|
||||
k1="0" k2="1" k3="1" k4="0"/>
|
||||
k1="0" k2="1" k3="1" k4="0" />
|
||||
</filter>
|
||||
*/
|
||||
var embossFilter = Blockly.createSvgElement('filter',
|
||||
|
||||
@@ -38,6 +38,7 @@ goog.require('Blockly.Workspace');
|
||||
goog.require('Blockly.Xml');
|
||||
goog.require('Blockly.ZoomControls');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.math.Coordinate');
|
||||
goog.require('goog.userAgent');
|
||||
@@ -65,6 +66,12 @@ Blockly.WorkspaceSvg = function(options) {
|
||||
* @const
|
||||
*/
|
||||
this.SOUNDS_ = Object.create(null);
|
||||
/**
|
||||
* List of currently highlighted blocks.
|
||||
* @type !Array.<!Blockly.BlockSvg>
|
||||
* @private
|
||||
*/
|
||||
this.highlightedBlocks_ = [];
|
||||
};
|
||||
goog.inherits(Blockly.WorkspaceSvg, Blockly.Workspace);
|
||||
|
||||
@@ -260,7 +267,7 @@ Blockly.WorkspaceSvg.prototype.createDom = function(opt_backgroundClass) {
|
||||
// Determine if there needs to be a category tree, or a simple list of
|
||||
// blocks. This cannot be changed later, since the UI is very different.
|
||||
if (this.options.hasCategories) {
|
||||
/**
|
||||
/**
|
||||
* @type {Blockly.Toolbox}
|
||||
* @private
|
||||
*/
|
||||
@@ -537,53 +544,43 @@ Blockly.WorkspaceSvg.prototype.render = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Turn the visual trace functionality on or off.
|
||||
* @param {boolean} armed True if the trace should be on.
|
||||
* Was used back when block highlighting (for execution) and block selection
|
||||
* (for editing) were the same thing.
|
||||
* Any calls of this function can be deleted.
|
||||
* @deprecated October 2016
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.traceOn = function(armed) {
|
||||
this.traceOn_ = armed;
|
||||
if (this.traceWrapper_) {
|
||||
Blockly.unbindEvent_(this.traceWrapper_);
|
||||
this.traceWrapper_ = null;
|
||||
}
|
||||
if (armed) {
|
||||
this.traceWrapper_ = Blockly.bindEventWithChecks_(this.svgBlockCanvas_,
|
||||
'blocklySelectChange', this, function() {this.traceOn_ = false;});
|
||||
}
|
||||
Blockly.WorkspaceSvg.prototype.traceOn = function() {
|
||||
console.warn('Deprecated call to traceOn, delete this.');
|
||||
};
|
||||
|
||||
/**
|
||||
* Highlight a block in the workspace.
|
||||
* @param {?string} id ID of block to find.
|
||||
* Highlight or unhighlight a block in the workspace.
|
||||
* @param {?string} id ID of block to highlight/unhighlight,
|
||||
* or null for no block (used to unhighlight all blocks).
|
||||
* @param {boolean=} opt_state If undefined, highlight specified block and
|
||||
* automatically unhighlight all others. If true or false, manually
|
||||
* highlight/unhighlight the specified block.
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.highlightBlock = function(id) {
|
||||
if (this.traceOn_ && Blockly.dragMode_ != Blockly.DRAG_NONE) {
|
||||
// The blocklySelectChange event normally prevents this, but sometimes
|
||||
// there is a race condition on fast-executing apps.
|
||||
this.traceOn(false);
|
||||
}
|
||||
if (!this.traceOn_) {
|
||||
return;
|
||||
}
|
||||
var block = null;
|
||||
if (id) {
|
||||
block = this.getBlockById(id);
|
||||
if (!block) {
|
||||
return;
|
||||
Blockly.WorkspaceSvg.prototype.highlightBlock = function(id, opt_state) {
|
||||
if (opt_state === undefined) {
|
||||
// Unhighlight all blocks.
|
||||
for (var i = 0, block; block = this.highlightedBlocks_[i]; i++) {
|
||||
block.setHighlighted(false);
|
||||
}
|
||||
this.highlightedBlocks_.length = 0;
|
||||
}
|
||||
// Temporary turn off the listener for selection changes, so that we don't
|
||||
// trip the monitor for detecting user activity.
|
||||
this.traceOn(false);
|
||||
// Select the current block.
|
||||
// Highlight/unhighlight the specified block.
|
||||
var block = id ? this.getBlockById(id) : null;
|
||||
if (block) {
|
||||
block.select();
|
||||
} else if (Blockly.selected) {
|
||||
Blockly.selected.unselect();
|
||||
var state = (opt_state === undefined) || opt_state;
|
||||
// Using Set here would be great, but at the cost of IE10 support.
|
||||
if (!state) {
|
||||
goog.array.remove(this.highlightedBlocks_, block);
|
||||
} else if (this.highlightedBlocks_.indexOf(block) == -1) {
|
||||
this.highlightedBlocks_.push(block);
|
||||
}
|
||||
block.setHighlighted(state);
|
||||
}
|
||||
// Restore the monitor for user activity after the selection event has fired.
|
||||
var thisWorkspace = this;
|
||||
setTimeout(function() {thisWorkspace.traceOn(true);}, 1);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -172,7 +172,6 @@
|
||||
alert('Ready to execute this code:\n\n' + code);
|
||||
document.getElementById('stepButton').disabled = '';
|
||||
highlightPause = false;
|
||||
workspace.traceOn(true);
|
||||
workspace.highlightBlock(null);
|
||||
}
|
||||
|
||||
@@ -183,6 +182,7 @@
|
||||
if (!ok) {
|
||||
// Program complete, no more code to execute.
|
||||
document.getElementById('stepButton').disabled = 'disabled';
|
||||
workspace.highlightBlock(null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user