VOR symbology and Nearest VOR page.
This commit is contained in:
parent
bbd99635e3
commit
339064ce31
8 changed files with 260 additions and 35 deletions
|
@ -54,6 +54,14 @@ getTextElement : func(symbolName) {
|
|||
return me._symbols[symbolName];
|
||||
},
|
||||
|
||||
highlightTextElement : func(symbolName) {
|
||||
me._symbols[symbolName].highlightElement();
|
||||
},
|
||||
|
||||
unhighlightTextElement : func(symbolName) {
|
||||
me._symbols[symbolName].unhighlightElement();
|
||||
},
|
||||
|
||||
getTextValue : func(symbolName) {
|
||||
var sym = me._symbols[symbolName];
|
||||
assert(sym != nil, "Unknown text element " ~ symbolName ~ " (check your addTextElements call?)");
|
||||
|
|
|
@ -55,7 +55,7 @@ var NavigationMap =
|
|||
|
||||
var r = func(name,vis=1,zindex=nil) return caller(0)[0];
|
||||
# TODO: we'll need some z-indexing here, right now it's just random
|
||||
foreach(var type; [r('GRID'),r('DTO',0),r('TFC',0),r('APT'),r('DME'),r('VOR'),r('FIX',0),r('NDB'),r('GPS'),r('RTE'),r('WPT'),r('FLT'),r('WXR',0),r('APS')] ) {
|
||||
foreach(var type; [r('GRID'),r('DTO',0),r('TFC',0),r('APT'),r('DME'),r('VOR_FG1000'),r('NDB'),r('FIX',0),r('GPS'),r('RTE'),r('WPT'),r('FLT'),r('WXR',0),r('APS')] ) {
|
||||
obj.MFDMap.addLayer(
|
||||
factory: canvas.SymbolLayer,
|
||||
type_arg: type.name,
|
||||
|
|
|
@ -51,7 +51,7 @@ var NavigationMapController =
|
|||
|
||||
GRID : { enabled: 0, declutter: 1, range: 20, max_range: 2000 },
|
||||
DME : { enabled: 1, declutter: 1, range: 150, max_range: 300 },
|
||||
VOR : { enabled: 1, declutter: 1, range: 150, max_range: 300 },
|
||||
VOR_FG1000 : { enabled: 1, declutter: 1, range: 150, max_range: 300 },
|
||||
NDB : { enabled: 1, declutter: 1, range: 15, max_range: 30 },
|
||||
FIX : { enabled: 1, declutter: 1, range: 15, max_range: 30 },
|
||||
RTE : { enabled: 1, declutter: 3, range: 2000, max_range: 2000 },
|
||||
|
|
|
@ -49,7 +49,7 @@ var NavigationMapStyles =
|
|||
me.Styles.FIX = {};
|
||||
me.Styles.FIX.color = [0,0,0]; # White outline
|
||||
me.Styles.FIX.fill_color = [1,1,1,1]; # Black fill
|
||||
me.Styles.FIX.scale_factor = 0.5; # 60%
|
||||
me.Styles.FIX.scale_factor = 0.5; # 50%
|
||||
|
||||
me.Styles.FIX.text_offset = [0, -12];
|
||||
me.Styles.FIX.text_color = [0,0,0,1]; # Black text ...
|
||||
|
@ -68,11 +68,19 @@ var NavigationMapStyles =
|
|||
me.Styles.NDB.text_padding = 2;
|
||||
me.Styles.NDB.text_alignment = 'center-bottom';
|
||||
|
||||
|
||||
me.Styles.VOR = {};
|
||||
me.Styles.VOR.range_line_width = 2;
|
||||
me.Styles.VOR.radial_line_width = 1;
|
||||
me.Styles.VOR.scale_factor = 0.6; # 60%
|
||||
me.Styles.VOR_FG1000 = {};
|
||||
me.Styles.VOR_FG1000.line_width = 1;
|
||||
me.Styles.VOR_FG1000.scale_factor = 1.0; # 50%
|
||||
me.Styles.VOR_FG1000.circle_radius = 128;
|
||||
me.Styles.VOR_FG1000.icon_color = [0.0,0.0,0.5];
|
||||
me.Styles.VOR_FG1000.circle_color = [0.2,0.8,0.8];
|
||||
me.Styles.VOR_FG1000.text_offset = [0, -12];
|
||||
me.Styles.VOR_FG1000.text_color = [0,0,0,1]; # Black text ...
|
||||
me.Styles.VOR_FG1000.text_bgcolor = [1,1,1,1]; # ... on a white background
|
||||
me.Styles.VOR_FG1000.text_mode = canvas.Text.TEXT + canvas.Text.FILLEDBOUNDINGBOX;
|
||||
me.Styles.VOR_FG1000.text_padding = 2;
|
||||
me.Styles.VOR_FG1000.text_alignment = 'center-bottom';
|
||||
me.Styles.VOR_FG1000.font_size = 14;
|
||||
|
||||
me.Styles.APS = {};
|
||||
me.Styles.APS.scale_factor = 0.25;
|
||||
|
|
|
@ -113,8 +113,6 @@ var NearestIntersections =
|
|||
|
||||
if (nav == nil) return;
|
||||
|
||||
debug.dump(nav);
|
||||
|
||||
if (nav.lat < 0.0) {
|
||||
me.setTextElement("Lat", sprintf("S %.4f", -nav.lat));
|
||||
} else {
|
||||
|
|
|
@ -10,34 +10,148 @@ var NearestVOR =
|
|||
],
|
||||
};
|
||||
|
||||
obj.topMenu(device, obj, nil);
|
||||
|
||||
obj.setController(fg1000.NearestVORController.new(obj, svg));
|
||||
|
||||
# Dynamic elements. There is a single dynamic element containing the list of
|
||||
# the 25 nearest intersections.
|
||||
obj.select = PFD.GroupElement.new(
|
||||
obj.pageName,
|
||||
svg,
|
||||
[ "Arrow", "ID", "CRS", "DST"],
|
||||
11,
|
||||
"Arrow",
|
||||
1,
|
||||
"ScrollTrough",
|
||||
"ScrollThumb",
|
||||
250 - 116
|
||||
);
|
||||
|
||||
# Other dynamic text elements
|
||||
obj.addTextElements(["Lat", "Lon", "Name", "Freq"]);
|
||||
|
||||
obj.topMenu(device, obj, nil);
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
# Indicate which group is selected by colour of the softkeys
|
||||
display_toggle : func(device, svg, mi, group) {
|
||||
var bg_name = sprintf("SoftKey%d-bg",mi.menu_id);
|
||||
if (me.getController().getSelectedGroup() == group) {
|
||||
device.svg.getElementById(bg_name).setColorFill(0.5,0.5,0.5);
|
||||
svg.setColor(0.0,0.0,0.0);
|
||||
} else {
|
||||
device.svg.getElementById(bg_name).setColorFill(0.0,0.0,0.0);
|
||||
svg.setColor(1.0,1.0,1.0);
|
||||
}
|
||||
svg.setText(mi.title);
|
||||
svg.setVisible(1); # display function
|
||||
},
|
||||
|
||||
# Function to highlight the VOR softkey - used when CRSR is pressed to indicate
|
||||
# that we're editing the VOR selection.
|
||||
selectVOR : func() {
|
||||
me.resetMenuColors();
|
||||
var bg_name = sprintf("SoftKey%d-bg",4);
|
||||
var tname = sprintf("SoftKey%d",4);
|
||||
me.device.svg.getElementById(bg_name).setColorFill(0.5,0.5,0.5);
|
||||
me.device.svg.getElementById(tname).setColor(0.0,0.0,0.0);
|
||||
},
|
||||
|
||||
hideCRSR : func() {
|
||||
me.select.hideCRSR();
|
||||
me.unhighlightTextElement("Freq");
|
||||
me.resetMenuColors();
|
||||
},
|
||||
|
||||
offdisplay : func() {
|
||||
me._group.setVisible(0);
|
||||
# The Nearest... pages use the underlying navigation map.
|
||||
me.mfd.NavigationMap.offdisplayPartial();
|
||||
|
||||
# Reset the menu colours. Shouldn't have to do this here, but
|
||||
# there's not currently an obvious other location to do so.
|
||||
for(var i = 0; i < 12; i +=1) {
|
||||
var name = sprintf("SoftKey%d",i);
|
||||
me.device.svg.getElementById(name ~ "-bg").setColorFill(0.0,0.0,0.0);
|
||||
me.device.svg.getElementById(name).setColor(1.0,1.0,1.0);
|
||||
}
|
||||
me.resetMenuColors();
|
||||
|
||||
me.getController().offdisplay();
|
||||
},
|
||||
ondisplay : func() {
|
||||
me._group.setVisible(1);
|
||||
me.mfd.setPageTitle(me.title);
|
||||
me.getController().ondisplay();
|
||||
|
||||
# The Nearest... pages use the underlying navigation map.
|
||||
me.mfd.NavigationMap.ondisplayPartial();
|
||||
|
||||
me.mfd.setPageTitle(me.title);
|
||||
},
|
||||
updateNavData : func(navdata) {
|
||||
|
||||
if ((navdata == nil) or (size(navdata) == 0)) return;
|
||||
|
||||
var navDataList = [];
|
||||
for (var i = 0; i < size(navdata); i = i + 1) {
|
||||
var nav = navdata[i];
|
||||
var crsAndDst = courseAndDistance(nav);
|
||||
|
||||
# Display the course and distance in NM .
|
||||
# 248 is the extended ASCII code for the degree symbol
|
||||
var crs = sprintf("%i%c", crsAndDst[0], 248);
|
||||
var dst = sprintf("%.1fnm", crsAndDst[1]);
|
||||
|
||||
# Convert into something we can pass straight to the UIGroup.
|
||||
append(navDataList, {
|
||||
Arrow : nav.id,
|
||||
ID: nav.id,
|
||||
CRS: crs,
|
||||
DST: dst,
|
||||
});
|
||||
}
|
||||
|
||||
me.select.setValues(navDataList);
|
||||
|
||||
if (size(navDataList) > 0) {
|
||||
me.updateNavDataItem(navdata[0]);
|
||||
} else {
|
||||
me.setTextElement("Name", "NONE WITHIN 200NM");
|
||||
me.setTextElement("Lon", "");
|
||||
me.setTextElement("Lat", "");
|
||||
me.setTextElement("Frequency", "");
|
||||
}
|
||||
},
|
||||
updateNavDataItem : func(nav) {
|
||||
|
||||
if (nav == nil) return;
|
||||
|
||||
if (nav.lat < 0.0) {
|
||||
me.setTextElement("Lat", sprintf("S %.4f", -nav.lat));
|
||||
} else {
|
||||
me.setTextElement("Lat", sprintf("N %.4f", nav.lat));
|
||||
}
|
||||
|
||||
if (nav.lon < 0.0) {
|
||||
me.setTextElement("Lon", sprintf("W%3.4f", -nav.lon));
|
||||
} else {
|
||||
me.setTextElement("Lon", sprintf("E%3.4f", nav.lon));
|
||||
}
|
||||
|
||||
me.setTextElement("Freq", sprintf("%.2f", nav.frequency / 100.0));
|
||||
me.setTextElement("Name", nav.name);
|
||||
|
||||
# Display the DTO line to the airport
|
||||
me.mfd.NavigationMap.getController().setDTOLineTarget(nav.lat, nav.lon);
|
||||
},
|
||||
|
||||
topMenu : func(device, pg, menuitem) {
|
||||
pg.clearMenu();
|
||||
pg.resetMenuColors();
|
||||
device.updateMenus();
|
||||
pg.addMenuItem(0, "ENGINE", pg, pg.mfd.EIS.engineMenu);
|
||||
pg.addMenuItem(2, "MAP", pg, pg.mfd.NavigationMap.mapMenu);
|
||||
pg.addMenuItem(4, "VOR", pg,
|
||||
func(dev, pg, mi) { pg.getController().selectVOR(); device.updateMenus(); }, # callback
|
||||
func(svg, mi) { pg.display_toggle(device, svg, mi, NearestVORController.UIGROUP.VOR); }
|
||||
);
|
||||
|
||||
pg.addMenuItem(5, "FREQ", pg,
|
||||
func(dev, pg, mi) { pg.getController().selectFrequencies(); device.updateMenus(); }, # callback
|
||||
func(svg, mi) { pg.display_toggle(device, svg, mi, NearestVORController.UIGROUP.FREQ); }
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -1,59 +1,154 @@
|
|||
# NearestVOR Controller
|
||||
var NearestVORController =
|
||||
{
|
||||
|
||||
UIGROUP : {
|
||||
NONE : 0, # No group currently selected,
|
||||
VOR : 1,
|
||||
FREQ : 2,
|
||||
},
|
||||
|
||||
new : func (page, svg)
|
||||
{
|
||||
var obj = {
|
||||
parents : [ NearestVORController, MFDPageController.new(page) ],
|
||||
_crsrToggle : 0,
|
||||
_recipient : nil,
|
||||
_page : page,
|
||||
};
|
||||
var obj = { parents : [ NearestVORController, MFDPageController.new(page) ] };
|
||||
|
||||
obj.page = page;
|
||||
obj._currentGroup = NearestVORController.UIGROUP.NONE;
|
||||
obj._crsrToggle = 0;
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
selectVOR : func() {
|
||||
me.selectGroup(NearestVORController.UIGROUP.VOR)
|
||||
},
|
||||
selectFrequencies : func() {
|
||||
me.selectGroup(NearestVORController.UIGROUP.FREQ);
|
||||
},
|
||||
getSelectedGroup : func() {
|
||||
return me._currentGroup;
|
||||
},
|
||||
selectGroup : func(grp) {
|
||||
me._currentGroup = grp;
|
||||
if (grp == NearestVORController.UIGROUP.VOR) me.page.select.showCRSR() else me.page.select.hideCRSR();
|
||||
if (grp == NearestVORController.UIGROUP.FREQ) me.page.highlightTextElement("Freq") else me.page.unhighlightTextElement("Freq");
|
||||
me._crsrToggle = 1;
|
||||
},
|
||||
|
||||
|
||||
# Input Handling
|
||||
handleCRSR : func() {
|
||||
me._crsrToggle = (! me._crsrToggle);
|
||||
if (me._crsrToggle) {
|
||||
me.page.topMenu(me.page.device, me.page, nil);
|
||||
me.page.selectVOR();
|
||||
me.selectVOR();
|
||||
} else {
|
||||
me._page.hideCRSR();
|
||||
me.page.hideCRSR();
|
||||
}
|
||||
|
||||
return emesary.Transmitter.ReceiptStatus_Finished;
|
||||
},
|
||||
handleFMSInner : func(value) {
|
||||
if (me._crsrToggle == 1) {
|
||||
# Scroll through whatever is the current list
|
||||
if (me._currentGroup == NearestVORController.UIGROUP.VOR) {
|
||||
# Scroll through whatever is the current list
|
||||
me.page.select.incrSmall(value);
|
||||
var id = me.page.select.getValue();
|
||||
var data = me.getNavDataItem(id);
|
||||
if ((data != nil) and (size(data) >0)) me.page.updateNavDataItem(data[0]);
|
||||
}
|
||||
return emesary.Transmitter.ReceiptStatus_Finished;
|
||||
} else {
|
||||
# Pass to the page group controller to display and scroll through the page group menu
|
||||
return me._page.mfd.SurroundController.handleFMSInner(value);
|
||||
return me.page.mfd.SurroundController.handleFMSInner(value);
|
||||
}
|
||||
},
|
||||
handleFMSOuter : func(value) {
|
||||
if (me._crsrToggle == 1) {
|
||||
if (me._currentGroup == NearestVORController.UIGROUP.VOR) {
|
||||
# Scroll through whatever is the current list
|
||||
me.page.select.incrSmall(value);
|
||||
var id = me.page.select.getValue();
|
||||
var data = me.getNavDataItem(id);
|
||||
if ((data != nil) and (size(data) >0)) me.page.updateNavDataItem(data[0]);
|
||||
}
|
||||
return emesary.Transmitter.ReceiptStatus_Finished;
|
||||
} else {
|
||||
# Pass to the page group controller to display and scroll through the page group menu
|
||||
return me._page.mfd.SurroundController.handleFMSOuter(value);
|
||||
return me.page.mfd.SurroundController.handleFMSOuter(value);
|
||||
}
|
||||
},
|
||||
handleEnter : func(value) {
|
||||
if (me._crsrToggle == 1) {
|
||||
if (me._currentGroup == NearestVORController.UIGROUP.VOR) {
|
||||
# Scroll through whatever is the current list
|
||||
me.page.select.incrSmall(value);
|
||||
var id = me.page.select.getValue();
|
||||
var data = me.getNavDataItem(id);
|
||||
if ((data != nil) and (size(data) >0)) me.page.updateNavDataItem(data[0]);
|
||||
}
|
||||
if (me._currentGroup == NearestVORController.UIGROUP.FREQ) {
|
||||
var freq = me.page.getTextValue("Freq");
|
||||
if (freq != nil) {
|
||||
me.page.mfd.SurroundController.setStandbyNavComFreq(freq);
|
||||
}
|
||||
}
|
||||
|
||||
return emesary.Transmitter.ReceiptStatus_Finished;
|
||||
} else {
|
||||
return emesary.Transmitter.ReceiptStatus_NotProcessed;
|
||||
}
|
||||
},
|
||||
|
||||
handleRange : func(val)
|
||||
{
|
||||
# Pass any range entries to the NavMapController
|
||||
me.page.mfd.NavigationMap.getController().handleRange(val);
|
||||
},
|
||||
|
||||
# Reset controller if required when the page is displayed or hidden
|
||||
ondisplay : func() {
|
||||
me.RegisterWithEmesary();
|
||||
var fixes = me.getNearestNavData("vor");
|
||||
me.page.updateNavData(fixes);
|
||||
me.page.mfd.NavigationMap.getController().enableDTO(1);
|
||||
me._crsrToggle = 0;
|
||||
me.page.hideCRSR();
|
||||
},
|
||||
offdisplay : func() {
|
||||
me.page.mfd.NavigationMap.getController().enableDTO(0);
|
||||
me.DeRegisterWithEmesary();
|
||||
},
|
||||
|
||||
getNearestNavData : func(type) {
|
||||
var notification = notifications.PFDEventNotification.new(
|
||||
"MFD",
|
||||
1,
|
||||
notifications.PFDEventNotification.NavData,
|
||||
{Id: "NavDataWithinRange", Value: type});
|
||||
|
||||
var response = me._transmitter.NotifyAll(notification);
|
||||
|
||||
if (! me._transmitter.IsFailed(response)) {
|
||||
return notification.EventParameter.Value;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
},
|
||||
|
||||
getNavDataItem : func(id) {
|
||||
# Use Emesary to get the Navigation data
|
||||
var notification = notifications.PFDEventNotification.new(
|
||||
"MFD",
|
||||
1,
|
||||
notifications.PFDEventNotification.NavData,
|
||||
{Id: "NavAidByID", Value: { id: id, type: "vor"} });
|
||||
|
||||
var response = me._transmitter.NotifyAll(notification);
|
||||
|
||||
if (! me._transmitter.IsFailed(response)) {
|
||||
return notification.EventParameter.Value;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1491,6 +1491,7 @@ OverlayLayer.Controller = {
|
|||
###
|
||||
# set up a cache for 32x32 symbols (initialized below in load_MapStructure)
|
||||
var SymbolCache32x32 = nil;
|
||||
var SymbolCache256x256 = nil;
|
||||
|
||||
var MapStructure = {
|
||||
# Generalized load methods used to load various symbols, layer controllers,...
|
||||
|
@ -1609,6 +1610,7 @@ var load_MapStructure = func {
|
|||
|
||||
# sets up a shared symbol cache, which will be used by all MapStructure maps and layers
|
||||
canvas.SymbolCache32x32 = SymbolCache.new(1024,32);
|
||||
canvas.SymbolCache256x256 = SymbolCache.new(1024,256);
|
||||
|
||||
# Find files and load them:
|
||||
var contents_dir = FG_ROOT~"/Nasal/canvas/map/";
|
||||
|
|
Loading…
Reference in a new issue