diff --git a/Aircraft/Instruments-3d/FG1000/MFDPages/PFDInstruments.svg b/Aircraft/Instruments-3d/FG1000/MFDPages/PFDInstruments.svg
index a3c61f79d..866a2e904 100644
--- a/Aircraft/Instruments-3d/FG1000/MFDPages/PFDInstruments.svg
+++ b/Aircraft/Instruments-3d/FG1000/MFDPages/PFDInstruments.svg
@@ -24,11 +24,11 @@
borderopacity="1"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
- inkscape:zoom="7.4375004"
- inkscape:cx="279.11962"
- inkscape:cy="261.78273"
+ inkscape:zoom="3.7187502"
+ inkscape:cx="99.463593"
+ inkscape:cy="150.41314"
inkscape:document-units="px"
- inkscape:current-layer="layer6"
+ inkscape:current-layer="svg3140"
showgrid="false"
showguides="false"
inkscape:guide-bbox="true"
@@ -75,7 +75,7 @@
image/svg+xml
-
+
@@ -6998,13 +6998,67 @@
id="PFDInstrumentsPFD-Map"
inkscape:label="PFD-Map">
+ style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:1.005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="PFDInstrumentsPFD-Map-bg-1"
+ width="218.99536"
+ height="218.99538"
+ x="9.3594561"
+ y="491.24179"
+ inkscape:label="PFD-Map-bg" />
+
+
+
+
+ NORTH UP
+
+ 15nm
.
+#
+# FMS Interface using Emesary to update FMS properties from Emesary messages.
+
+var GenericFMSUpdater =
+{
+ new : func () {
+ var obj = {
+ parents : [
+ GenericFMSUpdater,
+ PropertyUpdater.new(
+ notifications.PFDEventNotification.DefaultType,
+ notifications.PFDEventNotification.FMSData,
+ )
+ ],
+ };
+
+ obj.addPropMap("FMSHeadingBug", "/autopilot/settings/heading-bug-deg");
+ obj.addPropMap("FMSSelectedAlt", "/autopilot/settings/target-alt-ft");
+ obj.addPropMap("FMSPressureSettingInHG", "/instrumentation/altimeter/setting-inhg");
+ return obj;
+ },
+};
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/GenericInterfaceController.nas b/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/GenericInterfaceController.nas
index 2ac874175..d19cbb82c 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/GenericInterfaceController.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/Interfaces/GenericInterfaceController.nas
@@ -24,6 +24,7 @@ io.load_nasal(nasal_dir ~ 'Interfaces/GenericNavComPublisher.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'Interfaces/GenericNavComUpdater.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'Interfaces/NavDataInterface.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'Interfaces/GenericFMSPublisher.nas', "fg1000");
+io.load_nasal(nasal_dir ~ 'Interfaces/GenericFMSUpdater.nas', "fg1000");
io.load_nasal(nasal_dir ~ 'Interfaces/GenericADCPublisher.nas', "fg1000");
@@ -51,6 +52,7 @@ var GenericInterfaceController = {
obj.navcomUpdater = fg1000.GenericNavComUpdater.new();
obj.navdataInterface = fg1000.NavDataInterface.new();
obj.gpsPublisher = fg1000.GenericFMSPublisher.new();
+ obj.gpsUpdater = fg1000.GenericFMSUpdater.new();
obj.adcPublisher = fg1000.GenericADCPublisher.new();
return obj;
},
@@ -62,6 +64,7 @@ var GenericInterfaceController = {
me.navcomUpdater.start();
me.navdataInterface.start();
me.gpsPublisher.start();
+ me.gpsUpdater.start();
me.adcPublisher.start();
},
@@ -72,6 +75,7 @@ var GenericInterfaceController = {
me.navcomUpdater.stop();
me.navdataInterface.stop();
me.gpsPublisher.stop();
+ me.gpsUpdater.stop();
me.adcPublisher.stop();
},
};
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPage.nas b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPage.nas
index 7b3cf932b..207f9fa61 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPage.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPage.nas
@@ -146,5 +146,14 @@ getDevice : func() {
getMFD : func() {
return me.mfd;
},
+getPageName : func () {
+ return me.pageName;
+},
+getSVG : func() {
+ return me._SVGGroup;
+},
+getGroup : func() {
+ return me._group;
+}
};
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPageController.nas b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPageController.nas
index d1218a639..554740766 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPageController.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPageController.nas
@@ -44,7 +44,7 @@ handleNavFreqTransfer : func (value) { return me.page.mfd.SurroundController.han
handleNavOuter : func (value) { return me.page.mfd.SurroundController.handleNavOuter(value); },
handleNavInner : func (value) { return me.page.mfd.SurroundController.handleNavInner(value); },
handleNavToggle : func (value) { return me.page.mfd.SurroundController.handleNavToggle(value); },
-handleHeading : func (value) { return emesary.Transmitter.ReceiptStatus_NotProcessed; },
+handleHeading : func (value) { return me.page.mfd.SurroundController.handleHeading(value); },
handleHeadingPress : func (value) { return emesary.Transmitter.ReceiptStatus_NotProcessed; },
# Joystick
@@ -53,7 +53,7 @@ handleJoystickHorizontal : func (value) { return emesary.Transmitter.ReceiptStat
handleJoystickHorizontal : func (value) { return emesary.Transmitter.ReceiptStatus_NotProcessed; },
#CRS/BARO
-handleBaro : func (value) { return emesary.Transmitter.ReceiptStatus_NotProcessed; },
+handleBaro : func (value) { return me.page.mfd.SurroundController.handleBaro(value); },
handleCRS : func (value) { return emesary.Transmitter.ReceiptStatus_NotProcessed; },
handleCRSCenter : func (value) { return emesary.Transmitter.ReceiptStatus_NotProcessed; },
@@ -94,8 +94,8 @@ handleMenu : func (value) { return emesary.Transmitter.ReceiptStatus_NotProcess
handleProc : func (value) { return emesary.Transmitter.ReceiptStatus_NotProcessed; },
handleEnter : func (value) { return emesary.Transmitter.ReceiptStatus_NotProcessed; },
-handleAltOuter : func (value) { return emesary.Transmitter.ReceiptStatus_NotProcessed; },
-handleAltInner : func (value) { return emesary.Transmitter.ReceiptStatus_NotProcessed; },
+handleAltOuter : func (value) { return me.page.mfd.SurroundController.handleAltOuter(value); },
+handleAltInner : func (value) { return me.page.mfd.SurroundController.handleAltInner(value); },
RegisterWithEmesary : func()
{
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/NavigationMap/NavigationMapController.nas b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/NavigationMap/NavigationMapController.nas
index ffe88d45e..4a9e34493 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/NavigationMap/NavigationMapController.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/NavigationMap/NavigationMapController.nas
@@ -17,75 +17,7 @@
# Navigation Map Controller
var NavigationMapController =
{
- # Vertical ranges, and labels.
- # 28 ranges from 500ft to 2000nm, measuring the vertical map distance.
- # Vertical size of the map (once the nav box and softkey area is removed) is 689px.
- # 2000nm = 12,152,000ft.
- RANGES : [{range: 500/6076.12, label: "500ft"},
- {range: 750/6076.12, label: "750ft"},
- {range: 1000/6076.12, label: "1000ft"},
- {range: 1500/6076.12, label: "1500ft"},
- {range: 2000/6076.12, label: "2000ft"},
- {range: 0.5, label: "0.5nm"},
- {range: 0.75, label: "0.75nm"},
- {range: 1, label: "1nm"},
- {range: 2, label: "2nm"},
- {range: 3, label: "3nm"},
- {range: 4, label: "4nm"},
- {range: 6, label: "6nm"},
- {range: 8, label: "8nm"},
- {range: 10, label: "10nm"},
- {range: 12, label: "12nm"},
- {range: 15, label: "15nm"},
- {range: 20, label: "20nm"},
- {range: 25, label: "25nm"},
- {range: 30, label: "30nm"},
- {range: 40, label: "40nm"},
- {range: 50, label: "50nm"},
- {range: 75, label: "75nm"},
- {range: 100, label: "100nm"},
- {range: 200, label: "200nm"},
- {range: 500, label: "500nm"},
- {range: 1000, label: "1000nm"},
- {range: 1500, label: "1500nm"},
- {range: 2000, label: "2000nm"}, ],
- ORIENTATIONS : [
- { label: "NORTH UP" },
- { label: "TRK UP" },
- { label: "DTK UP" },
- { label: "HDG UP" },
- ],
-
- # Layer display configuration:
- # enabled - whether this layer has been enabled by the user
- # declutter - the maximum declutter level (0-3) that this layer is visible in
- # range - the maximum range this layer is visible (configured by user)
- # max_range - the maximum range value that a user can configure for this layer.
- LAYER_RANGES : {
- DTO : { enabled: 0, declutter: 3, range: 2000, max_range: 2000 },
-
- GRID : { enabled: 0, declutter: 1, range: 20, max_range: 2000 },
- DME : { 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 },
- WPT : { enabled: 1, declutter: 3, range: 2000, max_range: 2000 },
-
- APS : { enabled: 1, declutter: 3, range: 2000, max_range: 2000 },
- FLT : { enabled: 1, declutter: 3, range: 2000, max_range: 2000 },
-
- WXR : { enabled: 1, declutter: 2, range: 2000, max_range: 2000 },
-
- APT : { enabled: 1, declutter: 2, range: 150, max_range: 300 },
-
- TFC : { enabled: 0, declutter: 3, range: 150, max_range: 2000},
-
- OpenAIP : { enabled: 1, declutter: 1, range: 150, max_range: 300 },
- STAMEN : { enabled: 1, declutter: 3, range: 500, max_range: 2000 },
- STAMEN_terrain : { enabled: 1, declutter: 3, range: 500, max_range: 2000 },
- },
# TODO: Add STAMEN topo layer, which is visible on all levels as opposed to
# roads, railways, boundaries, cities which are only visible on declutter 0.
@@ -96,7 +28,6 @@ var NavigationMapController =
# Airways levels.
AIRWAYS : [ "AIRWAYS", "AIRWY ON", "AIRWY LO", "AIRWY HI"],
-
new : func (page, svg)
{
var obj = { parents : [ NavigationMapController, MFDPageController.new(page) ] };
@@ -105,7 +36,7 @@ var NavigationMapController =
obj.airways = 0;
obj.page = page;
obj.setZoom(obj.current_zoom);
- obj.setOrientation(obj.ORIENTATIONS[0]);
+ obj.setOrientation(fg1000.ORIENTATIONS[0]);
return obj;
},
@@ -116,12 +47,12 @@ var NavigationMapController =
me.setZoom(me.current_zoom +1);
},
setZoom : func(zoom) {
- if ((zoom < 0) or (zoom > (size(me.RANGES) - 1))) return;
+ if ((zoom < 0) or (zoom > (size(fg1000.RANGES) - 1))) return;
me.current_zoom = zoom;
# Ranges above represent vertical ranges, but the display is a rectangle, so
# we need to use the diagonal range of the 1024 x 689, which is 617px.
# 617px is 1.8 x 689/2, so we need to increase the range values by x1.8
- me.page.setRange(me.RANGES[zoom].range, me.RANGES[zoom].label);
+ me.page.setRange(fg1000.RANGES[zoom].range, fg1000.RANGES[zoom].label);
me.updateVisibility();
},
setOrientation : func(orientation) {
@@ -129,10 +60,10 @@ var NavigationMapController =
},
updateVisibility : func() {
# Determine which layers should be visible.
- foreach (var layer_name; keys(me.LAYER_RANGES)) {
- var layer = me.LAYER_RANGES[layer_name];
+ foreach (var layer_name; me.page.mfd.ConfigStore.getLayerNames()) {
+ var layer = me.page.mfd.ConfigStore.getLayer(layer_name);
if (layer.enabled and
- (me.RANGES[me.current_zoom].range <= layer.range) and
+ (fg1000.RANGES[me.current_zoom].range <= layer.range) and
(me.declutter <= layer.declutter) )
{
me.page.MFDMap.getLayer(layer_name).setVisible(1);
@@ -141,15 +72,11 @@ var NavigationMapController =
}
}
},
- configureLayer : func(layer, enabled, range) {
- me.LAYER_RANGES[layer].enabled = enabled;
- me.LAYER_RANGES[layer].range = math.min(range, me.LAYER_RANGES[layer].max_range);
- },
isEnabled : func(layer) {
- return me.LAYER_RANGES[layer].enabled;
+ return me.page.mfd.ConfigStore.isLayerEnabled(layer);
},
toggleLayer : func(layer) {
- me.LAYER_RANGES[layer].enabled = ! me.LAYER_RANGES[layer].enabled;
+ me.page.mfd.ConfigStore.toggleLayerEnabled(layer);
me.updateVisibility();
},
@@ -162,6 +89,10 @@ var NavigationMapController =
me.updateVisibility();
},
+ getDCLTRTitle : func() {
+ return me.DCLTR[me.declutter];
+ },
+
# Increment through the AIRWAYS levels. At present this doesn't do anything
# except change the label. It should enable/disable different airways
# information.
@@ -171,13 +102,16 @@ var NavigationMapController =
device.updateMenus();
me.updateVisibility();
},
+ getAIRWAYSTitle : func() {
+ return me.AIRWAYS[me.airways];
+ },
# Set the DTO line target
setDTOLineTarget : func(lat, lon) {
me.page.MFDMap.getLayer("DTO").controller.setTarget(lat,lon);
},
enableDTO : func(enable) {
- me.LAYER_RANGES["DTO"].enabled = enable;
+ me.page.mfd.ConfigStore.setLayerEnabled("DTO", enable);
me.updateVisibility();
},
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstruments.nas b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstruments.nas
index 15785673a..f930916cd 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstruments.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstruments.nas
@@ -28,6 +28,10 @@ var PFDInstruments =
magenta : [1, 0, 1],
},
+ CDI_SOURCE : [ "GPS", "NAV1", "NAV2" ],
+
+ BRG_SOURCE : ["OFF", "NAV1", "NAV2", "GPS", "ADF"],
+
new : func (mfd, myCanvas, device, svg)
{
var obj = {
@@ -38,7 +42,7 @@ var PFDInstruments =
_ias_already_exceeded : 0,
_windDataDisplay : 0,
- _CDISource : "OFF",
+ _CDISource : "GPS",
_BRG1 : "OFF",
_BRG2 : "OFF",
_DME : 0,
@@ -46,6 +50,7 @@ var PFDInstruments =
_Map : 0,
_Multiline : 0,
_annunciation : 0,
+
};
# Hide various elements for the moment. TODO - implement
@@ -78,12 +83,17 @@ var PFDInstruments =
obj.device.svg.getElementById("PFDInstruments" ~ id).set("clip", clip);
}
+ #obj.insetMap = fg1000.NavMap.new(obj, [130,170], "rect(-160px, 160px, 160px, -160px)", -100, 2);
+ obj._SVGGroup.setInt("z-index", 10);
+ #obj._SVGGroup.setVisible(0);
+ #obj.insetMap = fg1000.NavMap.new(obj, [119,601], "rect(-109px, 109px, 109px, -109px)", 50, 2);
+ obj.insetMap = fg1000.NavMap.new(obj, obj.getElement("PFD-Map-Display"), [119,601], "rect(-109px, 109px, 109px, -109px)", 0, 2);
#obj.topMenu(device, obj, nil);
obj.setController(fg1000.PFDInstrumentsController.new(obj, svg));
obj.setWindDisplay(0);
- obj.setCDISource("OFF");
+ obj.setCDISource("GPS");
obj.setBRG1("OFF");
obj.setBRG2("OFF");
obj.setDME(0);
@@ -91,6 +101,10 @@ var PFDInstruments =
obj.setMultiline(0);
obj.setAnnunciation(0);
obj.setOMI("");
+ obj.setInsetMapVisible(0);
+ obj.updateHDG(0);
+ obj.updateSelectedALT(0);
+ obj.updateCRS(0);
return obj;
},
@@ -99,11 +113,11 @@ var PFDInstruments =
topMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
- pg.addMenuItem(1, "INSET", pg); # TODO
+ pg.addMenuItem(1, "INSET", pg, pg.mfd.PFDInstruments.insetMenu);
pg.addMenuItem(3, "PFD", pg, pg.mfd.PFDInstruments.PFDMenu);
pg.addMenuItem(4, "OBS", pg); # TODO
- pg.addMenuItem(5, "CDI", pg); # TODO
- pg.addMenuItem(6, "DME", pg); # TODO
+ pg.addMenuItem(5, "CDI", pg, pg.incrCDI);
+ #pg.addMenuItem(6, "DME", pg, func(dev, pg, mi) { pg.toggleDME(); } ); # TODO
pg.addMenuItem(7, "XPDR", pg); # TODO
pg.addMenuItem(8, "IDENT", pg); # TODO
pg.addMenuItem(9, "TMR/REF", pg); # TODO
@@ -112,24 +126,121 @@ var PFDInstruments =
device.updateMenus();
},
+ incrCDI : func(dev, pg, mi) {
+ var idx = -1;
+ for (var i = 0; i < size(PFDInstruments.CDI_SOURCE); i = i + 1) {
+ if (PFDInstruments.CDI_SOURCE[i] == pg._CDISource) {
+ idx = i;
+ break;
+ }
+ }
+
+ if (idx == -1) die("Unabled to increment CDI. _CDISource:" ~ me._CDISource);
+
+ idx = math.mod(idx + 1, size(PFDInstruments.CDI_SOURCE));
+ pg.setCDISource(PFDInstruments.CDI_SOURCE[idx]);
+ },
+
+ insetMenu : func(device, pg, menuitem) {
+
+ # Switch on the inset Map
+ pg.setInsetMapVisible(1);
+
+ pg.clearMenu();
+ pg.resetMenuColors();
+ pg.addMenuItem(0, "OFF", pg, func(dev, pg, mi) { pg.setInsetMapVisible(0); }); # TODO
+ pg.addMenuItem(1, "DCLTR", pg,
+ func(dev, pg, mi) { pg.insetMap.incrDCLTR(dev, mi); device.updateMenus(); },
+ func(svg, mi) { pg.displayDCLTR(svg, mi); },
+ );
+ #pg.addMenuItem(2, "WXLGND", pg); # Optional
+
+ # TODO: Support TRFC-1 to add traffic layer, TRFC-2 to just display a traffic map
+ pg.addMenuItem(3, "TRAFFIC", pg,
+ func(dev, pg, mi) { pg.insetMap.toggleLayer("TFC"); device.updateMenus(); }, # callback
+ func(svg, mi) { pg.display_toggle(device, svg, mi, "TFC"); }
+ );
+
+ pg.addMenuItem(4, "TOPO", pg,
+ func(dev, pg, mi) { pg.insetMap.toggleLayer("STAMEN"); device.updateMenus(); }, # callback
+ func(svg, mi) { pg.display_toggle(device, svg, mi, "STAMEN"); }
+ );
+
+ pg.addMenuItem(5, "TERRAIN", pg,
+ func(dev, pg, mi) { pg.insetMap.toggleLayer("STAMEN_terrain"); device.updateMenus(); }, # callback
+ func(svg, mi) { pg.display_toggle(device, svg, mi, "STAMEN_terrain"); }
+ );
+ #pg.addMenuItem(6, "STRMSCP", pg); # TODO
+ #pg.addMenuItem(7, "NEXRAD", pg); # TODO
+ #pg.addMenuItem(8, "XM LTNG", pg); # TODO
+ #pg.addMenuItem(9, "METAR", pg); # TODO
+ pg.addMenuItem(10, "BACK", pg, pg.mfd.PFDInstruments.topMenu);
+ pg.addMenuItem(11, "ALERTS", pg); # TODO
+ device.updateMenus();
+ },
+
+ displayDCLTR : func(svg, mi) {
+ mi.title = pg.mfd.PFDInstruments.insetMap.getDCLTRTitle();
+ svg.setText(mi.title);
+ svg.setVisible(1);
+ },
+
+ # Display map toggle softkeys which change color depending
+ # on whether a particular layer is enabled or not.
+ display_toggle : func(device, svg, mi, layer) {
+ var bg_name = sprintf("SoftKey%d-bg",mi.menu_id);
+ if (me.insetMap.isEnabled(layer)) {
+ 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
+ },
+
PFDMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
pg.addMenuItem(0, "SYN VIS", pg); # TODO
pg.addMenuItem(1, "DFLTS", pg);
pg.addMenuItem(2, "WIND", pg, pg.mfd.PFDInstruments.windMenu);
- pg.addMenuItem(3, "DME", pg); # TODO
- pg.addMenuItem(4, "BRG1", pg); # TODO
+ #pg.addMenuItem(3, "DME", pg); # TODO
+ pg.addMenuItem(4, "BRG1", pg, pg.mfd.PFDInstruments.incrBRG1); # TODO
pg.addMenuItem(5, "HSI FRMT", pg); # TODO
- pg.addMenuItem(6, "BRG2", pg); # TODO
+ pg.addMenuItem(6, "BRG2", pg, pg.mfd.PFDInstruments.incrBRG2); # TODO
#pg.addMenuItem(8, "IDENT", pg); # TODO
pg.addMenuItem(8, "ALT UNIT ", pg); # TODO
- pg.addMenuItem(9, "STD BARO", pg); # TODO
+ pg.addMenuItem(9, "STD BARO", pg, func(dev, pg, mi) { pg.getController().setStdBaro(); } );
pg.addMenuItem(10, "BACK", pg, pg.mfd.PFDInstruments.topMenu);
pg.addMenuItem(11, "ALERTS", pg); # TODO
device.updateMenus();
},
+ incrBRG1 : func(dev, pg, mi) { pg.mfd.PFDInstruments.incrBRG("BRG1"); },
+ incrBRG2 : func(dev, pg, mi) { pg.mfd.PFDInstruments.incrBRG("BRG2"); },
+
+ incrBRG : func(brg) {
+ var curr = (brg == "BRG1" ? me.getBRG1() : me.getBRG2());
+ var idx = -1;
+ for (var i = 0; i < size(PFDInstruments.BRG_SOURCE); i = i + 1) {
+ if (PFDInstruments.BRG_SOURCE[i] == curr) {
+ idx = i;
+ break;
+ }
+ }
+
+ if (idx == -1) die("Unabled to increment BRG. curr:" ~ curr);
+
+ idx = math.mod(idx + 1, size(PFDInstruments.BRG_SOURCE));
+ if (brg == "BRG1") {
+ me.setBRG1(PFDInstruments.BRG_SOURCE[idx]);
+ } else {
+ me.setBRG2(PFDInstruments.BRG_SOURCE[idx]);
+ }
+ },
+
windMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
@@ -379,7 +490,7 @@ var PFDInstruments =
updateBARO : func (baro) {
# TODO: Support hPa and inhg
#var fmt = me._baro_unit == "inhg" ? "%.2fin" : "%i%shPa";
- var fmt = "%.2fin";
+ var fmt = "%.2fIN";
me.setTextElement("BARO-text", sprintf(fmt, baro));
},
@@ -394,7 +505,6 @@ var PFDInstruments =
},
updateHDG : func (hdg) {
- if (hdg == nil)
me.getElement("Heading-bug").setRotation(hdg * D2R);
me.setTextElement("SelectedHDG-text", sprintf("%03d°%s", hdg, ""));
},
@@ -459,6 +569,10 @@ var PFDInstruments =
}
},
+ toggleDME : func() {
+ me.setDME(! me._DME);
+ },
+
setDME : func (enabled) {
me._DME = enabled;
me.getElement("DME1").setVisible(enabled);
@@ -518,34 +632,48 @@ var PFDInstruments =
me._CDISource = source;
},
- updateCDI : func (heading, course, waypoint_valid, course_deviation_deg, deflection_dots, xtrk_nm, from) {
+ updateCDI : func (heading, course, waypoint_valid, course_deviation_deg, deflection_dots, xtrk_nm, from, annun) {
if (me._CDISource == "OFF") return;
- var rot = (course - heading) * D2R;
- me.getElement("CDI")
- .setRotation(rot)
- .show();
- me.getElement("GPS-CTI-diamond")
- .setVisible(waypoint_valid)
- .setRotation(course_deviation_deg * D2R);
-
- if ((me._CDISource == "GPS") and (deflection_dots > 2)) {
- # Only display the cross-track error if the error exceeds the maximum
- # deflection of two dots.
- me.getElement("CDI-GPS-XTK-text")
- .setText(sprintf("XTK %iNM", abs(xtrk_nm)))
- .show();
- } else {
+ if (waypoint_valid == 0) {
+ me.getElement(me._CDISource ~ "-CDI").hide();
+ me.getElement(me._CDISource ~ "-FROM").hide();
+ me.getElement(me._CDISource ~ "-TO").hide();
+ me.getElement("CDI").setRotation(0);
+ me.getElement("GPS-CTI-diamond").hide();
me.getElement("CDI-GPS-XTK-text").hide();
+ me.getElement("CDI-GPS-ANN-text").hide();
+ } else {
+ me.getElement(me._CDISource ~ "-CDI").show();
+
+ var rot = (course - heading) * D2R;
+ me.getElement("CDI")
+ .setRotation(rot)
+ .show();
+ me.getElement("GPS-CTI-diamond")
+ .setVisible(waypoint_valid)
+ .setRotation(course_deviation_deg * D2R);
+
+ if ((me._CDISource == "GPS") and (deflection_dots > 2)) {
+ # Only display the cross-track error if the error exceeds the maximum
+ # deflection of two dots.
+ me.getElement("CDI-GPS-XTK-text")
+ .setText(sprintf("XTK %iNM", abs(xtrk_nm)))
+ .show();
+ } else {
+ me.getElement("CDI-GPS-XTK-text").hide();
+ }
+
+ if (me._CDISource == "GPS") me.getElement("CDI-GPS-ANN-text").setText(annun).show();
+
+ var scale = math.clamp(deflection_dots, -2.4, 2.4);
+ me.getElement(me._CDISource ~ "-CDI").setTranslation(65 * scale, 0);
+
+ # Display the appropriate TO/FROM indication for the selected source,
+ # switching all others off.
+ me.getElement(me._CDISource ~ "-TO").setVisible(from == 0);
+ me.getElement(me._CDISource ~ "-FROM").setVisible(from);
}
-
- var scale = math.clamp(deflection_dots, -2.4, 2.4);
- me.getElement(me._CDISource ~ "-CDI").setTranslation(65 * scale, 0);
-
- # Display the appropriate TO/FROM indication for the selected source,
- # switching all others off.
- me.getElement(me._CDISource ~ "-TO").setVisible(from == 0);
- me.getElement(me._CDISource ~ "-FROM").setVisible(from);
},
# Update the wind display. There are three options:
@@ -631,5 +759,11 @@ var PFDInstruments =
me.getElement("MarkerText").setText(omi);
}
me._OMI = omi;
- }
+ },
+
+ setInsetMapVisible :func(enabled ) {
+ me.getElement("PFD-Map").setVisible(enabled);
+ me.getElement("PFD-Map-bg").setVisible(enabled);
+ me.insetMap.setVisible(enabled);
+ },
};
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstrumentsController.nas b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstrumentsController.nas
index 3237229f3..eb3391d02 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstrumentsController.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/PFDInstruments/PFDInstrumentsController.nas
@@ -17,11 +17,6 @@
# PFDInstruments Controller
var PFDInstrumentsController =
{
-
-
- # Declutter levels.
- WIND : [ "DCLTR", "DCLTR-1", "DCLTR-2", "DCLTR-3"],
-
new : func (page, svg)
{
var obj = {
@@ -35,6 +30,13 @@ var PFDInstrumentsController =
_selected_alt_ft : 0,
_heading : 0,
_source : "GPS",
+ _from :0,
+ _leg_id : "",
+ _leg_bearing : 0,
+ _leg_distance_nm : 0,
+ _leg_deviation_deg : 0,
+ _deflection_dots :0,
+ _leg_xtrk_nm : 0,
};
return obj;
@@ -74,6 +76,25 @@ var PFDInstrumentsController =
}
},
+ handleRange : func(val)
+ {
+ var incr_or_decr = (val > 0) ? me.page.insetMap.zoomIn() : me.page.insetMap.zoomOut();
+ },
+
+ # Set the STD BARO to 29.92 in Hg
+ setStdBaro : func() {
+ var data = {};
+ data["FMSPressureSettingInHG"] = 29.92;
+
+ var notification = notifications.PFDEventNotification.new(
+ "MFD",
+ me._page.mfd.getDeviceID(),
+ notifications.PFDEventNotification.FMSData,
+ data);
+
+ me.transmitter.NotifyAll(notification);
+ },
+
# Handle update of the airdata information.
# ADC data is produced periodically as an entire set
handleADCData : func(data) {
@@ -97,6 +118,7 @@ var PFDInstrumentsController =
me.page.updateVSI(data["ADCVerticalSpeedFPM"]);
me.page.updateTAS(data["ADCTrueAirspeed"]);
me.page.updateBARO(data["ADCPressureSettingInHG"]);
+
me.page.updateOAT(data["ADCOutsideAirTemperatureC"]);
me.page.updateHSI(data["ADCHeadingDeg"]);
me._heading = data["ADCHeadingDeg"];
@@ -113,31 +135,65 @@ var PFDInstrumentsController =
return emesary.Transmitter.ReceiptStatus_OK;
},
- # Handle update to the FMS information.
+ # Handle update to the FMS information. Note that there is no guarantee
+ # that the entire set of FMS data will be available.
handleFMSData : func(data) {
- me.page.updateHDG(data["FMSHeadingBug"]);
- me.page.updateSelectedALT(data["FMSSelectedAlt"]);
- me._selected_alt_ft = data["FMSSelectedAlt"];
-
- me.page.updateCRS(data["FMSLegBearing"]);
-
- var from = 0;
- if (me._navSelected == 1) {
- from = data["FMSNav1From"];
- } else {
- from = data["FMSNav2From"];
+ if (data["FMSHeadingBug"] != nil) me.page.updateHDG(data["FMSHeadingBug"]);
+ if (data["FMSSelectedAlt"] != nil) {
+ me.page.updateSelectedALT(data["FMSSelectedAlt"]);
+ me._selected_alt_ft = data["FMSSelectedAlt"];
}
- me.page.updateCDI(
- heading: me._heading,
- course: data["FMSLegBearing"],
- waypoint_valid: 1,
- course_deviation_deg : data["FMSLegTrackErrorAngle"],
- deflection_dots : data["FMSLegCourseError"], # TODO: proper conversion depending on source, environment
- xtrk_nm : data["FMSLegCourseError"],
- from: from,
- );
+ if (data["FMSLegValid"] == "false") {
+ # No valid leg data, likely because there's no GPS course set
+ me.page.updateCRS(0);
+ me.page.updateCDI(
+ heading: me._heading,
+ course: 0,
+ waypoint_valid: 0,
+ course_deviation_deg : 0,
+ deflection_dots : 0,
+ xtrk_nm : 0,
+ from: 0,
+ );
+
+ # Update the bearing indicators with GPS data if that's what we're displaying.
+ if (me.page.getBRG1() == "GPS") me.page.setBRG1("NONE", 0);
+ if (me.page.getBRG2() == "GPS") me.page.setBRG2("NONE", 0);
+ } else {
+
+ if (data["FMSLegBearing"] != nil) me.page.updateCRS(data["FMSLegBearing"]);
+
+ if (me._navSelected == 1) {
+ if (data["FMSNav1From"] != nil) me._from = data["FMSNav1From"];
+ } else {
+ if (data["FMSNav2From"] != nil) me._from = data["FMSNav2From"];
+ }
+
+ if (data["FMSLegID"] != nil) me._leg_id = data["FMSLegID"];
+ if (data["FMSLegBearing"] != nil) me._leg_bearing = data["FMSLegBearing"];
+ if (data["FMSLegTrackErrorAngle"] != nil) me._leg_deviation_deg = data["FMSLegTrackErrorAngle"];
+
+ # TODO: Proper cross-track error based on source and flight phase.
+ if (data["FMSLegCourseError"] != nil) me.deflection_dots = data["FMSLegCourseError"];
+ if (data["FMSLegCourseError"] != nil) me._leg_xtrk_nm = data["FMSLegCourseError"];
+
+ me.page.updateCDI(
+ heading: me._heading,
+ course: me._leg_bearing,
+ waypoint_valid: (data["FMSLegValid"] == "true"),
+ course_deviation_deg : me._leg_deviation_deg,
+ deflection_dots : me._deflection_dots,
+ xtrk_nm : me._leg_xtrk_nm,
+ from: me._from,
+ annun: "ENR"
+ );
+
+ # Update the bearing indicators with GPS data if that's what we're displaying.
+ if (me.page.getBRG1() == "GPS") me.page.setBRG1(me._leg_id, me._leg_bearing);
+ if (me.page.getBRG2() == "GPS") me.page.setBRG2(me._leg_id, me._leg_bearing);
+ }
return emesary.Transmitter.ReceiptStatus_OK;
},
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/Surround/SurroundController.nas b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/Surround/SurroundController.nas
index 2c8efdd6f..e8f21e3fd 100644
--- a/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/Surround/SurroundController.nas
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/MFDPages/Surround/SurroundController.nas
@@ -33,6 +33,9 @@ var SurroundController =
_nav1standby : 0.0,
_nav2active : 0.0,
_nav2standby : 0.0,
+ _pressure_settings_inhg : 0.0,
+ _selected_alt_ft : 0.0,
+ _heading_bug_deg : 0.0,
};
obj.RegisterWithEmesary();
@@ -54,6 +57,17 @@ var SurroundController =
me.transmitter.NotifyAll(notification);
},
+ # Helper function to notify the Emesary bridge of a FMSData update.
+ sendFMSDataNotification : func(data) {
+ var notification = notifications.PFDEventNotification.new(
+ "MFD",
+ me._page.mfd.getDeviceID(),
+ notifications.PFDEventNotification.FMSData,
+ data);
+
+ me.transmitter.NotifyAll(notification);
+ },
+
handleNavComData : func(data) {
# Store off particularly important data for control.
@@ -75,6 +89,15 @@ var SurroundController =
return emesary.Transmitter.ReceiptStatus_OK;
},
+ handleFMSADCData : func(data) {
+ if (data["ADCPressureSettingInHG"] != nil) me._pressure_settings_inhg = data["ADCPressureSettingInHG"];
+ if (data["FMSSelectedAlt"] != nil) me._selected_alt_ft = data["FMSSelectedAlt"];
+ if (data["FMSHeadingBug"] != nil) me._heading_bug_deg = data["FMSHeadingBug"];
+
+ # Pass FMS and ADC data straight to the page to display in the header fields
+ me._page.updateHeaderData(data);
+ return emesary.Transmitter.ReceiptStatus_OK;
+ },
#
# Handle the various COM and NAV controls at the top left and top right of the Fascia
@@ -334,6 +357,45 @@ var SurroundController =
handleComVolToggle : func (value) {
},
+ handleBaro : func(value) {
+ var incr_or_decr = (value > 0) ? 1 : -1;
+ var press = me._pressure_settings_inhg + (incr_or_decr * 0.01);
+ var data = {};
+ data["FMSPressureSettingInHG"] = sprintf("%.2f", press);
+ me.sendFMSDataNotification(data);
+ return emesary.Transmitter.ReceiptStatus_Finished;
+ },
+
+ handleAltInner : func(value) {
+ var incr_or_decr = (value > 0) ? 1 : -1;
+ var alt = int(me._selected_alt_ft + incr_or_decr * 100);
+ if (alt < 0) alt = 0;
+ var data = {};
+ data["FMSSelectedAlt"] = alt;
+ me.sendFMSDataNotification(data);
+ return emesary.Transmitter.ReceiptStatus_Finished;
+ },
+
+ handleAltOuter : func(value) {
+ var incr_or_decr = (value > 0) ? 1 : -1;
+ var alt = int(me._selected_alt_ft + incr_or_decr * 1000);
+ if (alt < 0) alt = 0;
+ var data = {};
+ data["FMSSelectedAlt"] = alt;
+ me.sendFMSDataNotification(data);
+ return emesary.Transmitter.ReceiptStatus_Finished;
+ },
+
+ handleHeading : func(value) {
+ var incr_or_decr = (value > 0) ? 1 : -1;
+ var hdg = me._heading_bug_deg + incr_or_decr;
+ hdg = math.mod(hdg, 360);
+ var data = {};
+ data["FMSHeadingBug"] = sprintf("%i", hdg);
+ me.sendFMSDataNotification(data);
+ return emesary.Transmitter.ReceiptStatus_Finished;
+ },
+
# These methods are slightly unusual in that they are called by other
# controllers when the CRSR is not active. Hence they aren't referenced
# in the RegisterWithEmesary call below.
@@ -381,10 +443,8 @@ var SurroundController =
(notification.Event_Id == notifications.PFDEventNotification.ADCData) )
and notification.EventParameter != nil)
{
- # Pass FMS and ADC data straight to the page to display in the header fields
- return controller._page.updateHeaderData(notification.EventParameter);
+ return controller.handleFMSADCData(notification.EventParameter);
}
-
}
return emesary.Transmitter.ReceiptStatus_NotProcessed;
};
diff --git a/Aircraft/Instruments-3d/FG1000/Nasal/NavMap.nas b/Aircraft/Instruments-3d/FG1000/Nasal/NavMap.nas
new file mode 100644
index 000000000..db515c61a
--- /dev/null
+++ b/Aircraft/Instruments-3d/FG1000/Nasal/NavMap.nas
@@ -0,0 +1,239 @@
+# Copyright 2018 Stuart Buchanan
+# This file is part of FlightGear.
+#
+# FlightGear is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# FlightGear is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with FlightGear. If not, see .
+#
+# Common Navigation map functions
+var NavMap = {
+
+ # Declutter levels.
+ DCLTR : [ "DCLTR", "DCLTR-1", "DCLTR-2", "DCLTR-3"],
+
+ # Airways levels.
+ AIRWAYS : [ "AIRWAYS", "AIRWY ON", "AIRWY LO", "AIRWY HI"],
+
+ new : func(page, element, center, clip="", zindex=0, vis_shift=0 )
+ {
+ var obj = {
+ parents : [ NavMap ],
+ _group : page.getGroup(),
+ _svg : page.getSVG(),
+ _page : page,
+ _pageName : page.getPageName(),
+ current_zoom : 13,
+ declutter : 0,
+ airways : 0,
+ vis_shift : vis_shift,
+ };
+
+ element.setTranslation(center[0], center[1]);
+
+ obj.Styles = fg1000.NavigationMapStyles.new();
+ obj.Options = fg1000.NavigationMapOptions.new();
+
+ obj.Map = element.createChild("map");
+ obj.Map.setScreenRange(689/2.0);
+
+ obj._rangeDisplay = obj._svg.getElementById(obj._pageName ~ "RangeDisplay");
+ if (obj._rangeDisplay == nil) die("Unable to find element " ~ obj._pageName ~ "RangeDisplay");
+
+ obj._orientationDisplay = obj._svg.getElementById(obj._pageName ~ "OrientationDisplay");
+ if (obj._orientationDisplay == nil) die("Unable to find element " ~ obj._pageName ~ "OrientationDisplay");
+
+ # Initialize the controllers:
+ var ctrl_ns = canvas.Map.Controller.get("Aircraft position");
+ var source = ctrl_ns.SOURCES["current-pos"];
+ if (source == nil) {
+ # TODO: amend
+ var source = ctrl_ns.SOURCES["current-pos"] = {
+ getPosition: func subvec(geo.aircraft_position().latlon(), 0, 2),
+ getAltitude: func getprop('/position/altitude-ft'),
+ getHeading: func {
+ if (me.aircraft_heading)
+ getprop('/orientation/heading-deg')
+ else 0
+ },
+ aircraft_heading: 1,
+ };
+ }
+ setlistener("/sim/gui/dialogs/map-canvas/aircraft-heading-up", func(n) {
+ source.aircraft_heading = n.getBoolValue();
+ }, 1);
+ # Make it move with our aircraft:
+ obj.Map.setController("Aircraft position", "current-pos"); # from aircraftpos.controller
+
+ if (clip != "") {
+ obj.Map.set("clip-frame", canvas.Element.LOCAL);
+ obj.Map.set("clip", clip);
+ }
+
+ if (zindex != 0) {
+ element.setInt("z-index", zindex);
+ }
+
+ 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_FG1000'),r('NDB'),r('FIX',0),r('GPS'),r('RTE'),r('WPT'),r('FLT'),r('WXR',0),r('APS')] ) {
+ obj.Map.addLayer(
+ factory: canvas.SymbolLayer,
+ type_arg: type.name,
+ priority: 4,
+ style: obj.Styles.getStyle(type.name),
+ options: obj.Options.getOption(type.name),
+ visible: type.vis);
+ }
+
+ foreach(var type; [ r('STAMEN_terrain'),r('STAMEN'), r('OpenAIP') ]) {
+ obj.Map.addLayer(
+ factory: canvas.OverlayLayer,
+ type_arg: type.name,
+ priority: 1,
+ style: obj.Styles.getStyle(type.name),
+ options: obj.Options.getOption(type.name),
+ visible: 0);
+ }
+
+ obj.setZoom(obj.current_zoom);
+ obj.setOrientation(0);
+ obj.Map.setVisible(0);
+ return obj;
+ },
+
+ toggleLayerVisible : func(name) {
+ (var l = me.Map.getLayer(name)).setVisible(l.getVisible());
+ },
+
+ setLayerVisible : func(name,n=1) {
+ me.Map.getLayer(name).setVisible(n);
+ },
+
+ setRange : func(range, label) {
+ me.Map.setRange(range);
+ me._rangeDisplay.setText(label);
+ },
+
+ setOrientation : func(orientation) {
+ # TODO - implment this
+ me._orientationDisplay.setText(fg1000.ORIENTATIONS[orientation].label);
+ },
+
+ setScreenRange : func(range) {
+ me.Map.setScreenRange(range);
+ },
+
+ zoomIn : func() {
+ me.setZoom(me.current_zoom -1);
+ },
+
+ zoomOut : func() {
+ me.setZoom(me.current_zoom +1);
+ },
+
+ setZoom : func(zoom) {
+ if ((zoom < 0) or (zoom > (size(fg1000.RANGES) - 1))) return;
+ me.current_zoom = zoom;
+ # Ranges above represent vertical ranges, but the display is a rectangle, so
+ # we need to use the diagonal range of the 1024 x 689, which is 617px.
+ # 617px is 1.8 x 689/2, so we need to increase the range values by x1.8
+ me.setRange(fg1000.RANGES[zoom].range, fg1000.RANGES[zoom].label);
+ me.updateVisibility();
+ },
+
+ updateVisibility : func() {
+ # Determine which layers should be visible.
+ foreach (var layer_name; me._page.mfd.ConfigStore.getLayerNames()) {
+ var layer = me._page.mfd.ConfigStore.getLayer(layer_name);
+
+ # Layers are only displayed if:
+ # 1) the user has enabled them.
+ # 2) The current zoom level is _less_ than the maximum range for the layer
+ # (i.e. as the range gets larger, we remove layers). Note that for
+ # inset maps, the range that items are removed is lower.
+ # 3) They haven't been removed due to the declutter level.
+ var effective_zoom = math.clamp(me.current_zoom + me.vis_shift, 0, size(fg1000.RANGES));
+ var effective_range = fg1000.RANGES[effective_zoom].range;
+ if (layer.enabled and
+ (effective_range <= layer.range) and
+ (me.declutter <= layer.declutter) )
+ {
+ me.Map.getLayer(layer_name).setVisible(1);
+ } else {
+ me.Map.getLayer(layer_name).setVisible(0);
+ }
+ }
+ },
+
+ isEnabled : func(layer) {
+ return me._page.mfd.ConfigStore.isLayerEnabled(layer);
+ },
+
+ toggleLayer : func(layer) {
+ me._page.mfd.ConfigStore.toggleLayerEnabled(layer);
+ me.updateVisibility();
+ },
+
+ # Increment through the de-clutter levels, which impact what layers are
+ # displayed. We also need to update the declutter menu item.
+ incrDCLTR : func(device, menuItem) {
+ me.declutter = math.mod(me.declutter +1, 4);
+ me.updateVisibility();
+ return me.DCLTR[me.declutter];
+ },
+
+ getDCLTRTitle : func() {
+ return me.DCLTR[me.declutter];
+ },
+
+ # Increment through the AIRWAYS levels. At present this doesn't do anything
+ # except change the label. It should enable/disable different airways
+ # information.
+ incrAIRWAYS : func(device, menuItem) {
+ me.airways = math.mod(me.airways +1, 4);
+ me.updateVisibility();
+ return me.AIRWAYS[me.airways];
+ },
+
+ getAIRWAYSTitle : func() {
+ return me.AIRWAYS[me.airways];
+ },
+
+ # Set the DTO line target
+ setDTOLineTarget : func(lat, lon) {
+ me.Map.getLayer("DTO").controller.setTarget(lat,lon);
+ },
+ enableDTO : func(enable) {
+ me._page.mfd.ConfigStore.setLayerEnabled("DTO", enable);
+ me.updateVisibility();
+ },
+
+ handleRange : func(val)
+ {
+ var incr_or_decr = (val > 0) ? 1 : -1;
+ me.setZoom(me.current_zoom + incr_or_decr);
+ },
+
+ getMap : func() {
+ return me.Map;
+ },
+ show : func() {
+ me.Map.show();
+ },
+ hide : func() {
+ me.Map.hide();
+ },
+ setVisible : func(visible) {
+ me.Map.setVisible(visible);
+ }
+
+};