1
0
Fork 0

- now that XML dialogs run their own Nasal namespace and have <open> and

<close> block, remove autopilot helper file autopilot.nas and (re)implement
  its functionality in autopilot.xml
- make AP dialog "bidirectional" and "live": all input fields are <live>
  (i.e. they are updated as the autopilot settings are changed, for example
  by panel actions or property browser changes)
- dialog input is only forwarded to the AP; no direct checkbox/radiobutton
  handling through widget operation, instead:
- changes to the AP properties operate checkboxes/radiobuttons

This makes the AP dialog always reflect the AP state. If the AP refuses
one setting and sets it back to something else, then the dialog will
immediately react and show the actual setting.
This commit is contained in:
mfranz 2006-04-05 20:24:21 +00:00
parent 352b2bf5ec
commit 4a0b56deb3
2 changed files with 367 additions and 349 deletions

View file

@ -1,83 +0,0 @@
##
## These are just GUI helper routines. The autopilot itself is not a
## Nasal module.
##
tagSettings =
{
"hdg-wing" : ["/autopilot/locks/heading", "wing-leveler"],
"hdg-bug" : ["/autopilot/locks/heading", "dg-heading-hold"],
"hdg-true" : ["/autopilot/locks/heading", "true-heading-hold"],
"hdg-nav" : ["/autopilot/locks/heading", "nav1-hold"],
"vel-throttle" : ["/autopilot/locks/speed", "speed-with-throttle"],
"vel-pitch" : ["/autopilot/locks/speed", "speed-with-pitch-trim"],
"alt-vert" : ["/autopilot/locks/altitude", "vertical-speed-hold"],
"alt-pitch" : ["/autopilot/locks/altitude", "pitch-hold"],
"alt-aoa" : ["/autopilot/locks/altitude", "aoa-hold"],
"alt-alt" : ["/autopilot/locks/altitude", "altitude-hold"],
"alt-agl" : ["/autopilot/locks/altitude", "agl-hold"],
"alt-gs" : ["/autopilot/locks/altitude", "gs1-hold"]
};
radioGroups = [["hdg-wing", "hdg-bug", "hdg-true", "hdg-nav"],
["vel-throttle", "vel-pitch"],
["alt-vert", "alt-pitch", "alt-aoa", "alt-alt",
"alt-agl", "alt-gs"]];
# Initialize to get the types of the gui properties correct
INIT = func {
guinode = props.globals.getNode("/autopilot/gui", 1);
foreach(tag; keys(tagSettings)) {
guinode.getNode(tag, 1).setBoolValue(0);
}
foreach(tag; ["hdg", "alt", "vel"]) {
guinode.getNode(tag ~ "-active", 1).setBoolValue(0);
}
}
settimer(INIT, 0);
update = func {
# Suck out the values from the dialog
fgcommand("dialog-apply", props.Node.new());
# Sanitize the radio buttons such that only one is selected. We are
# passed a tag indicating the one that was pressed.
if(size(arg) > 0) {
tag = arg[0];
foreach(group; radioGroups) {
for(i=0; i<size(group); i = i+1) {
if(tag == group[i]) {
if(getprop("/autopilot/gui", tag)) {
# The user just turned it on, turn the rest off...
for(j=0; j<size(group); j=j+1) {
if(j != i) {
setprop("/autopilot/gui", group[j], 0);
}
}
} else {
# The user tried to turn off an active radio
# button. Turn it back on.
setprop("/autopilot/gui", tag, 1);
}
}
}
}
}
# Set the actual output properties for the autopilot system
foreach(tag; keys(tagSettings)) {
setting = tagSettings[tag];
if(getprop("/autopilot/gui", tag)) {
setprop(setting[0], setting[1]);
}
}
if(!getprop("/autopilot/gui/hdg-active")) {
setprop("/autopilot/locks/heading", ""); }
if(!getprop("/autopilot/gui/alt-active")) {
setprop("/autopilot/locks/altitude", ""); }
if(!getprop("/autopilot/gui/vel-active")) {
setprop("/autopilot/locks/speed", ""); }
# Push any changes back to the dialog
fgcommand("dialog-update", props.Node.new());
}

View file

@ -21,160 +21,254 @@
<hrule><dummy/></hrule>
<nasal>
<open>
# manage one AP property group with checkbox and radio buttons
#
Group = {
new : func(name, options) {
var m = { parents: [Group] };
m.name = name;
m.enabled = 0;
m.mode = options[0];
m.options = [];
var node = props.globals.getNode("/autopilot/locks");
if (node.getNode(name) == nil or node.getNode(name, 1).getValue() == nil) {
node.getNode(name, 1).setValue("");
}
m.active = dlg.getNode(name ~ "-active", 1);
foreach (var o; options) {
node = dlg.getNode(o);
if (node == nil) {
node = dlg.getNode(o, 1);
node.setBoolValue(0);
}
append(m.options, node);
}
return m;
},
# handle checkbox
#
enable : func {
me.enabled = me.active.getBoolValue();
setprop("/autopilot/locks/" ~ me.name, me.enabled ? me.mode : "");
},
# handle radiobuttons
#
set : func(mode) {
me.mode = mode;
foreach (var o; me.options) {
o.setBoolValue(o.getName() == mode);
}
if (me.enabled) {
setprop("/autopilot/locks/" ~ me.name, mode);
}
},
# update checkboxes/radiobuttons state from the AP (listener callback)
#
update : func(mode) {
me.enabled = (mode != "");
me.active.setBoolValue(me.enabled);
if (mode == "") {
mode = me.mode;
}
foreach (var o; me.options) {
o.setBoolValue(o.getName() == mode);
}
},
};
var dlg = props.globals.getNode("/sim/gui/dialogs/autopilot", 1);
# - first entry ("heading" etc.) is the target property in /autopilot/locks/ *and*
# the checkbox state property name (with "-active" appended);
# - second entry is a list of available options for the /autopilot/locks/* property
# and used as radio button state property; the first list entry is used as default
#
var hdg = Group.new("heading", ["dg-heading-hold", "wing-leveler", "true-heading-hold", "nav1-hold"]);
var vel = Group.new("speed", ["speed-with-throttle", "speed-with-pitch-trim"]);
var alt = Group.new("altitude", ["altitude-hold", "vertical-speed-hold", "pitch-hold",
"aoa-hold", "agl-hold", "gs1-hold"]);
var lst = [
setlistener("/autopilot/locks/heading", func { hdg.update(cmdarg().getValue()) }, 1),
setlistener("/autopilot/locks/speed", func { vel.update(cmdarg().getValue()) }, 1),
setlistener("/autopilot/locks/altitude", func { alt.update(cmdarg().getValue()) }, 1),
];
</open>
<close>
foreach (var l; lst) {
removelistener(l);
}
</close>
</nasal>
<group>
<layout>hbox</layout>
<default-padding>8</default-padding>
<group> <!-- Pitch/Altitude -->
<group> <!-- Heading -->
<layout>vbox</layout>
<group>
<layout>hbox</layout>
<checkbox>
<label>Heading Control</label>
<halign>fill</halign>
<property>/autopilot/gui/hdg-active</property>
<binding>
<command>dialog-apply</command>
</binding>
<binding>
<command>nasal</command>
<script>autopilot.update()</script>
</binding>
</checkbox>
<layout>hbox</layout>
<checkbox>
<label>Heading Control</label>
<halign>fill</halign>
<property>/sim/gui/dialogs/autopilot/heading-active</property>
<live>true</live>
<binding>
<command>dialog-apply</command>
</binding>
<binding>
<command>nasal</command>
<script>hdg.enable()</script>
</binding>
</checkbox>
</group>
<group>
<layout>table</layout>
<text>
<label>Wings Level</label>
<halign>right</halign>
<row>0</row><col>0</col>
</text>
<radio>
<row>0</row><col>1</col>
<property>/autopilot/gui/hdg-wing</property>
<binding>
<command>nasal</command>
<script>autopilot.update("hdg-wing")</script>
</binding>
</radio>
<layout>table</layout>
<text>
<label>Wings Level</label>
<halign>right</halign>
<row>0</row><col>0</col>
</text>
<radio>
<row>0</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/wing-leveler</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>hdg.set("wing-leveler")</script>
</binding>
</radio>
<text>
<label>Heading Bug</label>
<halign>right</halign>
<row>1</row><col>0</col>
</text>
<radio>
<row>1</row><col>1</col>
<property>/autopilot/gui/hdg-bug</property>
<binding>
<command>nasal</command>
<script>autopilot.update("hdg-bug")</script>
</binding>
</radio>
<input>
<row>1</row><col>2</col>
<name>hdg-bug</name>
<property>/autopilot/settings/heading-bug-deg</property>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>Heading Bug</label>
<halign>right</halign>
<row>1</row><col>0</col>
</text>
<radio>
<row>1</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/dg-heading-hold</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>hdg.set("dg-heading-hold")</script>
</binding>
</radio>
<input>
<row>1</row><col>2</col>
<property>/autopilot/settings/heading-bug-deg</property>
<live>true</live>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>True Heading</label>
<halign>right</halign>
<row>2</row><col>0</col>
</text>
<radio>
<row>2</row><col>1</col>
<property>/autopilot/gui/hdg-true</property>
<binding>
<command>nasal</command>
<script>autopilot.update("hdg-true")</script>
</binding>
</radio>
<input>
<row>2</row><col>2</col>
<name>hdg-true</name>
<property>/autopilot/settings/true-heading-deg</property>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>True Heading</label>
<halign>right</halign>
<row>2</row><col>0</col>
</text>
<radio>
<row>2</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/true-heading-hold</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>hdg.set("true-heading-hold")</script>
</binding>
</radio>
<input>
<row>2</row><col>2</col>
<property>/autopilot/settings/true-heading-deg</property>
<live>true</live>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>NAV1 CDI Course</label>
<halign>right</halign>
<row>3</row><col>0</col>
</text>
<radio>
<row>3</row><col>1</col>
<property>/autopilot/gui/hdg-nav</property>
<binding>
<command>nasal</command>
<script>autopilot.update("hdg-nav")</script>
</binding>
</radio>
<text>
<label>NAV1 CDI Course</label>
<halign>right</halign>
<row>3</row><col>0</col>
</text>
<radio>
<row>3</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/nav1-hold</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>hdg.set("nav1-hold")</script>
</binding>
</radio>
</group>
<hrule><dummy/></hrule>
<group>
<layout>hbox</layout>
<checkbox>
<label>Velocity Control</label>
<halign>fill</halign>
<property>/autopilot/gui/vel-active</property>
<binding>
<command>dialog-apply</command>
</binding>
<binding>
<command>nasal</command>
<script>autopilot.update()</script>
</binding>
</checkbox>
<layout>hbox</layout>
<checkbox>
<label>Velocity Control</label>
<halign>fill</halign>
<property>/sim/gui/dialogs/autopilot/speed-active</property>
<live>true</live>
<binding>
<command>dialog-apply</command>
</binding>
<binding>
<command>nasal</command>
<script>vel.enable()</script>
</binding>
</checkbox>
</group>
<group>
<layout>table</layout>
<text>
<label>Speed with Throttle</label>
<halign>right</halign>
<row>0</row><col>0</col>
</text>
<radio>
<row>0</row><col>1</col>
<property>/autopilot/gui/vel-throttle</property>
<binding>
<command>nasal</command>
<script>autopilot.update("vel-throttle")</script>
</binding>
</radio>
<input>
<row>0</row><col>2</col>
<rowspan>2</rowspan>
<name>vel-throttle</name>
<property>/autopilot/settings/target-speed-kt</property>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<layout>table</layout>
<text>
<label>Speed with Throttle</label>
<halign>right</halign>
<row>0</row><col>0</col>
</text>
<radio>
<row>0</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/speed-with-throttle</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>vel.set("speed-with-throttle")</script>
</binding>
</radio>
<input>
<row>0</row><col>2</col>
<rowspan>2</rowspan>
<property>/autopilot/settings/target-speed-kt</property>
<live>true</live>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>Speed with Pitch</label>
<halign>right</halign>
<row>1</row><col>0</col>
</text>
<radio>
<row>1</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/speed-with-pitch-trim</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>vel.set("speed-with-pitch-trim")</script>
</binding>
</radio>
<text>
<label>Speed with Pitch</label>
<halign>right</halign>
<row>1</row><col>0</col>
</text>
<radio>
<row>1</row><col>1</col>
<property>/autopilot/gui/vel-pitch</property>
<binding>
<command>nasal</command>
<script>autopilot.update("vel-pitch")</script>
</binding>
</radio>
</group>
</group> <!-- End of Heading/Speed -->
@ -185,146 +279,153 @@
<group> <!-- Pitch/Altitude -->
<layout>vbox</layout>
<group>
<layout>hbox</layout>
<checkbox>
<label>Pitch/Altitude Control</label>
<halign>fill</halign>
<property>/autopilot/gui/alt-active</property>
<binding>
<command>dialog-apply</command>
</binding>
<binding>
<command>nasal</command>
<script>autopilot.update()</script>
</binding>
</checkbox>
<layout>hbox</layout>
<checkbox>
<label>Pitch/Altitude Control</label>
<halign>fill</halign>
<property>/sim/gui/dialogs/autopilot/altitude-active</property>
<live>true</live>
<binding>
<command>dialog-apply</command>
</binding>
<binding>
<command>nasal</command>
<script>alt.enable()</script>
</binding>
</checkbox>
</group>
<group>
<layout>table</layout>
<text>
<label>Vertical Speed</label>
<halign>right</halign>
<row>0</row><col>0</col>
</text>
<radio>
<row>0</row><col>1</col>
<property>/autopilot/gui/alt-vert</property>
<binding>
<command>nasal</command>
<script>autopilot.update("alt-vert")</script>
</binding>
</radio>
<input>
<row>0</row><col>2</col>
<name>alt-vert</name>
<property>/autopilot/settings/vertical-speed-fpm</property>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<layout>table</layout>
<text>
<label>Vertical Speed</label>
<halign>right</halign>
<row>0</row><col>0</col>
</text>
<radio>
<row>0</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/vertical-speed-hold</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>alt.set("vertical-speed-hold")</script>
</binding>
</radio>
<input>
<row>0</row><col>2</col>
<property>/autopilot/settings/vertical-speed-fpm</property>
<live>true</live>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>Pitch Hold</label>
<halign>right</halign>
<row>1</row><col>0</col>
</text>
<radio>
<row>1</row><col>1</col>
<property>/autopilot/gui/alt-pitch</property>
<binding>
<command>nasal</command>
<script>autopilot.update("alt-pitch")</script>
</binding>
</radio>
<input>
<row>1</row><col>2</col>
<name>alt-pitch</name>
<property>/autopilot/settings/target-pitch-deg</property>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>Pitch Hold</label>
<halign>right</halign>
<row>1</row><col>0</col>
</text>
<radio>
<row>1</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/pitch-hold</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>alt.set("pitch-hold")</script>
</binding>
</radio>
<input>
<row>1</row><col>2</col>
<property>/autopilot/settings/target-pitch-deg</property>
<live>true</live>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>AoA Hold</label>
<halign>right</halign>
<row>2</row><col>0</col>
</text>
<radio>
<row>2</row><col>1</col>
<property>/autopilot/gui/alt-aoa</property>
<binding>
<command>nasal</command>
<script>autopilot.update("alt-aoa")</script>
</binding>
</radio>
<input>
<row>2</row><col>2</col>
<name>alt-aoa</name>
<property>/autopilot/settings/target-aoa-deg</property>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>AoA Hold</label>
<halign>right</halign>
<row>2</row><col>0</col>
</text>
<radio>
<row>2</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/aoa-hold</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>alt.set("aoa-hold")</script>
</binding>
</radio>
<input>
<row>2</row><col>2</col>
<property>/autopilot/settings/target-aoa-deg</property>
<live>true</live>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>Altitude Hold</label>
<halign>right</halign>
<row>3</row><col>0</col>
</text>
<radio>
<row>3</row><col>1</col>
<property>/autopilot/gui/alt-alt</property>
<binding>
<command>nasal</command>
<script>autopilot.update("alt-alt")</script>
</binding>
</radio>
<input>
<row>3</row><col>2</col>
<name>alt-alt</name>
<property>/autopilot/settings/target-altitude-ft</property>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>Altitude Hold</label>
<halign>right</halign>
<row>3</row><col>0</col>
</text>
<radio>
<row>3</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/altitude-hold</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>alt.set("altitude-hold")</script>
</binding>
</radio>
<input>
<row>3</row><col>2</col>
<property>/autopilot/settings/target-altitude-ft</property>
<live>true</live>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>AGL Hold</label>
<halign>right</halign>
<row>4</row><col>0</col>
</text>
<radio>
<row>4</row><col>1</col>
<property>/autopilot/gui/alt-agl</property>
<binding>
<command>nasal</command>
<script>autopilot.update("alt-agl")</script>
</binding>
</radio>
<input>
<row>4</row><col>2</col>
<name>alt-agl</name>
<property>/autopilot/settings/target-agl-ft</property>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>AGL Hold</label>
<halign>right</halign>
<row>4</row><col>0</col>
</text>
<radio>
<row>4</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/agl-hold</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>alt.set("agl-hold")</script>
</binding>
</radio>
<input>
<row>4</row><col>2</col>
<property>/autopilot/settings/target-agl-ft</property>
<live>true</live>
<binding>
<command>dialog-apply</command>
</binding>
</input>
<text>
<label>NAV1 Glideslope</label>
<halign>right</halign>
<row>5</row><col>0</col>
</text>
<radio>
<row>5</row><col>1</col>
<property>/autopilot/gui/alt-gs</property>
<binding>
<command>nasal</command>
<script>autopilot.update("alt-gs")</script>
</binding>
</radio>
<text>
<label>NAV1 Glideslope</label>
<halign>right</halign>
<row>5</row><col>0</col>
</text>
<radio>
<row>5</row><col>1</col>
<property>/sim/gui/dialogs/autopilot/gs1-hold</property>
<live>true</live>
<binding>
<command>nasal</command>
<script>alt.set("gs1-hold")</script>
</binding>
</radio>
</group>
<empty><stretch>true</stretch></empty>