<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.
449 lines
13 KiB
XML
449 lines
13 KiB
XML
<?xml version="1.0"?>
|
|
<PropertyList>
|
|
<name>autopilot</name>
|
|
<layout>vbox</layout>
|
|
|
|
<!--
|
|
/autopilot/locks/altitude
|
|
/autopilot/locks/heading
|
|
/autopilot/locks/speed
|
|
/autopilot/settings/heading-bug-deg
|
|
/autopilot/settings/target-agl-ft
|
|
/autopilot/settings/target-altitude-ft
|
|
/autopilot/settings/target-aoa-deg
|
|
/autopilot/settings/target-pitch-deg
|
|
/autopilot/settings/target-speed-kt
|
|
/autopilot/settings/true-heading-deg
|
|
/autopilot/settings/vertical-speed-fpm
|
|
-->
|
|
|
|
<text><label>Autopilot Settings</label></text>
|
|
|
|
<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> <!-- Heading -->
|
|
<layout>vbox</layout>
|
|
<group>
|
|
<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>/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>/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>/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>/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>/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>/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>
|
|
|
|
</group>
|
|
</group> <!-- End of Heading/Speed -->
|
|
|
|
|
|
<vrule><dummy/></vrule>
|
|
|
|
|
|
<group> <!-- Pitch/Altitude -->
|
|
<layout>vbox</layout>
|
|
<group>
|
|
<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>/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>/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>/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>/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>/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>/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>
|
|
|
|
</group> <!-- End of Pitch/Altitude VBox -->
|
|
</group>
|
|
|
|
<button>
|
|
<legend>Close</legend>
|
|
<default>true</default>
|
|
<key>Esc</key>
|
|
<padding>10</padding>
|
|
<binding>
|
|
<command>dialog-apply</command>
|
|
</binding>
|
|
<binding>
|
|
<command>dialog-close</command>
|
|
</binding>
|
|
</button>
|
|
|
|
</PropertyList>
|