mirror of
https://github.com/google/blockly.git
synced 2026-01-13 11:57:10 +01:00
Adds support for category styles
This commit is contained in:
@@ -689,8 +689,10 @@ Blockly.setTheme = function(theme) {
|
||||
this.theme_ = theme;
|
||||
var ws = Blockly.getMainWorkspace();
|
||||
|
||||
//update blocks in workspace
|
||||
this.updateBlockStyles_(ws.getAllBlocks());
|
||||
|
||||
//update blocks in the flyout
|
||||
if (!ws.toolbox_ && ws.flyout_ && ws.flyout_.workspace_) {
|
||||
this.updateBlockStyles_(ws.flyout_.workspace_.getAllBlocks());
|
||||
}
|
||||
@@ -698,6 +700,11 @@ Blockly.setTheme = function(theme) {
|
||||
ws.refreshToolboxSelection();
|
||||
}
|
||||
|
||||
//update colours on the categories
|
||||
if (ws.toolbox_) {
|
||||
ws.toolbox_.updateColourFromTheme();
|
||||
}
|
||||
|
||||
var event = new Blockly.Events.Ui(null, 'themeChanged');
|
||||
event.workspaceId = ws.id;
|
||||
Blockly.Events.fire(event);
|
||||
|
||||
@@ -28,11 +28,14 @@ goog.provide('Blockly.Theme');
|
||||
/**
|
||||
* Class for a theme.
|
||||
* @param {Object.<string, Blockly.BlockStyle>} blockStyles A map from style
|
||||
* names (strings) to objects with style attributes.
|
||||
* names (strings) to objects with style attributes relating to blocks.
|
||||
* @param {Object.<string, Blockly.CategoryStyle>} categoryStyles A map from style
|
||||
* names (strings) to objects with style attributes relating to categories.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Theme = function(blockStyles) {
|
||||
Blockly.Theme = function(blockStyles, categoryStyles) {
|
||||
this.blockStyles_ = blockStyles;
|
||||
this.categoryStyles_ = categoryStyles;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -71,3 +74,21 @@ Blockly.Theme.prototype.getBlockStyle = function(blockStyleName) {
|
||||
Blockly.Theme.prototype.setBlockStyle = function(blockStyleName, blockStyle) {
|
||||
this.blockStyles_[blockStyleName] = blockStyle;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the CategoryStyle for the given category style name.
|
||||
* @param{String} categoryStyleName The name of the block style.
|
||||
* @return {Blockly.CategoryStyle} The style with the block style name.
|
||||
*/
|
||||
Blockly.Theme.prototype.getCategoryStyle = function(categoryStyleName) {
|
||||
return this.categoryStyles_[categoryStyleName];
|
||||
};
|
||||
|
||||
/**
|
||||
* Overrides or adds a style to the categoryStyles map.
|
||||
* @param{String} categoryStyleName The name of the category style.
|
||||
* @param{Blockly.CategoryStyle} categoryStyle The category style
|
||||
*/
|
||||
Blockly.Theme.prototype.setCategoryStyle = function(categoryStyleName, categoryStyle) {
|
||||
this.categoryStyles_[categoryStyleName] = categoryStyle;
|
||||
};
|
||||
|
||||
126
core/toolbox.js
126
core/toolbox.js
@@ -332,25 +332,22 @@ Blockly.Toolbox.prototype.syncTrees_ = function(treeIn, treeOut, pathToMedia) {
|
||||
openNode = newOpenNode;
|
||||
}
|
||||
}
|
||||
// Decode the colour for any potential message references
|
||||
// (eg. `%{BKY_MATH_HUE}`).
|
||||
var colour = Blockly.utils.replaceMessageReferences(
|
||||
childIn.getAttribute('colour'));
|
||||
if (colour === null || colour === '') {
|
||||
// No attribute. No colour.
|
||||
childOut.hexColour = '';
|
||||
} else if (/^#[0-9a-fA-F]{6}$/.test(colour)) {
|
||||
childOut.hexColour = colour;
|
||||
this.hasColours_ = true;
|
||||
} else if (typeof colour === 'number' ||
|
||||
(typeof colour === 'string' && !isNaN(Number(colour)))) {
|
||||
childOut.hexColour = Blockly.hueToRgb(Number(colour));
|
||||
this.hasColours_ = true;
|
||||
} else {
|
||||
|
||||
var styleName = childIn.getAttribute('style');
|
||||
var colour = childIn.getAttribute('colour');
|
||||
|
||||
if (colour && styleName) {
|
||||
childOut.hexColour = '';
|
||||
console.warn('Toolbox category "' + categoryName +
|
||||
'" has unrecognized colour attribute: ' + colour);
|
||||
'" can not have both a style and a colour');
|
||||
}
|
||||
else if (styleName) {
|
||||
this.setColourFromStyle_(styleName, childOut, categoryName);
|
||||
}
|
||||
else {
|
||||
this.setColour_(colour, childOut, categoryName);
|
||||
}
|
||||
|
||||
if (childIn.getAttribute('expanded') == 'true') {
|
||||
if (childOut.blocks.length) {
|
||||
// This is a category that directly contains blocks.
|
||||
@@ -395,6 +392,103 @@ Blockly.Toolbox.prototype.syncTrees_ = function(treeIn, treeOut, pathToMedia) {
|
||||
return openNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets 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.
|
||||
* @param {Blockly.Toolbox.TreeNode} childOut The child to set the hexColour on.
|
||||
* @param {string} categoryName Name of the toolbox category.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Toolbox.prototype.setColour_ = function(colourValue, childOut, categoryName){
|
||||
// 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.
|
||||
childOut.hexColour = '';
|
||||
} else if (/^#[0-9a-fA-F]{6}$/.test(colour)) {
|
||||
childOut.hexColour = colour;
|
||||
this.hasColours_ = true;
|
||||
} else if (typeof colour === 'number' ||
|
||||
(typeof colour === 'string' && !isNaN(Number(colour)))) {
|
||||
childOut.hexColour = Blockly.hueToRgb(Number(colour));
|
||||
this.hasColours_ = true;
|
||||
} else {
|
||||
childOut.hexColour = '';
|
||||
console.warn('Toolbox category "' + categoryName +
|
||||
'" has unrecognized colour attribute: ' + colour);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves and sets the colour for the category using the style name.
|
||||
* The category colour is set from the colour style attribute.
|
||||
* @param {string} styleName Name of the style.
|
||||
* @param {!Blockly.Toolbox.TreeNode} childOut The child to set the hexColour on.
|
||||
* @param {string} categoryName Name of the toolbox category.
|
||||
*/
|
||||
Blockly.Toolbox.prototype.setColourFromStyle_ = function(
|
||||
styleName, childOut, categoryName){
|
||||
childOut.styleName = styleName;
|
||||
if (styleName && Blockly.getTheme()) {
|
||||
var style = Blockly.getTheme().getCategoryStyle(styleName);
|
||||
if (style && style.colour) {
|
||||
this.setColour_(style.colour, childOut, categoryName);
|
||||
}
|
||||
else {
|
||||
console.warn('Style "' + styleName + '" must exist and contain a colour value');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Recursively updates all the category colours using the category style name.
|
||||
* @param {Blockly.Toolbox.TreeNode=} opt_tree Starting point of tree.
|
||||
* Defaults to the root node.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Toolbox.prototype.updateColourFromTheme_ = function(opt_tree) {
|
||||
var tree = opt_tree || this.tree_;
|
||||
if (tree) {
|
||||
var children = tree.getChildren(false);
|
||||
for (var i = 0, child; child = children[i]; i++) {
|
||||
if (child.styleName) {
|
||||
this.setColourFromStyle_(child.styleName, child, '');
|
||||
this.addColour_();
|
||||
}
|
||||
this.updateColourFromTheme_(child);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the category colours and background colour of selected categories.
|
||||
*/
|
||||
Blockly.Toolbox.prototype.updateColourFromTheme = function() {
|
||||
var tree = this.tree_;
|
||||
if (tree) {
|
||||
this.updateColourFromTheme_(tree);
|
||||
this.updateSelectedItemColour_(tree);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the background colour of the selected category.
|
||||
* @param {!Blockly.Toolbox.TreeNode} tree Starting point of tree.
|
||||
* Defaults to the root node.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Toolbox.prototype.updateSelectedItemColour_ = function(tree) {
|
||||
var selectedItem = tree.selectedItem_;
|
||||
if (selectedItem) {
|
||||
var hexColour = selectedItem.hexColour || '#57e';
|
||||
selectedItem.getRowElement().style.backgroundColor = hexColour;
|
||||
tree.toolbox_.addColour_(selectedItem);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Recursively add colours to this toolbox.
|
||||
* @param {Blockly.Toolbox.TreeNode=} opt_tree Starting point of tree.
|
||||
|
||||
@@ -412,7 +412,7 @@ h1 {
|
||||
Variables category uses untyped variable blocks.
|
||||
See https://developers.google.com/blockly/guides/create-custom-blocks/variables#untyped_variable_blocks for more information. -->
|
||||
<xml id="toolbox-categories" style="display: none">
|
||||
<category name="Logic" colour="%{BKY_LOGIC_HUE}">
|
||||
<category name="Logic" style="logic_category">
|
||||
<block type="controls_if"></block>
|
||||
<block type="logic_compare"></block>
|
||||
<block type="logic_operation"></block>
|
||||
@@ -421,7 +421,7 @@ h1 {
|
||||
<block type="logic_null" disabled="true"></block>
|
||||
<block type="logic_ternary"></block>
|
||||
</category>
|
||||
<category name="Loops" colour="%{BKY_LOOPS_HUE}">
|
||||
<category name="Loops" style="loop_category">
|
||||
<block type="controls_repeat_ext">
|
||||
<value name="TIMES">
|
||||
<shadow type="math_number">
|
||||
@@ -451,7 +451,7 @@ h1 {
|
||||
<block type="controls_forEach"></block>
|
||||
<block type="controls_flow_statements"></block>
|
||||
</category>
|
||||
<category name="Math" colour="%{BKY_MATH_HUE}">
|
||||
<category name="Math" style="math_category">
|
||||
<block type="math_number" gap="32">
|
||||
<field name="NUM">123</field>
|
||||
</block>
|
||||
@@ -552,7 +552,7 @@ h1 {
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
<category name="Text" colour="%{BKY_TEXTS_HUE}">
|
||||
<category name="Text" style="text_category">
|
||||
<block type="text"></block>
|
||||
<block type="text_join"></block>
|
||||
<block type="text_append">
|
||||
@@ -654,7 +654,7 @@ h1 {
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
<category name="Lists" colour="%{BKY_LISTS_HUE}">
|
||||
<category name="Lists" style="list_category">
|
||||
<block type="lists_create_with">
|
||||
<mutation items="0"></mutation>
|
||||
</block>
|
||||
@@ -706,7 +706,7 @@ h1 {
|
||||
<block type="lists_sort"></block>
|
||||
<block type="lists_reverse"></block>
|
||||
</category>
|
||||
<category name="Colour" colour="%{BKY_COLOUR_HUE}">
|
||||
<category name="Colour" style="colour_category">
|
||||
<block type="colour_picker"></block>
|
||||
<block type="colour_random"></block>
|
||||
<block type="colour_rgb">
|
||||
@@ -745,15 +745,15 @@ h1 {
|
||||
</block>
|
||||
</category>
|
||||
<sep></sep>
|
||||
<category name="Variables" colour="%{BKY_VARIABLES_HUE}" custom="VARIABLE"></category>
|
||||
<category name="Functions" colour="%{BKY_PROCEDURES_HUE}" custom="PROCEDURE"></category>
|
||||
<category name="Variables" style="variable_category" custom="VARIABLE"></category>
|
||||
<category name="Functions" style="procedure_category" custom="PROCEDURE"></category>
|
||||
</xml>
|
||||
|
||||
<!-- toolbox-categories-typed-variables has a category menu and an
|
||||
auto-closing flyout. The Variables category uses typed variable blocks.
|
||||
See https://developers.google.com/blockly/guides/create-custom-blocks/variables#typed_variable_blocks for more information. -->
|
||||
<xml id="toolbox-categories-typed-variables" style="display: none">
|
||||
<category name="Logic" colour="%{BKY_LOGIC_HUE}">
|
||||
<category name="Logic" style="logic_category">
|
||||
<block type="controls_if"></block>
|
||||
<block type="logic_compare"></block>
|
||||
<block type="logic_operation"></block>
|
||||
@@ -762,7 +762,7 @@ h1 {
|
||||
<block type="logic_null" disabled="true"></block>
|
||||
<block type="logic_ternary"></block>
|
||||
</category>
|
||||
<category name="Loops" colour="%{BKY_LOOPS_HUE}">
|
||||
<category name="Loops" style="loop_category">
|
||||
<block type="controls_repeat_ext">
|
||||
<value name="TIMES">
|
||||
<shadow type="math_number">
|
||||
@@ -792,7 +792,7 @@ h1 {
|
||||
<block type="controls_forEach"></block>
|
||||
<block type="controls_flow_statements"></block>
|
||||
</category>
|
||||
<category name="Math" colour="%{BKY_MATH_HUE}">
|
||||
<category name="Math" style="math_category">
|
||||
<block type="math_number" gap="32">
|
||||
<field name="NUM">123</field>
|
||||
</block>
|
||||
@@ -893,7 +893,7 @@ h1 {
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
<category name="Text" colour="%{BKY_TEXTS_HUE}">
|
||||
<category name="Text" style="text_category">
|
||||
<block type="text"></block>
|
||||
<block type="text_join"></block>
|
||||
<block type="text_append">
|
||||
@@ -995,7 +995,7 @@ h1 {
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
<category name="Lists" colour="%{BKY_LISTS_HUE}">
|
||||
<category name="Lists" style="list_category">
|
||||
<block type="lists_create_with">
|
||||
<mutation items="0"></mutation>
|
||||
</block>
|
||||
@@ -1047,7 +1047,7 @@ h1 {
|
||||
<block type="lists_sort"></block>
|
||||
<block type="lists_reverse"></block>
|
||||
</category>
|
||||
<category name="Colour" colour="%{BKY_COLOUR_HUE}">
|
||||
<category name="Colour" style="colour_category">
|
||||
<block type="colour_picker"></block>
|
||||
<block type="colour_random"></block>
|
||||
<block type="colour_rgb">
|
||||
@@ -1086,8 +1086,8 @@ h1 {
|
||||
</block>
|
||||
</category>
|
||||
<sep></sep>
|
||||
<category name="Variables" colour="%{BKY_VARIABLES_DYNAMIC_HUE}" custom="VARIABLE_DYNAMIC"></category>
|
||||
<category name="Functions" colour="%{BKY_PROCEDURES_HUE}" custom="PROCEDURE"></category>
|
||||
<category name="Variables" style="variable_category" custom="VARIABLE_DYNAMIC"></category>
|
||||
<category name="Functions" style="procedure_category" custom="PROCEDURE"></category>
|
||||
</xml>
|
||||
|
||||
<!-- toolbox-test-blocks has a category menu and an auto-closing flyout.
|
||||
|
||||
@@ -63,4 +63,34 @@ var defaultBlockStyles = {
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Themes.Classic = new Blockly.Theme(defaultBlockStyles);
|
||||
var categoryStyles = {
|
||||
"colour_category":{
|
||||
"colour": "20"
|
||||
},
|
||||
"list_category": {
|
||||
"colour": "260"
|
||||
},
|
||||
"logic_category": {
|
||||
"colour": "210"
|
||||
},
|
||||
"loop_category": {
|
||||
"colour": "120"
|
||||
},
|
||||
"math_category": {
|
||||
"colour": "230"
|
||||
},
|
||||
"procedure_category": {
|
||||
"colour": "290"
|
||||
},
|
||||
"text_category": {
|
||||
"colour": "160"
|
||||
},
|
||||
"variable_category": {
|
||||
"colour": "330"
|
||||
},
|
||||
"variable_dynamic_category":{
|
||||
"colour": "310"
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Themes.Classic = new Blockly.Theme(defaultBlockStyles, categoryStyles);
|
||||
|
||||
@@ -82,5 +82,35 @@ var defaultBlockStyles = {
|
||||
}
|
||||
};
|
||||
|
||||
var categoryStyles = {
|
||||
"colour_category":{
|
||||
"colour": "#a52714",
|
||||
},
|
||||
"list_category": {
|
||||
"colour": "#4a148c",
|
||||
},
|
||||
"logic_category": {
|
||||
"colour": "#01579b",
|
||||
},
|
||||
"loop_category": {
|
||||
"colour": "#33691e",
|
||||
},
|
||||
"math_category": {
|
||||
"colour": "#1a237e",
|
||||
},
|
||||
"procedure_category": {
|
||||
"colour": "#006064",
|
||||
},
|
||||
"text_category": {
|
||||
"colour": "#004d40",
|
||||
},
|
||||
"variable_category": {
|
||||
"colour": "#880e4f",
|
||||
},
|
||||
"variable_dynamic_category":{
|
||||
"colour": "#880e4f",
|
||||
}
|
||||
};
|
||||
|
||||
//This style is still being fleshed out and may change.
|
||||
Blockly.Themes.HighContrast = new Blockly.Theme(defaultBlockStyles);
|
||||
Blockly.Themes.HighContrast = new Blockly.Theme(defaultBlockStyles, categoryStyles);
|
||||
|
||||
@@ -82,5 +82,35 @@ var defaultBlockStyles = {
|
||||
}
|
||||
};
|
||||
|
||||
var categoryStyles = {
|
||||
"colour_category":{
|
||||
"colour": "#a5745b",
|
||||
},
|
||||
"list_category": {
|
||||
"colour": "#745ba5",
|
||||
},
|
||||
"logic_category": {
|
||||
"colour": "#5b80a5",
|
||||
},
|
||||
"loop_category": {
|
||||
"colour": "#5ba55b",
|
||||
},
|
||||
"math_category": {
|
||||
"colour": "#5b67a5",
|
||||
},
|
||||
"procedure_category": {
|
||||
"colour": "#995ba5",
|
||||
},
|
||||
"text_category": {
|
||||
"colour": "#5ba58c",
|
||||
},
|
||||
"variable_category": {
|
||||
"colour": "#a55b99",
|
||||
},
|
||||
"variable_dynamic_category":{
|
||||
"colour": "#a55b99",
|
||||
}
|
||||
};
|
||||
|
||||
//This style is still being fleshed out and may change.
|
||||
Blockly.Themes.Modern = new Blockly.Theme(defaultBlockStyles);
|
||||
Blockly.Themes.Modern = new Blockly.Theme(defaultBlockStyles, categoryStyles);
|
||||
|
||||
Reference in New Issue
Block a user