/** * Populate the mutator's dialog with this block's components. * @param {!Workspace} workspace Mutator's workspace. * @return {!Blockly.Block} Root block in mutator. * @this Blockly.Block */ public override Block decompose(Workspace workspace) { var containerBlock = (BlockSvg)workspace.newBlock(ProceduresMutatorcontainerBlock.type_name); containerBlock.initSvg(); // Check/uncheck the allow statement box. if (this.getInput("RETURN") != null) { containerBlock.setFieldValue(this.hasStatements_ ? "TRUE" : "FALSE", "STATEMENTS"); } else { containerBlock.getInput("STATEMENT_INPUT").setVisible(false); } // Parameter list. var connection = containerBlock.getInput("STACK").connection; for (var i = 0; i < this.arguments_.Length; i++) { var paramBlock = (ProceduresMutatorargBlock)workspace.newBlock(ProceduresMutatorargBlock.type_name); paramBlock.initSvg(); paramBlock.setFieldValue(this.arguments_[i], "NAME"); // Store the old location. paramBlock.oldLocation = i; connection.connect(paramBlock.previousConnection); connection = paramBlock.nextConnection; } // Initialize procedure's callers with blank IDs. Core.Procedures.mutateCallers(this); return(containerBlock); }
/** * Populate the mutator's dialog with this block's components. * @param {!Workspace} workspace Mutator's workspace. * @return {!Blockly.Block} Root block in mutator. * @this Blockly.Block */ public override Block decompose(Workspace workspace) { var containerBlock = (BlockSvg)workspace.newBlock(ListsCreateWithContainerBlock.type_name); containerBlock.initSvg(); var connection = containerBlock.getInput("STACK").connection; for (var i = 0; i < this.itemCount_; i++) { var itemBlock = (BlockSvg)workspace.newBlock(ListsCreateWithItemBlock.type_name); itemBlock.initSvg(); connection.connect(itemBlock.previousConnection); connection = itemBlock.nextConnection; } return(containerBlock); }
/** * Populate the mutator's dialog with this block's components. * @param {!Workspace} workspace Mutator's workspace. * @return {!Blockly.Block} Root block in mutator. * @this Blockly.Block */ public override Block decompose(Workspace workspace) { var containerBlock = (BlockSvg)workspace.newBlock(ControlsIfIfBlock.type_name); containerBlock.initSvg(); var connection = containerBlock.nextConnection; for (var i = 1; i <= this.elseifCount_; i++) { var elseifBlock = (BlockSvg)workspace.newBlock(ControlsIfElseIfBlock.type_name); elseifBlock.initSvg(); connection.connect(elseifBlock.previousConnection); connection = elseifBlock.nextConnection; } if (this.elseCount_ != 0) { var elseBlock = (BlockSvg)workspace.newBlock(ControlsIfElseBlock.type_name); elseBlock.initSvg(); connection.connect(elseBlock.previousConnection); } return(containerBlock); }
/// <summary> /// Get Blockly Block by rendering pre-defined block in workspace. /// </summary> /// <param name="blockType"> Type of block that has already been defined.</param> /// <param name="workspace">Workspace on which to render</param> /// the block. /// <returns>The Blockly.Block of desired type.</returns> public static Blockly.Block getDefinedBlock(string blockType, Blockly.Workspace workspace) { workspace.clear(); return(workspace.newBlock(blockType)); }
/// <summary> /// Decode an XML block tag and create a block (and possibly sub blocks) on the /// workspace. /// </summary> /// <param name="xmlBlock">XML block element.</param> /// <param name="workspace">The workspace.</param> /// <returns>The root block created.</returns> private static BlockSvg domToBlockHeadless_(Element xmlBlock, Workspace workspace) { BlockSvg block = null; var prototypeName = xmlBlock.GetAttribute("type"); goog.asserts.assert(prototypeName != null, "Block type unspecified: %s", xmlBlock.OuterHTML); var id = xmlBlock.GetAttribute("id"); block = (BlockSvg)workspace.newBlock(prototypeName, id); BlockSvg blockChild = null; foreach (var xmlChild_ in xmlBlock.ChildNodes) { if (xmlChild_.NodeType == NodeType.Text) { // Ignore any text at the <block> level. It's all whitespace anyway. continue; } Element xmlChild = (Element)xmlChild_; Input input; // Find any enclosed blocks or shadows in this tag. Element childBlockNode = null; Element childShadowNode = null; foreach (var grandchildNode in xmlChild.ChildNodes) { if (grandchildNode.NodeType == NodeType.Element) { if (grandchildNode.NodeName.ToLowerCase() == "block") { childBlockNode = (Element)grandchildNode; } else if (grandchildNode.NodeName.ToLowerCase() == "shadow") { childShadowNode = (Element)grandchildNode; } } } // Use the shadow block if there is no child block. if (childBlockNode == null && childShadowNode != null) { childBlockNode = childShadowNode; } var name = xmlChild.GetAttribute("name"); switch (xmlChild.NodeName.ToLowerCase()) { case "mutation": // Custom data for an advanced block. if (true /*block.domToMutation*/) { block.domToMutation(xmlChild); if (true /*block.initSvg*/) { // Mutation may have added some elements that need initalizing. block.initSvg(); } } break; case "comment": block.setCommentText(xmlChild.TextContent); var visible = xmlChild.GetAttribute("pinned"); if (visible != null && !block.isInFlyout) { // Give the renderer a millisecond to render and position the block // before positioning the comment bubble. Window.SetTimeout(() => { if (block.comment != null /*&& block.comment.setVisible*/) { block.comment.setVisible(visible == "true"); } }, 1); } var bubbleW = Script.ParseFloat(xmlChild.GetAttribute("w") ?? "0.0"); var bubbleH = Script.ParseFloat(xmlChild.GetAttribute("h") ?? "0.0"); if (!Double.IsNaN(bubbleW) && !Double.IsNaN(bubbleH) && block.comment != null /*&& block.comment.setVisible*/) { block.comment.setBubbleSize(bubbleW, bubbleH); } break; case "data": block.data = xmlChild.TextContent; break; case "title": // Titles were renamed to field in December 2013. // Fall through. case "field": var field = block.getField(name); if (field == null) { Console.WriteLine("Ignoring non-existent field " + name + " in block " + prototypeName); break; } field.setValue(xmlChild.TextContent); break; case "value": case "statement": input = block.getInput(name); if (input == null) { Console.WriteLine("Ignoring non-existent input " + name + " in block " + prototypeName); break; } if (childShadowNode != null) { input.connection.setShadowDom(childShadowNode); } if (childBlockNode != null) { blockChild = Xml.domToBlockHeadless_(childBlockNode, workspace); if (blockChild.outputConnection != null) { input.connection.connect(blockChild.outputConnection); } else if (blockChild.previousConnection != null) { input.connection.connect(blockChild.previousConnection); } else { goog.asserts.fail( "Child block does not have output or previous statement."); } } break; case "next": if (childShadowNode != null && block.nextConnection != null) { block.nextConnection.setShadowDom(childShadowNode); } if (childBlockNode != null) { goog.asserts.assert(block.nextConnection != null, "Next statement does not exist."); // If there is more than one XML "next" tag. goog.asserts.assert(!block.nextConnection.isConnected(), "Next statement is already connected."); blockChild = Xml.domToBlockHeadless_(childBlockNode, workspace); goog.asserts.assert(blockChild.previousConnection != null, "Next block does not have previous statement."); block.nextConnection.connect(blockChild.previousConnection); } break; default: // Unknown tag; ignore. Same principle as HTML parsers. Console.WriteLine("Ignoring unknown tag: " + xmlChild.NodeName); break; } } var inline = xmlBlock.GetAttribute("inline"); if (inline != null) { block.setInputsInline(inline == "true"); } var disabled = xmlBlock.GetAttribute("disabled"); if (disabled != null) { block.setDisabled(disabled == "true"); } var deletable = xmlBlock.GetAttribute("deletable"); if (deletable != null) { block.setDeletable(deletable == "true"); } var movable = xmlBlock.GetAttribute("movable"); if (movable != null) { block.setMovable(movable == "true"); } var editable = xmlBlock.GetAttribute("editable"); if (editable != null) { block.setEditable(editable == "true"); } var collapsed = xmlBlock.GetAttribute("collapsed"); if (collapsed != null) { block.setCollapsed(collapsed == "true"); } if (xmlBlock.NodeName.ToLowerCase() == "shadow") { // Ensure all children are also shadows. var children = block.getChildren(); foreach (var child in children) { goog.asserts.assert(child.isShadow(), "Shadow block not allowed non-shadow child."); } block.setShadow(true); } return(block); }