diff --git a/Aircraft/c172p/c172-checklists.xml b/Aircraft/c172p/c172-checklists.xml new file mode 100644 index 000000000..646299de8 --- /dev/null +++ b/Aircraft/c172p/c172-checklists.xml @@ -0,0 +1,444 @@ +<PropertyList> + <checklist> + <title>Before Starting Engine</title> + <item> + <name>Preflight Inspection</name> + <value>COMPLETE</value> + </item> + <item> + <name>Passenger</name> + <value>COMPLETE</value> + </item> + <item> + <name>Seats, Seat Belts, Shoulder Harnesses</name> + <value>ADJUST and LOCK</value> + </item> + <item> + <name>Brakes</name> + <value>TEST and SET (shift-B)</value> + </item> + <item> + <name>Avionics Power Switch</name> + <value>OFF</value> + </item> + <item> + <name>Circuit Breakers</name> + <value>CHECK IN</value> + </item> + <item> + <name>Electrical Equipment, Autopilot</name> + <value>OFF</value> + </item> + <item> + <name>Fuel Selector Valve</name> + <value>BOTH</value> + </item> + </checklist> + + + <checklist> + <title>Starting Engine</title> + <item> + <name>Prime</name> + <value>As Required - 2-6 strokes</value> + </item> + <item> + <name>Carburetor Heat</name> + <value>COLD</value> + </item> + <item> + <name>Throttle</name> + <value>OPEN 1/8 INCH</value> + </item> + <item> + <name>Mixture</name> + <value>RICH</value> + </item> + <item> + <name>Propellor Area</name> + <value>CLEAR</value> + </item> + <item> + <name>Master Switch</name> + <value>ON</value> + </item> + <item> + <name>Magnetos</name> + <value>BOTH</value> + <value>(press } three times)</value> + </item> + <item> + <name>Ignition Switch</name> + <value>ON</value> + <value>(press s, release when engine starts)</value> + </item> + <item> + <name>Oil Pressure</name> + <value>CHECK</value> + </item> + <item> + <name>Avionics Power Switch</name> + <value>ON</value> + </item> + <item> + <name>Navigation Lights and Flashing Beacon</name> + <value>ON as required</value> + </item> + <item> + <name>Radios</name> + <value>ON</value> + </item> + </checklist> + + <checklist> + <title>Before Takeoff</title> + <item> + <name>Parking Brake</name> + <value>SET (shift-B)</value> + </item> + <item> + <name>Seats, Seat Belts, Shoulder Harnesses</name> + <value>CHECK SECURE</value> + </item> + <item> + <name>Cabin Doors</name> + <value>CLOSED and LOCKED</value> + </item> + <item> + <name>Flight Controls</name> + <value>FREE and CORRECT</value> + </item> + <item> + <name>Flight Instruments</name> + <value>CHECK and SET</value> + </item> + <item> + <name>Fuel Quantity</name> + <value>CHECK</value> + </item> + <item> + <name>Mixture</name> + <value>RICH</value> + </item> + <item> + <name>Fuel Selector Valve</name> + <value>RECHECK BOTH</value> + </item> + <item> + <name>Elevator Trim</name> + <value>SET for takeoff</value> + </item> + <item> + <name>Throttle</name> + <value>1700 RPM</value> + </item> + <item> + <name>Magnetos</name> + <value>CHECK RPM DROP</value> + <value>(125 rpm max)</value> + </item> + <item> + <name>Carburetor Heat</name> + <value>CHECK for RPM drop</value> + </item> + <item> + <name>Suction Gauge</name> + <value>CHECK</value> + </item> + <item> + <name>Engine Instruments and Ammeter</name> + <value>CHECK</value> + </item> + <item> + <name>Throttle</name> + <value>1000RPM or LESS</value> + </item> + <item> + <name>Throttle Friction Lock</name> + <value>ADJUST</value> + </item> + <item> + <name>Strobe Lights</name> + <value>AS DESIRED</value> + </item> + <item> + <name>Radios and Avionics</name> + <value>SET</value> + </item> + <item> + <name>Autopilot</name> + <value>OFF</value> + </item> + <item> + <name>Wing Flaps</name> + <value>SET for takeoff</value> + </item> + <item> + <name>Brakes</name> + <value>RELEASE</value> + </item> + </checklist> + + <checklist> + <title>Normal Takeoff</title> + <item> + <name>Wing Flaps</name> + <value>0 - 10 degrees</value> + </item> + <item> + <name>Carburetor Heat</name> + <value>COLD</value> + </item> + <item> + <name>Throttle</name> + <value>FULL OPEN</value> + </item> + <item> + <name>Elevator Control</name> + <value>LIFT NOSE WHEEL</value> + <value>(at 55 KIAS)</value> + </item> + </checklist> + + <checklist> + <title>Short Field Takeoff</title> + <item> + <name>Wing Flaps</name> + <value>10 degrees</value> + </item> + <item> + <name>Carburetor Heat</name> + <value>COLD</value> + </item> + <item> + <name>Brakes</name> + <value>APPLY</value> + </item> + <item> + <name>Throttle</name> + <value>FULL OPEN</value> + </item> + <item> + <name>Mixture</name> + <value>RICH</value> + <value>(above 3000ft, LEAN to obtain maximum RPM)</value> + </item> + <item> + <name>Brakes</name> + <value>RELEASE</value> + </item> + <item> + <name>Elevator Control</name> + <value>SLIGHTLY TAIL LOW</value> + </item> + <item> + <name>Climb Speed</name> + <value>56 KIAS</value> + </item> + </checklist> + + <checklist> + <title>Enroute Climb</title> + <item> + <name>Airspeed</name> + <value>70-85 KIAS</value> + </item> + <item> + <name>Throttle</name> + <value>FULL OPEN</value> + </item> + <item> + <name>Mixture</name> + <value>RICH</value> + <value>(above 3000ft, LEAN to obtain maximum RPM)</value> + </item> + </checklist> + + <checklist> + <title>Cruise</title> + <item> + <name>Power</name> + <value>2100-2700 RPM</value> + <value>(no more than 75% recommended)</value> + </item> + <item> + <name>Elevator Trim</name> + <value>ADJUST</value> + </item> + <item> + <name>Mixture</name> + <value>LEAN</value> + </item> + </checklist> + + <checklist> + <title>Descent</title> + <item> + <name>Fuel Selector Valve</name> + <value>BOTH</value> + </item> + <item> + <name>Power</name> + <value>AS DESIRED</value> + </item> + <item> + <name>Mixture</name> + <value>ADJUST for smooth operation</value> + <value>(full rich for idle power)</value> + </item> + <item> + <name>Carburetor Heat</name> + <value>FULL HEAT AS REQUIRED</value> + <value>(to prevent carburetor icing)</value> + </item> + </checklist> + + <checklist> + <title>Before Landing</title> + <item> + <name>Seats, Seat Belt, Shoulder Harnesses</name> + <value>SECURE</value> + </item> + <item> + <name>Fuel Selector Valve</name> + <value>BOTH</value> + </item> + <item> + <name>Mixture</name> + <value>RICH</value> + </item> + <item> + <name>Carburetor Heat</name> + <value>FULL HEAT</value> + <value>(apply full heat before reducing power)</value> + </item> + <item> + <name>Autopilot</name> + <value>OFF</value> + </item> + </checklist> + + <checklist> + <title>Normal Landing</title> + <item> + <name>Airspeed</name> + <value>65-75 KIAS (flaps UP)</value> + </item> + <item> + <name>Wing Flaps</name> + <value>AS DESIRED</value> + <value>(0 - 10 degrees below 110KIAS</value> + <value>10 - 30 degrees below 85KIAS</value> + </item> + <item> + <name>Airspeed</name> + <value>60-70 KIAS (flaps DOWN)</value> + </item> + <item> + <name>Touchdown</name> + <value>MAIN WHEELS FIRST</value> + </item> + <item> + <name>Landing Roll</name> + <value>LOWER NOSE WHEEL GENTLY</value> + </item> + <item> + <name>Braking</name> + <value>MINIMUM REQUIRED</value> + </item> + </checklist> + + <checklist> + <title>Short Field Landing</title> + <item> + <name>Airspeed</name> + <value>65-75 KIAS (flaps UP)</value> + </item> + <item> + <name>Wing Flaps</name> + <value>FULL DOWN (30 degrees)</value> + </item> + <item> + <name>Airspeed</name> + <value>61 KIAS (until flare)</value> + </item> + <item> + <name>Power</name> + <value>REDUCE to idle after clearing obstacle</value> + </item> + <item> + <name>Touchdown</name> + <value>MAIN WHEELS FIRST</value> + </item> + <item> + <name>Braking</name> + <value>APPLY HEAVILY</value> + </item> + <item> + <name>Wing Flaps</name> + <value>RETRACT</value> + </item> + </checklist> + + <checklist> + <title>Aborted Landing</title> + <item> + <name>Throttle</name> + <value>FULL OPEN</value> + </item> + <item> + <name>Carburetor Heat</name> + <value>COLD</value> + </item> + <item> + <name>Wing Flaps</name> + <value>20 degrees (immediately)</value> + </item> + <item> + <name>Climb Speed</name> + <value>55 KIAS</value> + </item> + <item> + <name>Wing Flaps</name> + <value>10 degrees (until obstacles are cleared)</value> + <value>RETRACT (after reaching safe altitude and 60 KIAS)</value> + </item> + </checklist> + + <checklist> + <title>After Landing</title> + <item> + <name>Carburetor Heat</name> + <value>COLD</value> + </item> + <item> + <name>Wing Flaps</name> + <value>UP</value> + </item> + </checklist> + + <checklist> + <title>Securing Airplane</title> + <item> + <name>Parking Brake</name> + <value>SET</value> + </item> + <item> + <name>Avionics, Power, Electrical, Autopilot</name> + <value>OFF</value> + </item> + <item> + <name>Mixture</name> + <value>PULLED FULL OUT</value> + </item> + <item> + <name>Ignition Switch</name> + <value>OFF</value> + </item> + <item> + <name>Control Lock</name> + <value>INSTALL</value> + </item> + </checklist> + +</PropertyList> diff --git a/Aircraft/c172p/c172-help.xml b/Aircraft/c172p/c172-help.xml index 0429466be..e210fcb59 100644 --- a/Aircraft/c172p/c172-help.xml +++ b/Aircraft/c172p/c172-help.xml @@ -13,33 +13,11 @@ <desc>Increase/decrease panel lighting</desc> </key> <line/> - <line>_________Engine Start Checklist_________</line> - <line>Mixture: Rich</line> - <line>Throttle: Open 1/8"</line> - <line>Parking Brake: Applied (Shift-B)</line> - <line>Prop Area: Clear</line> - <line>Magnetos: Both ( } three times )</line> - <line>Ignition: Start (s)</line> - <line>Throttle: 800-1000rpm</line> - <line/> - <line>_________Pre-Takeoff Checklist_________</line> - <line>Parking Brake: Applied (Shift-B)</line> - <line>Flight Controls: Free and Correct</line> - <line>Elevator Trim: Takeoff</line> - <line>Mixture: Rich</line> - <line>Throttle: 1700rpm</line> - <line>Suction gauge: Check</line> - <line>Engine Instruments: Check</line> - <line>Ammeter: Check</line> - <line>Magnetos: Check (125rpm max drop, 50rpm max diff</line> - <line>Throttle: Closed (check idle)</line> - <line>Throttle: 800-1000rpm</line> - <line>Mixture: As required</line> - <line/> - <line>_________Procedures_________</line> + <line>For checklists, see under Help->Aircraft Checklists</line> + <line/> <line>Takeoff: no flaps, full throttle, rotate at 55 KIAS</line> <line>Climbout: no flaps, full throttle, 80 KIAS</line> - <line>Cruise: Throttle 65%, Mixture rich of peak,</line> + <line>Cruise: Throttle 65%, Mixture rich of peak</line> <line>Landing: full flaps, 65 KIAS</line> <line/> <line>_________V Speeds_________</line> diff --git a/Aircraft/c172p/c172p-set.xml b/Aircraft/c172p/c172p-set.xml index bacf17e12..5cdedc57e 100644 --- a/Aircraft/c172p/c172p-set.xml +++ b/Aircraft/c172p/c172p-set.xml @@ -96,6 +96,8 @@ Started October 23 2001 by John Check, fgpanels@rockfish.net </sound> <help include="c172-help.xml"/> + + <checklists include="c172-checklists.xml"/> <tutorials include="Tutorials/c172-tutorials.xml"/> diff --git a/Input/Joysticks/Saitek/Pro-Flight-Cessna-Yoke.xml b/Input/Joysticks/Saitek/Pro-Flight-Cessna-Yoke.xml index 916dbb9cb..4545a393e 100644 --- a/Input/Joysticks/Saitek/Pro-Flight-Cessna-Yoke.xml +++ b/Input/Joysticks/Saitek/Pro-Flight-Cessna-Yoke.xml @@ -20,6 +20,9 @@ Button 13/14 (left hand quadrant buttons): Flaps Up/Down Buttons 15/16 (middle quadrant buttons): Gear Up/Down Buttons 17/18 (right quandrant buttons): Spoilers Up/Down + Button 19 (Throttle < 0): Reverse Thrust + Button 20 (Prop < 0): Propellor Beta + Button 21 (Mixture <0) : Cut-off Buttons 23/24/25 (right hand selector switch): View direction Sensitivity --> @@ -32,7 +35,7 @@ <name>Pro Flight Cessna Yoke</name> <axis n="0"> - <name>Yoke left/right</name> + <name>Yoke lepft/right</name> <desc>Aileron</desc> <binding> <command>property-scale</command> @@ -379,6 +382,191 @@ </binding> </mod-up> </button> + + <button n="19"> <!-- Power < 0 --> + <name>Throttle pushed below 0</name> + <desc>Thrust reverser/beta</desc> + <repeatable>false</repeatable> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[0]/reverser</property> + <value>true</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[1]/reverser</property> + <value>true</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[2]/reverser</property> + <value>true</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[3]/reverser</property> + <value>true</value> + </binding> + <binding> + <command>property-assign</command> + <property>/engines/engine[0]/reverse-thrust</property> + <value>1</value> + </binding> + <binding> + <command>property-assign</command> + <property>/engines/engine[1]/reverse-thrust</property> + <value>1</value> + </binding> + <binding> + <command>property-assign</command> + <property>/engines/engine[2]/reverse-thrust</property> + <value>1</value> + </binding> + <binding> + <command>property-assign</command> + <property>/engines/engine[3]/reverse-thrust</property> + <value>1</value> + </binding> + <mod-up> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[0]/reverser</property> + <value>false</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[1]/reverser</property> + <value>false</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[2]/reverser</property> + <value>false</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[3]/reverser</property> + <value>false</value> + </binding> + <binding> + <command>property-assign</command> + <property>/engines/engine[0]/reverse-thrust</property> + <value>0</value> + </binding> + <binding> + <command>property-assign</command> + <property>/engines/engine[1]/reverse-thrust</property> + <value>0</value> + </binding> + <binding> + <command>property-assign</command> + <property>/engines/engine[2]/reverse-thrust</property> + <value>0</value> + </binding> + <binding> + <command>property-assign</command> + <property>/engines/engine[3]/reverse-thrust</property> + <value>0</value> + </binding> + </mod-up> + </button> + + <button n="20"> <!-- Propeller < 0 --> + <name>Propeller pushed below 0</name> + <desc>Feather Prop</desc> + <repeatable>false</repeatable> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[0]/propeller-feather</property> + <value>true</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[1]/propeller-feather</property> + <value>true</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[2]/propeller-feather</property> + <value>true</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[3]/propeller-feather</property> + <value>true</value> + </binding> + <mod-up> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[0]/propeller-feather</property> + <value>false</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[1]/propeller-feather</property> + <value>false</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[2]/propeller-feather</property> + <value>false</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[3]/propeller-feather</property> + <value>false</value> + </binding> + </mod-up> + </button> + + <button n="21"> <!-- Mixture < 0 --> + <name>Mixture pushed below 0</name> + <desc>Engine cut-off</desc> + <repeatable>false</repeatable> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[0]/cutoff</property> + <value>true</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[1]/cutoff</property> + <value>true</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[2]/cutoff</property> + <value>true</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[3]/cutoff</property> + <value>true</value> + </binding> + <mod-up> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[0]/cutoff</property> + <value>false</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[1]/cutoff</property> + <value>false</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[2]/cutoff</property> + <value>false</value> + </binding> + <binding> + <command>property-assign</command> + <property>/controls/engines/engine[3]/cutoff</property> + <value>false</value> + </binding> + </mod-up> + </button> + <button n="22"> <name>Yoke mode switch left</name> <desc>Coolie hat sensitivity low</desc> diff --git a/Nasal/canvas/api.nas b/Nasal/canvas/api.nas index c6ae4d55e..9c8c4b2f6 100644 --- a/Nasal/canvas/api.nas +++ b/Nasal/canvas/api.nas @@ -324,6 +324,7 @@ var Element = { # Class for a group element on a canvas # var Group = { +# public: new: func(node, id) { return { parents: [Group, Element.new(node, id)] }; @@ -342,6 +343,17 @@ var Group = { return factory([me._node, type], id); }, + # Get a vector of all child elements + getChildren: func() + { + var children = []; + + foreach(var c; me._node.getChildren()) + if( me._isElementNode(c) ) + append(children, me._wrapElement(c)); + + return children; + }, # Get first child with given id (breadth-first search) # # @note Use with care as it can take several miliseconds (for me eg. ~2ms). @@ -361,15 +373,11 @@ var Group = { { var node_id = node.getNode("id"); if( node_id != nil and node_id.getValue() == id ) - # Create element from existing node - return me._element_factories[ node.getName() ](node, nil); + return me._wrapElement(node); } foreach(var c; node.getChildren()) - # element nodes have type NONE and valid element names (those in the the - # factor list) - if( c.getType() == "NONE" - and me._element_factories[ c.getName() ] != nil ) + if( me._isElementNode(c) ) append(stack, c); } }, @@ -379,6 +387,19 @@ var Group = { foreach(var type; keys(me._element_factories)) me._node.removeChildren(type, 0); return me; + }, +# private: + _isElementNode: func(el) + { + # element nodes have type NONE and valid element names (those in the factory + # list) + return el.getType() == "NONE" + and me._element_factories[ el.getName() ] != nil; + }, + _wrapElement: func(node) + { + # Create element from existing node + return me._element_factories[ node.getName() ](node, nil); } }; diff --git a/Nasal/canvas/map.nas b/Nasal/canvas/map.nas new file mode 100644 index 000000000..0e1196907 --- /dev/null +++ b/Nasal/canvas/map.nas @@ -0,0 +1,182 @@ +# Runway +# +var Runway = { + # Create Runway from hash + # + # @param rwy Hash containing runway data as returned from + # airportinfo().runways[ <runway designator> ] + new: func(rwy) + { + return { + parents: [Runway], + rwy: rwy + }; + }, + # Get a point on the runway with the given offset + # + # @param pos Position along the center line + # @param off Offset perpendicular to the center line + pointOffCenterline: func(pos, off = 0) + { + var coord = geo.Coord.new(); + coord.set_latlon(me.rwy.lat, me.rwy.lon); + coord.apply_course_distance(me.rwy.heading, pos - 0.5 * me.rwy.length); + + if( off ) + coord.apply_course_distance(me.rwy.heading + 90, off); + + return ["N" ~ coord.lat(), "E" ~ coord.lon()]; + } +}; + +# AirportMap +# +var AirportMap = { + # Create AirportMap from hash + # + # @param apt Hash containing airport data as returned from airportinfo() + new: func(apt) + { + return { + parents: [AirportMap], + _apt: apt + }; + }, + # Build the graphical representation of the represented airport + # + # @param layer_runways canvas.Group to attach airport map to + build: func(layer_runways) + { + var rws_done = {}; + + me.grp_apt = layer_runways.createChild("group", "apt-" ~ me._apt.id); + + foreach(var rw; keys(me._apt.runways)) + { + var is_heli = substr(rw, 0, 1) == "H"; + var rw_dir = is_heli ? nil : int(substr(rw, 0, 2)); + + var rw_rec = ""; + var thresh_rec = 0; + if( rw_dir != nil ) + { + rw_rec = sprintf("%02d", math.mod(rw_dir - 18, 36)); + if( size(rw) == 3 ) + { + var map_rec = { + "R": "L", + "L": "R", + "C": "C" + }; + rw_rec ~= map_rec[substr(rw, 2)]; + } + + if( rws_done[rw_rec] != nil ) + continue; + + var rw_rec = me._apt.runways[rw_rec]; + if( rw_rec != nil ) + thresh_rec = rw_rec.threshold; + } + + rws_done[rw] = 1; + + rw = me._apt.runways[rw]; + var icon_rw = + me.grp_apt.createChild("path", "runway-" ~ rw.id) + .setStrokeLineWidth(0.5) + .setColor(1.0,1.0,1.0) + .setColorFill(0.2, 0.2, 0.2); + + var rwy = Runway.new(rw); + var beg_thr = rwy.pointOffCenterline(rw.threshold); + var beg_thr1 = rwy.pointOffCenterline(rw.threshold, 0.5 * rw.width); + var beg_thr2 = rwy.pointOffCenterline(rw.threshold, -0.5 * rw.width); + var beg1 = rwy.pointOffCenterline(0, 0.5 * rw.width); + var beg2 = rwy.pointOffCenterline(0, -0.5 * rw.width); + + var end_thr = rwy.pointOffCenterline(rw.length - thresh_rec); + var end_thr1 = rwy.pointOffCenterline(rw.length - thresh_rec, 0.5 * rw.width); + var end_thr2 = rwy.pointOffCenterline(rw.length - thresh_rec, -0.5 * rw.width); + var end1 = rwy.pointOffCenterline(rw.length, 0.5 * rw.width); + var end2 = rwy.pointOffCenterline(rw.length, -0.5 * rw.width); + + icon_rw.setDataGeo + ( + [ canvas.Path.VG_MOVE_TO, + canvas.Path.VG_LINE_TO, + canvas.Path.VG_LINE_TO, + canvas.Path.VG_LINE_TO, + canvas.Path.VG_CLOSE_PATH ], + [ beg1[0], beg1[1], + beg2[0], beg2[1], + end2[0], end2[1], + end1[0], end1[1] ] + ); + + if( rw.length / rw.width > 3 and !is_heli ) + { + # only runways which are much longer than wide are + # real runways, otherwise it's probably a heliport. + var icon_cl = + me.grp_apt.createChild("path", "centerline") + .setStrokeLineWidth(0.5) + .setColor(1,1,1) + .setStrokeDashArray([15, 10]); + + icon_cl.setDataGeo + ( + [ canvas.Path.VG_MOVE_TO, + canvas.Path.VG_LINE_TO ], + [ beg_thr[0], beg_thr[1], + end_thr[0], end_thr[1] ] + ); + + var icon_thr = + me.grp_apt.createChild("path", "threshold") + .setStrokeLineWidth(1.5) + .setColor(1,1,1); + + icon_thr.setDataGeo + ( + [ canvas.Path.VG_MOVE_TO, + canvas.Path.VG_LINE_TO, + canvas.Path.VG_MOVE_TO, + canvas.Path.VG_LINE_TO ], + [ beg_thr1[0], beg_thr1[1], + beg_thr2[0], beg_thr2[1], + end_thr1[0], end_thr1[1], + end_thr2[0], end_thr2[1] ] + ); + } + } + + foreach(var park; me._apt.parking()) + { + var icon_park = + me.grp_apt.createChild("text", "parking-" ~ park.name) + .setDrawMode( canvas.Text.ALIGNMENT + + canvas.Text.TEXT ) + .setText(park.name) + .setFont("LiberationFonts/LiberationMono-Bold.ttf") + .setGeoPosition(park.lat, park.lon) + .setFontSize(15, 1.3); + } + + var icon_tower = + me.grp_apt.createChild("path", "tower") + .setStrokeLineWidth(1) + .setScale(1.5) + .setColor(0.2,0.2,1.0) + .moveTo(-3, 0) + .vert(-10) + .line(-3, -10) + .horiz(12) + .line(-3, 10) + .vert(10); + + var pos = me._apt.tower(); + icon_tower.setGeoPosition(pos.lat, pos.lon); + + } +}; diff --git a/Nasal/gui.nas b/Nasal/gui.nas index de1f97c29..6c4c7e95f 100644 --- a/Nasal/gui.nas +++ b/Nasal/gui.nas @@ -146,6 +146,7 @@ _setlistener("/sim/signals/nasal-dir-initialized", func { # enable/disable menu entries menuEnable("fuel-and-payload", fdm == "yasim" or fdm == "jsb"); + menuEnable("aircraft-checklists", props.globals.getNode("/sim/checklists") != nil); var isAutopilotMenuEnabled = func { foreach( var apdp; autopilotDisableProps ) { if( props.globals.getNode( apdp ) != nil ) diff --git a/Translations/en/menu.xml b/Translations/en/menu.xml index a21e90682..51c6e8e8d 100644 --- a/Translations/en/menu.xml +++ b/Translations/en/menu.xml @@ -27,9 +27,8 @@ <!-- Location menu --> <location>Location</location> - <position-on-ground>Position Aircraft On Ground</position-on-ground> <position-in-air>Position Aircraft In Air</position-in-air> - <goto-airport>Select Airport From List</goto-airport> + <goto-airport>Select Airport</goto-airport> <random-attitude>Random Attitude</random-attitude> <tower-position>Tower Position</tower-position> @@ -110,6 +109,7 @@ <help>Help</help> <help-browser>Help (opens in browser)</help-browser> <aircraft-keys>Aircraft Help</aircraft-keys> + <aircraft-checklists>Aircraft Checklists</aircraft-checklists> <common-keys>Common Aircraft Keys</common-keys> <basic-keys>Basic Simulator Keys</basic-keys> <joystick-config>Joystick Configuration</joystick-config> diff --git a/gui/dialogs/about.xml b/gui/dialogs/about.xml index 0886cc404..bddef0a9f 100644 --- a/gui/dialogs/about.xml +++ b/gui/dialogs/about.xml @@ -113,6 +113,9 @@ <empty> <stretch>true</stretch> </empty> + + <hrule/> + <text> <halign>center</halign> @@ -166,7 +169,67 @@ <format>Revision: %s</format> <property>/sim/version/revision</property> </text> + </group> + <empty> + <stretch>true</stretch> + </empty> + + <hrule/> + + <text> + <halign>center</halign> + <label>Graphics/OpenGL Information</label> + </text> + + <group> + <layout>vbox</layout> + <border>10</border> + <halign>center</halign> + <default-padding>2</default-padding> + + + <text> + <halign>left</halign> + <label>MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM</label> + <format>OpenGL Vendor: %s</format> + <property>/sim/rendering/gl-vendor</property> + </text> + + <text> + <halign>left</halign> + <label>MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM</label> + <format>OpenGL Renderer: %s</format> + <property>/sim/rendering/gl-renderer</property> + </text> + + <text> + <halign>left</halign> + <label>MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM</label> + <format>OpenGL Version: %s</format> + <property>/sim/rendering/gl-version</property> + </text> + + <text> + <halign>left</halign> + <label>MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM</label> + <format>GLSL Version: %s</format> + <property>/sim/rendering/gl-shading-language-version</property> + </text> + + <text> + <halign>left</halign> + <label>MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM</label> + <format>Max Texture Size: %s</format> + <property>/sim/rendering/max-texture-size</property> + </text> + + <text> + <halign>left</halign> + <label>MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM</label> + <format>Depth Buffer Bits: %s</format> + <property>/sim/rendering/depth-buffer-bits</property> + </text> </group> </group> @@ -188,6 +251,35 @@ </binding> </button> + <button> + <legend>Take screen shot</legend> + <equal>true</equal> + <default>false</default> + <binding> + <command>nasal</command> + <script>fgcommand("screen-capture");</script> + </binding> + </button> + + <button> + <legend>Copy to Clipboard</legend> + <equal>true</equal> + <default>false</default> + <binding> + <command>nasal</command> + <script><![CDATA[ + var properties = ["gl-vendor","gl-version","gl-renderer", "gl-shading-language-version"]; + var data = ""; + var path = "/sim/rendering/"; + foreach(var p; properties) + data ~= p ~":"~getprop(path~p) ~"\n"; + clipboard.setText(data); + gui.popupTip("Copied version information to clipboard!"); + ]]></script> + </binding> + </button> + + <empty><stretch>true</stretch></empty> </group> diff --git a/gui/dialogs/airports.xml b/gui/dialogs/airports.xml index 75fb36749..6be2b6f15 100644 --- a/gui/dialogs/airports.xml +++ b/gui/dialogs/airports.xml @@ -31,20 +31,93 @@ <nasal> <open> - var id = ""; - var node = props.globals.getNode("/sim/gui/dialogs/airports", 1); - if (node.getNode("list") == nil) - node.getNode("list", 1).setValue(""); + setprop("/sim/gui/dialogs/airports/selected-airport/rwy", ""); + setprop("/sim/gui/dialogs/airports/selected-airport/parkpos", ""); + setprop("/sim/gui/dialogs/airports/list", ""); + + var airport_id = getprop("/sim/presets/airport-id"); + if (airport_id == nil) { airport_id = "KSFO"; } + + var dlg = props.globals.getNode("/sim/gui/dialogs/airports", 1); + var avail_runways = dlg.getNode("available-runways", 1); + var avail_parking = dlg.getNode("available-parking", 1); + + if (dlg.getNode("list") == nil) + dlg.getNode("list", 1).setValue(""); - node = node.getNode("list"); + var airportlist = dlg.getNode("list"); + + var mode = { + runway: dlg.getNode("use_runway", 1), + bestrunway: dlg.getNode("use_best_runway", 1), + parkpos: dlg.getNode("use_parkpos", 1) + }; + + var set_radio = func(m) { + foreach (k; keys(mode)) { + mode[k].setBoolValue(m == k); + } + } + + var initialized = 0; + foreach (k; keys(mode)) { + if (mode[k].getType() == "NONE" or initialized) { + mode[k].setBoolValue(0); + } else { + initialized += mode[k].getBoolValue(); + } + } + if (!initialized) { + set_radio("bestrunway"); + } + + var update_info = func { + var info = airportinfo(airport_id); + setprop("/sim/gui/dialogs/airports/selected-airport/id", airport_id); + setprop("/sim/gui/dialogs/airports/selected-airport/name", info.name ~ " (" ~ airport_id ~ ")"); + setprop("/sim/gui/dialogs/airports/selected-airport/location", sprintf("%.3f / %.3f", info.lon, info.lat)); + setprop("/sim/gui/dialogs/airports/selected-airport/lon", info.lon); + setprop("/sim/gui/dialogs/airports/selected-airport/elevation-ft", 3.28 * info.elevation); + setprop("/sim/gui/dialogs/airports/selected-airport/rwy", ""); + setprop("/sim/gui/dialogs/airports/selected-airport/parkpos", ""); + + var longest_runway = 0; + var runway_string = ""; + var runways = info.runways; + + avail_runways.removeChildren("value"); + avail_parking.removeChildren("value"); + var runway_keys = sort(keys(runways), string.icmp); + var i = 0; + + foreach(var rwy; runway_keys) { + runway_string = runway_string ~ rwy ~ " "; + longest_runway = math.max(longest_runway, runways[rwy].length * 3.28); + avail_runways.getNode("value[" ~ i ~ "]", 1).setValue(rwy); + i += 1; + } + + i = 0; + foreach (var park; info.parking()) { + avail_parking.getNode("value[" ~ i ~ "]", 1).setValue(park.name); + i += 1; + } + + setprop("/sim/gui/dialogs/airports/selected-airport/longest-runway", longest_runway); + + gui.dialog_update("airports", "runway-list"); + gui.dialog_update("airports", "parking-list"); + } var listbox = func { - id = pop(split(" ", node.getValue())); - id = substr(id, 1, size(id) - 2); # strip parentheses + airport_id = pop(split(" ", airportlist.getValue())); + airport_id = substr(airport_id, 1, size(airport_id) - 2); # strip parentheses + + update_info(); } var apply = func { - setprop("/sim/presets/airport-id", id); + setprop("/sim/presets/airport-id", airport_id); setprop("/sim/presets/longitude-deg", -9999); setprop("/sim/presets/latitude-deg", -9999); setprop("/sim/presets/altitude-ft", -9999); @@ -53,79 +126,463 @@ setprop("/sim/presets/offset-azimuth-deg", 0); setprop("/sim/presets/glideslope-deg", 0); setprop("/sim/presets/heading-deg", 0); - setprop("/sim/presets/runway", ""); - setprop("/sim/presets/parkpos", ""); - } + + if (mode["bestrunway"].getBoolValue()) { + setprop("/sim/presets/runway", ""); + setprop("/sim/presets/parkpos", ""); + } else if (mode["runway"].getBoolValue()) { + setprop("/sim/presets/runway", getprop("/sim/gui/dialogs/airports/selected-airport/rwy")); + setprop("/sim/presets/parkpos", ""); + } else { + setprop("/sim/presets/runway", ""); + setprop("/sim/presets/parkpos", getprop("/sim/gui/dialogs/airports/selected-airport/parkpos")); + } + + } + + + update_info(); </open> </nasal> - - <airport-list> - <name>airport-list</name> - <pref-width>440</pref-width> - <pref-height>360</pref-height> - <halign>fill</halign> - <valign>fill</valign> - <stretch>true</stretch> - <property>/sim/gui/dialogs/airports/list</property> - <binding> - <command>dialog-apply</command> - <object-name>airport-list</object-name> - </binding> - <binding> - <command>nasal</command> - <script>listbox()</script> - </binding> - </airport-list> - + <group> <layout>hbox</layout> <default-padding>4</default-padding> + + <group> + <layout>vbox</layout> - <text> - <label>Airport:</label> - <pref-width>60</pref-width> - </text> + <group> + <layout>hbox</layout> + <default-padding>4</default-padding> - <input> - <name>input</name> - <pref-width>280</pref-width> - <halign>fill</halign> - <stretch>true</stretch> - <property>/sim/gui/dialogs/airports/list</property> - <binding> - <command>dialog-apply</command> - <object-name>input</object-name> - </binding> - <binding> - <command>dialog-update</command> - <object-name>airport-list</object-name> - </binding> - </input> + <text> + <label>Airport:</label> + </text> - <button> - <legend>Search</legend> - <binding> - <command>dialog-apply</command> - <object-name>input</object-name> - </binding> - <binding> - <command>dialog-update</command> - <object-name>airport-list</object-name> - </binding> - </button> + <input> + <name>input</name> + <pref-width>200</pref-width> + <halign>fill</halign> + <stretch>true</stretch> + <property>/sim/gui/dialogs/airports/list</property> + <binding> + <command>dialog-apply</command> + <object-name>input</object-name> + </binding> + <binding> + <command>dialog-update</command> + <object-name>airport-list</object-name> + </binding> + </input> + + <button> + <legend>Clear</legend> + <binding> + <command>property-assign</command> + <property>/sim/gui/dialogs/airports/list</property> + <value></value> + </binding> + <binding> + <command>dialog-update</command> + <object-name>input</object-name> + </binding> + <binding> + <command>dialog-update</command> + <object-name>airport-list</object-name> + </binding> + </button> + + <button> + <legend>Search</legend> + <default>true</default> + <binding> + <command>dialog-apply</command> + <object-name>input</object-name> + </binding> + <binding> + <command>dialog-update</command> + <object-name>airport-list</object-name> + </binding> + </button> + + </group> + + <airport-list> + <name>airport-list</name> + <pref-width>300</pref-width> + <pref-height>260</pref-height> + <halign>fill</halign> + <valign>fill</valign> + <stretch>true</stretch> + <property>/sim/gui/dialogs/airports/list</property> + <binding> + <command>dialog-apply</command> + <object-name>airport-list</object-name> + </binding> + <binding> + <command>nasal</command> + <script>listbox()</script> + </binding> + </airport-list> + + <hrule/> + + <group> + <layout>table</layout> + + <text> + <row>0</row> + <col>0</col> + <width>200</width> + <halign>right</halign> + <label>Airport:</label> + </text> + <text> + <row>0</row> + <col>1</col> + <colspan>3</colspan> + <halign>left</halign> + <live>true</live> + <property>/sim/gui/dialogs/airports/selected-airport/name</property> + </text> + + <text> + <row>1</row> + <col>0</col> + <halign>right</halign> + <label>Lon/Lat:</label> + </text> + <text> + <row>1</row> + <col>1</col> + <halign>left</halign> + <live>true</live> + <property>/sim/gui/dialogs/airports/selected-airport/location</property> + </text> + + <text> + <row>1</row> + <col>3</col> + <halign>right</halign> + <label>Elevation (ft):</label> + </text> + <text> + <row>1</row> + <col>4</col> + <halign>left</halign> + <live>true</live> + <format>%.0f</format> + <property>/sim/gui/dialogs/airports/selected-airport/elevation-ft</property> + </text> + + <text> + <row>2</row> + <col>0</col> + <halign>right</halign> + <label>Longest runway (ft):</label> + </text> + <text> + <row>2</row> + <col>1</col> + <halign>left</halign> + <live>true</live> + <format>%.0f</format> + <property>/sim/gui/dialogs/airports/selected-airport/longest-runway</property> + </text> + + </group> + + <hrule/> + + <group> + <layout>table</layout> + <halign>center</halign> + + <radio> + <row>2</row><col>0</col> + <property>/sim/gui/dialogs/airports/use_best_runway</property> + <live>true</live> + <binding> + <command>nasal</command> + <script>set_radio("bestrunway")</script> + </binding> + </radio> + + <text> + <row>2</row><col>1</col> + <halign>right</halign> + <label>Best runway</label> + <enable> + <property>/sim/gui/dialogs/airports/use_best_runway</property> + </enable> + </text> + <text> + <row>2</row><col>2</col> + <halign>right</halign> + <label>(based on wind)</label> + <enable> + <property>/sim/gui/dialogs/airports/use_best_runway</property> + </enable> + </text> + + <radio> + <row>3</row><col>0</col> + <property>/sim/gui/dialogs/airports/use_runway</property> + <live>true</live> + <binding> + <command>nasal</command> + <script>set_radio("runway")</script> + </binding> + </radio> + + <text> + <row>3</row><col>1</col> + <halign>right</halign> + <label>Runway:</label> + <enable> + <property>/sim/gui/dialogs/airports/use_runway</property> + </enable> + </text> + + <combo> + <name>runway-list</name> + <row>3</row><col>2</col> + <pref-width>85</pref-width> + <enable> + <property>/sim/gui/dialogs/airports/use_runway</property> + </enable> + <property>/sim/gui/dialogs/airports/selected-airport/rwy</property> + <editable>false</editable> + <properties>sim/gui/dialogs/airports/available-runways</properties> + <binding> + <command>dialog-apply</command> + <object-name>runway-list</object-name> + </binding> + </combo> + + <radio> + <row>4</row><col>0</col> + <property>/sim/gui/dialogs/airports/use_parkpos</property> + <live>true</live> + <binding> + <command>nasal</command> + <script>set_radio("parkpos")</script> + </binding> + </radio> + + <text> + <row>4</row><col>1</col> + <halign>right</halign> + <label>Parking:</label> + <enable> + <property>/sim/gui/dialogs/airports/use_parkpos</property> + </enable> + </text> + + <combo> + <name>parking-list</name> + <row>4</row><col>2</col> + <pref-width>85</pref-width> + <enable> + <property>/sim/gui/dialogs/airports/use_parkpos</property> + </enable> + <property>/sim/gui/dialogs/airports/selected-airport/parkpos</property> + <editable>false</editable> + <properties>sim/gui/dialogs/airports/available-parking</properties> + <binding> + <command>dialog-apply</command> + <object-name>parking-list</object-name> + </binding> + </combo> + </group> + + </group> + + <vrule/> + + <group> + <layout>vbox</layout> + + <canvas> + <name>map-dialog</name> + <valign>fill</valign> + <halign>fill</halign> + <stretch>true</stretch> + <pref-width>600</pref-width> + <pref-height>400</pref-height> + <view n="0">600</view> + <view n="1">400</view> + + <nasal> + + + <load><![CDATA[ + var my_canvas = canvas.get(cmdarg()); + my_canvas.setColorBackground(0.2, 0.5, 0.2, 0.5); + + var root = my_canvas.createGroup(); + + var map = root.createChild("map", "map-test") + .setTranslation(300, 200); + + var layer_runways = map.createChild("group", "runways"); + + var updateMap = func() { + var id = getprop("/sim/gui/dialogs/airports/selected-airport/id"); + + if (id != "") { + var apt = airportinfo(id); + + map.removeAllChildren(); + layer_runways = map.createChild("group", "runways"); + + var airport = canvas.AirportMap.new(apt); + airport.build(layer_runways); + + map._node.getNode("ref-lat", 1).setDoubleValue(apt.lat); + map._node.getNode("ref-lon", 1).setDoubleValue(apt.lon); + map._node.getNode("hdg", 1).setDoubleValue(0.0); + } + } + + var ranges = [0.1, 0.25, 0.5, 1, 2.5, 5]; + + var updateZoom = func() + { + var z = getprop("/sim/gui/dialogs/airports/zoom"); + if( z == nil ) + z = 0; + var zoom = ranges[4 - z]; + map._node.getNode("range", 1).setDoubleValue(zoom); + + settimer(updateZoom, 0.5, 1); + }; + + var updateRunwayHighlight = func() + { + var selected_rwy = getprop("/sim/gui/dialogs/airports/selected-airport/rwy"); + var selected_apt = getprop("/sim/gui/dialogs/airports/selected-airport/id"); + + var is_heli = substr(selected_rwy, 0, 1) == "H"; + var rw_dir = is_heli ? nil : int(substr(selected_rwy, 0, 2)); + + var rw_rec = ""; + if( rw_dir != nil ) { + rw_rec = sprintf("%02d", math.mod(rw_dir - 18, 36)); + if( size(selected_rwy) == 3 ) { + var map_rec = { + "R": "L", + "L": "R", + "C": "C" + }; + rw_rec ~= map_rec[substr(selected_rwy, 2)]; + } + } + + foreach (var apt; layer_runways.getChildren()) { + if (apt.get("id") == "apt-" ~ selected_apt) { + foreach (var rwy; apt.getChildren()) { + if ((rwy.get("id") == "runway-" ~ selected_rwy) or + (rwy.get("id") == "runway-" ~ rw_rec) ) + { + rwy.setColor(1.0,0.0,0.0); + } else { + rwy.setColor(1.0,1.0,1.0); + } + } + } + } + } + + var updateParkingHighlight = func() + { + var selected_parkpos = getprop("/sim/gui/dialogs/airports/selected-airport/parkpos"); + var selected_apt = getprop("/sim/gui/dialogs/airports/selected-airport/id"); + + foreach (var apt; layer_runways.getChildren()) { + if (apt.get("id") == "apt-" ~ selected_apt) { + foreach (var rwy; apt.getChildren()) { + if (rwy.get("id") == "parking-" ~ selected_parkpos) { + rwy.setColor(1.0,0.0,0.0); + } else { + rwy.setColor(1.0,1.0,1.0); + } + } + } + } + } + + var aptlistener = setlistener("/sim/gui/dialogs/airports/selected-airport/id", updateMap); + var rwylistener = setlistener("/sim/gui/dialogs/airports/selected-airport/rwy", updateRunwayHighlight); + var parkposlistener = setlistener("/sim/gui/dialogs/airports/selected-airport/parkpos", updateParkingHighlight); + + update_info(); + updateZoom(); + ]]> + </load> + <close> + removelistener(aptlistener); + removelistener(rwylistener); + removelistener(parkposlistener); + </close> + </nasal> + </canvas> + + <hrule/> + + <group> + <layout>hbox</layout> + + <button> + <name>zoomout</name> + <legend>-</legend> + <pref-width>22</pref-width> + <pref-height>22</pref-height> + + <binding> + <command>property-adjust</command> + <property>/sim/gui/dialogs/airports/zoom</property> + <min>0</min> + <step>-1</step> + </binding> + </button> + + <text> + <label>MMM</label> + <format>Zoom %d</format> + <property>/sim/gui/dialogs/airports/zoom</property> + <live>true</live> + </text> + + <button> + <name>zoomin</name> + <legend>+</legend> + <pref-width>22</pref-width> + <pref-height>22</pref-height> + + <binding> + <command>property-adjust</command> + <property>//sim/gui/dialogs/airports/zoom</property> + <step>1</step> + <max>4</max> + </binding> + </button> + </group> + </group> </group> - + <hrule/> - + <group> <layout>hbox</layout> <default-padding>10</default-padding> + <empty><stretch>true</stretch></empty> <button> - <legend>Apply</legend> + <legend>OK</legend> <equal>true</equal> - <default>true</default> <binding> <command>dialog-apply</command> <object-name>airport-list</object-name> @@ -137,12 +594,15 @@ <binding> <command>presets-commit</command> </binding> + <binding> + <command>dialog-close</command> + </binding> </button> <empty><stretch>true</stretch></empty> <button> - <legend>Close</legend> + <legend>Cancel</legend> <equal>true</equal> <key>Esc</key> <binding> diff --git a/gui/dialogs/checklist.xml b/gui/dialogs/checklist.xml new file mode 100644 index 000000000..b459abb65 --- /dev/null +++ b/gui/dialogs/checklist.xml @@ -0,0 +1,186 @@ +<?xml version="1.0"?> + +<PropertyList> + <name>checklist</name> + <layout>vbox</layout> + <default-padding>1</default-padding> + + <color> + <red type="float">0.41</red> + <green type="float">0.4</green> + <blue type="float">0.42</blue> + <alpha type="float">1.0</alpha> + <alpha type="float">1.0</alpha> + </color> + + <nasal> + <open> + var dlgRoot = cmdarg(); + var checklists = props.globals.getNode("/sim/checklists", 1).getChildren("checklist"); + + if (size(checklists) > 0) { + + var combo = gui.findElementByName(dlgRoot, "checklist-combo"); + var group = gui.findElementByName(dlgRoot, "checklist-table-group"); + + forindex (var idx; checklists) { + combo.getChild("value", idx, 1).setValue(checklists[idx].getNode("title", 1).getValue()); + var c = checklists[idx]; + var row = 0; + + # Set up a new table, only visible when this checklist is selected. + var table = group.getChild("group", idx, 1); + table.getNode("row", 1).setValue(0); + table.getNode("col", 1).setValue(0); + table.getNode("default-padding", 1).setValue(4); + table.getNode("layout", 1).setValue("table"); + table.getNode("valign", 1).setValue("top"); + + var vis = table.getNode("visible", 1).getNode("equals", 1); + vis.getNode("property", 1).setValue("sim/gui/dialogs/checklist/selected-checklist"); + vis.getNode("value", 1).setValue(c.getNode("title").getValue()); + + var items = c.getChildren("item"); + var txtcount = 0; + + forindex (var i; items) { + var item = items[i]; + + var t = table.getChild("text", txtcount, 1); + txtcount += 1; + + t.getNode("halign", 1).setValue("left"); + t.getNode("row", 1).setValue(row); + t.getNode("col", 1).setValue(0); + t.getNode("label", 1).setValue(item.getNode("name", 1).getValue()); + + var values = item.getChildren("value"); + + forindex (var v; values) { + var t = table.getChild("text", txtcount, 1); + txtcount += 1; + t.getNode("halign", 1).setValue("right"); + t.getNode("row", 1).setValue(row); + if (v > 0) { + # The second row of values can overlap with the + # first column if required - helps keep the + # checklist dialog as compact as possible + t.getNode("col", 1).setValue(0); + t.getNode("colspan", 1).setValue(2); + } else { + t.getNode("col", 1).setValue(1); + } + + t.getNode("label", 1).setValue(values[v].getValue()); + row = row + 1; + } + } + } + + setprop("sim/gui/dialogs/checklist/selected-checklist", + checklists[0].getNode("title").getValue()); + } else { + var group = gui.findElementByName(dlgRoot, "checklist-table-group"); + var table = group.getNode("text", 1); + table.getNode("row", 1).setValue(0); + table.getNode("col", 1).setValue(0); + table.getNode("default-padding", 1).setValue(4); + table.getNode("layout", 1).setValue("table"); + table.getNode("valign", 1).setValue("top"); + table.getNode("halign", 1).setValue("center"); + table.getNode("label", 1).setValue("No checklists exist for this aircraft"); + + } + + var setTransparency = func(updateDialog){ + var alpha = (getprop("/sim/gui/dialogs/checklist/transparent") or 0); + dlgRoot.getNode("color/alpha").setValue(1-alpha*0.3); + dlgRoot.getNode("color/red").setValue(0.41-alpha*0.2); + dlgRoot.getNode("color/green").setValue(0.4-alpha*0.2); + dlgRoot.getNode("color/blue").setValue(0.42-alpha*0.2); + var n = props.Node.new({ "dialog-name": "checklist" }); + if (updateDialog) + { + fgcommand("dialog-close", n); + fgcommand("dialog-show", n); + } + } + setTransparency(0); + + </open> + </nasal> + + <group> + <layout>hbox</layout> + <empty><stretch>1</stretch></empty> + + <text> + <label>Aircraft Checklists</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> + + <text> + <halign>right</halign> + <label>Checklist:</label> + </text> + + <combo> + <name>checklist-combo</name> + <property>/sim/gui/dialogs/checklist/selected-checklist</property> + <editable>false</editable> + <pref-width>200</pref-width> + <halign>fill</halign> + <binding> + <command>dialog-apply</command> + <object-name>checklist-combo</object-name> + </binding> + </combo> + + <empty><stretch>true</stretch></empty> + + <checkbox> + <label>Transparent</label> + <pref-width>100</pref-width> + <property>/sim/gui/dialogs/checklist/transparent</property> + <live>true</live> + <halign>right</halign> + <binding> + <command>dialog-apply</command> + </binding> + <binding> + <command>property-toggle</command> + </binding> + <binding> + <command>nasal</command> + <script>setTransparency(1);</script> + </binding> + </checkbox> + </group> + + <hrule/> + + <group> + <default-padding>4</default-padding> + <halign>fill</halign> + <layout>table</layout> + <name>checklist-table-group</name> + </group> +</PropertyList> diff --git a/gui/dialogs/environment-settings.xml b/gui/dialogs/environment-settings.xml index de8c19c9a..4a19cd95e 100644 --- a/gui/dialogs/environment-settings.xml +++ b/gui/dialogs/environment-settings.xml @@ -17,7 +17,7 @@ </empty> <text> - <label>Environmental Settings</label> + <label>Environment Settings</label> </text> <empty> @@ -226,23 +226,6 @@ </empty> <layout>hbox</layout> - <button> - <legend>OK</legend> - <binding> - <command>dialog-apply</command> - </binding> - <binding> - <command>dialog-close</command> - </binding> - </button> - - <button> - <legend>Apply</legend> - <binding> - <command>dialog-apply</command> - </binding> - </button> - <button> <legend>Close</legend> <default>true</default> diff --git a/gui/dialogs/location-on-ground.xml b/gui/dialogs/location-on-ground.xml deleted file mode 100644 index 2e58660f9..000000000 --- a/gui/dialogs/location-on-ground.xml +++ /dev/null @@ -1,303 +0,0 @@ -<?xml version="1.0"?> - -<PropertyList> - <name>location-on-ground</name> - <layout>vbox</layout> - - <group> - <layout>hbox</layout> - <empty><stretch>1</stretch></empty> - - <text> - <label>Position Aircraft On Ground</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/> - - <nasal> - <open> - var dlg = props.globals.getNode("/sim/gui/dialogs/location-on-ground", 1); - var apt = dlg.getNode("airport", 1); - var aptname = dlg.getNode("airport-name", 1); - apt.setValue(getprop("/sim/presets/airport-id")); - var rwy = dlg.getNode("runway", 1); - rwy.setValue(""); - var parkpos = dlg.getNode("parkpos", 1); - parkpos.setValue(""); - - var mode = { - runway: dlg.getNode("use_runway", 1), - bestrunway: dlg.getNode("use_best_runway", 1), - parkpos: dlg.getNode("use_parkpos", 1) - }; - - var set_radio = func(m) { - foreach (k; keys(mode)) { - mode[k].setBoolValue(m == k); - } - } - - var initialized = 0; - foreach (k; keys(mode)) { - if (mode[k].getType() == "NONE" or initialized) { - mode[k].setBoolValue(0); - } else { - initialized += mode[k].getBoolValue(); - } - } - if (!initialized) { - set_radio("bestrunway"); - } - - var runways = dlg.getNode("available-runways", 1); - var parking = dlg.getNode("available-parking", 1); - - var updateAirport = func { - var icao = apt.getValue(); - runways.removeChildren("value"); - parking.removeChildren("value"); - - var a = airportinfo(icao); - if (a == nil) { - aptname.setValue(""); - return; - } - - aptname.setValue(a.name); - var i=0; - foreach (var rwy; keys(a.runways)) { - runways.getNode("value[" ~ i ~ "]", 1).setValue(rwy); - i += 1; - } - - i = 0; - foreach (var park; a.parking()) { - parking.getNode("value[" ~ i ~ "]", 1).setValue(park.name); - i += 1; - } - - gui.dialog_update("location-on-ground"); - } - - updateAirport(); - </open> - </nasal> - - <group> - <layout>table</layout> - <halign>center</halign> - - <text> - <row>0</row><col>1</col> - <halign>right</halign> - <label>Airport:</label> - </text> - - <input> - <row>0</row><col>2</col> - <live>true</live> - <property>/sim/gui/dialogs/location-on-ground/airport</property> - <binding> - <command>dialog-apply</command> - </binding> - <binding> - <command>nasal</command> - <script> - updateAirport(); - </script> - </binding> - </input> - - <text> - <row>1</row> - <col>1</col> - <format>%s</format> - <property>/sim/gui/dialogs/location-on-ground/airport-name</property> - <live>true</live> - <stretch>true</stretch> - <halign>fill</halign> - </text> - - <radio> - <row>2</row><col>0</col> - <property>/sim/gui/dialogs/location-on-ground/use_best_runway</property> - <live>true</live> - <binding> - <command>nasal</command> - <script>set_radio("bestrunway")</script> - </binding> - </radio> - - <text> - <row>2</row><col>1</col> - <halign>right</halign> - <label>Best runway</label> - <enable> - <property>/sim/gui/dialogs/location-on-ground/use_best_runway</property> - </enable> - </text> - <text> - <row>2</row><col>2</col> - <halign>right</halign> - <label>(based on wind)</label> - <enable> - <property>/sim/gui/dialogs/location-on-ground/use_best_runway</property> - </enable> - </text> - - <radio> - <row>3</row><col>0</col> - <property>/sim/gui/dialogs/location-on-ground/use_runway</property> - <live>true</live> - <binding> - <command>nasal</command> - <script>set_radio("runway")</script> - </binding> - </radio> - - <text> - <row>3</row><col>1</col> - <halign>right</halign> - <label>Runway:</label> - <enable> - <property>/sim/gui/dialogs/location-on-ground/use_runway</property> - </enable> - </text> - - <combo> - <name>runway</name> - <row>3</row><col>2</col> - <pref-width>85</pref-width> - <enable> - <property>/sim/gui/dialogs/location-on-ground/use_runway</property> - </enable> - <property>sim/gui/dialogs/location-on-ground/runway</property> - <editable>false</editable> - <properties>sim/gui/dialogs/location-on-ground/available-runways</properties> - <binding> - <command>dialog-apply</command> - <object-name>runway</object-name> - </binding> - </combo> - - <radio> - <row>4</row><col>0</col> - <property>/sim/gui/dialogs/location-on-ground/use_parkpos</property> - <live>true</live> - <binding> - <command>nasal</command> - <script>set_radio("parkpos")</script> - </binding> - </radio> - - <text> - <row>4</row><col>1</col> - <halign>right</halign> - <label>Parking:</label> - <enable> - <property>/sim/gui/dialogs/location-on-ground/use_parkpos</property> - </enable> - </text> - - <combo> - <name>parking</name> - <row>4</row><col>2</col> - <pref-width>85</pref-width> - <enable> - <property>/sim/gui/dialogs/location-on-ground/use_parkpos</property> - </enable> - <property>/sim/gui/dialogs/location-on-ground/parkpos</property> - <editable>false</editable> - <properties>sim/gui/dialogs/location-on-ground/available-parking</properties> - <binding> - <command>dialog-apply</command> - <object-name>parking</object-name> - </binding> - </combo> - </group> - - <hrule/> - - <group> - <layout>hbox</layout> - <default-padding>10</default-padding> - <empty><stretch>true</stretch></empty> - - <button> - <legend>OK</legend> - <default>true</default> - <equal>true</equal> - <binding> - <command>dialog-apply</command> - </binding> - <enable> - <not> - <and> - <property>/sim/gui/dialogs/location-on-ground/use_runway</property> - <equals> - <property>/sim/gui/dialogs/location-on-ground/runway</property> - <value></value> - </equals> - </and> - </not> - </enable> - <binding> - <command>nasal</command> - <script> - setprop("/sim/presets/airport-id", apt.getValue()); - if (mode["bestrunway"].getBoolValue()) { - setprop("/sim/presets/runway", ""); - setprop("/sim/presets/parkpos", ""); - } else if (mode["runway"].getBoolValue()) { - setprop("/sim/presets/runway", rwy.getValue()); - setprop("/sim/presets/parkpos", ""); - } else { - setprop("/sim/presets/runway", ""); - setprop("/sim/presets/parkpos", parkpos.getValue()); - } - setprop("/sim/presets/longitude-deg", -9999); - setprop("/sim/presets/latitude-deg", -9999); - setprop("/sim/presets/altitude-ft", -9999); - setprop("/sim/presets/airspeed-kt", 0); - setprop("/sim/presets/offset-distance-nm", 0); - setprop("/sim/presets/offset-azimuth-nm", 0); - setprop("/sim/presets/glideslope-deg", 0); - setprop("/sim/presets/heading-deg", 9999); - </script> - </binding> - <binding> - <command>presets-commit</command> - </binding> - <binding> - <command>dialog-close</command> - </binding> - </button> - - <empty><stretch>true</stretch></empty> - - <button> - <legend>Cancel</legend> - <equal>true</equal> - <key>Esc</key> - <binding> - <command>dialog-close</command> - </binding> - </button> - - <empty><stretch>true</stretch></empty> - </group> -</PropertyList> diff --git a/gui/menubar.xml b/gui/menubar.xml index 2d074f404..aadd572fb 100644 --- a/gui/menubar.xml +++ b/gui/menubar.xml @@ -172,14 +172,6 @@ <menu> <name>location</name> - <item> - <name>position-on-ground</name> - <binding> - <command>dialog-show</command> - <dialog-name>location-on-ground</dialog-name> - </binding> - </item> - <item> <name>position-in-air</name> <binding> @@ -719,6 +711,14 @@ <script>gui.showHelpDialog("/sim/help")</script> </binding> </item> + + <item> + <name>aircraft-checklists</name> + <binding> + <command>dialog-show</command> + <dialog-name>checklist</dialog-name> + </binding> + </item> <item> <name>common-keys</name>