/// <summary> /// Parse XML to restore the else-if and else inputs. /// </summary> /// <param name="xmlElement">XML storage element.</param> public override void domToMutation(Element xmlElement) { cases_ = new JsArray <Tuple <string, string> >(); foreach (Element childNode in xmlElement.ChildNodes) { if (childNode.NodeName.ToLower() == "case") { var value = childNode.GetAttribute("value"); if (value != null) { cases_.Push(new Tuple <string, string>(value, null)); } else { var min = childNode.GetAttribute("minimum"); var max = childNode.GetAttribute("maximum"); if ((min != null) && (max != null)) { cases_.Push(new Tuple <string, string>(min, max)); } } } } var count = xmlElement.GetAttribute("default"); defaultCount_ = count == null ? 0 : Int32.Parse(count); updateShape_(); }
/// <summary> /// Overrides {@link goog.ui.ControlRenderer#setContent} for palettes. Locates /// the HTML table representing the palette grid, and replaces the contents of /// each cell with a new element from the array of nodes passed as the second /// argument. If the new content has too many items the table will have more /// rows added to fit, if there are less items than the table has cells, then the /// left over cells will be empty. /// </summary> /// <param name="element"> Root element of the palette control.</param> /// <param name="content">Array of items to replace existing /// palette items.</param> public override void setContent(HTMLElement element, goog.ui.ControlContent content) { var items = content.As <JsArray <Node> >(); if (element != null) { var tbody = (HTMLTableSectionElement)goog.dom.getElementsByTagNameAndClass( goog.dom.TagName.TBODY, le.getCssName(this.getCssClass(), "body"), element)[0]; if (tbody != null) { var index = 0; foreach (HTMLTableRowElement row in tbody.Rows) { foreach (var cell in row.Cells) { goog.dom.removeChildren(cell); if (items != null) { var item = items[index++]; if (item != null) { goog.dom.appendChild(cell, item); } } } } // Make space for any additional items. if (index < items.Length) { var cells = new JsArray <Node>(); var dom = goog.dom.getDomHelper(element); var width = ((HTMLTableRowElement)tbody.Rows[0]).Cells.Length; while (index < items.Length) { var item = items[index++]; cells.Push(this.createCell(item, dom)); if (cells.Length == width) { var row = this.createRow(cells, dom); goog.dom.appendChild(tbody, row); cells.Clear(); } } if (cells.Length > 0) { while (cells.Length < width) { cells.Push(this.createCell("", dom)); } var row = this.createRow(cells, dom); goog.dom.appendChild(tbody, row); } } } // Make sure the new contents are still unselectable. goog.style.setUnselectable(element, true, goog.userAgent.GECKO); } }
/// <summary> /// Reconfigure this block based on the mutator dialog's components. /// </summary> /// <param name="containerBlock">Root block in mutator.</param> public override void compose(Block containerBlock) { var clauseBlock = containerBlock.getInputTargetBlock("STACK"); // Count text of inputs. cases_ = new JsArray <Tuple <string, string> >(); defaultCount_ = 0; var statementConnections = new JsArray <Connection>(); Connection defaultStatementConnection = null; while (clauseBlock != null) { switch (clauseBlock.type) { case SwitchCaseTextConstBlock.type_name: { var value = clauseBlock.getFieldValue("CONST"); cases_.Push(new Tuple <string, string>(value, null)); statementConnections.Push(((SwitchCaseTextConstBlock)clauseBlock).statementConnection_); } break; case SwitchCaseTextRangeBlock.type_name: { var range_min = clauseBlock.getFieldValue("RANGE_MIN"); var range_max = clauseBlock.getFieldValue("RANGE_MAX"); cases_.Push(new Tuple <string, string>(range_min, range_max)); statementConnections.Push(((SwitchCaseTextRangeBlock)clauseBlock).statementConnection_); } break; case SwitchCaseTextDefaultBlock.type_name: { defaultCount_++; defaultStatementConnection = ((SwitchCaseTextDefaultBlock)clauseBlock).statementConnection_; } break; default: throw new Exception("Unknown block type."); } clauseBlock = (clauseBlock.nextConnection != null) ? clauseBlock.nextConnection.targetBlock() : null; } updateShape_(); // Reconnect any child blocks. for (var i = 0; i <= cases_.Length; i++) { Mutator.reconnect(statementConnections[i], this, "DO" + i); } Mutator.reconnect(defaultStatementConnection, this, "DEFAULT_DO"); }
/// <summary> /// Undo or redo the previous action. /// </summary> /// <param name="redo">False if undo, true if redo.</param> public void undo(bool redo) { var inputStack = redo ? this.redoStack_ : this.undoStack_; var outputStack = redo ? this.undoStack_ : this.redoStack_; var inputEvent = inputStack.Pop(); if (inputEvent == null) { return; } var events = new JsArray <Events.Abstract> { inputEvent }; // Do another undo/redo if the next one is of the same group. while (inputStack.Length != 0 && inputEvent.group != null && inputEvent.group == inputStack[inputStack.Length - 1].group) { events.Push(inputStack.Pop()); } // Push these popped events on the opposite stack. foreach (var e in events) { outputStack.Push(e); } events = Events.filter(events, redo); Events.recordUndo = false; foreach (var e in events) { e.run(redo); } Events.recordUndo = true; }
/// <summary> /// Finds the top-level blocks and returns them. Blocks are optionally sorted /// by position; top to bottom (with slight LTR or RTL bias). /// </summary> /// <param name="ordered">Sort the list if true.</param> /// <returns>The top-level block objects.</returns> public JsArray <Block> getTopBlocks(bool ordered) { // Copy the topBlocks_ list. var blocks = new JsArray <Block>(); this.topBlocks_.ForEach((b) => blocks.Push(b)); if (ordered && blocks.Length > 1) { var offset = System.Math.Sin(goog.math.toRadians(Workspace.SCAN_ANGLE)); if (this.RTL) { offset *= -1; } blocks.Sort((a, b) => { var aXY = a.getRelativeToSurfaceXY(); var bXY = b.getRelativeToSurfaceXY(); var aa = (aXY.y + offset * aXY.x); var bb = (bXY.y + offset * bXY.x); if (aa == bb) { return(0); } if (aa > bb) { return(1); } else { return(-1); } }); } return(blocks); }
public node procedures_defreturn(ProceduresDefBlock block) { var lv = local_switch(); var args = new JsArray <arg_node>(); for (var x = 0; x < block.arguments_.Length; x++) { args.Push(new arg_node(this, local_add_f(block.arguments_[x]))); } var funcName = intern(block.getFieldValue("NAME")); var branch = statementToCode(block, "STACK"); var returnValue = valueToCode(block, "RETURN"); if (returnValue == null) { returnValue = new return_node(this, returnValue); } ((begin_node)branch).progs.Push(returnValue); var code = new def_node(this, funcName, args, branch); local_resume(lv); return(code); }
/// <summary> /// Get this warning's texts. /// </summary> /// <returns>All texts concatenated into one string.</returns> public override string getText() { var allWarnings = new JsArray <string>(); foreach (var id in this.text_.Keys) { allWarnings.Push(this.text_[id]); } return(allWarnings.Join("\n")); }
private string join_(int[] ints, string dem) { var sb = new JsArray <string>(); foreach (int i in ints) { sb.Push(i.ToString()); } return(sb.Join(dem)); }
/// <summary> /// Given a set of block types, gets the Blockly.Block objects for each block /// type. /// </summary> /// <param name="blockTypes">Array of blocks that have been defined.</param> /// <returns>Array of Blockly.Block objects corresponding /// to the array of blockTypes.</returns> public JsArray <Block> getDefinedBlocks(JsArray <string> blockTypes) { var blocks = new JsArray <Blockly.Block>(); for (var i = 0; i < blockTypes.Length; i++) { blocks.Push(FactoryUtils.getDefinedBlock(blockTypes[i], this.hiddenWorkspace)); } return(blocks); }