route-manager vbox true 0.0); var isFL = dlg.getNode("cruise-is-flight-level", 1); isFL.setBoolValue(routem.getNode('cruise/flight-level').getValue() > 0); var sel_index = func { return int(selection.getValue()); } var clear = func { flightplan().cleanPlan(); selection.setIntValue(-1); } var insert = func { var insertIndex = sel_index(); if (insertIndex < 0) { var msg = "Select the waypoint after which new waypoints should be added"; setprop("sim/messages/copilot", msg); return; } # Input is a list of space-separated waypoint specifications var argv = split(" ", input.getValue()); foreach (var arg; argv) { # When argument is not empty (caused by multiple space # separators) insert *after* waypoint if (size(arg) > 0) { insertIndex += 1; cmd.setValue("@insert" ~ insertIndex ~ ":" ~ arg); } } input.setValue(""); selection.setValue(insertIndex); gui.dialog_update("route-manager"); } var remove = func { flightplan().deleteWP(sel_index()); } var route = func { var fp = flightplan(); var from = fp.getWP(sel_index() - 1); var to = fp.getWP(sel_index()); if ((from == nil ) or (to == nil)) { printlog('info', 'unable to route, invalid start ad end points'); return; } var route = airwaysRoute(from, to); fp.insertWaypoints(route, sel_index()); } var jump_to = func { flightplan().current = sel_index(); } var load_route = func(path) { routem.getNode("file-path", 1).setValue(path.getValue()); cmd.setValue("@load"); gui.dialog_update("route-manager"); } var save_route = func(path) { routem.getNode("file-path", 1).setValue(path.getValue()); cmd.setValue("@save"); gui.dialog_update("route-manager"); } var defaultDirInFileSelector = getprop("/sim/fg-home") ~ "/Export"; var file_selector = gui.FileSelector.new( callback: load_route, title: "Load flight-plan", button: "Load", dir: defaultDirInFileSelector, dotfiles: 1); var save_selector = gui.FileSelector.new( callback: save_route, title: "Save flight-plan", button: "Save", dir: defaultDirInFileSelector, dotfiles: 1); var activate_fp = func { fgcommand("activate-flightplan", props.Node.new({"activate": 1})); } var departureRunways = dlg.getNode("departure-runways", 1); var destRunways = dlg.getNode("destination-runways", 1); var sids = dlg.getNode("sids", 1); var stars = dlg.getNode("stars", 1); var approaches = dlg.getNode("approaches", 1); var updateRunways = func { departureRunways.removeChildren("value"); destRunways.removeChildren("value"); var apt = flightplan().departure; if (apt != nil) { var i=0; foreach (var rwy; keys(apt.runways)) { departureRunways.getNode("value[" ~ i ~ "]", 1).setValue(rwy); i += 1; } } apt = flightplan().destination; if (apt != nil) { var i=0; foreach (var rwy; keys(apt.runways)) { destRunways.getNode("value[" ~ i ~ "]", 1).setValue(rwy); i += 1; } } gui.dialog_update("route-manager"); } var updateSIDs = func { sids.removeChildren("value"); var apt = flightplan().departure; var rwy = flightplan().departure_runway; if (apt == nil) { return; } if (size(apt.sids(rwy)) == 0) { sids.getNode("value[0]", 1).setValue("DEFAULT"); sids.getNode("value[1]", 1).setValue("(none)"); gui.dialog_update("route-manager", "sid"); return; } var i=1; sids.getNode("value[0]", 1).setValue("(none)"); foreach (var s; apt.sids(rwy)) { var sid = apt.getSid(s); var transVec = sid.transitions; if (size(transVec) > 0) { # list each transition of the SID foreach (var trans; transVec) { sids.getNode("value[" ~ i ~ "]", 1).setValue(s ~ "-" ~ trans); i += 1; } } else { # no transitions defined, simple case sids.getNode("value[" ~ i ~ "]", 1).setValue(s); i += 1; } } gui.dialog_update("route-manager", "sid"); } var updateSTARs = func { stars.removeChildren("value"); var apt = flightplan().destination; var rwy = flightplan().destination_runway; if (apt == nil or apt.stars(rwy) == nil) { return; } var i=1; stars.getNode("value[0]", 1).setValue("(none)"); foreach (var s; apt.stars(rwy)) { var star = apt.getStar(s); var transVec = star.transitions; if (size(transVec) > 0) { # list each transition of the STAR foreach (var trans; transVec) { stars.getNode("value[" ~ i ~ "]", 1).setValue(s ~ "-" ~ trans); i += 1; } } else { # no transitions defined, simple case stars.getNode("value[" ~ i ~ "]", 1).setValue(s); i += 1; } } gui.dialog_update("route-manager", "star"); } var updateApproaches = func { approaches.removeChildren("value"); var apt = flightplan().destination; var rwy = flightplan().destination_runway; if (apt == nil) { return; } if (size(apt.getApproachList(rwy)) == 0) { approaches.getNode("value[0]", 1).setValue("DEFAULT"); approaches.getNode("value[1]", 1).setValue("(none)"); gui.dialog_update("route-manager", "approach"); return; } var i=1; approaches.getNode("value[0]", 1).setValue("(none)"); foreach (var s; apt.getApproachList(rwy)) { approaches.getNode("value[" ~ i ~ "]", 1).setValue(s); i += 1; } gui.dialog_update("route-manager", "approach"); } var initPosition = func { var routeActive = routem.getNode("active").getValue(); if (routeActive) return; # FIXME have user waypoints check var fp = flightplan(); var airborne = getprop('/gear/gear[0]/wow') == 0; if (airborne) { printlog('info', 'route-manager dialog, init in-air, clearing departure settings'); fp.departure = nil; return; } # we're on the ground, find the nearest airport to start from if (fp.departure == nil) { var apts = findAirportsWithinRange(25.0); if (size(apts) == 0) return; # no airports nearby fp.departure = apts[0]; # use the closest one } if (fp.departure_runway == nil) { printlog('info', 'selecting departure runway'); var rwy = fp.departure.findBestRunwayForPos( geo.aircraft_position() ); fp.departure_runway = rwy; } } # initialise departure values based on current position initPosition(); updateRunways(); updateSIDs(); updateSTARs(); updateApproaches(); ]]> file_selector.del(); save_selector.del(); hbox 1 1 table 0 0 right 0 1 left departure-airport 70 /autopilot/route-manager/departure/airport true dialog-apply departure-airport nasal 0 2 %s /autopilot/route-manager/departure/name true true fill 0 3 right 0 4 left departure-runway /autopilot/route-manager/departure/runway false /sim/gui/dialogs/route-manager/departure-runways dialog-apply departure-runway nasal 0 7 right 0 8 left sid /autopilot/route-manager/departure/sid false /sim/gui/dialogs/route-manager/sids dialog-apply sid 1 0 right 1 1 left 70 destination-airport /autopilot/route-manager/destination/airport true dialog-apply destination-airport nasal 1 2 true 200 %s /autopilot/route-manager/destination/name true fill 1 3 right 1 4 left destination-runway /autopilot/route-manager/destination/runway false /sim/gui/dialogs/route-manager/destination-runways dialog-apply destination-runway nasal 1 5 right 1 6 120 left approach /autopilot/route-manager/destination/approach false /sim/gui/dialogs/route-manager/approaches dialog-apply approach 1 7 right 1 8 left star /autopilot/route-manager/destination/star false /sim/gui/dialogs/route-manager/stars dialog-apply star 2 0 right 2 1 left alternate-airport 70 /autopilot/route-manager/alternate/airport true dialog-apply alternate-airport 2 2 %s /autopilot/route-manager/alternate/name true true fill table right 0 cruise-speed true left 50 1 /sim/gui/dialogs/route-manager/cruise-is-mach /autopilot/route-manager/cruise/speed-kts dialog-apply cruise-speed cruise-speed-mach true left 50 /autopilot/route-manager/cruise/mach dialog-apply cruise-speed-mach /sim/gui/dialogs/route-manager/cruise-is-mach 1 cruise-speed-type-check left /sim/gui/dialogs/route-manager/cruise-is-mach dialog-apply cruise-speed-type-check 2 right 3 cruise-alt true left true 100 /autopilot/route-manager/cruise/altitude-ft dialog-apply cruise-alt /sim/gui/dialogs/route-manager/cruise-is-flight-level 4 cruise-alt-fl true left true 100 /autopilot/route-manager/cruise/flight-level dialog-apply cruise-alt-fl /sim/gui/dialogs/route-manager/cruise-is-flight-level 4 cruise-alt-type-check left /sim/gui/dialogs/route-manager/cruise-is-flight-level dialog-apply cruise-alt-type-check 5 hbox 2 Target: %s /autopilot/route-manager/wp[0]/id true Dist: %.2f nm /autopilot/route-manager/wp[0]/dist true ETA: %s /autopilot/route-manager/wp[0]/eta true hbox 2 true fill fill list fill fill true 150 /sim/gui/dialogs/route-manager/selection dialog-apply list hbox 4 input fill true 220 /sim/gui/dialogs/route-manager/input 1 0.7 0.7 0.7 hbox fill 8 true