1
0
Fork 0
fgdata/Nasal/multikey.nas

120 lines
2.6 KiB
Text
Raw Normal View History

var listener = nil;
var cmd = nil;
var data = nil;
var translate = { 356: '<', 357: '^', 358: '>', 359: '_' };
var start = func {
popup(cmd = "");
listener = setlistener("/devices/status/keyboard/event", func(event) {
var key = event.getNode("key");
2008-09-29 13:30:42 +00:00
if (!event.getNode("pressed").getValue()) {
2008-09-29 22:39:45 +00:00
if (key.getValue() == `;`) # FIXME hack around kbd bug
key.setValue(`:`);
2008-09-29 13:30:42 +00:00
return;
}
if (handle_key(key.getValue()))
key.setValue(-1);
});
}
var stop = func {
2008-09-29 13:30:42 +00:00
gui.popdown();
removelistener(listener);
listener = nil;
}
var handle_key = func(key) {
var mode = 0;
if (key == 27) {
stop();
return 1;
} elsif (key == 8) {
cmd = substr(cmd, 0, size(cmd) - 1);
} elsif (key == `\n` or key == `\r`) {
mode = 2;
} elsif (contains(translate, key)) {
cmd ~= translate[key];
} elsif (!string.isprint(key)) {
return 0;
} else {
cmd ~= chr(key);
}
2008-09-29 14:16:50 +00:00
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;
}
}
}
if (mode and size(bindings)) {
foreach (var b; bindings)
props.runBinding(b, "__multikey");
if (mode == 2)
stop();
}
if (mode < 2)
2008-09-29 14:16:50 +00:00
popup(cmd, __multikey._ or desc);
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);
gui.popupTip("", 1e9, { layout: "vbox", text:
[{ label: title, color: { red: r, green: g, blue: b } },
{ label: cmd }] });
}
var init = func {
2008-09-29 22:39:45 +00:00
globals["__multikey"] = { _: };
var tree = props.globals.getNode("/input/keyboard/multikey", 1);
foreach (var n; tree.getChildren("nasal")) {
n.getNode("module", 1).setValue("__multikey");
fgcommand("nasal", n);
}
var add = func(node, label) {
var name = node.getNode("name", 1).getValue();
2008-09-29 22:39:45 +00:00
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]);
}
data = [];
add(tree, "");
data = sort(data, func(a, b) -cmp(a[0], b[0]));
}
_setlistener("/sim/signals/nasal-dir-initialized", init);
2008-09-29 22:39:45 +00:00