1
0
Fork 0

use patthern tree, offer options on <TAB>

This commit is contained in:
mfranz 2008-10-02 00:59:52 +00:00
parent 3fbb11b27a
commit 67c40af00c

View file

@ -1,11 +1,15 @@
var listener = nil;
var cmd = nil;
var data = nil;
var dialog = nil;
var menu = 0;
var translate = { 356: '<', 357: '^', 358: '>', 359: '_' };
var start = func {
popup(cmd = "");
cmd = "";
dialog = Dialog.new();
handle_key(8);
listener = setlistener("/devices/status/keyboard/event", func(event) {
var key = event.getNode("key");
if (!event.getNode("pressed").getValue()) {
@ -20,7 +24,7 @@ var start = func {
var stop = func {
gui.popdown();
dialog.del();
removelistener(listener);
listener = nil;
}
@ -34,7 +38,7 @@ var handle_key = func(key) {
} elsif (key == 8) {
cmd = substr(cmd, 0, size(cmd) - 1);
} elsif (key == 9) {
#
menu = !menu;
} elsif (key == `\n` or key == `\r`) {
mode = 2;
} elsif (contains(translate, key)) {
@ -45,23 +49,18 @@ var handle_key = func(key) {
cmd ~= chr(key);
}
var desc = __multikey._ = nil;
var bindings = [];
if (size(cmd)) {
foreach (var e; data) {
var match = string.scanf(cmd, e[0], __multikey.arg = []);
if (match) {
desc = e[1].getNode("desc", 1).getValue() or "";
desc = call(sprintf, [desc] ~ __multikey.arg);
bindings = e[1].getChildren("binding");
if (e[1].getNode("no-exit") != nil) {
cmd = substr(cmd, 0, size(cmd) - 1);
mode = 1;
} elsif (e[1].getNode("exit") != nil) {
mode = 2;
}
break;
}
var options = [];
var desc = __multikey._ = nil;
if ((var node = find_entry(cmd, data, __multikey.arg = [])) != nil) {
desc = node.getNode("desc", 1).getValue() or "";
desc = call(sprintf, [desc] ~ __multikey.arg);
bindings = node.getChildren("binding");
if (node.getNode("no-exit") != nil) {
cmd = substr(cmd, 0, size(cmd) - 1);
mode = 1;
} elsif (node.getNode("exit") != nil) {
mode = 2;
}
}
@ -72,23 +71,69 @@ var handle_key = func(key) {
stop();
}
if (mode < 2)
popup(cmd, __multikey._ or desc);
dialog.update(cmd, __multikey._ or desc, menu and node != nil ? node.getChildren("key") : []);
return 1;
}
var popup = func(cmd, title = nil) {
if (!size(cmd))
var (title, r, g, b) = ("Command Mode", 1, 0.7, 0);
elsif (title)
var (r, g, b) = (0.7, 1, 0.7);
else
var (title, r, g, b) = ("<unknown>", 1, 0.4, 0.4);
var Dialog = {
new : func {
var m = { parents: [Dialog] };
m.name = "multikey";
m.prop = props.Node.new({ "dialog-name": m.name });
m.isopen = 0;
m.update("", "", []);
return m;
},
del : func {
me.isopen and fgcommand("dialog-close", me.prop);
me.isopen = 0;
},
update : func(cmd, title, options) {
if (!size(cmd))
var (title, r, g, b) = ("Command Mode", 1, 0.7, 0);
elsif (title)
var (r, g, b) = (0.7, 1, 0.7);
else
var (title, r, g, b) = ("<unknown>", 1, 0.4, 0.4);
gui.popupTip("", 1e9, { layout: "vbox", text:
[{ label: title, color: { red: r, green: g, blue: b } },
{ label: cmd }] });
}
me.del();
var dlg = gui.Widget.new();
dlg.set("name", me.name);
dlg.set("y", -80);
dlg.set("layout", "vbox");
dlg.set("default-padding", 5);
var t = dlg.addChild("text");
t.set("label", title);
t.setColor(r, g, b);
dlg.addChild("text").set("label", cmd);
if (options != nil and size(options)) {
dlg.addChild("hrule");
var g = dlg.addChild("group");
g.set("layout", "table");
g.set("default-padding", 3);
forindex (var i; options) {
var c = g.addChild("text");
c.set("label", options[i].getNode("name", 1).getValue());
c.set("row", i);
c.set("col", 0);
var c = g.addChild("text");
c.set("label", " ... ");
c.set("row", i);
c.set("col", 1);
var c = g.addChild("text");
c.set("label", options[i].getNode("desc", 1).getValue() or "");
c.set("row", i);
c.set("col", 2);
c.set("halign", "left");
}
}
fgcommand("dialog-new", dlg.prop());
fgcommand("dialog-show", me.prop);
me.isopen = 1;
},
};
var help = func {
@ -103,7 +148,7 @@ var help = func {
continue;
if (string.isalnum(k[0][0]) and k[0][0] != curr) {
curr = k[0][0];
var line = "--------------------------------------------";
var line = "-----------------------------------------------";
print(debug._c("33", sprintf("\n-- %s %s", title, substr(line, size(title) + 2))));
}
var cmd = k[0];
@ -116,10 +161,10 @@ var help = func {
cmd = string.replace(cmd, "_", debug._c("35", "_"));
printf("%s\t%s", cmd, desc);
}
print(debug._c("33", "\n-- Legend ------------------------------------"));
print(debug._c("33", "\n-- Legend ---------------------------------------"));
printf("\t%s ... unsigned number", debug._c("32", "%u"));
printf("\t%s ... signed number", debug._c("31", "%d"));
printf("\t%s ... floation point number", debug._c("36", "%f"));
printf("\t%s ... floating point number", debug._c("36", "%f"));
printf("\t%s ... cursor left", debug._c("35", "<"));
printf("\t%s ... cursor right", debug._c("35", ">"));
printf("\t%s ... cursor up", debug._c("35", "^"));
@ -127,6 +172,19 @@ var help = func {
}
var find_entry = func(str, data, result) {
foreach (var c; data.children)
if ((var n = find_entry(str, c, result)) != nil)
return n;
if (string.scanf(str, data.format, var res = [])) {
foreach (var r; res)
append(result, r);
return data.node;
}
return nil;
}
var init = func {
globals["__multikey"] = { _: };
var tree = props.globals.getNode("/input/keyboard/multikey", 1);
@ -136,19 +194,18 @@ var init = func {
fgcommand("nasal", n);
}
var add = func(node, label) {
var name = node.getNode("name", 1).getValue();
if (name == nil) # 'or ""' doesn't work here, as we don't want to drop '0'
name = "";
foreach (var key; node.getChildren("key"))
add(key, label ~ name);
if (size(name))
append(data, [label ~ name, node]);
var scan = func(tree, format = "") {
var d = [];
foreach (var n; tree.getChildren("key")) {
var name = n.getNode("name", 1).getValue();
if (name == nil)
continue;
append(d, { format: format ~ name, node: n, children: scan(n, format ~ name) });
}
return d;
}
data = [];
add(tree, "");
data = sort(data, func(a, b) -cmp(a[0], b[0]));
data = { format: "", node: tree, children: scan(tree) };
}