mixio 1.10.0
This commit is contained in:
708
blockly/core/toolbox/category.js
Normal file
708
blockly/core/toolbox/category.js
Normal file
@@ -0,0 +1,708 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview A toolbox category used to organize blocks in the toolbox.
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.ToolboxCategory');
|
||||
|
||||
goog.require('Blockly.ISelectableToolboxItem');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.ToolboxItem');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.aria');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
|
||||
goog.requireType('Blockly.ICollapsibleToolboxItem');
|
||||
goog.requireType('Blockly.IToolbox');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a category in a toolbox.
|
||||
* @param {!Blockly.utils.toolbox.CategoryInfo} categoryDef The information needed
|
||||
* to create a category in the toolbox.
|
||||
* @param {!Blockly.IToolbox} toolbox The parent toolbox for the category.
|
||||
* @param {Blockly.ICollapsibleToolboxItem=} opt_parent The parent category or null if
|
||||
* the category does not have a parent.
|
||||
* @constructor
|
||||
* @extends {Blockly.ToolboxItem}
|
||||
* @implements {Blockly.ISelectableToolboxItem}
|
||||
*/
|
||||
Blockly.ToolboxCategory = function(categoryDef, toolbox, opt_parent) {
|
||||
Blockly.ToolboxCategory.superClass_.constructor.call(
|
||||
this, categoryDef, toolbox, opt_parent);
|
||||
|
||||
/**
|
||||
* The name that will be displayed on the category.
|
||||
* @type {string}
|
||||
* @protected
|
||||
*/
|
||||
this.name_ = Blockly.utils.replaceMessageReferences(categoryDef['name']);
|
||||
|
||||
/**
|
||||
* The colour of the category.
|
||||
* @type {string}
|
||||
* @protected
|
||||
*/
|
||||
this.colour_ = this.getColour_(categoryDef);
|
||||
|
||||
/**
|
||||
* The html container for the category.
|
||||
* @type {?Element}
|
||||
* @protected
|
||||
*/
|
||||
this.htmlDiv_ = null;
|
||||
|
||||
/**
|
||||
* The html element for the category row.
|
||||
* @type {?Element}
|
||||
* @protected
|
||||
*/
|
||||
this.rowDiv_ = null;
|
||||
|
||||
/**
|
||||
* The html element that holds children elements of the category row.
|
||||
* @type {?Element}
|
||||
* @protected
|
||||
*/
|
||||
this.rowContents_ = null;
|
||||
|
||||
/**
|
||||
* The html element for the toolbox icon.
|
||||
* @type {?Element}
|
||||
* @protected
|
||||
*/
|
||||
this.iconDom_ = null;
|
||||
|
||||
/**
|
||||
* The html element for the toolbox label.
|
||||
* @type {?Element}
|
||||
* @protected
|
||||
*/
|
||||
this.labelDom_ = null;
|
||||
|
||||
/**
|
||||
* All the css class names that are used to create a category.
|
||||
* @type {!Blockly.ToolboxCategory.CssConfig}
|
||||
* @protected
|
||||
*/
|
||||
this.cssConfig_ = this.makeDefaultCssConfig_();
|
||||
|
||||
var cssConfig = categoryDef['cssconfig'] || categoryDef['cssConfig'];
|
||||
Blockly.utils.object.mixin(this.cssConfig_, cssConfig);
|
||||
|
||||
/**
|
||||
* True if the category is meant to be hidden, false otherwise.
|
||||
* @type {boolean}
|
||||
* @protected
|
||||
*/
|
||||
this.isHidden_ = false;
|
||||
|
||||
/**
|
||||
* True if this category is disabled, false otherwise.
|
||||
* @type {boolean}
|
||||
* @protected
|
||||
*/
|
||||
this.isDisabled_ = false;
|
||||
|
||||
/**
|
||||
* The flyout items for this category.
|
||||
* @type {string|!Blockly.utils.toolbox.FlyoutItemInfoArray}
|
||||
* @protected
|
||||
*/
|
||||
this.flyoutItems_ = [];
|
||||
|
||||
this.parseContents_(categoryDef);
|
||||
};
|
||||
|
||||
Blockly.utils.object.inherits(Blockly.ToolboxCategory, Blockly.ToolboxItem);
|
||||
|
||||
/**
|
||||
* All the CSS class names that are used to create a category.
|
||||
* @typedef {{
|
||||
* container:(string|undefined),
|
||||
* row:(string|undefined),
|
||||
* rowcontentcontainer:(string|undefined),
|
||||
* icon:(string|undefined),
|
||||
* label:(string|undefined),
|
||||
* selected:(string|undefined),
|
||||
* openicon:(string|undefined),
|
||||
* closedicon:(string|undefined)
|
||||
* }}
|
||||
*/
|
||||
Blockly.ToolboxCategory.CssConfig;
|
||||
|
||||
/**
|
||||
* Name used for registering a toolbox category.
|
||||
* @const {string}
|
||||
*/
|
||||
Blockly.ToolboxCategory.registrationName = 'category';
|
||||
|
||||
/**
|
||||
* The number of pixels to move the category over at each nested level.
|
||||
* @type {number}
|
||||
*/
|
||||
Blockly.ToolboxCategory.nestedPadding = 19;
|
||||
|
||||
/**
|
||||
* The width in pixels of the strip of colour next to each category.
|
||||
* @type {number}
|
||||
*/
|
||||
Blockly.ToolboxCategory.borderWidth = 8;
|
||||
|
||||
/**
|
||||
* The default colour of the category. This is used as the background colour of
|
||||
* the category when it is selected.
|
||||
* @type {string}
|
||||
*/
|
||||
Blockly.ToolboxCategory.defaultBackgroundColour = '#57e';
|
||||
|
||||
/**
|
||||
* Creates an object holding the default classes for a category.
|
||||
* @return {!Blockly.ToolboxCategory.CssConfig} The configuration object holding
|
||||
* all the CSS classes for a category.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.makeDefaultCssConfig_ = function() {
|
||||
return {
|
||||
'container': 'blocklyToolboxCategory',
|
||||
'row': 'blocklyTreeRow',
|
||||
'rowcontentcontainer': 'blocklyTreeRowContentContainer',
|
||||
'icon': 'blocklyTreeIcon',
|
||||
'label': 'blocklyTreeLabel',
|
||||
'contents': 'blocklyToolboxContents',
|
||||
'selected': 'blocklyTreeSelected',
|
||||
'openicon': 'blocklyTreeIconOpen',
|
||||
'closedicon': 'blocklyTreeIconClosed',
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the contents array depending on if the category is a dynamic category,
|
||||
* or if its contents are meant to be shown in the flyout.
|
||||
* @param {!Blockly.utils.toolbox.CategoryInfo} categoryDef The information needed
|
||||
* to create a category.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.parseContents_ = function(categoryDef) {
|
||||
var contents = categoryDef['contents'];
|
||||
|
||||
if (categoryDef['custom']) {
|
||||
this.flyoutItems_ = categoryDef['custom'];
|
||||
} else if (contents) {
|
||||
for (var i = 0, itemDef; (itemDef = contents[i]); i++) {
|
||||
var flyoutItem = /** @type {Blockly.utils.toolbox.FlyoutItemInfo} */ (itemDef);
|
||||
this.flyoutItems_.push(flyoutItem);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.init = function() {
|
||||
this.createDom_();
|
||||
if (this.toolboxItemDef_['hidden'] == 'true') {
|
||||
this.hide();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the DOM for the category.
|
||||
* @return {!Element} The parent element for the category.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.createDom_ = function() {
|
||||
this.htmlDiv_ = this.createContainer_();
|
||||
Blockly.utils.aria.setRole(this.htmlDiv_, Blockly.utils.aria.Role.TREEITEM);
|
||||
Blockly.utils.aria.setState(/** @type {!Element} */ (this.htmlDiv_),
|
||||
Blockly.utils.aria.State.SELECTED,false);
|
||||
Blockly.utils.aria.setState(/** @type {!Element} */ (this.htmlDiv_),
|
||||
Blockly.utils.aria.State.LEVEL, this.level_);
|
||||
|
||||
this.rowDiv_ = this.createRowContainer_();
|
||||
this.rowDiv_.style.pointerEvents = 'auto';
|
||||
this.htmlDiv_.appendChild(this.rowDiv_);
|
||||
|
||||
this.rowContents_ = this.createRowContentsContainer_();
|
||||
this.rowContents_.style.pointerEvents = 'none';
|
||||
this.rowDiv_.appendChild(this.rowContents_);
|
||||
|
||||
this.iconDom_ = this.createIconDom_();
|
||||
Blockly.utils.aria.setRole(this.iconDom_, Blockly.utils.aria.Role.PRESENTATION);
|
||||
this.rowContents_.appendChild(this.iconDom_);
|
||||
|
||||
this.labelDom_ = this.createLabelDom_(this.name_);
|
||||
this.rowContents_.appendChild(this.labelDom_);
|
||||
Blockly.utils.aria.setState(/** @type {!Element} */ (this.htmlDiv_),
|
||||
Blockly.utils.aria.State.LABELLEDBY, this.labelDom_.getAttribute('id'));
|
||||
|
||||
this.addColourBorder_(this.colour_);
|
||||
|
||||
return this.htmlDiv_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the container that holds the row and any subcategories.
|
||||
* @return {!Element} The div that holds the icon and the label.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.createContainer_ = function() {
|
||||
var container = document.createElement('div');
|
||||
Blockly.utils.dom.addClass(container, this.cssConfig_['container']);
|
||||
return container;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the parent of the contents container. All clicks will happen on this
|
||||
* div.
|
||||
* @return {!Element} The div that holds the contents container.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.createRowContainer_ = function() {
|
||||
var rowDiv = document.createElement('div');
|
||||
Blockly.utils.dom.addClass(rowDiv, this.cssConfig_['row']);
|
||||
var nestedPadding = Blockly.ToolboxCategory.nestedPadding * this.getLevel();
|
||||
nestedPadding = nestedPadding.toString() + 'px';
|
||||
this.workspace_.RTL ? rowDiv.style.paddingRight = nestedPadding :
|
||||
rowDiv.style.paddingLeft = nestedPadding;
|
||||
return rowDiv;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the container for the label and icon.
|
||||
* This is necessary so we can set all subcategory pointer events to none.
|
||||
* @return {!Element} The div that holds the icon and the label.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.createRowContentsContainer_ = function() {
|
||||
var contentsContainer = document.createElement('div');
|
||||
Blockly.utils.dom.addClass(contentsContainer, this.cssConfig_['rowcontentcontainer']);
|
||||
return contentsContainer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the span that holds the category icon.
|
||||
* @return {!Element} The span that holds the category icon.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.createIconDom_ = function() {
|
||||
var toolboxIcon = document.createElement('span');
|
||||
if (!this.parentToolbox_.isHorizontal()) {
|
||||
Blockly.utils.dom.addClass(toolboxIcon, this.cssConfig_['icon']);
|
||||
}
|
||||
|
||||
toolboxIcon.style.display = 'inline-block';
|
||||
return toolboxIcon;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the span that holds the category label.
|
||||
* This should have an ID for accessibility purposes.
|
||||
* @param {string} name The name of the category.
|
||||
* @return {!Element} The span that holds the category label.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.createLabelDom_ = function(name) {
|
||||
var toolboxLabel = document.createElement('span');
|
||||
toolboxLabel.setAttribute('id', this.getId() + '.label');
|
||||
toolboxLabel.textContent = name;
|
||||
Blockly.utils.dom.addClass(toolboxLabel, this.cssConfig_['label']);
|
||||
return toolboxLabel;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the colour for this category.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.refreshTheme = function() {
|
||||
this.colour_ = this.getColour_(/** @type {Blockly.utils.toolbox.CategoryInfo} **/
|
||||
(this.toolboxItemDef_));
|
||||
this.addColourBorder_(this.colour_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the strip of colour to the toolbox category.
|
||||
* @param {string} colour The category colour.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.addColourBorder_ = function(colour) {
|
||||
if (colour) {
|
||||
var border = Blockly.ToolboxCategory.borderWidth + 'px solid ' +
|
||||
(colour || '#ddd');
|
||||
if (this.workspace_.RTL) {
|
||||
this.rowDiv_.style.borderRight = border;
|
||||
} else {
|
||||
this.rowDiv_.style.borderLeft = border;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets either the colour or the style for a category.
|
||||
* @param {!Blockly.utils.toolbox.CategoryInfo} categoryDef The object holding
|
||||
* information on the category.
|
||||
* @return {string} The hex colour for the category.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.getColour_ = function(categoryDef) {
|
||||
var styleName = categoryDef['categorystyle'] || categoryDef['categoryStyle'];
|
||||
var colour = categoryDef['colour'];
|
||||
|
||||
if (colour && styleName) {
|
||||
console.warn('Toolbox category "' + this.name_ +
|
||||
'" must not have both a style and a colour');
|
||||
} else if (styleName) {
|
||||
return this.getColourfromStyle_(styleName);
|
||||
} else {
|
||||
return this.parseColour_(colour);
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the colour for the category using the style name and returns the new
|
||||
* colour as a hex string.
|
||||
* @param {string} styleName Name of the style.
|
||||
* @return {string} The hex colour for the category.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.getColourfromStyle_ = function(styleName) {
|
||||
var theme = this.workspace_.getTheme();
|
||||
if (styleName && theme) {
|
||||
var style = theme.categoryStyles[styleName];
|
||||
if (style && style.colour) {
|
||||
return this.parseColour_(style.colour);
|
||||
} else {
|
||||
console.warn('Style "' + styleName +
|
||||
'" must exist and contain a colour value');
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the HTML element that is clickable.
|
||||
* The parent toolbox element receives clicks. The parent toolbox will add an ID
|
||||
* to this element so it can pass the onClick event to the correct toolboxItem.
|
||||
* @return {!Element} The HTML element that receives clicks.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.getClickTarget = function() {
|
||||
return /** @type {!Element} */(this.rowDiv_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the colour on the category.
|
||||
* @param {number|string} colourValue HSV hue value (0 to 360), #RRGGBB string,
|
||||
* or a message reference string pointing to one of those two values.
|
||||
* @return {string} The hex colour for the category.
|
||||
* @private
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.parseColour_ = function(colourValue) {
|
||||
// Decode the colour for any potential message references
|
||||
// (eg. `%{BKY_MATH_HUE}`).
|
||||
var colour = Blockly.utils.replaceMessageReferences(colourValue);
|
||||
if (colour == null || colour === '') {
|
||||
// No attribute. No colour.
|
||||
return '';
|
||||
} else {
|
||||
var hue = Number(colour);
|
||||
if (!isNaN(hue)) {
|
||||
return Blockly.hueToHex(hue);
|
||||
} else {
|
||||
var hex = Blockly.utils.colour.parse(colour);
|
||||
if (hex) {
|
||||
return hex;
|
||||
} else {
|
||||
console.warn('Toolbox category "' + this.name_ +
|
||||
'" has unrecognized colour attribute: ' + colour);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds appropriate classes to display an open icon.
|
||||
* @param {?Element} iconDiv The div that holds the icon.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.openIcon_ = function(iconDiv) {
|
||||
if (!iconDiv) {
|
||||
return;
|
||||
}
|
||||
Blockly.utils.dom.removeClasses(iconDiv, this.cssConfig_['closedicon']);
|
||||
Blockly.utils.dom.addClass(iconDiv, this.cssConfig_['openicon']);
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds appropriate classes to display a closed icon.
|
||||
* @param {?Element} iconDiv The div that holds the icon.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.closeIcon_ = function(iconDiv) {
|
||||
if (!iconDiv) {
|
||||
return;
|
||||
}
|
||||
Blockly.utils.dom.removeClasses(iconDiv, this.cssConfig_['openicon']);
|
||||
Blockly.utils.dom.addClass(iconDiv, this.cssConfig_['closedicon']);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets whether the category is visible or not.
|
||||
* For a category to be visible its parent category must also be expanded.
|
||||
* @param {boolean} isVisible True if category should be visible.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.setVisible_ = function(isVisible) {
|
||||
this.htmlDiv_.style.display = isVisible ? 'block' : 'none';
|
||||
this.isHidden_ = !isVisible;
|
||||
|
||||
if (this.parentToolbox_.getSelectedItem() == this) {
|
||||
this.parentToolbox_.clearSelection();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the category.
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.hide = function() {
|
||||
this.setVisible_(false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the category. Category will only appear if its parent category is also
|
||||
* expanded.
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.show = function() {
|
||||
this.setVisible_(true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether the category is visible.
|
||||
* A category is only visible if all of its ancestors are expanded and isHidden_ is false.
|
||||
* @return {boolean} True if the category is visible, false otherwise.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.isVisible = function() {
|
||||
return !this.isHidden_ && this.allAncestorsExpanded_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether all ancestors of a category (parent and parent's parent, etc.) are expanded.
|
||||
* @return {boolean} True only if every ancestor is expanded
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.allAncestorsExpanded_ = function() {
|
||||
var category = this;
|
||||
while (category.getParent()) {
|
||||
category = category.getParent();
|
||||
if (!category.isExpanded()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.isSelectable = function() {
|
||||
return this.isVisible() && !this.isDisabled_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles when the toolbox item is clicked.
|
||||
* @param {!Event} _e Click event to handle.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.onClick = function(_e) {
|
||||
// No-op
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the current category as selected.
|
||||
* @param {boolean} isSelected True if this category is selected, false
|
||||
* otherwise.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.setSelected = function(isSelected) {
|
||||
if (isSelected) {
|
||||
var defaultColour = this.parseColour_(
|
||||
Blockly.ToolboxCategory.defaultBackgroundColour);
|
||||
this.rowDiv_.style.backgroundColor = this.colour_ || defaultColour;
|
||||
Blockly.utils.dom.addClass(this.rowDiv_, this.cssConfig_['selected']);
|
||||
} else {
|
||||
this.rowDiv_.style.backgroundColor = '';
|
||||
Blockly.utils.dom.removeClass(this.rowDiv_, this.cssConfig_['selected']);
|
||||
}
|
||||
Blockly.utils.aria.setState(/** @type {!Element} */ (this.htmlDiv_),
|
||||
Blockly.utils.aria.State.SELECTED, isSelected);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets whether the category is disabled.
|
||||
* @param {boolean} isDisabled True to disable the category, false otherwise.
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.setDisabled = function(isDisabled) {
|
||||
this.isDisabled_ = isDisabled;
|
||||
this.getDiv().setAttribute('disabled', isDisabled);
|
||||
isDisabled ? this.getDiv().setAttribute('disabled', 'true') :
|
||||
this.getDiv().removeAttribute('disabled');
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the name of the category. Used for emitting events.
|
||||
* @return {string} The name of the toolbox item.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.getName = function() {
|
||||
return this.name_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.getParent = function() {
|
||||
return this.parent_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.getDiv = function() {
|
||||
return this.htmlDiv_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the contents of the category. These are items that are meant to be
|
||||
* displayed in the flyout.
|
||||
* @return {!Blockly.utils.toolbox.FlyoutItemInfoArray|string} The definition
|
||||
* of items to be displayed in the flyout.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.getContents = function() {
|
||||
return this.flyoutItems_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the contents to be displayed in the flyout.
|
||||
* If the flyout is open when the contents are updated, refreshSelection on the
|
||||
* toolbox must also be called.
|
||||
* @param {!Blockly.utils.toolbox.FlyoutDefinition|string} contents The contents
|
||||
* to be displayed in the flyout. A string can be supplied to create a
|
||||
* dynamic category.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.updateFlyoutContents = function(contents) {
|
||||
this.flyoutItems_ = [];
|
||||
|
||||
if (typeof contents == 'string') {
|
||||
this.toolboxItemDef_['custom'] = contents;
|
||||
} else {
|
||||
// Removes old custom field when contents is updated.
|
||||
delete this.toolboxItemDef_['custom'];
|
||||
this.toolboxItemDef_['contents'] =
|
||||
Blockly.utils.toolbox.convertFlyoutDefToJsonArray(contents);
|
||||
}
|
||||
this.parseContents_(
|
||||
/** @type {Blockly.utils.toolbox.CategoryInfo} */ (this.toolboxItemDef_));
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.ToolboxCategory.prototype.dispose = function() {
|
||||
Blockly.utils.dom.removeNode(this.htmlDiv_);
|
||||
};
|
||||
|
||||
/**
|
||||
* CSS for Toolbox. See css.js for use.
|
||||
*/
|
||||
Blockly.Css.register([
|
||||
/* eslint-disable indent */
|
||||
'.blocklyTreeRow:not(.blocklyTreeSelected):hover {',
|
||||
'background-color: rgba(255, 255, 255, 0.2);',
|
||||
'}',
|
||||
|
||||
'.blocklyToolboxDiv[layout="h"] .blocklyToolboxCategory {',
|
||||
'margin: 1px 5px 1px 0;',
|
||||
'}',
|
||||
|
||||
'.blocklyToolboxDiv[dir="RTL"][layout="h"] .blocklyToolboxCategory {',
|
||||
'margin: 1px 0 1px 5px;',
|
||||
'}',
|
||||
|
||||
'.blocklyTreeRow {',
|
||||
'height: 22px;',
|
||||
'line-height: 22px;',
|
||||
'margin-bottom: 3px;',
|
||||
'padding-right: 8px;',
|
||||
'white-space: nowrap;',
|
||||
'}',
|
||||
|
||||
'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {',
|
||||
'margin-left: 8px;',
|
||||
'padding-right: 0px',
|
||||
'}',
|
||||
|
||||
'.blocklyTreeIcon {',
|
||||
'background-image: url(<<<PATH>>>/sprites.png);',
|
||||
'height: 16px;',
|
||||
'vertical-align: middle;',
|
||||
'visibility: hidden;',
|
||||
'width: 16px;',
|
||||
'}',
|
||||
|
||||
'.blocklyTreeIconClosed {',
|
||||
'background-position: -32px -1px;',
|
||||
'}',
|
||||
|
||||
'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeIconClosed {',
|
||||
'background-position: 0 -1px;',
|
||||
'}',
|
||||
|
||||
'.blocklyTreeSelected>.blocklyTreeIconClosed {',
|
||||
'background-position: -32px -17px;',
|
||||
'}',
|
||||
|
||||
'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeSelected>.blocklyTreeIconClosed {',
|
||||
'background-position: 0 -17px;',
|
||||
'}',
|
||||
|
||||
'.blocklyTreeIconOpen {',
|
||||
'background-position: -16px -1px;',
|
||||
'}',
|
||||
|
||||
'.blocklyTreeSelected>.blocklyTreeIconOpen {',
|
||||
'background-position: -16px -17px;',
|
||||
'}',
|
||||
|
||||
'.blocklyTreeLabel {',
|
||||
'cursor: default;',
|
||||
'font: 16px sans-serif;',
|
||||
'padding: 0 3px;',
|
||||
'vertical-align: middle;',
|
||||
'}',
|
||||
|
||||
'.blocklyToolboxDelete .blocklyTreeLabel {',
|
||||
'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',
|
||||
'}',
|
||||
|
||||
'.blocklyTreeSelected .blocklyTreeLabel {',
|
||||
'color: #fff;',
|
||||
'}'
|
||||
/* eslint-enable indent */
|
||||
]);
|
||||
|
||||
Blockly.registry.register(Blockly.registry.Type.TOOLBOX_ITEM,
|
||||
Blockly.ToolboxCategory.registrationName, Blockly.ToolboxCategory);
|
||||
298
blockly/core/toolbox/collapsible_category.js
Normal file
298
blockly/core/toolbox/collapsible_category.js
Normal file
@@ -0,0 +1,298 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview A toolbox category used to organize blocks in the toolbox.
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.CollapsibleToolboxCategory');
|
||||
|
||||
goog.require('Blockly.ICollapsibleToolboxItem');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.ToolboxCategory');
|
||||
goog.require('Blockly.ToolboxItem');
|
||||
goog.require('Blockly.ToolboxSeparator');
|
||||
goog.require('Blockly.utils.aria');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.object');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
|
||||
goog.requireType('Blockly.IToolbox');
|
||||
goog.requireType('Blockly.IToolboxItem');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a category in a toolbox that can be collapsed.
|
||||
* @param {!Blockly.utils.toolbox.CategoryInfo} categoryDef The information needed
|
||||
* to create a category in the toolbox.
|
||||
* @param {!Blockly.IToolbox} toolbox The parent toolbox for the category.
|
||||
* @param {Blockly.ICollapsibleToolboxItem=} opt_parent The parent category or null if
|
||||
* the category does not have a parent.
|
||||
* @constructor
|
||||
* @extends {Blockly.ToolboxCategory}
|
||||
* @implements {Blockly.ICollapsibleToolboxItem}
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory = function(categoryDef, toolbox, opt_parent) {
|
||||
/**
|
||||
* Container for any child categories.
|
||||
* @type {?Element}
|
||||
* @protected
|
||||
*/
|
||||
this.subcategoriesDiv_ = null;
|
||||
|
||||
/**
|
||||
* Whether or not the category should display its subcategories.
|
||||
* @type {boolean}
|
||||
* @protected
|
||||
*/
|
||||
this.expanded_ = false;
|
||||
|
||||
/**
|
||||
* The child toolbox items for this category.
|
||||
* @type {!Array<!Blockly.ToolboxItem>}
|
||||
* @protected
|
||||
*/
|
||||
this.toolboxItems_ = [];
|
||||
|
||||
Blockly.CollapsibleToolboxCategory.superClass_.constructor.call(
|
||||
this, categoryDef, toolbox, opt_parent);
|
||||
};
|
||||
|
||||
Blockly.utils.object.inherits(Blockly.CollapsibleToolboxCategory, Blockly.ToolboxCategory);
|
||||
|
||||
/**
|
||||
* All the CSS class names that are used to create a collapsible
|
||||
* category. This is all the properties from the regular category plus contents.
|
||||
* @typedef {{
|
||||
* container:?string,
|
||||
* row:?string,
|
||||
* rowcontentcontainer:?string,
|
||||
* icon:?string,
|
||||
* label:?string,
|
||||
* selected:?string,
|
||||
* openicon:?string,
|
||||
* closedicon:?string,
|
||||
* contents:?string
|
||||
* }}
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.CssConfig;
|
||||
|
||||
/**
|
||||
* Name used for registering a collapsible toolbox category.
|
||||
* @const {string}
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.registrationName = 'collapsibleCategory';
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.makeDefaultCssConfig_ = function() {
|
||||
var cssConfig = Blockly.CollapsibleToolboxCategory.superClass_.makeDefaultCssConfig_.call(this);
|
||||
cssConfig['contents'] = 'blocklyToolboxContents';
|
||||
return cssConfig;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.parseContents_ = function(categoryDef) {
|
||||
var contents = categoryDef['contents'];
|
||||
var prevIsFlyoutItem = true;
|
||||
|
||||
if (categoryDef['custom']) {
|
||||
this.flyoutItems_ = categoryDef['custom'];
|
||||
} else if (contents) {
|
||||
for (var i = 0, itemDef; (itemDef = contents[i]); i++) {
|
||||
// Separators can exist as either a flyout item or a toolbox item so
|
||||
// decide where it goes based on the type of the previous item.
|
||||
if (!Blockly.registry.hasItem(Blockly.registry.Type.TOOLBOX_ITEM, itemDef['kind']) ||
|
||||
(itemDef['kind'].toLowerCase() == Blockly.ToolboxSeparator.registrationName &&
|
||||
prevIsFlyoutItem)) {
|
||||
var flyoutItem = /** @type {Blockly.utils.toolbox.FlyoutItemInfo} */ (itemDef);
|
||||
this.flyoutItems_.push(flyoutItem);
|
||||
prevIsFlyoutItem = true;
|
||||
} else {
|
||||
this.createToolboxItem_(itemDef);
|
||||
prevIsFlyoutItem = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a toolbox item and adds it to the list of toolbox items.
|
||||
* @param {!Blockly.utils.toolbox.ToolboxItemInfo} itemDef The information needed
|
||||
* to create a toolbox item.
|
||||
* @private
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.createToolboxItem_ = function(itemDef) {
|
||||
var registryName = itemDef['kind'];
|
||||
var categoryDef = /** @type {!Blockly.utils.toolbox.CategoryInfo} */ (itemDef);
|
||||
|
||||
// Categories that are collapsible are created using a class registered under
|
||||
// a diffferent name.
|
||||
if (registryName.toUpperCase() == 'CATEGORY' &&
|
||||
Blockly.utils.toolbox.isCategoryCollapsible(categoryDef)) {
|
||||
registryName = Blockly.CollapsibleToolboxCategory.registrationName;
|
||||
}
|
||||
var ToolboxItemClass = Blockly.registry.getClass(
|
||||
Blockly.registry.Type.TOOLBOX_ITEM, registryName);
|
||||
var toolboxItem = new ToolboxItemClass(itemDef, this.parentToolbox_, this);
|
||||
this.toolboxItems_.push(toolboxItem);
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.init = function() {
|
||||
Blockly.CollapsibleToolboxCategory.superClass_.init.call(this);
|
||||
|
||||
this.setExpanded(this.toolboxItemDef_['expanded'] == 'true' ||
|
||||
this.toolboxItemDef_['expanded']);
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.createDom_ = function() {
|
||||
Blockly.CollapsibleToolboxCategory.superClass_.createDom_.call(this);
|
||||
|
||||
var subCategories = this.getChildToolboxItems();
|
||||
this.subcategoriesDiv_ = this.createSubCategoriesDom_(subCategories);
|
||||
Blockly.utils.aria.setRole(this.subcategoriesDiv_,
|
||||
Blockly.utils.aria.Role.GROUP);
|
||||
this.htmlDiv_.appendChild(this.subcategoriesDiv_);
|
||||
|
||||
return this.htmlDiv_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.createIconDom_ = function() {
|
||||
var toolboxIcon = document.createElement('span');
|
||||
if (!this.parentToolbox_.isHorizontal()) {
|
||||
Blockly.utils.dom.addClass(toolboxIcon, this.cssConfig_['icon']);
|
||||
toolboxIcon.style.visibility = 'visible';
|
||||
}
|
||||
|
||||
toolboxIcon.style.display = 'inline-block';
|
||||
return toolboxIcon;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the DOM for all subcategories.
|
||||
* @param {!Array<!Blockly.ToolboxItem>} subcategories The subcategories.
|
||||
* @return {!Element} The div holding all the subcategories.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.createSubCategoriesDom_ = function(subcategories) {
|
||||
var contentsContainer = document.createElement('div');
|
||||
Blockly.utils.dom.addClass(contentsContainer, this.cssConfig_['contents']);
|
||||
|
||||
for (var i = 0; i < subcategories.length; i++) {
|
||||
var newCategory = subcategories[i];
|
||||
newCategory.init();
|
||||
var newCategoryDiv = newCategory.getDiv();
|
||||
contentsContainer.appendChild(newCategoryDiv);
|
||||
if (newCategory.getClickTarget) {
|
||||
newCategory.getClickTarget().setAttribute('id', newCategory.getId());
|
||||
}
|
||||
}
|
||||
return contentsContainer;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Opens or closes the current category.
|
||||
* @param {boolean} isExpanded True to expand the category, false to close.
|
||||
* @public
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.setExpanded = function(isExpanded) {
|
||||
if (this.expanded_ == isExpanded) {
|
||||
return;
|
||||
}
|
||||
this.expanded_ = isExpanded;
|
||||
if (isExpanded) {
|
||||
this.subcategoriesDiv_.style.display = 'block';
|
||||
this.openIcon_(this.iconDom_);
|
||||
} else {
|
||||
this.subcategoriesDiv_.style.display = 'none';
|
||||
this.closeIcon_(this.iconDom_);
|
||||
}
|
||||
Blockly.utils.aria.setState(/** @type {!Element} */ (this.htmlDiv_),
|
||||
Blockly.utils.aria.State.EXPANDED, isExpanded);
|
||||
|
||||
this.parentToolbox_.handleToolboxItemResize();
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.setVisible_ = function(isVisible) {
|
||||
this.htmlDiv_.style.display = isVisible ? 'block' : 'none';
|
||||
for (var i = 0, child; (child = this.getChildToolboxItems()[i]); i++) {
|
||||
child.setVisible_(isVisible);
|
||||
}
|
||||
this.isHidden_ = !isVisible;
|
||||
|
||||
if (this.parentToolbox_.getSelectedItem() == this) {
|
||||
this.parentToolbox_.clearSelection();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether the category is expanded to show its child subcategories.
|
||||
* @return {boolean} True if the toolbox item shows its children, false if it
|
||||
* is collapsed.
|
||||
* @public
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.isExpanded = function() {
|
||||
return this.expanded_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.isCollapsible = function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.onClick = function(_e) {
|
||||
this.toggleExpanded();
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggles whether or not the category is expanded.
|
||||
* @public
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.toggleExpanded = function() {
|
||||
this.setExpanded(!this.expanded_);
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.getDiv = function() {
|
||||
return this.htmlDiv_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets any children toolbox items. (ex. Gets the subcategories)
|
||||
* @return {!Array<!Blockly.IToolboxItem>} The child toolbox items.
|
||||
*/
|
||||
Blockly.CollapsibleToolboxCategory.prototype.getChildToolboxItems = function() {
|
||||
return this.toolboxItems_;
|
||||
};
|
||||
|
||||
|
||||
Blockly.registry.register(Blockly.registry.Type.TOOLBOX_ITEM,
|
||||
Blockly.CollapsibleToolboxCategory.registrationName, Blockly.CollapsibleToolboxCategory);
|
||||
123
blockly/core/toolbox/separator.js
Normal file
123
blockly/core/toolbox/separator.js
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview A separator used for separating toolbox categories.
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
* @author maribethb@google.com (Maribeth Bottorff)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.ToolboxSeparator');
|
||||
|
||||
goog.require('Blockly.IToolboxItem');
|
||||
goog.require('Blockly.registry');
|
||||
goog.require('Blockly.ToolboxItem');
|
||||
goog.require('Blockly.utils.dom');
|
||||
|
||||
goog.requireType('Blockly.IToolbox');
|
||||
goog.requireType('Blockly.utils.toolbox');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a toolbox separator. This is the thin visual line that appears on
|
||||
* the toolbox. This item is not interactable.
|
||||
* @param {!Blockly.utils.toolbox.SeparatorInfo} separatorDef The information
|
||||
* needed to create a separator.
|
||||
* @param {!Blockly.IToolbox} toolbox The parent toolbox for the separator.
|
||||
* @constructor
|
||||
* @extends {Blockly.ToolboxItem}
|
||||
* @implements {Blockly.IToolboxItem}
|
||||
*/
|
||||
Blockly.ToolboxSeparator = function(separatorDef, toolbox) {
|
||||
|
||||
Blockly.ToolboxSeparator.superClass_.constructor.call(
|
||||
this, separatorDef, toolbox);
|
||||
/**
|
||||
* All the CSS class names that are used to create a separator.
|
||||
* @type {!Blockly.ToolboxSeparator.CssConfig}
|
||||
* @protected
|
||||
*/
|
||||
this.cssConfig_ = {
|
||||
'container': 'blocklyTreeSeparator'
|
||||
};
|
||||
|
||||
var cssConfig = separatorDef['cssconfig'] || separatorDef['cssConfig'];
|
||||
Blockly.utils.object.mixin(this.cssConfig_, cssConfig);
|
||||
};
|
||||
Blockly.utils.object.inherits(Blockly.ToolboxSeparator, Blockly.ToolboxItem);
|
||||
|
||||
/**
|
||||
* All the CSS class names that are used to create a separator.
|
||||
* @typedef {{
|
||||
* container:(string|undefined)
|
||||
* }}
|
||||
*/
|
||||
Blockly.ToolboxSeparator.CssConfig;
|
||||
|
||||
/**
|
||||
* Name used for registering a toolbox separator.
|
||||
* @const {string}
|
||||
*/
|
||||
Blockly.ToolboxSeparator.registrationName = 'sep';
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.ToolboxSeparator.prototype.init = function() {
|
||||
this.createDom_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the DOM for a separator.
|
||||
* @return {!Element} The parent element for the separator.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.ToolboxSeparator.prototype.createDom_ = function() {
|
||||
var container = document.createElement('div');
|
||||
Blockly.utils.dom.addClass(container, this.cssConfig_['container']);
|
||||
this.htmlDiv_ = container;
|
||||
return container;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.ToolboxSeparator.prototype.getDiv = function() {
|
||||
return this.htmlDiv_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
Blockly.ToolboxSeparator.prototype.dispose = function() {
|
||||
Blockly.utils.dom.removeNode(this.htmlDiv_);
|
||||
};
|
||||
|
||||
/**
|
||||
* CSS for Toolbox. See css.js for use.
|
||||
*/
|
||||
Blockly.Css.register([
|
||||
/* eslint-disable indent */
|
||||
'.blocklyTreeSeparator {',
|
||||
'border-bottom: solid #e5e5e5 1px;',
|
||||
'height: 0;',
|
||||
'margin: 5px 0;',
|
||||
'}',
|
||||
|
||||
'.blocklyToolboxDiv[layout="h"] .blocklyTreeSeparator {',
|
||||
'border-right: solid #e5e5e5 1px;',
|
||||
'border-bottom: none;',
|
||||
'height: auto;',
|
||||
'margin: 0 5px 0 5px;',
|
||||
'padding: 5px 0;',
|
||||
'width: 0;',
|
||||
'}',
|
||||
/* eslint-enable indent */
|
||||
]);
|
||||
|
||||
Blockly.registry.register(Blockly.registry.Type.TOOLBOX_ITEM,
|
||||
Blockly.ToolboxSeparator.registrationName, Blockly.ToolboxSeparator);
|
||||
1131
blockly/core/toolbox/toolbox.js
Normal file
1131
blockly/core/toolbox/toolbox.js
Normal file
File diff suppressed because it is too large
Load Diff
148
blockly/core/toolbox/toolbox_item.js
Normal file
148
blockly/core/toolbox/toolbox_item.js
Normal file
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview An item in the toolbox.
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.ToolboxItem');
|
||||
|
||||
goog.require('Blockly.IToolboxItem');
|
||||
|
||||
goog.requireType('Blockly.ICollapsibleToolboxItem');
|
||||
goog.requireType('Blockly.IToolbox');
|
||||
goog.requireType('Blockly.utils.toolbox');
|
||||
goog.requireType('Blockly.WorkspaceSvg');
|
||||
|
||||
|
||||
/**
|
||||
* Class for an item in the toolbox.
|
||||
* @param {!Blockly.utils.toolbox.ToolboxItemInfo} toolboxItemDef The JSON defining the
|
||||
* toolbox item.
|
||||
* @param {!Blockly.IToolbox} toolbox The toolbox that holds the toolbox item.
|
||||
* @param {Blockly.ICollapsibleToolboxItem=} opt_parent The parent toolbox item
|
||||
* or null if the category does not have a parent.
|
||||
* @constructor
|
||||
* @implements {Blockly.IToolboxItem}
|
||||
*/
|
||||
Blockly.ToolboxItem = function(toolboxItemDef, toolbox, opt_parent) {
|
||||
|
||||
/**
|
||||
* The id for the category.
|
||||
* @type {string}
|
||||
* @protected
|
||||
*/
|
||||
this.id_ = toolboxItemDef['toolboxitemid'] || Blockly.utils.IdGenerator.getNextUniqueId();
|
||||
|
||||
/**
|
||||
* The parent of the category.
|
||||
* @type {?Blockly.ICollapsibleToolboxItem}
|
||||
* @protected
|
||||
*/
|
||||
this.parent_ = opt_parent || null;
|
||||
|
||||
/**
|
||||
* The level that the category is nested at.
|
||||
* @type {number}
|
||||
* @protected
|
||||
*/
|
||||
this.level_ = this.parent_ ? this.parent_.getLevel() + 1 : 0;
|
||||
|
||||
/**
|
||||
* The JSON definition of the toolbox item.
|
||||
* @type {!Blockly.utils.toolbox.ToolboxItemInfo}
|
||||
* @protected
|
||||
*/
|
||||
this.toolboxItemDef_ = toolboxItemDef;
|
||||
|
||||
/**
|
||||
* The toolbox this category belongs to.
|
||||
* @type {!Blockly.IToolbox}
|
||||
* @protected
|
||||
*/
|
||||
this.parentToolbox_ = toolbox;
|
||||
|
||||
/**
|
||||
* The workspace of the parent toolbox.
|
||||
* @type {!Blockly.WorkspaceSvg}
|
||||
* @protected
|
||||
*/
|
||||
this.workspace_ = this.parentToolbox_.getWorkspace();
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the toolbox item.
|
||||
* This includes creating the DOM and updating the state of any items based
|
||||
* on the info object.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxItem.prototype.init = function() {
|
||||
// No-op by default.
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the div for the toolbox item.
|
||||
* @return {?Element} The div for the toolbox item.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxItem.prototype.getDiv = function() {
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a unique identifier for this toolbox item.
|
||||
* @return {string} The ID for the toolbox item.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxItem.prototype.getId = function() {
|
||||
return this.id_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the parent if the toolbox item is nested.
|
||||
* @return {?Blockly.IToolboxItem} The parent toolbox item, or null if
|
||||
* this toolbox item is not nested.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxItem.prototype.getParent = function() {
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the nested level of the category.
|
||||
* @return {number} The nested level of the category.
|
||||
* @package
|
||||
*/
|
||||
Blockly.ToolboxItem.prototype.getLevel = function() {
|
||||
return this.level_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether the toolbox item is selectable.
|
||||
* @return {boolean} True if the toolbox item can be selected.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxItem.prototype.isSelectable = function() {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether the toolbox item is collapsible.
|
||||
* @return {boolean} True if the toolbox item is collapsible.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxItem.prototype.isCollapsible = function() {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of this toolbox item. No-op by default.
|
||||
* @public
|
||||
*/
|
||||
Blockly.ToolboxItem.prototype.dispose = function() {
|
||||
};
|
||||
Reference in New Issue
Block a user