1
0
Fork 0

Initial commit of FG1000 MFD

This commit is contained in:
Stuart Buchanan 2017-11-24 23:04:46 +00:00
parent 0117da44ff
commit 3d31775ff3
22 changed files with 6899 additions and 275 deletions

View file

@ -0,0 +1,841 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg4136"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="EIS_c172s_v2.svg">
<defs
id="defs4138">
<linearGradient
id="linearGradient4779"
osb:paint="gradient">
<stop
style="stop-color:#352837;stop-opacity:1;"
offset="0"
id="stop4781" />
<stop
style="stop-color:#352837;stop-opacity:0;"
offset="1"
id="stop4783" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.3515539"
inkscape:cx="4.4492679"
inkscape:cy="930.9091"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2495"
inkscape:window-height="1416"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1"
showguides="false"
inkscape:snap-object-midpoints="false"
inkscape:snap-center="true" />
<metadata
id="metadata4141">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.51325756;stroke-opacity:1"
id="SBattAmps"
width="149.48674"
height="688.48676"
x="-0.28891727"
y="56.43882"
inkscape:label="#rect4684" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.01574385;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 74.242188,57.513672 C 57.591382,57.455549 40.919193,63.107347 27.365234,74.480469 0.25731786,97.226713 -6.4772629,136.22443 11.429688,166.74609 l 0.875,-0.51367 C -5.3549643,136.13227 1.2859805,97.689926 28.019531,75.257812 54.753082,52.825699 93.76355,52.961876 120.33984,75.580078 c 26.5763,22.618202 32.94749,61.105902 15.07813,91.082032 l 0.87109,0.51953 C 154.40866,136.78573 147.9465,97.741579 120.99805,74.806641 107.52382,63.339172 90.892993,57.571795 74.242188,57.513672 Z"
id="OuterRPM"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 74.070312,60.328125 C 58.093724,60.272356 42.097371,65.691238 29.099609,76.597656 3.1040851,98.410493 -3.3615793,135.84409 13.810547,165.11328 l 4.3125,-2.5293 C 2.168248,135.38968 8.1597914,100.69426 32.3125,80.427734 56.465208,60.161205 91.672961,60.284097 115.68359,80.71875 c 24.01064,20.43465 29.76145,55.1697 13.61719,82.25195 l 4.29492,2.56055 C 150.97175,136.38266 144.76644,98.905897 118.92383,76.912109 106.00252,65.915216 90.046901,60.383894 74.070312,60.328125 Z"
id="WhiteRPM"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#009900;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 103.45312,66.941406 -2.1289,4.523438 c 19.86326,9.346943 33.61421,28.13482 36.51758,49.894536 l 4.95703,-0.66016 C 139.67156,97.261392 124.84825,77.009188 103.45312,66.941406 Z"
id="GreenRPM"
inkscape:connector-curvature="0" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 138.41016,129.90234 c 0,11.6428 -3.14777,23.06767 -9.10938,33.06836 l 4.29492,2.56055 c 6.423,-10.77468 9.81446,-23.08503 9.81446,-35.62891 l -5,0 z"
id="RedRPM"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 11.702553,167.05926 9.343911,-5.49271"
id="path4713"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 136.0776,167.56433 -9.97526,-5.93465"
id="path4715"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:FreeMono;-inkscape-font-specification:FreeMono;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
x="0.72086191"
y="180.59354"
id="text4717"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4719"
x="0.72086191"
y="180.59354">0</tspan></text>
<text
sodipodi:linespacing="125%"
id="text4725"
y="180.95068"
x="110.5423"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:FreeMono;-inkscape-font-specification:FreeMono;text-align:start;letter-spacing:-3px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;"
xml:space="preserve"><tspan
y="180.95068"
x="110.5423"
id="tspan4727"
sodipodi:role="line">3000</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:35px;line-height:125%;font-family:FreeMono;-inkscape-font-specification:FreeMono;text-align:start;letter-spacing:-3px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="40.9702"
y="184.0697"
id="RPMDisplay"
sodipodi:linespacing="125%"
inkscape:label="#text4729"><tspan
sodipodi:role="line"
id="tspan4731"
x="40.9702"
y="184.0697"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;font-family:FreeSans;-inkscape-font-specification:FreeSans">2200</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="52.228359"
y="154.23056"
id="text4733"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4735"
x="52.228359"
y="154.23056">RPM</tspan></text>
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 72.822029,125.96939 -59.459758,31.77936 6.366604,-9.03366 4.578139,3.17116 -0.526987,6.34826 -10.196797,-0.65694"
id="RPMPointer"
inkscape:connector-curvature="0"
inkscape:label="#path4775"
inkscape:transform-center-x="30.347137"
inkscape:transform-center-y="17.260628" />
<g
id="g4866"
transform="translate(-0.54554609,-307.18002)">
<rect
y="544.53625"
x="8.4391518"
height="6.9623003"
width="75.530403"
id="rect4862"
style="opacity:1;fill:#00af00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<g
transform="translate(0,21.780942)"
inkscape:label="#g4833"
id="FFLOW">
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 8.0559648,519.47505 0,12.23313 134.8260452,0.0746 -0.0746,-12.03652"
id="path4789"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 20.684108,531.22649 0,-11.60383"
id="path4799"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4813"
d="m 34.931231,531.30108 0,-11.60383"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 34.931231,531.30108 0,-11.60383"
id="path4815"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4819"
d="m 48.656208,531.30108 0,-11.60383"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 62.082816,531.30108 0,-11.60383"
id="path4821"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4823"
d="m 75.509424,531.30108 0,-11.60383"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 89.681955,531.52486 0,-11.60383"
id="path4825"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4827"
d="m 102.95938,531.22649 0,-11.60383"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 116.53517,531.30108 0,-11.60383"
id="path4829"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4831"
d="m 129.66341,531.30108 0,-11.60383"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<text
sodipodi:linespacing="125%"
id="text4846"
y="528.42615"
x="30.433645"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
id="tspan4850"
y="528.42615"
x="30.433645"
sodipodi:role="line">FFLOW GPH</tspan></text>
<text
id="text4854"
y="569.60107"
x="3.5804288"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
xml:space="preserve"><tspan
y="569.60107"
x="3.5804288"
id="tspan4856"
sodipodi:role="line">0</tspan></text>
<text
id="text4858"
y="569.60101"
x="130.08891"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
xml:space="preserve"><tspan
y="569.60101"
x="130.08891"
id="tspan4860"
sodipodi:role="line">20</tspan></text>
<path
inkscape:label="#path4864"
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="FuelFlowPointer"
d="m 4.5714659,539.5634 0.043695,9.19243 3.48115,3.34929 3.5075231,-3.37566 0,-9.18946 z"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g4888"
transform="translate(-0.54554609,-238.25676)">
<rect
style="opacity:1;fill:#00af00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4890"
width="38.714603"
height="6.9623003"
x="72.682198"
y="544.53625" />
<rect
y="544.53625"
x="138.82405"
height="6.9623003"
width="4.0085921"
id="rect4930"
style="opacity:1;fill:#ca0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<g
id="g4892"
inkscape:label="#g4833"
transform="translate(0,21.780942)">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path4894"
d="m 8.0559648,519.47505 0,12.23313 134.8260452,0.0746 -0.0746,-12.03652"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="41.193565"
y="528.42615"
id="text4916"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
x="41.193565"
y="528.42615"
id="tspan4918">OIL PRES</tspan></text>
<rect
y="544.53625"
x="8.0171986"
height="6.9622803"
width="20.886898"
id="rect4932"
style="opacity:1;fill:#aa0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 4.5714659,539.5634 0.043695,9.19243 3.48115,3.34929 3.5075231,-3.37566 0,-9.18946 z"
id="OilPressurePointer"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc"
inkscape:label="#path4864" />
</g>
<g
transform="translate(-0.54554609,-188.88773)"
id="g4934">
<rect
y="544.53625"
x="33.440144"
height="6.9623003"
width="105.27841"
id="rect4936"
style="opacity:1;fill:#00af00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
style="opacity:1;fill:#ca0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4938"
width="4.0085921"
height="6.9623003"
x="138.82405"
y="544.53625" />
<g
transform="translate(0,21.780942)"
inkscape:label="#g4833"
id="g4940">
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 8.0559648,519.47505 0,12.23313 134.8260452,0.0746 -0.0746,-12.03652"
id="path4942"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</g>
<text
sodipodi:linespacing="125%"
id="text4944"
y="528.42615"
x="41.193565"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
id="tspan4946"
y="528.42615"
x="41.193565"
sodipodi:role="line">OIL TEMP</tspan></text>
<path
inkscape:label="#path4864"
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="OilTempPointer"
d="m 4.5714659,539.5634 0.043695,9.19243 3.48115,3.34929 3.5075231,-3.37566 0,-9.18946 z"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g4952"
transform="translate(-0.54554609,-142.18193)">
<g
id="g4956"
inkscape:label="#g4833"
transform="translate(0,21.780942)">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path4958"
d="m 8.0559648,519.47505 0,12.23313 134.8260452,0.0746 -0.0746,-12.03652"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path4960"
d="m 20.684108,531.22649 0,-11.60383"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 34.931231,531.30108 0,-11.60383"
id="path4962"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4964"
d="m 34.931231,531.30108 0,-11.60383"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 48.656208,531.30108 0,-11.60383"
id="path4966"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4968"
d="m 62.082816,531.30108 0,-11.60383"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 75.509424,531.30108 0,-11.60383"
id="path4970"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4972"
d="m 89.681955,531.52486 0,-11.60383"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 102.95938,531.22649 0,-11.60383"
id="path4974"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4976"
d="m 116.53517,531.30108 0,-11.60383"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 129.66341,531.30108 0,-11.60383"
id="path4978"
inkscape:connector-curvature="0" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="62.060768"
y="528.42615"
id="text4980"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
x="62.060768"
y="528.42615"
id="tspan4982">EGT</tspan></text>
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 4.5714659,539.5634 0.043695,9.19243 3.48115,3.34929 3.5075231,-3.37566 0,-9.18946 z"
id="EGTPointer"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc"
inkscape:label="#path4864" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="3.9031074"
y="550.22003"
id="EGTCylinder"
inkscape:label="#text4994"><tspan
sodipodi:role="line"
id="tspan4996"
x="3.9031074"
y="550.22003">1</tspan></text>
</g>
<g
id="g4998"
transform="translate(-0.54554609,-81.176495)">
<rect
style="opacity:1;fill:#00af00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect5000"
width="37.847004"
height="6.9623003"
x="54.624344"
y="544.53625" />
<g
id="g5004"
inkscape:label="#g4833"
transform="translate(0,21.780942)">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path5006"
d="m 8.0559648,519.47505 0,12.23313 134.8260452,0.0746 -0.0746,-12.03652"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="60.289185"
y="528.42615"
id="text5008"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
x="60.289185"
y="528.42615"
id="tspan5010">VAC</tspan></text>
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 4.5714659,539.5634 0.043695,9.19243 3.48115,3.34929 3.5075231,-3.37566 0,-9.18946 z"
id="VacPointer"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc"
inkscape:label="#path4864" />
</g>
<g
id="g5014"
transform="translate(0,271.9634)">
<g
id="g5018"
inkscape:label="#g4833"
transform="translate(-0.54554609,-285.39908)">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path5020"
d="m 8.0559648,519.47505 0,12.23313 134.8260452,0.0746 -0.0746,-12.03652"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.39230883px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 53.078837,542.01976 0,-22.4943"
id="path5028"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path5034"
d="m 97.957359,541.88715 0,-21.89756"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.37371683px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path5056"
d="m 8.2003174,542.28497 0,-22.4943"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.39230883px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.37371683px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 142.83588,542.15236 0,-21.89756"
id="path5058"
inkscape:connector-curvature="0" />
</g>
<rect
style="opacity:1;fill:#00af00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect5016"
width="100.89178"
height="6.9623003"
x="24.303904"
y="242.57767" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="22.578058"
y="221.09695"
id="text5042"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
x="22.578058"
y="221.09695"
id="tspan5044">FUEL QTY GAL</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="3.034883"
y="272.61682"
id="text5046"><tspan
sodipodi:role="line"
id="tspan5048"
x="3.034883"
y="272.61682"
style="font-size:15px">0</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="136.70422"
y="272.93927"
id="text5050"><tspan
sodipodi:role="line"
id="tspan5052"
x="136.70422"
y="272.93927"
style="font-size:15px">F</tspan></text>
<rect
y="242.57767"
x="7.5952349"
height="6.9623003"
width="5.0407143"
id="rect5062"
style="opacity:1;fill:#aa0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
y="242.57767"
x="12.592917"
height="6.9623003"
width="11.754019"
id="rect5064"
style="opacity:1;fill:#acaf00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="43.221519"
y="272.61682"
id="text5066"><tspan
sodipodi:role="line"
id="tspan5068"
x="43.221519"
y="272.61682"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:FreeSans;-inkscape-font-specification:FreeSans">10</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="88.535469"
y="272.61682"
id="text5070"><tspan
sodipodi:role="line"
id="tspan5072"
x="88.535469"
y="272.61682">20</tspan></text>
<g
id="RightFuelPointer"
inkscape:label="#g4282">
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 4.0259199,259.63213 -2.9100082,0 6.4348532,-12.49326 7.3051411,12.49326 -3.797618,0 z"
id="RightFuelTriangle"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc"
inkscape:label="#path4864" />
<text
inkscape:label="#text5076"
id="RightFuelLabel"
y="259.8103"
x="3.8553977"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
xml:space="preserve"><tspan
y="259.8103"
x="3.8553977"
id="tspan5078"
sodipodi:role="line">R</tspan></text>
</g>
<g
id="LeftFuelPointer"
inkscape:label="#g4277">
<path
inkscape:label="#path4864"
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="LeftFuelTriangle"
d="m 4.0259199,232.43184 -2.9100082,0 6.4348532,12.49326 7.3051411,-12.49326 -3.797618,0 z"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="3.8553977"
y="239.81961"
id="LeftFuelLabel"
inkscape:label="#text5076"><tspan
sodipodi:role="line"
id="tspan5082"
x="3.8553977"
y="239.81961">L</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="1.7752202"
y="306.83356"
id="text5092"><tspan
sodipodi:role="line"
id="tspan5094"
x="1.7752202"
y="306.83356">ENG HRS</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="73.508011"
y="307.17853"
id="EngineHours"
inkscape:label="#text5096"><tspan
sodipodi:role="line"
id="tspan5098"
x="73.508011"
y="307.17853">XXXX.X</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="26.265755"
y="341.14606"
id="text5100"><tspan
sodipodi:role="line"
id="tspan5102"
x="26.265755"
y="341.14606">ELECTRICAL</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 120.34531,335.65557 16.45634,0.21098"
id="path5108"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path5110"
d="M 7.8936094,335.65557 24.34995,335.86655"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:0%;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="13.590033"
y="359.64337"
id="text5112"
sodipodi:linespacing="0%"><tspan
sodipodi:role="line"
id="tspan5114"
x="13.590033"
y="359.64337">M</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="56.530724"
y="359.56085"
id="text5116"><tspan
sodipodi:role="line"
id="tspan5118"
x="56.530724"
y="359.56085">BUS</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="119.29041"
y="359.64337"
id="text5120"><tspan
sodipodi:role="line"
id="tspan5122"
x="119.29041"
y="359.64337">E</tspan></text>
<flowRoot
xml:space="preserve"
id="flowRoot5124"
style="fill-opacity:1;font-size:15px;opacity:1;fill-rule:nonzero;fill:#ffffff;stroke:#ffffff;stroke-opacity:1;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;-inkscape-font-specification:FreeSans;font-family:FreeSans;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal"><flowRegion
id="flowRegion5126"><rect
id="rect5128"
width="250.43182"
height="44.305546"
x="-18.988091"
y="931.89331" /></flowRegion><flowPara
id="flowPara5130" /></flowRoot> <text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="9.3704567"
y="382.3924"
id="MBusVolts"
inkscape:label="#text5132"><tspan
sodipodi:role="line"
id="tspan5134"
x="9.3704567"
y="382.3924">32.0</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="50.673546"
y="382.84338"
id="text5136"><tspan
sodipodi:role="line"
id="tspan5138"
x="50.673546"
y="382.84338">VOLTS</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="112.32812"
y="381.33752"
id="EBusVolts"
inkscape:label="#text5140"><tspan
sodipodi:role="line"
id="tspan5142"
x="112.32812"
y="381.33752">32.0</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="15.066884"
y="425.23657"
id="text5144"><tspan
sodipodi:role="line"
id="tspan5146"
x="15.066884"
y="425.23657">M</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="55.660442"
y="425.23657"
id="text5148"><tspan
sodipodi:role="line"
id="tspan5150"
x="55.660442"
y="425.23657">BATT</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="124.56488"
y="425.15405"
id="text5152"><tspan
sodipodi:role="line"
id="tspan5154"
x="124.56488"
y="425.15405">S</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="5.1508813"
y="450.11658"
id="MBattAmps"
inkscape:label="#text5156"><tspan
sodipodi:role="line"
id="tspan5158"
x="5.1508813"
y="450.11658">+110</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="53.034382"
y="450.35657"
id="text5160"><tspan
sodipodi:role="line"
id="tspan5162"
x="53.034382"
y="450.35657">AMPS</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;font-family:FreeSans;-inkscape-font-specification:FreeSans;text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="109.16343"
y="450.11658"
id="text5164"><tspan
sodipodi:role="line"
id="tspan5166"
x="109.16343"
y="450.11658">+110</tspan></text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 46 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 90 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 89 KiB

View file

@ -0,0 +1,68 @@
# FG1000 Engine Information Display Default Driver
#
# Driver values in the EIS.
var PropMap =
{
new : func(name, property)
{
var obj = { parents : [ PropMap ] };
obj._name = name;
obj._val = 0;
obj._prop = globals.props.getNode(property, 1);
obj._val = obj._prop.getValue();
return obj;
},
update : func()
{
me._val = me._prop.getValue();
},
getValue : func()
{
return me._val;
}
};
var EISDriver =
{
new : func()
{
var obj = { parents : [ EISDriver ] };
# Hack to handle most aircraft not having proper engine hours
setprop("/engines/engine[0]/hours", 157.0);
obj._propmap = {
"RPM" : PropMap.new("RPM", "/engines/engine[0]/rpm"),
"MBusVolts" : PropMap.new("MBusVolts", "/systems/electrical/volts"),
"EngineHours" : PropMap.new("EngineHours", "/engines/engine[0]/hours"),
"FuelFlowGPH" : PropMap.new("FuelFlowGPH", "/engines/engine[0]/fuel-flow-gph"),
"OilPressurePSI" : PropMap.new("OilPressurePSI", "/engines/engine[0]/oil-pressure-psi"),
"OilTemperatureF" : PropMap.new("OilTemperatureF", "/engines/engine[0]/oil-temperature-degf"),
"EGTNorm" : PropMap.new("EGTNorm", "/engines/engine[0]/egt-norm"),
"VacuumSuctionInHG" : PropMap.new("VacuumSuctionInHG", "/systems/vacuum/suction-inhg"),
"LeftFuelUSGal" : PropMap.new("LeftFuelUSGal", "/consumables/fuel/tank[0]/indicated-level-gal_us"),
"RightFuelUSGal" : PropMap.new("RightFuelUSGal", "/consumables/fuel/tank[1]/indicated-level-gal_us"),
};
return obj;
},
getValue : func(name)
{
if (me._propmap[name] == nil) print("Unknown Driver Key in EISDriver.nas " ~ name);
return me._propmap[name].getValue();
},
update: func () {
foreach (var tp; keys(me._propmap)) {
me._propmap[tp].update();
}
}
};

View file

@ -0,0 +1,146 @@
# FG1000 Engine Information Display
# A mapping from names of elements to specific elements of the SVG.
# These names mapped to values by the provided EISDriver.
var DynamicTextElementMap =
{
new : func(svg, name, element_id, format)
{
var obj = { parents : [ DynamicTextElementMap ] };
obj._name = name;
obj._element_id = element_id;
obj._element = svg.getElementById(element_id);
obj._format = format;
return obj;
},
update : func(driver)
{
me._element.setText(sprintf(me._format, driver.getValue(me._name)));
},
};
var DynamicSliderElementMap =
{
new : func(svg, name, element_id, min=0.0, max=1.0)
{
var obj = { parents : [ DynamicSliderElementMap ] };
obj._name = name;
obj._element_id = element_id;
obj._element = svg.getElementById(element_id);
obj._baseTranslation = obj._element.getTranslation();
obj._min = min;
obj._max = max;
return obj;
},
update : func(driver)
{
var value = driver.getValue(me._name);
if (value == nil) value = 0.0;
# Bound value to the minimum and maximum values.
value = math.max(me._min, value);
value = math.min(me._max, value);
# Convert to normalized value
value = (value - me._min) / (me._max - me._min);
# Simply shift the slider along. All sliders have a 0 value
# at x=3.5, and a maximum value at x=138.0.
me._element.setTranslation([
me._baseTranslation[0] + (value * (138.0 - 3.5)),
me._baseTranslation[1]
]);
},
};
var DynamicRotatingElementMap =
{
new : func(svg, name, element_id, min=0.0, max=1.0, range=360.0)
{
var obj = { parents : [ DynamicRotatingElementMap ] };
obj._name = name;
obj._element_id = element_id;
obj._element = svg.getElementById(element_id);
obj._baseTranslation = obj._element.getTranslation();
obj._min = min;
obj._max = max;
obj._range = range;
return obj;
},
update : func(driver)
{
var value = driver.getValue(me._name);
if (value == nil) value = 0.0;
# Bound value to the minimum and maximum values.
value = math.max(me._min, value);
value = math.min(me._max, value);
# Convert to normalized value
value = (value - me._min) / (me._max - me._min);
me._element.setRotation(value * me._range * D2R, [100.0, 100.0]);
},
};
var EIS =
{
new : func (myCanvas, EISDriver)
{
var obj = { parents : [ EIS ] };
obj._canvas = myCanvas;
obj._EISDriver = EISDriver;
obj._svg= obj._canvas.createGroup("EIS");
canvas.parsesvg(obj._svg, '/Aircraft/Instruments-3d/FG1000/Models/EIS_c172s.svg');
# Objects to display as straight text
obj._textElements = [
DynamicTextElementMap.new(obj._svg, "RPM", "RPMDisplay", "%i"),
DynamicTextElementMap.new(obj._svg, "MBusVolts" , "MBusVolts", "%.01f"),
DynamicTextElementMap.new(obj._svg, "MBusVolts" , "EBusVolts", "%.01f"),
DynamicTextElementMap.new(obj._svg, "EngineHours" , "EngineHours", "%.01f"),
];
obj._sliderElements = [
DynamicSliderElementMap.new(obj._svg, "FuelFlowGPH", "FuelFlowPointer", 0.0, 20.0),
DynamicSliderElementMap.new(obj._svg, "OilPressurePSI", "OilPressurePointer", 0.0, 115.0),
DynamicSliderElementMap.new(obj._svg, "OilTemperatureF", "OilTempPointer", 0.0, 245.0),
DynamicSliderElementMap.new(obj._svg, "EGTNorm", "EGTPointer", 0.0, 1.0),
DynamicSliderElementMap.new(obj._svg, "EGTNorm", "EGTCylinder", 0.0, 1.0),
DynamicSliderElementMap.new(obj._svg, "VacuumSuctionInHG", "VacPointer", 3.0, 7.0),
DynamicSliderElementMap.new(obj._svg, "LeftFuelUSGal", "LeftFuelPointer", 0.0, 30.0),
DynamicSliderElementMap.new(obj._svg, "RightFuelUSGal", "RightFuelPointer", 0.0, 30.0),
];
obj._rotationElements = [
DynamicRotatingElementMap.new(obj._svg, "RPM", "RPMPointer", 0.0, 3000.0, 260.0),
];
obj._svg.getElementById("RPMPointer").set("center-offset-x", 150.0);
obj._svg.getElementById("RPMPointer").set("center-offset-y", 100.0);
return obj;
},
update : func()
{
foreach(var te; me._textElements) {
te.update(me._EISDriver);
}
foreach(var se; me._sliderElements) {
se.update(me._EISDriver);
}
foreach(var se; me._rotationElements) {
se.update(me._EISDriver);
}
}
};

View file

@ -0,0 +1,85 @@
# FG1000 MFD
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
io.load_nasal(nasal_dir ~ 'NavMap/NavMap.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'NavMap/NavMapStyles.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'NavMap/NavMapOptions.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'NavMap/NavMapController.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'TrafficMap/TrafficMap.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'TrafficMap/TrafficMapStyles.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'TrafficMap/TrafficMapOptions.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'TrafficMap/TrafficMapController.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'EIS.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'Drivers/EISDriver.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'PageGroupController.nas', "fg1000");
var MFD =
{
# Center of any maps
MAP_CENTER : {
X: (1024/2 + 60),
Y: (768/2 + 20)
},
# Constants for the hard-buttons on the fascia
FASCIA : {
FMS_OUTER : 0,
FMS_INNER : 1,
RANGE : 2,
},
new : func (myCanvas)
{
var obj = { parents : [ MFD ] };
obj._svg = myCanvas.createGroup("softkeys");
canvas.parsesvg(obj._svg, '/Aircraft/Instruments-3d/FG1000/Models/MFD.svg');
obj._MFDDevice = canvas.PFD_Device.new(obj._svg, 12, "SoftKey", myCanvas, "MFD");
obj._MFDDevice.RegisterWithEmesary();
# Engine Information System
obj._eisDriver = fg1000.EISDriver.new();
obj._eis = fg1000.EIS.new(myCanvas, obj._eisDriver);
# Controller for the display on the bottom left which allows selection
# of page groups and individual pages using the FMS controller.
obj._pageGroupController = fg1000.PageGroupController.new(myCanvas, obj._svg, obj._MFDDevice);
obj._pageGroupController.RegisterWithEmesary();
obj._pageGroupController.addPage("NavigationMap", fg1000.NavMap.new(myCanvas, obj._MFDDevice, obj._svg));
obj._pageGroupController.addPage("TrafficMap", fg1000.TrafficMap.new(myCanvas, obj._MFDDevice, obj._svg));
# Display the NavMap and the appropriate top level on startup.
obj._MFDDevice.selectPage(obj._pageGroupController.getPage("NavigationMap"));
# Add a wheel controller., which we will attach to the zoom.
myCanvas.addEventListener("wheel", func(e)
{
if (e.deltaY >0) {
obj._MFDDevice.current_page.controller.zoomIn();
} else {
obj._MFDDevice.current_page.controller.zoomOut();
}
});
var updateTimer = func() {
obj._eisDriver.update();
obj._eis.update();
settimer(updateTimer, 0.1);
};
updateTimer();
return obj;
},
del: func()
{
me._pageGroupController.DeRegisterWithEmesary();
}
};

View file

@ -0,0 +1,211 @@
# Navigation Map
var NavMap =
{
new : func (myCanvas, device, svg)
{
var obj = {
_group : myCanvas.createGroup("NavigationMapLayer"),
parents : [ NavMap, device.addPage("NavigationMap", "NavigationMapGroup") ]
};
obj.Styles = fg1000.NavMapStyles.new();
obj.Options = fg1000.NavMapOptions.new();
obj.MFDMap = obj._group.createChild("map");
# Need to display this underneath the softkeys, EIS, header.
obj._group.set("z-index", -10.0);
obj._group.setVisible(0);
obj.device = device;
# Initialize the controller:
var ctrl_ns = canvas.Map.Controller.get("Aircraft position");
var source = ctrl_ns.SOURCES["current-pos"];
if (source == nil) {
# TODO: amend
var source = ctrl_ns.SOURCES["current-pos"] = {
getPosition: func subvec(geo.aircraft_position().latlon(), 0, 2),
getAltitude: func getprop('/position/altitude-ft'),
getHeading: func {
if (me.aircraft_heading)
getprop('/orientation/heading-deg')
else 0
},
aircraft_heading: 1,
};
}
setlistener("/sim/gui/dialogs/map-canvas/aircraft-heading-up", func(n) {
source.aircraft_heading = n.getBoolValue();
}, 1);
# Make it move with our aircraft:
obj.MFDMap.setController("Aircraft position", "current-pos"); # from aircraftpos.controller
# Center the map's origin, modified to take into account the surround.
obj.MFDMap.setTranslation(
fg1000.MFD.MAP_CENTER.X,
fg1000.MFD.MAP_CENTER.Y
);
var r = func(name,vis=1,zindex=nil) return caller(0)[0];
# TODO: we'll need some z-indexing here, right now it's just random
foreach(var type; [r('GRID'),r('TFC',0),r('APT'),r('DME'),r('VOR'),r('NDB'),r('FIX',0),r('RTE'),r('WPT'),r('FLT'),r('WXR',0),r('APS')] ) {
obj.MFDMap.addLayer(factory: canvas.SymbolLayer, type_arg: type.name,
visible: type.vis, priority: 4,
style: obj.Styles.getStyle(type.name),
options: obj.Options.getOption(type.name) );
}
foreach(var type; [ r('STAMEN_terrain'),r('STAMEN'), r('OpenAIP') ]) {
obj.MFDMap.addLayer(factory: canvas.OverlayLayer, type_arg: type.name,
visible: 0, priority: 1,
style: obj.Styles.getStyle(type.name),
options: obj.Options.getOption(type.name) );
}
obj.controller = fg1000.NavMapController.new(obj, svg, "RangeDisplay", 8);
var topMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "ENGINE", pg, engineMenu);
pg.addMenuItem(2, "MAP", pg, mapMenu);
pg.addMenuItem(8, "DCLTR", pg, func(dev, pg, mi) { obj.controller.incrDCLTR(dev, mi); } );
#pg.addMenuItem(9, "SHW CHRT", pg); # Optional
#pg.addMenuItem(10, "CHKLIST", pg); # Optional
device.updateMenus();
};
var engineMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "ENGINE", pg, engineMenu);
pg.addMenuItem(1, "LEAN", pg, leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, systemMenu);
pg.addMenuItem(8, "BACK", pg, topMenu);
device.updateMenus();
};
# Display map toggle softkeys which change color depending
# on whether a particular layer is enabled or not.
var display_toggle = func(device, svg, mi, layer) {
var bg_name = sprintf("SoftKey%d-bg",mi.menu_id);
if (obj.controller.isEnabled(layer)) {
device.svg.getElementById(bg_name).setColorFill(0.5,0.5,0.5);
svg.setColor(0.0,0.0,0.0);
} else {
device.svg.getElementById(bg_name).setColorFill(0.0,0.0,0.0);
svg.setColor(1.0,1.0,1.0);
}
svg.setText(mi.title);
svg.setVisible(1); # display function
};
# Function to undo any colors set by display_toggle when loading a new menu
var resetMenuColors = func(device) {
for(var i = 0; i < 12; i +=1) {
var name = sprintf("SoftKey%d",i);
device.svg.getElementById(name ~ "-bg").setColorFill(0.0,0.0,0.0);
device.svg.getElementById(name).setColor(1.0,1.0,1.0);
}
}
var mapMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "TRAFFIC", pg,
func(dev, pg, mi) { obj.controller.toggleLayer("TFC"); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "TFC"); }
);
pg.addMenuItem(1, "PROFILE", pg);
pg.addMenuItem(2, "TOPO", pg,
func(dev, pg, mi) { obj.controller.toggleLayer("STAMEN"); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "STAMEN"); }
);
pg.addMenuItem(3, "TERRAIN", pg,
func(dev, pg, mi) { obj.controller.toggleLayer("STAMEN_terrain"); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "STAMEN_terrain"); }
);
pg.addMenuItem(4, "AIRWAYS", pg, func(dev, pg, mi) { obj.controller.incrAIRWAYS(dev, mi); } );
#pg.addMenuItem(5, "STRMSCP", pg); Optional
#pg.addMenuItem(6, "PRECIP", pg); Optional, or NEXRAD
#pg.addMenuItem(7, "XM LTNG", pg); Optional, or DL LTNG
#pg.addMenuItem(8, "METAR", pg);
#pg.addMenuItem(9, "LEGEND", pg); Optional - only available with NEXRAD/XM LTNG/METAR/PROFILE selected
pg.addMenuItem(10, "BACK", pg, topMenu); # Or should this just be the next button?
device.updateMenus();
};
var leanMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "ENGINE", pg, engineMenu);
pg.addMenuItem(1, "LEAN", pg, leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, systemMenu);
pg.addMenuItem(3, "CYL SELECT", pg);
pg.addMenuItem(4, "ASSIST", pg);
pg.addMenuItem(9, "BACK", pg, engineMenu);
device.updateMenus();
};
var systemMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "ENGINE", pg, engineMenu);
pg.addMenuItem(1, "LEAN", pg, leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, systemMenu);
pg.addMenuItem(3, "RST FUEL", pg);
pg.addMenuItem(4, "GAL REM", pg, galRemMenu);
pg.addMenuItem(5, "BACK", pg, engineMenu);
device.updateMenus();
};
var galRemMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "ENGINE", pg, engineMenu);
pg.addMenuItem(1, "LEAN", pg, leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, systemMenu);
pg.addMenuItem(3, "-10 GAL", pg);
pg.addMenuItem(4, "-1 GAL", pg);
pg.addMenuItem(5, "+1 GAL", pg);
pg.addMenuItem(6, "+10 GAL", pg);
pg.addMenuItem(7, "44 GAL", pg);
pg.addMenuItem(8, "BACK", pg, engineMenu);
device.updateMenus();
};
topMenu(device, obj, nil);
return obj;
},
toggleLayerVisible : func(name) {
(var l = me.MFDMap.getLayer(name)).setVisible(l.getVisible());
},
setLayerVisible : func(name,n=1) {
me.MFDMap.getLayer(name).setVisible(n);
},
setRange : func(range) {
me.MFDMap.setRange(range);
},
setScreenRange : func(range) {
me.MFDMap.setScreenRange(range);
},
offdisplay : func() {
me._group.setVisible(0);
# Reset the menu colours. Shouldn't have to do this here, but
# there's not currently an obvious other location to do so.
for(var i = 0; i < 12; i +=1) {
var name = sprintf("SoftKey%d",i);
me.device.svg.getElementById(name ~ "-bg").setColorFill(0.0,0.0,0.0);
me.device.svg.getElementById(name).setColor(1.0,1.0,1.0);
}
},
ondisplay : func() {
me._group.setVisible(1);
},
};

View file

@ -0,0 +1,152 @@
# Navigation Map Controller
var NavMapController =
{
# Vertical ranges, and labels.
# 28 ranges from 500ft to 2000nm, measuring the vertical map distance.
# Vertical size of the map (once the nav box and softkey area is removed) is 689px.
# 2000nm = 12,152,000ft.
RANGES : [{range: 500/6076.12, label: "500ft"},
{range: 750/6076.12, label: "750ft"},
{range: 1000/6076.12, label: "1000ft"},
{range: 1500/6076.12, label: "1500ft"},
{range: 2000/6076.12, label: "2000ft"},
{range: 0.5, label: "0.5nm"},
{range: 0.75, label: "0.75nm"},
{range: 1, label: "1nm"},
{range: 2, label: "2nm"},
{range: 3, label: "3nm"},
{range: 4, label: "4nm"},
{range: 6, label: "6nm"},
{range: 8, label: "8nm"},
{range: 10, label: "10nm"},
{range: 12, label: "12nm"},
{range: 15, label: "15nm"},
{range: 20, label: "20nm"},
{range: 25, label: "25nm"},
{range: 30, label: "30nm"},
{range: 40, label: "40nm"},
{range: 50, label: "50nm"},
{range: 75, label: "75nm"},
{range: 100, label: "100nm"},
{range: 200, label: "200nm"},
{range: 500, label: "500nm"},
{range: 1000, label: "1000nm"},
{range: 1500, label: "1500nm"},
{range: 2000, label: "2000nm"}, ],
# Layer display configuration:
# enabled - whether this layer has been enabled by the user
# declutter - the maximum declutter level (0-3) that this layer is visible in
# range - the maximum range this layer is visible (configured by user)
# max_range - the maximum range value that a user can configure for this layer.
LAYER_RANGES : {
GRID : { enabled: 0, declutter: 1, range: 20, max_range: 2000 },
DME : { enabled: 1, declutter: 1, range: 150, max_range: 300 },
VOR : { enabled: 1, declutter: 1, range: 150, max_range: 300 },
NDB : { enabled: 1, declutter: 1, range: 15, max_range: 30 },
FIX : { enabled: 1, declutter: 1, range: 15, max_range: 30 },
RTE : { enabled: 1, declutter: 3, range: 2000, max_range: 2000 },
WPT : { enabled: 1, declutter: 3, range: 2000, max_range: 2000 },
APS : { enabled: 1, declutter: 3, range: 2000, max_range: 2000 },
FLT : { enabled: 1, declutter: 3, range: 2000, max_range: 2000 },
WXR : { enabled: 1, declutter: 2, range: 2000, max_range: 2000 },
APT : { enabled: 1, declutter: 2, range: 150, max_range: 300 },
TFC : { enabled: 0, declutter: 3, range: 150, max_range: 2000},
OpenAIP : { enabled: 1, declutter: 1, range: 150, max_range: 300 },
STAMEN : { enabled: 1, declutter: 3, range: 500, max_range: 2000 },
STAMEN_terrain : { enabled: 1, declutter: 3, range: 500, max_range: 2000 },
},
# TODO: Add STAMEN topo layer, which is visible on all levels as opposed to
# roads, railways, boundaries, cities which are only visible on declutter 0.
# Declutter levels.
DCLTR : [ "DCLTR", "DCLTR-1", "DCLTR-2", "DCLTR-3"],
# Airways levels.
AIRWAYS : [ "AIRWAYS", "AIRWY ON", "AIRWY LO", "AIRWY HI"],
new : func (navmap, svg, zoom_label, current_zoom)
{
var obj = { parents : [ NavMapController ] };
obj.current_zoom = current_zoom;
obj.declutter = 0;
obj.airways = 0;
obj.navmap = navmap;
obj.navmap.setScreenRange(689/2.0);
obj.label = svg.getElementById(zoom_label);
obj.setZoom(obj.current_zoom);
return obj;
},
zoomIn : func() {
me.setZoom(me.current_zoom -1);
},
zoomOut : func() {
me.setZoom(me.current_zoom +1);
},
zoom : func(val)
{
var incr_or_decr = (val > 0) ? 1 : -1;
me.setZoom(me.current_zoom + incr_or_decr);
},
setZoom : func(zoom) {
if ((zoom < 0) or (zoom > (size(me.RANGES) - 1))) return;
me.current_zoom = zoom;
# Ranges above represent vertical ranges, but the display is a rectangle, so
# we need to use the diagonal range of the 1024 x 689, which is 617px.
# 617px is 1.8 x 689/2, so we need to increase the range values by x1.8
me.navmap.setRange(me.RANGES[zoom].range);
me.label.setText(me.RANGES[zoom].label);
me.updateVisibility();
},
updateVisibility : func() {
# Determine which layers should be visible.
foreach (var layer_name; keys(me.LAYER_RANGES)) {
var layer = me.LAYER_RANGES[layer_name];
if (layer.enabled and
(me.RANGES[me.current_zoom].range <= layer.range) and
(me.declutter <= layer.declutter) )
{
me.navmap.MFDMap.getLayer(layer_name).setVisible(1);
} else {
me.navmap.MFDMap.getLayer(layer_name).setVisible(0);
}
}
},
configureLayer : func(layer, enabled, range) {
me.LAYER_RANGES[layer].enabled = enabled;
me.LAYER_RANGES[layer].range = math.min(range, me.LAYER_RANGES[layer].max_range);
},
isEnabled : func(layer) {
return me.LAYER_RANGES[layer].enabled;
},
toggleLayer : func(layer) {
me.LAYER_RANGES[layer].enabled = ! me.LAYER_RANGES[layer].enabled;
me.updateVisibility();
},
# Increment through the de-clutter levels, which impact what layers are
# displayed. We also need to update the declutter menu item.
incrDCLTR : func(device, menuItem) {
me.declutter = math.mod(me.declutter +1, 4);
menuItem.title = me.DCLTR[me.declutter];
device.updateMenus();
me.updateVisibility();
},
# Increment through the AIRWAYS levels. At present this doesn't do anything
# except change the label. It should enable/disable different airways
# information.
incrAIRWAYS : func(device, menuItem) {
me.airways = math.mod(me.airways +1, 4);
menuItem.title = me.AIRWAYS[me.airways];
device.updateMenus();
me.updateVisibility();
},
};

View file

@ -0,0 +1,28 @@
# Navigation Map Options
var NavMapOptions =
{
new : func() {
var obj = { parents : [NavMapOptions] };
obj.Options= {};
obj.loadOptions();
return obj;
},
getOption : func(type) {
return me.Options[type];
},
setOption : func(type, name, value) {
me.Options[type][name] = value;
},
loadOptions : func() {
me.clearOptions();
me.Options.APS = {};
},
clearOptions : func() {
me.Options = {};
},
};

View file

@ -0,0 +1,66 @@
# Navigation Map Styles
var NavMapStyles =
{
new : func() {
var obj = { parents : [ NavMapStyles ]};
obj.Styles = {};
obj.loadStyles();
return obj;
},
getStyle : func(type) {
return me.Styles[type];
},
setStyle : func(type, name, value) {
me.Styles[type][name] = value;
},
loadStyles : func() {
me. clearStyles();
me.Styles.DME = {};
me.Styles.DME.debug = 1; # HACK for benchmarking/debugging purposes
me.Styles.DME.animation_test = 0; # for prototyping animated symbols
me.Styles.DME.scale_factor = 0.4; # 40% (applied to whole group)
me.Styles.DME.line_width = 3.0;
me.Styles.DME.color_tuned = [0,1,0]; #rgb
me.Styles.DME.color_default = [1,1,0]; #rgb
me.Styles.APT = {};
me.Styles.APT.scale_factor = 0.4; # 40% (applied to whole group)
me.Styles.APT.line_width = 3.0;
me.Styles.APT.color_default = [0,0.6,0.85]; #rgb
me.Styles.APT.label_font_color = me.Styles.APT.color_default;
me.Styles.APT.label_font_size=28;
me.Styles.TFC = {};
me.Styles.TFC.scale_factor = 0.4; # 40% (applied to whole group)
me.Styles.WPT = {};
me.Styles.WPT.scale_factor = 0.5; # 50% (applied to whole group)
me.Styles.RTE = {};
me.Styles.RTE.line_width = 2;
me.Styles.FLT = {};
me.Styles.FLT.line_width = 3;
me.Styles.FIX = {};
me.Styles.FIX.color = [1,0,0];
me.Styles.FIX.scale_factor = 0.4; # 40%
me.Styles.VOR = {};
me.Styles.VOR.range_line_width = 2;
me.Styles.VOR.radial_line_width = 1;
me.Styles.VOR.scale_factor = 0.6; # 60%
me.Styles.APS = {};
me.Styles.APS.scale_factor = 0.25;
},
clearStyles : func() {
me.Styles = {};
},
};

View file

@ -0,0 +1,195 @@
# Controller for the PageGroup navigation, displayed in the bottom right of the
# FMS, and controlled by the FMS knob
# Set of pages, references by SVG ID
var PAGE_GROUPS = [
{ label: "MapPageGroupLabel",
group: "MapPageGroup",
pages: [ "NavigationMap", "TrafficMap", "Stormscope", "WeatherDataLink", "TAWSB"],
},
{ label: "WPTGroupLabel",
group: "WPTPageGroup",
pages: [ "AirportInformation", "IntersectionInformation", "NDBInformation", "VORInformation", "UserWPTInformation"],
},
{ label: "AuxGroupLabel",
group: "AuxPageGroup",
pages: [ "TripPlanning", "Utility", "GPSStatus", "XMRadio", "SystemStatus"],
},
{ label: "FPLGroupLabel",
group: "FPLPageGroup",
pages: [ "ActiveFlightPlan", "FlightPlanCatalog", "StoredFlightPlan"],
},
{ label: "LstGroupLabel",
group: "LstPageGroup",
pages: [ "Checklist1", "Checklist2", "Checklist3", "Checklist4", "Checklist5"],
},
{ label: "NrstGroupLabel",
group: "NrstPageGroup",
pages: [ "NearestAirports", "NearestIntersections", "NearestNDB", "NearestVOR", "NearestUserWaypoints", "NearestFrequencies", "NearestAirspaces"],
}
];
var PageGroupController =
{
new : func (myCanvas, svg, device)
{
var obj = { parents : [ PageGroupController ] };
obj._canvas = myCanvas;
obj._svg = svg;
obj._device = device;
obj._menuVisible = 0;
obj._selectedPageGroup = 0;
obj._selectedPage = 0;
# List of pages to be controllers. Keys are the pages in PAGE_GROUPS;
obj._pageList = {};
# Timers to controll when to hide the menu after inactivity, and when to load
# a new page.
obj._hideMenuTimer = maketimer(5, obj, obj.hideMenu);
obj._hideMenuTimer.singleShot = 1;
obj._loadPageTimer = maketimer(0.5, obj, obj.loadPage);
obj._loadPageTimer.singleShot = 1;
# Emesary
obj._recipient = nil;
obj.hideMenu();
return obj;
},
addPage : func(name, page)
{
me._pageList[name] = page;
},
getPage : func(name)
{
return me._pageList[name];
},
hideMenu : func()
{
foreach(var pageGroup; PAGE_GROUPS)
{
me._svg.getElementById(pageGroup.group).setVisible(0);
me._svg.getElementById(pageGroup.label).setVisible(0);
}
me._menuVisible = 0;
},
# Function to change a page based on the selection
loadPage : func()
{
var pageToLoad = PAGE_GROUPS[me._selectedPageGroup].pages[me._selectedPage];
var page = me._pageList[pageToLoad];
if (page != nil) {
me._device.selectPage(page);
} else {
printf("Unable to find page " ~ pageToLoad);
}
},
showMenu : func()
{
foreach(var pageGroup; PAGE_GROUPS)
{
if (PAGE_GROUPS[me._selectedPageGroup].label == pageGroup.label)
{
# Display the page group and highlight the label
me._svg.getElementById(pageGroup.group).setVisible(1);
me._svg.getElementById(pageGroup.label).setVisible(1);
me._svg.getElementById(pageGroup.label).setColor(0.7,0.7,1.0);
foreach (var page; pageGroup.pages)
{
# Highlight the current page.
if (pageGroup.pages[me._selectedPage] == page) {
me._svg.getElementById(page).setColor(0.7,0.7,1.0);
} else {
me._svg.getElementById(page).setColor(0.7,0.7,0.7);
}
}
}
else
{
# Hide the pagegroup and unhighlight the label on the bottom
me._svg.getElementById(pageGroup.group).setVisible(0);
me._svg.getElementById(pageGroup.label).setVisible(1);
me._svg.getElementById(pageGroup.label).setColor(0.7,0.7,0.7);
}
}
me._menuVisible = 1;
me._hideMenuTimer.stop();
me._hideMenuTimer.restart(5);
me._loadPageTimer.stop();
me._loadPageTimer.restart(0.5);
},
FMSOuter : func(val)
{
if (me._menuVisible == 1) {
# Change page group
var incr_or_decr = (val > 0) ? 1 : -1;
me._selectedPageGroup = math.mod(me._selectedPageGroup + incr_or_decr, size(PAGE_GROUPS));
me._selectedPage = 0;
}
me.showMenu();
},
FMSInner : func(val)
{
if (me._menuVisible == 1) {
# Change page group
var incr_or_decr = (val > 0) ? 1 : -1;
me._selectedPage = math.mod(me._selectedPage + incr_or_decr, size(PAGE_GROUPS[me._selectedPageGroup].pages));
}
me.showMenu();
},
RegisterWithEmesary : func(transmitter = nil){
if (transmitter == nil)
transmitter = emesary.GlobalTransmitter;
if (me._recipient == nil){
me._recipient = emesary.Recipient.new("PageController_" ~ me._device.designation);
var pfd_obj = me._device;
var controller = me;
me._recipient.Receive = func(notification)
{
if (notification.Device_Id == pfd_obj.device_id
and notification.NotificationType == notifications.PFDEventNotification.DefaultType) {
if (notification.Event_Id == notifications.PFDEventNotification.HardKeyPushed
and notification.EventParameter != nil)
{
var id = notification.EventParameter.Id;
var value = notification.EventParameter.Value;
#printf("Button pressed " ~ id ~ " " ~ value);
if (id == fg1000.MFD.FASCIA.FMS_OUTER) controller.FMSOuter(value);
if (id == fg1000.MFD.FASCIA.FMS_INNER) controller.FMSInner(value);
if (id == fg1000.MFD.FASCIA.RANGE) { if (pfd_obj.current_page.controller.zoom != nil) pfd_obj.current_page.controller.zoom(value); }
}
return emesary.Transmitter.ReceiptStatus_OK;
}
return emesary.Transmitter.ReceiptStatus_NotProcessed;
};
transmitter.Register(me._recipient);
me.transmitter = transmitter;
}
},
DeRegisterWithEmesary : func(transmitter = nil){
# remove registration from transmitter; but keep the recipient once it is created.
if (me.transmitter != nil)
me.transmitter.DeRegister(me._recipient);
me.transmitter = nil;
},
};

View file

@ -0,0 +1,172 @@
# Traffic Map
#
# Functionally similar to the Garmin GTS 800 Unit
#
var TrafficMap =
{
new : func (myCanvas, device, svg)
{
var obj = {
_group : myCanvas.createGroup("TrafficMapLayer"),
parents : [ TrafficMap, device.addPage("TrafficMap", "TrafficMapGroup") ]
};
obj.Styles = fg1000.TrafficMapStyles.new();
obj.Options = fg1000.TrafficMapOptions.new();
obj.mapgroup = obj._group.createChild("map");
obj.device = device;
# Dynamic text elements
obj.op_label = svg.getElementById("TrafficMapOpMode");
obj.alt_label = svg.getElementById("TrafficMapAltMode");
obj.outer_label = svg.getElementById("TrafficMapOuterRange");
obj.inner_label = svg.getElementById("TrafficMapInnerRange");
# Need to display this underneath the softkeys, EIS, header.
obj._group.set("z-index", -10.0);
obj._group.setVisible(0);
# Initialize the controller:
var ctrl_ns = canvas.Map.Controller.get("Aircraft position");
var source = ctrl_ns.SOURCES["current-pos"];
if (source == nil) {
# TODO: amend
var source = ctrl_ns.SOURCES["current-pos"] = {
getPosition: func subvec(geo.aircraft_position().latlon(), 0, 2),
getAltitude: func getprop('/position/altitude-ft'),
getHeading: func {
if (me.aircraft_heading)
getprop('/orientation/heading-deg')
else 0
},
aircraft_heading: 1,
};
}
setlistener("/sim/gui/dialogs/map-canvas/aircraft-heading-up", func(n) {
source.aircraft_heading = n.getBoolValue();
}, 1);
# Make it move with our aircraft:
obj.mapgroup.setController("Aircraft position", "current-pos"); # from aircraftpos.controller
# Center the map's origin, modified to take into account the surround.
obj.mapgroup.setTranslation(
fg1000.MFD.MAP_CENTER.X,
fg1000.MFD.MAP_CENTER.Y
);
var r = func(name,vis=1,zindex=nil) return caller(0)[0];
foreach(var type; [r('TFC',0),r('APS')] ) {
obj.mapgroup.addLayer(canvas.SymbolLayer,
type.name,
4,
obj.Styles.getStyle(type.name),
obj.Options.getOption(type.name),
type.vis );
}
obj.controller = fg1000.TrafficMapController.new(obj, svg);
var topMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(4, "STANDBY", pg,
func(dev, pg, mi) { pg.controller.setOperate(0); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "STANDBY"); }
);
pg.addMenuItem(5, "OPERATE", pg,
func(dev, pg, mi) { pg.controller.setOperate(1); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "OPERATE"); }
);
pg.addMenuItem(6, "TEST", pg, func(dev, pg, mi) { printf("Traffic Map TEST mode not implemented yet."); }, nil);
pg.addMenuItem(7, "FLT ID", pg,
func(dev, pg, mi) { pg.controller.toggleFlightID(); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "FLT ID"); }
);
pg.addMenuItem(8, "ALT MODE", pg, altMenu);
device.updateMenus();
};
var altMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(4, "ABOVE", pg,
func(dev, pg, mi) { pg.controller.setAlt("ABOVE"); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "ABOVE"); }
);
pg.addMenuItem(5, "NORMAL", pg,
func(dev, pg, mi) { pg.controller.setAlt("NORMAL"); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "NORMAL"); }
);
pg.addMenuItem(6, "BELOW", pg,
func(dev, pg, mi) { pg.controller.setAlt("BELOW"); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "BELOW"); }
);
pg.addMenuItem(7, "UNREST", pg,
func(dev, pg, mi) { pg.controller.setAlt("UNREST"); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "UNREST"); }
);
pg.addMenuItem(8, "BACK", pg, topMenu);
device.updateMenus();
};
# Display map toggle softkeys which change color depending
# on whether a particular layer is enabled or not.
var display_toggle = func(device, svg, mi, layer) {
var bg_name = sprintf("SoftKey%d-bg",mi.menu_id);
if (obj.controller.isEnabled(layer)) {
device.svg.getElementById(bg_name).setColorFill(0.5,0.5,0.5);
svg.setColor(0.0,0.0,0.0);
} else {
device.svg.getElementById(bg_name).setColorFill(0.0,0.0,0.0);
svg.setColor(1.0,1.0,1.0);
}
svg.setText(mi.title);
svg.setVisible(1); # display function
};
# Function to undo any colors set by display_toggle when loading a new menu
var resetMenuColors = func(device) {
for(var i = 0; i < 12; i +=1) {
var name = sprintf("SoftKey%d",i);
device.svg.getElementById(name ~ "-bg").setColorFill(0.0,0.0,0.0);
device.svg.getElementById(name).setColor(1.0,1.0,1.0);
}
}
topMenu(device, obj, nil);
return obj;
},
setLayerVisible : func(name,n=1) {
me.mapgroup.getLayer(name).setVisible(n);
},
setRange : func(range, inner_label, outer_label) {
me.mapgroup.setRange(range);
me.inner_label.setText(inner_label);
me.outer_label.setText(outer_label);
},
setScreenRange : func(range) {
me.mapgroup.setScreenRange(range);
},
offdisplay : func() {
me._group.setVisible(0);
# Reset the menu colours. Shouldn't have to do this here, but
# there's not currently an obvious other location to do so.
for(var i = 0; i < 12; i +=1) {
var name = sprintf("SoftKey%d",i);
me.device.svg.getElementById(name ~ "-bg").setColorFill(0.0,0.0,0.0);
me.device.svg.getElementById(name).setColor(1.0,1.0,1.0);
}
},
ondisplay : func() {
me._group.setVisible(1);
},
};

View file

@ -0,0 +1,91 @@
# Traffic Map Controller
var TrafficMapController =
{
# Altitude levels levels.
ALTS : { ABOVE : { label: "ABOVE", ceiling_ft: 9000, floor_ft: 2700 },
NORMAL : { label: "NORMAL", ceiling_ft: 2700, floor_ft: 2700 },
BELOW : { label: "BELOW", ceiling_ft: 2700, floor_ft: 9000 },
UNREST : { label: "UNRESTRICTED", ceiling_ft: 9000, floor_ft: 9000 }},
# Three ranges available
# 2nm
# 2nm / 6nm
# 6nm / 12nm
#
# TODO: Currently we simply use the outer range, and display the inner
# range as 1/3 of the outer. Doing this properly, we should display
# different inner rings.
RANGES : [ {range: 2, inner_label: nil, outer_label: "2nm"},
{range: 6, inner_label: "2nm", outer_label: "6nm"},
{range: 12, inner_label: "4nm", outer_label: "12nm"} ],
new : func (trafficmap, svg)
{
var obj = { parents : [ TrafficMapController ] };
obj.range = 1;
obj.alt = "NORMAL";
obj.operating = 0;
obj.flight_id = 0;
obj.trafficmap = trafficmap;
obj.trafficmap.setScreenRange(689/2.0);
obj.setZoom(obj.range);
return obj;
},
zoomIn : func() {
me.setZoom(me.current_zoom -1);
},
zoomOut : func() {
me.setZoom(me.current_zoom +1);
},
zoom : func(val)
{
var incr_or_decr = (val > 0) ? 1 : -1;
me.setZoom(me.current_zoom + incr_or_decr);
},
setZoom : func(zoom) {
if ((zoom < 0) or (zoom > (size(me.RANGES) - 1))) return;
me.current_zoom = zoom;
me.trafficmap.setRange(
me.RANGES[zoom].range,
me.RANGES[zoom].inner_label,
me.RANGES[zoom].outer_label);
},
setAlt : func(alt) {
if (me.ALTS[alt] == nil) return;
me.trafficmap.alt_label.setText(me.ALTS[alt].label);
me.alt = alt;
# Update the TFC controller to filter out the correct targets
me.trafficmap.mapgroup.getLayer("TFC").options.ceiling_ft = me.ALTS[alt].ceiling_ft;
me.trafficmap.mapgroup.getLayer("TFC").options.floor_ft = me.ALTS[alt].floor_ft;
},
setOperate : func(enabled) {
if (enabled) {
me.trafficmap.op_label.setText("OPERATING");
me.trafficmap.setLayerVisible("TFC", 1);
me.operating = 1;
} else {
me.trafficmap.op_label.setText("STANDBY");
me.trafficmap.setLayerVisible("TFC", 0);
me.operating = 0;
}
},
setFlightID : func(enabled) {
me.flight_id = enabled;
me.trafficmap.Options.setOption("TFC", "display_id", enabled);
},
toggleFlightID : func() {
me.setFlightID(! me.flight_id);
},
isEnabled : func(label) {
# Cheeky little function that returns whether the alt or operation mode
# matches the label. Used to highlight current settings in softkeys
if (label == me.alt) return 1;
if (me.operating and label == "OPERATE") return 1;
if (me.operating == 0 and label == "STANDBY") return 1;
if (me.flight_id == 1 and label == "FLT ID") return 1;
return 0;
},
};

View file

@ -0,0 +1,34 @@
# Traffic Map Options
var TrafficMapOptions =
{
new : func() {
var obj = { parents : [TrafficMapOptions] };
obj.Options= {};
obj.loadOptions();
return obj;
},
getOption : func(type) {
return me.Options[type];
},
setOption : func(type, name, value) {
me.Options[type][name] = value;
},
loadOptions : func() {
me.clearOptions();
me.Options.APS = {};
me.Options.TFC = {
ceiling_ft : 2700, # Display targets up to this height above the aircraft
floor_ft : 2700, # Display target from this height below the aircraft
display_id: 0,
};
},
clearOptions : func() {
me.Options = {};
},
};

View file

@ -0,0 +1,33 @@
# Traffic Map Styles
var TrafficMapStyles =
{
new : func() {
var obj = { parents : [ TrafficMapStyles ]};
obj.Styles = {};
obj.loadStyles();
return obj;
},
getStyle : func(type) {
return me.Styles[type];
},
setStyle : func(type, name, value) {
me.Styles[type][name] = value;
},
loadStyles : func() {
me. clearStyles();
me.Styles.TFC = {};
me.Styles.TFC.scale_factor = 1.0; # 40% (applied to whole group)
me.Styles.APS = {};
me.Styles.APS.scale_factor = 0.25;
},
clearStyles : func() {
me.Styles = {};
},
};

View file

@ -17,17 +17,22 @@
# #
# Menu Item. There is a list of these for each page changing button per display page # Menu Item. There is a list of these for each page changing button per display page
# Parameters: # Parameters:
# menu_id : page change event id for this menu item. e.g. button number # menu_id : page change event id for this menu item. e.g. button number
# title : Title Text (for display on the device) # title : Title Text (for display on the device)
# page : Instance of page usually returned from PFD.addPage # page : Instance of page usually returned from PFD.addPage
# callbackfn : Function to call when menu item is selected
# displayfn : Function to call when the menu item is displayed. Used to enable
# highlighting of menu items, for example.
var PFD_MenuItem = var PFD_MenuItem =
{ {
new : func (menu_id, title, page) new : func (menu_id, title, page, callbackfn=nil, displayfn=nil)
{ {
var obj = {parents : [PFD_MenuItem] }; var obj = {parents : [PFD_MenuItem] };
obj.page = page; obj.page = page;
obj.menu_id = menu_id; obj.menu_id = menu_id;
obj.callbackfn = callbackfn;
obj.displayfn = displayfn;
obj.title = title; obj.title = title;
return obj; return obj;
}, },
@ -63,7 +68,7 @@ var PFD_Page =
# make a page that is currenty visible not visible before making a new page visible, # make a page that is currenty visible not visible before making a new page visible,
# however more than one page could be visible - but only one set of menu buttons can be active # however more than one page could be visible - but only one set of menu buttons can be active
# so if two pages are visible (e.g. an overlay) then when the overlay removed it would be necessary # so if two pages are visible (e.g. an overlay) then when the overlay removed it would be necessary
# to call setVisible on the base page to ensure that the menus are seutp # to call setVisible on the base page to ensure that the menus are setup
setVisible : func(vis) setVisible : func(vis)
{ {
if(me.svg != nil) if(me.svg != nil)
@ -75,6 +80,21 @@ var PFD_Page =
me.offdisplay(); me.offdisplay();
}, },
# Standard callback for buttons, causing the appropriate page to be displayed
std_callbackfn : func (device, me, mi)
{
device.selectPage(mi.page);
},
# Standard display function for buttons, displaying the text and making visible
std_displayfn : func(svg_element, menuitem)
{
svg_element.setText(menuitem.title);
svg_element.setVisible(1);
#me.buttons[mi.menu_id].setText(mi.title);
#me.buttons[mi.menu_id].setVisible(1);
},
# #
# Perform action when button is pushed # Perform action when button is pushed
notifyButton : func(button_id) notifyButton : func(button_id)
@ -82,7 +102,7 @@ var PFD_Page =
{ {
if (mi.menu_id == button_id) if (mi.menu_id == button_id)
{ {
me.device.selectPage(mi.page); if (mi.callbackfn != nil) mi.callbackfn(me.device, me, mi);
break; break;
} }
} }
@ -96,14 +116,25 @@ var PFD_Page =
# page that will be selected when pressed # page that will be selected when pressed
# #
# The corresponding menu for the selected page will automatically be loaded # The corresponding menu for the selected page will automatically be loaded
addMenuItem : func(menu_id, title, page) addMenuItem : func(menu_id, title, page, callbackfn=nil, displayfn=nil)
{ {
var nm = PFD_MenuItem.new(menu_id, title, page); if (callbackfn == nil) callbackfn = me.std_callbackfn;
if (displayfn == nil) displayfn = me.std_displayfn;
var nm = PFD_MenuItem.new(menu_id, title, page, callbackfn, displayfn);
append(me.menus, nm); append(me.menus, nm);
return nm; return nm;
}, },
# base method for update; this can be overriden per page instance to provide update of the #
# Clear all items from the menu. Use-case is where they may be a hierarchy
# of menus within the same page.
#
clearMenu : func()
{
me.menus = [];
},
# base method for update; this can be overridden per page instance to provide update of the
# elements on display (e.g. to display updated properties) # elements on display (e.g. to display updated properties)
update : func(notification=nil) update : func(notification=nil)
{ {
@ -133,6 +164,7 @@ var PFD_Device =
# - num_menu_buttons is the Number of menu buttons; starting from the bottom left then right, then top, then left. # - num_menu_buttons is the Number of menu buttons; starting from the bottom left then right, then top, then left.
# - button prefix (e.g MI_) is the prefix of the labels in the SVG for the menu boxes. # - button prefix (e.g MI_) is the prefix of the labels in the SVG for the menu boxes.
# - _canvas is the canvas group. # - _canvas is the canvas group.
# - designation (optional) is used for Emesary designation
#NOTE: #NOTE:
# This does not actually create the canvas elements, or parse the SVG, that would typically be done in # This does not actually create the canvas elements, or parse the SVG, that would typically be done in
# a higher level class that contains an instance of this class. # a higher level class that contains an instance of this class.
@ -161,7 +193,7 @@ var PFD_Device =
else else
{ {
obj.buttons[idx] = msvg; obj.buttons[idx] = msvg;
obj.buttons[idx].setText(sprintf("M",idx)); obj.buttons[idx].setText(sprintf("M%d",idx));
} }
} }
obj.Recipient = nil; obj.Recipient = nil;
@ -187,17 +219,19 @@ var PFD_Device =
var pfd_obj = me; var pfd_obj = me;
me.Recipient.Receive = func(notification) me.Recipient.Receive = func(notification)
{ {
if (notification.Device_id == pfd_obj.device_id if (notification.Device_Id == pfd_obj.device_id
and notification.NotificationType == notifications.PFDEventNotification.DefaultType) { and notification.NotificationType == notifications.PFDEventNotification.DefaultType) {
if (notification.Event_Id == notifications.PFDEventNotification.SoftKeyPushed if (notification.Event_Id == notifications.PFDEventNotification.SoftKeyPushed
and notification.EventParameter != nil) and notification.EventParameter != nil)
{ {
#printf("Button pressed " ~ notification.EventParameter);
pfd_obj.notifyButton(notification.EventParameter); pfd_obj.notifyButton(notification.EventParameter);
} }
else if (notification.Event_Id == notifications.PFDEventNotification.ChangeMenuText else if (notification.Event_Id == notifications.PFDEventNotification.ChangeMenuText
and notification.EventParameter != nil) and notification.EventParameter != nil)
{ {
foreach(var eventMenu; notification.EventParameter) { foreach(var eventMenu; notification.EventParameter) {
#printf("Menu Text changed : " ~ eventMenu.Text);
foreach (var mi ; pfd_obj.current_page.menus) { foreach (var mi ; pfd_obj.current_page.menus) {
if (pfd_obj.buttons[eventMenu.Id] != nil) { if (pfd_obj.buttons[eventMenu.Id] != nil) {
pfd_obj.buttons[eventMenu.Id].setText(eventMenu.Text); pfd_obj.buttons[eventMenu.Id].setText(eventMenu.Text);
@ -253,6 +287,17 @@ var PFD_Device =
return np; return np;
}, },
# #
# Get a named page
#
getPage : func(title)
{
foreach(var p; me.pages) {
if (p.title == title) return p;
}
return nil;
},
#
# manage the update of the currently selected page # manage the update of the currently selected page
update : func(notification=nil) update : func(notification=nil)
{ {
@ -264,6 +309,8 @@ var PFD_Device =
# - the page object method controls the visibility # - the page object method controls the visibility
selectPage : func(p) selectPage : func(p)
{ {
if (me.current_page == p) return;
if (me.current_page != nil) if (me.current_page != nil)
me.current_page.setVisible(0); me.current_page.setVisible(0);
if (me.buttons != nil) if (me.buttons != nil)
@ -276,8 +323,7 @@ var PFD_Device =
{ {
if (me.buttons[mi.menu_id] != nil) if (me.buttons[mi.menu_id] != nil)
{ {
me.buttons[mi.menu_id].setText(mi.title); mi.displayfn(me.buttons[mi.menu_id], mi);
me.buttons[mi.menu_id].setVisible(1);
} }
else else
printf("PFD_device: Menu for button not found. Menu ID '%s'",mi.menu_id); printf("PFD_device: Menu for button not found. Menu ID '%s'",mi.menu_id);
@ -290,12 +336,17 @@ var PFD_Device =
# ensure that the menus are display correctly for the current page. # ensure that the menus are display correctly for the current page.
updateMenus : func updateMenus : func
{ {
foreach(var mb ; me.buttons)
if (mb != nil)
mb.setVisible(0);
if (me.current_page == nil) return;
foreach(var mi ; me.current_page.menus) foreach(var mi ; me.current_page.menus)
{ {
if (me.buttons[mi.menu_id] != nil) if (me.buttons[mi.menu_id] != nil)
{ {
me.buttons[mi.menu_id].setText(mi.title); mi.displayfn(me.buttons[mi.menu_id], mi);
me.buttons[mi.menu_id].setVisible(1);
} }
else else
printf("No corresponding item '%s'",mi.menu_id); printf("No corresponding item '%s'",mi.menu_id);

View file

@ -0,0 +1,40 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'STAMEN_terrain';
var parents = [OverlayLayer.Controller];
var __self__ = caller(0)[0];
OverlayLayer.Controller.add(name, __self__);
TileLayer.add(name, {
parents: [TileLayer],
type: name, # Layer type
df_controller: __self__, # controller to use by default -- this one
});
var new = func(layer) {
var m = {
parents: [__self__],
layer: layer,
map: layer.map,
listeners: [],
};
layer.makeURL = string.compileTemplate('http://b.tile.stamen.com/terrain-background/{z}/{x}/{y}.png');
layer.makePath = string.compileTemplate(layer.maps_base ~ '/stamen-terrain-background/{z}/{x}/{y}.png');
#layer.makeURL = string.compileTemplate('http://b.tile.stamen.com/toner/{z}/{x}/{y}.png');
#layer.makePath = string.compileTemplate(layer.maps_base ~ '/stamen-toner/{z}/{x}/{y}.png');
m.addVisibilityListener();
m.addRangeListener();
m.addScreenRangeListener();
return m;
};
var updateLayer = func() {
}
var del = func() {
foreach (var l; me.listeners)
removelistener(l);
};

View file

@ -1,7 +1,7 @@
# See: http://wiki.flightgear.org/MapStructure # See: http://wiki.flightgear.org/MapStructure
# FIXME: this needs to be configurable via the ctor to optionally differentiate between MP and AI traffic, and exclude ground/sea traffic # FIXME: this needs to be configurable via the ctor to optionally differentiate between MP and AI traffic, and exclude ground/sea traffic
# or at least use a different, non-TCAS symbol for those (looking pretty weird ATM) # or at least use a different, non-TCAS symbol for those (looking pretty weird ATM)
# #
# Class things: # Class things:
var name = 'TFC'; var name = 'TFC';
var parents = [SymbolLayer.Controller]; var parents = [SymbolLayer.Controller];
@ -11,6 +11,13 @@ SymbolLayer.add(name, {
parents: [MultiSymbolLayer], parents: [MultiSymbolLayer],
type: name, # Symbol type type: name, # Symbol type
df_controller: __self__, # controller to use by default -- this one df_controller: __self__, # controller to use by default -- this one
df_style: {
},
df_options: { # default configuration options
floor_ft: 120000, # Display target from this height below the aircraft
ceiling_ft: 120000, # Display targets up to this height above the aircraft
display_id: 1, # Display aircraft ID
},
}); });
var model_root = props.globals.getNode("/ai/models/"); var model_root = props.globals.getNode("/ai/models/");
@ -67,7 +74,7 @@ var get_alt_diff = func(model) {
var model_alt = model.get_alt(); var model_alt = model.get_alt();
var alt = me.map.getAlt(); var alt = me.map.getAlt();
if (alt == nil or model_alt == nil) return 0; if (alt == nil or model_alt == nil) return 0;
return alt-model_alt; return alt - model_alt;
}; };
## ##
@ -83,6 +90,12 @@ var searchCmd_default = func {
var result = []; var result = [];
var models = 0; var models = 0;
var alt = me.map.getAlt();
if (alt == nil) alt = 0;
var min_alt = alt - me.layer.options.floor_ft;
var max_alt = alt + me.layer.options.ceiling_ft;
# AI and Multiplayer traffic # AI and Multiplayer traffic
foreach (var t; model_root.getChildren()) { foreach (var t; model_root.getChildren()) {
if (!t.getValue("valid")) continue; if (!t.getValue("valid")) continue;
@ -95,11 +108,16 @@ var searchCmd_default = func {
printlog("alert", "lat/lon was nil for AI node "~t.getPath()); printlog("alert", "lat/lon was nil for AI node "~t.getPath());
continue; continue;
} }
if (me.map.controller.in_range(lat, lon))
append(result, TrafficModel.new(t, nil, me.layer)); var tm = TrafficModel.new(t, nil, me.layer);
if ((min_alt < tm.get_alt()) and
(tm.get_alt() < max_alt) and
me.map.controller.in_range(lat, lon) ) {
append(result, tm);
}
} }
#print("Found "~size(result)~" TrafficModel's in range out of "~models~" total."); #print("Found "~size(result)~" TrafficModel's in range out of "~models~" total.");
return result; return result;
}; };

View file

@ -13,7 +13,7 @@
# #
# Version : 4.8 # Version : 4.8
# #
# Copyright © 2016 Richard Harrison Released under GPL V2 # Copyright <EFBFBD> 2016 Richard Harrison Released under GPL V2
# #
#---------------------------------------------------------------------------*/ #---------------------------------------------------------------------------*/
@ -35,7 +35,7 @@ var PFDEventNotification_Id = 20;
# #
# Usage example - this can all go into one Nasal module somewhere. # Usage example - this can all go into one Nasal module somewhere.
#----------- #-----------
# var PropertySyncNotification = # var PropertySyncNotification =
# { # {
# new: func(_ident="none", _name="", _kind=0, _secondary_kind=0) # new: func(_ident="none", _name="", _kind=0, _secondary_kind=0)
# { # {
@ -65,13 +65,13 @@ var PFDEventNotification_Id = 20;
# compared to over 1100 bytes with the traditional method. # compared to over 1100 bytes with the traditional method.
# #
# The other advantage with this method of transferring data is that the model is in full control of what is # The other advantage with this method of transferring data is that the model is in full control of what is
# sent, and also when it is sent. This works on a per notification basis so less important properties could be # sent, and also when it is sent. This works on a per notification basis so less important properties could be
# transmitted on a less frequent schedule; however this will require an instance of the notification for each one. # transmitted on a less frequent schedule; however this will require an instance of the notification for each one.
# #
# PropertySyncNotificationBase is a shortcut notification; as it doesn't need to received and all # PropertySyncNotificationBase is a shortcut notification; as it doesn't need to received and all
# of the properties are simply set when the notification is unpacked over MP. # of the properties are simply set when the notification is unpacked over MP.
# So although the notification will be transmitted # So although the notification will be transmitted
var PropertySyncNotificationBase = var PropertySyncNotificationBase =
{ {
new: func(_ident="none", _name="", _kind=0, _secondary_kind=0) new: func(_ident="none", _name="", _kind=0, _secondary_kind=0)
{ {
@ -87,29 +87,29 @@ var PropertySyncNotificationBase =
new_class.addIntProperty = func(variable, property, length) new_class.addIntProperty = func(variable, property, length)
{ {
me[variable] = nil; me[variable] = nil;
append(me._bridgeProperties, append(me._bridgeProperties,
{ {
getValue:func{return emesary.TransferInt.encode(getprop(property) or 0,length);}, getValue:func{return emesary.TransferInt.encode(getprop(property) or 0,length);},
setValue:func(v,bridge,pos){var dv=emesary.TransferInt.decode(v,length,pos);me[variable]=dv.value;setprop(bridge.PropertyRoot~property, me[variable]);return dv;}, setValue:func(v,bridge,pos){var dv=emesary.TransferInt.decode(v,length,pos);me[variable]=dv.value;setprop(bridge.PropertyRoot~property, me[variable]);return dv;},
}); });
} }
new_class.addNormProperty = func(variable, property, length) new_class.addNormProperty = func(variable, property, length)
{ {
me[variable] = nil; me[variable] = nil;
append(me._bridgeProperties, append(me._bridgeProperties,
{ {
getValue:func{return emesary.TransferNorm.encode(getprop(property) or 0,length);}, getValue:func{return emesary.TransferNorm.encode(getprop(property) or 0,length);},
setValue:func(v,bridge,pos){var dv=emesary.TransferNorm.decode(v,length,pos);me[variable] = dv.value;setprop(bridge.PropertyRoot~property, me[variable]);return dv;}, setValue:func(v,bridge,pos){var dv=emesary.TransferNorm.decode(v,length,pos);me[variable] = dv.value;setprop(bridge.PropertyRoot~property, me[variable]);return dv;},
}); });
} }
new_class.addStringProperty = func(variable, property) new_class.addStringProperty = func(variable, property)
{ {
me[variable] = nil; me[variable] = nil;
append(me._bridgeProperties, append(me._bridgeProperties,
{ {
getValue:func{return emesary.TransferString.encode(getprop(property) or 0);}, getValue:func{return emesary.TransferString.encode(getprop(property) or 0);},
setValue:func(v,bridge,pos){var dv=emesary.TransferString.decode(v,pos);me[variable] = dv.value;setprop(bridge.PropertyRoot~property, me[variable]);return dv;}, setValue:func(v,bridge,pos){var dv=emesary.TransferString.decode(v,pos);me[variable] = dv.value;setprop(bridge.PropertyRoot~property, me[variable]);return dv;},
}); });
} }
@ -121,9 +121,9 @@ var PropertySyncNotificationBase =
} }
}; };
# #
# Transmit a generic control event. # Transmit a generic control event.
# two parameters - the event Id and the event value which is a 4 byte length (+/- 1,891371.000) # two parameters - the event Id and the event value which is a 4 byte length (+/- 1,891371.000)
var AircraftControlNotification = var AircraftControlNotification =
{ {
new: func(_ident="none") new: func(_ident="none")
{ {
@ -136,15 +136,15 @@ var AircraftControlNotification =
new_class.bridgeProperties = func new_class.bridgeProperties = func
{ {
return return
[ [
{ {
getValue:func{return emesary.TransferInt.encode(new_class.EventType,2);}, getValue:func{return emesary.TransferInt.encode(new_class.EventType,2);},
setValue:func(v,bridge,pos){var dv=emesary.TransferInt.decode(v,2,pos);new_class.EventType=dv.value;return dv;}, setValue:func(v,bridge,pos){var dv=emesary.TransferInt.decode(v,2,pos);new_class.EventType=dv.value;return dv;},
}, },
{ {
getValue:func{return emesary.TransferFixedDouble.encode(new_class.EventValue,4,1000);}, getValue:func{return emesary.TransferFixedDouble.encode(new_class.EventValue,4,1000);},
setValue:func(v,bridge,pos){var dv=emesary.TransferFixedDouble.decode(v,4,1000,pos);new_class.EventValue=dv.value;print("dec ",dv.value);return dv;}, setValue:func(v,bridge,pos){var dv=emesary.TransferFixedDouble.decode(v,4,1000,pos);new_class.EventValue=dv.value;print("dec ",dv.value);return dv;},
}, },
]; ];
}; };
@ -154,9 +154,9 @@ var AircraftControlNotification =
# #
# #
# Use to transmit events that happen at a specific place; can be used to make # Use to transmit events that happen at a specific place; can be used to make
# models that are simulated locally (e.g. tankers) appear on other player's MP sessions. # models that are simulated locally (e.g. tankers) appear on other player's MP sessions.
var GeoEventNotification = var GeoEventNotification =
{ {
# new: # new:
# _ident - the identifier for the notification. not bridged. # _ident - the identifier for the notification. not bridged.
@ -188,43 +188,43 @@ var GeoEventNotification =
}; };
new_class.bridgeProperties = func new_class.bridgeProperties = func
{ {
return return
[ [
{ {
getValue:func{return emesary.TransferCoord.encode(new_class.Position);}, getValue:func{return emesary.TransferCoord.encode(new_class.Position);},
setValue:func(v,root,pos){var dv=emesary.TransferCoord.decode(v, pos);new_class.Position=dv.value;return dv}, setValue:func(v,root,pos){var dv=emesary.TransferCoord.decode(v, pos);new_class.Position=dv.value;return dv},
}, },
{ {
getValue:func{return emesary.TransferString.encode(new_class.Name);}, getValue:func{return emesary.TransferString.encode(new_class.Name);},
setValue:func(v,root,pos){var dv=emesary.TransferString.decode(v,pos);new_class.Name=dv.value;return dv}, setValue:func(v,root,pos){var dv=emesary.TransferString.decode(v,pos);new_class.Name=dv.value;return dv},
}, },
{ {
getValue:func{return emesary.TransferByte.encode(new_class.Kind);}, getValue:func{return emesary.TransferByte.encode(new_class.Kind);},
setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.Kind=dv.value;return dv}, setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.Kind=dv.value;return dv},
}, },
{ {
getValue:func{return emesary.TransferByte.encode(new_class.SecondaryKind);}, getValue:func{return emesary.TransferByte.encode(new_class.SecondaryKind);},
setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.SecondaryKind=dv.value;return dv}, setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.SecondaryKind=dv.value;return dv},
}, },
{ {
getValue:func{return emesary.TransferFixedDouble.encode(new_class.u_fps,2,10);}, getValue:func{return emesary.TransferFixedDouble.encode(new_class.u_fps,2,10);},
setValue:func(v,root,pos){var dv=emesary.TransferFixedDouble.decode(v,2,10,pos);new_class.u_fps=dv.value;return dv}, setValue:func(v,root,pos){var dv=emesary.TransferFixedDouble.decode(v,2,10,pos);new_class.u_fps=dv.value;return dv},
}, },
{ {
getValue:func{return emesary.TransferFixedDouble.encode(new_class.v_fps,2,10);}, getValue:func{return emesary.TransferFixedDouble.encode(new_class.v_fps,2,10);},
setValue:func(v,root,pos){var dv=emesary.TransferFixedDouble.decode(v,2,10,pos);new_class.v_fps=dv.value;return dv}, setValue:func(v,root,pos){var dv=emesary.TransferFixedDouble.decode(v,2,10,pos);new_class.v_fps=dv.value;return dv},
}, },
{ {
getValue:func{return emesary.TransferFixedDouble.encode(new_class.w_fps,2,10);}, getValue:func{return emesary.TransferFixedDouble.encode(new_class.w_fps,2,10);},
setValue:func(v,root,pos){var dv=emesary.TransferFixedDouble.decode(v,2,10,pos);new_class.w_fps=dv.value;return dv}, setValue:func(v,root,pos){var dv=emesary.TransferFixedDouble.decode(v,2,10,pos);new_class.w_fps=dv.value;return dv},
}, },
{ {
getValue:func{return emesary.TransferString.encode(new_class.RemoteCallsign);}, getValue:func{return emesary.TransferString.encode(new_class.RemoteCallsign);},
setValue:func(v,root,pos){var dv=emesary.TransferString.decode(v,pos);new_class.RemoteCallsign=dv.value;return dv}, setValue:func(v,root,pos){var dv=emesary.TransferString.decode(v,pos);new_class.RemoteCallsign=dv.value;return dv},
}, },
{ {
getValue:func{return emesary.TransferByte.encode(new_class.Flags);}, getValue:func{return emesary.TransferByte.encode(new_class.Flags);},
setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.Flags=dv.value;return dv}, setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.Flags=dv.value;return dv},
}, },
]; ];
}; };
@ -232,7 +232,7 @@ var GeoEventNotification =
}, },
}; };
# #
# Defined kinds: # Defined kinds:
# 1 - Created # 1 - Created
# 2 - Moved # 2 - Moved
# 3 - Deleted # 3 - Deleted
@ -242,8 +242,8 @@ var GeoEventNotification =
# using the first 4 bits as the classification and the second 4 bits as the sub-classification # using the first 4 bits as the classification and the second 4 bits as the sub-classification
#----------- #-----------
# Type 0000 : Cargo # Type 0000 : Cargo
# 0 0000 0000 - Vehicle # 0 0000 0000 - Vehicle
# 1 0000 0001 - Person # 1 0000 0001 - Person
# 2 0000 0010 - 10 kg Item # 2 0000 0010 - 10 kg Item
# 3 0000 0011 - 20 kg Item # 3 0000 0011 - 20 kg Item
# 4 0000 0100 - 30 kg Item # 4 0000 0100 - 30 kg Item
@ -256,26 +256,26 @@ var GeoEventNotification =
# 11 0000 1011 - Chaff # 11 0000 1011 - Chaff
# 12 0000 1100 - Flares # 12 0000 1100 - Flares
# 13 0000 1101 - Water (fire fighting) # 13 0000 1101 - Water (fire fighting)
# 14 0000 1110 - # 14 0000 1110 -
# 15 0000 1111 - Morris Marina # 15 0000 1111 - Morris Marina
#-------- #--------
# Type 0001 : Self propelled # Type 0001 : Self propelled
# 16 0001 0000 - X-2 # 16 0001 0000 - X-2
# 17 0001 0001 - X-15 # 17 0001 0001 - X-15
# 18 0001 0010 - X-24 # 18 0001 0010 - X-24
# 19 0001 0011 - # 19 0001 0011 -
# 20 0001 0100 - # 20 0001 0100 -
# 21 0001 0101 - # 21 0001 0101 -
# 22 0001 0110 - # 22 0001 0110 -
# 23 0001 0111 - # 23 0001 0111 -
# 24 0001 1000 - # 24 0001 1000 -
# 25 0001 1001 - # 25 0001 1001 -
# 26 0001 1010 - # 26 0001 1010 -
# 27 0001 1011 - # 27 0001 1011 -
# 28 0001 1100 - # 28 0001 1100 -
# 29 0001 1101 - # 29 0001 1101 -
# 30 0001 1110 - # 30 0001 1110 -
# 31 0001 1111 - # 31 0001 1111 -
#-------- #--------
# Type 0010 : Aircraft Damage (e.g space shuttle re-entry or during launch) # Type 0010 : Aircraft Damage (e.g space shuttle re-entry or during launch)
# 32 0010 0000 - Engine 1 # 32 0010 0000 - Engine 1
@ -300,36 +300,36 @@ var GeoEventNotification =
# 49 0011 0001 - Drop Tank 2 # 49 0011 0001 - Drop Tank 2
# 50 0011 0010 - Drop Tank 3 # 50 0011 0010 - Drop Tank 3
# 51 0011 0011 - Drop Tank 4 # 51 0011 0011 - Drop Tank 4
# 52 0011 0100 - # 52 0011 0100 -
# 53 0011 0101 - # 53 0011 0101 -
# 54 0011 0110 - # 54 0011 0110 -
# 55 0011 0111 - # 55 0011 0111 -
# 56 0011 1000 - # 56 0011 1000 -
# 57 0011 1001 - # 57 0011 1001 -
# 58 0011 1010 - # 58 0011 1010 -
# 59 0011 1011 - # 59 0011 1011 -
# 60 0011 1100 - # 60 0011 1100 -
# 61 0011 1101 - # 61 0011 1101 -
# 62 0011 1110 - # 62 0011 1110 -
# 63 0011 1111 - # 63 0011 1111 -
#-------- #--------
# Type 0100 : # Type 0100 :
# 64 0100 0000 - # 64 0100 0000 -
# 65 0100 0001 - # 65 0100 0001 -
# 66 0100 0010 - # 66 0100 0010 -
# 67 0100 0011 - # 67 0100 0011 -
# 68 0100 0100 - # 68 0100 0100 -
# 69 0100 0101 - # 69 0100 0101 -
# 70 0100 0110 - # 70 0100 0110 -
# 71 0100 0111 - # 71 0100 0111 -
# 72 0100 1000 - # 72 0100 1000 -
# 73 0100 1001 - # 73 0100 1001 -
# 74 0100 1010 - # 74 0100 1010 -
# 75 0100 1011 - # 75 0100 1011 -
# 76 0100 1100 - # 76 0100 1100 -
# 77 0100 1101 - # 77 0100 1101 -
# 78 0100 1110 - # 78 0100 1110 -
# 79 0100 1111 - # 79 0100 1111 -
#-------- #--------
# Type 0101 : Models/Geometry items # Type 0101 : Models/Geometry items
# 80 0101 0000 - Aim91x.ac # 80 0101 0000 - Aim91x.ac
@ -354,199 +354,202 @@ var GeoEventNotification =
# 97 0110 0001 - rocket.ac # 97 0110 0001 - rocket.ac
# 98 0110 0010 - tracer.ac # 98 0110 0010 - tracer.ac
# 99 0110 0011 - tracer2.ac # 99 0110 0011 - tracer2.ac
# 100 0110 0100 - # 100 0110 0100 -
# 101 0110 0101 - # 101 0110 0101 -
# 102 0110 0110 - # 102 0110 0110 -
# 103 0110 0111 - # 103 0110 0111 -
# 104 0110 1000 - # 104 0110 1000 -
# 105 0110 1001 - # 105 0110 1001 -
# 106 0110 1010 - # 106 0110 1010 -
# 107 0110 1011 - # 107 0110 1011 -
# 108 0110 1100 - # 108 0110 1100 -
# 109 0110 1101 - # 109 0110 1101 -
# 110 0110 1110 - # 110 0110 1110 -
# 111 0110 1111 - # 111 0110 1111 -
#-------- #--------
# Type 0111 : Models/Geometry items # Type 0111 : Models/Geometry items
# 112 0111 0000 - # 112 0111 0000 -
# 113 0111 0001 - # 113 0111 0001 -
# 114 0111 0010 - # 114 0111 0010 -
# 115 0111 0011 - # 115 0111 0011 -
# 116 0111 0100 - # 116 0111 0100 -
# 117 0111 0101 - # 117 0111 0101 -
# 118 0111 0110 - # 118 0111 0110 -
# 119 0111 0111 - # 119 0111 0111 -
# 120 0111 1000 - # 120 0111 1000 -
# 121 0111 1001 - # 121 0111 1001 -
# 122 0111 1010 - # 122 0111 1010 -
# 123 0111 1011 - # 123 0111 1011 -
# 124 0111 1100 - # 124 0111 1100 -
# 125 0111 1101 - # 125 0111 1101 -
# 126 0111 1110 - # 126 0111 1110 -
# 127 0111 1111 - # 127 0111 1111 -
#-------- #--------
# Type 1000 : Models/Geometry items # Type 1000 : Models/Geometry items
# 128 1000 0000 - # 128 1000 0000 -
# 129 1000 0001 - # 129 1000 0001 -
# 130 1000 0010 - # 130 1000 0010 -
# 131 1000 0011 - # 131 1000 0011 -
# 132 1000 0100 - # 132 1000 0100 -
# 133 1000 0101 - # 133 1000 0101 -
# 134 1000 0110 - # 134 1000 0110 -
# 135 1000 0111 - # 135 1000 0111 -
# 136 1000 1000 - # 136 1000 1000 -
# 137 1000 1001 - # 137 1000 1001 -
# 138 1000 1010 - # 138 1000 1010 -
# 139 1000 1011 - # 139 1000 1011 -
# 140 1000 1100 - # 140 1000 1100 -
# 141 1000 1101 - # 141 1000 1101 -
# 142 1000 1110 - # 142 1000 1110 -
# 143 1000 1111 - # 143 1000 1111 -
#-------- #--------
# Type 1001 : # Type 1001 :
# 144 1001 0000 - # 144 1001 0000 -
# 145 1001 0001 - # 145 1001 0001 -
# 146 1001 0010 - # 146 1001 0010 -
# 147 1001 0011 - # 147 1001 0011 -
# 148 1001 0100 - # 148 1001 0100 -
# 149 1001 0101 - # 149 1001 0101 -
# 150 1001 0110 - # 150 1001 0110 -
# 151 1001 0111 - # 151 1001 0111 -
# 152 1001 1000 - # 152 1001 1000 -
# 153 1001 1001 - # 153 1001 1001 -
# 154 1001 1010 - # 154 1001 1010 -
# 155 1001 1011 - # 155 1001 1011 -
# 156 1001 1100 - # 156 1001 1100 -
# 157 1001 1101 - # 157 1001 1101 -
# 158 1001 1110 - # 158 1001 1110 -
# 159 1001 1111 - # 159 1001 1111 -
#-------- #--------
# Type 1010 : # Type 1010 :
# 160 1010 0000 - # 160 1010 0000 -
# 161 1010 0001 - # 161 1010 0001 -
# 162 1010 0010 - # 162 1010 0010 -
# 163 1010 0011 - # 163 1010 0011 -
# 164 1010 0100 - # 164 1010 0100 -
# 165 1010 0101 - # 165 1010 0101 -
# 166 1010 0110 - # 166 1010 0110 -
# 167 1010 0111 - # 167 1010 0111 -
# 168 1010 1000 - # 168 1010 1000 -
# 169 1010 1001 - # 169 1010 1001 -
# 170 1010 1010 - # 170 1010 1010 -
# 171 1010 1011 - # 171 1010 1011 -
# 172 1010 1100 - # 172 1010 1100 -
# 173 1010 1101 - # 173 1010 1101 -
# 174 1010 1110 - # 174 1010 1110 -
# 175 1010 1111 - # 175 1010 1111 -
#-------- #--------
# Type 1011 : # Type 1011 :
# 176 1011 0000 - # 176 1011 0000 -
# 177 1011 0001 - # 177 1011 0001 -
# 178 1011 0010 - # 178 1011 0010 -
# 179 1011 0011 - # 179 1011 0011 -
# 180 1011 0100 - # 180 1011 0100 -
# 181 1011 0101 - # 181 1011 0101 -
# 182 1011 0110 - # 182 1011 0110 -
# 183 1011 0111 - # 183 1011 0111 -
# 184 1011 1000 - # 184 1011 1000 -
# 185 1011 1001 - # 185 1011 1001 -
# 186 1011 1010 - # 186 1011 1010 -
# 187 1011 1011 - # 187 1011 1011 -
# 188 1011 1100 - # 188 1011 1100 -
# 189 1011 1101 - # 189 1011 1101 -
# 190 1011 1110 - # 190 1011 1110 -
# 191 1011 1111 - # 191 1011 1111 -
#-------- #--------
# Type 1100 : # Type 1100 :
# 192 1100 0000 - # 192 1100 0000 -
# 193 1100 0001 - # 193 1100 0001 -
# 194 1100 0010 - # 194 1100 0010 -
# 195 1100 0011 - # 195 1100 0011 -
# 196 1100 0100 - # 196 1100 0100 -
# 197 1100 0101 - # 197 1100 0101 -
# 198 1100 0110 - # 198 1100 0110 -
# 199 1100 0111 - # 199 1100 0111 -
# 200 1100 1000 - # 200 1100 1000 -
# 201 1100 1001 - # 201 1100 1001 -
# 202 1100 1010 - # 202 1100 1010 -
# 203 1100 1011 - # 203 1100 1011 -
# 204 1100 1100 - # 204 1100 1100 -
# 205 1100 1101 - # 205 1100 1101 -
# 206 1100 1110 - # 206 1100 1110 -
# 207 1100 1111 - # 207 1100 1111 -
#-------- #--------
# Type 1101 : # Type 1101 :
# 208 1101 0000 - # 208 1101 0000 -
# 209 1101 0001 - # 209 1101 0001 -
# 210 1101 0010 - # 210 1101 0010 -
# 211 1101 0011 - # 211 1101 0011 -
# 212 1101 0100 - # 212 1101 0100 -
# 213 1101 0101 - # 213 1101 0101 -
# 214 1101 0110 - # 214 1101 0110 -
# 215 1101 0111 - # 215 1101 0111 -
# 216 1101 1000 - # 216 1101 1000 -
# 217 1101 1001 - # 217 1101 1001 -
# 218 1101 1010 - # 218 1101 1010 -
# 219 1101 1011 - # 219 1101 1011 -
# 220 1101 1100 - # 220 1101 1100 -
# 221 1101 1101 - # 221 1101 1101 -
# 222 1101 1110 - # 222 1101 1110 -
# 223 1101 1111 - # 223 1101 1111 -
#-------- #--------
# Type 1110 : # Type 1110 :
# 224 1110 0000 - # 224 1110 0000 -
# 225 1110 0001 - # 225 1110 0001 -
# 226 1110 0010 - # 226 1110 0010 -
# 227 1110 0011 - # 227 1110 0011 -
# 228 1110 0100 - # 228 1110 0100 -
# 229 1110 0101 - # 229 1110 0101 -
# 230 1110 0110 - # 230 1110 0110 -
# 231 1110 0111 - # 231 1110 0111 -
# 232 1110 1000 - # 232 1110 1000 -
# 233 1110 1001 - # 233 1110 1001 -
# 234 1110 1010 - # 234 1110 1010 -
# 235 1110 1011 - # 235 1110 1011 -
# 236 1110 1100 - # 236 1110 1100 -
# 237 1110 1101 - # 237 1110 1101 -
# 238 1110 1110 - # 238 1110 1110 -
# 239 1110 1111 - # 239 1110 1111 -
#-------- #--------
# Type 1111 : # Type 1111 :
# 240 1111 0000 - # 240 1111 0000 -
# 241 1111 0001 - # 241 1111 0001 -
# 242 1111 0010 - # 242 1111 0010 -
# 243 1111 0011 - # 243 1111 0011 -
# 244 1111 0100 - # 244 1111 0100 -
# 245 1111 0101 - # 245 1111 0101 -
# 246 1111 0110 - # 246 1111 0110 -
# 247 1111 0111 - # 247 1111 0111 -
# 248 1111 1000 - # 248 1111 1000 -
# 249 1111 1001 - # 249 1111 1001 -
# 250 1111 1010 - # 250 1111 1010 -
# 251 1111 1011 - # 251 1111 1011 -
# 252 1111 1100 - # 252 1111 1100 -
# 253 1111 1101 - # 253 1111 1101 -
# 254 1111 1110 - # 254 1111 1110 -
# 255 1111 1111 - # 255 1111 1111 -
# #
# #
# Use to transmit events that happen at a specific place; can be used to make # Use to transmit events that happen at a specific place; can be used to make
# models that are simulated locally (e.g. tankers) appear on other player's MP sessions. # models that are simulated locally (e.g. tankers) appear on other player's MP sessions.
var PFDEventNotification = var PFDEventNotification =
{ {
# new: # new:
# _ident - the identifier for the notification. not bridged. # _ident - the identifier for the notification. not bridged.
# _pfd_id - numeric identification of the PFD within the model # _pfd_id - numeric identification of the PFD within the model
# _event_id - event ID. # _event_id - event ID.
# 1 softkey pushed. # 1 softkey pushed.
# 2 select page by ID # 2 select page by ID
# 3 Change softkey button text
# 4 hardkey pushed - i.e. non-soft keys that don't change function based on context.
# _event_param - param related to the event ID. implementation specific. # _event_param - param related to the event ID. implementation specific.
## ##
SoftKeyPushed : 1, SoftKeyPushed : 1,
SelectPageById : 2, SelectPageById : 2,
ChangeMenuText : 3, #event parameter contains hash of { Id: , Text: } ChangeMenuText : 3, #event parameter contains array of { Id: , Text: } tuples
HardKeyPushed : 4, #event parameter contains single { Id: , Value: } tuple
DefaultType : "PFDEventNotification", DefaultType : "PFDEventNotification",
new: func(_ident, _device_id,_event_id,_event_parameter_id) new: func(_ident, _device_id,_event_id,_event_parameter_id)
@ -560,15 +563,15 @@ var PFDEventNotification =
new_class.bridgeProperties = func new_class.bridgeProperties = func
{ {
return return
[ [
{ {
getValue:func{return emesary.TransferByte.encode(new_class.Event_Id);}, getValue:func{return emesary.TransferByte.encode(new_class.Event_Id);},
setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.Event_Id=dv.value;return dv}, setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.Event_Id=dv.value;return dv},
}, },
{ {
getValue:func{return emesary.TransferByte.encode(new_class.EventParameter);}, getValue:func{return emesary.TransferByte.encode(new_class.EventParameter);},
setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.EventParameter=dv.value;return dv}, setValue:func(v,root,pos){var dv=emesary.TransferByte.decode(v,pos);new_class.EventParameter=dv.value;return dv},
}, },
]; ];
}; };

View file

@ -110,6 +110,7 @@
<performance-monitor>Monitor System Performance</performance-monitor> <performance-monitor>Monitor System Performance</performance-monitor>
<write-video-config>Save Video Configuration</write-video-config> <write-video-config>Save Video Configuration</write-video-config>
<property-browser>Browse Internal Properties</property-browser> <property-browser>Browse Internal Properties</property-browser>
<fg1000>FG1000 MFD</fg1000>
<logging>Logging</logging> <logging>Logging</logging>
<local_weather>Local Weather (Test)</local_weather> <local_weather>Local Weather (Test)</local_weather>
<print-scene-info>Print Visible Scene Info</print-scene-info> <print-scene-info>Print Visible Scene Info</print-scene-info>

892
gui/dialogs/fg1000.xml Normal file
View file

@ -0,0 +1,892 @@
<?xml version="1.0"?>
<PropertyList>
<name>fg1000</name>
<layout>vbox</layout>
<resizable>true</resizable>
<default-padding>3</default-padding>
<color>
<alpha type="float">1.0</alpha>
</color>
<nasal>
<open><![CDATA[
var self = cmdarg();
var listeners = [];
var mfd = nil;
]]></open>
<close><![CDATA[
foreach (var l; listeners)
removelistener(l);
setsize(listeners, 0);
mfd.del();
]]></close>
</nasal>
<group>
<layout>hbox</layout>
<default-padding>1</default-padding>
<empty><stretch>1</stretch></empty>
<text>
<label>FG1000 MFD</label>
</text>
<empty><stretch>1</stretch></empty>
<button>
<pref-width>16</pref-width>
<pref-height>16</pref-height>
<legend></legend>
<keynum>27</keynum>
<border>2</border>
<binding>
<command>dialog-close</command>
</binding>
</button>
</group>
<hrule/>
<group>
<layout>hbox</layout>
<stretch>true</stretch>
<halign>fill</halign>
<!-- Left sidebar NAV & Autopilot-->
<group>
<layout>vbox</layout>
<halign>center</halign>
<valign>top</valign>
<dial>
<name>vol</name>
<label>VOL</label>
<pref-width>30</pref-width>
<property>/gui/dialogs/fg1000/nav-vol</property>
</dial>
<button>
<name>toggle-nav</name>
<legend>&lt;-&gt;</legend>
<pref-width>30</pref-width>
<pref-height>30</pref-height>
<halign>right</halign>
<binding>
<command>property-swap</command>
<condition>
<not>
<property>/instrumentation/nav-selected</property>
</not>
</condition>
<property>/instrumentation/nav[0]/frequencies/selected-mhz</property>
<property>/instrumentation/nav[0]/frequencies/standby-mhz</property>
</binding>
<binding>
<command>property-swap</command>
<condition>
<property>/instrumentation/nav-selected</property>
</condition>
<property>/instrumentation/nav[1]/frequencies/selected-mhz</property>
<property>/instrumentation/nav[1]/frequencies/standby-mhz</property>
</binding>
</button>
<text><label>NAV</label></text>
<group>
<layout>hbox</layout>
<halign>center</halign>
<default-padding>0</default-padding>
<button>
<name>nav-decrease-MHz</name>
<legend>&lt;&lt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
<button>
<name>nav-decrease-KHz</name>
<legend>&lt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
<button>
<name>nav-increase-KHz</name>
<legend>&gt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
<button>
<name>nav-increase-MHz</name>
<legend>&gt;&gt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
</group>
<button>
<name>toggle-nav</name>
<legend>1-2</legend>
<pref-width>50</pref-width>
<pref-height>25</pref-height>
<default-padding>0</default-padding>
<binding>
<command>property-toggle</command>
<property>/instrumentation/nav-selected</property>
</binding>
</button>
<!-- Heading Control -->
<text><label>HDG</label></text>
<dial>
<name>hdg</name>
<width>20</width>
<property>/gui/dialogs/fg1000/hdg</property>
</dial>
<button>
<name>hdg-sync</name>
<legend>HDG SYNC</legend>
<pref-width>75</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-toggle</command>
<property>/instrumentation/nav-selected</property>
</binding>
</button>
<group>
<!-- AP Controls -->
<layout>table</layout>
<button>
<col>0</col><row>0</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>AP</name>
<legend>AP</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/ap</property>
</binding>
</button>
<button>
<col>1</col><row>0</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>FD</name>
<legend>FD</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/fd</property>
</binding>
</button>
<button>
<col>0</col><row>1</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>HDG</name>
<legend>HDG</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/hdg</property>
</binding>
</button>
<button>
<col>1</col><row>1</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>ALT</name>
<legend>ALT</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/alt</property>
</binding>
</button>
<button>
<col>0</col><row>2</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>NAV</name>
<legend>NAV</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/nav</property>
</binding>
</button>
<button>
<col>1</col><row>2</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>VNV</name>
<legend>VNV</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/vnv</property>
</binding>
</button>
<button>
<col>0</col><row>3</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>APR</name>
<legend>APR</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/apr</property>
</binding>
</button>
<button>
<col>1</col><row>3</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>BC</name>
<legend>BC</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/bc</property>
</binding>
</button>
<button>
<col>0</col><row>4</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>VS</name>
<legend>VS</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/vs</property>
</binding>
</button>
<button>
<col>1</col><row>4</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>up</name>
<legend>UP</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/up</property>
</binding>
</button>
<button>
<col>0</col><row>5</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>FLC</name>
<legend>FLC</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/flc</property>
</binding>
</button>
<button>
<col>1</col><row>5</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>DN</name>
<legend>DN</legend>
<binding>
<command>property-toggle</command>
<property>/sim/instrumentation/fg1000/autopilot/dn</property>
</binding>
</button>
</group>
<text><label>ALT</label></text>
<group>
<layout>hbox</layout>
<halign>center</halign>
<default-padding>0</default-padding>
<!-- ALT controller -->
<button>
<name>alt-decr-large</name>
<legend>&lt;&lt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
<button>
<name>alt-decr-small</name>
<legend>&lt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
<button>
<name>alt-incr-small</name>
<legend>&gt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
<button>
<name>alt-incr-large</name>
<legend>&gt;&gt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
</group>
<!-- End of left hand stack of controls -->
</group>
<vrule/>
<group>
<layout>vbox</layout>
<stretch>true</stretch>
<group>
<canvas>
<name>canvas-map</name>
<valign>center</valign>
<halign>center</halign>
<stretch>false</stretch>
<pref-width>1024</pref-width>
<pref-height>768</pref-height>
<width>1024</width>
<height>768</height>
<nasal><load><![CDATA[
var myCanvas = canvas.get( cmdarg() );
myCanvas.setColorBackground(0,0,0,1.0);
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
io.load_nasal(nasal_dir ~ 'MFD.nas', "fg1000");
mfd = fg1000.MFD.new(myCanvas);
softkeypushed = 0;
# Connect the buttons - using the provided model index to get the right ones from the model binding
var softkey_listener = setlistener("/sim/gui/dialogs/fg1000/softkey-pressed", func(v)
{
if (v != nil) {
if (v.getValue()) {
softkeypushed = v.getValue();
#printf("Button %d", softkeypushed);
#mfd._MFDDevice.notifyButton(softkeypushed);
var notification = notifications.PFDEventNotification.new("MFD", 1, notifications.PFDEventNotification.SoftKeyPushed, softkeypushed);
emesary.GlobalTransmitter.NotifyAll(notification);
softkeypushed = 0;
}
}
}
);
append(listeners, softkey_listener);
#append(listeners, setlistener("/sim/gui/dialogs/fg1000/fms-incr-large-pressed", func(v) { mfd._pageGroupController.incrFMSOuter(); } ));
#append(listeners, setlistener("/sim/gui/dialogs/fg1000/fms-incr-small-pressed", func(v) { mfd._pageGroupController.incrFMSInner(); } ));
#append(listeners, setlistener("/sim/gui/dialogs/fg1000/fms-decr-large-pressed", func(v) { mfd._pageGroupController.decrFMSOuter(); } ));
#append(listeners, setlistener("/sim/gui/dialogs/fg1000/fms-decr-small-pressed", func(v) { mfd._pageGroupController.decrFMSInner(); } ));
append(listeners, setlistener("/sim/gui/dialogs/fg1000/fms-incr-large-pressed", func(v) {
var notification = notifications.PFDEventNotification.new("MFD", 1, notifications.PFDEventNotification.HardKeyPushed, { Id: fg1000.MFD.FASCIA.FMS_OUTER, Value: 1.0 });
emesary.GlobalTransmitter.NotifyAll(notification);
} ));
append(listeners, setlistener("/sim/gui/dialogs/fg1000/fms-incr-small-pressed", func(v) {
var notification = notifications.PFDEventNotification.new("MFD", 1, notifications.PFDEventNotification.HardKeyPushed, { Id: fg1000.MFD.FASCIA.FMS_INNER, Value: 1.0 });
emesary.GlobalTransmitter.NotifyAll(notification);
} ));
append(listeners, setlistener("/sim/gui/dialogs/fg1000/fms-decr-large-pressed", func(v) {
var notification = notifications.PFDEventNotification.new("MFD", 1, notifications.PFDEventNotification.HardKeyPushed, { Id: fg1000.MFD.FASCIA.FMS_OUTER, Value: -1.0 });
emesary.GlobalTransmitter.NotifyAll(notification);
} ));
append(listeners, setlistener("/sim/gui/dialogs/fg1000/fms-decr-small-pressed", func(v) {
var notification = notifications.PFDEventNotification.new("MFD", 1, notifications.PFDEventNotification.HardKeyPushed, { Id: fg1000.MFD.FASCIA.FMS_INNER, Value: -1.0 });
emesary.GlobalTransmitter.NotifyAll(notification);
} ));
append(listeners, setlistener("/sim/gui/dialogs/fg1000/range-decr-pressed", func(v) {
var notification = notifications.PFDEventNotification.new("MFD", 1, notifications.PFDEventNotification.HardKeyPushed, { Id: fg1000.MFD.FASCIA.RANGE, Value: -1.0 });
emesary.GlobalTransmitter.NotifyAll(notification);
} ));
append(listeners, setlistener("/sim/gui/dialogs/fg1000/range-incr-pressed", func(v) {
var notification = notifications.PFDEventNotification.new("MFD", 1, notifications.PFDEventNotification.HardKeyPushed, { Id: fg1000.MFD.FASCIA.RANGE, Value: 1.0 });
emesary.GlobalTransmitter.NotifyAll(notification);
} ));
]]></load></nasal>
</canvas>
<layout>hbox</layout>
<stretch>true</stretch>
<halign>fill</halign>
<valign>fill</valign>
</group>
<group>
<!-- Buttons on the bottom of the fascia -->
<layout>hbox</layout>
<stretch>true</stretch>
<halign>fill</halign>
<valign>top</valign>
<button>
<name>softkey-1</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>1</value>
</binding>
</button>
<button>
<name>softkey-2</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>2</value>
</binding>
</button>
<button>
<name>softkey-3</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>3</value>
</binding>
</button>
<button>
<name>softkey-4</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>4</value>
</binding>
</button>
<button>
<name>softkey-5</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>5</value>
</binding>
</button>
<button>
<name>softkey-6</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>6</value>
</binding>
</button>
<button>
<name>softkey-7</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>7</value>
</binding>
</button>
<button>
<name>softkey-8</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>8</value>
</binding>
</button>
<button>
<name>softkey-9</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>9</value>
</binding>
</button>
<button>
<name>softkey-10</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>10</value>
</binding>
</button>
<button>
<name>softkey-11</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>11</value>
</binding>
</button>
<button>
<name>softkey-12</name>
<legend>^</legend>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/softkey-pressed</property>
<value>12</value>
</binding>
</button>
<!-- End of softkeys -->
</group>
<!-- End of middle vertical panel -->
</group>
<vrule/>
<group>
<!-- Righthand control panel -->
<layout>vbox</layout>
<halign>center</halign>
<valign>top</valign>
<dial>
<name>com-vol</name>
<label>VOL</label>
<pref-width>30</pref-width>
<property>/gui/dialogs/fg1000/com-vol</property>
</dial>
<button>
<name>toggle-com</name>
<legend>&lt;-&gt;</legend>
<pref-width>30</pref-width>
<pref-height>30</pref-height>
<halign>left</halign>
<binding>
<command>property-swap</command>
<condition>
<not>
<property>/instrumentation/com-selected</property>
</not>
</condition>
<property>/instrumentation/com[0]/frequencies/selected-mhz</property>
<property>/instrumentation/com[0]/frequencies/standby-mhz</property>
</binding>
<binding>
<command>property-swap</command>
<condition>
<property>/instrumentation/com-selected</property>
</condition>
<property>/instrumentation/com[1]/frequencies/selected-mhz</property>
<property>/instrumentation/com[1]/frequencies/standby-mhz</property>
</binding>
</button>
<text><label>COM</label></text>
<group>
<layout>hbox</layout>
<halign>center</halign>
<default-padding>0</default-padding>
<button>
<name>com-decrease-MHz</name>
<legend>&lt;&lt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
<button>
<name>com-decrease-KHz</name>
<legend>&lt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
<button>
<name>com-increase-KHz</name>
<legend>&gt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
<button>
<name>com-increase-MHz</name>
<legend>&gt;&gt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
</button>
</group>
<button>
<name>toggle-nav</name>
<legend>1-2</legend>
<pref-width>50</pref-width>
<pref-height>25</pref-height>
<default-padding>0</default-padding>
<binding>
<command>property-toggle</command>
<property>/instrumentation/nav-selected</property>
</binding>
</button>
<text>
<label>BARO</label>
</text>
<dial>
<name>baro</name>
<width>20</width>
<property>/gui/dialogs/fg1000/baro</property>
</dial>
<text>
<label>CRS</label>
</text>
<dial>
<name>crs</name>
<width>20</width>
<property>/gui/dialogs/fg1000/crs</property>
<binding><command>dialog-apply</command></binding>
</dial>
<button>
<name>crs-center</name>
<legend>CRS CTR</legend>
<pref-width>75</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-toggle</command>
<property>/instrumentation/com-selected</property>
</binding>
</button>
<!-- Map Controls -->
<text><label>RANGE</label></text>
<group>
<layout>hbox</layout>
<halign>center</halign>
<default-padding>0</default-padding>
<!-- RANGE controller -->
<button>
<name>range-decr</name>
<legend>&lt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/range-incr-pressed</property>
<value>1</value>
</binding>
</button>
<button>
<name>range-incr</name>
<legend>&gt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/range-decr-pressed</property>
<value>1</value>
</binding>
</button>
</group>
<group>
<layout>table</layout>
<halign>center</halign>
<default-padding>0</default-padding>
<button>
<row>0</row><col>1</col>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
<name>map-up</name>
<legend>^</legend>
</button>
<button>
<row>1</row><col>0</col>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
<name>map-left</name>
<legend>&lt;</legend>
</button>
<button>
<row>1</row><col>1</col>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
<name>map-ptr</name>
<legend>PTR</legend>
</button>
<button>
<row>1</row><col>2</col>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
<name>map-right</name>
<legend>&gt;</legend>
</button>
<button>
<row>2</row><col>1</col>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
<name>map-down</name>
<legend>v</legend>
</button>
</group>
<group>
<!-- FMS Controls -->
<layout>table</layout>
<halign>center</halign>
<button>
<col>0</col><row>0</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>DTO</name>
<legend>DTO</legend>
</button>
<button>
<col>1</col><row>0</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>menu</name>
<legend>MENU</legend>
</button>
<button>
<col>0</col><row>1</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>FPL</name>
<legend>FPL</legend>
</button>
<button>
<col>1</col><row>1</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>PROC</name>
<legend>PROC</legend>
</button>
<button>
<col>0</col><row>2</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>CLR</name>
<legend>CLR</legend>
</button>
<button>
<col>1</col><row>2</row>
<pref-width>40</pref-width>
<pref-height>25</pref-height>
<name>ENT</name>
<legend>ENT</legend>
</button>
</group>
<text><label>FMS</label></text>
<group>
<layout>hbox</layout>
<halign>center</halign>
<default-padding>0</default-padding>
<!-- FMS controller -->
<button>
<name>fms-decr-large</name>
<legend>&lt;&lt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/fms-decr-large-pressed</property>
<value>1</value>
</binding>
</button>
<button>
<name>fms-decr-small</name>
<legend>&lt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/fms-decr-small-pressed</property>
<value>1</value>
</binding>
</button>
<button>
<name>fms-incr-small</name>
<legend>&gt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/fms-incr-small-pressed</property>
<value>1</value>
</binding>
</button>
<button>
<name>fms-incr-large</name>
<legend>&gt;&gt;</legend>
<pref-width>25</pref-width>
<pref-height>25</pref-height>
<binding>
<command>property-assign</command>
<property>/sim/gui/dialogs/fg1000/fms-incr-large-pressed</property>
<value>1</value>
</binding>
</button>
</group>
<button>
<name>crsr</name>
<legend>CRSR</legend>
<pref-width>50</pref-width>
<pref-height>25</pref-height>
</button>
</group>
</group>
</PropertyList>

View file

@ -342,21 +342,21 @@
<![CDATA[ <![CDATA[
var varray = volcano.volcano_manager.volcano_array; var varray = volcano.volcano_manager.volcano_array;
var n = size(varray); var n = size(varray);
var aircraft_pos = geo.aircraft_position(); var aircraft_pos = geo.aircraft_position();
var j = 0; var j = 0;
for (var i = 0; i< n; i=i+1) for (var i = 0; i< n; i=i+1)
{ {
#print(i, " ", varray[i].name); #print(i, " ", varray[i].name);
var distance = aircraft_pos.distance_to(varray[i].pos); var distance = aircraft_pos.distance_to(varray[i].pos);
if (distance < 150000.0) # only add nearby objects if (distance < 150000.0) # only add nearby objects
{ {
var name = varray[i].name; var name = varray[i].name;
setprop("/environment/volcanoes/volcanoes-nearby/value["~j~"]", name); setprop("/environment/volcanoes/volcanoes-nearby/value["~j~"]", name);
if (j==0) if (j==0)
{setprop("/environment/volcanoes/volcano-selected", name);} {setprop("/environment/volcanoes/volcano-selected", name);}
@ -553,17 +553,17 @@
if (name != nil) # check whether a dialog is defined at all if (name != nil) # check whether a dialog is defined at all
{ {
var aircraft_pos = geo.aircraft_position(); var aircraft_pos = geo.aircraft_position();
var carrier_lat = c.getNode("position").getNode("latitude-deg").getValue(); var carrier_lat = c.getNode("position").getNode("latitude-deg").getValue();
var carrier_lon = c.getNode("position").getNode("longitude-deg").getValue(); var carrier_lon = c.getNode("position").getNode("longitude-deg").getValue();
var carrier_pos = geo.Coord.new(); var carrier_pos = geo.Coord.new();
carrier_pos.set_latlon(carrier_lat, carrier_lon); carrier_pos.set_latlon(carrier_lat, carrier_lon);
var distance = aircraft_pos.distance_to(carrier_pos); var distance = aircraft_pos.distance_to(carrier_pos);
if (distance < 50000.0) # only add nearby objects if (distance < 50000.0) # only add nearby objects
{ {
setprop("/ai/control/objects-nearby/value["~i~"]", name); setprop("/ai/control/objects-nearby/value["~i~"]", name);
if (i==0) if (i==0)
{setprop("/ai/control/object-selected", name);} {setprop("/ai/control/object-selected", name);}
@ -821,6 +821,14 @@
</binding> </binding>
</item> </item>
<item>
<name>fg1000</name>
<binding>
<command>dialog-show</command>
<dialog-name>fg1000</dialog-name>
</binding>
</item>
<item> <item>
<name>logging</name> <name>logging</name>
<binding> <binding>