From 57b8debf7eca0d1bafd3515ab3de9495974fa100 Mon Sep 17 00:00:00 2001 From: mfranz <mfranz> Date: Thu, 14 Jun 2007 23:19:43 +0000 Subject: [PATCH] - Dialog: add optional third arg: dialog name (by default taken from the dialog's <name> entry) - FileSelctor: new class derived from Dialog. It clones the file-select dialog and reports chosen files/dirs via callback function. --- Nasal/gui.nas | 70 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/Nasal/gui.nas b/Nasal/gui.nas index 7587b1ec1..1808c98fb 100644 --- a/Nasal/gui.nas +++ b/Nasal/gui.nas @@ -151,8 +151,12 @@ Widget = { # # SYNOPSIS: # (B) Dialog.new(<dialog-name>); ... use dialog from $FG_ROOT/gui/dialogs/ -# (A) Dialog.new(<prop>, <path>); ... load aircraft specific dialog from -# <path> under property <prop> +# +# (A) Dialog.new(<prop>, <path> [, <dialog-name>]); +# ... load aircraft specific dialog from +# <path> under property <prop> and under +# name <dialog-name>; if no name is given, +# then it's taken from the XML dialog # # prop ... target node (name must be "dialog") # path ... file path relative to $FG_ROOT @@ -169,17 +173,18 @@ Widget = { # livery_dialog.toggle(); # Dialog = { - new : func(prop, path = nil) { + new : func(prop, path = nil, name = nil) { var m = { parents : [Dialog] }; m.state = 0; + m.name = name; if (path == nil) { # global dialog in $FG_ROOT/gui/dialogs/ m.prop = props.Node.new({ "dialog-name" : prop }); } else { # aircraft dialog with given path m.path = path; - m.prop = isa(props.Node, prop) ? prop : props.globals.getNode(prop, 1); - if (m.prop.getName() != "dialog") { + m.prop = isa(prop, props.Node) ? prop : props.globals.getNode(prop, 1); + if (m.prop.getName() != "dialog") die("Dialog class: node name must end with '/dialog'"); - } + m.listener = setlistener("/sim/signals/reinit-gui", func { m.load() }, 1); } return m; @@ -193,11 +198,16 @@ Dialog = { me.prop.removeChildren(); fgcommand("loadxml", props.Node.new({"filename": getprop("/sim/fg-root") ~ "/" ~ me.path, "targetnode": me.prop.getPath()})); + var n = me.prop.getNode("name"); if (n == nil) die("Dialog class: XML dialog must have <name>"); - me.name = n.getValue(); + if (me.name == nil) + me.name = n.getValue(); + else + n.setValue(me.name); + me.prop.getNode("dialog-name", 1).setValue(me.name); fgcommand("dialog-new", me.prop); if (state) @@ -225,10 +235,51 @@ Dialog = { }; +## +# Open file select dialog (subclass of the Dialog class). +# +# SYNOPSIS: FileSelector.new(<callback> [, <oper> [, <dir> [, <file> [, <hidden>]]]) +# +# callback ... callback function that gets return value as cmdarg().getValue() +# oper ... string that describes purpose (put on the "OK" button) +# dir ... starting dir ($FG_ROOT if unset) +# file ... pre-selected default file name +# hidden ... flag that decids whether UNIX dotfiles should be shown (1) or not (0) +# +# EXAMPLE: +# +# var report = func { print("file ", cmdarg().getValue(), " selected") } +# var selector = gui.FileSelector(report, "Save Flight", "/tmp", "flight.sav"); +# selector.open(); # see the Dialog class for other methods +# +var FileSelector = { + new : func(callback, operation = "OK", dir = "", file = "", show_hidden = 0) { + var name = "file-select-" ~ int(1e9 * rand()); + var data = props.globals.getNode("/sim/gui/dialogs/" ~ name, 1); + var m = Dialog.new(data.getNode("dialog", 1), "gui/dialogs/file-select.xml", name); + m.parents = [FileSelector, Dialog]; + data.getNode("operation", 1).setValue(operation); + data.getNode("directory", 1).setValue(dir); + data.getNode("selection", 1).setValue(file); + data.getNode("show-hidden", 1).setBoolValue(show_hidden); + m.cblistener = setlistener(data.getNode("path", 1), callback); + FileSelector.instance[name] = m; + return m; + }, + del : func { + me.close(); + delete(me.instance, me.name); + removelistener(me.cblistener); + me.prop.getParent().removeChild(me.prop.getName(), me.prop.getIndex()); + }, + instance : {}, +}; + + ## # Open property browser with given target path. # -property_browser = func(dir = "/") { +var property_browser = func(dir = "/") { var dlgname = "property-browser"; foreach (var module; keys(globals)) { if (find("__dlg:" ~ dlgname, module) == 0) { @@ -248,9 +299,8 @@ property_browser = func(dir = "/") { settimer(func { foreach (var b; props.globals.getChildren("browser")) { var path = b.getValue(); - if (path != nil and size(path)) { + if (path != nil and size(path)) property_browser(path); - } } props.globals.removeChildren("browser"); }, 0);