/// <summary> /// Run a deletion event. /// </summary> /// <param name="forward"></param> public override void run(bool forward) { var workspace = Workspace.getById(this.workspaceId); if (forward) { foreach (var id in this.ids) { var block = (BlockSvg)workspace.getBlockById(id); if (block != null) { block.dispose(false, false); } else if (id == this.blockId) { // Only complain about root-level block. Console.WriteLine("Can't delete non-existant block: " + id); } } } else { var xml = goog.dom.createDom("xml"); xml.AppendChild(this.oldXml); Xml.domToWorkspace(xml, workspace); } }
/// <summary> /// Enable/disable a block depending on whether it is properly connected. /// Use this on applications where all blocks should be connected to a top block. /// Recommend setting the 'disable' option to 'false' in the config so that /// users don't try to reenable disabled orphan blocks. /// </summary> /// <param name="ev">Custom data for event.</param> public static void disableOrphans(Events.Abstract ev) { if (ev.type == Events.MOVE || ev.type == Events.CREATE) { Events.disable(); var workspace = Workspace.getById(ev.workspaceId); var block = workspace.getBlockById(ev.blockId); if (block != null) { if (block.getParent() != null && !block.getParent().disabled) { var children = block.getDescendants(); foreach (var child in children) { child.setDisabled(false); } } else if ((block.outputConnection != null || block.previousConnection != null) && Core.dragMode_ == Core.DRAG_NONE) { do { block.setDisabled(true); block = block.getNextBlock(); } while (block != null); } } Events.enable(); } }
/// <summary> /// Run a move event. /// </summary> /// <param name="forward">True if run forward, false if run backward (undo).</param> public override void run(bool forward) { var workspace = Workspace.getById(this.workspaceId); var block = workspace.getBlockById(this.blockId); if (block == null) { Console.WriteLine("Can't move non-existant block: " + this.blockId); return; } var parentId = forward ? this.newParentId : this.oldParentId; var inputName = forward ? this.newInputName : this.oldInputName; var coordinate = forward ? this.newCoordinate : this.oldCoordinate; Block parentBlock = null; if (parentId != null) { parentBlock = workspace.getBlockById(parentId); if (parentBlock == null) { Console.WriteLine("Can't connect to non-existant block: " + parentId); return; } } if (block.getParent() != null) { block.unplug(); } if (coordinate != null) { var xy = block.getRelativeToSurfaceXY(); block.moveBy(coordinate.x - xy.x, coordinate.y - xy.y); } else { var blockConnection = block.outputConnection != null ? block.outputConnection : block.previousConnection; Connection parentConnection = null; if (inputName != null) { var input = parentBlock.getInput(inputName); if (input != null) { parentConnection = input.connection; } } else if (blockConnection.type == Core.PREVIOUS_STATEMENT) { parentConnection = parentBlock.nextConnection; } if (parentConnection != null) { blockConnection.connect(parentConnection); } else { Console.WriteLine("Can't connect to non-existant input: " + inputName); } } }
/// <summary> /// Fire all queued events. /// </summary> private static void fireNow_() { var queue = Events.filter(Events.FIRE_QUEUE_, true); Events.FIRE_QUEUE_.Clear(); foreach (var ev in queue) { var workspace = Workspace.getById(ev.workspaceId); if (workspace != null) { workspace.fireChangeListener(ev); } } }
/// <summary> /// Returns the parentId and input if the block is connected, /// or the XY location if disconnected. /// </summary> /// <returns>Collection of location info.</returns> private Location currentLocation_() { var workspace = Workspace.getById(this.workspaceId); var block = workspace.getBlockById(this.blockId); var location = new Location(); var parent = block.getParent(); if (parent != null) { location.parentId = parent.id; var input = parent.getInputWithBlock(block); if (input != null) { location.inputName = input.name; } } else { location.coordinate = block.getRelativeToSurfaceXY(); } return(location); }
/// <summary> /// Run a change event. /// </summary> /// <param name="forward">True if run forward, false if run backward (undo).</param> public override void run(bool forward) { var workspace = Workspace.getById(this.workspaceId); var block = (BlockSvg)workspace.getBlockById(this.blockId); if (block == null) { Console.WriteLine("Can't change non-existant block: " + this.blockId); return; } if (block.mutator != null) { // Close the mutator (if open) since we don't want to update it. block.mutator.setVisible(false); } var value = forward ? this.newValue : this.oldValue; switch (this.element) { case "field": var field = block.getField(this.name); if (field != null) { // Run the validator for any side-effects it may have. // The validator's opinion on validity is ignored. field.callValidator(value); field.setValue(value); } else { Console.WriteLine("Can't set non-existant field: " + this.name); } break; case "comment": block.setCommentText(value); break; case "collapsed": block.setCollapsed(value == "true"); break; case "disabled": block.setDisabled(value == "true"); break; case "inline": block.setInputsInline(value == "true"); break; case "mutation": var oldMutation = ""; if (true /*block.mutationToDom*/) { var oldMutationDom = block.mutationToDom(); oldMutation = oldMutationDom != null?oldMutationDom.ToString() : Xml.domToText(oldMutationDom); } if (true /*block.domToMutation*/) { value = value != null ? value : "<mutation></mutation>"; var dom = Xml.textToDom("<xml>" + value + "</xml>"); block.domToMutation((Element)dom.FirstChild); } Events.fire(new Events.Change( block, "mutation", null, oldMutation, value)); break; default: Console.WriteLine("Unknown change type: " + this.element); break; } }