A3XX: Major ND internal improvements, now complies with IDG MFD system by Necolatis
This commit is contained in:
parent
171d12b3c1
commit
367ee4cb90
6 changed files with 155 additions and 509 deletions
|
@ -255,34 +255,6 @@
|
|||
<z-m>0.22255</z-m>
|
||||
<pitch-deg>-16.534</pitch-deg>
|
||||
</offsets>
|
||||
<condition>
|
||||
<and>
|
||||
<greater-than-equals>
|
||||
<property>systems/electrical/bus/ac1</property>
|
||||
<value>110</value>
|
||||
</greater-than-equals>
|
||||
<greater-than-equals>
|
||||
<property>systems/electrical/bus/ac2</property>
|
||||
<value>110</value>
|
||||
</greater-than-equals>
|
||||
<not-equals>
|
||||
<property>modes/cpt-du-xfr</property>
|
||||
<value>2</value>
|
||||
</not-equals>
|
||||
<not-equals>
|
||||
<property>systems/electrical/ac1-src</property>
|
||||
<value>RAT</value>
|
||||
</not-equals>
|
||||
<not-equals>
|
||||
<property>systems/electrical/ac2-src</property>
|
||||
<value>RAT</value>
|
||||
</not-equals>
|
||||
<greater-than>
|
||||
<property>controls/lighting/DU/du2</property>
|
||||
<value>0</value>
|
||||
</greater-than>
|
||||
</and>
|
||||
</condition>
|
||||
</model>
|
||||
|
||||
<animation>
|
||||
|
@ -306,34 +278,6 @@
|
|||
<z-m>0.22255</z-m>
|
||||
<pitch-deg>-16.534</pitch-deg>
|
||||
</offsets>
|
||||
<condition>
|
||||
<and>
|
||||
<greater-than-equals>
|
||||
<property>systems/electrical/bus/ac1</property>
|
||||
<value>110</value>
|
||||
</greater-than-equals>
|
||||
<greater-than-equals>
|
||||
<property>systems/electrical/bus/ac2</property>
|
||||
<value>110</value>
|
||||
</greater-than-equals>
|
||||
<not-equals>
|
||||
<property>modes/fo-du-xfr</property>
|
||||
<value>2</value>
|
||||
</not-equals>
|
||||
<not-equals>
|
||||
<property>systems/electrical/ac1-src</property>
|
||||
<value>RAT</value>
|
||||
</not-equals>
|
||||
<not-equals>
|
||||
<property>systems/electrical/ac2-src</property>
|
||||
<value>RAT</value>
|
||||
</not-equals>
|
||||
<greater-than>
|
||||
<property>controls/lighting/DU/du5</property>
|
||||
<value>0</value>
|
||||
</greater-than>
|
||||
</and>
|
||||
</condition>
|
||||
</model>
|
||||
|
||||
<animation>
|
||||
|
|
|
@ -25,11 +25,6 @@ var SymbolCache32x32 = canvas.SymbolCache32x32;
|
|||
var SymbolCache = canvas.SymbolCache;
|
||||
var Text = canvas.Text;
|
||||
|
||||
|
||||
if(version < 3.2){
|
||||
io.include('canvas_compat.nas');
|
||||
}
|
||||
|
||||
io.include('ND_config.nas');
|
||||
io.include('framework/canvas.nas');
|
||||
io.include('framework/navdisplay.nas');
|
||||
|
|
|
@ -1,66 +1,141 @@
|
|||
# A3XX ND Canvas
|
||||
# Joshua Davidson (it0uchpods) and Nikolai V. Chr.
|
||||
|
||||
##############################################
|
||||
# Copyright (c) Joshua Davidson (it0uchpods) #
|
||||
##############################################
|
||||
|
||||
io.include('A3XX_ND.nas');
|
||||
|
||||
io.include('A3XX_ND_drivers.nas');
|
||||
canvas.NDStyles['Airbus'].options.defaults.route_driver = A3XXRouteDriver.new();
|
||||
|
||||
var nd_nd = nil;
|
||||
var nd_nd2 = nil;
|
||||
|
||||
var nd_display = {};
|
||||
|
||||
setlistener("sim/signals/fdm-initialized", func() {
|
||||
var ND = canvas.NavDisplay;
|
||||
|
||||
var myCockpit_switches = {
|
||||
# symbolic alias : relative property (as used in bindings), initial value, type
|
||||
'toggle_range': {path: '/inputs/range-nm', value:40, type:'INT'},
|
||||
'toggle_weather': {path: '/inputs/wxr', value:0, type:'BOOL'},
|
||||
'toggle_airports': {path: '/inputs/arpt', value:0, type:'BOOL'},
|
||||
'toggle_ndb': {path: '/inputs/NDB', value:0, type:'BOOL'},
|
||||
'toggle_stations': {path: '/inputs/sta', value:0, type:'BOOL'},
|
||||
'toggle_vor': {path: '/inputs/VORD', value:0, type:'BOOL'},
|
||||
'toggle_dme': {path: '/inputs/DME', value:0, type:'BOOL'},
|
||||
'toggle_cstr': {path: '/inputs/CSTR', value:0, type:'BOOL'},
|
||||
'toggle_waypoints': {path: '/inputs/wpt', value:0, type:'BOOL'},
|
||||
'toggle_position': {path: '/inputs/pos', value:0, type:'BOOL'},
|
||||
'toggle_data': {path: '/inputs/data',value:0, type:'BOOL'},
|
||||
'toggle_terrain': {path: '/inputs/terr',value:0, type:'BOOL'},
|
||||
'toggle_traffic': {path: '/inputs/tfc',value:0, type:'BOOL'},
|
||||
'toggle_centered': {path: '/inputs/nd-centered',value:0, type:'BOOL'},
|
||||
'toggle_lh_vor_adf': {path: '/input/lh-vor-adf',value:0, type:'INT'},
|
||||
'toggle_rh_vor_adf': {path: '/input/rh-vor-adf',value:0, type:'INT'},
|
||||
'toggle_display_mode': {path: '/nd/canvas-display-mode', value:'NAV', type:'STRING'},
|
||||
'toggle_display_type': {path: '/mfd/display-type', value:'LCD', type:'STRING'},
|
||||
'toggle_true_north': {path: '/mfd/true-north', value:0, type:'BOOL'},
|
||||
'toggle_track_heading': {path: '/trk-selected', value:0, type:'BOOL'},
|
||||
'toggle_wpt_idx': {path: '/inputs/plan-wpt-index', value: -1, type: 'INT'},
|
||||
'toggle_plan_loop': {path: '/nd/plan-mode-loop', value: 0, type: 'INT'},
|
||||
'toggle_weather_live': {path: '/mfd/wxr-live-enabled', value: 0, type: 'BOOL'},
|
||||
'toggle_chrono': {path: '/inputs/CHRONO', value: 0, type: 'INT'},
|
||||
'toggle_xtrk_error': {path: '/mfd/xtrk-error', value: 0, type: 'BOOL'},
|
||||
'toggle_trk_line': {path: '/mfd/trk-line', value: 0, type: 'BOOL'},
|
||||
# add new switches here
|
||||
};
|
||||
var myCockpit_switches = {
|
||||
'toggle_range': {path: '/inputs/range-nm', value:40, type:'INT'},
|
||||
'toggle_weather': {path: '/inputs/wxr', value:0, type:'BOOL'},
|
||||
'toggle_airports': {path: '/inputs/arpt', value:0, type:'BOOL'},
|
||||
'toggle_ndb': {path: '/inputs/NDB', value:0, type:'BOOL'},
|
||||
'toggle_stations': {path: '/inputs/sta', value:0, type:'BOOL'},
|
||||
'toggle_vor': {path: '/inputs/VORD', value:0, type:'BOOL'},
|
||||
'toggle_dme': {path: '/inputs/DME', value:0, type:'BOOL'},
|
||||
'toggle_cstr': {path: '/inputs/CSTR', value:0, type:'BOOL'},
|
||||
'toggle_waypoints': {path: '/inputs/wpt', value:0, type:'BOOL'},
|
||||
'toggle_position': {path: '/inputs/pos', value:0, type:'BOOL'},
|
||||
'toggle_data': {path: '/inputs/data',value:0, type:'BOOL'},
|
||||
'toggle_terrain': {path: '/inputs/terr',value:0, type:'BOOL'},
|
||||
'toggle_traffic': {path: '/inputs/tfc',value:0, type:'BOOL'},
|
||||
'toggle_centered': {path: '/inputs/nd-centered',value:0, type:'BOOL'},
|
||||
'toggle_lh_vor_adf': {path: '/input/lh-vor-adf',value:0, type:'INT'},
|
||||
'toggle_rh_vor_adf': {path: '/input/rh-vor-adf',value:0, type:'INT'},
|
||||
'toggle_display_mode': {path: '/nd/canvas-display-mode', value:'NAV', type:'STRING'},
|
||||
'toggle_display_type': {path: '/nd/display-type', value:'LCD', type:'STRING'},
|
||||
'toggle_true_north': {path: '/nd/true-north', value:0, type:'BOOL'},
|
||||
'toggle_track_heading': {path: '/trk-selected', value:0, type:'BOOL'},
|
||||
'toggle_wpt_idx': {path: '/inputs/plan-wpt-index', value: -1, type: 'INT'},
|
||||
'toggle_plan_loop': {path: '/nd/plan-mode-loop', value: 0, type: 'INT'},
|
||||
'toggle_weather_live': {path: '/nd/wxr-live-enabled', value: 0, type: 'BOOL'},
|
||||
'toggle_chrono': {path: '/inputs/CHRONO', value: 0, type: 'INT'},
|
||||
'toggle_xtrk_error': {path: '/nd/xtrk-error', value: 0, type: 'BOOL'},
|
||||
'toggle_trk_line': {path: '/nd/trk-line', value: 0, type: 'BOOL'},
|
||||
};
|
||||
|
||||
# get a handle to the NavDisplay in canvas namespace (for now), see $FG_ROOT/Nasal/canvas/map/navdisplay.mfd
|
||||
var ND = canvas.NavDisplay;
|
||||
var canvas_nd_base = {
|
||||
init: func(canvas_group, file = nil) {
|
||||
var font_mapper = func(family, weight) {
|
||||
return "LiberationFonts/LiberationSans-Regular.ttf";
|
||||
};
|
||||
|
||||
## TODO: We want to support multiple independent ND instances here!
|
||||
# foreach(var pilot; var pilots = [ {name:'cpt', path:'instrumentation/efis',
|
||||
# name:'fo', path:'instrumentation[1]/efis']) {
|
||||
if (file != nil) {
|
||||
canvas.parsesvg(canvas_group, file, {'font-mapper': font_mapper});
|
||||
|
||||
var svg_keys = me.getKeys();
|
||||
foreach(var key; svg_keys) {
|
||||
me[key] = canvas_group.getElementById(key);
|
||||
}
|
||||
}
|
||||
me.page = canvas_group;
|
||||
|
||||
##
|
||||
# set up a new ND instance, under 'instrumentation/efis' and use the
|
||||
# myCockpit_switches hash to map control properties
|
||||
var NDCpt = ND.new("instrumentation/efis", myCockpit_switches, 'Airbus');
|
||||
var NDFo = ND.new("instrumentation/efis[1]", myCockpit_switches, 'Airbus');
|
||||
return me;
|
||||
},
|
||||
getKeys: func() {
|
||||
return [];
|
||||
},
|
||||
update: func() {
|
||||
if (getprop("/systems/electrical/bus/ac1") >= 110 and getprop("/systems/electrical/ac1-src") != "RAT" and getprop("/systems/electrical/bus/ac2") >= 110 and getprop("/systems/electrical/ac2-src") != "RAT" and getprop("/controls/lighting/DU/du2") > 0) {
|
||||
nd_nd.page.show();
|
||||
nd_nd.NDCpt.update();
|
||||
} else {
|
||||
nd_nd.page.hide();
|
||||
}
|
||||
if (getprop("/systems/electrical/bus/ac1") >= 110 and getprop("/systems/electrical/ac1-src") != "RAT" and getprop("/systems/electrical/bus/ac2") >= 110 and getprop("/systems/electrical/ac2-src") != "RAT" and getprop("/controls/lighting/DU/du5") > 0) {
|
||||
nd_nd2.page.show();
|
||||
nd_nd2.NDFo.update();
|
||||
} else {
|
||||
nd_nd2.page.hide();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var canvas_nd_nd = {
|
||||
new: func(canvas_group) {
|
||||
var m = {parents: [canvas_nd_nd, canvas_nd_base]};
|
||||
m.init(canvas_group);
|
||||
|
||||
# here we make the ND:
|
||||
me.NDCpt = ND.new("instrumentation/efis", myCockpit_switches, 'Airbus');
|
||||
me.NDCpt.newMFD(canvas_group);
|
||||
me.NDCpt.update();
|
||||
|
||||
return m;
|
||||
},
|
||||
getKeys: func() {
|
||||
return [];
|
||||
},
|
||||
update: func() {
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
var canvas_nd_nd_r = {
|
||||
new: func(canvas_group) {
|
||||
var m = {parents: [canvas_nd_nd_r, canvas_nd_base]};
|
||||
m.init(canvas_group);
|
||||
|
||||
# here we make the ND:
|
||||
me.NDFo = ND.new("instrumentation/efis[1]", myCockpit_switches, 'Airbus');
|
||||
me.NDFo.newMFD(canvas_group);
|
||||
me.NDFo.update();
|
||||
|
||||
return m;
|
||||
},
|
||||
getKeys: func() {
|
||||
return [];
|
||||
},
|
||||
update: func() {
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
setlistener("sim/signals/fdm-initialized", func {
|
||||
setprop("instrumentation/efis[0]/inputs/plan-wpt-index", -1);
|
||||
setprop("instrumentation/efis[1]/inputs/plan-wpt-index", -1);
|
||||
|
||||
nd_display.main = canvas.new({
|
||||
"name": "ND",
|
||||
"name": "ND1",
|
||||
"size": [1024, 1024],
|
||||
"view": [1024, 1024],
|
||||
"mipmapping": 1
|
||||
});
|
||||
|
||||
nd_display.right = canvas.new({
|
||||
"name": "ND",
|
||||
"name": "ND2",
|
||||
"size": [1024, 1024],
|
||||
"view": [1024, 1024],
|
||||
"mipmapping": 1
|
||||
|
@ -68,77 +143,68 @@ setlistener("sim/signals/fdm-initialized", func() {
|
|||
|
||||
nd_display.main.addPlacement({"node": "ND.screen"});
|
||||
nd_display.right.addPlacement({"node": "ND_R.screen"});
|
||||
var group_nd = nd_display.main.createGroup();
|
||||
var group_nd2 = nd_display.right.createGroup();
|
||||
|
||||
var group = nd_display.main.createGroup();
|
||||
NDCpt.newMFD(group);
|
||||
NDCpt.update();
|
||||
nd_nd = canvas_nd_nd.new(group_nd);
|
||||
nd_nd2 = canvas_nd_nd_r.new(group_nd2);
|
||||
|
||||
var group_r = nd_display.right.createGroup();
|
||||
NDFo.newMFD(group_r);
|
||||
NDFo.update();
|
||||
nd_update.start();
|
||||
});
|
||||
|
||||
setprop("instrumentation/efis/inputs/plan-wpt-index", -1);
|
||||
setprop("instrumentation/efis[1]/inputs/plan-wpt-index", -1);
|
||||
var nd_update = maketimer(0.05, func {
|
||||
canvas_nd_base.update();
|
||||
});
|
||||
|
||||
print("ND Canvas Initialized!");
|
||||
}); # fdm-initialized listener callback
|
||||
|
||||
for(i = 0; i < 2; i = i + 1){
|
||||
setlistener("instrumentation/efis["~i~"]/nd/display-mode", func(node){
|
||||
for (i = 0; i < 2; i = i + 1 ) {
|
||||
setlistener("/instrumentation/efis["~i~"]/nd/display-mode", func(node) {
|
||||
var par = node.getParent().getParent();
|
||||
var idx = par.getIndex();
|
||||
var canvas_mode = "instrumentation/efis["~idx~"]/nd/canvas-display-mode";
|
||||
var nd_centered = "instrumentation/efis["~idx~"]/inputs/nd-centered";
|
||||
var mode = getprop("instrumentation/efis["~idx~"]/nd/display-mode");
|
||||
var cvs_mode = 'NAV';
|
||||
var canvas_mode = "/instrumentation/efis["~idx~"]/nd/canvas-display-mode";
|
||||
var nd_centered = "/instrumentation/efis["~idx~"]/inputs/nd-centered";
|
||||
var mode = getprop("/instrumentation/efis["~idx~"]/nd/display-mode");
|
||||
var cvs_mode = "NAV";
|
||||
var centered = 1;
|
||||
if(mode == 'ILS'){
|
||||
cvs_mode = 'APP';
|
||||
if (mode == "ILS") {
|
||||
cvs_mode = "APP";
|
||||
}
|
||||
elsif(mode == 'VOR') {
|
||||
cvs_mode = 'VOR';
|
||||
else if (mode == "VOR") {
|
||||
cvs_mode = "VOR";
|
||||
}
|
||||
elsif(mode == 'NAV'){
|
||||
cvs_mode = 'MAP';
|
||||
else if (mode == "NAV"){
|
||||
cvs_mode = "MAP";
|
||||
}
|
||||
elsif(mode == 'ARC'){
|
||||
cvs_mode = 'MAP';
|
||||
else if (mode == "ARC"){
|
||||
cvs_mode = "MAP";
|
||||
centered = 0;
|
||||
}
|
||||
elsif(mode == 'PLAN'){
|
||||
cvs_mode = 'PLAN';
|
||||
else if (mode == "PLAN"){
|
||||
cvs_mode = "PLAN";
|
||||
}
|
||||
setprop(canvas_mode, cvs_mode);
|
||||
setprop(nd_centered, centered);
|
||||
});
|
||||
}
|
||||
|
||||
#setlistener("/instrumentation/mcdu/f-pln/disp/first", func{
|
||||
#var first = getprop("/instrumentation/mcdu/f-pln/disp/first");
|
||||
#if(typeof(first) == 'nil') first = -1;
|
||||
#if(getprop('autopilot/route-manager/route/num') == 0) first = -1;
|
||||
#setprop("instrumentation/efis/inputs/plan-wpt-index", first);
|
||||
#setprop("instrumentation/efis[1]/inputs/plan-wpt-index", first);
|
||||
#});
|
||||
|
||||
setlistener('/instrumentation/efis/nd/terrain-on-nd', func{
|
||||
var terr_on_hd = getprop('/instrumentation/efis/nd/terrain-on-nd');
|
||||
setlistener("/instrumentation/efis[0]/nd/terrain-on-nd", func{
|
||||
var terr_on_hd = getprop("/instrumentation/efis[0]/nd/terrain-on-nd");
|
||||
var alpha = 1;
|
||||
if(terr_on_hd) alpha = 0.5;
|
||||
if (terr_on_hd) {
|
||||
alpha = 0.5;
|
||||
}
|
||||
nd_display.main.setColorBackground(0,0,0,alpha);
|
||||
});
|
||||
|
||||
setlistener('/flight-management/control/capture-leg', func(n){
|
||||
setlistener("/flight-management/control/capture-leg", func(n) {
|
||||
var capture_leg = n.getValue();
|
||||
setprop("instrumentation/efis/mfd/xtrk-error", capture_leg);
|
||||
setprop("instrumentation/efis[1]/mfd/xtrk-error", capture_leg);
|
||||
setprop("instrumentation/efis/mfd/trk-line", capture_leg);
|
||||
setprop("instrumentation/efis[1]/mfd/trk-line", capture_leg);
|
||||
setprop("instrumentation/efis[0]/nd/xtrk-error", capture_leg);
|
||||
setprop("instrumentation/efis[1]/nd/xtrk-error", capture_leg);
|
||||
setprop("instrumentation/efis[0]/nd/trk-line", capture_leg);
|
||||
setprop("instrumentation/efis[1]/nd/trk-line", capture_leg);
|
||||
}, 0, 0);
|
||||
|
||||
var showNd = func(nd = nil) {
|
||||
if(nd == nil) nd = 'main';
|
||||
# The optional second arguments enables creating a window decoration
|
||||
var dlg = canvas.Window.new([512, 512], "dialog");
|
||||
dlg.setCanvas( nd_display[nd] );
|
||||
dlg.setCanvas(nd_display[nd]);
|
||||
}
|
||||
|
|
|
@ -1,355 +0,0 @@
|
|||
var _MP_dbg_lvl = "info";
|
||||
#var _MP_dbg_lvl = "alert";
|
||||
#io.include('Nasal/canvas/MapStructure.nas');
|
||||
|
||||
var makedie = func(prefix) func(msg) globals.die(prefix~" "~msg);
|
||||
|
||||
var __die = makedie("MapStructure");
|
||||
|
||||
var _arg2valarray = func
|
||||
{
|
||||
var ret = arg;
|
||||
while ( typeof(ret) == "vector"
|
||||
and size(ret) == 1 and typeof(ret[0]) == "vector" )
|
||||
ret = ret[0];
|
||||
return ret;
|
||||
}
|
||||
|
||||
var assert_m = func(hash, member)
|
||||
if (!contains(hash, member))
|
||||
die("required field not found: '"~member~"'");
|
||||
var assert_ms = func(hash, members...)
|
||||
foreach (var m; members)
|
||||
if (m != nil) assert_m(hash, m);
|
||||
|
||||
##
|
||||
# Combine a specific hash with a default hash, e.g. for
|
||||
# options/df_options and style/df_style in a SymbolLayer.
|
||||
#
|
||||
var default_hash = func(opt, df) {
|
||||
if (opt != nil and typeof(opt)=='hash') {
|
||||
if (df != nil and opt != df and !isa(opt, df)) {
|
||||
if (contains(opt, "parents"))
|
||||
opt.parents ~= [df];
|
||||
else
|
||||
opt.parents = [df];
|
||||
}
|
||||
return opt;
|
||||
} else return df;
|
||||
}
|
||||
|
||||
|
||||
var try_aux_method = func(obj, method_name) {
|
||||
var name = "<test%"~id(caller(0)[0])~">";
|
||||
call(compile("obj."~method_name~"()", name), nil, var err=[]); # try...
|
||||
#debug.dump(err);
|
||||
if (size(err)) # ... and either leave caght or rethrow
|
||||
if (err[1] != name)
|
||||
die(err[0]);
|
||||
}
|
||||
|
||||
Group.setColor = func(r,g,b, excl = nil){
|
||||
var children = me.getChildren();
|
||||
foreach(var e; children){
|
||||
var do_skip = 0;
|
||||
if(excl != nil){
|
||||
foreach(var cl; excl){
|
||||
if(isa(e, cl)){
|
||||
do_skip = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!do_skip)
|
||||
e.setColor(r,g,b);
|
||||
}
|
||||
}
|
||||
|
||||
Symbol._new = func(m) {
|
||||
#m.style = m.layer.style;
|
||||
#m.options = m.layer.options;
|
||||
if (m.controller != nil) {
|
||||
temp = m.controller.new(m,m.model);
|
||||
if (temp != nil)
|
||||
m.controller = temp;
|
||||
}
|
||||
else __die("Symbol._new(): default controller not found");
|
||||
};
|
||||
|
||||
Symbol.del = func() {
|
||||
if (me.controller != nil)
|
||||
me.controller.del(me, me.model);
|
||||
try_aux_method(me.model, "del");
|
||||
};
|
||||
|
||||
SymbolLayer.findsym = func(model, del=0) {
|
||||
forindex (var i; me.list) {
|
||||
var e = me.list[i];
|
||||
#print("List["~i~"]");
|
||||
#debug.dump(e);
|
||||
if (Symbol.Controller.equals(e.model, model)) {
|
||||
if (del) {
|
||||
# Remove this element from the list
|
||||
# TODO: maybe C function for this? extend pop() to accept index?
|
||||
var prev = subvec(me.list, 0, i);
|
||||
var next = subvec(me.list, i+1);
|
||||
me.list = prev~next;
|
||||
#return 1;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
};
|
||||
|
||||
# to add support for additional ghosts, just append them to the vector below, possibly at runtime:
|
||||
var supported_ghosts = ['positioned','Navaid','Fix','flightplan-leg','FGAirport'];
|
||||
var is_positioned_ghost = func(obj) {
|
||||
var gt = ghosttype(obj);
|
||||
foreach(var ghost; supported_ghosts) {
|
||||
if (gt == ghost) return 1; # supported ghost was found
|
||||
}
|
||||
return 0; # not a known/supported ghost
|
||||
};
|
||||
|
||||
Symbol.Controller.equals = func(l, r, p=nil) {
|
||||
if (l == r) return 1;
|
||||
if (p == nil) {
|
||||
var ret = Symbol.Controller.equals(l, r, l);
|
||||
if (ret != nil) return ret;
|
||||
if (contains(l, "parents")) {
|
||||
foreach (var p; l.parents) {
|
||||
var ret = Symbol.Controller.equals(l, r, p);
|
||||
if (ret != nil) return ret;
|
||||
}
|
||||
}
|
||||
die("Symbol.Controller: no suitable equals() found! Of type: "~typeof(l));
|
||||
} else {
|
||||
if (typeof(p) == 'ghost')
|
||||
if ( is_positioned_ghost(p) )
|
||||
return l.id == r.id;
|
||||
else
|
||||
die("Symbol.Controller: bad/unsupported ghost of type '"~ghosttype(l)~"' (see MapStructure.nas Symbol.Controller.getpos() to add new ghosts)");
|
||||
if (typeof(p) == 'hash'){
|
||||
# Somewhat arbitrary convention:
|
||||
# * l.equals(r) -- instance method, i.e. uses "me" and "arg[0]"
|
||||
# * parent._equals(l,r) -- class method, i.e. uses "arg[0]" and "arg[1]"
|
||||
if (contains(p, "equals"))
|
||||
return l.equals(r);
|
||||
}
|
||||
if (contains(p, "_equals"))
|
||||
return p._equals(l,r);
|
||||
}
|
||||
return nil; # scio correctum est
|
||||
};
|
||||
|
||||
canvas.LineSymbol = {
|
||||
parents:[Symbol],
|
||||
element_id: nil,
|
||||
needs_update: 1,
|
||||
# Static/singleton:
|
||||
makeinstance: func(name, hash) {
|
||||
if (!isa(hash, LineSymbol))
|
||||
die("LineSymbol: OOP error");
|
||||
return Symbol.add(name, hash);
|
||||
},
|
||||
# For the instances returned from makeinstance:
|
||||
new: func(group, model, controller=nil) {
|
||||
if (me == nil) die("Need me reference for LineSymbol.new()");
|
||||
if (typeof(model) != 'vector') die("LineSymbol.new(): need a vector of points");
|
||||
var m = {
|
||||
parents: [me],
|
||||
group: group,
|
||||
#layer: layer,
|
||||
model: model,
|
||||
controller: controller == nil ? me.df_controller : controller,
|
||||
element: group.createChild(
|
||||
"path", me.element_id
|
||||
),
|
||||
};
|
||||
append(m.parents, m.element);
|
||||
Symbol._new(m);
|
||||
|
||||
m.init();
|
||||
return m;
|
||||
},
|
||||
# Non-static:
|
||||
draw: func() {
|
||||
if (!me.needs_update) return;
|
||||
#printlog(_MP_dbg_lvl, "redrawing a LineSymbol "~me.layer.type);
|
||||
me.element.reset();
|
||||
var cmds = [];
|
||||
var coords = [];
|
||||
var cmd = Path.VG_MOVE_TO;
|
||||
foreach (var m; me.model) {
|
||||
var (lat,lon) = me.controller.getpos(m);
|
||||
append(coords,"N"~lat);
|
||||
append(coords,"E"~lon);
|
||||
append(cmds,cmd);
|
||||
cmd = Path.VG_LINE_TO;
|
||||
}
|
||||
me.element.setDataGeo(cmds, coords);
|
||||
me.element.update(); # this doesn't help with flickering, it seems
|
||||
},
|
||||
del: func() {
|
||||
printlog(_MP_dbg_lvl, "LineSymbol.del()");
|
||||
me.deinit();
|
||||
call(Symbol.del, nil, me);
|
||||
me.element.del();
|
||||
},
|
||||
# Default wrappers:
|
||||
init: func() me.draw(),
|
||||
deinit: func(),
|
||||
update: func() {
|
||||
if (me.controller != nil) {
|
||||
if (!me.controller.update(me, me.model)) return;
|
||||
elsif (!me.controller.isVisible(me.model)) {
|
||||
me.element.hide();
|
||||
return;
|
||||
}
|
||||
} else
|
||||
me.element.show();
|
||||
me.draw();
|
||||
},
|
||||
}; # of LineSymbol
|
||||
|
||||
Path.addSegmentGeo = func(cmd, coords...)
|
||||
{
|
||||
var coords = _arg2valarray(coords);
|
||||
var num_coords = me.num_coords[cmd];
|
||||
if( size(coords) != num_coords )
|
||||
debug.warn
|
||||
(
|
||||
"Invalid number of arguments (expected " ~ num_coords ~ ")"
|
||||
);
|
||||
else
|
||||
{
|
||||
me.setInt("cmd[" ~ (me._last_cmd += 1) ~ "]", cmd);
|
||||
for(var i = 0; i < num_coords; i += 1)
|
||||
me.set("coord-geo[" ~ (me._last_coord += 1) ~ "]", coords[i]);
|
||||
}
|
||||
|
||||
return me;
|
||||
}
|
||||
|
||||
Path.arcGeo = func(cmd, rx,ry,unk,lat,lon){
|
||||
if(cmd < 18 and cmd > 24){
|
||||
debug.warn("Invalid command " ~ cmd);
|
||||
return me;
|
||||
}
|
||||
else
|
||||
{
|
||||
me.setInt("cmd[" ~ (me._last_cmd += 1) ~ "]", cmd);
|
||||
#for(var i = 0; i < num_coords; i += 1)
|
||||
me.setDouble("coord[" ~ (me._last_coord += 1) ~ "]", rx);
|
||||
me.setDouble("coord[" ~ (me._last_coord += 1) ~ "]", ry);
|
||||
me.setDouble("coord[" ~ (me._last_coord += 1) ~ "]", unk);
|
||||
me.setDouble("coord-geo[N" ~ (me._last_coord += 1) ~ "]", lat);
|
||||
me.setDouble("coord-geo[E" ~ (me._last_coord += 1) ~ "]", lat);
|
||||
}
|
||||
|
||||
return me;
|
||||
}
|
||||
|
||||
SymbolLayer.onRemoved = func(model) {
|
||||
#print('onRemoved');
|
||||
#debug.dump(model);
|
||||
var sym = me.findsym(model, 1);
|
||||
if (sym == nil) die("model not found");
|
||||
#print(typeof(model.del));
|
||||
#call(func sym.del, nil, var err = []);
|
||||
sym.del();
|
||||
#print('ERR CHK');
|
||||
#debug.dump(err);
|
||||
# ignore errors
|
||||
# TODO: ignore only missing member del() errors? and only from the above line?
|
||||
# Note: die(err[0]) rethrows it; die(err[0]~"") does not.
|
||||
}
|
||||
|
||||
Map.addLayer = func(factory, type_arg=nil, priority=nil){
|
||||
if(contains(me.layers, type_arg))
|
||||
print("addLayer() warning: overwriting existing layer:", type_arg);
|
||||
|
||||
# print("addLayer():", type_arg);
|
||||
|
||||
# Argument handling
|
||||
if (type_arg != nil)
|
||||
var type = factory.get(type_arg);
|
||||
else var type = factory;
|
||||
|
||||
var the_layer = me.layers[type_arg]= type.new(me);
|
||||
the_layer.map = me;
|
||||
if (priority == nil)
|
||||
priority = type.df_priority;
|
||||
if (priority != nil)
|
||||
me.layers[type_arg].setInt("z-index", priority);
|
||||
return me;
|
||||
}
|
||||
|
||||
Map.getLat = func me.get("ref-lat");
|
||||
Map.getLon = func me.get("ref-lon");
|
||||
Map.getHdg = func me.get("hdg");
|
||||
Map.getAlt = func me.get("altitude");
|
||||
Map.getRange = func me.get("range");
|
||||
Map.getLatLon = func [me.get("ref-lat"), me.get("ref-lon")];
|
||||
Map.getPosCoord = func {
|
||||
var (lat, lon) = (me.get("ref-lat"),
|
||||
me.get("ref-lon"));
|
||||
var alt = me.get("altitude");
|
||||
if (lat == nil or lon == nil) {
|
||||
if (contains(me, "coord")) {
|
||||
debug.warn("canvas.Map: lost ref-lat and/or ref-lon source");
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
if (!contains(me, "coord")) {
|
||||
me.coord = geo.Coord.new();
|
||||
var m = me;
|
||||
me.coord.update = func m.getPosCoord();
|
||||
}
|
||||
me.coord.set_latlon(lat,lon,alt or 0);
|
||||
return me.coord;
|
||||
}
|
||||
|
||||
SymbolLayer.new = func(group, controller=nil) {
|
||||
var m = {
|
||||
parents: [me],
|
||||
map: group,
|
||||
group: group.createChild("group", me.id), # TODO: the id is not properly set, but would be useful for debugging purposes (VOR, FIXES, NDB etc)
|
||||
list: [],
|
||||
};
|
||||
m.searcher = geo.PositionedSearch.new(me.searchCmd, me.onAdded, me.onRemoved, m);
|
||||
# FIXME: hack to expose type of layer:
|
||||
if (caller(1)[1] == Map.addLayer) {
|
||||
var this_type = caller(1)[0].type_arg;
|
||||
if (this_type != nil)
|
||||
m.group.set("symbol-layer-type", this_type);
|
||||
}
|
||||
if (controller == nil)
|
||||
#controller = SymbolLayer.Controller.new(me.type, m);
|
||||
controller = me.df_controller;
|
||||
assert_m(controller, "parents");
|
||||
if (controller.parents[0] == SymbolLayer.Controller)
|
||||
controller = controller.new(m);
|
||||
assert_m(controller, "parents");
|
||||
assert_m(controller.parents[0], "parents");
|
||||
if (controller.parents[0].parents[0] != SymbolLayer.Controller)
|
||||
die("OOP error");
|
||||
m.controller = controller;
|
||||
m.update();
|
||||
return m;
|
||||
};
|
||||
|
||||
canvas.SingleSymbolLayer = {
|
||||
parents: [SymbolLayer]
|
||||
};
|
||||
|
||||
canvas.MultiSymbolLayer = {
|
||||
parents: [SymbolLayer]
|
||||
};
|
||||
|
||||
canvas.NavaidSymbolLayer = {
|
||||
parents: [canvas.MultiSymbolLayer]
|
||||
};
|
||||
|
||||
|
|
@ -31,7 +31,6 @@ canvas.NavDisplay.newMFD = func(canvas_group, parent=nil, nd_options=nil, update
|
|||
me.range_dependant_layers = [];
|
||||
me.always_update_layers = {};
|
||||
me.inited = 1;
|
||||
me.update_timer = maketimer(update_time, func me.update() );
|
||||
me.nd = canvas_group;
|
||||
me.canvas_handle = parent;
|
||||
me.df_options = nil;
|
||||
|
@ -227,9 +226,6 @@ canvas.NavDisplay.newMFD = func(canvas_group, parent=nil, nd_options=nil, update
|
|||
|
||||
#print("navdisplay.mfd:ND layer setup completed");
|
||||
|
||||
# start the update timer, which makes sure that the update() will be called
|
||||
me.update_timer.start();
|
||||
|
||||
# TODO: move this to RTE.lcontroller ?
|
||||
me.listen("/autopilot/route-manager/current-wp", func(activeWp) {
|
||||
canvas.updatewp( activeWp.getValue() );
|
||||
|
|
|
@ -1 +1 @@
|
|||
4019
|
||||
4020
|
Reference in a new issue