From 5c1b5179a994f83c9ef542aaf047808023e9ced9 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Tue, 26 Mar 2024 14:55:59 -0700 Subject: [PATCH] Several Blockly fixes (#9939) * restore red color of block quotes * bring back default paramter for text blocks * bring back light outline for dark shadow blocks * remove references to inDebugWorkspace * get field slider track color from the parent block --- libs/pxt-common/pxt-core.d.ts | 7 ++++++ pxtblocks/builtins/loops.ts | 4 ++-- pxtblocks/builtins/variables.ts | 4 ++-- .../blocks/functionDefinitionBlock.ts | 4 ++-- pxtblocks/plugins/functions/extensions.ts | 2 +- pxtblocks/plugins/math/fieldSlider.ts | 24 ++++++++++++++++++- pxtblocks/plugins/renderer/pathObject.ts | 18 ++++++++++++++ pxtblocks/plugins/text/fieldString.ts | 6 +++++ pxtblocks/toolbox.ts | 2 +- pxtlib/blocks.ts | 4 ++-- 10 files changed, 64 insertions(+), 11 deletions(-) diff --git a/libs/pxt-common/pxt-core.d.ts b/libs/pxt-common/pxt-core.d.ts index 5645a41a2761..c3ff32eb6f67 100644 --- a/libs/pxt-common/pxt-core.d.ts +++ b/libs/pxt-common/pxt-core.d.ts @@ -272,6 +272,7 @@ declare interface String { //% shim=String_::charAt weight=48 //% help=text/char-at //% blockId="string_get" block="char from %this=text|at %pos" blockNamespace="text" + //% this.defl="this" charAt(index: number): string; /** Returns the length of a String object. */ @@ -293,6 +294,7 @@ declare interface String { //% shim=String_::compare //% help=text/compare //% blockId="string_compare" block="compare %this=text| to %that" blockNamespace="text" + //% this.defl="this" compare(that: string): number; /** @@ -303,6 +305,7 @@ declare interface String { //% helper=stringSubstr //% help=text/substr //% blockId="string_substr" block="substring of %this=text|from %start|of length %length" blockNamespace="text" + //% this.defl="this" substr(start: number, length?: number): string; /** @@ -338,6 +341,7 @@ declare interface String { //% help=text/is-empty //% blockId="string_isempty" blockNamespace="text" //% block="%this=text| is empty" + //% this.defl="this" isEmpty(): boolean; /** @@ -349,6 +353,7 @@ declare interface String { //% help=text/index-of //% blockId="string_indexof" blockNamespace="text" //% block="%this=text|find index of %searchValue" + //% this.defl="this" indexOf(searchValue: string, start?: number): number; /** @@ -360,6 +365,7 @@ declare interface String { //% help=text/includes //% blockId="string_includes" blockNamespace="text" //% block="%this=text|includes %searchValue" + //% this.defl="this" includes(searchValue: string, start?: number): boolean; /** @@ -371,6 +377,7 @@ declare interface String { //% help=text/split //% blockId="string_split" blockNamespace="text" //% block="split %this=text|at %separator" + //% this.defl="this" split(separator?: string, limit?: number): string[]; /** diff --git a/pxtblocks/builtins/loops.ts b/pxtblocks/builtins/loops.ts index bc43e63ef107..1b70cfdd6a0a 100644 --- a/pxtblocks/builtins/loops.ts +++ b/pxtblocks/builtins/loops.ts @@ -177,8 +177,8 @@ export function initLoops() { * @param {!Array} options List of menu options to add to. * @this Blockly.Block */ - customContextMenu: function (options: any[]) { - if (!this.isCollapsed() && !this.inDebugWorkspace()) { + customContextMenu: function (this: Blockly.BlockSvg, options: any[]) { + if (!this.isCollapsed() && !(this.workspace?.options?.readOnly)) { let option: any = { enabled: true }; let name = this.getField('VAR').getText(); option.text = lf("Create 'get {0}'", name); diff --git a/pxtblocks/builtins/variables.ts b/pxtblocks/builtins/variables.ts index 42ba6176a758..6a954ad9b1f3 100644 --- a/pxtblocks/builtins/variables.ts +++ b/pxtblocks/builtins/variables.ts @@ -154,8 +154,8 @@ export function initVariables() { * @param {!Array} options List of menu options to add to. * @this Blockly.Block */ - customContextMenu: function (options: any[]) { - if (!(this.inDebugWorkspace())) { + customContextMenu: function (this: Blockly.BlockSvg, options: any[]) { + if (!(this.workspace?.options?.readOnly)) { let option: any = { enabled: this.workspace.remainingCapacity() > 0 }; diff --git a/pxtblocks/plugins/functions/blocks/functionDefinitionBlock.ts b/pxtblocks/plugins/functions/blocks/functionDefinitionBlock.ts index fdec3856e633..16d6aaa49db8 100644 --- a/pxtblocks/plugins/functions/blocks/functionDefinitionBlock.ts +++ b/pxtblocks/plugins/functions/blocks/functionDefinitionBlock.ts @@ -142,7 +142,7 @@ const FUNCTION_DEFINITION_MIXIN: FunctionDefinitionMixin = { makeEditOption: function (this: FunctionDefinitionBlock) { return { - enabled: true, // FIXME !this.inDebugWorkspace(), + enabled: !(this.workspace?.options?.readOnly), text: Blockly.Msg.FUNCTIONS_EDIT_OPTION, callback: () => { editFunctionCallback(this); @@ -160,7 +160,7 @@ const FUNCTION_DEFINITION_MIXIN: FunctionDefinitionMixin = { callBlock.setAttribute("type", FUNCTION_CALL_BLOCK_TYPE); return { - enabled: this.workspace.remainingCapacity() > 0, // FIXME && !block.inDebugWorkspace(), + enabled: this.workspace.remainingCapacity() > 0 && !(this.workspace?.options?.readOnly), text: Blockly.Msg.FUNCTIONS_CREATE_CALL_OPTION.replace("%1", functionName), callback: Blockly.ContextMenu.callbackFactory(this, callBlock), }; diff --git a/pxtblocks/plugins/functions/extensions.ts b/pxtblocks/plugins/functions/extensions.ts index a221d2c323f1..a667125a3f60 100644 --- a/pxtblocks/plugins/functions/extensions.ts +++ b/pxtblocks/plugins/functions/extensions.ts @@ -52,7 +52,7 @@ function inlineSvgs(this: InlineSvgsExtensionBlock) { const contextMenuEditMixin = { customContextMenu: function (this: Blockly.Block, menuOptions: any[]) { const gtdOption = { - enabled: true, // FIXME: !this.inDebugWorkspace(), + enabled: !(this.workspace?.options?.readOnly), text: Blockly.Msg[MsgKey.FUNCTIONS_GO_TO_DEFINITION_OPTION], callback: () => { const functionName = this.getField("function_name")!.getText(); diff --git a/pxtblocks/plugins/math/fieldSlider.ts b/pxtblocks/plugins/math/fieldSlider.ts index 1734a10a61ed..bec5d51870b3 100644 --- a/pxtblocks/plugins/math/fieldSlider.ts +++ b/pxtblocks/plugins/math/fieldSlider.ts @@ -179,6 +179,25 @@ export class FieldSlider extends Blockly.FieldNumber { slider.min = this.getMin() + ""; slider.max = this.getMax() + ""; slider.value = this.getValue() + ""; + + let color: string; + + if (this.sourceBlock_ instanceof Blockly.BlockSvg) { + // If the block color is white, grab from the parent block instead + if (this.sourceBlock_.getColour() === "#ffffff") { + if (this.sourceBlock_.getParent()) { + color = this.sourceBlock_.getParent().getColourTertiary(); + } + } + else { + color = this.sourceBlock_.getColourTertiary(); + } + } + + if (color) { + slider.setAttribute("style", `--blocklyFieldSliderBackgroundColor: ${color}`); + } + if (!Number.isNaN(this.step_)) { slider.step = this.step_ + ""; } @@ -212,6 +231,9 @@ export class FieldSlider extends Blockly.FieldNumber { Blockly.fieldRegistry.register('field_slider', FieldSlider); Blockly.Css.register(` +:root { + --blocklyFieldSliderBackgroundColor: #547AB2; +} .blocklyFieldSliderLabel { font-family: "Helvetica Neue", "Segoe UI", Helvetica, sans-serif; font-size: 0.65rem; @@ -240,7 +262,7 @@ input[type=range]::-webkit-slider-runnable-track { outline: none; border-radius: 11px; margin-bottom: 20px; - background: #547AB2; + background: var(--blocklyFieldSliderBackgroundColor); } input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; diff --git a/pxtblocks/plugins/renderer/pathObject.ts b/pxtblocks/plugins/renderer/pathObject.ts index fbc96499af05..50fc2c35ef62 100644 --- a/pxtblocks/plugins/renderer/pathObject.ts +++ b/pxtblocks/plugins/renderer/pathObject.ts @@ -74,6 +74,20 @@ export class PathObject extends Blockly.zelos.PathObject { } } + override applyColour(block: Blockly.BlockSvg): void { + super.applyColour(block); + + // For dark shadow blocks, add a lighter border to differentiate + if (block.isShadow() && block.getParent()) { + const colour = block.getParent().style.colourTertiary; + const rgb = Blockly.utils.colour.hexToRgb(colour); + const luminance = calculateLuminance(rgb); + if (luminance < 0.15) { + this.svgPath.setAttribute('stroke', Blockly.utils.colour.blend("#ffffff", colour, 0.3)); + } + } + } + setHasDottedOutllineOnHover(enabled: boolean) { this.hasDottedOutlineOnHover = enabled; @@ -127,6 +141,10 @@ export class PathObject extends Blockly.zelos.PathObject { } } +function calculateLuminance(rgb: number[]) { + return ((0.2126 * rgb[0]) + (0.7152 * rgb[1]) + (0.0722 * rgb[2])) / 255; +} + Blockly.Css.register(` .blockly-dotted-outline-on-hover { transition: stroke .4s; diff --git a/pxtblocks/plugins/text/fieldString.ts b/pxtblocks/plugins/text/fieldString.ts index 6a01ef2d0b4d..ec6a20281441 100644 --- a/pxtblocks/plugins/text/fieldString.ts +++ b/pxtblocks/plugins/text/fieldString.ts @@ -86,4 +86,10 @@ export class FieldString extends Blockly.FieldTextInput { } } +Blockly.Css.register(` +.field-text-quote { + fill: #a31515 !important; +} +`); + Blockly.fieldRegistry.register('field_string', FieldString); \ No newline at end of file diff --git a/pxtblocks/toolbox.ts b/pxtblocks/toolbox.ts index 4b97c7584d1c..dda718a4c98e 100644 --- a/pxtblocks/toolbox.ts +++ b/pxtblocks/toolbox.ts @@ -351,7 +351,7 @@ export function createToolboxBlock(info: pxtc.BlocksInfo, fn: pxtc.SymbolInfo, c let shadowId = t.shadowBlockId; let defaultValue = t.defaultValue; - if (!isFixedInstance && !shadowId) { + if (!isFixedInstance && (!shadowId || shadowId === "variables_get")) { shadowId = "variables_get"; defaultValue = defaultValue || t.definitionName; } diff --git a/pxtlib/blocks.ts b/pxtlib/blocks.ts index 2fe5410761c3..b7dc1b1b8be4 100644 --- a/pxtlib/blocks.ts +++ b/pxtlib/blocks.ts @@ -151,10 +151,10 @@ namespace pxt.blocks { const defName = def.name; const isVar = !def.shadowBlockId || def.shadowBlockId === "variables_get"; - let defaultValue: string; + let defaultValue = fn.attributes.paramDefl[defName] || fn.attributes.paramDefl["this"]; if (isVar) { - defaultValue = def.varName || fn.attributes.paramDefl[defName] || fn.attributes.paramDefl["this"]; + defaultValue = def.varName || defaultValue; } res.thisParameter = {