sclass G22LAScriptIDE { settable G22Utils g22utils; settable S noScriptSelectedMsg = "Please select or create a script to edit it"; A script; transient SingleComponentPanel scp; transient JLeftArrowScriptIDE[] ides; transient JTabbedPane tabs; abstract class Mode { S name; gettable bool editable; *(S *name, bool *editable) {} simplyCached abstract IVarWithNotify scriptVar(); void addButtons(JPanel panel) {} toString { ret name; } S tabName() { ret scriptVar().has() ? name : "Not " + firstToLower(name); } } class ModeClearedForAutoRun > Mode { *() { super("Cleared for auto-run", false); } IVarWithNotify scriptVar(A script) { var var = new VirtualVar( -> getVar(script.clearedForAutoRun()), null /*text -> script.setClearedForAutoRun(text == null ?: new ClearForAutoRun(text))*/); addWeakChangeListener(script.varClearedForAutoRun(), var); ret var; } toString { ret name; } } class ModeSaved > Mode { *() { super("Saved", false); } IVarWithNotify scriptVar() { ret getterVarOnly(script.varText()); } void addButtons(JPanel panel) { panel.add(jbutton("Forget code", rThread forgetSaved)); } } class ModeEdit > Mode { *() { super("Editing", true); } IVarWithNotify scriptVar() { var var = new VirtualVar( -> script.textForEditing(), text -> script.editingText(text) ); addWeakChangeListener(script.varEditingText(), var); ret var; } void addButtons(JPanel panel) { panel.add(jbutton("Save", rThread saveEdit)); panel.add(jbutton("Discard changes", rThread discardEdit)); } } transient new ModeSaved modeSaved; transient L modes = ll( new ModeEdit, modeSaved, new ModeClearedForAutoRun ); *(G22Utils *g22utils) {} visualize { ides = new JLeftArrowScriptIDE[l(modes)]; if (scp == null) scp = singleComponentPanel(); loadScript(script); ret scp; } void setScript(A script) { if (this.script != script) loadScript(script); } void loadScript(A script) { this.script = script; if (scp == null) ret; if (script == null) scp.set(jcenteredlabel(noScriptSelectedMsg())); else { tabs = jtabs(); for (int i, Mode mode : unpair iterateWithIndex(modes)) { var ide = ides[i] = g22utils.leftArrowIDE(); modifyIDE(ide); var varScript = mode.scriptVar(); ide.lvScript(varWithNotifyToLiveValue(S.class, varScript)); addTab(tabs, str(mode)); ide.visualize(); JPanel moreButtons = jline(); mode.addButtons(moreButtons); ide.scpMoreButtons.set(moreButtons); ide.setEditable(mode.editable()); varScript.onChangeAndNow(text -> setTab(tabs, i, text == null ? jcenteredlabel("Empty") : wrapIDE(ide)); } script.onChangeAndNow(r { for (int i, Mode mode : unpair iterateWithIndex(modes)) setTabTitle(tabs, i, mode.tabName(script)); }); scp.set(tabs); } } swappable JComponent wrapIDE(JLeftArrowScriptIDE ide) { ret ide.visualize(); } event settingUpIDE(JLeftArrowScriptIDE ide); swappable void modifyIDE(JLeftArrowScriptIDE ide) { ide.showTitle(false); settingUpIDE(ide); } void saveEdit { script.completeEdit(); } void setMode(Mode mode) { selectTab(tabs, indexOf(modes, mode)); } void discardEdit { setMode(modeSaved); script.editingText(null); } void forgetSaved { script.setTextWithHistory(null); } }