From 5aa2e485e187640de0aeb902ceabc1d7d9e4a133 Mon Sep 17 00:00:00 2001 From: Dr Tracy Gardner Date: Mon, 23 Feb 2026 15:26:11 +0000 Subject: [PATCH] Add list variable setter shadows to Lists flyout --- main/blocklyinit.js | 113 ++++++++++++++++++++++++++++++++++++++++++++ toolbox.js | 3 +- 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/main/blocklyinit.js b/main/blocklyinit.js index d0af3f0d..0fea5240 100644 --- a/main/blocklyinit.js +++ b/main/blocklyinit.js @@ -441,6 +441,119 @@ export function initializeWorkspace() { return xmlList; }); + workspace.registerToolboxCategoryCallback("LIST", function (ws) { + const xmlList = []; + const variableMap = ws.getVariableMap(); + const getNextListName = () => { + const vars = variableMap.getAllVariables(); + let maxSuffix = 0; + vars.forEach((model) => { + const match = model.name.match(/^list(\d+)$/); + if (match) { + maxSuffix = Math.max( + maxSuffix, + parseInt(match[1], 10), + ); + } + }); + return `list${maxSuffix + 1}`; + }; + + const createSetListBlock = (valueBuilder) => { + const block = document.createElement("block"); + block.setAttribute("type", "variables_set"); + + const field = document.createElement("field"); + field.setAttribute("name", "VAR"); + field.setAttribute("variabletype", ""); + field.textContent = getNextListName(); + block.appendChild(field); + + const value = document.createElement("value"); + value.setAttribute("name", "VALUE"); + value.appendChild(valueBuilder()); + block.appendChild(value); + + return block; + }; + + const createListShadow = (shadowType, values) => { + const shadow = document.createElement("shadow"); + shadow.setAttribute("type", "lists_create_with"); + shadow.setAttribute("inline", "true"); + + const mutation = document.createElement("mutation"); + mutation.setAttribute("items", "2"); + shadow.appendChild(mutation); + + values.forEach((value, index) => { + const valueNode = document.createElement("value"); + valueNode.setAttribute("name", `ADD${index}`); + const childShadow = document.createElement("shadow"); + childShadow.setAttribute("type", shadowType); + const field = document.createElement("field"); + field.setAttribute( + "name", + shadowType === "math_number" + ? "NUM" + : shadowType === "colour" + ? "COLOR" + : "TEXT", + ); + field.textContent = String(value); + childShadow.appendChild(field); + valueNode.appendChild(childShadow); + shadow.appendChild(valueNode); + }); + + return shadow; + }; + + xmlList.push( + createSetListBlock(() => { + const shadow = document.createElement("shadow"); + shadow.setAttribute("type", "lists_create_empty"); + return shadow; + }), + ); + xmlList.push( + createSetListBlock(() => + createListShadow("math_number", [1, 2]), + ), + ); + xmlList.push( + createSetListBlock(() => createListShadow("text", ["", ""])), + ); + xmlList.push( + createSetListBlock(() => + createListShadow("colour", ["#ff0000", "#0000ff"]), + ), + ); + + [ + "lists_create_empty", + "lists_create_with", + "lists_repeat", + "lists_length", + "lists_isEmpty", + "lists_indexOf", + "lists_getIndex", + "lists_setIndex", + "lists_getSublist", + "lists_split", + "lists_sort", + ].forEach((type) => { + const block = document.createElement("block"); + block.setAttribute("type", type); + if (type === "lists_create_with") { + block.setAttribute("inline", "true"); + } + xmlList.push(block); + }); + + return xmlList; + }); + // Add change listeners workspace.addChangeListener(BlockDynamicConnection.finalizeConnections); workspace.addChangeListener(handleBlockSelect); diff --git a/toolbox.js b/toolbox.js index 55a22507..4664f474 100644 --- a/toolbox.js +++ b/toolbox.js @@ -3273,6 +3273,7 @@ const toolboxLists = { icon: "./images/lists.svg", //colour: categoryColours["Lists"], categorystyle: "variables_category", + custom: "LIST", contents: [ { kind: "block", @@ -4896,4 +4897,4 @@ Blockly.registry.register( Blockly.CollapsibleToolboxCategory.registrationName, CustomCollapsibleToolboxCategory, true, -); \ No newline at end of file +);