1
0
Fork 0

Airbus style for MapStructure/navdisplay

This commit is contained in:
artix 2015-05-30 20:20:59 +02:00
parent d04903ddb1
commit a6fe054946
44 changed files with 6717 additions and 182 deletions

105
Nasal/canvas/MapDrivers.nas Normal file
View file

@ -0,0 +1,105 @@
var RouteDriver = {
new: func(){
var m = {
parents: [RouteDriver],
};
m.init();
return m;
},
init: func(){
me.update();
},
update: func(){
me.flightplan = flightplan();
},
getNumberOfFlightPlans: func(){1},
getFlightPlanType: func(fpNum){'current'},
getFlightPlan: func(fpNum){me.flightplan},
getPlanSize: func(fpNum){me.flightplan.getPlanSize()},
getWP: func(fpNum, idx){me.flightplan.getWP(idx)},
getPlanModeWP: func(plan_wp_idx){me.flightplan.getWP(plan_wp_idx)},
hasDiscontinuity: func(fpNum, wptID){0},
getListeners: func(){[]},
shouldUpdate: func 1
};
var MultiRouteDriver = {
parents: [RouteDriver],
new: func(){
var m = {
parents: [MultiRouteDriver],
_flightplans: [],
currentFlightPlan: 0
};
m.init();
return m;
},
addFlightPlan: func(type, plan){
append(me._flightplans, {
type: type,
flightplan: plan
});
},
removeFlightPlanAtIndex: func(idx){
var sz = size(me._flightplans);
if(idx < sz){
if(sz == 1)
me._flightplans = [];
elsif(sz == 2 and idx == 0)
me._flightplans = [me._flightplans[1]];
elsif(sz == 2 and idx == 1)
pop(me._flightplans);
else {
var subv_l = subvec(me._flightplans, 0, idx);
var subv_r = subvec(me._flightplans, idx + 1);
me._flightplans = subv_l ~ subv_r;
}
}
me.triggerSignal('fp-added');
},
removeFlightPlanOfType: func(type){
var new_vec = [];
foreach(var fp; me._flightplans){
if(fp['type'] != type)
append(new_vec, fp);
}
me._flightplans = new_vec;
me.triggerSignal('fp-removed');
},
getNumberOfFlightPlans: func(){
size(me._flightplans);
},
getFlightPlanType: func(fpNum){
if(fpNum >= size(me._flightplans)) return nil;
var fp = me._flightplans[fpNum];
return fp.type;
},
getFlightPlan: func(fpNum){
if(fpNum >= size(me._flightplans)) return nil;
return me._flightplans[fpNum];
},
getPlanSize: func(fpNum){
if(fpNum >= size(me._flightplans)) return 0;
return me._flightplans[fpNum].getPlanSize();
},
getWP: func(fpNum, idx){
if(fpNum >= size(me._flightplans)) return nil;
var fp = me._flightplans[fpNum].getPlanSize();
return fp.getWP(idx);
},
getPlanModeWP: func(idx){
if(me.currentFlightPlan >= size(me._flightplans)) return nil;
var fp = me._flightplans[me.currentFlightPlan];
return fp.getWP(idx);
},
triggerSignal: func(signal){
setprop(me.signalPath(signal));
},
signalPath: func(signal){
'autopilot/route-manager/signals/rd-'~ signal;
},
getListeners: func(){[
me.getSignal('fp-added'),
me.getSignal('fp-removed')
]}
};

View file

@ -261,6 +261,17 @@ var hashdup = func(_,rkeys=nil) {
var h={}; var k=rkeys!=nil?rkeys:members(_); var h={}; var k=rkeys!=nil?rkeys:members(_);
foreach (var k;k) h[tryintern(k)]=member(_,k); h foreach (var k;k) h[tryintern(k)]=member(_,k); h
} }
var opt_member = func(h,k) {
if (contains(h, k)) return h[k];
if (contains(h, "parents")) {
var _=h.parents;
for (var i=0;i<size(_);i+=1){
var v = opt_member(_[i], k);
if (v != nil) return v;
}
}
return nil;
}
var member = func(h,k) { var member = func(h,k) {
if (contains(h, k)) return h[k]; if (contains(h, k)) return h[k];
if (contains(h, "parents")) { if (contains(h, "parents")) {
@ -434,6 +445,118 @@ var Symbol = {
t.setColor(color); t.setColor(color);
return t; return t;
}, },
# Helper method that can be used to create a formatted String using
# values extracted from the current model.
#
# SYNOPSIS:
#
# symbol.formattedString(format, model_property_names)
#
# Arguments:
# - format: string
# - model_property_names: a vector of strings representing the model
# property names to be used as arguments
#
# EXAMPLE:
#
# var label = waypoint.formattedString('Waypoint %s: lat %.4f, lng %.4f', [model.id, model.lat, model.lon]);
formattedString: func(frmt, model_props){
if(me.model == nil) return frmt;
var args = [];
foreach(var prop; model_props){
if(contains(me.model, prop)){
var val = me.model[prop];
var tp = typeof(val);
if(tp != 'scalar'){
val = '';
#printlog("warn", "formattedString: invalid type for "~prop~" (" ~ tp ~ ")");
} else {
append(args, val);
}
}
}
return call(sprintf, [frmt] ~ args);
},
# Wrapper method for accessing options. It allows to pass a default value
# if the requested option is not defined.
#
# EXAMPLE:
# var ok = (contains(me.options, 'enabled') ? me.options.enabled : 0);
# var ok = me.getOption('enabled', 0);
getOption: func(name, default = nil){
var opt = me.options;
if(opt == nil)
opt = me.layer.options;
if(opt == nil) return default;
var val = opt_member(opt, name);
if(val == nil) return default;
return val;
},
# Wrapper method for accessing style. It allows to pass a default value
# if the requested style is not defined.
# It also automatically resolves style properties when they're defined as
# functions, by calling the corresponding function using the 'me' context
#
# EXAMPLE:
#
# me.style = {
# color: [1,1,1],
# line_color: func(){
# me.model.tuned ? [0,0,1] : [1,1,1]
# }
# }
# var color = me.getStyle('color'); # --> [1,1,1]
# me.model.tuned = 1;
# var line_color = me.getStyle('line_color'); # --> [0,0,1]
# var txt_color = me.getStyle('text_color', [1,1,1]); # --> [1,1,1]
getStyle: func(name, default = nil){
var st = me.style;
if(st == nil)
st = me.layer.style;
if(st == nil) return default;
var val = opt_member(st, name);
if(typeof(val) == 'func'){
val = (call(val,[],me));
}
if(val == nil) return default;
return val;
},
getLabelFromModel: func(default_val = nil){
if(me.model == nil) return default_val;
if(default_val == nil and contains(me.model, 'id'))
default_val = me.model.id;
var label_content = me.getOption('label_content');
if(label_content == nil) return default_val;
if(typeof(label_content) == 'scalar')
label_content = [label_content];
var format_s = me.getOption('label_format');
var label = '';
if(format_s == nil){
format_s = "%s";
}
return me.formattedString(format_s, label_content);
},
# Executes callback function specified by the first argument with
# variable arguments. The callback is executed within the 'me' context.
# Callbacks must be defined inside the options hash.
#
# EXAMPLE:
#
# me.options = {
# dump_callback: func(){
# print('Waypoint '~ me.model.id);
# }
# }
# me.callback('dump');
callback: func(name, args...){
name = name ~'_callback';
var f = me.getOption(name);
if(typeof(f) == 'func'){
return call(f, args, me);
}
}
}; # of Symbol }; # of Symbol
@ -611,6 +734,7 @@ var DotSym = {
} else } else
me.element.show(); me.element.show();
me.draw(); me.draw();
if(me.getOption('disable_position', 0)) return;
var pos = me.controller.getpos(me.model); var pos = me.controller.getpos(me.model);
if (size(pos) == 2) if (size(pos) == 2)
pos~=[nil]; # fall through pos~=[nil]; # fall through
@ -632,17 +756,27 @@ var SVGSymbol = {
element_type: "group", element_type: "group",
cacheable: 0, cacheable: 0,
init: func() { init: func() {
me.callback('init_before');
var opt_path = me.getStyle('svg_path');
if(opt_path != nil)
me.svg_path = opt_path;
if (!me.cacheable) { if (!me.cacheable) {
canvas.parsesvg(me.element, me.svg_path); if(me.svg_path != nil and me.svg_path != '')
canvas.parsesvg(me.element, me.svg_path);
# hack: # hack:
if (var scale = me.layer.style['scale_factor']) if (var scale = me.layer.style['scale_factor'])
me.element.setScale(scale); me.element.setScale(scale);
if ((var transl = me.layer.style['translate']) != nil)
me.element.setTranslation(transl);
} else { } else {
__die("cacheable not implemented yet!"); __die("cacheable not implemented yet!");
} }
me.callback('init_after');
me.draw(); me.draw();
}, },
draw: func, draw: func{
me.callback('draw');
},
}; # of SVGSymbol }; # of SVGSymbol
@ -685,7 +819,13 @@ var LineSymbol = {
# For the instances returned from makeinstance: # For the instances returned from makeinstance:
new: func(group, layer, model, controller=nil) { new: func(group, layer, model, controller=nil) {
if (me == nil) __die("Need me reference for LineSymbol.new()"); if (me == nil) __die("Need me reference for LineSymbol.new()");
if (typeof(model) != 'vector') __die("LineSymbol.new(): need a vector of points"); if (typeof(model) != 'vector') {
if(typeof(model) == 'hash'){
if(!contains(model, 'path'))
__die("LineSymbol.new(): model hash requires path");
}
else __die("LineSymbol.new(): need a vector of points or a hash");
}
var m = { var m = {
parents: [me], parents: [me],
group: group, group: group,
@ -705,19 +845,32 @@ var LineSymbol = {
# Non-static: # Non-static:
draw: func() { draw: func() {
if (!me.needs_update) return; if (!me.needs_update) return;
me.callback('draw_before');
printlog(_MP_dbg_lvl, "redrawing a LineSymbol "~me.layer.type); printlog(_MP_dbg_lvl, "redrawing a LineSymbol "~me.layer.type);
me.element.reset(); me.element.reset();
var cmds = []; var cmds = [];
var coords = []; var coords = [];
var cmd = canvas.Path.VG_MOVE_TO; var cmd = canvas.Path.VG_MOVE_TO;
foreach (var m; me.model) { var path = me.model;
var (lat,lon) = me.controller.getpos(m); if(typeof(path) == 'hash'){
append(coords,"N"~lat); path = me.model.path;
append(coords,"E"~lon); if(path == nil)
append(cmds,cmd); cmd = canvas.Path.VG_LINE_TO; __die("LineSymbol model requires a 'path' member (vector)");
}
foreach (var m; path) {
if(size(keys(m)) >= 2){
var (lat,lon) = me.controller.getpos(m);
append(coords,"N"~lat);
append(coords,"E"~lon);
append(cmds,cmd);
cmd = canvas.Path.VG_LINE_TO;
} else {
cmd = canvas.Path.VG_MOVE_TO;
}
} }
me.element.setDataGeo(cmds, coords); me.element.setDataGeo(cmds, coords);
me.element.update(); # this doesn't help with flickering, it seems me.element.update(); # this doesn't help with flickering, it seems
me.callback('draw_after');
}, },
del: func() { del: func() {
printlog(_MP_dbg_lvl, "LineSymbol.del()"); printlog(_MP_dbg_lvl, "LineSymbol.del()");
@ -791,6 +944,24 @@ var SymbolLayer = {
assert_m(controller.parents[0], "parents"); assert_m(controller.parents[0], "parents");
if (controller.parents[0].parents[0] != SymbolLayer.Controller) if (controller.parents[0].parents[0] != SymbolLayer.Controller)
__die("MultiSymbolLayer: OOP error"); __die("MultiSymbolLayer: OOP error");
if(options != nil){
var listeners = opt_member(controller, 'listeners');
var listen = opt_member(options, 'listen');
if (listen != nil and listeners != nil){
var listen_tp = typeof(listen);
if(listen_tp != 'vector' and listen_tp != 'scalar')
__die("Options 'listen' cannot be a "~ listen_tp);
if(typeof(listen) == 'scalar')
listen = [listen];
foreach(var node_name; listen){
var node = opt_member(options, node_name);
if(node == nil)
node = node_name;
append(controller.listeners,
setlistener(node, func call(m.update,[],m),0,0));
}
}
}
m.controller = controller; m.controller = controller;
}, },
# For instances: # For instances:
@ -1010,6 +1181,67 @@ var SingleSymbolLayer = {
# set up a cache for 32x32 symbols (initialized below in load_MapStructure) # set up a cache for 32x32 symbols (initialized below in load_MapStructure)
var SymbolCache32x32 = nil; var SymbolCache32x32 = nil;
var MapStructure = {
# Generalized load methods used to load various symbols, layer controllers,...
loadFile : func(file, name) {
if (name == nil)
var name = split("/", file)[-1];
var code = io.readfile(file);
var code = call(func compile(code, file), [code], var err=[]);
if (size(err)) {
if (substr(err[0], 0, 12) == "Parse error:") { # hack around Nasal feature
var e = split(" at line ", err[0]);
if (size(e) == 2)
err[0] = string.join("", [e[0], "\n at ", file, ", line ", e[1], "\n "]);
}
for (var i = 1; (var c = caller(i)) != nil; i += 1)
err ~= subvec(c, 2, 2);
debug.printerror(err);
return;
}
#code=bind(
call(code, nil, nil, var hash = {});
# validate
var url = ' http://wiki.flightgear.org/MapStructure#';
# TODO: these rules should be extended for all main files lcontroller/scontroller and symbol
var checks = [
{ extension:'symbol', symbol:'update', type:'func', error:' update() must not be overridden:', id:300},
# Sorry, this one doesn't work with the new LineSymbol
# { extension:'symbol', symbol:'draw', type:'func', required:1, error:' symbol files need to export a draw() routine:', id:301},
# Sorry, this one doesn't work with the new SingleSymbolLayer
# { extension:'lcontroller', symbol:'searchCmd', type:'func', required:1, error:' lcontroller without searchCmd method:', id:100},
];
var makeurl = func(scope, id) url ~ scope ~ ':' ~ id;
var bailout = func(file, message, scope, id) __die(file~message~"\n"~makeurl(scope,id) );
var current_ext = split('.', file)[-1];
foreach(var check; checks) {
# check if we have any rules matching the current file extension
if (current_ext == check.extension) {
# check for fields that must not be overridden
if (check['error'] != nil and
hash[check.symbol]!=nil and !check['required'] and
typeof(hash[check.symbol])==check.type ) {
bailout(file,check.error,check.extension,check.id);
}
# check for required fields
if (check['required'] != nil and
hash[check.symbol]==nil and
typeof( hash[check.symbol]) != check.type) {
bailout(file,check.error,check.extension,check.id);
}
}
}
return hash;
}
};
var load_MapStructure = func { var load_MapStructure = func {
canvas.load_MapStructure = func; # disable any subsequent attempt to load canvas.load_MapStructure = func; # disable any subsequent attempt to load
@ -1063,62 +1295,6 @@ var load_MapStructure = func {
####### LOAD FILES ####### ####### LOAD FILES #######
(func { (func {
var FG_ROOT = getprop("/sim/fg-root"); var FG_ROOT = getprop("/sim/fg-root");
var load = func(file, name) {
if (name == nil)
var name = split("/", file)[-1];
var code = io.readfile(file);
var code = call(func compile(code, file), [code], var err=[]);
if (size(err)) {
if (substr(err[0], 0, 12) == "Parse error:") { # hack around Nasal feature
var e = split(" at line ", err[0]);
if (size(e) == 2)
err[0] = string.join("", [e[0], "\n at ", file, ", line ", e[1], "\n "]);
}
for (var i = 1; (var c = caller(i)) != nil; i += 1)
err ~= subvec(c, 2, 2);
debug.printerror(err);
return;
}
#code=bind(
call(code, nil, nil, var hash = {});
# validate
var url = ' http://wiki.flightgear.org/MapStructure#';
# TODO: these rules should be extended for all main files lcontroller/scontroller and symbol
var checks = [
{ extension:'symbol', symbol:'update', type:'func', error:' update() must not be overridden:', id:300},
# Sorry, this one doesn't work with the new LineSymbol
# { extension:'symbol', symbol:'draw', type:'func', required:1, error:' symbol files need to export a draw() routine:', id:301},
# Sorry, this one doesn't work with the new SingleSymbolLayer
# { extension:'lcontroller', symbol:'searchCmd', type:'func', required:1, error:' lcontroller without searchCmd method:', id:100},
];
var makeurl = func(scope, id) url ~ scope ~ ':' ~ id;
var bailout = func(file, message, scope, id) __die(file~message~"\n"~makeurl(scope,id) );
var current_ext = split('.', file)[-1];
foreach(var check; checks) {
# check if we have any rules matching the current file extension
if (current_ext == check.extension) {
# check for fields that must not be overridden
if (check['error'] != nil and
hash[check.symbol]!=nil and !check['required'] and
typeof(hash[check.symbol])==check.type ) {
bailout(file,check.error,check.extension,check.id);
}
# check for required fields
if (check['required'] != nil and
hash[check.symbol]==nil and
typeof( hash[check.symbol]) != check.type) {
bailout(file,check.error,check.extension,check.id);
}
}
}
return hash;
};
# sets up a shared symbol cache, which will be used by all MapStructure maps and layers # sets up a shared symbol cache, which will be used by all MapStructure maps and layers
canvas.SymbolCache32x32 = SymbolCache.new(1024,32); canvas.SymbolCache32x32 = SymbolCache.new(1024,32);
@ -1146,7 +1322,7 @@ var load_MapStructure = func {
foreach (var d; dep_names) { foreach (var d; dep_names) {
foreach (var f; deps[d]) { foreach (var f; deps[d]) {
var name = split(".", f)[0]; var name = split(".", f)[0];
load(contents_dir~f, name); MapStructure.loadFile(contents_dir~f, name);
} }
} }
})(); })();

View file

@ -360,6 +360,46 @@ var Group = {
return children; return children;
}, },
# Recursively get all children of class specified by first param
getChildrenOfType: func(type, array = nil){
var children = array;
if(children == nil)
children = [];
var my_children = me.getChildren();
if(typeof(type) != 'vector')
type = [type];
foreach(var c; my_children){
foreach(var t; type){
if(isa(c, t)){
append(children, c);
}
}
if(isa(c, canvas.Group)){
c.getChildrenOfType(type, children);
}
}
return children;
},
# Set color to children of type Path and Text. It is possible to optionally
# specify which types of children should be affected by passing a vector as
# the last agrument, ie. my_group.setColor(1,1,1,[Path]);
setColor: func(){
var color = arg;
var types = [Path, Text];
var arg_c = size(color);
if(arg_c > 1 and typeof(color[-1]) == 'vector'){
types = color[-1];
color = subvec(color, 0, arg_c - 1);
}
var children = me.getChildrenOfType(types);
if(typeof(color) == 'vector'){
var first = color[0];
if(typeof(first) == 'vector')
color = first;
}
foreach(var c; children)
c.setColor(color);
},
# Get first child with given id (breadth-first search) # Get first child with given id (breadth-first search)
# #
# @note Use with care as it can take several miliseconds (for me eg. ~2ms). # @note Use with care as it can take several miliseconds (for me eg. ~2ms).
@ -460,11 +500,12 @@ var Map = {
return me; return me;
}, },
addLayer: func(factory, type_arg=nil, priority=nil, style=nil, options=nil, visible=1) addLayer: func(factory, type_arg=nil, priority=nil, style=nil, opts=nil, visible=1)
{ {
if(contains(me.layers, type_arg)) if(contains(me.layers, type_arg))
printlog("warn", "addLayer() warning: overwriting existing layer:", type_arg); printlog("warn", "addLayer() warning: overwriting existing layer:", type_arg);
var options = opts;
# Argument handling # Argument handling
if (type_arg != nil) { if (type_arg != nil) {
var layer = factory.new(type:type_arg, group:me, map:me, style:style, options:options, visible:visible); var layer = factory.new(type:type_arg, group:me, map:me, style:style, options:options, visible:visible);

View file

@ -9,9 +9,9 @@ SymbolLayer.add(name, {
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_options: { # default configuration options df_options: { # default configuration options
active_node: "/autopilot/route-manager/active", fplan_active: "/autopilot/route-manager/active",
vnav_node: "/autopilot/route-manager/vnav/", vnav_node: "/autopilot/route-manager/vnav/",
types: ["tc", "td", "sc", "ed"], types: ["tc", "td", "ec", "ed","sc", "sd"],
} }
}); });
var new = func(layer) { var new = func(layer) {
@ -22,7 +22,8 @@ var new = func(layer) {
listeners: [], listeners: [],
}; };
layer.searcher._equals = func(a,b) a.getName() == b.getName(); layer.searcher._equals = func(a,b) a.getName() == b.getName();
append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() )); append(m.listeners, setlistener(layer.options.fplan_active,
func m.layer.update() ));
m.addVisibilityListener(); m.addVisibilityListener();
return m; return m;

View file

@ -13,20 +13,39 @@ var element_type = "group";
var init = func { var init = func {
var name = me.model.getName(); var name = me.model.getName();
var disptext = chr(string.toupper(name[0]))~"/"~chr(string.toupper(name[1])); var svg_path = me.getOption('svg_path');
var radius = me.style.radius; if (svg_path != nil) {
me.element.createChild("path") var grp = me.element.createChild("group", name);
if(typeof(svg_path) == 'scalar'){
canvas.parsesvg(me.element, svg_path);
}
else{ #need hash
if(!contains(svg_path, name))
die('ALT-Profile: no SVG Path for '~ name);
var path = svg_path[name];
canvas.parsesvg(me.element, path);
}
} else {
var disptext = chr(string.toupper(name[0]))~"/"~chr(string.toupper(name[1]));
var radius = me.style.radius;
me.element.createChild("path")
.setStrokeLineWidth(5) .setStrokeLineWidth(5)
.moveTo(-radius, 0) .moveTo(-radius, 0)
.arcLargeCW(radius, radius, 0, 2 * radius, 0) .arcLargeCW(radius, radius, 0, 2 * radius, 0)
.arcLargeCW(radius, radius, 0, -2 * radius, 0) .arcLargeCW(radius, radius, 0, -2 * radius, 0)
.setColor(0.195,0.96,0.097); .setColor(0.195,0.96,0.097);
me.element.createChild("text") me.element.createChild("text")
.setDrawMode( canvas.Text.TEXT ) .setDrawMode( canvas.Text.TEXT )
.setText(disptext) .setText(disptext)
.setFont("LiberationFonts/LiberationSans-Regular.ttf") .setFont("LiberationFonts/LiberationSans-Regular.ttf")
.setFontSize(28) .setFontSize(28)
.setTranslation(25,35) .setTranslation(25,35)
.setColor(0.195,0.96,0.097); .setColor(0.195,0.96,0.097);
}
me.callback('init_after');
}
var draw = func{
me.callback('draw');
} }

View file

@ -13,9 +13,13 @@ SymbolLayer.add(name, {
# N.B.: if used, this SymbolLayer should be updated every frame # N.B.: if used, this SymbolLayer should be updated every frame
# by the Map Controller, or as often as the position is changed. # by the Map Controller, or as often as the position is changed.
var new = func(layer) { var new = func(layer) {
var __model = layer.map.getPosCoord();
#debug.dump(typeof(layer.options));
if(layer.options != nil and contains(layer.options, 'model'))
__model = layer.options.model;
return { return {
parents: [__self__], parents: [__self__],
_model: layer.map.getPosCoord(), _model: __model,
}; };
}; };
var del = func; var del = func;

View file

@ -15,6 +15,8 @@ SymbolLayer.add(name, {
color_default: [0,0.6,0.85], color_default: [0,0.6,0.85],
label_font_color:[0,0.6,0.85], label_font_color:[0,0.6,0.85],
label_font_size: 28, label_font_size: 28,
text_offset: [17,35],
svg_path: nil
}, },
}); });

View file

@ -11,23 +11,34 @@ var text_apt = nil;
# add the draw routine from airports-nd.draw here # add the draw routine from airports-nd.draw here
var init = func { var init = func {
var icon_apt = me.element.createChild("path", name ~ " icon" ) var icon_apt = nil;
var style = me.layer.style;
var svg_path = style.svg_path;
if (svg_path != nil) {
canvas.parsesvg(me.element, svg_path);
} else {
icon_apt = me.element.createChild("path", name ~ " icon" )
.moveTo(-17,0) .moveTo(-17,0)
.arcSmallCW(17,17,0,34,0) .arcSmallCW(17,17,0,34,0)
.arcSmallCW(17,17,0,-34,0) .arcSmallCW(17,17,0,-34,0)
.close() .close()
.setColor(me.layer.style.color_default) .setColor(style.color_default)
.setStrokeLineWidth(me.layer.style.line_width); .setStrokeLineWidth(style.line_width);
}
var text = me.getLabelFromModel();
if(text == nil){
text = me.model.id;
}
var text_apt = me.element.createChild("text", name ~ " label") var text_apt = me.element.createChild("text", name ~ " label")
.setDrawMode( canvas.Text.TEXT ) .setDrawMode( canvas.Text.TEXT )
.setTranslation(17,35) .setTranslation(style.text_offset)
.setText(me.model.id) .setText(text)
.setFont("LiberationFonts/LiberationSans-Regular.ttf") .setFont("LiberationFonts/LiberationSans-Regular.ttf")
.setColor(me.layer.style.label_font_color) .setColor(style.label_font_color)
.setFontSize(me.layer.style.label_font_size); .setFontSize(style.label_font_size);
# FIXME: this applies scale to the whole group, better do this separately for each element? # FIXME: this applies scale to the whole group, better do this separately for each element?
me.element.setScale(me.layer.style.scale_factor); me.element.setScale(style.scale_factor);
}; };
var draw = func; var draw = func;

View file

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="87.8438"
height="108.844"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
sodipodi:docname="boeingAirplane.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.9598"
inkscape:cx="19.8149"
inkscape:cy="54.088"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1366"
inkscape:window-height="716"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-364.652,-344.745)">
<g
id="airplane"
transform="translate(364.652,346.745)"
inkscape:label="#g3781">
<path
id="apl_path"
d="m 44.0787,102 0,-90 M 84,38 l -78,0 M 63,90 l -38,0"
style="fill:none;stroke:#f2f235;stroke-width:3.9685px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:connector-curvature="0" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 142 KiB

View file

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="48px"
height="48px"
id="svg3090"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="Nuovo documento 10">
<defs
id="defs3092" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8.6118945"
inkscape:cx="24.13482"
inkscape:cy="21.929539"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1256"
inkscape:window-height="677"
inkscape:window-x="20"
inkscape:window-y="20"
inkscape:window-maximized="0" />
<metadata
id="metadata3095">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g3120"
transform="translate(0.81282928,-0.3483554)">
<g
id="g3110">
<rect
style="fill:#af0063;stroke:#af0063"
id="rect3106"
width="31.128778"
height="1.1431472"
x="7.7382278"
y="-24.606066"
transform="scale(1,-1)" />
<rect
transform="matrix(0,-1,-1,0,0,0)"
y="-23.874191"
x="-39.598881"
height="1.1431472"
width="31.128778"
id="rect3108"
style="fill:#af0063;stroke:#af0063" />
</g>
<g
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,-10.169774,23.516978)"
id="g3114">
<rect
transform="scale(1,-1)"
y="-24.606066"
x="7.7382278"
height="1.1431472"
width="31.128778"
id="rect3116"
style="fill:#af0063;stroke:#af0063" />
<rect
style="fill:#af0063;stroke:#af0063"
id="rect3118"
width="31.128778"
height="1.1431472"
x="-39.598881"
y="-23.874191"
transform="matrix(0,-1,-1,0,0,0)" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="48px"
height="48px"
id="svg2985"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="airbus_decel.svg">
<defs
id="defs2987" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4.3"
inkscape:cx="-12.902798"
inkscape:cy="24.002241"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1075"
inkscape:window-height="665"
inkscape:window-x="20"
inkscape:window-y="20"
inkscape:window-maximized="0" />
<metadata
id="metadata2990">
<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
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
sodipodi:type="arc"
style="fill:none;stroke:#af0063;stroke-width:1.47335875;stroke-miterlimit:4;stroke-dasharray:none"
id="path5312"
sodipodi:cx="24.069767"
sodipodi:cy="23.581396"
sodipodi:rx="17.55814"
sodipodi:ry="16.976744"
d="m 41.627907,23.581396 a 17.55814,16.976744 0 1 1 -35.1162798,0 17.55814,16.976744 0 1 1 35.1162798,0 z"
transform="matrix(1.3347658,0,0,1.3804934,-7.6915012,-8.9902419)" />
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#af0063;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"
x="24.799843"
y="38.763"
id="text6082"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan6084"
x="24.799843"
y="38.763">D</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="48px"
height="48px"
id="svg2985"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="airbus_ec.svg">
<defs
id="defs2987" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.27"
inkscape:cx="11.14417"
inkscape:cy="15.800695"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1075"
inkscape:window-height="665"
inkscape:window-x="20"
inkscape:window-y="20"
inkscape:window-maximized="0" />
<metadata
id="metadata2990">
<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
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="ec_symbol"
style="stroke:#af0063;stroke-opacity:1">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path2993"
d="m 2.9285709,34.185715 12.3428571,-12.685716 30.514286,0 -4.8,-7.542856"
style="fill:none;stroke:#af0063;stroke-width:2.39999999999999991;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
<path
style="fill:none;stroke:#af0063;stroke-width:2.40000010000000019px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 45.785714,21.561266 -4.8,7.542856"
id="path3094"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="48px"
height="48px"
id="svg2985"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="airbus_ed.svg">
<defs
id="defs2987" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.27"
inkscape:cx="-22.252415"
inkscape:cy="15.800695"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1280"
inkscape:window-height="706"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata2990">
<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
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="ed_symbol"
transform="matrix(1,0,0,-1,0,48.142858)"
style="stroke:#118eff;stroke-opacity:1">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path2993"
d="m 2.9285709,34.185715 12.3428571,-12.685716 30.514286,0 -4.8,-7.542856"
style="fill:none;stroke:#118eff;stroke-width:2.40000010000000019;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
style="fill:none;stroke:#118eff;stroke-width:2.40000010000000019px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 45.785714,21.561266 -4.8,7.542856"
id="path3094"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="64px"
height="64px"
id="svg6263"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="airbus_hold_r.svg">
<defs
id="defs6265" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="11.363636"
inkscape:cy="39.272727"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="64"
inkscape:window-height="64"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata6268">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
d="m 38,58 l 0,-38 a 10,10 0 1 1 -20,0 l -5,-7 m5,7 l 8,-2"
id="path7043"
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:55.40000153;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="64px"
height="64px"
id="svg6263"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="airbus_holdL.svg">
<defs
id="defs6265" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="11.363636"
inkscape:cy="36.978476"
inkscape:current-layer="svg6263"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1280"
inkscape:window-height="703"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata6268">
<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></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="matrix(-1,0,0,1,59,0)">
<path
d="m 38,58 0,-38 a 10,10 0 1 1 -20,0 l -5,-7 m 5,7 8,-2"
id="path7043"
style="fill:none;stroke:#ffffff;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:55.40000153;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="48px"
height="48px"
id="svg2985"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="airbus_sc.svg">
<defs
id="defs2987" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4.3"
inkscape:cx="-39.763263"
inkscape:cy="24.002241"
inkscape:current-layer="Layer 1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1075"
inkscape:window-height="665"
inkscape:window-x="20"
inkscape:window-y="20"
inkscape:window-maximized="0" />
<metadata
id="metadata2990">
<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
id="Layer 1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="stroke:#ffffff;stroke-width:2.07588959px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 0.30339278,31.209046 c 44.00763722,0 34.21827422,0 34.21827422,0 l 9.840217,-13.513241 2.733394,9.652315 M 34.291189,18.20861 44.865702,16.790953"
id="sc_symbol"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="48px"
height="48px"
id="svg2985"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="airbus_td.svg">
<defs
id="defs2987" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4.3"
inkscape:cx="-8.8330301"
inkscape:cy="24.002241"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1075"
inkscape:window-height="665"
inkscape:window-x="20"
inkscape:window-y="20"
inkscape:window-maximized="0" />
<metadata
id="metadata2990">
<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
id="Layer 1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="fill:#none;stroke:#ffffff;stroke-width:2.07588959000000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 0.30339278,21.60313 c 44.00763722,0 34.21827422,0 34.21827422,0 l 9.840217,13.513241 2.733394,-9.652314 m -12.804089,9.139509 10.574513,1.417657"
id="sd_symbol"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,140 @@
<?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:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48px"
height="48px"
id="svg2985"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="airbus_spd_limit.svg">
<defs
id="defs2987">
<linearGradient
id="linearGradient5782"
osb:paint="solid">
<stop
style="stop-color:#323232;stop-opacity:1;"
offset="0"
id="stop5784" />
</linearGradient>
<linearGradient
id="linearGradient5412"
osb:paint="solid">
<stop
style="stop-color:#af0063;stop-opacity:1;"
offset="0"
id="stop5414" />
</linearGradient>
<pattern
patternUnits="userSpaceOnUse"
width="34.9375"
height="5.375"
patternTransform="translate(7.71875,41.3125)"
id="pattern5851">
<g
id="g5847"
transform="translate(-7.71875,-41.3125)">
<rect
style="fill:#000000;fill-opacity:0;fill-rule:nonzero;stroke:#323232;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect5800"
width="34.813999"
height="2.6294737"
x="7.7832417"
y="43.999527" />
<rect
y="41.370525"
x="7.7832417"
height="2.6294737"
width="34.814232"
id="rect5845"
style="fill:#323232;fill-opacity:1;fill-rule:nonzero;stroke:#323232;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
</g>
</pattern>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.73"
inkscape:cx="25.807853"
inkscape:cy="26.171035"
inkscape:current-layer="airbus-vor-sym"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1197"
inkscape:window-height="667"
inkscape:window-x="20"
inkscape:window-y="20"
inkscape:window-maximized="0" />
<metadata
id="metadata2990">
<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
id="airbus-spd-sym"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="fill:#323232;fill-opacity:1;stroke:none"
d="M 12.5 11.5 C 11.276818 12.626179 10.226321 13.93529 9.375 15.375 L 38.625 15.375 C 37.773679 13.93529 36.723182 12.626179 35.5 11.5 L 12.5 11.5 z "
id="rect3058" />
<path
style="fill:#af0063;fill-opacity:1;stroke:none"
d="M 9.4375 15.28125 C 8.706022 16.49978 8.0972549 17.795497 7.6875 19.1875 L 40.3125 19.1875 C 39.902745 17.795497 39.293978 16.49978 38.5625 15.28125 L 9.4375 15.28125 z "
id="rect4544" />
<path
style="fill:#323232;fill-opacity:1;stroke:none"
d="M 7.71875 19.09375 C 7.3437512 20.340744 7.1407327 21.650439 7.0625 23 L 40.9375 23 C 40.859267 21.650439 40.656249 20.340744 40.28125 19.09375 L 7.71875 19.09375 z "
id="rect4556" />
<path
style="fill:#af0063;fill-opacity:1;stroke:none"
d="M 7.0625 22.90625 C 7.0396116 23.267297 7 23.633178 7 24 C 7 24.945579 7.1015573 25.877693 7.25 26.78125 L 40.75 26.78125 C 40.898443 25.877693 41 24.945579 41 24 C 41 23.633178 40.960388 23.267297 40.9375 22.90625 L 7.0625 22.90625 z "
id="rect4558" />
<path
style="fill:#323232;fill-opacity:1;stroke:none"
d="M 7.21875 26.6875 C 7.4348196 28.051579 7.8235864 29.358048 8.34375 30.59375 L 39.65625 30.59375 C 40.176414 29.358048 40.56518 28.051579 40.78125 26.6875 L 7.21875 26.6875 z "
id="rect4572" />
<path
style="fill:#af0063;fill-opacity:1;stroke:none"
d="M 8.28125 30.5 C 8.8624157 31.905891 9.6447903 33.188749 10.5625 34.375 L 37.4375 34.375 C 38.35521 33.188749 39.137584 31.905891 39.71875 30.5 L 8.28125 30.5 z "
id="rect4574" />
<path
style="fill:#323232;fill-opacity:1;stroke:none"
d="M 10.46875 34.28125 C 11.63072 35.807354 13.051977 37.12846 14.65625 38.1875 L 33.34375 38.1875 C 34.948023 37.12846 36.36928 35.807354 37.53125 34.28125 L 10.46875 34.28125 z "
id="rect4578" />
<path
style="fill:#af0063;fill-opacity:1;stroke:none"
d="M 14.5 38.09375 C 17.213218 39.926763 20.479185 41 24 41 C 27.520815 41 30.786782 39.926763 33.5 38.09375 L 14.5 38.09375 z "
id="rect4580" />
<path
style="fill:#323232;fill-opacity:1;stroke:none"
d="M 24 7 C 22.20493 7 20.468087 7.2655778 18.84375 7.78125 L 29.15625 7.78125 C 27.531913 7.2655778 25.79507 7 24 7 z "
id="rect4592" />
<path
style="fill:#af0063;fill-opacity:1;stroke:none"
d="M 19.1875 7.6875 C 16.607244 8.4470332 14.285939 9.80207 12.375 11.59375 L 35.625 11.59375 C 33.714061 9.80207 31.392756 8.4470332 28.8125 7.6875 L 19.1875 7.6875 z "
id="rect4594" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="48px"
height="48px"
id="svg2985"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="airbus_tc.svg">
<defs
id="defs2987" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.27"
inkscape:cx="14.464853"
inkscape:cy="15.800695"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1075"
inkscape:window-height="665"
inkscape:window-x="20"
inkscape:window-y="20"
inkscape:window-maximized="0" />
<metadata
id="metadata2990">
<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
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="tc_symbol">
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path2993"
d="m 2.9285709,34.185715 12.3428571,-12.685716 30.514286,0 -4.8,-7.542856"
style="fill:none;stroke:#118eff;stroke-width:2.39999999999999991;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
<path
style="fill:none;stroke:#118eff;stroke-width:2.4000001px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 45.785714,21.561266 -4.8,7.542856"
id="path3094"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="48px"
height="48px"
id="svg2985"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="airbus_td.svg">
<defs
id="defs2987" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4.3"
inkscape:cx="-8.8330301"
inkscape:cy="24.002241"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1075"
inkscape:window-height="665"
inkscape:window-x="20"
inkscape:window-y="20"
inkscape:window-maximized="0" />
<metadata
id="metadata2990">
<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
id="Layer 1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="fill:#none;stroke:#ffffff;stroke-width:2.07588959000000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 0.30339278,21.60313 c 44.00763722,0 34.21827422,0 34.21827422,0 l 9.840217,13.513241 2.733394,-9.652314 m -12.804089,9.139509 10.574513,1.417657"
id="td_symbol"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
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="50"
height="50"
id="svg3076"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="airbus-vor.svg">
<metadata
id="metadata3092">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3090" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1248"
inkscape:window-height="703"
id="namedview3088"
showgrid="false"
inkscape:zoom="1.6619718"
inkscape:cx="-33.09322"
inkscape:cy="71"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg3076" />
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<g
id="g3078"
inkscape:groupmode="layer"
transform="matrix(0.34013605,0,0,0.33783784,0.84746249,0.78240397)">
<title
id="title3080">Layer 1</title>
<g
id="svg_7">
<line
id="svg_3"
y2="71"
x2="142"
y1="71"
x1="112"
style="fill:none;stroke:#b00064;stroke-width:5" />
<circle
id="svg_2"
r="39.115215"
cy="71.5"
cx="71"
sodipodi:cx="71"
sodipodi:cy="71.5"
sodipodi:rx="39.115215"
sodipodi:ry="39.115215"
style="fill:none;stroke:#b00064;stroke-width:5"
d="m 110.11522,71.5 c 0,21.602737 -17.512483,39.11522 -39.11522,39.11522 -21.602737,0 -39.115215,-17.512483 -39.115215,-39.11522 0,-21.602737 17.512478,-39.115215 39.115215,-39.115215 21.602737,0 39.11522,17.512478 39.11522,39.115215 z" />
<line
id="svg_4"
y2="71"
x2="30"
y1="71"
x1="0"
style="fill:none;stroke:#b00064;stroke-width:5" />
<line
transform="matrix(0,1,-1,0,198,58)"
id="svg_5"
y2="128"
x2="85"
y1="128"
x1="55"
style="fill:none;stroke:#b00064;stroke-width:5" />
<line
id="svg_6"
transform="matrix(0,1,-1,0,85,-55)"
y2="15"
x2="85"
y1="15"
x1="55"
style="fill:none;stroke:#b00064;stroke-width:5" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
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="48px"
height="48px"
id="svg2985"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="airbus_vor.svg">
<defs
id="defs2987" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.7255132"
inkscape:cx="41.056088"
inkscape:cy="29.220813"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1197"
inkscape:window-height="667"
inkscape:window-x="20"
inkscape:window-y="20"
inkscape:window-maximized="0" />
<metadata
id="metadata2990">
<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
id="airbus-vor-sym"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
sodipodi:type="arc"
style="fill:none;stroke:#af0063;stroke-width:1.57920909;stroke-miterlimit:4;stroke-dasharray:none"
id="path3014"
sodipodi:cx="28.214285"
sodipodi:cy="22.642857"
sodipodi:rx="10.5"
sodipodi:ry="10.214286"
d="m 38.714285,22.642857 a 10.5,10.214286 0 1 1 -21,0 10.5,10.214286 0 1 1 21,0 z"
transform="matrix(1.1857807,0,0,1.2189494,-9.1389546,-3.9914967)" />
<path
inkscape:connector-curvature="0"
id="path3084"
d="m 36.915889,23.738251 c 7.210196,0 9.210196,0 9.210196,0 l 0,0"
style="fill:none;stroke:#af0063;stroke-width:2.23682857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#af0063;stroke-width:2.22900009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 24.316735,1.1057656 c 0,7.8137242 0,7.8137242 0,7.8137242 l 0,2.0000002"
id="path3086"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
inkscape:connector-curvature="0"
id="path3088"
d="m 24.316735,35.872915 c 0,7.462294 0,9.462294 0,9.462294 l 0,0"
style="fill:none;stroke:#af0063;stroke-width:2.22900009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#af0063;stroke-width:2.23682857;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 3.3195483,23.738251 c 7.2101957,0 7.2101957,0 7.2101957,0 l 2,0"
id="path4589"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -0,0 +1,37 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'DECEL';
var parents = [canvas.SymbolLayer.Controller];
var __self__ = caller(0)[0];
canvas.SymbolLayer.Controller.add(name, __self__);
canvas.SymbolLayer.add(name, {
parents: [MultiSymbolLayer],
type: name, # Symbol type
df_controller: __self__, # controller to use by default -- this one
df_options : { # default configuration options
decel_node: "/instrumentation/nd/symbols/decel/"
}
});
var new = func(layer) {
var m = {
parents: [__self__],
layer: layer,
map: layer.map,
listeners: [],
};
layer.searcher._equals = func(a,b) a.getName() == b.getName();
return m;
};
var del = func() {
foreach (var l; me.listeners)
removelistener(l);
};
var searchCmd = func {
var results = [];
var symNode = props.globals.getNode(me.layer.options.decel_node);
if (symNode != nil and symNode.getValue('longitude-deg') != nil)
append(results, symNode);
return results;
}

View file

@ -0,0 +1,32 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'DECEL';
var parents = [canvas.DotSym];
var __self__ = caller(0)[0];
canvas.DotSym.makeinstance( name, __self__ );
#canvas.SymbolLayer.get(name).df_style = {
# radius: 13,
#};
var element_type = "group";
var init = func {
var svg_path = me.getStyle('svg_path');
if(svg_path == nil)
svg_path = 'Nasal/canvas/map/Airbus/Images/airbus_decel.svg';
me.decel_grp = me.element.createChild("group","decel");
canvas.parsesvg(me.decel_grp, svg_path);
me.decel_grp.set('z-index', 5);
}
var draw = func{
if(me.decel_grp != nil){
var spd_ctrl = getprop(me.options.spd_ctrl);
var spd_managed = (spd_ctrl == me.options.managed_val);
if(spd_managed)
me.decel_grp.setColor(me.style.managed_color);
else
me.decel_grp.setColor(me.style.selected_color);
}
}

View file

@ -103,22 +103,27 @@ var init_cache = func {
# #
var init = func { var init = func {
# debug.dump(me.layer.style); # debug.dump(me.layer.style);
me.icon_dme = me.element.createChild("path") var draw_func = me.getOption('draw_dme');
.moveTo(-15,0) if(typeof(draw_func) == 'func'){
.line(-12.5,-7.5) me.icon_dme = draw_func(me);
.line(7.5,-12.5) } else {
.line(12.5,7.5) me.icon_dme = me.element.createChild("path")
.lineTo(7.5,-12.5) .moveTo(-15,0)
.line(12.5,-7.5) .line(-12.5,-7.5)
.line(7.5,12.5) .line(7.5,-12.5)
.line(-12.5,7.5) .line(12.5,7.5)
.lineTo(15,0) .lineTo(7.5,-12.5)
.lineTo(7.5,12.5) .line(12.5,-7.5)
.vert(14.5) .line(7.5,12.5)
.horiz(-14.5) .line(-12.5,7.5)
.vert(-14.5) .lineTo(15,0)
.close() .lineTo(7.5,12.5)
.setStrokeLineWidth( me.layer.style.line_width ); .vert(14.5)
.horiz(-14.5)
.vert(-14.5)
.close()
.setStrokeLineWidth( me.layer.style.line_width );
}
# finally scale the symbol as requested, this is done last so that people can override this when creating the layer # finally scale the symbol as requested, this is done last so that people can override this when creating the layer
me.apply_scale(); me.apply_scale();
@ -126,6 +131,15 @@ var init = func {
me.timer = maketimer(0.33, func me.animate() ); me.timer = maketimer(0.33, func me.animate() );
me.timer.start(); me.timer.start();
} }
if(me.getOption('draw_text', 0)){
me.dme_text = me.element.createChild("text")
.setDrawMode( canvas.Text.TEXT )
.setText(me.model.id)
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
.setFontSize(28)
.setColor(me.getStyle('text_color', [1,1,1]))
.setTranslation(me.getStyle('translation', [45,25]));
}
me.draw(); me.draw();
} }

View file

@ -30,20 +30,31 @@ var drawFIX = func(group) {
.setStrokeLineWidth(line_width) .setStrokeLineWidth(line_width)
.setColor(color); .setColor(color);
} }
var _name = name;
var cache = StyleableCacheable.new(
name:name, draw_func: drawFIX,
cache: SymbolCache32x32,
draw_mode: SymbolCache.DRAW_CENTERED,
relevant_keys: ["line_width", "color"],
);
var init = func { var init = func {
# initialize the cached fix symbol # initialize the cached fix symbol
var draw_fn = me.getOption('draw_function');
if(typeof(draw_fn) != 'func')
draw_fn = drawFIX;
var cache = StyleableCacheable.new(
name:_name,
draw_func: draw_fn,
cache: SymbolCache32x32,
draw_mode: SymbolCache.DRAW_CENTERED,
relevant_keys: ["line_width", "color"],
);
cache.render(me.element, me.style).setScale(me.style.scale_factor); cache.render(me.element, me.style).setScale(me.style.scale_factor);
var txt_offset = me.getStyle('text_offset', [17, 35]);
var txt_color = me.getStyle('text_color', [0,0.6,0.85]);
# non-cached stuff: # non-cached stuff:
if (me.style.show_labels) if (me.style.show_labels){
me.text_fix = me.newText(me.model.id).setScale(me.style.scale_factor).setTranslation(17,35).setColor(0,0.6,0.85); me.text_fix = me.newText(me.model.id).
setScale(me.style.scale_factor).
setTranslation(txt_offset).
setColor(txt_color);
}
} }
var draw = func; var draw = func {me.callback('draw');};

View file

@ -0,0 +1,100 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'HOLD';
var parents = [canvas.SymbolLayer.Controller];
var __self__ = caller(0)[0];
canvas.SymbolLayer.Controller.add(name, __self__);
canvas.SymbolLayer.add(name, {
parents: [MultiSymbolLayer],
type: name, # Symbol 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: [],
};
#debug.dump(layer.parents);
layer.searcher._equals = func(a,b) a.id == b.id;
#append(m.listeners, setlistener(layer.options.fplan_active, func m.layer.update() ));
#m.addVisibilityListener();
return m;
};
var del = func() {
foreach (var l; me.listeners)
removelistener(l);
};
var searchCmd = func {
var results = [];
var node = props.globals.getNode(me.layer.options.hold_node);
var wp_id = node.getValue('wp');
if(wp_id == nil or wp_id == '' or wp_id == '---'){
return [];
}
var pointsNode = node.getNode('points');
var pointNode = nil;
var lat = nil;
var lon = nil;
if(pointsNode != nil)
pointNode = pointsNode.getNode('point', 0);
if (pointNode != nil){
lat = pointNode.getValue('lat');
lon = pointNode.getValue('lon');
}
if (pointNode != nil and lat != nil and lon != nil){
var r = node.getValue('crs');
var d = node.getValue('dist');
var t = node.getValue('turn');
var model = {
parents: [geo.Coord],
id: wp_id~r~d~t,
pos: pointNode,
type: 'pattern',
latlon: func(){
return [
lat,
lon
];
},
radial: r,
dist: d,
turn: t,
equals: func(o){me.id == o.id and me.radial == o.radial}
};
append(results, model);
} else {
var wp_idx = node.getValue('wp_id');
var fp = flightplan();
var wp = fp.getWP(wp_idx);
#print("HOLD AT "~wp.wp_lat~", "~wp.wp_lon);
if(wp == nil or wp.id != wp_id)
return [];
var wp_lat = wp.wp_lat;
var wp_lon = wp.wp_lon;
var model = {
parents: [geo.Coord],
id: wp_id~'-'~wp_idx~'-inactive',
pos: nil,
type: 'hold_symbol',
latlon: func(){
return [
wp_lat,
wp_lon
];
},
radial: node.getValue('crs'),
dist: node.getValue('dist'),
turn: node.getValue('turn'),
equals: func(o){me.id == o.id}
};
append(results, model);
}
return results;
}

View file

@ -0,0 +1,106 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'HOLD';
var parents = [canvas.DotSym];
var __self__ = caller(0)[0];
canvas.DotSym.makeinstance( name, __self__ );
#canvas.SymbolLayer.get(name).df_style = {
# radius: 13,
#};
var element_type = "group";
var draw_pattern = func(dist, ){
var pattern = me.element.createChild("path", 'hold-pattern');
pattern.set("z-index",4);
var w = (dist * 2) / math.pi;
var h = dist * 70;
var r = w / 2;
pattern.arcSmallCW(r,r,0,70 * w,0).
line(0,h).
arcSmallCW(r,r,0,-70 * w,0).
line(0,-h).
setStrokeLineWidth(5).
setColor(me.active_color);
return pattern;
};
var draw_hold_sym = func(turn){
var hold_symbol = me.element.createChild("group", 'hold-symbol');
var svg = "Nasal/canvas/map/Airbus/Images/airbus_hold"~turn~".svg";
canvas.parsesvg(hold_symbol, svg);
hold_symbol.setTranslation(-32,-64).set('z-index', 4);
return hold_symbol;
}
var init = func {
var type = me.model.type;
var dist = me.model.dist;
var turn = me.model.turn;
me.active_color = me.getStyle('active_color',
me.getOption('active_route_color',
[0.4,0.7,0.4]));
me.inactive_color = me.getStyle('inactive_color',
me.getOption('inactive_route_color',
[0.95,0.95,0.21]));
if(type == 'pattern'){
me.hold_pattern = me.draw_pattern(dist);
me.hold_symbol = nil;
} else {
#print('CREATING HOLD SYM');
me.hold_pattern = nil;
me.hold_symbol = me.draw_hold_sym(turn);
}
}
var draw = func{
var type = me.model.type;
var map = me.layer.map;
var pos = map.getPos();
if(type == 'pattern'){
var dist = me.model.dist;
if(me.hold_symbol != nil){
me.hold_symbol.hide();
}
if(me.hold_pattern == nil)
me.hold_pattern = me.draw_pattern(dist);
if(me.hold_pattern == nil) return;
var radial = me.model.radial;
if(radial != nil){
var hdg = pos[2];
if(hdg == nil) hdg = 0;
radial -= hdg;
if(radial < 0) radial = 360 + radial;
me.element.setRotation(radial*D2R);
}
var rng = pos[3];
if(rng == nil) rng = 10;
rng = 10 / rng;
me.element.setScale(rng,rng);
var lat_ctrl = getprop(me.getOption('lat_ctrl'));
var lnav = (lat_ctrl == me.getOption('lat_ctrl_managed','fmgc'));
var actv = getprop(me.getOption('fplan_active'));
#print('HOLD ' ~ lnav ~ ',' ~ actv);
if(!lnav or !actv)
me.hold_pattern.setStrokeDashArray([32, 16]);
else
me.hold_pattern.setStrokeDashArray([1,0]);
if(!actv)
me.hold_pattern.setColor(me.inactive_color);
else
me.hold_pattern.setColor(me.active_color);
} else {
var turn = me.model.turn;
if(me.hold_pattern != nil){
me.hold_pattern.hide();
}
if(me.hold_symbol == nil)
me.hold_symbol = me.draw_hold_sym(turn);
me.hold_symbol.show();
me.element.setScale(1,1);
me.element.setRotation(0);
}
}

View file

@ -15,6 +15,7 @@ SymbolLayer.add(name, {
active_node: "/autopilot/route-manager/active", active_node: "/autopilot/route-manager/active",
current_wp_node: "/autopilot/route-manager/current-wp", current_wp_node: "/autopilot/route-manager/current-wp",
wp_num: "/autopilot/route-manager/route/num", wp_num: "/autopilot/route-manager/route/num",
display_inactive_rte: 0
} }
}); });
var new = func(layer) { var new = func(layer) {
@ -25,9 +26,19 @@ var new = func(layer) {
listeners: [], listeners: [],
}; };
layer.searcher._equals = func(l,r) 0; # TODO: create model objects instead? layer.searcher._equals = func(l,r) 0; # TODO: create model objects instead?
append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() ), setlistener(layer.options.wp_num, func m.layer.update() )); append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() ),
setlistener(layer.options.wp_num, func m.layer.update() ));
m.addVisibilityListener(); m.addVisibilityListener();
var driver = opt_member(m.layer.options, 'route_driver');
if(driver == nil){
driver = RouteDriver.new();
}
var driver_listeners = driver.getListeners();
foreach(var listener; driver_listeners){
append(m.listeners, setlistener(listener, func m.layer.update()));
}
m.route_driver = driver;
return m; return m;
}; };
var del = func() { var del = func() {
@ -35,21 +46,49 @@ var del = func() {
removelistener(l); removelistener(l);
}; };
var last_result = [];
var searchCmd = func { var searchCmd = func {
# FIXME: do we return the current route even if it isn't active? # FIXME: do we return the current route even if it isn't active?
printlog(_MP_dbg_lvl, "Running query: ", name); printlog(_MP_dbg_lvl, "Running query: ", name);
var plans = []; # TODO: multiple flightplans? var plans = []; # TODO: multiple flightplans?
var plans = [];
var driver = me.route_driver;
driver.update();
if(!driver.shouldUpdate()) return me.last_result;
# http://wiki.flightgear.org/Nasal_Flightplan # http://wiki.flightgear.org/Nasal_Flightplan
var fp = flightplan(); var planCount = driver.getNumberOfFlightPlans();
var fpSize = fp.getPlanSize(); for (var idx = 0; idx < planCount; idx += 1) {
if (!getprop(me.layer.options.active_node)) fpSize = 0; #var fp = driver.getFlightPlan(idx);
var coords = []; var fpSize = driver.getPlanSize(idx);
for (var i=0; i<fpSize; i += 1) { if(fpSize < 2) continue;
var leg = fp.getWP(i); var type = driver.getFlightPlanType(idx);
coords ~= leg.path(); if(type == nil) type = 'current';
if (!getprop(me.layer.options.active_node) and
type == 'current' and
!me.layer.options.display_inactive_rte) fpSize = 0;
var coords = [];
var discontinuity = 0;
for (var i=0; i<fpSize; i += 1) {
var leg = driver.getWP(idx, i);
if(discontinuity)
coords ~= [{},{lon:leg.wp_lon, lat:leg.wp_lat}];
else
coords ~= leg.path();
discontinuity = driver.hasDiscontinuity(idx, leg.id);
}
append(plans, {
id: type,
#name: type,
type: type,
path: coords,
#size: fpSize,
equals: func(o){
me.id == o.id# and me.size == o.size
}
});
} }
append(plans, coords); me.last_result = plans;
return plans; return plans;
}; };

View file

@ -11,8 +11,31 @@ SymbolLayer.get(name).df_style = { # style to use by default
color: [1,0,1] color: [1,0,1]
}; };
var init = func { var getLineStyle = func(property, df_val){
me.element.setColor(me.style.color) var type = nil;
.setStrokeLineWidth(me.style.line_width); if(typeof(me.model) == 'hash'){
type = me.model.type;
}
if(type != nil and type != 'current'){
var base_prop = property;
property = property~'_'~type;
me.getStyle(property, me.getStyle(base_prop, df_val));
} else {
me.getStyle(property, df_val);
}
};
var setRouteStyle = func{
var df_style = SymbolLayer.get(name).df_style;
var dash = me.getLineStyle('line_dash', []);
var color = me.getLineStyle('color', df_style.color);
var line_width = me.getLineStyle('line_width', df_style.line_width);
me.element.setColor(color).setStrokeLineWidth(line_width);
if(typeof(dash) == 'vector')
me.element.setStrokeDashArray(dash);
};
var init = func {
me.setRouteStyle();
}; };

View file

@ -0,0 +1,104 @@
# See: http://wiki.flightgear.org/MapStructure
var name = 'RWY-profile';
var parents = [SymbolLayer.Controller];
var __self__ = caller(0)[0];
SymbolLayer.Controller.add(name, __self__);
SymbolLayer.add(name, {
parents: [MultiSymbolLayer],
type: name, # Symbol type
df_controller: __self__, # controller to use by default -- this one
df_options: { # default configuration options
disable_position: 1,
dep_rwy: '/autopilot/route-manager/departure/runway',
dest_rwy: '/autopilot/route-manager/destination/runway',
dep_arpt: '/autopilot/route-manager/departure/airport',
dest_arpt: '/autopilot/route-manager/destination/airport'
}
});
var new = func(layer) {
var m = {
parents: [__self__],
layer: layer,
map: layer.map,
listeners: [],
};
layer.searcher._equals = func(l,r) {l.equals(r)}; # TODO: create model objects instead?
#append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() ));
#m.addVisibilityListener();
var driver = opt_member(m.layer.options, 'route_driver');
if(driver == nil){
driver = RouteDriver.new();
}
var driver_listeners = driver.getListeners();
foreach(var listener; driver_listeners){
append(m.listeners, setlistener(listener, func m.layer.update()));
}
m.route_driver = driver;
return m;
};
var del = func() {
foreach (var l; me.listeners)
removelistener(l);
};
var FPRunwayModel = {
new: func(apt, rwy){
var m = {
parents: [FPRunwayModel],
id: rwy.id,
lat: rwy.lat,
lon: rwy.lon,
length: rwy.length,
width: rwy.width,
heading: rwy.heading,
airport_id: apt.id
};
return m;
},
latlon: func(){
return [
me.lat,
me.lon
];
},
equals: func(o){me.id == o.id and me.airport_id == o.airport_id}
};
var searchCmd = func {
#var desApt = airportinfo(getprop(me.layer.options.dest_arpt));
#var depApt = airportinfo(getprop(me.layer.options.dep_arpt));
#if(desApt == nil and depApt == nil)
# return [];
var res = [];
var desRwy = nil;
var depRwy = nil;
var driver = me.route_driver;
if(!driver.shouldUpdate()) return res;
driver.update();
var fpcount = driver.getNumberOfFlightPlans();
for(var i = 0; i < fpcount; i += 1){
if(!driver.shouldUpdate()) continue;
var fp = driver.getFlightPlan(i);
var depApt = fp.departure;
if(depApt != nil){
var depRwy = fp.departure_runway;
if(depRwy != nil){
var model = FPRunwayModel.new(depApt, depRwy);
append(res, model);
}
}
var desApt = fp.destination;
if(desApt != nil){
var desRwy = fp.destination_runway;
if(desRwy != nil){
var model = FPRunwayModel.new(desApt, desRwy);
append(res, model);
}
}
}
return res;
};

View file

@ -0,0 +1,93 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'RWY-profile';
var parents = [DotSym];
var __self__ = caller(0)[0];
DotSym.makeinstance( name, __self__ );
var element_type = "group";
var style = { # style to use by default
zoom: 20,
color: [1,1,1],
center_line_len: 0.75,
line_width: 3
};
SymbolLayer.get(name).df_style = style;
#var already_drawn = 0;
var init = func {
#if(me.already_drawn) return;
var lat = me.model.lat;
var lon = me.model.lon;
var rwyhdg = me.model.heading;
var width = me.model.width;
var length = me.model.length;
var group = me.element;
var ctr_len = length * me.getStyle('center_line_len', 0.75);
var crds = [];
var coord = geo.Coord.new();
width = width * me.getStyle('zoom', 20); # Else rwy is too thin to be visible
var line_w = me.getStyle('line_width', 3);
var color = me.getStyle('color', [1,1,1]);
coord.set_latlon(lat, lon);
coord.apply_course_distance(rwyhdg, -(ctr_len / 2));
append(crds,"N"~coord.lat());
append(crds,"E"~coord.lon());
coord.apply_course_distance(rwyhdg, (ctr_len));
append(crds,"N"~coord.lat());
append(crds,"E"~coord.lon());
icon_rwy = group.createChild("path", "rwy-cl")
.setStrokeLineWidth(line_w)
.setDataGeo([2,4],crds)
.setColor(color);
#.setStrokeDashArray([10, 20, 10, 20, 10]);
#icon_rwy.hide();
var crds = [];
coord.set_latlon(lat, lon);
append(crds,"N"~coord.lat());
append(crds,"E"~coord.lon());
coord.apply_course_distance(rwyhdg + 90, width/2);
append(crds,"N"~coord.lat());
append(crds,"E"~coord.lon());
coord.apply_course_distance(rwyhdg, length);
append(crds,"N"~coord.lat());
append(crds,"E"~coord.lon());
icon_rwy = group.createChild("path", "rwy")
.setStrokeLineWidth(line_w)
.setDataGeo([2,4,4],crds)
.setColor(color);
var crds = [];
append(crds,"N"~coord.lat());
append(crds,"E"~coord.lon());
coord.apply_course_distance(rwyhdg - 90, width);
append(crds,"N"~coord.lat());
append(crds,"E"~coord.lon());
coord.apply_course_distance(rwyhdg, -length);
append(crds,"N"~coord.lat());
append(crds,"E"~coord.lon());
coord.apply_course_distance(rwyhdg + 90, width / 2);
append(crds,"N"~coord.lat());
append(crds,"E"~coord.lon());
icon_rwy = group.createChild("path", "rwy")
.setStrokeLineWidth(line_w)
.setDataGeo([2,4,4,4],crds)
.setColor(color);
};
var draw = func{}
#var 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();
#}

View file

@ -0,0 +1,49 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'SPD-profile';
var parents = [canvas.SymbolLayer.Controller];
var __self__ = caller(0)[0];
var _options = { # default configuration options
alts: [100,140,250,260,'wp']
};
canvas.SymbolLayer.Controller.add(name, __self__);
canvas.SymbolLayer.add(name, {
parents: [MultiSymbolLayer],
type: name, # Symbol type
df_controller: __self__, # controller to use by default -- this one
df_options: _options
});
var new = func(layer) {
var m = {
parents: [__self__],
layer: layer,
#map: layer.map,
listeners: [],
};
layer.searcher._equals = func(a,b) a.getName() == b.getName();
#append(m.listeners, setlistener(layer.options.fplan_active, func m.layer.update() ));
#m.addVisibilityListener();
return m;
};
var del = func() {
foreach (var l; me.listeners)
removelistener(l);
};
var searchCmd = func {
var results = [];
var symNode = props.globals.getNode(me.layer.options.spd_node);
if (symNode != nil)
foreach (var alt; me.layer.options.alts) {
t = 'spd-change-point' ~ '-' ~ alt;
#print('SPD-Controller, search for '~t);
var n = symNode.getNode(t);
if (n != nil and n.getValue('longitude-deg') != nil){
#print('SPD-Controller -> Append');
append(results, n);
}
}
return results;
}

View file

@ -0,0 +1,40 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'SPD-profile';
var parents = [canvas.SVGSymbol];
var __self__ = caller(0)[0];
canvas.DotSym.makeinstance( name, __self__ );
#canvas.SymbolLayer.get(name).df_style = {
# radius: 13,
#};
var element_type = "group";
var svg_path = 'Nasal/canvas/map/Airbus/Images/airbus_spd_limit.svg';
var spd_sym = nil;
#var init = func {
# var name = me.model.getName();
# #var radius = me.style.radius;
# var sym_group = me.element.createChild("group", name);
# sym_group.set("z-index",5);
# var color = me.getStyle('color');
# var spd_path = sym_group.createChild("path").
# setStrokeLineWidth(3).
# moveTo(-17,0).
# arcSmallCW(17,17,0,34,0).
# arcSmallCW(17,17,0,-34,0).
# setColor(color).
# setColorFill(color).
# set("z-index",5);
#}
var draw = func{
# var name = me.model.getName();
# var sym_group = me.element.getElementById(name);
# sym_group.set('z-index', 5);
if(me.spd_sym == nil){
me.spd_sym = me.getElementById("airbus-spd-sym");
me.spd_sym.setTranslation(-24, -24).set('z-index', 5);
}
}

View file

@ -0,0 +1,62 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name ='VOR-airbus';
var parents = [SymbolLayer.Controller];
var __self__ = caller(0)[0];
SymbolLayer.Controller.add(name, __self__);
SymbolLayer.add(name, {
parents: [NavaidSymbolLayer],
type: name, # Symbol type
df_controller: __self__, # controller to use by default -- this one
df_options: {
nav1_frq: 'instrumentation/nav/frequencies/selected-mhz',
nav2_frq: 'instrumentation/nav[1]/frequencies/selected-mhz'
},
df_style: {
scale: 1
}
});
var new = func(layer) {
var m = {
parents: [__self__],
layer: layer,
map: layer.map,
active_vors: [],
navNs: props.globals.getNode("instrumentation").getChildren("nav"),
listeners: [],
query_type:'vor',
};
setsize(m.active_vors, size(m.navNs));
foreach (var navN; m.navNs) {
append(m.listeners, setlistener(
navN.getNode("frequencies/selected-mhz"),
func m.changed_freq()
));
}
#call(debug.dump, keys(layer));
m.changed_freq(update:0);
m.addVisibilityListener();
return m;
};
var del = func() {
printlog(_MP_dbg_lvl, name,".lcontroller.del()");
foreach (var l; me.listeners)
removelistener(l);
};
# Controller methods
var isActive = func(model) {
var my_freq = model.frequency/100;
foreach (var freq; me.active_vors)
if (freq == my_freq) return 1;
return 0;
};
var changed_freq = func(update=1) {
#debug.dump(me.active_vors);
foreach (var navN; me.navNs)
me.active_vors[ navN.getIndex() ] = navN.getValue("frequencies/selected-mhz");
if (update) me.layer.update();
};
var searchCmd = NavaidSymbolLayer.make('vor');

View file

@ -0,0 +1,44 @@
# Class things:
var name = 'VOR-airbus';
var parents = [SVGSymbol];
var __self__ = caller(0)[0];
DotSym.makeinstance( name, __self__ );
var element_type = "group"; # we want a group, becomes "me.element"
var text_vor = nil;
var svg_path = 'Nasal/canvas/map/Airbus/Images/airbus_vor.svg';
var vor_sym = nil;
var draw = func{
if(me.vor_sym == nil)
me.vor_sym = me.element.getElementById("airbus-vor-sym");
me.vor_sym.setTranslation(-24,-24);
if(me.text_vor == nil){
var transl = me.getStyle('translation', [25,10]);
var text_color = me.getStyle('text_color', [1,1,1]);
me.text_vor = me.element.createChild("text")
.setDrawMode( canvas.Text.TEXT )
.setText(me.model.id)
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
.setFontSize(28)
.setColor(text_color)
.setTranslation(transl);
}
var frq = me.model.frequency;
if(frq != nil){
var dfcolor = me.getStyle('color', [0.9,0,0.47]);
var tuned_color = me.getStyle('tuned_color', [0,0.62,0.84]);
frq = frq / 100;
var nav1_frq = getprop(me.options.nav1_frq);
var nav2_frq = getprop(me.options.nav2_frq);
if(nav1_frq == frq or nav2_frq == frq){
me.element.setColor(tuned_color);
} else {
me.element.setColor(dfcolor);
}
}
me.text_vor.setColor(me.getStyle('text_color', [1,1,1]));
}

View file

@ -0,0 +1,137 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'WPT-airbus';
var parents = [canvas.SymbolLayer.Controller];
var __self__ = caller(0)[0];
canvas.SymbolLayer.Controller.add(name, __self__);
canvas.SymbolLayer.add(name, {
parents: [canvas.MultiSymbolLayer],
type: name, # Symbol type
df_controller: __self__, # controller to use by default -- this one
df_options: { # default configuration options
fix_symbol: func(group){
group.createChild('path')
.moveTo(-10,0)
.lineTo(0,-17)
.lineTo(10,0)
.lineTo(0,17)
.close()
.setStrokeLineWidth(3)
.setColor(1,1,1)
.setScale(1);
},
vor_symbol: 'Nasal/canvas/map/Airbus/Images/airbus_vor.svg',
airport_symbol: 'Nasal/canvas/map/Airbus/Images/airbus_airport.svg',
ndb_symbol: func(group){
group.createChild('path')
.moveTo(-15,15)
.lineTo(0,-15)
.lineTo(15,15)
.close()
.setStrokeLineWidth(3)
#.setColor(0.69,0,0.39)
#.setTranslation(-24, -24),
.setScale(1,1);
}
},
df_style: {
active_wp_color: [0.4,0.7,0.4],
current_wp_color: [1,1,1],
translation: {
'airport': [-24,-24],
'vor': [-24,-24]
}
},
toggle_cstr: 0
});
var new = func(layer) {
var m = {
parents: [__self__],
layer: layer,
map: layer.map,
listeners: [],
};
layer.searcher._equals = func(a,b) a.equals(b);
var driver = opt_member(m.layer.options, 'route_driver');
if(driver == nil){
driver = RouteDriver.new();
}
var driver_listeners = driver.getListeners();
foreach(var listener; driver_listeners){
append(m.listeners, setlistener(listener, func m.layer.update()));
}
m.route_driver = driver;
return m;
};
var del = func() {
foreach (var l; me.listeners)
removelistener(l);
};
var WPTModel = {
new: func(fp, idx) {
var m = { parents:[WPTModel] };
var wp = fp.getWP(idx);
m.id = wp.id;
m.name = wp.wp_name;
m.alt = wp.alt_cstr;
m.spd = wp.speed_cstr;
m.type = wp.wp_type;
(m.lat,m.lon) = (wp.wp_lat,wp.wp_lon);
var is_rwy = (m.type == 'runway');
var id_len = size(m.id);
if(!is_rwy and id_len < 5){
if(id_len == 4 and airportinfo(m.id) != nil)
m.navtype = 'airport';
else {
var navaid = nil;
foreach(var t; ['vor', 'ndb']){
navaid = navinfo(m.lat, m.lon, t, m.id);
if(navaid != nil and size(navaid)){
m.navtype = t;
break;
}
}
if(navaid == nil or !size(navaid)) m.navtype = 'fix';
}
} else {
m.navtype = (is_rwy ? 'rwy' : 'fix');
}
m.wp = wp;
idx = wp.index;
m.idx = idx;
m.is_departure = (idx == 0 and is_rwy);
m.is_destination = (idx > 0 and is_rwy);
return m;
},
equals: func(other) {
# this is set on symbol init, so use this for equality...
me.name == other.name and me.alt == other.alt and
me.type == other.type and me.idx == other.idx and
me.navtype == other.navtype
},
};
var searchCmd = func {
var driver = me.route_driver;
if(!driver.shouldUpdate()) return [];
driver.update();
var result = [];
var planCount = driver.getNumberOfFlightPlans();
for(var idx = 0; idx < planCount; idx += 1){
var fp = driver.getFlightPlan(idx);
if(fp == nil) continue;
var fpSize = fp.getPlanSize(idx);
for (var i = 0; i < fpSize; i+=1){
if(!driver.shouldUpdate()) return[];
append(result, WPTModel.new(fp, i));
}
}
return result;
}

View file

@ -0,0 +1,137 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'WPT-airbus';
var parents = [canvas.DotSym];
var __self__ = caller(0)[0];
canvas.DotSym.makeinstance( name, __self__ );
var element_type = "group";
var init = func {
var name = me.model.name;
var alt = me.model.alt;
var spd = me.model.spd;
var wp_group = me.element;
me.alt_path = nil;
var colors = [
'wp_color',
'current_wp_color',
'constraint_color',
'active_constraint_color',
'missed_constraint_color'
];
foreach(col; colors){
me[col] = me.getStyle(col, me.getOption(col));
}
var idLen = size(me.model.id);
var draw_sym = nil;
var navtype = me.model.navtype;
if (navtype == nil) navtype = 'fix';
if(navtype == 'airport')
draw_sym = me.options.airport_symbol;
elsif(navtype == 'vor')
draw_sym = me.options.vor_symbol;
elsif(navtype == 'ndb')
draw_sym = me.options.ndb_symbol;
else
draw_sym = me.options.fix_symbol;
me.wp_sym = me.element.createChild('group', 'wp-'~ me.model.idx);
if(typeof(draw_sym) == 'func')
draw_sym(me.wp_sym);
elsif(typeof(draw_sym) == 'scalar')
canvas.parsesvg(me.wp_sym, draw_sym);
var translation = me.getStyle('translation', {});
if(contains(translation, navtype)){
me.wp_sym.setTranslation(translation[navtype]);
}
me.text_wps = wp_group.createChild("text", "wp-text-" ~ me.model.idx)
.setDrawMode( canvas.Text.TEXT )
.setText(me.model.name)
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
.setFontSize(28)
.setTranslation(25,15)
.setColor(1,1,1);
me.text_alt = nil;
if(alt > 0 or spd > 0){
var cstr_txt = "\n";
if(alt > 0){
if(alt > 10000)
cstr_txt ~= sprintf('FL%3.0f', int(alt / 100));
else
cstr_txt ~= sprintf('%4.0f', int(alt));
}
if(spd > 0){
if(alt > 0) cstr_txt ~= "\n";
if(spd <= 1)
cstr_txt ~= sprintf('%1.2fM', spd);
else
cstr_txt ~= sprintf('%3.0fKT', int(spd));
}
me.text_alt = wp_group.createChild("text", "wp-alt-text-" ~ me.model.idx)
.setDrawMode( canvas.Text.TEXT )
.setText(cstr_txt)
.setFont("LiberationFonts/LiberationSans-Regular.ttf")
.setFontSize(28)
.setTranslation(25,15);
}
}
var draw = func{
var wp_group = me.element;
var alt = me.model.alt;
var i = me.model.idx;
var vnav_actv = getprop(me.options.ver_ctrl) == me.options.managed_val;
var curwp = getprop(me.options.current_wp);
if(alt > 0){
var wp_d = me.model.wp.distance_along_route;
var lvl_off_at = getprop(me.options.level_off_alt);
if(lvl_off_at == nil) lvl_off_at = 0;
if(me.alt_path == nil){
me.alt_path = wp_group.createChild("path").
setStrokeLineWidth(4).
moveTo(-22,0).
arcSmallCW(22,22,0,44,0).
arcSmallCW(22,22,0,-44,0);
}
if(vnav_actv){
if(lvl_off_at and (lvl_off_at - wp_d) > 0.5 and curwp == i)
me.alt_path.setColor(me.missed_constraint_color);
else
me.alt_path.setColor(me.active_constraint_color);
}
else
me.alt_path.setColor(me.constraint_color);
if(me.layer.toggle_cstr)
me.alt_path.show();
else
me.alt_path.hide();
} else {
if(me.alt_path != nil) me.alt_path.hide();
}
wp_group.set("z-index",4);
#var sym = me.element.getElementById('wp-' ~ me.model.idx);
if(alt > 0 and me.text_alt != nil){
if(vnav_actv)
me.text_alt.setColor(me.active_constraint_color);
else
me.text_alt.setColor(me.constraint_color);
}
if(i == curwp) {
me.wp_sym.setColor(me.current_wp_color);
me.text_wps.setColor(me.current_wp_color);
} else {
me.wp_sym.setColor(me.wp_color);
me.text_wps.setColor(me.wp_color);
}
if(me.model.is_departure or me.model.is_destination){
var prop = (me.model.is_departure ? 'departure' : 'destination');
var rwy = getprop("/autopilot/route-manager/"~prop~"/runway");
if(rwy != nil and size(rwy) > 0){
me.wp_sym.hide();
} else {
me.wp_sym.show();
}
}
}

View file

@ -24,6 +24,15 @@ var new = func(layer) {
}; };
layer.searcher._equals = func(l,r) l.equals(r); layer.searcher._equals = func(l,r) l.equals(r);
append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() ), setlistener(layer.options.wp_num, func m.layer.update() )); append(m.listeners, setlistener(layer.options.active_node, func m.layer.update() ), setlistener(layer.options.wp_num, func m.layer.update() ));
var driver = opt_member(m.layer.options, 'route_driver');
if(driver == nil){
driver = RouteDriver.new();
}
var driver_listeners = driver.getListeners();
foreach(var listener; driver_listeners){
append(m.listeners, setlistener(listener, func m.layer.update()));
}
m.route_driver = driver;
m.addVisibilityListener(); m.addVisibilityListener();
return m; return m;
@ -59,12 +68,16 @@ var searchCmd = func {
printlog(_MP_dbg_lvl, "Running query: "~name); printlog(_MP_dbg_lvl, "Running query: "~name);
if (!getprop(me.options.active_node)) return []; if (!getprop(me.options.active_node)) return [];
var driver = me.route_driver;
var fp = flightplan(); driver.update();
var fpSize = fp.getPlanSize();
var result = []; var result = [];
for (var i = 0; i < fpSize; i+=1) var planCount = driver.getNumberOfFlightPlans();
append(result, WPT_model.new(fp, i)); for(var idx = 0; idx < planCount; idx += 1){
var fp = driver.getFlightPlan(idx);
var fpSize = fp.getPlanSize(idx);
for (var i = 0; i < fpSize; i+=1)
append(result, WPT_model.new(fp, i));
}
return result; return result;
}; };

View file

@ -0,0 +1,69 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'WXR_live';
var parents = [SymbolLayer.Controller];
var __self__ = caller(0)[0];
SymbolLayer.Controller.add(name, __self__);
SymbolLayer.add(name, {
parents: [MultiSymbolLayer],
type: name, # Symbol type
df_controller: __self__, # controller to use by default -- this one
df_options: { # default configuration options
viewport_radius: 670
}
});
var wxr_tree = "/instrumentation/wxr";
var new = func(layer) {
var m = {
parents: [__self__],
layer: layer,
map: layer.map,
listeners: [],
};
layer.searcher._equals = func(l,r) l.equals(r);
m.addVisibilityListener();
#io.read_properties(getprop("/sim/fg-root") ~ "/Nasal/canvas/wxr_api.xml", wxr_tree);
var saved_conf = getprop("/sim/fg-home") ~ "/Export/wxr_api.xml";
if(io.stat(saved_conf) != nil)
io.read_properties(saved_conf, wxr_tree);
else
io.read_properties(getprop("/sim/fg-root") ~ "/Nasal/canvas/wxr_api.xml", wxr_tree);
return m;
};
var del = func() {
#print(name~".lcontroller.del()");
foreach (var l; me.listeners)
removelistener(l);
};
var searchCmd = func {
if(me.map.getRange() == nil) return [];
var api_key = getprop(wxr_tree~"/api-key");
if(!api_key or api_key == '' or api_key == 'YOUR API KEY')
return [];
var lat = getprop(wxr_tree~"/center/latitude-deg");
var lon = getprop(wxr_tree~"/center/longitude-deg");
if(lat == nil or lon == nil) {
var pos = geo.aircraft_position();
lat = pos.lat();
lon = pos.lon();
}
var result = geo.Coord.new();
result.set_latlon(lat, lon);
result.rangeNm = me.map.getRange();
result.key = api_key;
result.res = getprop(wxr_tree~"/resolution");
result.ltype = getprop(wxr_tree~"/layer-type");
result.smooth = getprop(wxr_tree~"/smooth");
result.fetchRad = getprop(wxr_tree~"/fetch-radius");
result.equals = func(r){
me.ltype == r.ltype and me.fetchRad == r.fetchRad and
me.lat == r.lat and me.lon == r.lon
};
return [result];
};

View file

@ -0,0 +1,111 @@
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'WXR_live';
var parents = [DotSym];
var __self__ = caller(0)[0];
DotSym.makeinstance( name, __self__ );
var element_type = "group";
var getWXRImageFilePath = func(){
var home = getprop('sim/fg-home');
var aircraft = getprop('sim/aircraft');
var idx = me.layer.getCanvas()._node.getIndex();
return home ~ '/Export/' ~ aircraft ~ '-wxr-'~me.ltype~'-'~idx~'.png';
};
var getWXRAPIUrl = func(lat, lon){
var res = me.res;
if(me.ltype == "radar"){
return "http://api.wunderground.com/api/"~me.key~
"/radar/image.png?centerlat="~lat~"&centerlon="~lon~
"&radius="~me.fetchRad~"&width="~res~"&height="~res~
"&smooth="~me.smooth;
} else {
return nil;
}
};
var fetchWXRMap = func(size){
if(me.fetching) return;
var pos = geo.aircraft_position();
var lat = pos.lat();
var lon = pos.lon();
var url = me.getWXRAPIUrl(lat, lon);
var filePath = me.getWXRImageFilePath();
if(url == nil) {
print(me.name~': No URL!');
return;
}
me.fetching = 1;
http.save(url, filePath)
.fail(func(){print(me.name~': Download failed!');})
.done(func(){
var sz = size * 2;
var transl = -size;
me.wxlayer.hide();
me.wxlayer.setFile(filePath)
.setSize(sz, sz)
.setTranslation(transl, transl);
me.wxlayer.show();
me.last_request = getprop("/sim/time/elapsed-sec");
})
.always(func(){
setprop("/instrumentation/wxr/center/latitude-deg", lat);
setprop("/instrumentation/wxr/center/longitude-deg", lon);
me.fetching = 0;
print("[WXR] Live Layer Request: "~url); # Debugging
});
};
var init = func {
#print('WXR init');
me.fetching = 0;
me.key = me.model.key; # API Key from Wunderground API Subscription
me.res = me.model.res; # Resolution of image to fetch (default 2048)
me.ltype = me.model.ltype; # Layer Type - radar, satellite
me.smooth = me.model.smooth; # If we should fetch a smoothened image or the original
me.fetchRad = me.model.fetchRad; # Radius of radar layer to fetch
me.range = me.model.rangeNm; # Range of Navigation Display
me.viewport_radius = me.getOption('viewport_radius', 670);
me.wxlayer = me.element.createChild("image").set("z-index", -100).hide();
me.last_request = -210;
me.update_interval = 240;
var r_scaled = (me.fetchRad*me.viewport_radius)/me.range;
me.fetchWXRMap(r_scaled);
};
var draw = func {
var range = me.layer.map.getRange(); # Range of Navigation Display
var update_size = (range != me.range);
me.range = range;
me.fetchRad = me.model.fetchRad; # Radius of radar layer to fetch
#var r_scaled = (me.fetchRad*670)/me.range;
var r_scaled = (me.fetchRad*me.viewport_radius)/me.range;
var hdg = me.layer.map.getHdg();
var rot = 0 - hdg;
if(rot < 0) rot = 360 + rot;
me.element.setRotation(rot*D2R);
if(update_size){
print('WXR draw range:'~ me.range);
print('Update size: '~r_scaled~'x2 = '~(r_scaled*2));
me.wxlayer.hide();
me.wxlayer.setSize(2*r_scaled, 2*r_scaled)
.setTranslation(-r_scaled, -r_scaled);
me.wxlayer.show();
}
if(getprop("/sim/time/elapsed-sec") - me.last_request > me.update_interval) {
#print('Fetching WXR map...');
me.key = me.model.key; # API Key from Wunderground API Subscription
me.res = me.model.res; # Resolution of image to fetch (default 2048)
me.ltype = me.model.ltype; # Layer Type - radar, satellite
me.smooth = me.model.smooth; # If we should fetch a smoothened image or the original
me.fetchWXRMap(r_scaled);
}
};

View file

@ -22,6 +22,8 @@ io.include("Nasal/canvas/map/navdisplay.styles");
# encapsulate hdg/lat/lon source, so that the ND may also display AI/MP aircraft in a pilot-view at some point (aka stress-testing) # encapsulate hdg/lat/lon source, so that the ND may also display AI/MP aircraft in a pilot-view at some point (aka stress-testing)
# TODO: this predates aircraftpos.controller (MapStructure) should probably be unified to some degree ... # TODO: this predates aircraftpos.controller (MapStructure) should probably be unified to some degree ...
var wxr_live_tree = "/instrumentation/wxr";
var NDSourceDriver = {}; var NDSourceDriver = {};
NDSourceDriver.new = func { NDSourceDriver.new = func {
var m = {parents:[NDSourceDriver]}; var m = {parents:[NDSourceDriver]};
@ -78,6 +80,10 @@ var default_switches = {
'toggle_true_north': {path: '/mfd/true-north', value:0, type:'BOOL'}, 'toggle_true_north': {path: '/mfd/true-north', value:0, type:'BOOL'},
'toggle_rangearc': {path: '/mfd/rangearc', value:0, type:'BOOL'}, 'toggle_rangearc': {path: '/mfd/rangearc', value:0, type:'BOOL'},
'toggle_track_heading':{path: '/trk-selected', value:0, type:'BOOL'}, 'toggle_track_heading':{path: '/trk-selected', value:0, type:'BOOL'},
'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'},
}; };
## ##
@ -118,6 +124,10 @@ var NavDisplay = {
# listeners for cockpit switches # listeners for cockpit switches
listen_switch: func(s,c) { listen_switch: func(s,c) {
# print("event setup for: ", id(c)); # print("event setup for: ", id(c));
if (!contains(me.efis_switches, s)) {
print('EFIS Switch not defined: '~ s);
return;
}
me.listen( me.get_full_switch_path(s), func { me.listen( me.get_full_switch_path(s), func {
# print("listen_switch triggered:", s, " callback id:", id(c) ); # print("listen_switch triggered:", s, " callback id:", id(c) );
c(); c();
@ -133,11 +143,22 @@ var NavDisplay = {
# helper method for getting configurable cockpit switches (which are usually different in each aircraft) # helper method for getting configurable cockpit switches (which are usually different in each aircraft)
get_switch: func(s) { get_switch: func(s) {
var switch = me.efis_switches[s]; var switch = me.efis_switches[s];
if(switch == nil) return nil;
var path = me.efis_path ~ switch.path ; var path = me.efis_path ~ switch.path ;
#print(s,":Getting switch prop:", path); #print(s,":Getting switch prop:", path);
return getprop( path ); return getprop( path );
}, },
# helper method for setting configurable cockpit switches (which are usually different in each aircraft)
set_switch: func(s, v) {
var switch = me.efis_switches[s];
if(switch == nil) return nil;
var path = me.efis_path ~ switch.path ;
#print(s,":Getting switch prop:", path);
setprop( path, v );
},
# for creating NDs that are driven by AI traffic instead of the main aircraft (generalization rocks!) # for creating NDs that are driven by AI traffic instead of the main aircraft (generalization rocks!)
connectAI: func(source=nil) { connectAI: func(source=nil) {
@ -159,6 +180,12 @@ var NavDisplay = {
NavDisplay.id +=1; NavDisplay.id +=1;
var m = { parents : [NavDisplay]}; var m = { parents : [NavDisplay]};
var df_toggles = keys(default_switches);
foreach(var toggle_name; df_toggles){
if(!contains(switches, toggle_name))
switches[toggle_name] = default_switches[toggle_name];
}
m.inited = 0; m.inited = 0;
m.timers=[]; m.timers=[];
@ -166,6 +193,7 @@ var NavDisplay = {
m.aircraft_source = NDSourceDriver.new(); # uses the main aircraft as the driver/source (speeds, position, heading) m.aircraft_source = NDSourceDriver.new(); # uses the main aircraft as the driver/source (speeds, position, heading)
m.nd_style = NDStyles[style]; # look up ND specific stuff (file names etc) m.nd_style = NDStyles[style]; # look up ND specific stuff (file names etc)
m.style_name = style;
m.radio_list=["instrumentation/comm/frequencies","instrumentation/comm[1]/frequencies", m.radio_list=["instrumentation/comm/frequencies","instrumentation/comm[1]/frequencies",
"instrumentation/nav/frequencies", "instrumentation/nav[1]/frequencies"]; "instrumentation/nav/frequencies", "instrumentation/nav[1]/frequencies"];
@ -197,7 +225,7 @@ var NavDisplay = {
m.mk_minimums = props.globals.getNode("instrumentation/mk-viii/inputs/arinc429/decision-height"); m.mk_minimums = props.globals.getNode("instrumentation/mk-viii/inputs/arinc429/decision-height");
# TODO: these are switches, can be unified with switch handling hash above (eventually): # TODO: these are switches, can be unified with switch handling hash above (eventually):
m.nd_plan_wpt = m.efis.initNode("inputs/plan-wpt-index", 0, "INT"); # not yet in switches hash m.nd_plan_wpt = m.efis.initNode("inputs/plan-wpt-index", -1, "INT"); # not yet in switches hash
### ###
# initialize all switches based on the defaults specified in the switch hash # initialize all switches based on the defaults specified in the switch hash
@ -212,13 +240,28 @@ var NavDisplay = {
return m; return m;
}, },
newMFD: func(canvas_group, parent=nil, options=nil, update_time=0.05) newMFD: func(canvas_group, parent=nil, nd_options=nil, update_time=0.05)
{ {
if (me.inited) die("MFD already was added to scene"); if (me.inited) die("MFD already was added to scene");
me.inited = 1; me.inited = 1;
me.range_dependant_layers = [];
me.always_update_layers = {};
me.update_timer = maketimer(update_time, func me.update() ); me.update_timer = maketimer(update_time, func me.update() );
me.nd = canvas_group; me.nd = canvas_group;
me.canvas_handle = parent; me.canvas_handle = parent;
me.df_options = nil;
if (contains(me.nd_style, 'options'))
me.df_options = me.nd_style.options;
nd_options = default_hash(nd_options, me.df_options);
me.options = nd_options;
me.route_driver = nil;
if (contains(me.options, 'route_driver')) {
me.route_driver = me.options.route_driver;
}
elsif (contains(me.options, 'defaults')) {
if(contains(me.options.defaults, 'route_driver'))
me.route_driver = me.options.defaults.route_driver;
}
# load the specified SVG file into the me.nd group and populate all sub groups # load the specified SVG file into the me.nd group and populate all sub groups
@ -245,10 +288,19 @@ var NavDisplay = {
"HdgBugCRT2","TrkBugLCD2","HdgBugLCD2","hdgBug2","selHdgLine","selHdgLine2","curHdgPtr2", "HdgBugCRT2","TrkBugLCD2","HdgBugLCD2","hdgBug2","selHdgLine","selHdgLine2","curHdgPtr2",
"staArrowL","staArrowR","staToL","staFromL","staToR","staFromR"] ) "staArrowL","staArrowR","staToL","staFromL","staToR","staFromR"] )
me.symbols[element] = me.nd.getElementById(element).updateCenter(); me.symbols[element] = me.nd.getElementById(element).updateCenter();
var map_rect = [124, 1024, 1024, 0];
var map_opts = me.options.map;
if (map_opts == nil) map_opts = {};
if (typeof(map_opts.rect) == 'vector')
map_rect = map_opts.rect;
map_rect = join(', ', map_rect);
me.map = me.nd.createChild("map","map") me.map = me.nd.createChild("map","map")
.set("clip", "rect(124, 1024, 1024, 0)") .set("clip", map_rect)
.set("screen-range", 700); .set("screen-range", 700);
var z_idx = map_opts['z-index'];
if (z_idx != nil) me.map.set('z-index', z_idx);
me.update_sub(); # init some map properties based on switches me.update_sub(); # init some map properties based on switches
@ -323,6 +375,7 @@ var NavDisplay = {
me.layers={}; # storage container for all ND specific layers me.layers={}; # storage container for all ND specific layers
# look up all required layers as specified per the NDStyle hash and do the initial setup for event handling # look up all required layers as specified per the NDStyle hash and do the initial setup for event handling
var default_opts = me.options != nil and contains(me.options, 'defaults') ? me.options.defaults : nil;
foreach(var layer; me.nd_style.layers) { foreach(var layer; me.nd_style.layers) {
if(layer['disabled']) continue; # skip this layer if(layer['disabled']) continue; # skip this layer
#print("newMFD(): Setting up ND layer:", layer.name); #print("newMFD(): Setting up ND layer:", layer.name);
@ -332,16 +385,33 @@ var NavDisplay = {
the_layer = me.layers[layer.name] = canvas.MAP_LAYERS[layer.name].new( me.map, layer.name, controller ); the_layer = me.layers[layer.name] = canvas.MAP_LAYERS[layer.name].new( me.map, layer.name, controller );
else { else {
printlog(_MP_dbg_lvl, "Setting up MapStructure-based layer for ND, name:", layer.name); printlog(_MP_dbg_lvl, "Setting up MapStructure-based layer for ND, name:", layer.name);
var opt = options != nil and options[layer.name] != nil ? options[layer.name] :nil; var opt = me.options != nil and me.options[layer.name] != nil ? me.options[layer.name] : nil;
# print("Options is: ", opt!=nil?"enabled":"disabled"); if (opt == nil and contains(layer, 'options'))
opt = layer.options;
if (opt != nil and default_opts != nil)
opt = default_hash(opt, default_opts);
#elsif(default_opts != nil)
# opt = default_opts;
var style = nil;
if(contains(layer, 'style'))
style = layer.style;
#print("Options is: ", opt!=nil?"enabled":"disabled");
#debug.dump(opt);
me.map.addLayer( me.map.addLayer(
factory: canvas.SymbolLayer, factory: canvas.SymbolLayer,
type_arg: layer.name, type_arg: layer.name,
options:opt, opts: opt,
visible:0, visible:0,
style: style,
priority: layer['z-index'] priority: layer['z-index']
); );
the_layer = me.layers[layer.name] = me.map.getLayer(layer.name); the_layer = me.layers[layer.name] = me.map.getLayer(layer.name);
if(opt != nil and contains(opt, 'range_dependant')){
if(opt.range_dependant)
append(me.range_dependant_layers, the_layer);
}
if(contains(layer, 'always_update'))
me.always_update_layers[layer.name] = layer.always_update;
if (1) (func { if (1) (func {
var l = layer; var l = layer;
var _predicate = l.predicate; var _predicate = l.predicate;
@ -443,15 +513,28 @@ var NavDisplay = {
} }
# First, update the display position of the map # First, update the display position of the map
var oldRange = me.map.getRange();
var pos = { var pos = {
lat: nil, lon: nil, lat: nil, lon: nil,
alt: nil, hdg: nil, alt: nil, hdg: nil,
range: nil, range: nil,
}; };
# reposition the map, change heading & range: # reposition the map, change heading & range:
if(me.in_mode('toggle_display_mode', ['PLAN']) and getprop(me.efis_path ~ "/inputs/plan-wpt-index") >= 0) { var pln_wpt_idx = getprop(me.efis_path ~ "/inputs/plan-wpt-index");
pos.lat = getprop("/autopilot/route-manager/route/wp["~getprop(me.efis_path ~ "/inputs/plan-wpt-index")~"]/latitude-deg"); if(me.in_mode('toggle_display_mode', ['PLAN']) and pln_wpt_idx >= 0) {
pos.lon = getprop("/autopilot/route-manager/route/wp["~getprop(me.efis_path ~ "/inputs/plan-wpt-index")~"]/longitude-deg"); if(me.route_driver != nil){
var wp = me.route_driver.getPlanModeWP(pln_wpt_idx);
if(wp != nil){
pos.lat = wp.wp_lat;
pos.lon = wp.wp_lon;
} else {
pos.lat = getprop("/autopilot/route-manager/route/wp["~pln_wpt_idx~"]/latitude-deg");
pos.lon = getprop("/autopilot/route-manager/route/wp["~pln_wpt_idx~"]/longitude-deg");
}
} else {
pos.lat = getprop("/autopilot/route-manager/route/wp["~pln_wpt_idx~"]/latitude-deg");
pos.lon = getprop("/autopilot/route-manager/route/wp["~pln_wpt_idx~"]/longitude-deg");
}
} else { } else {
pos.lat = userLat; pos.lat = userLat;
pos.lon = userLon; pos.lon = userLon;
@ -463,7 +546,14 @@ var NavDisplay = {
pos.range = me.rangeNm(); # avoid this here, use a listener instead pos.range = me.rangeNm(); # avoid this here, use a listener instead
pos.hdg = userHdgTrkTru; pos.hdg = userHdgTrkTru;
} }
if(me.options != nil and (var pos_callback = me.options['position_callback']) != nil)
pos_callback(me, pos);
call(me.map.setPos, [pos.lat, pos.lon], me.map, pos); call(me.map.setPos, [pos.lat, pos.lon], me.map, pos);
if(pos.range != oldRange){
foreach(l; me.range_dependant_layers){
l.update();
}
}
}, },
# each model should keep track of when it last got updated, using current lat/lon # each model should keep track of when it last got updated, using current lat/lon
# in update(), we can then check if the aircraft has traveled more than 0.5-1 nm (depending on selected range) # in update(), we can then check if the aircraft has traveled more than 0.5-1 nm (depending on selected range)
@ -472,7 +562,13 @@ var NavDisplay = {
update: func() # FIXME: This stuff is still too aircraft specific, cannot easily be reused by other aircraft update: func() # FIXME: This stuff is still too aircraft specific, cannot easily be reused by other aircraft
{ {
var _time = systime(); var _time = systime();
# Disables WXR Live if it's not enabled. The toggle_weather_live should be common to all
# ND instances.
var wxr_live_enabled = getprop(wxr_live_tree~'/enabled');
if(wxr_live_enabled == nil or wxr_live_enabled == '')
wxr_live_enabled = 0;
me.set_switch('toggle_weather_live', wxr_live_enabled);
call(me.update_sub, nil, nil, caller(0)[0]); # call this in the same namespace to "steal" its variables call(me.update_sub, nil, nil, caller(0)[0]); # call this in the same namespace to "steal" its variables
# MapStructure update! # MapStructure update!
@ -481,17 +577,26 @@ var NavDisplay = {
} else { } else {
# TODO: ugly list here # TODO: ugly list here
# FIXME: use a VOLATILE layer helper here that handles TFC, APS, WXR etc ? # FIXME: use a VOLATILE layer helper here that handles TFC, APS, WXR etc ?
me.map.update(func(layer) (var n=layer.type) == "TFC" or n == "APS"); var update_layers = me.always_update_layers;
me.map.update(func(layer) contains(update_layers, layer.type));
} }
# Other symbol update # Other symbol update
# TODO: should be refactored! # TODO: should be refactored!
if(me.in_mode('toggle_display_mode', ['PLAN'])) var translation_callback = nil;
me.map.setTranslation(512,512); if(me.options != nil)
elsif(me.get_switch('toggle_centered')) translation_callback = me.options['translation_callback'];
me.map.setTranslation(512,565); if(typeof(translation_callback) == 'func'){
else var trsl = translation_callback(me);
me.map.setTranslation(512,824); me.map.setTranslation(trsl.x, trsl.y);
} else {
if(me.in_mode('toggle_display_mode', ['PLAN']))
me.map.setTranslation(512,512);
elsif(me.get_switch('toggle_centered'))
me.map.setTranslation(512,565);
else
me.map.setTranslation(512,824);
}
if(me.get_switch('toggle_rh_vor_adf') == 1) { if(me.get_switch('toggle_rh_vor_adf') == 1) {
me.symbols.vorR.setText("VOR R"); me.symbols.vorR.setText("VOR R");

File diff suppressed because it is too large Load diff