Adds support for category styles

This commit is contained in:
alschmiedt
2019-01-09 11:18:44 -08:00
parent bac9a16da0
commit 40a1ae752b
7 changed files with 249 additions and 37 deletions

View File

@@ -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);

View File

@@ -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;
};

View File

@@ -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.

View File

@@ -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.

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);