Board index FlightGear Development Nasal

Nasal: Replacing a menubar item  Topic is solved

Nasal is the scripting language of FlightGear.

Nasal: Replacing a menubar item

Postby Necolatis » Sat Apr 02, 2016 7:40 pm

If I in nasal go in and replace the binding command inside "sim/menubar" for a default menu item, the new binding does not take affect.

Do I somehow need to refresh the entire menubar for this to happen? Even tried to delete the item, and make anew, but then its greyed out.
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore


Hangar: https://sites.google.com/site/fghangar/
User avatar
Necolatis
 
Posts: 1833
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2018.1.1
OS: Windows 10 Pro

Re: Nasal: Replacing a menubar item

Postby Thorsten » Sun Apr 03, 2016 6:30 am

You mean you want to do it once at startup or be able to do it dynamically?

Replacing a default with a custom dialog at startup is exemplified by the Shuttle propellant dialog for instance - whether this works runtime I don't know.
Thorsten
 
Posts: 9549
Joined: Mon Nov 02, 2009 8:33 am

Re: Nasal: Replacing a menubar item  

Postby Hooray » Sun Apr 03, 2016 8:26 am

last I checked (and IIRC), it worked by loading the menubar.xml file into the property tree, from where it is then "compiled" into an actual PUI data structure with bindings,so you will see the menubar structure in the property tree, but at that point, it's already compiled and what you change there doesn't have any effect, unless you also "reinit-gui".

Like Thorsten said, it would make sense to look at other aircraft using aircraft specific menu items, and maybe document the whole process a little better.

For the time being, I *think* that reinit-gui will also reload menubar.xml - but it would be straightforward to add an option to it, so that it skips that step.
(no idea if that's already supported or not)
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: 11100
Joined: Tue Mar 25, 2008 8:40 am

Re: Nasal: Replacing a menubar item

Postby Necolatis » Sun Apr 03, 2016 12:39 pm

Thanks for the comments.

And thanks Hooray, the trick worked, and can now dynamically change a binding:
fgcommand("reinit", props.Node.new({"subsystem":"gui"}));
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore


Hangar: https://sites.google.com/site/fghangar/
User avatar
Necolatis
 
Posts: 1833
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2018.1.1
OS: Windows 10 Pro

Re: Nasal: Replacing a menubar item

Postby Hooray » Tue Apr 05, 2016 2:47 pm

It may be a good idea to document such techniques/workarounds, either in the form of a dedicated wiki tutorial, or by adding to the fgcommand docs.
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: 11100
Joined: Tue Mar 25, 2008 8:40 am

Re: Nasal: Replacing a menubar item

Postby flug » Sat Feb 18, 2017 8:03 am

Necolatis wrote in Sat Apr 02, 2016 7:40 pm:If I in nasal go in and replace the binding command inside "sim/menubar" for a default menu item, the new binding does not take affect.

Do I somehow need to refresh the entire menubar for this to happen? Even tried to delete the item, and make anew, but then its greyed out.


I think one way to do this if via fgcommand ("gui-redraw"). Look @ gui.nas about line 63.

Here is the code I use for the Bombable menu item & dialogue boxes that pop up below it.

Code: Select all
#This function adds the dialog object to an actual GUI menubar item


var init_bombable_dialog = func () {
       #return; #gui prob
       
       #we set bomb_menuNum to -1 at initialization time. 
       #On reinit & some other times, this routine will be called again
       #so if bomb_menuNum != -1 we know not to seek out another new menu number
       #Without this check, we'd get a new Bombable menu added each time FG reinits
       #or re-positions. Additionally, we run through all the existing menu items & look for one with name "Bombable". If that exists they we don't created another new menu item.
       if (bomb_menuNum==nil or bomb_menuNum==-1) {
        #find the next open menu number/kludge
         bomb_menuNum=97; #the default
         for (var i=0;i<300;i+=1) {
           p=props.globals.getNode("/sim/menubar/default/menu["~i~"]");
           if ( typeof(p) == "nil" ) {
              bomb_menuNum=i;
              print ("Bombable: Found empty menu: " ~ i);
              break;
           } else {
              # var l = props.globals.getNode("/sim/menubar/default/menu["~i~"]/name");
              var n = p.getChild("name");
              if (typeof(n) != "nil" ) var l = n.getValue();
              print ("Bombable: Looking at menu found a " ~ typeof(l));
             
              #p = records.create_printable_summary(l);
              if (typeof(l) != "nil") mss= l else mss= "nothing at " ~ i;
              print ("Bombable: Looking @ menu found: " ~ mss);
              if ( typeof(l) != "nil" and l == "Bombable") { # aha, we've already set up the menu once before.  So just re-use it. This happens in FG 2016.x etc when the user re-inits.
                bomb_menuNum=i;
                print ("Bombable: Found existing Bombable menu: " ~ i);
                return;
              }
           }   
         }
        }
       
        #init the main bombable options menu
        #todo: figure out how to position it in the center of the screen or somewhere better
        dialog.init(0,0);
       
        #make the GUI menubar item to select the options menu
        props.globals.getNode ("/sim/menubar/default/menu["~bomb_menuNum~"]/enabled", 1).setBoolValue(1);
        props.globals.getNode ("/sim/menubar/default/menu["~bomb_menuNum~"]/name", 1).setValue("Bombable");
        props.globals.getNode ("/sim/menubar/default/menu["~bomb_menuNum~"]/item/enabled", 1).setBoolValue(1);
        #Note: the label must be distinct from all other labels in the menubar
        #or you will get duplicate functionality with the other menu item
        #sharing the same label
        props.globals.getNode ("/sim/menubar/default/menu["~bomb_menuNum~"]/item/label", 1).setValue("Bombable Options"); #must be unique name from all others in the menubar or they both pop up together
        props.globals.getNode ("/sim/menubar/default/menu["~bomb_menuNum~"]/item/binding/command", 1).setValue("nasal");
        props.globals.getNode ("/sim/menubar/default/menu["~bomb_menuNum~"]/item/binding/script", 1).setValue("bombable.dialog.create()");

        props.globals.getNode ("/sim/menubar/default/menu["~bomb_menuNum~"]/item[1]/label", 1).setValue("Bombable Statistics"); #must be unique name from all others in the menubar or they both pop up together
        props.globals.getNode ("/sim/menubar/default/menu["~bomb_menuNum~"]/item[1]/binding/command", 1).setValue("nasal");
        props.globals.getNode ("/sim/menubar/default/menu["~bomb_menuNum~"]/item[1]/binding/script", 1).setValue("bombable.records.display_results()");
       
       
       
       #reinit makes the property changes to both the GUI & input become active
       #the delay is to avoid a segfault under dev version of FlightGear, 2010/09/07
       #This just a workaround, a real fix would like: 
       #  overwriting preferences.xml with a new one including a line like <menubar include="Dialogs/bombable.xml"/>'
       #Thx goes to user Citronnier for tracking this down 
       #settimer (func {fgcommand("reinit")}, 15);
       #As of FG 2.4.0, a straight "reinit" leads to FG crash or the dreaded NAN issue
       #at least with some aircraft.  Reinit/gui (as below) gets around this problem.
       #fgcommand("reinit", props.Node.new({subsystem : "gui"}));
       
       #OK . . . per gui.nas line 63, this appears to be the right way to do this:
       fgcommand ("gui-redraw");
}
flug
 
Posts: 218
Joined: Wed Jun 17, 2009 1:06 am

Re: Nasal: Replacing a menubar item

Postby Hooray » Sat Feb 25, 2017 5:25 pm

For the sake of completeness, at some point, a few folks were also working on using Nasal and Canvas to provide a non-PUI menubar equivalent using just the Canvas system:

http://wiki.flightgear.org/Howto:Making ... as_Menubar
Image

This could be considered the final step to get rid entirely rid of PUI once the pui2canvas is sufficiently complete to parse a subset of PUI/XML:

http://wiki.flightgear.org/Howto:Proces ... ing_Canvas
Image
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: 11100
Joined: Tue Mar 25, 2008 8:40 am


Return to Nasal

Who is online

Users browsing this forum: No registered users and 1 guest