Board index FlightGear Development Canvas

Event Click Listener on SVG element  Topic is solved

Canvas is FlightGear's new fully scriptable 2D drawing system that will allow you to easily create new instruments, HUDs and even GUI dialogs and custom GUI widgets, without having to write C++ code and without having to rebuild FlightGear.

Re: Event Click Listener on SVG element

Postby Philosopher » Mon Jul 28, 2014 5:24 pm

The problem is, while inkscape's layers are just groups, they have id's of "layer[n]", while their actual name is exposed like ‘inkscape:label="CTR"’, so the information is there but not used...
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: Event Click Listener on SVG element

Postby Hooray » Mon Jul 28, 2014 5:27 pm

using that info should require under 5 lines of Nasal in svg.nas probably ...
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Event Click Listener on SVG element

Postby omega95 » Mon Jul 28, 2014 6:23 pm

Ok, I'm really lost here. I know there's somewhere I'm supposed to use a closure but I'm not, but I can't figure out where. Whenever I run functions under capt_mfd, it shows the display in the fo_mfd. and fo_mfd.stuff also affects the fo_mfd. The capt_mfd display just never seems to get affected.

mfd.nas
Code: Select all

# Object Types --> click, textbox, label

var font_mapper = func(family, weight)
{
   if( family == "Liberation Sans" and weight == "normal" )
      return "LiberationFonts/LiberationSans-Regular.ttf";
};

var generators = {
   click: func() {
      return func(widget, svg_element) {
         svg_element.addListener("click", func {
            object.function();
         })
      }
   }
};

var new = func(par) {
   var m = {parents:[par]};
   return m;
}

var mfd = {
   activePage: "",
   activeMenu: "",
   pages: {},
   menus: {},
   menuLayers: [],
   pageLayers: [],
   svgCache: {},
   new: func(placement, svg_path, svg_cache) {
      var t = {parents:[mfd]};
      t.display = canvas.new({
         "name":         "MFD Display",
         "size":         [800, 1024],
         "view":         [800, 1024],
         "mipmapping":   1
      });
      
      t.display.addPlacement({"node": placement});
      t.svgGroup = t.display.createGroup();   # SVG Objects for pages
      canvas.parsesvg(t.svgGroup, svg_path, {'font-mapper':font_mapper});      
      
      foreach(var element; svg_cache) {
         t.svgCache[element] = t.svgGroup.getElementById(element);
      }
      
      return t;
   },
   addMenu: func(menu) {
      me.menus[menu.name] = menu;
      append(me.menuLayers, menu.layer);
      me.svgCache[menu.layer] = me.svgGroup.getElementById(menu.layer);
   },
   addPage: func(page) {
      me.pages[page.name] = page;
      append(me.pageLayers, page.layer);
      me.svgCache[page.layer] = me.svgGroup.getElementById(page.layer);
   },
   loadPage: func(page) {
      if(page != me.activePage) {
         # Clear all other page layers and show active page layer
         foreach(var layer; me.pageLayers) {
            me.svgCache[layer].hide();
         }
         me.svgCache[me.pages[page].layer].show();
         # Run page load function
         me.pages[page].load(me);
         me.loadMenu(me.pages[page].menu);
      }
   },
   loadMenu: func(menu) {
      if(menu != me.activeMenu) {
         # Clear all other page layers and show active page layer
         foreach(var layer; me.menuLayers) {
            me.svgCache[layer].hide();
         }
         me.svgCache[me.menus[menu].layer].show();
         # Run page load function
         me.menus[menu].load(me);
      }
   },
   showDlg: func {
      if(getprop("sim/instrument-options/canvas-popup-enable")) {
          var dlg = canvas.Window.new([400, 512], "dialog");
          dlg.setCanvas(me.display);
      }
   }
};


a380_mfds.nas - Instantiates the capt_mfd and fo_mfd
Code: Select all
var svg_elements = [];

var capt_mfd = mfd.new("mfd.l", "Aircraft/A380/Models/Instruments/MFD/display.svg", svg_elements);
var fo_mfd = mfd.new("mfd.r", "Aircraft/A380/Models/Instruments/MFD/display.svg", svg_elements);

print("Airbus Multi-Function Displays Initialized");


And, here's an example page -
Code: Select all
var fms_active_fpln = {
   name: 'fms_active_fpln',
   layer: 'fms_active_fpln',
   menu: 'menu_fms',
   widgets: [
      #FIXME
   ],
   load: func(m) {
   
   }
};

capt_mfd.addPage(new(fms_active_fpln));
fo_mfd.addPage(new(fms_active_fpln));
Merlion Virtual Airlines - the experience of a flight time...
Get high quality aircraft, airports, video tutorials or development tools from my hangar.
omega95
 
Posts: 1222
Joined: Sat Jul 30, 2011 1:59 am
Location: -unknown-
Callsign: MIA0001, OM-EGA
IRC name: omega95
Version: 2.12 git
OS: Ubuntu 13.04

Re: Event Click Listener on SVG element

Postby Hooray » Mon Jul 28, 2014 8:14 pm

Is there any way to look at all of your commits/code ? I am kinda missing the bits where you are setting up your callbacks.
Aside from that, are you aware of the fact that your mfd class has a bunch of static variables at the top, that will inevitably be shared across all instances of the mfd unless you explicitly change that in your new()-constructor ?

referring to stuff like this:
Code: Select all
 activePage: "",
   activeMenu: "",
   pages: {},
   menus: {},
   menuLayers: [],
   pageLayers: [],
   svgCache: {},


Whenenever you want to have instance-specific fields, you need to initialize those separately in your constructor:
Code: Select all
var m = {parents:[Class]}
m.field = [];
m.pages = {};
...


otherwise, all me.FOO lookups will use the shared state instead, basically equivalent to this C++ code:
Code: Select all
struct mfd {
static std::string activePage;
static std::string activeMenu;
static std::map<..> pages;
static std::map<..> menus;
static std::vector<...> menuLayers;
static std::vector<...> pageLayers;
static std::map<...> svgCache;
};
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Event Click Listener on SVG element

Postby omega95 » Tue Aug 05, 2014 8:16 am

Alright, that helps a lot - I can control the individual MFDs separately. But the problem is that I can only click on the object in the dialog, and not in the 3D model object - which is actually more important for this purpose.

Does that have something to do with the canvas sub-system itself or do I have to do something to enable the 3D model object to be clickable? :?
Merlion Virtual Airlines - the experience of a flight time...
Get high quality aircraft, airports, video tutorials or development tools from my hangar.
omega95
 
Posts: 1222
Joined: Sat Jul 30, 2011 1:59 am
Location: -unknown-
Callsign: MIA0001, OM-EGA
IRC name: omega95
Version: 2.12 git
OS: Ubuntu 13.04

Re: Event Click Listener on SVG element  

Postby TheTom » Tue Aug 05, 2014 8:23 am

TheTom
 
Posts: 322
Joined: Sun Oct 09, 2011 11:20 am

Re: Event Click Listener on SVG element

Postby omega95 » Tue Aug 05, 2014 9:10 am

That's wonderful! Thank you very much! :D
Merlion Virtual Airlines - the experience of a flight time...
Get high quality aircraft, airports, video tutorials or development tools from my hangar.
omega95
 
Posts: 1222
Joined: Sat Jul 30, 2011 1:59 am
Location: -unknown-
Callsign: MIA0001, OM-EGA
IRC name: omega95
Version: 2.12 git
OS: Ubuntu 13.04

Previous

Return to Canvas

Who is online

Users browsing this forum: No registered users and 5 guests