property-browser vbox true 3 hbox 1 /sim/gui/dialogs/property-browser/title true true property-list 500 fill fill true /sim/gui/dialogs/property-browser/list dialog-apply property-list nasal hbox 2 true fill true /sim/gui/dialogs/property-browser/label 170 input fill true 170 /sim/gui/dialogs/property-browser/input var self = cmdarg(); var dlgname = self.getNode("name").getValue(); var dlg = props.globals.getNode("/sim/gui/dialogs/" ~ dlgname, 1); var title = dlg.getNode("title", 1); var label = dlg.getNode("label", 1); var input = dlg.getNode("input", 1); var list = dlg.getNode("list", 1); var node = nil; # selected node entry (props.Node) var dir = nil; # current directory (string) var update_interval = 2; var root_title = "Internal Properties"; var no_selection = "[none]"; var update = func(w) { self.setValues({ "dialog-name": dlgname, "object-name": w }); fgcommand("dialog-update", self); } var squeeze = func(s, n) { if (n >= size(s) or 7 > n ) return s; var l = substr(s, 0, (n - 3) / 2); var r = substr(s, size(s) + size(l) + 3 - n); return l ~ "..." ~ r; } var select = func { var lst = list.getValue(); node = props.globals.getNode(lst); if (node == nil) node = props.globals; setprop("/sim/gui/dialogs/property-browser/selected", node.getPath()); if (node.getAttribute("children")) { dir = node.getPath(); title.setValue(node.getPath() == "" ? root_title : lst); node = nil; label.setValue(no_selection); input.setValue(""); } else { var name = node.getName(); var index = node.getIndex(); var type = node.getType(); if (index) name ~= "[" ~ index ~ "]"; var value = nil; if (type == "BOOL") { value = node.getBoolValue() ? "true" : "false"; title.setValue("Hint: Ctrl-click toggles bool values"); settimer(func title.setValue(dir), 5, 1); } elsif (type == "STRING") { value = node.getValue(); } elsif (type == "NONE") { value = ""; } elsif (type != "ALIAS") { value = node.getValue() ~ ""; } label.setValue(squeeze(name, 30)); input.setValue(value); } update("input"); } var set = func { if (node != nil) node.setValue(input.getValue()); } var clone = func(startdir) { var base = props.globals.getNode("/sim/gui/dialogs", 1); var name = "property-browser-"; for (var i = 1; 1; i += 1) if (base.getNode(name ~ i, 0) == nil) break; base = base.getNode(name ~ i, 1).getPath(); setprop(base ~ "/last", startdir); self.setValues({ "name": name ~ i, "dialog-name": name ~ i, "group[0]/text/property": base ~ "/title", "property-list/property": base ~ "/list", "group[1]/text/property": base ~ "/label", "group[1]/input/property": base ~ "/input", }); fgcommand("dialog-new", self); fgcommand("dialog-show", self); var originalPath = '/sim/gui/dialogs/property-browser'; # reset the values, so we don't use incorrect paths # when the last browser is closed and then re-opened # bug: https://sourceforge.net/p/flightgear/codetickets/2044/ self.setValues({ "name": "property-browser", "dialog-name": "property-browser", "group[0]/text/property": originalPath ~ "/title", "property-list/property": originalPath ~ "/list", "group[1]/text/property": originalPath ~ "/label", "group[1]/input/property": originalPath ~ "/input", }); } var auto_update = func { list.setValue(dir); update("property-list"); if (update_interval) settimer(auto_update, update_interval, 1); } dir = dlg.getNode("last") != nil ? dlg.getNode("last").getValue() : "/"; list.setValue(dir); select(); auto_update(); update_interval = 0; if (find("property-browser-", dlgname) >= 0) dlg.getParent().removeChildren(dlgname); else dlg.getNode("last", 1).setValue(dir);