-20 -20 nasal-console nasal-console vbox true hbox 1 1 editfield fill fill true 450 200 6 20 true false sim/gui/selected-style/fonts/nasal-editor /sim/gui/dialogs/nasal-console/edit dialog-apply editfield nasal fill fill true 450 200 6 hbox fill 4 false fill true 20 20 0 1 ## 1 ## ## /sim/gui/dialogs/nasal-console/tab-down[1] ## dialog-apply editfield nasal dialog-update editfield hbox 4 1 var self = cmdarg(); var dlg = props.globals.getNode("/sim/gui/dialogs/nasal-console", 1); var kbdctrl = props.globals.getNode("/devices/status/keyboard/ctrl", 1); var edit = dlg.getNode("edit", 1); if (!contains(globals, "__nasal_console")) globals["__nasal_console"] = {}; var locals = globals["__nasal_console"]; var numtabs = size(dlg.getChildren("code")); if (!numtabs) numtabs = 10; var dump = func { gui.dialog_apply("nasal-console", "editfield"); select(active); rule = "--------------------------------------------------------------------------------"; print(rule ~ "\n"); print(edit.getValue()); print(rule); } var clear = func { edit.setValue(""); select(active); } var copy = func { gui.dialog_apply("nasal-console", "editfield"); select(active); clipboard.setText( edit.getValue() ); } var paste = func { edit.setValue( clipboard.getText() ); select(active); } var execute = func(what = nil) { var num = what != nil ? what.getIndex() : active; var tag = "<nasal-console/#" ~ num ~ ">"; var err = []; if (what == nil) what = edit; var f = call(func { compile(what.getValue(), tag) }, nil, nil, nil, err); if (size(err)) { print(tag ~ ": " ~ err[0]); return; } f = bind(f, globals); call(f, nil, nil, locals, err); debug.printerror(err); } var tabs = self.getNode("group[1]"); var select = func(which, init = 0) { if (active) { # false in help mode dlg.getNode("active").setIntValue(active); if (!init) dlg.getChild("code", active).setValue(string.trim(edit.getValue())); } if (kbdctrl.getValue()) { execute(dlg.getChild("code", which)); return; } active = which; foreach (var c; dlg.getChildren("tab-down")) c.setBoolValue(c.getIndex() == active); dlg.getNode("active").setIntValue(active = which); edit.setValue(dlg.getChild("code", active).getValue()); } var get_button_desc = func (b) { var sep = " ... "; var key=b.getChild("key"); var desc=b.getChild("key-desc"); if( !isa(key, props.Node) or !isa(desc, props.Node) ) return ""; return " "~key.getValue() ~sep~desc.getValue() ~"\n"; } var key_bindings = (func { var desc = ""; var buttons = self.getNode("group[2]").getChildren("button"); foreach(var b; buttons) desc ~= get_button_desc(b); return desc; })(); var help = func { active = 0; foreach (var c; dlg.getChildren("tab-down")) c.setBoolValue(0); edit.setValue("Keys:\n" ~ " tab ... leave edit mode (visible text cursor)\n" ~ " return ... execute active code\n" ~ key_bindings ~ " esc ... close dialog\n\n" ~ "Ctrl-click on tab buttons executes code without\n" ~ "switching to the tab. Add more <code> properties\n" ~ "in ~/.fgfs/autosave.xml for more tab buttons."); } # setup tab buttons and properties from the template tabs.removeChildren("button"); var template = tabs.getNode("button-template"); var d = dlg.getPath(); for (var i = 1; i <= numtabs; i += 1) { var button = tabs.getChild("button", i, 1); var state = dlg.getChild("tab-down", i, 1); state.setBoolValue(0); props.copy(template, button); button.getNode("enabled").setBoolValue(1); button.getNode("legend").setIntValue(i); button.getNode("binding[1]/script").setValue("select(" ~ i ~ ")"); button.getNode("property").setValue(state.getPath()); var c = dlg.getChild("code", i); if (c == nil or c.getType() == "NONE") { c = dlg.getChild("code", i, 1); c.setValue(""); c.setAttribute("userarchive", 1); } } edit.setValue(""); var active = dlg.getNode("active", 1).getValue(); if (active == nil) active = 1; select(active, 1);