mirror of
https://github.com/google/blockly.git
synced 2026-01-09 18:10:08 +01:00
Merge pull request #3357 from rachel-fenichel/colourer
Move block colouring code from block to the pathObject
This commit is contained in:
@@ -74,7 +74,7 @@ goog.addDependency("../../core/inject.js", ['Blockly.inject'], ['Blockly.BlockDr
|
||||
goog.addDependency("../../core/input.js", ['Blockly.Input'], ['Blockly.Connection', 'Blockly.FieldLabel']);
|
||||
goog.addDependency("../../core/insertion_marker_manager.js", ['Blockly.InsertionMarkerManager'], ['Blockly.blockAnimations', 'Blockly.Events']);
|
||||
goog.addDependency("../../core/keyboard_nav/action.js", ['Blockly.Action'], []);
|
||||
goog.addDependency("../../core/keyboard_nav/ast_node.js", ['Blockly.ASTNode'], []);
|
||||
goog.addDependency("../../core/keyboard_nav/ast_node.js", ['Blockly.ASTNode'], ['Blockly.utils.Coordinate']);
|
||||
goog.addDependency("../../core/keyboard_nav/cursor.js", ['Blockly.Cursor'], []);
|
||||
goog.addDependency("../../core/keyboard_nav/cursor_svg.js", ['Blockly.CursorSvg'], ['Blockly.Cursor', 'Blockly.utils.object']);
|
||||
goog.addDependency("../../core/keyboard_nav/flyout_cursor.js", ['Blockly.FlyoutCursor'], ['Blockly.Cursor', 'Blockly.utils.object']);
|
||||
@@ -92,8 +92,9 @@ goog.addDependency("../../core/renderers/common/block_rendering.js", ['Blockly.b
|
||||
goog.addDependency("../../core/renderers/common/constants.js", ['Blockly.blockRendering.ConstantProvider'], ['Blockly.utils.svgPaths']);
|
||||
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'], []);
|
||||
goog.addDependency("../../core/renderers/common/info.js", ['Blockly.blockRendering.RenderInfo'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.blockRendering.Hat', 'Blockly.blockRendering.InlineInput', 'Blockly.blockRendering.InRowSpacer', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.RoundCorner', 'Blockly.blockRendering.Row', 'Blockly.blockRendering.SpacerRow', 'Blockly.blockRendering.StatementInput', 'Blockly.blockRendering.SquareCorner', 'Blockly.blockRendering.TopRow', 'Blockly.blockRendering.Types']);
|
||||
goog.addDependency("../../core/renderers/common/path_object.js", ['Blockly.blockRendering.IPathObject', 'Blockly.blockRendering.PathObject'], ['Blockly.utils.dom']);
|
||||
goog.addDependency("../../core/renderers/common/path_object.js", ['Blockly.blockRendering.PathObject'], ['Blockly.blockRendering.IPathObject', 'Blockly.Theme', 'Blockly.utils.dom']);
|
||||
goog.addDependency("../../core/renderers/common/renderer.js", ['Blockly.blockRendering.Renderer'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Drawer', 'Blockly.blockRendering.IPathObject', 'Blockly.blockRendering.PathObject', 'Blockly.blockRendering.RenderInfo', 'Blockly.CursorSvg']);
|
||||
goog.addDependency("../../core/renderers/geras/constants.js", ['Blockly.geras.ConstantProvider'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.utils.object']);
|
||||
goog.addDependency("../../core/renderers/geras/drawer.js", ['Blockly.geras.Drawer'], ['Blockly.blockRendering.ConstantProvider', 'Blockly.blockRendering.Drawer', 'Blockly.geras.Highlighter', 'Blockly.geras.PathObject', 'Blockly.geras.RenderInfo', 'Blockly.utils.object', 'Blockly.utils.svgPaths']);
|
||||
@@ -101,7 +102,7 @@ goog.addDependency("../../core/renderers/geras/highlight_constants.js", ['Blockl
|
||||
goog.addDependency("../../core/renderers/geras/highlighter.js", ['Blockly.geras.Highlighter'], ['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/geras/info.js", ['Blockly.geras', 'Blockly.geras.RenderInfo'], ['Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.RenderInfo', 'Blockly.blockRendering.BottomRow', 'Blockly.blockRendering.InputRow', 'Blockly.blockRendering.Measurable', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection', 'Blockly.blockRendering.Types', 'Blockly.blockRendering.ExternalValueInput', 'Blockly.geras.InlineInput', 'Blockly.geras.StatementInput', 'Blockly.utils.object']);
|
||||
goog.addDependency("../../core/renderers/geras/measurables/inputs.js", ['Blockly.geras.InlineInput', 'Blockly.geras.StatementInput'], ['Blockly.utils.object']);
|
||||
goog.addDependency("../../core/renderers/geras/path_object.js", ['Blockly.geras.PathObject'], ['Blockly.blockRendering.IPathObject', 'Blockly.utils.dom']);
|
||||
goog.addDependency("../../core/renderers/geras/path_object.js", ['Blockly.geras.PathObject'], ['Blockly.blockRendering.IPathObject', 'Blockly.utils.dom', 'Blockly.utils.object']);
|
||||
goog.addDependency("../../core/renderers/geras/renderer.js", ['Blockly.geras.Renderer'], ['Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.geras.ConstantProvider', 'Blockly.geras.Drawer', 'Blockly.geras.HighlightConstantProvider', 'Blockly.geras.PathObject', 'Blockly.geras.RenderInfo', 'Blockly.utils.object']);
|
||||
goog.addDependency("../../core/renderers/measurables/base.js", ['Blockly.blockRendering.Measurable'], ['Blockly.blockRendering.Types']);
|
||||
goog.addDependency("../../core/renderers/measurables/connections.js", ['Blockly.blockRendering.Connection', 'Blockly.blockRendering.NextConnection', 'Blockly.blockRendering.OutputConnection', 'Blockly.blockRendering.PreviousConnection'], ['Blockly.blockRendering.Measurable', 'Blockly.blockRendering.Types', 'Blockly.utils.object']);
|
||||
@@ -122,7 +123,7 @@ goog.addDependency("../../core/renderers/zelos/measurables/rows.js", ['Blockly.z
|
||||
goog.addDependency("../../core/renderers/zelos/renderer.js", ['Blockly.zelos.Renderer'], ['Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider', 'Blockly.zelos.Drawer', 'Blockly.zelos.RenderInfo']);
|
||||
goog.addDependency("../../core/requires.js", ['Blockly.requires'], ['Blockly', 'Blockly.Comment', 'Blockly.HorizontalFlyout', 'Blockly.VerticalFlyout', 'Blockly.FlyoutButton', 'Blockly.Generator', 'Blockly.Toolbox', 'Blockly.Trashcan', 'Blockly.VariablesDynamic', 'Blockly.ZoomControls', 'Blockly.Mutator', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldLabelSerializable', 'Blockly.FieldImage', 'Blockly.FieldTextInput', 'Blockly.FieldMultilineInput', 'Blockly.FieldNumber', 'Blockly.FieldVariable', 'Blockly.geras.Renderer', 'Blockly.Themes.Classic', 'Blockly.Themes.Dark', 'Blockly.Themes.Deuteranopia', 'Blockly.Themes.HighContrast', 'Blockly.Themes.Tritanopia']);
|
||||
goog.addDependency("../../core/scrollbar.js", ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['Blockly.Touch', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom']);
|
||||
goog.addDependency("../../core/theme.js", ['Blockly.Theme'], []);
|
||||
goog.addDependency("../../core/theme.js", ['Blockly.Theme'], ['Blockly.utils.colour']);
|
||||
goog.addDependency("../../core/theme/classic.js", ['Blockly.Themes.Classic'], ['Blockly.Theme']);
|
||||
goog.addDependency("../../core/theme/dark.js", ['Blockly.Themes.Dark'], ['Blockly.Theme']);
|
||||
goog.addDependency("../../core/theme/deuteranopia.js", ['Blockly.Themes.Deuteranopia'], ['Blockly.Theme']);
|
||||
|
||||
111
core/block.js
111
core/block.js
@@ -252,30 +252,14 @@ Blockly.Block.prototype.hue_ = null;
|
||||
/**
|
||||
* Colour of the block in '#RRGGBB' format.
|
||||
* @type {string}
|
||||
* @private
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Block.prototype.colour_ = '#000000';
|
||||
|
||||
/**
|
||||
* Secondary colour of the block.
|
||||
* Colour of shadow blocks.
|
||||
* @type {?string}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Block.prototype.colourSecondary_ = null;
|
||||
|
||||
/**
|
||||
* Tertiary colour of the block.
|
||||
* Colour of the block's border.
|
||||
* @type {?string}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Block.prototype.colourTertiary_ = null;
|
||||
|
||||
/**
|
||||
* Name of the block style.
|
||||
* @type {?string}
|
||||
* @private
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Block.prototype.styleName_ = null;
|
||||
|
||||
@@ -908,60 +892,6 @@ Blockly.Block.prototype.getColour = function() {
|
||||
return this.colour_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the secondary colour of a block.
|
||||
* @return {?string} #RRGGBB string.
|
||||
*/
|
||||
Blockly.Block.prototype.getColourSecondary = function() {
|
||||
return this.colourSecondary_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the tertiary colour of a block.
|
||||
* @return {?string} #RRGGBB string.
|
||||
*/
|
||||
Blockly.Block.prototype.getColourTertiary = function() {
|
||||
return this.colourTertiary_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the shadow colour of a block.
|
||||
* @return {?string} #RRGGBB string.
|
||||
*/
|
||||
Blockly.Block.prototype.getColourShadow = function() {
|
||||
var colourSecondary = this.getColourSecondary();
|
||||
if (colourSecondary) {
|
||||
return colourSecondary;
|
||||
}
|
||||
return Blockly.utils.colour.blend('#fff', this.getColour(), 0.6);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the border colour(s) of a block.
|
||||
* @return {{colourDark, colourLight, colourBorder}} An object containing
|
||||
* colour values for the border(s) of the block. If the block is using a
|
||||
* style the colourBorder will be defined and equal to the tertiary colour
|
||||
* of the style (#RRGGBB string). Otherwise the colourDark and colourLight
|
||||
* attributes will be defined (#RRGGBB strings).
|
||||
* @package
|
||||
*/
|
||||
Blockly.Block.prototype.getColourBorder = function() {
|
||||
var colourTertiary = this.getColourTertiary();
|
||||
if (colourTertiary) {
|
||||
return {
|
||||
colourBorder: colourTertiary,
|
||||
colourLight: null,
|
||||
colourDark: null
|
||||
};
|
||||
}
|
||||
var colour = this.getColour();
|
||||
return {
|
||||
colourBorder: null,
|
||||
colourLight: Blockly.utils.colour.blend('#fff', colour, 0.3),
|
||||
colourDark: Blockly.utils.colour.blend('#000', colour, 0.2)
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the name of the block style.
|
||||
* @return {?string} Name of the block style.
|
||||
@@ -984,48 +914,17 @@ Blockly.Block.prototype.getHue = function() {
|
||||
* or a message reference string pointing to one of those two values.
|
||||
*/
|
||||
Blockly.Block.prototype.setColour = function(colour) {
|
||||
var dereferenced = (typeof colour == 'string') ?
|
||||
Blockly.utils.replaceMessageReferences(colour) : colour;
|
||||
|
||||
var hue = Number(dereferenced);
|
||||
if (!isNaN(hue) && 0 <= hue && hue <= 360) {
|
||||
this.hue_ = hue;
|
||||
this.colour_ = Blockly.hueToHex(hue);
|
||||
} else {
|
||||
var hex = Blockly.utils.colour.parse(dereferenced);
|
||||
if (hex) {
|
||||
this.colour_ = hex;
|
||||
// Only store hue if colour is set as a hue.
|
||||
this.hue_ = null;
|
||||
} else {
|
||||
var errorMsg = 'Invalid colour: "' + dereferenced + '"';
|
||||
if (colour != dereferenced) {
|
||||
errorMsg += ' (from "' + colour + '")';
|
||||
}
|
||||
throw Error(errorMsg);
|
||||
}
|
||||
}
|
||||
var parsed = Blockly.utils.colour.parseBlockColour(colour);
|
||||
this.hue_ = parsed.hue;
|
||||
this.colour_ = parsed.hex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the style and colour values of a block.
|
||||
* @param {string} blockStyleName Name of the block style
|
||||
* @throws {Error} if the block style does not exist.
|
||||
*/
|
||||
Blockly.Block.prototype.setStyle = function(blockStyleName) {
|
||||
var theme = this.workspace.getTheme();
|
||||
var blockStyle = theme.getBlockStyle(blockStyleName);
|
||||
this.styleName_ = blockStyleName;
|
||||
|
||||
if (blockStyle) {
|
||||
this.colourSecondary_ = blockStyle['colourSecondary'];
|
||||
this.colourTertiary_ = blockStyle['colourTertiary'];
|
||||
this.hat = blockStyle.hat;
|
||||
// Set colour will trigger an updateColour() on a block_svg
|
||||
this.setColour(blockStyle['colourPrimary']);
|
||||
} else {
|
||||
throw Error('Invalid style name: ' + blockStyleName);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -63,22 +63,20 @@ 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}
|
||||
*/
|
||||
this.style = workspace.getTheme().getBlockStyle(null);
|
||||
|
||||
/**
|
||||
* The renderer's path object.
|
||||
* @type {Blockly.blockRendering.IPathObject}
|
||||
* @package
|
||||
*/
|
||||
this.pathObject =
|
||||
workspace.getRenderer().makePathObject(this.svgGroup_);
|
||||
|
||||
// The next three paths are set only for backwards compatibility reasons.
|
||||
/**
|
||||
* The dark path of the block.
|
||||
* @type {SVGElement}
|
||||
* @private
|
||||
*/
|
||||
this.svgPathDark_ = this.pathObject.svgPathDark || null;
|
||||
this.pathObject = workspace.getRenderer().makePathObject(this.svgGroup_);
|
||||
|
||||
// The next two paths are set only for backwards compatibility reasons.
|
||||
/**
|
||||
* The primary path of the block.
|
||||
* @type {SVGElement}
|
||||
@@ -267,7 +265,7 @@ Blockly.BlockSvg.prototype.initSvg = function() {
|
||||
for (var i = 0; i < icons.length; i++) {
|
||||
icons[i].createIcon();
|
||||
}
|
||||
this.updateColour();
|
||||
this.applyColour();
|
||||
this.updateMovable();
|
||||
var svg = this.getSvgRoot();
|
||||
if (!this.workspace.options.readOnly && !this.eventsInit_ && svg) {
|
||||
@@ -939,7 +937,7 @@ Blockly.BlockSvg.prototype.setEditable = function(editable) {
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setShadow = function(shadow) {
|
||||
Blockly.BlockSvg.superClass_.setShadow.call(this, shadow);
|
||||
this.updateColour();
|
||||
this.applyColour();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1027,75 +1025,33 @@ Blockly.BlockSvg.prototype.dispose = function(healStack, animate) {
|
||||
this.svgGroup_ = null;
|
||||
this.svgPath_ = null;
|
||||
this.svgPathLight_ = null;
|
||||
this.svgPathDark_ = null;
|
||||
Blockly.utils.dom.stopTextWidthCache();
|
||||
};
|
||||
|
||||
/**
|
||||
* Change the colour of a block.
|
||||
* @package
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.updateColour = function() {
|
||||
Blockly.BlockSvg.prototype.applyColour = function() {
|
||||
if (!this.isEnabled()) {
|
||||
// Disabled blocks don't have colour.
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isShadow()) {
|
||||
this.setShadowColour_();
|
||||
} else {
|
||||
this.setBorderColour_();
|
||||
this.svgPath_.setAttribute('fill', this.getColour());
|
||||
}
|
||||
this.pathObject.applyColour(this.isShadow());
|
||||
|
||||
var icons = this.getIcons();
|
||||
for (var i = 0; i < icons.length; i++) {
|
||||
icons[i].updateColour();
|
||||
icons[i].applyColour();
|
||||
}
|
||||
|
||||
for (var x = 0, input; input = this.inputList[x]; x++) {
|
||||
for (var y = 0, field; field = input.fieldRow[y]; y++) {
|
||||
field.updateColour();
|
||||
field.applyColour();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the colour of the border.
|
||||
* Removes the light and dark paths if a border colour is defined.
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setBorderColour_ = function() {
|
||||
var borderColours = this.getColourBorder();
|
||||
if (borderColours.colourBorder) {
|
||||
this.svgPathLight_.style.display = 'none';
|
||||
this.svgPathDark_.style.display = 'none';
|
||||
|
||||
this.svgPath_.setAttribute('stroke', borderColours.colourBorder);
|
||||
} else {
|
||||
this.svgPathLight_.style.display = '';
|
||||
this.svgPathDark_.style.display = '';
|
||||
this.svgPath_.setAttribute('stroke', 'none');
|
||||
|
||||
this.svgPathLight_.setAttribute('stroke', borderColours.colourLight);
|
||||
this.svgPathDark_.setAttribute('fill', borderColours.colourDark);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the colour of shadow blocks.
|
||||
* @return {?string} The background colour of the block.
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setShadowColour_ = function() {
|
||||
var shadowColour = this.getColourShadow() || '';
|
||||
|
||||
this.svgPathLight_.style.display = 'none';
|
||||
this.svgPathDark_.setAttribute('fill', shadowColour);
|
||||
this.svgPath_.setAttribute('stroke', 'none');
|
||||
this.svgPath_.setAttribute('fill', shadowColour);
|
||||
return shadowColour;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable or disable a block.
|
||||
*/
|
||||
@@ -1111,7 +1067,7 @@ Blockly.BlockSvg.prototype.updateDisabled = function() {
|
||||
var removed = Blockly.utils.dom.removeClass(
|
||||
/** @type {!Element} */ (this.svgGroup_), 'blocklyDisabled');
|
||||
if (removed) {
|
||||
this.updateColour();
|
||||
this.applyColour();
|
||||
}
|
||||
}
|
||||
var children = this.getChildren(false);
|
||||
@@ -1337,8 +1293,16 @@ Blockly.BlockSvg.prototype.setDeleteStyle = function(enable) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Overrides of functions on Blockly.Block that take into account whether the
|
||||
// block has been rendered.
|
||||
/**
|
||||
* Get the colour of a block.
|
||||
* @return {string} #RRGGBB string.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.getColour = function() {
|
||||
return this.style.colourPrimary;
|
||||
};
|
||||
|
||||
/**
|
||||
* Change the colour of a block.
|
||||
@@ -1346,9 +1310,34 @@ Blockly.BlockSvg.prototype.setDeleteStyle = function(enable) {
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setColour = function(colour) {
|
||||
Blockly.BlockSvg.superClass_.setColour.call(this, colour);
|
||||
var styleObj = this.workspace.getTheme().getBlockStyleForColour(this.colour_);
|
||||
|
||||
if (this.rendered) {
|
||||
this.updateColour();
|
||||
this.pathObject.setStyle(styleObj.style);
|
||||
this.style = styleObj.style;
|
||||
this.styleName_ = styleObj.name;
|
||||
|
||||
this.applyColour();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the style and colour values of a block.
|
||||
* @param {string} blockStyleName Name of the block style
|
||||
* @throws {Error} if the block style does not exist.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setStyle = function(blockStyleName) {
|
||||
var blockStyle = this.workspace.getTheme().getBlockStyle(blockStyleName);
|
||||
this.styleName_ = blockStyleName;
|
||||
|
||||
if (blockStyle) {
|
||||
this.hat = blockStyle.hat;
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -247,7 +247,7 @@ Blockly.Comment.prototype.createEditableBubble_ = function() {
|
||||
// Expose this comment's block's ID on its top-level SVG group.
|
||||
this.bubble_.setSvgId(this.block_.id);
|
||||
this.bubble_.registerResizeEvent(this.onBubbleResize_.bind(this));
|
||||
this.updateColour();
|
||||
this.applyColour();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -603,10 +603,10 @@ Blockly.Field.prototype.getSvgRoot = function() {
|
||||
|
||||
/**
|
||||
* Updates the field to match the colour/style of the block. Should only be
|
||||
* called by BlockSvg.updateColour().
|
||||
* called by BlockSvg.applyColour().
|
||||
* @package
|
||||
*/
|
||||
Blockly.Field.prototype.updateColour = function() {
|
||||
Blockly.Field.prototype.applyColour = function() {
|
||||
// Non-abstract sub-classes may wish to implement this. See FieldDropdown.
|
||||
};
|
||||
|
||||
|
||||
@@ -269,9 +269,8 @@ Blockly.FieldAngle.prototype.showEditor_ = function() {
|
||||
var editor = this.dropdownCreate_();
|
||||
Blockly.DropDownDiv.getContentDiv().appendChild(editor);
|
||||
|
||||
var border = this.sourceBlock_.getColourBorder();
|
||||
border = border.colourBorder || border.colourLight;
|
||||
Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), border);
|
||||
Blockly.DropDownDiv.setColour(this.sourceBlock_.style.colourPrimary,
|
||||
this.sourceBlock_.style.colourTertiary);
|
||||
|
||||
Blockly.DropDownDiv.showPositionedByField(
|
||||
this, this.dropdownDispose_.bind(this));
|
||||
|
||||
@@ -129,9 +129,9 @@ Blockly.FieldDate.prototype.render_ = function() {
|
||||
* Updates the field's colours to match those of the block.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldDate.prototype.updateColour = function() {
|
||||
this.todayColour_ = this.sourceBlock_.getColour();
|
||||
this.selectedColour_ = this.sourceBlock_.getColourShadow();
|
||||
Blockly.FieldDate.prototype.applyColour = function() {
|
||||
this.todayColour_ = this.sourceBlock_.style.colourPrimary;
|
||||
this.selectedColour_ = this.sourceBlock_.style.colourSecondary;
|
||||
this.updateEditor_();
|
||||
};
|
||||
|
||||
|
||||
@@ -468,13 +468,13 @@ Blockly.FieldDropdown.prototype.doValueUpdate_ = function(newValue) {
|
||||
* Updates the dropdown arrow to match the colour/style of the block.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.updateColour = function() {
|
||||
Blockly.FieldDropdown.prototype.applyColour = function() {
|
||||
// Update arrow's colour.
|
||||
if (this.sourceBlock_ && this.arrow_) {
|
||||
if (this.sourceBlock_.isShadow()) {
|
||||
this.arrow_.style.fill = this.sourceBlock_.getColourShadow();
|
||||
this.arrow_.style.fill = this.sourceBlock_.style.colourSecondary;
|
||||
} else {
|
||||
this.arrow_.style.fill = this.sourceBlock_.getColour();
|
||||
this.arrow_.style.fill = this.sourceBlock_.style.colourPrimary;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -139,9 +139,9 @@ Blockly.Icon.prototype.iconClick_ = function(e) {
|
||||
/**
|
||||
* Change the colour of the associated bubble to match its block.
|
||||
*/
|
||||
Blockly.Icon.prototype.updateColour = function() {
|
||||
Blockly.Icon.prototype.applyColour = function() {
|
||||
if (this.isVisible()) {
|
||||
this.bubble_.setColour(this.block_.getColour());
|
||||
this.bubble_.setColour(this.block_.style.colourPrimary);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -322,7 +322,7 @@ Blockly.Mutator.prototype.setVisible = function(visible) {
|
||||
this.resizeBubble_();
|
||||
// When the mutator's workspace changes, update the source block.
|
||||
this.workspace_.addChangeListener(this.workspaceChanged_.bind(this));
|
||||
this.updateColour();
|
||||
this.applyColour();
|
||||
} else {
|
||||
// Dispose of the bubble.
|
||||
this.svgDialog_ = null;
|
||||
|
||||
57
core/renderers/common/i_path_object.js
Normal file
57
core/renderers/common/i_path_object.js
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 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 The interface for an object that owns a block's rendering SVG
|
||||
* elements.
|
||||
* @author fenichel@google.com (Rachel Fenichel)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.blockRendering.IPathObject');
|
||||
|
||||
goog.requireType('Blockly.Theme');
|
||||
|
||||
|
||||
/**
|
||||
* An interface for a block's path object.
|
||||
* @param {!SVGElement} _root The root SVG element.
|
||||
* @interface
|
||||
*/
|
||||
Blockly.blockRendering.IPathObject = function(_root) {};
|
||||
|
||||
/**
|
||||
* Apply the stored colours to the block's path, taking into account whether
|
||||
* the paths belong to a shadow block.
|
||||
* @param {boolean} isShadow True if the block is a shadow block.
|
||||
* @package
|
||||
*/
|
||||
Blockly.blockRendering.IPathObject.prototype.applyColour;
|
||||
|
||||
/**
|
||||
* Update the style.
|
||||
* @param {!Blockly.Theme.BlockStyle} blockStyle The block style to use.
|
||||
* @package
|
||||
*/
|
||||
Blockly.blockRendering.IPathObject.prototype.setStyle;
|
||||
|
||||
/**
|
||||
* Flip the SVG paths in RTL.
|
||||
* @package
|
||||
*/
|
||||
Blockly.blockRendering.IPathObject.prototype.flipRTL;
|
||||
@@ -22,19 +22,13 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.blockRendering.IPathObject');
|
||||
goog.provide('Blockly.blockRendering.PathObject');
|
||||
|
||||
goog.require('Blockly.blockRendering.IPathObject');
|
||||
goog.require('Blockly.Theme');
|
||||
goog.require('Blockly.utils.dom');
|
||||
|
||||
|
||||
/**
|
||||
* An interface for a block's path object.
|
||||
* @param {!SVGElement} _root The root SVG element.
|
||||
* @interface
|
||||
*/
|
||||
Blockly.blockRendering.IPathObject = function(_root) {};
|
||||
|
||||
/**
|
||||
* An object that handles creating and setting each of the SVG elements
|
||||
* used by the renderer.
|
||||
@@ -67,13 +61,11 @@ Blockly.blockRendering.PathObject = function(root) {
|
||||
{'class': 'blocklyPathLight'}, this.svgRoot);
|
||||
|
||||
/**
|
||||
* The dark path of the block.
|
||||
* @type {SVGElement}
|
||||
* The style object to use when colouring block paths.
|
||||
* @type {!Blockly.Theme.BlockStyle}
|
||||
* @package
|
||||
*/
|
||||
this.svgPathDark = Blockly.utils.dom.createSvgElement('path',
|
||||
{'class': 'blocklyPathDark', 'transform': 'translate(1,1)'},
|
||||
this.svgRoot);
|
||||
this.style = Blockly.Theme.createBlockStyle('#000000');
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -84,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';
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -95,3 +86,28 @@ Blockly.blockRendering.PathObject.prototype.flipRTL = function() {
|
||||
// Mirror the block's path.
|
||||
this.svgPath.setAttribute('transform', 'scale(-1 1)');
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply the stored colours to the block's path, taking into account whether
|
||||
* the paths belong to a shadow block.
|
||||
* @param {boolean} isShadow True if the block is a shadow block.
|
||||
* @package
|
||||
*/
|
||||
Blockly.blockRendering.PathObject.prototype.applyColour = function(isShadow) {
|
||||
if (isShadow) {
|
||||
this.svgPath.setAttribute('stroke', 'none');
|
||||
this.svgPath.setAttribute('fill', this.style.colourSecondary);
|
||||
} else {
|
||||
this.svgPath.setAttribute('stroke', this.style.colourTertiary);
|
||||
this.svgPath.setAttribute('fill', this.style.colourPrimary);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the style.
|
||||
* @param {!Blockly.Theme.BlockStyle} blockStyle The block style to use.
|
||||
* @package
|
||||
*/
|
||||
Blockly.blockRendering.PathObject.prototype.setStyle = function(blockStyle) {
|
||||
this.style = blockStyle;
|
||||
};
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
goog.provide('Blockly.geras.PathObject');
|
||||
|
||||
goog.require('Blockly.blockRendering.IPathObject');
|
||||
goog.require('Blockly.Theme');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.object');
|
||||
|
||||
|
||||
/**
|
||||
@@ -66,6 +68,20 @@ Blockly.geras.PathObject = function(root) {
|
||||
*/
|
||||
this.svgPathLight = Blockly.utils.dom.createSvgElement('path',
|
||||
{'class': 'blocklyPathLight'}, this.svgRoot);
|
||||
|
||||
/**
|
||||
* The colour of the dark path on the block in '#RRGGBB' format.
|
||||
* @type {string}
|
||||
* @package
|
||||
*/
|
||||
this.colourDark = '#000000';
|
||||
|
||||
/**
|
||||
* The style object to use when colouring block paths.
|
||||
* @type {!Blockly.Theme.BlockStyle}
|
||||
* @package
|
||||
*/
|
||||
this.style = Blockly.Theme.createBlockStyle('#000000');
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -90,3 +106,36 @@ Blockly.geras.PathObject.prototype.flipRTL = function() {
|
||||
this.svgPathLight.setAttribute('transform', 'scale(-1 1)');
|
||||
this.svgPathDark.setAttribute('transform', 'translate(1,1) scale(-1 1)');
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply the stored colours to the block's path, taking into account whether
|
||||
* the paths belong to a shadow block.
|
||||
* @param {boolean} isShadow True if the block is a shadow block.
|
||||
* @package
|
||||
*/
|
||||
Blockly.geras.PathObject.prototype.applyColour = function(isShadow) {
|
||||
if (isShadow) {
|
||||
this.svgPathLight.style.display = 'none';
|
||||
this.svgPathDark.setAttribute('fill', this.style.colourSecondary);
|
||||
this.svgPath.setAttribute('stroke', 'none');
|
||||
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.style.colourTertiary);
|
||||
this.svgPathDark.setAttribute('fill', this.colourDark);
|
||||
this.svgPath.setAttribute('fill', this.style.colourPrimary);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the style.
|
||||
* @param {!Blockly.Theme.BlockStyle} blockStyle The block style to use.
|
||||
* @package
|
||||
*/
|
||||
Blockly.geras.PathObject.prototype.setStyle = function(blockStyle) {
|
||||
this.style = blockStyle;
|
||||
this.colourDark =
|
||||
Blockly.utils.colour.blend('#000', this.style.colourPrimary, 0.2);
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
goog.provide('Blockly.Theme');
|
||||
|
||||
goog.require('Blockly.utils.colour');
|
||||
|
||||
/**
|
||||
* Class for a theme.
|
||||
@@ -37,10 +38,13 @@ goog.provide('Blockly.Theme');
|
||||
Blockly.Theme = function(blockStyles, categoryStyles, opt_componentStyles) {
|
||||
/**
|
||||
* The block styles map.
|
||||
* @type {!Object.<string, Blockly.Theme.BlockStyle>}
|
||||
* @type {!Object.<string, !Blockly.Theme.BlockStyle>}
|
||||
* @private
|
||||
*/
|
||||
this.blockStyles_ = blockStyles;
|
||||
this.blockStyles_ = {};
|
||||
|
||||
// Make sure all styles are valid before inserting them into the map.
|
||||
this.setAllBlockStyles(blockStyles);
|
||||
|
||||
/**
|
||||
* The category styles map.
|
||||
@@ -97,22 +101,88 @@ 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];
|
||||
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 = {};
|
||||
if (blockStyle) {
|
||||
Blockly.utils.object.mixin(valid, blockStyle);
|
||||
}
|
||||
|
||||
// Validate required properties.
|
||||
var parsedColour = Blockly.utils.colour.parseBlockColour(
|
||||
valid.colourPrimary || '#000');
|
||||
valid.colourPrimary = parsedColour.hex;
|
||||
valid.colourSecondary = valid.colourSecondary ?
|
||||
Blockly.utils.colour.parseBlockColour(valid.colourSecondary).hex :
|
||||
Blockly.utils.colour.blend('#fff', valid.colourPrimary, 0.6);
|
||||
valid.colourTertiary = valid.colourTertiary ?
|
||||
Blockly.utils.colour.parseBlockColour(valid.colourTertiary).hex :
|
||||
Blockly.utils.colour.blend('#fff', valid.colourPrimary, 0.3);
|
||||
|
||||
valid.hat = valid.hat || '';
|
||||
return valid;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the CategoryStyle for the given category style name.
|
||||
* @param {string} categoryStyleName The name of the category style.
|
||||
|
||||
@@ -34,7 +34,7 @@ Blockly.Themes.Deuteranopia = {};
|
||||
Blockly.Themes.Deuteranopia.defaultBlockStyles = {
|
||||
"colour_blocks": {
|
||||
"colourPrimary": "#f2a72c",
|
||||
"colourSecondary": "#f1c17",
|
||||
"colourSecondary": "#f1c170",
|
||||
"colourTertiary": "#da921c"
|
||||
},
|
||||
"list_blocks": {
|
||||
|
||||
@@ -211,3 +211,41 @@ Blockly.utils.colour.names = {
|
||||
'white': '#ffffff',
|
||||
'yellow': '#ffff00'
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse a block colour from a number or string, as provided in a block
|
||||
* definition.
|
||||
* @param {number|string} colour HSV hue value (0 to 360), #RRGGBB string,
|
||||
* or a message reference string pointing to one of those two values.
|
||||
* @return {{hue: ?number, hex: string}} An object containing the colour as
|
||||
* a #RRGGBB string, and the hue if the input was an HSV hue value.
|
||||
* @throws {Error} If the colour cannot be parsed.
|
||||
*/
|
||||
Blockly.utils.colour.parseBlockColour = function(colour) {
|
||||
var dereferenced = (typeof colour == 'string') ?
|
||||
Blockly.utils.replaceMessageReferences(colour) : colour;
|
||||
|
||||
var hue = Number(dereferenced);
|
||||
if (!isNaN(hue) && 0 <= hue && hue <= 360) {
|
||||
return {
|
||||
hue: hue,
|
||||
hex: Blockly.utils.colour.hsvToHex(hue, Blockly.HSV_SATURATION,
|
||||
Blockly.HSV_VALUE * 255)
|
||||
};
|
||||
} else {
|
||||
var hex = Blockly.utils.colour.parse(dereferenced);
|
||||
if (hex) {
|
||||
// Only store hue if colour is set as a hue.
|
||||
return {
|
||||
hue: null,
|
||||
hex: hex
|
||||
};
|
||||
} else {
|
||||
var errorMsg = 'Invalid colour: "' + dereferenced + '"';
|
||||
if (colour != dereferenced) {
|
||||
errorMsg += ' (from "' + colour + '")';
|
||||
}
|
||||
throw Error(errorMsg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -149,7 +149,7 @@ Blockly.Warning.prototype.createBubble = function() {
|
||||
textElement.setAttribute('x', maxWidth + Blockly.Bubble.BORDER_WIDTH);
|
||||
}
|
||||
}
|
||||
this.updateColour();
|
||||
this.applyColour();
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,7 +29,7 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
|
||||
"message0": "stack block",
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"style": "math_blocks"
|
||||
"colour": "120"
|
||||
},
|
||||
{
|
||||
"type": "test_basic_dummy",
|
||||
|
||||
@@ -253,28 +253,6 @@ function test_block_row_unplug_multi_inputs_child() {
|
||||
}
|
||||
}
|
||||
|
||||
function test_set_style() {
|
||||
blockTest_setUp();
|
||||
var styleStub = {
|
||||
getBlockStyle: function() {
|
||||
return {
|
||||
"colourPrimary": "#ffffff",
|
||||
"colourSecondary": "#aabbcc",
|
||||
"colourTertiary": "#ddeeff"
|
||||
};
|
||||
}
|
||||
};
|
||||
mockControl_ = setUpMockMethod(workspace, 'getTheme', null, [styleStub]);
|
||||
var blockA = workspace.newBlock('row_block');
|
||||
blockA.setStyle('styleOne');
|
||||
|
||||
assertEquals('#ffffff', blockA.colour_);
|
||||
assertEquals('#aabbcc', blockA.colourSecondary_);
|
||||
assertEquals('#ddeeff', blockA.colourTertiary_);
|
||||
|
||||
blockTest_tearDown();
|
||||
}
|
||||
|
||||
function test_set_style_throw_exception() {
|
||||
blockTest_setUp();
|
||||
var styleStub = {
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/**
|
||||
* @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 Tests for Blockly.Style
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
function defineThemeTestBlocks() {
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "stack_block",
|
||||
"message0": "",
|
||||
"previousStatement": null,
|
||||
"nextStatement": null
|
||||
},
|
||||
{
|
||||
"type": "row_block",
|
||||
"message0": "%1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "INPUT"
|
||||
}
|
||||
],
|
||||
"output": null
|
||||
}]);
|
||||
};
|
||||
|
||||
function undefineThemeTestBlocks() {
|
||||
delete Blockly.Blocks['stack_block'];
|
||||
delete Blockly.Blocks['row_block'];
|
||||
}
|
||||
|
||||
|
||||
function createBlockStyles() {
|
||||
return {
|
||||
"styleOne": {
|
||||
"colourPrimary": "colour1",
|
||||
"colourSecondary":"colour2",
|
||||
"colourTertiary":"colour3"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createMultipleBlockStyles() {
|
||||
return {
|
||||
"styleOne": {
|
||||
"colourPrimary": "colour1",
|
||||
"colourSecondary":"colour2",
|
||||
"colourTertiary":"colour3"
|
||||
},
|
||||
"styleTwo": {
|
||||
"colourPrimary": "colour1",
|
||||
"colourSecondary":"colour2",
|
||||
"colourTertiary":"colour3"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function test_setAllBlockStyles() {
|
||||
var theme = new Blockly.Theme(createBlockStyles());
|
||||
stringifyAndCompare(createBlockStyles(), theme.blockStyles_);
|
||||
theme.setAllBlockStyles(createMultipleBlockStyles());
|
||||
stringifyAndCompare(createMultipleBlockStyles(), theme.blockStyles_);
|
||||
}
|
||||
|
||||
function test_getAllBlockStyles() {
|
||||
var theme = new Blockly.Theme(createMultipleBlockStyles());
|
||||
var allBlocks = theme.getAllBlockStyles();
|
||||
stringifyAndCompare(createMultipleBlockStyles(), allBlocks);
|
||||
|
||||
}
|
||||
|
||||
function test_getBlockStyles() {
|
||||
var theme = new Blockly.Theme(createBlockStyles());
|
||||
var blockStyle = theme.getBlockStyle('styleOne');
|
||||
|
||||
stringifyAndCompare(blockStyle, createBlockStyles().styleOne);
|
||||
}
|
||||
|
||||
function test_setBlockStyleUpdate() {
|
||||
var theme = new Blockly.Theme(createBlockStyles());
|
||||
var blockStyle = createBlockStyles();
|
||||
blockStyle.styleOne.colourPrimary = 'somethingElse';
|
||||
|
||||
theme.setBlockStyle('styleOne', blockStyle.styleOne);
|
||||
|
||||
stringifyAndCompare(theme.blockStyles_, blockStyle);
|
||||
}
|
||||
|
||||
function test_setBlockStyleAdd() {
|
||||
var theme = new Blockly.Theme(createBlockStyles());
|
||||
var blockStyle = createMultipleBlockStyles();
|
||||
|
||||
theme.setBlockStyle('styleTwo', blockStyle.styleTwo);
|
||||
|
||||
stringifyAndCompare(theme.blockStyles_, blockStyle);
|
||||
}
|
||||
|
||||
function test_setTheme() {
|
||||
defineThemeTestBlocks();
|
||||
var blockStyles = createBlockStyles();
|
||||
var workspace = new Blockly.WorkspaceSvg({});
|
||||
var blockA = workspace.newBlock('stack_block');
|
||||
var blocks = [blockA];
|
||||
|
||||
blockA.setStyle = function() {this.styleName_ = 'styleTwo'};
|
||||
var callCount = 1;
|
||||
workspace.refreshToolboxSelection = function() {
|
||||
return ++callCount;
|
||||
};
|
||||
blockA.styleName_ = 'styleOne';
|
||||
|
||||
var mockControl_ = setUpMockMethod(Blockly, 'getMainWorkspace', null, [workspace]);
|
||||
|
||||
workspace.setTheme(blockStyles);
|
||||
|
||||
//Checks that the theme was set correctly on Blockly namespace
|
||||
stringifyAndCompare(workspace.getTheme(), blockStyles);
|
||||
|
||||
//Checks that the setTheme function was called on the block
|
||||
assertEquals(blockA.getStyleName(), 'styleTwo');
|
||||
|
||||
//check that the toolbox refreshed method was called
|
||||
assertEquals(workspace.refreshToolboxSelection(), 3);
|
||||
|
||||
assertEquals(Blockly.Events.FIRE_QUEUE_.pop().element, 'theme');
|
||||
|
||||
undefineThemeTestBlocks();
|
||||
|
||||
mockControl_.restore();
|
||||
}
|
||||
|
||||
function stringifyAndCompare(val1, val2) {
|
||||
var stringVal1 = JSON.stringify(val1);
|
||||
var stringVal2 = JSON.stringify(val2);
|
||||
assertEquals(stringVal1, stringVal2);
|
||||
}
|
||||
@@ -1249,4 +1249,66 @@ suite('Blocks', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('Style', function() {
|
||||
suite('Headless', function() {
|
||||
setup(function() {
|
||||
this.block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="empty_block"/>'
|
||||
), this.workspace);
|
||||
});
|
||||
test('Set colour', function() {
|
||||
this.block.setColour('20');
|
||||
assertEquals(this.block.getColour(), '#a5745b');
|
||||
assertEquals(this.block.colour_, this.block.getColour());
|
||||
assertEquals(this.block.hue_, '20');
|
||||
});
|
||||
test('Set style', function() {
|
||||
this.block.setStyle('styleOne');
|
||||
assertEquals(this.block.getStyleName(), 'styleOne');
|
||||
assertEquals(this.block.hue_, null);
|
||||
// Calling setStyle does not update the colour on a headless block.
|
||||
assertEquals(this.block.getColour(), '#000000');
|
||||
});
|
||||
});
|
||||
suite('Rendered', function() {
|
||||
setup(function() {
|
||||
this.workspace = Blockly.inject('blocklyDiv', {});
|
||||
this.block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="empty_block"/>'
|
||||
), this.workspace);
|
||||
this.workspace.setTheme(new Blockly.Theme({
|
||||
"styleOne" : {
|
||||
"colourPrimary": "#000000",
|
||||
"colourSecondary": "#999999",
|
||||
"colourTertiary": "#4d4d4d",
|
||||
"hat": ''
|
||||
}
|
||||
}), {});
|
||||
});
|
||||
teardown(function() {
|
||||
this.workspace.dispose();
|
||||
});
|
||||
test('Set colour hue', function() {
|
||||
this.block.setColour('20');
|
||||
assertEquals(this.block.getStyleName(), 'auto_#a5745b');
|
||||
assertEquals(this.block.getColour(), '#a5745b');
|
||||
assertEquals(this.block.colour_, this.block.getColour());
|
||||
assertEquals(this.block.hue_, '20');
|
||||
});
|
||||
test('Set colour hex', function() {
|
||||
this.block.setColour('#000000');
|
||||
assertEquals(this.block.getStyleName(), 'auto_#000000');
|
||||
assertEquals(this.block.getColour(), '#000000');
|
||||
assertEquals(this.block.colour_, this.block.getColour());
|
||||
assertEquals(this.block.hue_, null);
|
||||
});
|
||||
test('Set style', function() {
|
||||
this.block.setStyle('styleOne');
|
||||
assertEquals(this.block.getStyleName(), 'styleOne');
|
||||
assertEquals(this.block.getColour(), '#000000');
|
||||
assertEquals(this.block.colour_, this.block.getColour());
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,9 +52,10 @@ suite('Theme', function() {
|
||||
function createBlockStyles() {
|
||||
return {
|
||||
"styleOne": {
|
||||
"colourPrimary": "colour1",
|
||||
"colourSecondary":"colour2",
|
||||
"colourTertiary":"colour3"
|
||||
"colourPrimary": "#aaaaaa",
|
||||
"colourSecondary": "#bbbbbb",
|
||||
"colourTertiary": "#cccccc",
|
||||
"hat": 'cap'
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -62,14 +63,16 @@ suite('Theme', function() {
|
||||
function createMultipleBlockStyles() {
|
||||
return {
|
||||
"styleOne": {
|
||||
"colourPrimary": "colour1",
|
||||
"colourSecondary":"colour2",
|
||||
"colourTertiary":"colour3"
|
||||
"colourPrimary": "#aaaaaa",
|
||||
"colourSecondary": "#bbbbbb",
|
||||
"colourTertiary": "#cccccc",
|
||||
"hat": 'cap'
|
||||
},
|
||||
"styleTwo": {
|
||||
"colourPrimary": "colour1",
|
||||
"colourSecondary":"colour2",
|
||||
"colourTertiary":"colour3"
|
||||
"colourPrimary": "#000000",
|
||||
"colourSecondary": "#999999",
|
||||
"colourTertiary": "#4d4d4d",
|
||||
"hat": ''
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -103,7 +106,7 @@ suite('Theme', function() {
|
||||
test('Set BlockStyle Update', function() {
|
||||
var theme = new Blockly.Theme(createBlockStyles());
|
||||
var blockStyle = createBlockStyles();
|
||||
blockStyle.styleOne.colourPrimary = 'somethingElse';
|
||||
blockStyle.styleOne.colourPrimary = '#00ff00';
|
||||
|
||||
theme.setBlockStyle('styleOne', blockStyle.styleOne);
|
||||
|
||||
@@ -152,4 +155,120 @@ suite('Theme', function() {
|
||||
stub.restore();
|
||||
});
|
||||
|
||||
suite('Validate block styles', function() {
|
||||
test('Null', function() {
|
||||
var inputStyle = null;
|
||||
var expectedOutput = {
|
||||
"colourPrimary": "#000000",
|
||||
"colourSecondary": "#999999",
|
||||
"colourTertiary": "#4d4d4d",
|
||||
"hat": ''
|
||||
};
|
||||
stringifyAndCompare(
|
||||
Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput);
|
||||
});
|
||||
|
||||
test('Empty', function() {
|
||||
var inputStyle = {};
|
||||
var expectedOutput = {
|
||||
"colourPrimary": "#000000",
|
||||
"colourSecondary": "#999999",
|
||||
"colourTertiary": "#4d4d4d",
|
||||
"hat": ''
|
||||
};
|
||||
stringifyAndCompare(
|
||||
Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput);
|
||||
});
|
||||
|
||||
test('Incomplete hex', function() {
|
||||
var inputStyle = {
|
||||
"colourPrimary": "#012345"
|
||||
};
|
||||
var expectedOutput = {
|
||||
"colourPrimary": "#012345",
|
||||
"colourSecondary": "#99a7b5",
|
||||
"colourTertiary": "#4d657d",
|
||||
"hat": ''
|
||||
};
|
||||
stringifyAndCompare(
|
||||
Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput);
|
||||
});
|
||||
|
||||
test('Complete hex', function() {
|
||||
var inputStyle = {
|
||||
"colourPrimary": "#aaaaaa",
|
||||
"colourSecondary": "#bbbbbb",
|
||||
"colourTertiary": "#cccccc",
|
||||
"hat": 'cap'
|
||||
};
|
||||
var expectedOutput = {
|
||||
"colourPrimary": "#aaaaaa",
|
||||
"colourSecondary": "#bbbbbb",
|
||||
"colourTertiary": "#cccccc",
|
||||
"hat": 'cap'
|
||||
};
|
||||
stringifyAndCompare(
|
||||
Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput);
|
||||
});
|
||||
|
||||
test('Complete hue', function() {
|
||||
var inputStyle = {
|
||||
"colourPrimary": "20",
|
||||
"colourSecondary": "40",
|
||||
"colourTertiary": "60",
|
||||
};
|
||||
var expectedOutput = {
|
||||
"colourPrimary": "#a5745b",
|
||||
"colourSecondary": "#a58c5b",
|
||||
"colourTertiary": "#a5a55b",
|
||||
"hat": ''
|
||||
};
|
||||
stringifyAndCompare(
|
||||
Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput);
|
||||
});
|
||||
|
||||
test('Incomplete hue', function() {
|
||||
var inputStyle = {
|
||||
"colourPrimary": "20",
|
||||
};
|
||||
var expectedOutput = {
|
||||
"colourPrimary": "#a5745b",
|
||||
"colourSecondary": "#dbc7bd",
|
||||
"colourTertiary": "#c09e8c",
|
||||
"hat": ''
|
||||
};
|
||||
stringifyAndCompare(
|
||||
Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput);
|
||||
});
|
||||
|
||||
test('Complete css colour name', function() {
|
||||
var inputStyle = {
|
||||
"colourPrimary": "red",
|
||||
"colourSecondary": "white",
|
||||
"colourTertiary": "blue"
|
||||
};
|
||||
var expectedOutput = {
|
||||
"colourPrimary": "#ff0000",
|
||||
"colourSecondary": "#ffffff",
|
||||
"colourTertiary": "#0000ff",
|
||||
"hat": ''
|
||||
};
|
||||
stringifyAndCompare(
|
||||
Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput);
|
||||
});
|
||||
|
||||
test('Incomplete css colour name', function() {
|
||||
var inputStyle = {
|
||||
"colourPrimary": "black",
|
||||
};
|
||||
var expectedOutput = {
|
||||
"colourPrimary": "#000000",
|
||||
"colourSecondary": "#999999",
|
||||
"colourTertiary": "#4d4d4d",
|
||||
"hat": ''
|
||||
};
|
||||
stringifyAndCompare(
|
||||
Blockly.Theme.validatedBlockStyle(inputStyle), expectedOutput);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user