Switch to using the style object in the path object.

This commit is contained in:
Rachel Fenichel
2019-10-30 14:22:35 -07:00
parent ca1e49bf8e
commit 5ef08fc0d4
10 changed files with 141 additions and 152 deletions

View File

@@ -252,14 +252,14 @@ Blockly.Block.prototype.hue_ = null;
/**
* Colour of the block in '#RRGGBB' format.
* @type {string}
* @private
* @protected
*/
Blockly.Block.prototype.colour_ = '#000000';
/**
* Name of the block style.
* @type {?string}
* @private
* @protected
*/
Blockly.Block.prototype.styleName_ = null;

View File

@@ -63,6 +63,13 @@ Blockly.BlockSvg = function(workspace, prototypeName, opt_id) {
this.svgGroup_ = Blockly.utils.dom.createSvgElement('g', {}, null);
this.svgGroup_.translate_ = '';
/**
* A block style object.
* @type {!Blockly.Theme.BlockStyle}
* @public
*/
this.style = workspace.getTheme().getBlockStyle(null);
/**
* The renderer's path object.
* @type {Blockly.blockRendering.IPathObject}
@@ -1297,23 +1304,7 @@ Blockly.BlockSvg.prototype.setDeleteStyle = function(enable) {
* @return {string} #RRGGBB string.
*/
Blockly.BlockSvg.prototype.getColour = function() {
return this.pathObject.primaryColour;
};
/**
* Get the secondary colour of a block.
* @return {string} #RRGGBB string.
*/
Blockly.BlockSvg.prototype.getSecondaryColour = function() {
return this.pathObject.primaryColour;
};
/**
* Get the tertiary colour of a block.
* @return {string} #RRGGBB string.
*/
Blockly.BlockSvg.prototype.getTertiaryColour = function() {
return this.pathObject.primaryColour;
return this.style.colourPrimary;
};
/**
@@ -1322,7 +1313,12 @@ Blockly.BlockSvg.prototype.getTertiaryColour = function() {
*/
Blockly.BlockSvg.prototype.setColour = function(colour) {
Blockly.BlockSvg.superClass_.setColour.call(this, colour);
this.pathObject.setColour(colour);
var styleObj = this.workspace.getTheme().getBlockStyleForColour(this.colour_);
this.pathObject.setStyle(styleObj.style);
this.style = styleObj.style;
this.styleName_ = styleObj.name;
this.applyColour();
};
@@ -1332,13 +1328,16 @@ Blockly.BlockSvg.prototype.setColour = function(colour) {
* @throws {Error} if the block style does not exist.
*/
Blockly.BlockSvg.prototype.setStyle = function(blockStyleName) {
var theme = this.workspace.getTheme();
var blockStyle = theme.getBlockStyle(blockStyleName);
var blockStyle = this.workspace.getTheme().getBlockStyle(blockStyleName);
this.styleName_ = blockStyleName;
if (blockStyle) {
this.hat = blockStyle.hat;
this.pathObject.setColourFromStyle(blockStyle);
this.pathObject.setStyle(blockStyle);
// Set colour to match Block.
this.colour_ = blockStyle.colourPrimary;
this.style = blockStyle;
this.applyColour();
} else {
throw Error('Invalid style name: ' + blockStyleName);

View File

@@ -269,8 +269,8 @@ Blockly.FieldAngle.prototype.showEditor_ = function() {
var editor = this.dropdownCreate_();
Blockly.DropDownDiv.getContentDiv().appendChild(editor);
Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(),
this.sourceBlock_.getTertiaryColour());
Blockly.DropDownDiv.setColour(this.sourceBlock_.style.colourPrimary,
this.sourceBlock_.style.colourTertiary);
Blockly.DropDownDiv.showPositionedByField(
this, this.dropdownDispose_.bind(this));

View File

@@ -130,8 +130,8 @@ Blockly.FieldDate.prototype.render_ = function() {
* @package
*/
Blockly.FieldDate.prototype.applyColour = function() {
this.todayColour_ = this.sourceBlock_.getColour();
this.selectedColour_ = this.sourceBlock_.getSecondaryColour();
this.todayColour_ = this.sourceBlock_.style.colourPrimary;
this.selectedColour_ = this.sourceBlock_.style.colourSecondary;
this.updateEditor_();
};

View File

@@ -472,9 +472,9 @@ Blockly.FieldDropdown.prototype.applyColour = function() {
// Update arrow's colour.
if (this.sourceBlock_ && this.arrow_) {
if (this.sourceBlock_.isShadow()) {
this.arrow_.style.fill = this.sourceBlock_.getSecondaryColour();
this.arrow_.style.fill = this.sourceBlock_.style.colourSecondary;
} else {
this.arrow_.style.fill = this.sourceBlock_.getColour();
this.arrow_.style.fill = this.sourceBlock_.style.colourPrimary;
}
}
};

View File

@@ -25,6 +25,8 @@
goog.provide('Blockly.blockRendering.IPathObject');
goog.requireType('Blockly.Theme');
/**
* An interface for a block's path object.
@@ -42,19 +44,11 @@ Blockly.blockRendering.IPathObject = function(_root) {};
Blockly.blockRendering.IPathObject.prototype.applyColour;
/**
* Update colour properties based on a single colour value.
* @param {number|string} colour HSV hue value (0 to 360), #RRGGBB string,
* or a message reference string pointing to one of those two values.
* @package
*/
Blockly.blockRendering.IPathObject.prototype.setColour;
/**
* Update colour properties based on a block style.
* Update the style.
* @param {!Blockly.Theme.BlockStyle} blockStyle The block style to use.
* @package
*/
Blockly.blockRendering.IPathObject.prototype.setColourFromStyle;
Blockly.blockRendering.IPathObject.prototype.setStyle;
/**
* Flip the SVG paths in RTL.

View File

@@ -25,6 +25,7 @@
goog.provide('Blockly.blockRendering.PathObject');
goog.require('Blockly.blockRendering.IPathObject');
goog.require('Blockly.Theme');
goog.require('Blockly.utils.dom');
@@ -60,34 +61,11 @@ Blockly.blockRendering.PathObject = function(root) {
{'class': 'blocklyPathLight'}, this.svgRoot);
/**
* The dark path of the block.
* @type {SVGElement}
* @package
* The style object to use when colouring block paths.
* @type {!Blockly.Theme.BlockStyle}
* @public
*/
this.svgPathDark = Blockly.utils.dom.createSvgElement('path',
{'class': 'blocklyPathDark', 'transform': 'translate(1,1)'},
this.svgRoot);
/**
* Primary colour of the block in '#RRGGBB' format.
* @type {string}
* @package
*/
this.primaryColour = '#000000';
/**
* Secondary colour of the block in '#RRGGBB' format.
* @type {string}
* @package
*/
this.secondaryColour = '#000000';
/**
* Tertiary colour of the block in '#RRGGBB' format.
* @type {string}
* @package
*/
this.tertiaryColour = '#000000';
this.style = Blockly.Theme.createBlockStyle('#0000000');
};
/**
@@ -98,7 +76,6 @@ Blockly.blockRendering.PathObject = function(root) {
Blockly.blockRendering.PathObject.prototype.setPaths = function(pathString) {
this.svgPath.setAttribute('d', pathString);
this.svgPathLight.style.display = 'none';
this.svgPathDark.style.display = 'none';
};
/**
@@ -119,52 +96,18 @@ Blockly.blockRendering.PathObject.prototype.flipRTL = function() {
Blockly.blockRendering.PathObject.prototype.applyColour = function(isShadow) {
if (isShadow) {
this.svgPath.setAttribute('stroke', 'none');
this.svgPath.setAttribute('fill', this.secondaryColour);
this.svgPath.setAttribute('fill', this.style.colourSecondary);
} else {
this.svgPath.setAttribute('stroke', this.tertiaryColour);
this.svgPath.setAttribute('fill', this.primaryColour);
this.svgPath.setAttribute('stroke', this.style.colourTertiary);
this.svgPath.setAttribute('fill', this.style.colourPrimary);
}
};
/**
* Update colour properties based on a triplet of colours.
* @param {string} primary The primary colour.
* @param {?string} secondary The secondary colour, or null to have the colourer
* generate it.
* @param {?string} tertiary The tertiary colour, or null to have the colourer
* generate it.
* @protected
*/
Blockly.blockRendering.PathObject.prototype.setColourFromTriplet_ = function(
primary, secondary, tertiary) {
this.primaryColour = primary;
this.secondaryColour = secondary ||
Blockly.utils.colour.blend('#fff', primary, 0.6);
this.tertiaryColour = tertiary ||
Blockly.utils.colour.blend('#fff', primary, 0.3);
};
/**
* Update colour properties based on a single colour value.
* @param {number|string} colour HSV hue value (0 to 360), #RRGGBB string,
* or a message reference string pointing to one of those two values.
* @package
*/
Blockly.blockRendering.PathObject.prototype.setColour = function(colour) {
var parsed = Blockly.utils.colour.parseBlockColour(colour);
this.setColourFromTriplet_(parsed.hex, null, null);
};
/**
* Update colour properties based on a block style.
* Set the style.
* @param {!Blockly.Theme.BlockStyle} blockStyle The block style to use.
* @package
*/
Blockly.blockRendering.PathObject.prototype.setColourFromStyle = function(
blockStyle) {
var parsed =
Blockly.utils.colour.parseBlockColour(blockStyle['colourPrimary']);
this.setColourFromTriplet_(parsed.hex,
blockStyle['colourSecondary'],
blockStyle['colourTertiary']);
Blockly.blockRendering.PathObject.prototype.setStyle = function(blockStyle) {
this.style = blockStyle;
};

View File

@@ -35,7 +35,6 @@ goog.require('Blockly.utils.object');
* @param {!SVGElement} root The root SVG element.
* @constructor
* @implements {Blockly.blockRendering.IPathObject}
* @extends {Blockly.blockRendering.PathObject}
* @package
*/
Blockly.geras.PathObject = function(root) {
@@ -69,39 +68,20 @@ Blockly.geras.PathObject = function(root) {
this.svgPathLight = Blockly.utils.dom.createSvgElement('path',
{'class': 'blocklyPathLight'}, this.svgRoot);
/**
* Primary colour of the block in '#RRGGBB' format.
* @type {string}
* @package
*/
this.primaryColour = '#000000';
/**
* Secondary colour of the block in '#RRGGBB' format.
* Used for the body of a shadow block in Geras.
* @type {string}
* @package
*/
this.secondaryColour = '#000000';
/**
* Tertiary colour of the block in '#RRGGBB' format.
* Used for the light path (highlight) in Geras.
* @type {string}
* @package
*/
this.tertiaryColour = '#000000';
/**
* The colour of the dark path on the block in '#RRGGBB' format.
* @type {string}
* @package
*/
this.darkColour = '#000000';
/**
* The style object to use when colouring block paths.
* @type {!Blockly.Theme.BlockStyle}
* @public
*/
this.style = Blockly.Theme.createBlockStyle('#0000000');
};
Blockly.utils.object.inherits(Blockly.geras.PathObject,
Blockly.blockRendering.PathObject);
/**
* Set each of the paths generated by the renderer onto the respective SVG element.
@@ -135,26 +115,26 @@ Blockly.geras.PathObject.prototype.flipRTL = function() {
Blockly.geras.PathObject.prototype.applyColour = function(isShadow) {
if (isShadow) {
this.svgPathLight.style.display = 'none';
this.svgPathDark.setAttribute('fill', this.secondaryColour);
this.svgPathDark.setAttribute('fill', this.style.colourSecondary);
this.svgPath.setAttribute('stroke', 'none');
this.svgPath.setAttribute('fill', this.secondaryColour);
this.svgPath.setAttribute('fill', this.style.colourSecondary);
} else {
this.svgPathLight.style.display = '';
this.svgPathDark.style.display = '';
this.svgPath.setAttribute('stroke', 'none');
this.svgPathLight.setAttribute('stroke', this.tertiaryColour);
this.svgPathDark.setAttribute('fill', this.darkColour);
this.svgPath.setAttribute('fill', this.primaryColour);
this.svgPathLight.setAttribute('stroke', this.style.colourTertiary);
this.svgPathDark.setAttribute('fill', this.colourDark);
this.svgPath.setAttribute('fill', this.style.colourPrimary);
}
};
/**
* @override
* Set the style.
* @param {!Blockly.Theme.BlockStyle} blockStyle The block style to use.
* @package
*/
Blockly.geras.PathObject.prototype.setColourFromTriplet_ = function(primary,
secondary, tertiary) {
Blockly.geras.PathObject.superClass_.setColourFromTriplet_.call(this, primary,
secondary, tertiary);
this.darkColour = tertiary ||
Blockly.utils.colour.blend('#000', primary, 0.2);
Blockly.geras.PathObject.prototype.setStyle = function(blockStyle) {
this.style = blockStyle;
this.colourDark =
Blockly.utils.colour.blend('#000', this.style.colourPrimary, 0.2);
};

View File

@@ -22,6 +22,7 @@
goog.provide('Blockly.Theme');
goog.require('Blockly.utils.colour');
/**
* Class for a theme.
@@ -40,7 +41,10 @@ Blockly.Theme = function(blockStyles, categoryStyles, opt_componentStyles) {
* @type {!Object.<string, Blockly.Theme.BlockStyle>}
* @private
*/
this.blockStyles_ = blockStyles;
this.blockStyles_ = {};
// Make sure all styles are valid before insterting them into the map.
this.setAllBlockStyles(blockStyles);
/**
* The category styles map.
@@ -97,22 +101,90 @@ Blockly.Theme.prototype.getAllBlockStyles = function() {
/**
* Gets the BlockStyle for the given block style name.
* @param {string} blockStyleName The name of the block style.
* @return {Blockly.Theme.BlockStyle|undefined} The named block style.
* @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];
var defaultStyle = Blockly.Theme.createBlockStyle('#000000');
if (blockStyleName == null) {
return defaultStyle;
}
return this.blockStyles_[blockStyleName] || defaultStyle;
};
/**
* 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.
*/
* @package
*/
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 = {};
Blockly.utils.object.mixin(valid, blockStyle);
// Validate required properties.
var parsedColour = Blockly.utils.colour.parseBlockColour(
valid.colourPrimary || '#000000');
valid.colourPrimary = parsedColour.hex;
valid.colourSecondary = valid.colourSecondary ||
Blockly.utils.colour.blend('#fff', valid.colourPrimary, 0.6) ||
valid.colourPrimary;
valid.colourTertiary = valid.colourTertiary ||
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.

View File

@@ -229,7 +229,8 @@ Blockly.utils.colour.parseBlockColour = function(colour) {
if (!isNaN(hue) && 0 <= hue && hue <= 360) {
return {
hue: hue,
hex: Blockly.hueToHex(hue)
hex: Blockly.utils.colour.hsvToHex(hue, Blockly.HSV_SATURATION,
Blockly.HSV_VALUE * 255)
};
} else {
var hex = Blockly.utils.colour.parse(dereferenced);