Howto:Creating fullscreen Canvas applications

From FlightGear wiki
Jump to: navigation, search
This article is a stub. You can help the wiki by expanding it.


Objective

Demonstrate how to easily create Canvas-based fullscreen applications, i.e. for creating a standalone instrument/MFD viewer, FGPanel or FGCanvas mode for master/slave setups. This is just very basic boilerplate code, it can be used for all sorts of applications, including GUI/Widget designers, graph plotting, a fullscreen ATC client or even an instructor console, all implemented on top of Nasal scripting and the Canvas system.

You can also use the same approach to implement a fullscreen mode for instruments, so that they are easier to use, e.g. a CDU/MCDU).

Example for the Nasal Console

Open the Nasal Console.

The Nasal console in FG 3.0 with copy/paste buttons

##
# Here's a short demo, open the Nasal Console, copy this to your clipboard and then
# paste it into the Nasal console in FlightGear, next click "Execute".


##
# hide menubar 
#
setprop("/sim/menubar/visibility",0);

##
# you can also toggle the menubar automatically:
#
# setprop("/sim/menubar/autovisibility/enabled",1);

##
# get the screen coordinates
var x = getprop("/sim/startup/xsize");
var y = getprop("/sim/startup/ysize");

##
# create a new canvas fullscreen window 
#
var dlg = canvas.Window.new([x,y]);

##
# set rgba
#
var my_canvas = dlg.createCanvas()
                     .setColorBackground(1,1,1,1);

##
# create the toplevel canvas group
#                     
var root = my_canvas.createGroup();

##
# show an NDB symbol
canvas.parsesvg(root, "gui/dialogs/images/ndb_symbol.svg");


##
# add a simple event handler, clicking destroys the window
#
my_canvas.addEventListener("click", 
	func dlg.del() 
);

Submodule Example

Here's pretty much the same example, but this time not intended to be pasted into the Nasal console, but instead added to a separate Nasal submodule, and with some more elements added (a text area and a texture)

  • Create a new folder named 'fullscreen' in $FG_ROOT/Nasal/
  • add a new nasal file named demo.nas
  • paste the following code into demo.nas and save the file
###
# $FG_ROOT/Nasal/fullscreen/demo.nas
#

var demo = func {
 
##
# enable menubar hiding
#
setprop("/sim/menubar/autovisibility/enabled",1);
 
##
# get the screen coordinates
var x = getprop("/sim/startup/xsize");
var y = getprop("/sim/startup/ysize");
 
##
# create a new canvas fullscreen window 
#
var dlg = canvas.Window.new([x,y]);
 
##
# set rgba
#
var my_canvas = dlg.createCanvas()
                     .setColorBackground(1,1,1,1);
 
##
# create the toplevel canvas group
#                     
var root = my_canvas.createGroup();
 
##
# show an NDB symbol
canvas.parsesvg(root, "gui/dialogs/images/ndb_symbol.svg");

##
# add a text area
#
var text =
      root.createChild("text")
          .setText("Fullscreen Canvas Windows demo - click to close !")
          .setTranslation(50, 50)
          .setAlignment("left-top")
          .setFontSize(35)
          .setFont("LiberationFonts/LiberationSans-Regular.ttf")
          .set("max-width", x)
          .setColor(1,0,0); 

##
# add a raster image from the Instruments folder
# 
root.createChild("image")
				    .setFile("Aircraft/Instruments/Textures/gyro-fronts.rgb")
                                    .setSize(240,180)
                                    .setTranslation(50,100);

##
# add a simple event handler, clicking destroys the window
#
my_canvas.addEventListener("click", 
	func dlg.del() 
);
 
} # end of demo function

##
# register a submodule listener to ensure that our demo function is called
#
_setlistener("/nasal/fullscreen/loaded", demo );

Some standalone fullscreen applications are unlikely to require most FlightGear subsystems while they're running/maximized, such as the FDM, sound, AI-traffic manager, weather/environment etc - you should explicitly disable those to free computing resources. The draw-otw property that would normally disable scenery rendering is currently broken, but you can basically achieve the same thing by reducing visibility to 0m and setting a high value for fog.

For some additional info, please see:

An application class

var CanvasApplication = {
 ##
 # constructor
 new: func(x=300,y=200) {
  var m = { parents: [CanvasApplication] };
  m.dlg = canvas.Window.new([x,y],"dialog");
  m.canvas = m.dlg.createCanvas().setColorBackground(1,1,1,1);
  m.root = m.canvas.createGroup();
  m.init();
  return m;
 },


##
# show something and register an event listener
init: func() {
  canvas.parsesvg(me.root, "gui/dialogs/images/ndb_symbol.svg");
  me.canvas.addEventListener("click", func me.dlg.del() );
 },

}; # end of CanvasApplication

var test = CanvasApplication.new(x:400, y:200);
print("Success!");

What's next

Next, you'll probably want to learn more about:

For additional examples, see Tom's canvas-gui-demo branch at [1].