From 55997784ca6cd7f5fbcfc9f113022d3c9f49ffe8 Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Fri, 6 Dec 2019 10:51:36 -0800 Subject: [PATCH] Move blockStyles into constants (#3485) * Move blockStyles into constants. --- blockly_uncompressed.js | 3 +- core/block_svg.js | 11 +- core/renderers/common/constants.js | 130 +++++++++++++++++++++++ core/renderers/common/path_object.js | 6 +- core/renderers/common/renderer.js | 7 +- core/renderers/geras/path_object.js | 6 +- core/renderers/geras/renderer.js | 6 +- core/renderers/zelos/constants.js | 16 +++ core/renderers/zelos/path_object.js | 7 +- core/renderers/zelos/renderer.js | 6 +- core/theme.js | 145 +------------------------- core/theme/zelos.js | 117 +++++++++++++++++++++ core/toolbox.js | 2 +- core/workspace_svg.js | 3 + demos/custom-fields/turtle/index.html | 3 +- tests/mocha/theme_test.js | 41 +++++--- tests/playground.html | 7 +- tests/rendering/zelos/zelos.html | 7 ++ 18 files changed, 346 insertions(+), 177 deletions(-) create mode 100644 core/theme/zelos.js diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js index 6ac4ce25a..ee5292084 100644 --- a/blockly_uncompressed.js +++ b/blockly_uncompressed.js @@ -89,7 +89,7 @@ goog.addDependency("../../core/options.js", ['Blockly.Options'], ['Blockly.Theme goog.addDependency("../../core/procedures.js", ['Blockly.Procedures'], ['Blockly.Blocks', 'Blockly.constants', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.Msg', 'Blockly.Names', 'Blockly.utils.xml', 'Blockly.Workspace', 'Blockly.Xml']); goog.addDependency("../../core/rendered_connection.js", ['Blockly.RenderedConnection'], ['Blockly.Connection', 'Blockly.Events', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom', 'Blockly.utils.object']); goog.addDependency("../../core/renderers/common/block_rendering.js", ['Blockly.blockRendering'], ['Blockly.utils.object']); -goog.addDependency("../../core/renderers/common/constants.js", ['Blockly.blockRendering.ConstantProvider'], ['Blockly.utils.dom', 'Blockly.utils.svgPaths', 'Blockly.utils.userAgent']); +goog.addDependency("../../core/renderers/common/constants.js", ['Blockly.blockRendering.ConstantProvider'], ['Blockly.utils', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.svgPaths', 'Blockly.utils.userAgent']); goog.addDependency("../../core/renderers/common/debugger.js", ['Blockly.blockRendering.Debug'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types']); goog.addDependency("../../core/renderers/common/drawer.js", ['Blockly.blockRendering.Drawer'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types', 'Blockly.utils.svgPaths']); goog.addDependency("../../core/renderers/common/i_path_object.js", ['Blockly.blockRendering.IPathObject'], []); @@ -134,6 +134,7 @@ goog.addDependency("../../core/theme/deuteranopia.js", ['Blockly.Themes.Deuteran goog.addDependency("../../core/theme/highcontrast.js", ['Blockly.Themes.HighContrast'], ['Blockly.Theme']); goog.addDependency("../../core/theme/modern.js", ['Blockly.Themes.Modern'], ['Blockly.Theme']); goog.addDependency("../../core/theme/tritanopia.js", ['Blockly.Themes.Tritanopia'], ['Blockly.Theme']); +goog.addDependency("../../core/theme/zelos.js", ['Blockly.Themes.Zelos'], ['Blockly.Theme']); goog.addDependency("../../core/theme_manager.js", ['Blockly.ThemeManager'], ['Blockly.Theme']); goog.addDependency("../../core/toolbox.js", ['Blockly.Toolbox'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.Ui', 'Blockly.navigation', 'Blockly.Touch', 'Blockly.tree.TreeControl', 'Blockly.tree.TreeNode', 'Blockly.utils', 'Blockly.utils.aria', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.Rect']); goog.addDependency("../../core/tooltip.js", ['Blockly.Tooltip'], ['Blockly.utils.string']); diff --git a/core/block_svg.js b/core/block_svg.js index 4697f7405..571b7b8e9 100644 --- a/core/block_svg.js +++ b/core/block_svg.js @@ -68,14 +68,15 @@ Blockly.BlockSvg = function(workspace, prototypeName, opt_id) { * A block style object. * @type {!Blockly.Theme.BlockStyle} */ - this.style = workspace.getTheme().getBlockStyle(null); + this.style = workspace.getRenderer().getConstants().getBlockStyle(null); /** * The renderer's path object. * @type {Blockly.blockRendering.IPathObject} * @package */ - this.pathObject = workspace.getRenderer().makePathObject(this.svgGroup_); + this.pathObject = workspace.getRenderer().makePathObject( + this.svgGroup_, this.style); /** @type {boolean} */ this.rendered = false; @@ -1219,7 +1220,8 @@ Blockly.BlockSvg.prototype.getColour = function() { */ Blockly.BlockSvg.prototype.setColour = function(colour) { Blockly.BlockSvg.superClass_.setColour.call(this, colour); - var styleObj = this.workspace.getTheme().getBlockStyleForColour(this.colour_); + var styleObj = this.workspace.getRenderer().getConstants() + .getBlockStyleForColour(this.colour_); this.pathObject.setStyle(styleObj.style); this.style = styleObj.style; @@ -1234,7 +1236,8 @@ Blockly.BlockSvg.prototype.setColour = function(colour) { * @throws {Error} if the block style does not exist. */ Blockly.BlockSvg.prototype.setStyle = function(blockStyleName) { - var blockStyle = this.workspace.getTheme().getBlockStyle(blockStyleName); + var blockStyle = this.workspace.getRenderer() + .getConstants().getBlockStyle(blockStyleName); this.styleName_ = blockStyleName; if (blockStyle) { diff --git a/core/renderers/common/constants.js b/core/renderers/common/constants.js index d679b2ca1..0ad536f16 100644 --- a/core/renderers/common/constants.js +++ b/core/renderers/common/constants.js @@ -23,6 +23,8 @@ goog.provide('Blockly.blockRendering.ConstantProvider'); +goog.require('Blockly.utils'); +goog.require('Blockly.utils.colour'); goog.require('Blockly.utils.dom'); goog.require('Blockly.utils.svgPaths'); goog.require('Blockly.utils.userAgent'); @@ -481,6 +483,134 @@ Blockly.blockRendering.ConstantProvider.prototype.init = function() { this.OUTSIDE_CORNERS = this.makeOutsideCorners(); }; +/** + * Refresh constants properties that depend on the theme. + * @param {!Blockly.Theme} theme The current workspace theme. + * @package + */ +Blockly.blockRendering.ConstantProvider.prototype.refreshTheme = function( + theme) { + + /** + * The block styles map. + * @type {Object.} + * @package + */ + this.blockStyles = {}; + + var blockStyles = theme.blockStyles; + for (var key in blockStyles) { + this.blockStyles[key] = this.validatedBlockStyle_(blockStyles[key]); + } +}; + +/** + * Get or create a block style based on a single colour value. Generate a name + * for the style based on the colour. + * @param {string} colour #RRGGBB colour string. + * @return {{style: !Blockly.Theme.BlockStyle, name: string}} An object + * containing the style and an autogenerated name for that style. + * @package + */ +Blockly.blockRendering.ConstantProvider.prototype.getBlockStyleForColour = + function(colour) { + /* eslint-disable indent */ + var name = 'auto_' + colour; + if (!this.blockStyles[name]) { + this.blockStyles[name] = this.createBlockStyle_(colour); + } + return {style: this.blockStyles[name], name: name}; +}; /* eslint-enable indent */ + +/** + * Gets the BlockStyle for the given block style name. + * @param {?string} blockStyleName The name of the block style. + * @return {!Blockly.Theme.BlockStyle} The named block style, or a default style + * if no style with the given name was found. + */ +Blockly.blockRendering.ConstantProvider.prototype.getBlockStyle = function( + blockStyleName) { + return this.blockStyles[blockStyleName || ''] || + this.createBlockStyle_('#000000'); +}; + +/** + * Create a block style object based on the given colour. + * @param {string} colour #RRGGBB colour string. + * @return {!Blockly.Theme.BlockStyle} A populated block style based on the + * given colour. + * @protected + */ +Blockly.blockRendering.ConstantProvider.prototype.createBlockStyle_ = function( + colour) { + return this.validatedBlockStyle_({ + colourPrimary: colour + }); +}; + +/** + * Get a full block style object based on the input style object. Populate + * any missing values. + * @param {{ + * colourPrimary:string, + * colourSecondary:(string|undefined), + * colourTertiary:(string|undefined), + * hat:(string|undefined) + * }} blockStyle A full or partial block style object. + + * @return {!Blockly.Theme.BlockStyle} A full block style object, with all + * required properties populated. + * @protected + */ +Blockly.blockRendering.ConstantProvider.prototype.validatedBlockStyle_ = + function(blockStyle) { + /* eslint-disable indent */ + // Make a new object with all of the same properties. + var valid = /** @type {!Blockly.Theme.BlockStyle} */ ({}); + if (blockStyle) { + Blockly.utils.object.mixin(valid, blockStyle); + } + + // Validate required properties. + var parsedColour = Blockly.utils.parseBlockColour( + valid['colourPrimary'] || '#000'); + valid.colourPrimary = parsedColour.hex; + valid.colourSecondary = valid['colourSecondary'] ? + Blockly.utils.parseBlockColour(valid['colourSecondary']).hex : + this.generateSecondaryColour_(valid.colourPrimary); + valid.colourTertiary = valid.colourTertiary ? + Blockly.utils.parseBlockColour(valid['colourTertiary']).hex : + this.generateTertiaryColour_(valid.colourPrimary); + + valid.hat = valid['hat'] || ''; + return valid; +}; /* eslint-enable indent */ + +/** + * Generate a secondary colour from the passed in primary colour. + * @param {string} colour Primary colour. + * @return {string} The generated secondary colour. + * @protected + */ +Blockly.blockRendering.ConstantProvider.prototype.generateSecondaryColour_ = + function(colour) { + /* eslint-disable indent */ + return Blockly.utils.colour.blend('#fff', colour, 0.6) || colour; +}; /* eslint-enable indent */ + +/** + * Generate a tertiary colour from the passed in primary colour. + * @param {string} colour Primary colour. + * @return {string} The generated tertiary colour. + * @protected + */ +Blockly.blockRendering.ConstantProvider.prototype.generateTertiaryColour_ = + function(colour) { + /* eslint-disable indent */ + return Blockly.utils.colour.blend('#fff', colour, 0.3) || colour; +}; /* eslint-enable indent */ + + /** * Dispose of this constants provider. * Delete all DOM elements that this provider created. diff --git a/core/renderers/common/path_object.js b/core/renderers/common/path_object.js index bf2063cfe..c52996638 100644 --- a/core/renderers/common/path_object.js +++ b/core/renderers/common/path_object.js @@ -34,13 +34,15 @@ goog.require('Blockly.utils.dom'); * An object that handles creating and setting each of the SVG elements * used by the renderer. * @param {!SVGElement} root The root SVG element. + * @param {!Blockly.Theme.BlockStyle} style The style object to use for + * colouring. * @param {!Blockly.blockRendering.ConstantProvider} constants The renderer's * constants. * @constructor * @implements {Blockly.blockRendering.IPathObject} * @package */ -Blockly.blockRendering.PathObject = function(root, constants) { +Blockly.blockRendering.PathObject = function(root, style, constants) { /** * The renderer's constant provider. * @type {!Blockly.blockRendering.ConstantProvider} @@ -63,7 +65,7 @@ Blockly.blockRendering.PathObject = function(root, constants) { * @type {!Blockly.Theme.BlockStyle} * @package */ - this.style = Blockly.Theme.createBlockStyle('#000000'); + this.style = style; /** * Holds the cursors svg element when the cursor is attached to the block. diff --git a/core/renderers/common/renderer.js b/core/renderers/common/renderer.js index 51992224e..92c07083f 100644 --- a/core/renderers/common/renderer.js +++ b/core/renderers/common/renderer.js @@ -126,11 +126,14 @@ Blockly.blockRendering.Renderer.prototype.makeMarkerDrawer = function( /** * Create a new instance of a renderer path object. * @param {!SVGElement} root The root SVG element. + * @param {!Blockly.Theme.BlockStyle} style The style object to use for + * colouring. * @return {!Blockly.blockRendering.IPathObject} The renderer path object. * @package */ -Blockly.blockRendering.Renderer.prototype.makePathObject = function(root) { - return new Blockly.blockRendering.PathObject(root, +Blockly.blockRendering.Renderer.prototype.makePathObject = function(root, + style) { + return new Blockly.blockRendering.PathObject(root, style, /** @type {!Blockly.blockRendering.ConstantProvider} */ (this.constants_)); }; diff --git a/core/renderers/geras/path_object.js b/core/renderers/geras/path_object.js index 8bf6cfe34..33143d729 100644 --- a/core/renderers/geras/path_object.js +++ b/core/renderers/geras/path_object.js @@ -35,12 +35,14 @@ goog.require('Blockly.utils.object'); * An object that handles creating and setting each of the SVG elements * used by the renderer. * @param {!SVGElement} root The root SVG element. + * @param {!Blockly.Theme.BlockStyle} style The style object to use for + * colouring. * @param {!Blockly.geras.ConstantProvider} constants The renderer's constants. * @constructor * @extends {Blockly.blockRendering.PathObject} * @package */ -Blockly.geras.PathObject = function(root, constants) { +Blockly.geras.PathObject = function(root, style, constants) { /** * The renderer's constant provider. * @type {!Blockly.geras.ConstantProvider} @@ -89,7 +91,7 @@ Blockly.geras.PathObject = function(root, constants) { * @type {!Blockly.Theme.BlockStyle} * @package */ - this.style = Blockly.Theme.createBlockStyle('#000000'); + this.style = style; }; Blockly.utils.object.inherits(Blockly.geras.PathObject, Blockly.blockRendering.PathObject); diff --git a/core/renderers/geras/renderer.js b/core/renderers/geras/renderer.js index 769ff3f34..32508972b 100644 --- a/core/renderers/geras/renderer.js +++ b/core/renderers/geras/renderer.js @@ -99,12 +99,14 @@ Blockly.geras.Renderer.prototype.makeDrawer_ = function(block, info) { /** * Create a new instance of a renderer path object. * @param {!SVGElement} root The root SVG element. + * @param {!Blockly.Theme.BlockStyle} style The style object to use for + * colouring. * @return {!Blockly.geras.PathObject} The renderer path object. * @package * @override */ -Blockly.geras.Renderer.prototype.makePathObject = function(root) { - return new Blockly.geras.PathObject(root, +Blockly.geras.Renderer.prototype.makePathObject = function(root, style) { + return new Blockly.geras.PathObject(root, style, /** @type {!Blockly.geras.ConstantProvider} */ (this.getConstants())); }; diff --git a/core/renderers/zelos/constants.js b/core/renderers/zelos/constants.js index 81ebb784d..f3a2083ab 100644 --- a/core/renderers/zelos/constants.js +++ b/core/renderers/zelos/constants.js @@ -536,6 +536,22 @@ Blockly.zelos.ConstantProvider.prototype.makeInsideCorners = function() { }; }; +/** + * @override + */ +Blockly.zelos.ConstantProvider.prototype.generateSecondaryColour_ = function( + colour) { + return Blockly.utils.colour.blend('#000', colour, 0.15) || colour; +}; + +/** + * @override + */ +Blockly.zelos.ConstantProvider.prototype.generateTertiaryColour_ = function( + colour) { + return Blockly.utils.colour.blend('#000', colour, 0.25) || colour; +}; + /** * @override */ diff --git a/core/renderers/zelos/path_object.js b/core/renderers/zelos/path_object.js index 9a1206331..d3c7f94ca 100644 --- a/core/renderers/zelos/path_object.js +++ b/core/renderers/zelos/path_object.js @@ -34,13 +34,16 @@ goog.require('Blockly.utils.object'); * An object that handles creating and setting each of the SVG elements * used by the renderer. * @param {!SVGElement} root The root SVG element. + * @param {!Blockly.Theme.BlockStyle} style The style object to use for + * colouring. * @param {!Blockly.zelos.ConstantProvider} constants The renderer's constants. * @constructor * @extends {Blockly.blockRendering.PathObject} * @package */ -Blockly.zelos.PathObject = function(root, constants) { - Blockly.zelos.PathObject.superClass_.constructor.call(this, root, constants); +Blockly.zelos.PathObject = function(root, style, constants) { + Blockly.zelos.PathObject.superClass_.constructor.call(this, root, style, + constants); /** * The renderer's constant provider. diff --git a/core/renderers/zelos/renderer.js b/core/renderers/zelos/renderer.js index e620fb82a..5f805baf8 100644 --- a/core/renderers/zelos/renderer.js +++ b/core/renderers/zelos/renderer.js @@ -98,12 +98,14 @@ Blockly.zelos.Renderer.prototype.makeMarkerDrawer = function( /** * Create a new instance of a renderer path object. * @param {!SVGElement} root The root SVG element. + * @param {!Blockly.Theme.BlockStyle} style The style object to use for + * colouring. * @return {!Blockly.zelos.PathObject} The renderer path object. * @package * @override */ -Blockly.zelos.Renderer.prototype.makePathObject = function(root) { - return new Blockly.zelos.PathObject(root, +Blockly.zelos.Renderer.prototype.makePathObject = function(root, style) { + return new Blockly.zelos.PathObject(root, style, /** @type {!Blockly.zelos.ConstantProvider} */ (this.getConstants())); }; diff --git a/core/theme.js b/core/theme.js index eab7a856e..70aa6fba2 100644 --- a/core/theme.js +++ b/core/theme.js @@ -47,22 +47,20 @@ Blockly.Theme = function(name, blockStyles, categoryStyles, * @package */ this.name = name; + /** * The block styles map. * @type {!Object.} - * @private + * @package */ - this.blockStyles_ = {}; - - // Make sure all styles are valid before inserting them into the map. - this.setAllBlockStyles(blockStyles); + this.blockStyles = blockStyles; /** * The category styles map. * @type {!Object.} - * @private + * @package */ - this.categoryStyles_ = categoryStyles; + this.categoryStyles = categoryStyles; /** * The UI components styles map. @@ -91,139 +89,6 @@ Blockly.Theme.BlockStyle; */ Blockly.Theme.CategoryStyle; -/** - * Overrides or adds all values from blockStyles to blockStyles_ - * @param {Object.} blockStyles Map of - * block styles. - */ -Blockly.Theme.prototype.setAllBlockStyles = function(blockStyles) { - for (var key in blockStyles) { - this.setBlockStyle(key, blockStyles[key]); - } -}; - -/** - * Gets a map of all the block style names. - * @return {!Object.} Map of block styles. - */ -Blockly.Theme.prototype.getAllBlockStyles = function() { - return this.blockStyles_; -}; - -/** - * Gets the BlockStyle for the given block style name. - * @param {?string} blockStyleName The name of the block style. - * @return {!Blockly.Theme.BlockStyle} The named block style, or a default style - * if no style with the given name was found. - */ -Blockly.Theme.prototype.getBlockStyle = function(blockStyleName) { - return this.blockStyles_[blockStyleName || ''] || - Blockly.Theme.createBlockStyle('#000000'); -}; - -/** - * Overrides or adds a style to the blockStyles map. - * @param {string} blockStyleName The name of the block style. - * @param {Blockly.Theme.BlockStyle} blockStyle The block style. - */ -Blockly.Theme.prototype.setBlockStyle = function(blockStyleName, blockStyle) { - blockStyle = Blockly.Theme.validatedBlockStyle(blockStyle); - this.blockStyles_[blockStyleName] = blockStyle; -}; - -/** - * Get or create a block style based on a single colour value. Generate a name - * for the style based on the colour. - * @param {string} colour #RRGGBB colour string. - * @return {{style: !Blockly.Theme.BlockStyle, name: string}} An object - * containing the style and an autogenerated name for that style. - * @package - */ -Blockly.Theme.prototype.getBlockStyleForColour = function(colour) { - var name = 'auto_' + colour; - if (!this.blockStyles_[name]) { - this.blockStyles_[name] = Blockly.Theme.createBlockStyle(colour); - } - return {style: this.blockStyles_[name], name: name}; -}; - -/** - * Create a block style object based on the given colour. - * @param {string} colour #RRGGBB colour string. - * @return {!Blockly.Theme.BlockStyle} A populated block style based on the - * given colour. - * @package - */ -Blockly.Theme.createBlockStyle = function(colour) { - return { - colourPrimary: colour, - colourSecondary: Blockly.utils.colour.blend('#fff', colour, 0.6) || colour, - colourTertiary: Blockly.utils.colour.blend('#fff', colour, 0.3) || colour, - hat: '' - }; -}; - -/** - * Get a full block style object based on the input style object. Populate - * any missing values. - * @param {Blockly.Theme.BlockStyle} blockStyle A full or partial block - * style object. - * @return {!Blockly.Theme.BlockStyle} A full block style object, with all - * required properties populated. - * @package - */ -Blockly.Theme.validatedBlockStyle = function(blockStyle) { - // Make a new object with all of the same properties. - var valid = /** @type {!Blockly.Theme.BlockStyle} */ ({}); - if (blockStyle) { - Blockly.utils.object.mixin(valid, blockStyle); - } - - // Validate required properties. - var parsedColour = Blockly.utils.parseBlockColour( - valid['colourPrimary'] || '#000'); - valid.colourPrimary = parsedColour.hex; - valid.colourSecondary = valid['colourSecondary'] ? - Blockly.utils.parseBlockColour(valid['colourSecondary']).hex : - Blockly.utils.colour.blend('#fff', valid.colourPrimary, 0.6) || - valid.colourPrimary; - valid.colourTertiary = valid.colourTertiary ? - Blockly.utils.parseBlockColour(valid['colourTertiary']).hex : - Blockly.utils.colour.blend('#fff', valid.colourPrimary, 0.3) || - valid.colourPrimary; - - valid.hat = valid['hat'] || ''; - return valid; -}; - -/** - * Gets the CategoryStyle for the given category style name. - * @param {string} categoryStyleName The name of the category style. - * @return {Blockly.Theme.CategoryStyle|undefined} The named category style. - */ -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.Theme.CategoryStyle} categoryStyle The category style. -*/ -Blockly.Theme.prototype.setCategoryStyle = function(categoryStyleName, - categoryStyle) { - this.categoryStyles_[categoryStyleName] = categoryStyle; -}; - -/** - * Gets a map of all the category style names. - * @return {!Object.} Map of category - * styles. - */ -Blockly.Theme.prototype.getAllCategoryStyles = function() { - return this.categoryStyles_; -}; - /** * Gets the style for a given Blockly UI component. If the style value is a * string, we attempt to find the value of any named references. diff --git a/core/theme/zelos.js b/core/theme/zelos.js new file mode 100644 index 000000000..c6305ee62 --- /dev/null +++ b/core/theme/zelos.js @@ -0,0 +1,117 @@ +/** + * @license + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview Zelos theme. + */ +'use strict'; + +goog.provide('Blockly.Themes.Zelos'); + +goog.require('Blockly.Theme'); + + +// Temporary holding object. +Blockly.Themes.Zelos = {}; + +Blockly.Themes.Zelos.defaultBlockStyles = { + "colour_blocks": { + "colourPrimary": "#CF63CF", + "colourSecondary": "#C94FC9", + "colourTertiary": "#BD42BD" + }, + "list_blocks": { + "colourPrimary": "#9966FF", + "colourSecondary": "#855CD6", + "colourTertiary": "#774DCB" + }, + "logic_blocks": { + "colourPrimary": "#4C97FF", + "colourSecondary": "#4280D7", + "colourTertiary": "#3373CC" + }, + "loop_blocks": { + "colourPrimary": "#0fBD8C", + "colourSecondary": "#0DA57A", + "colourTertiary": "#0B8E69" + }, + "math_blocks": { + "colourPrimary": "#59C059", + "colourSecondary": "#46B946", + "colourTertiary": "#389438" + }, + "procedure_blocks": { + "colourPrimary": "#FF6680", + "colourSecondary": "#FF4D6A", + "colourTertiary": "#FF3355" + }, + "text_blocks": { + "colourPrimary": "#FFBF00", + "colourSecondary": "#E6AC00", + "colourTertiary": "#CC9900" + }, + "variable_blocks": { + "colourPrimary": "#FF8C1A", + "colourSecondary": "#FF8000", + "colourTertiary": "#DB6E00" + }, + "variable_dynamic_blocks": { + "colourPrimary": "#FF8C1A", + "colourSecondary": "#FF8000", + "colourTertiary": "#DB6E00" + }, + "hat_blocks": { + "colourPrimary": "#4C97FF", + "colourSecondary": "#4280D7", + "colourTertiary": "#3373CC", + "hat": "cap" + } +}; + +Blockly.Themes.Zelos.categoryStyles = { + "colour_category": { + "colour": "#CF63CF" + }, + "list_category": { + "colour": "#9966FF" + }, + "logic_category": { + "colour": "#4C97FF" + }, + "loop_category": { + "colour": "#0fBD8C" + }, + "math_category": { + "colour": "#59C059" + }, + "procedure_category": { + "colour": "#FF6680" + }, + "text_category": { + "colour": "#FFBF00" + }, + "variable_category": { + "colour": "#FF8C1A" + }, + "variable_dynamic_category": { + "colour": "#FF8C1A" + } +}; + +Blockly.Themes.Zelos = + new Blockly.Theme('zelos', Blockly.Themes.Zelos.defaultBlockStyles, + Blockly.Themes.Zelos.categoryStyles); diff --git a/core/toolbox.js b/core/toolbox.js index 8b939eb61..d029fd390 100644 --- a/core/toolbox.js +++ b/core/toolbox.js @@ -553,7 +553,7 @@ Blockly.Toolbox.prototype.setColourFromStyle_ = function( childOut.styleName = styleName; var theme = this.workspace_.getTheme(); if (styleName && theme) { - var style = theme.getCategoryStyle(styleName); + var style = theme.categoryStyles[styleName]; if (style && style.colour) { this.setColour_(style.colour, childOut, categoryName); } else { diff --git a/core/workspace_svg.js b/core/workspace_svg.js index b904e5e6a..d9c9a781a 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -162,6 +162,7 @@ Blockly.WorkspaceSvg = function(options, this.cachedParentSvg_ = null; this.themeManager_.subscribeWorkspace(this); + this.renderer_.getConstants().refreshTheme(this.getTheme()); }; Blockly.utils.object.inherits(Blockly.WorkspaceSvg, Blockly.Workspace); @@ -473,6 +474,8 @@ Blockly.WorkspaceSvg.prototype.setTheme = function(theme) { * @package */ Blockly.WorkspaceSvg.prototype.refreshTheme = function() { + this.getRenderer().getConstants().refreshTheme(this.getTheme()); + // Update all blocks in workspace that have a style name. this.updateBlockStyles_(this.getAllBlocks(false).filter( function(block) { diff --git a/demos/custom-fields/turtle/index.html b/demos/custom-fields/turtle/index.html index 484fc2b3e..9bc4dfeb2 100644 --- a/demos/custom-fields/turtle/index.html +++ b/demos/custom-fields/turtle/index.html @@ -90,7 +90,8 @@ function setRandomStyle() { var blocks = workspace.getAllBlocks(false); - var styles = Object.keys(workspace.getTheme().getAllBlockStyles()); + var styles = + Object.keys(workspace.getRenderer().getConstants().blockStyles); styles.splice(styles.indexOf(blocks[0].getStyleName()), 1); var style = styles[Math.floor(Math.random() * styles.length)]; for(var i = 0, block; block = blocks[i]; i++) { diff --git a/tests/mocha/theme_test.js b/tests/mocha/theme_test.js index 39beb4d99..0676dbc87 100644 --- a/tests/mocha/theme_test.js +++ b/tests/mocha/theme_test.js @@ -85,20 +85,23 @@ suite('Theme', function() { test('Set All BlockStyles', function() { var theme = new Blockly.Theme('test', createBlockStyles()); - stringifyAndCompare(createBlockStyles(), theme.blockStyles_); - theme.setAllBlockStyles(createMultipleBlockStyles()); - stringifyAndCompare(createMultipleBlockStyles(), theme.blockStyles_); + stringifyAndCompare(createBlockStyles(), theme.blockStyles); + var blockStyles = createMultipleBlockStyles(); + for (var key in blockStyles) { + theme.blockStyles[key] = blockStyles[key]; + } + stringifyAndCompare(createMultipleBlockStyles(), theme.blockStyles); }); test('Get All BlockStyles', function() { var theme = new Blockly.Theme('test', createMultipleBlockStyles()); - var allBlocks = theme.getAllBlockStyles(); + var allBlocks = theme.blockStyles; stringifyAndCompare(createMultipleBlockStyles(), allBlocks); }); test('Get BlockStyles', function() { var theme = new Blockly.Theme('test', createBlockStyles()); - var blockStyle = theme.getBlockStyle('styleOne'); + var blockStyle = theme.blockStyles['styleOne']; stringifyAndCompare(blockStyle, createBlockStyles().styleOne); }); @@ -108,18 +111,18 @@ suite('Theme', function() { var blockStyle = createBlockStyles(); blockStyle.styleOne.colourPrimary = '#00ff00'; - theme.setBlockStyle('styleOne', blockStyle.styleOne); + theme.blockStyles['styleOne'] = blockStyle.styleOne; - stringifyAndCompare(theme.blockStyles_, blockStyle); + stringifyAndCompare(theme.blockStyles, blockStyle); }); test('Set BlockStyle Add', function() { var theme = new Blockly.Theme('test', createBlockStyles()); var blockStyle = createMultipleBlockStyles(); - theme.setBlockStyle('styleTwo', blockStyle.styleTwo); + theme.blockStyles['styleTwo'] = blockStyle.styleTwo; - stringifyAndCompare(theme.blockStyles_, blockStyle); + stringifyAndCompare(theme.blockStyles, blockStyle); }); test('Set Theme', function() { @@ -158,6 +161,10 @@ suite('Theme', function() { }); suite('Validate block styles', function() { + setup(function() { + this.constants = new Blockly.blockRendering.ConstantProvider(); + }); + test('Null', function() { var inputStyle = null; var expectedOutput = { @@ -167,7 +174,7 @@ suite('Theme', function() { "hat": '' }; stringifyAndCompare( - Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput); + this.constants.validatedBlockStyle_(inputStyle), expectedOutput); }); test('Empty', function() { @@ -179,7 +186,7 @@ suite('Theme', function() { "hat": '' }; stringifyAndCompare( - Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput); + this.constants.validatedBlockStyle_(inputStyle), expectedOutput); }); test('Incomplete hex', function() { @@ -193,7 +200,7 @@ suite('Theme', function() { "hat": '' }; stringifyAndCompare( - Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput); + this.constants.validatedBlockStyle_(inputStyle), expectedOutput); }); test('Complete hex', function() { @@ -210,7 +217,7 @@ suite('Theme', function() { "hat": 'cap' }; stringifyAndCompare( - Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput); + this.constants.validatedBlockStyle_(inputStyle), expectedOutput); }); test('Complete hue', function() { @@ -226,7 +233,7 @@ suite('Theme', function() { "hat": '' }; stringifyAndCompare( - Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput); + this.constants.validatedBlockStyle_(inputStyle), expectedOutput); }); test('Incomplete hue', function() { @@ -240,7 +247,7 @@ suite('Theme', function() { "hat": '' }; stringifyAndCompare( - Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput); + this.constants.validatedBlockStyle_(inputStyle), expectedOutput); }); test('Complete css colour name', function() { @@ -256,7 +263,7 @@ suite('Theme', function() { "hat": '' }; stringifyAndCompare( - Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput); + this.constants.validatedBlockStyle_(inputStyle), expectedOutput); }); test('Incomplete css colour name', function() { @@ -270,7 +277,7 @@ suite('Theme', function() { "hat": '' }; stringifyAndCompare( - Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput); + this.constants.validatedBlockStyle_(inputStyle), expectedOutput); }); }); }); diff --git a/tests/playground.html b/tests/playground.html index 425910213..d866fd0d6 100644 --- a/tests/playground.html +++ b/tests/playground.html @@ -72,6 +72,7 @@ goog.require('Blockly.blockRendering.Debug'); goog.require('Blockly.minimalist.Renderer'); goog.require('Blockly.Themes.Modern'); +goog.require('Blockly.Themes.Zelos'); goog.require('Blockly.thrasos.Renderer'); goog.require('Blockly.zelos.Renderer'); @@ -194,7 +195,8 @@ function addToolboxButtonCallbacks() { }; var setRandomStyle = function(button) { var blocks = button.workspace_.getAllBlocks(false); - var styles = Object.keys(workspace.getTheme().getAllBlockStyles()); + var styles = + Object.keys(workspace.getRenderer().getConstants().blockStyles); styles.splice(styles.indexOf(blocks[0].getStyleName()), 1); var style = styles[Math.floor(Math.random() * styles.length)]; for(var i = 0, block; block = blocks[i]; i++) { @@ -331,6 +333,8 @@ function changeTheme() { Blockly.getMainWorkspace().setTheme(Blockly.Themes.Tritanopia); } else if (theme.value === "modern") { Blockly.getMainWorkspace().setTheme(Blockly.Themes.Modern); + } else if (theme.value === "zelos") { + Blockly.getMainWorkspace().setTheme(Blockly.Themes.Zelos); } else { Blockly.getMainWorkspace().setTheme(Blockly.Themes.Classic); } @@ -594,6 +598,7 @@ var spaghettiXml = [ +

diff --git a/tests/rendering/zelos/zelos.html b/tests/rendering/zelos/zelos.html index a9e93bd81..20f4ecd6d 100644 --- a/tests/rendering/zelos/zelos.html +++ b/tests/rendering/zelos/zelos.html @@ -32,8 +32,13 @@