Skip to content

Commit c9b5c4e

Browse files
authored
refactor: use block styles instead of directly specifying block colors (#171)
* fix: fix the highlight colors of dropdown fields * fix: synthesize a selected theme and override CSS variables when setting a theme * fix: drop the colours_ prefix from block style names * fix: fix CSS glitches when switching themes * fix: use the injected theme instead of overriding it * chore: explicitly declare the originalStyle property in dropdown-related fields * chore: add a comment to setTheme
1 parent a47aba6 commit c9b5c4e

File tree

10 files changed

+114
-111
lines changed

10 files changed

+114
-111
lines changed

src/blocks/control.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ Blockly.Blocks["control_stop"] = {
197197
this.appendDummyInput()
198198
.appendField(Blockly.Msg.CONTROL_STOP)
199199
.appendField(stopDropdown, "STOP_OPTION");
200-
this.setStyle("colours_control");
200+
this.setStyle("control");
201201
this.setPreviousStatement(true);
202202
},
203203
};

src/blocks/vertical_extensions.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ VerticalExtensions.colourHelper = function (category) {
4343
* @this {Blockly.Block}
4444
*/
4545
return function () {
46-
this.setStyle(`colours_${category}`);
46+
this.setStyle(category);
4747
};
4848
};
4949

src/colours.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const Colours = {
5252
numPadText: "white", // Do not use hex here, it cannot be inlined with data-uri SVG
5353
valueReportBackground: "#FFFFFF",
5454
valueReportBorder: "#AAAAAA",
55-
menuHover: "rgba(77, 151, 255, .25)",
55+
contextualMenuHover: "rgba(77, 151, 255, .25)",
5656
};
5757

5858
function varify(coloursObj, prefix = "--colour") {

src/css.js

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -413,19 +413,32 @@ const styles = `
413413
cursor: pointer;
414414
}
415415
416-
.scratch-renderer.scratch-theme .blocklyFlyoutLabelText {
416+
.scratch-renderer.default-theme .blocklyFlyoutLabelText,
417+
.scratch-renderer.high-contrast-theme .blocklyFlyoutLabelText {
417418
font-family: "Helvetica Neue", Helvetica, sans-serif;
418419
font-size: 14pt;
419420
fill: #575E75;
420421
font-weight: bold;
421422
}
422423
423-
.scratch-renderer.scratch-theme .blocklyText,
424-
.scratch-renderer.scratch-theme .blocklyHtmlInput {
424+
.scratch-renderer.default-theme .blocklyText,
425+
.scratch-renderer.default-theme .blocklyHtmlInput,
426+
.scratch-renderer.high-contrast-theme .blocklyText,
427+
.scratch-renderer.high-contrast-theme .blocklyHtmlInput {
425428
font-weight: 500;
426429
}
427430
428-
.scratch-renderer.scratch-theme .blocklyFlyoutButton .blocklyText {
431+
.scratch-renderer.high-contrast-theme .blocklyText,
432+
.scratch-renderer.high-contrast-theme .blocklyEditableField .blocklyDropdownText {
433+
fill: #000 !important;
434+
}
435+
436+
.scratch-renderer.high-contrast-theme .blocklyEditableField image:last-child {
437+
filter: invert(1);
438+
}
439+
440+
.scratch-renderer.default-theme .blocklyFlyoutButton .blocklyText,
441+
.scratch-renderer.high-contrast-theme .blocklyFlyoutButton .blocklyText {
429442
fill: var(--colour-textFieldText);
430443
}
431444
@@ -990,10 +1003,14 @@ const styles = `
9901003
z-index: 20000; /* Arbitrary, but some apps depend on it... */
9911004
}
9921005
993-
.blocklyWidgetDiv .blocklyMenu .blocklyMenuItem:hover {
1006+
.blocklyDropDownDiv .blocklyMenu .blocklyMenuItem:hover {
9941007
background: var(--colour-menuHover);
9951008
}
9961009
1010+
.blocklyWidgetDiv .blocklyMenu .blocklyMenuItem:hover {
1011+
background: var(--colour-contextualMenuHover);
1012+
}
1013+
9971014
.blocklyWidgetDiv .blocklyMenu .blocklyMenuItemDisabled.blocklyMenuItem:hover {
9981015
background: none;
9991016
}
@@ -1117,7 +1134,8 @@ const styles = `
11171134
transform: rotate(-180deg);
11181135
}
11191136
1120-
.scratch-renderer.scratch-theme .blocklyComment .blocklyTextarea {
1137+
.scratch-renderer.default-theme .blocklyComment .blocklyTextarea,
1138+
.scratch-renderer.high-contrast-theme .blocklyComment .blocklyTextarea {
11211139
border: none;
11221140
--commentFillColour: #fef49c;
11231141
font-size: 12pt;
@@ -1126,7 +1144,8 @@ const styles = `
11261144
color: #575e75;
11271145
}
11281146
1129-
.scratch-renderer.scratch-theme .blocklyCommentText.blocklyText {
1147+
.scratch-renderer.default-theme .blocklyCommentText.blocklyText,
1148+
.scratch-renderer.high-contrast-theme .blocklyCommentText.blocklyText {
11301149
font-weight: 400;
11311150
}
11321151
@@ -1146,6 +1165,9 @@ const styles = `
11461165
min-height: 32px;
11471166
padding: 4px 7em 4px 28px;
11481167
}
1168+
.high-contrast-theme.blocklyDropDownDiv .blocklyMenuItem {
1169+
color: #000;
1170+
}
11491171
.blocklyToolboxSelected .blocklyTreeLabel {
11501172
color: var(--colour-toolboxText);
11511173
}
@@ -1161,8 +1183,10 @@ const styles = `
11611183
width: 20px;
11621184
}
11631185
1164-
.scratch-renderer.scratch-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>rect,
1165-
.scratch-renderer.scratch-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>.blocklyPath {
1186+
.scratch-renderer.default-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>rect,
1187+
.scratch-renderer.default-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>.blocklyPath,
1188+
.scratch-renderer.high-contrast-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>rect,
1189+
.scratch-renderer.high-contrast-theme .blocklyDraggable:not(.blocklyDisabled) .blocklyEditableField:not(.blocklyEditing):hover>.blocklyPath {
11661190
stroke: revert-layer;
11671191
stroke-width: 1;
11681192
}

src/fields/field_dropdown.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@
77
import * as Blockly from "blockly/core";
88

99
class FieldDropdown extends Blockly.FieldDropdown {
10+
originalStyle;
11+
1012
showEditor_(event) {
1113
super.showEditor_(event);
1214
const sourceBlock = this.getSourceBlock();
15+
const style = sourceBlock.style;
1316
if (sourceBlock.isShadow()) {
1417
this.originalStyle = sourceBlock.getStyleName();
15-
sourceBlock.setColour(
16-
sourceBlock.style.colourQuaternary ?? sourceBlock.style.colourTertiary
18+
sourceBlock.setStyle(`${this.originalStyle}_selected`);
19+
} else if (this.borderRect_) {
20+
this.borderRect_.setAttribute(
21+
"fill",
22+
style.colourQuaternary ?? style.colourTertiary
1723
);
1824
}
1925
}

src/fields/field_matrix.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import * as Blockly from "blockly/core";
3232
* @constructor
3333
*/
3434
export class FieldMatrix extends Blockly.Field {
35+
originalStyle;
36+
3537
constructor(matrix) {
3638
super(matrix);
3739
/**
@@ -332,7 +334,11 @@ export class FieldMatrix extends Blockly.Field {
332334
this.sourceBlock_.getColour(),
333335
this.sourceBlock_.getColourTertiary()
334336
);
335-
Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_);
337+
Blockly.DropDownDiv.showPositionedByBlock(
338+
this,
339+
this.sourceBlock_,
340+
this.dropdownDispose_.bind(this)
341+
);
336342

337343
this.matrixTouchWrapper_ = Blockly.browserEvents.bind(
338344
this.matrixStage_,
@@ -353,10 +359,29 @@ export class FieldMatrix extends Blockly.Field {
353359
this.fillMatrix_
354360
);
355361

362+
const sourceBlock = this.getSourceBlock();
363+
const style = sourceBlock.style;
364+
if (sourceBlock.isShadow()) {
365+
this.originalStyle = sourceBlock.getStyleName();
366+
sourceBlock.setStyle(`${this.originalStyle}_selected`);
367+
} else if (this.borderRect_) {
368+
this.borderRect_.setAttribute(
369+
"fill",
370+
style.colourQuaternary ?? style.colourTertiary
371+
);
372+
}
373+
356374
// Update the matrix for the current value
357375
this.updateMatrix_();
358376
}
359377

378+
dropdownDispose_() {
379+
const sourceBlock = this.getSourceBlock();
380+
if (sourceBlock.isShadow()) {
381+
sourceBlock.setStyle(this.originalStyle);
382+
}
383+
}
384+
360385
/**
361386
* Make an svg object that resembles a 3x3 matrix to be used as a button.
362387
* @param {string} fill The color to fill the matrix nodes.

src/fields/field_variable.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import { ScratchMsgs } from "../../msg/scratch_msgs.js";
2828
import { createVariable, renameVariable } from "../variables.js";
2929

3030
class FieldVariable extends Blockly.FieldVariable {
31+
originalStyle;
32+
3133
constructor(varName, validator, variableTypes, defaultType, config) {
3234
super(varName, validator, variableTypes, defaultType, config);
3335
this.menuGenerator_ = FieldVariable.dropdownCreate;
@@ -139,16 +141,23 @@ class FieldVariable extends Blockly.FieldVariable {
139141
showEditor_(event) {
140142
super.showEditor_(event);
141143
const sourceBlock = this.getSourceBlock();
144+
const style = sourceBlock.style;
142145
if (sourceBlock.isShadow()) {
143-
sourceBlock.setColour(sourceBlock.style.colourQuaternary);
146+
this.originalStyle = sourceBlock.getStyleName();
147+
sourceBlock.setStyle(`${this.originalStyle}_selected`);
148+
} else if (this.borderRect_) {
149+
this.borderRect_.setAttribute(
150+
"fill",
151+
style.colourQuaternary ?? style.colourTertiary
152+
);
144153
}
145154
}
146155

147156
dropdownDispose_() {
148157
super.dropdownDispose_();
149158
const sourceBlock = this.getSourceBlock();
150159
if (sourceBlock.isShadow()) {
151-
sourceBlock.setStyle(`colours_${sourceBlock.type.split("_")[0]}`);
160+
sourceBlock.setStyle(this.originalStyle);
152161
}
153162
}
154163
}

src/index.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import {
3434
import { CheckableContinuousFlyout } from "./checkable_continuous_flyout.js";
3535
import { buildGlowFilter, glowStack } from "./glows.js";
3636
import { ScratchContinuousToolbox } from "./scratch_continuous_toolbox.js";
37-
import { ScratchTheme } from "./scratch_theme.js";
3837
import "./scratch_continuous_category.js";
3938
import "./scratch_comment_icon.js";
4039
import "./scratch_dragger.js";
@@ -73,7 +72,6 @@ export { contextMenuItems };
7372
export function inject(container, options) {
7473
Object.assign(options, {
7574
renderer: "scratch",
76-
theme: ScratchTheme,
7775
plugins: {
7876
toolbox: ScratchContinuousToolbox,
7977
flyoutsVerticalToolbox: CheckableContinuousFlyout,
@@ -82,14 +80,6 @@ export function inject(container, options) {
8280
});
8381
const workspace = Blockly.inject(container, options);
8482

85-
workspace.getRenderer().getConstants().selectedGlowFilterId = "";
86-
87-
const flyout = workspace.getFlyout();
88-
if (flyout) {
89-
flyout.getWorkspace().getRenderer().getConstants().selectedGlowFilterId =
90-
"";
91-
}
92-
9383
buildGlowFilter(workspace);
9484
buildShadowFilter(workspace);
9585

src/renderer/constants.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,40 @@
55
*/
66

77
import * as Blockly from "blockly/core";
8+
import { cssVarify } from "../colours.js";
89

910
export class ConstantProvider extends Blockly.zelos.ConstantProvider {
1011
REPLACEMENT_GLOW_COLOUR = "#ffffff";
12+
13+
/**
14+
* Sets the visual theme used to render the workspace.
15+
* This method also synthesizes a "selected" theme, used to color blocks with
16+
* dropdown menus when the menu is active. Additionally, if the theme's block
17+
* styles contain any raw color values, corresponding CSS variables will be
18+
* created/overridden so that those colors can be dynamically referenced in
19+
* stylesheets.
20+
* @param {!Blockly.Theme} The new theme to apply.
21+
*/
22+
setTheme(theme) {
23+
const root = document.querySelector(":root");
24+
for (const [key, colour] of Object.entries(theme.blockStyles)) {
25+
if (typeof colour === "string") {
26+
const varKey = `--colour-${key}`;
27+
root.style.setProperty(varKey, colour);
28+
} else {
29+
theme.setBlockStyle(`${key}_selected`, {
30+
colourPrimary: colour.colourQuaternary ?? colour.colourTertiary,
31+
colourSecondary: colour.colourQuaternary ?? colour.colourTertiary,
32+
colourTertiary: colour.colourQuaternary ?? colour.colourTertiary,
33+
colourQuaternary: colour.colourQuaternary ?? colour.colourTertiary,
34+
});
35+
}
36+
}
37+
super.setTheme(theme);
38+
}
39+
40+
createDom(svg, tagName, selector) {
41+
super.createDom(svg, tagName, selector);
42+
this.selectedGlowFilterId = "";
43+
}
1144
}

src/scratch_theme.js

Lines changed: 0 additions & 84 deletions
This file was deleted.

0 commit comments

Comments
 (0)