srecord noeq JG22NetworkElement(G22Utils g22utils, JG22Network parent, G22NetworkElement element) is Swingable { CollapsibleLeftPanel collapsiblePanel; JLeftArrowScriptIDE ide; SingleComponentPanel scpContent = scp(); JLabel lblDirty = jlabel(); transient new BoolVarWithNotify visualizing; { visualizing.onChange(l0 updateDirtyFlag); } cachedVisualize { ide = g22utils.leftArrowIDE(); ide.makeParser = -> { var parser = ide.makeParser_base(); element.configureParser(parser); ret parser; }; ide.withResultPanel(false); ide.lvScript(element.varCode()); ide.runScript = l0 calculate; var popDownButton = withRightMargin(jfullcenter( jPopDownButton_noText( "Calculate" := rThread calculate, "Visualize" := rThread visualizeNode, "Configure" := rThread configureNode, "Create input ports" := rThread autoCreateInputPorts, "Create output port" := rThread autoCreateOutputPort, "Copy code" := rThread copyCode, "Delete node" := rThread deleteElement ))); var lblNodeID = toolTip("Click here to drag node around", jlabel("Node:")); componentPopupMenuItem(lblDirty, "Show error", rThread showError); collapsiblePanel = new CollapsibleLeftPanel( false, "Code", jMinWidth(0, ide.visualize()), jMinWidth(0, northAndCenter( centerAndEastWithMargin( withLabel(lblNodeID, centerTextField(jVarTextField(element.varIdentifier()))), jline( lblDirty, popDownButton)), scpContent))); bindVarToVar(element.varCodeVisible(), collapsiblePanel.varExpanded()); var box = collapsiblePanel.visualize(); jMinSize(80, 50, box); setBorder(box, BorderFactory.createLineBorder(Color.green, 5); onMouseDown(lblNodeID, event -> { new ComponentDragger(box, event).bringToFront(true).start(); }); new ComponentResizeDragger(box, box); var bounds = or(element.bounds, rect(50, 50, 400, 300)); setBounds(box, bounds); onBoundsChange(box, r { element.bounds(toRect(getBounds(box))); element.network.change(); parent.mainPanel.revalidateMe(); }); ret box; } void deleteElement { parent.deleteElement(this); } void calculate { pcall-infobox { parent.networkInstance.calculateNode(g22utils, element); visualizeNode(); } } void configureNode { pcall-infobox { element.configureBlueprint(g22utils); } } void visualizeNode { pcall-infobox { temp tempSetBoolVar(visualizing); var parsedScript = element.compile(g22utils)!; callVisualizeFunction(parsedScript); } } void callVisualizeFunction(GazelleV_LeftArrowScript.Script parsedScript) { var visualizeFunction = parsedScript.getFunction("visualize"); O elementInstance = myInstance(); Component visualized = null; if (visualizeFunction != null) { var val = myValue(); O valueHandler = new O { void setValue(O o) { parent.networkInstance.setObject(element, val, o); } }; // TODO: timeout? RunResultWithTimestamps value = runResultWithTimestamps(-> wrap( visualizeFunction.call( new FlexibleVarContext, elementInstance, valueHandler, element))); ide.showScriptResult(value); if (value.isOK()) visualized = wrap(value!); else visualized = jErrorView(value.error()); } else visualized = new G22JavaObjectVisualizer(g22utils, elementInstance).visualize(); print(+visualized); scpContent.set(visualized); } void updateDirtyFlag { var value = myValue(); setText(lblDirty, value == null ? " " : visualizing! ? "Visualizing" : value.calculating() ? "Calculating" : value.hasError() ? "Error" : value.dirty() ? "Dirty" : "Clean"); } O myInstance() { O elementInstance = null; var ni = parent.networkInstance; if (ni != null) elementInstance = ni.getObjectForBlueprint(element); ret elementInstance; } G22NetworkInstance.Value myValue() { O elementInstance = null; var ni = parent.networkInstance; ret ni?.valuesByBlueprint.get(element); } void copyCode { copyTextToClipboardVerbose(element.code()); } void showError { showErrorFrame(myValue().error()); } void autoCreateOutputPort { element.autoCreateOutputPort(myValue()); } void autoCreateInputPorts { element.autoCreateInputPorts(g22utils); } }