2018-01-14 20:46:50 +00:00
|
|
|
|
|
|
|
io.include("constants.nas");
|
|
|
|
|
|
|
|
var MFDGUI =
|
|
|
|
{
|
|
|
|
|
|
|
|
# List of UI hotspots and their mapping to Emesary bridge notifications
|
|
|
|
WHEEL_HOT_SPOTS : [
|
|
|
|
{ notification: fg1000.FASCIA.NAV_VOL, shift: 0, top_left: [65, 45], bottom_right: [112, 90] },
|
|
|
|
{ notification: fg1000.FASCIA.NAV_INNER, shift: 0, top_left: [45, 168], bottom_right: [135, 250] },
|
|
|
|
{ notification: fg1000.FASCIA.NAV_OUTER, shift: 1, top_left: [45, 168], bottom_right: [135, 250] },
|
|
|
|
{ notification: fg1000.FASCIA.HEADING, shift: 0, top_left: [45, 338], bottom_right: [135, 411] },
|
|
|
|
{ notification: fg1000.FASCIA.ALT_INNER, shift: 0, top_left: [45, 800], bottom_right: [135, 880] },
|
|
|
|
{ notification: fg1000.FASCIA.ALT_OUTER, shift: 1, top_left: [45, 800], bottom_right: [135, 880] },
|
|
|
|
|
|
|
|
|
|
|
|
{ notification: fg1000.FASCIA.COM_VOL, shift: 0, top_left: [1290, 45], bottom_right: [1340, 90] },
|
|
|
|
{ notification: fg1000.FASCIA.COM_INNER, shift: 0, top_left: [1275, 170], bottom_right: [1355, 245] },
|
|
|
|
{ notification: fg1000.FASCIA.COM_OUTER, shift: 1, top_left: [1275, 170], bottom_right: [1355, 245] },
|
|
|
|
|
|
|
|
{ notification: fg1000.FASCIA.CRS, shift: 0, top_left: [1275, 331], bottom_right: [1355, 410] },
|
|
|
|
{ notification: fg1000.FASCIA.BARO, shift: 1, top_left: [1275, 331], bottom_right: [1355, 410] },
|
|
|
|
|
|
|
|
{ notification: fg1000.FASCIA.RANGE, shift: 0, top_left: [1275, 497], bottom_right: [1355, 554] },
|
|
|
|
|
|
|
|
{ notification: fg1000.FASCIA.FMS_INNER, shift: 0, top_left: [1275, 800], bottom_right: [1355, 880] },
|
|
|
|
{ notification: fg1000.FASCIA.FMS_OUTER, shift: 1, top_left: [1275, 800], bottom_right: [1355, 880] },
|
|
|
|
],
|
|
|
|
|
|
|
|
CLICK_HOT_SPOTS : [
|
|
|
|
{ notification: fg1000.FASCIA.NAV_ID, shift: 0, value: 1, top_left: [65, 47], bottom_right: [112, 90] },
|
|
|
|
{ notification: fg1000.FASCIA.NAV_FREQ_TRANSFER, shift: 0, value: 1, top_left: [100, 102], bottom_right: [150, 138] },
|
|
|
|
{ notification: fg1000.FASCIA.NAV_TOGGLE, shift: 0, value: 1, top_left: [45, 168], bottom_right: [135, 250] },
|
|
|
|
{ notification: fg1000.FASCIA.HEADING_PRESS, shift: 0, value: 1, top_left: [45, 338], bottom_right: [135, 411] },
|
|
|
|
|
|
|
|
{ notification: fg1000.FASCIA.COM_VOL_TOGGLE, shift: 0, value: 1, top_left: [1290, 45], bottom_right: [1340, 90] },
|
|
|
|
{ notification: fg1000.FASCIA.COM_FREQ_TRANSFER, shift: 0, value: 1, top_left: [1250, 100], bottom_right: [1300, 140] },
|
|
|
|
{ notification: fg1000.FASCIA.COM_FREQ_TRANSFER_HOLD, shift: 1, value: 1, top_left: [1250, 100], bottom_right: [1300, 140] },
|
|
|
|
{ notification: fg1000.FASCIA.CRS_CENTER, shift: 0, value: 1, top_left: [1275, 331], bottom_right: [1355, 410] },
|
|
|
|
|
|
|
|
{ notification: fg1000.FASCIA.JOYSTICK_PRESS, shift: 0, value: 1, top_left: [1295, 500], bottom_right: [1345, 550] },
|
|
|
|
|
|
|
|
{ notification: fg1000.FASCIA.JOYSTICK_HORIZONTAL, shift: 0, value: -1, top_left: [1255, 500], bottom_right: [1285, 550] },
|
|
|
|
{ notification: fg1000.FASCIA.JOYSTICK_HORIZONTAL, shift: 0, value: 1, top_left: [1345, 500], bottom_right: [1380, 550] },
|
|
|
|
|
|
|
|
{ notification: fg1000.FASCIA.JOYSTICK_VERTICAL, shift: 0, value: -1, top_left: [1295, 465], bottom_right: [1345, 500] },
|
|
|
|
{ notification: fg1000.FASCIA.JOYSTICK_VERTICAL, shift: 0, value: 1, top_left: [1295, 550], bottom_right: [1345, 585] },
|
|
|
|
|
|
|
|
{ notification: fg1000.FASCIA.DTO, shift: 0, value: 1, top_left: [1255, 620], bottom_right: [1305, 660] },
|
|
|
|
{ notification: fg1000.FASCIA.FPL, shift: 0, value: 1, top_left: [1255, 670], bottom_right: [1305, 710] },
|
|
|
|
{ notification: fg1000.FASCIA.CLR, shift: 0, value: 1, top_left: [1255, 720], bottom_right: [1305, 760] },
|
|
|
|
{ notification: fg1000.FASCIA.CLR_HOLD, shift: 1, value: 1, top_left: [1255, 720], bottom_right: [1305, 760] },
|
|
|
|
|
|
|
|
{ notification: fg1000.FASCIA.MENU, shift: 0, value: 1, top_left: [1325, 620], bottom_right: [1380, 660] },
|
|
|
|
{ notification: fg1000.FASCIA.PROC, shift: 0, value: 1, top_left: [1325, 670], bottom_right: [1380, 710] },
|
|
|
|
{ notification: fg1000.FASCIA.ENT, shift: 0, value: 1, top_left: [1325, 720], bottom_right: [1380, 760] },
|
|
|
|
|
|
|
|
{ notification: fg1000.FASCIA.FMS_CRSR, shift: 0, value: 1, top_left: [1275, 800], bottom_right: [1355, 880] },
|
|
|
|
],
|
|
|
|
|
|
|
|
SOFTKEY_HOTSPOTS : [
|
|
|
|
{ Id: 1, top_left: [205, 830], bottom_right: [265, 875] },
|
|
|
|
{ Id: 2, top_left: [290, 830], bottom_right: [350, 875] },
|
|
|
|
{ Id: 3, top_left: [375, 830], bottom_right: [435, 875] },
|
|
|
|
{ Id: 4, top_left: [460, 830], bottom_right: [520, 875] },
|
|
|
|
{ Id: 5, top_left: [545, 830], bottom_right: [605, 875] },
|
|
|
|
{ Id: 6, top_left: [630, 830], bottom_right: [690, 875] },
|
|
|
|
{ Id: 7, top_left: [715, 830], bottom_right: [775, 875] },
|
|
|
|
{ Id: 8, top_left: [800, 830], bottom_right: [860, 875] },
|
|
|
|
{ Id: 9, top_left: [885, 830], bottom_right: [945, 875] },
|
|
|
|
{ Id: 10, top_left: [970, 830], bottom_right: [1030, 875] },
|
|
|
|
{ Id: 11, top_left: [1055, 830], bottom_right: [1115, 875] },
|
|
|
|
{ Id: 12, top_left: [1145, 830], bottom_right: [1200, 875] },
|
|
|
|
],
|
|
|
|
|
|
|
|
new : func()
|
|
|
|
{
|
|
|
|
var obj = {
|
|
|
|
parents : [ MFDGUI ],
|
|
|
|
mfd : nil,
|
|
|
|
eisPublisher : nil,
|
|
|
|
navcomPublisher : nil,
|
|
|
|
navcomUpdater : nil,
|
|
|
|
navdataInterface : nil,
|
|
|
|
width : 1407,
|
|
|
|
height : 918,
|
2018-01-15 20:01:46 +00:00
|
|
|
scale : 1.0,
|
2018-01-14 20:46:50 +00:00
|
|
|
};
|
|
|
|
|
2018-01-15 20:01:46 +00:00
|
|
|
obj.scale = getprop("/sim/gui/mfd-scale") or 1.0;
|
|
|
|
|
|
|
|
obj.window = canvas.Window.new([obj.scale*obj.width,obj.scale*obj.height],"dialog").set('title',"FG1000 MFD");
|
2018-01-14 20:46:50 +00:00
|
|
|
|
|
|
|
obj.window.del = func() {
|
|
|
|
# Over-ride the window.del function so we clean up when the user closes the window
|
|
|
|
# Use call method to ensure we have the correct closure.
|
|
|
|
call(obj.cleanup, [], obj);
|
|
|
|
};
|
|
|
|
|
|
|
|
# creating the top-level/root group which will contain all other elements/group
|
|
|
|
obj.myCanvas = obj.window.createCanvas();
|
|
|
|
obj.root = obj.myCanvas.createGroup();
|
|
|
|
|
|
|
|
var nasal_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/FG1000/Nasal/";
|
|
|
|
io.load_nasal(nasal_dir ~ 'MFD.nas', "fg1000");
|
|
|
|
io.load_nasal(nasal_dir ~ 'Interfaces/PropertyPublisher.nas', "fg1000");
|
|
|
|
io.load_nasal(nasal_dir ~ 'Interfaces/PropertyUpdater.nas', "fg1000");
|
|
|
|
io.load_nasal(nasal_dir ~ 'Interfaces/GenericEISPublisher.nas', "fg1000");
|
|
|
|
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");
|
|
|
|
|
|
|
|
# Now create the MFD itself
|
2018-01-15 20:01:46 +00:00
|
|
|
if (obj.scale > 0.999) {
|
|
|
|
# If we're at full scale, then create it directly in this Canvas as that
|
|
|
|
# produces sharper results and perhaps better performance
|
|
|
|
obj.mfd = fg1000.MFD.new(obj.myCanvas);
|
|
|
|
obj.mfd._svg.setTranslation(186,45);
|
|
|
|
obj.mfd._svg.set("z-index", 150);
|
|
|
|
} else {
|
|
|
|
# If we're using some scaling factor, then we create it as an image raster
|
|
|
|
# which scales everything for us nicely.
|
|
|
|
obj.mfd_canvas = canvas.new({
|
|
|
|
"name" : "MFD Canvas",
|
|
|
|
"size" : [1024, 768],
|
|
|
|
"view" : [1024, 768],
|
|
|
|
"mipmapping": 0,
|
|
|
|
});
|
|
|
|
obj.mfd = fg1000.MFD.new(obj.mfd_canvas);
|
|
|
|
|
|
|
|
var mfd_child = obj.root.createChild("image")
|
|
|
|
.setFile(obj.mfd_canvas.getPath())
|
|
|
|
.set("z-index", 150)
|
|
|
|
.setTranslation(obj.scale*186,obj.scale*45)
|
|
|
|
.setSize(obj.scale*1024, obj.scale*768);
|
|
|
|
}
|
2018-01-14 20:46:50 +00:00
|
|
|
|
|
|
|
# Create the surround fascia, which is just a PNG image;
|
|
|
|
var child = obj.root.createChild("image")
|
|
|
|
.setFile("Aircraft/Instruments-3d/FG1000/Models/fascia.png")
|
|
|
|
.set("z-index", 100)
|
|
|
|
.setTranslation(0, 0)
|
2018-01-15 20:01:46 +00:00
|
|
|
.setSize(obj.scale*obj.width,obj.scale*obj.height);
|
2018-01-14 20:46:50 +00:00
|
|
|
|
|
|
|
obj.eisPublisher = fg1000.GenericEISPublisher.new();
|
|
|
|
obj.eisPublisher.start();
|
|
|
|
|
|
|
|
obj.navcomPublisher = fg1000.GenericNavComPublisher.new();
|
|
|
|
obj.navcomPublisher.start();
|
|
|
|
|
|
|
|
obj.navcomUpdater = fg1000.GenericNavComUpdater.new(obj.mfd.getDevice());
|
|
|
|
obj.navcomUpdater.start();
|
|
|
|
|
|
|
|
obj.navdataInterface = fg1000.NavDataInterface.new(obj.mfd.getDevice());
|
|
|
|
obj.navdataInterface.start();
|
|
|
|
|
|
|
|
# Add a event listener for the mouse wheel, which is used for turning the
|
|
|
|
# knobs.
|
|
|
|
obj.myCanvas.addEventListener("wheel", func(e)
|
|
|
|
{
|
|
|
|
foreach(var hotspot; MFDGUI.WHEEL_HOT_SPOTS) {
|
2018-01-15 20:01:46 +00:00
|
|
|
if ((e.localX > obj.scale*hotspot.top_left[0]) and (e.localX < obj.scale*hotspot.bottom_right[0]) and
|
|
|
|
(e.localY > obj.scale*hotspot.top_left[1]) and (e.localY < obj.scale*hotspot.bottom_right[1]) and
|
2018-01-14 20:46:50 +00:00
|
|
|
(e.shiftKey == hotspot.shift))
|
|
|
|
{
|
|
|
|
# We've found the hotspot, so send a notification to deal with it
|
|
|
|
var notification = notifications.PFDEventNotification.new(
|
|
|
|
"MFD",
|
|
|
|
1,
|
|
|
|
notifications.PFDEventNotification.HardKeyPushed,
|
|
|
|
{ Id: hotspot.notification, Value: e.deltaY }
|
|
|
|
);
|
|
|
|
emesary.GlobalTransmitter.NotifyAll(notification);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
# Add a event listener for the mouse click, which is used for buttons
|
|
|
|
obj.myCanvas.addEventListener("click", func(e)
|
|
|
|
{
|
|
|
|
foreach(var hotspot; MFDGUI.CLICK_HOT_SPOTS) {
|
2018-01-15 20:01:46 +00:00
|
|
|
if ((e.localX > obj.scale*hotspot.top_left[0]) and (e.localX < obj.scale*hotspot.bottom_right[0]) and
|
|
|
|
(e.localY > obj.scale*hotspot.top_left[1]) and (e.localY < obj.scale*hotspot.bottom_right[1]) and
|
2018-01-14 20:46:50 +00:00
|
|
|
(e.shiftKey == hotspot.shift))
|
|
|
|
{
|
|
|
|
# We've found the hotspot, so send a notification to deal with it
|
|
|
|
var notification = notifications.PFDEventNotification.new(
|
|
|
|
"MFD",
|
|
|
|
1,
|
|
|
|
notifications.PFDEventNotification.HardKeyPushed,
|
|
|
|
{ Id: hotspot.notification, Value: hotspot.value }
|
|
|
|
);
|
|
|
|
emesary.GlobalTransmitter.NotifyAll(notification);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach(var hotspot; MFDGUI.SOFTKEY_HOTSPOTS) {
|
2018-01-15 20:01:46 +00:00
|
|
|
if ((e.localX > obj.scale*hotspot.top_left[0]) and (e.localX < obj.scale*hotspot.bottom_right[0]) and
|
|
|
|
(e.localY > obj.scale*hotspot.top_left[1]) and (e.localY < obj.scale*hotspot.bottom_right[1]))
|
2018-01-14 20:46:50 +00:00
|
|
|
{
|
|
|
|
# We've found the hotspot, so send a notification to deal with it
|
|
|
|
var notification = notifications.PFDEventNotification.new(
|
|
|
|
"MFD",
|
|
|
|
1,
|
|
|
|
notifications.PFDEventNotification.SoftKeyPushed,
|
|
|
|
hotspot.Id
|
|
|
|
);
|
|
|
|
emesary.GlobalTransmitter.NotifyAll(notification);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
},
|
|
|
|
|
|
|
|
cleanup : func()
|
|
|
|
{
|
|
|
|
me.mfd.del();
|
|
|
|
me.eisPublisher.stop();
|
|
|
|
me.eisPublisher = nil;
|
|
|
|
|
|
|
|
me.navcomPublisher.stop();
|
|
|
|
me.navcomPublisher = nil;
|
|
|
|
|
|
|
|
me.navcomUpdater.stop();
|
|
|
|
me.navcomUpdater = nil;
|
|
|
|
|
|
|
|
me.navdataInterface.stop();
|
|
|
|
me.navdataInterface =nil;
|
|
|
|
|
|
|
|
# Clean up the window itself
|
|
|
|
call(canvas.Window.del, [], me.window);
|
|
|
|
},
|
|
|
|
};
|