Replying to your previous posting (not yet the last one):
This can certainly all be done, and even done in a much simpler way than you mention - but it would probably be better to focus on just replacing the existing scheme for starters and consider extending it afterwards. Once the existing scheme is supported (which would be about 3-5 more iterations IMO), adding support for vertical menus is just a matter of using a vertical layout: 3 lines of code (1 minute).
Supporting additional items can also be done, sub-menus and checkboxes would seem most important to me currently though.
But it's really just ~5 lines of code to add support for a new feature - it works analogous to how the "menu.name" is extracted by using the hash which was created via the io.read_properties/getValues() calls, i.e. isn't even much work, simply because it will convert any valid PropertyList XML into a Nasal hash, and it is up to you to decide what to do with.
One simple way to experiment with this would be to add support for an optional "tooltip" tag that is shown on "mouseover" - which is roughly 3-5 lines of code, i.e. can be done by adapting existing code.
The RMB issue won't be a problem because there are several mouse modes supported (toggle via TAB).
Allowing greater flexibility in menubar.xml would be mainly a matter of coming up with desirable features/tags and mapping those recursively to existing code, such as showing another canvas upon clicking - which would be equivalent to a popup once you think about it. Obviously, the popup would need to be positioned properly (see tooltip.nas) and sized according to its entries (use the bounding box/layout info).
Thus, there are really just a handful of building blocks missing now that would need to be integrated.
The menubar structure you envision can be trivially supported by letting the menubar code call itself for creating sub-menus/popups recursively.
you've made a good point about aircraft specific menus, but your solution would be a lot of unnecessary work - it would be much easier to simply ALSO use io.read_properties() on the aircraft-set.xml file and then use props.nas and .getValues() to get any aircraft-specific menu entries directly out of the aircraft - the only thing where that fails would be dynamically added menus via Nasal code - but even then, it would make more sense to patch the underlying Nasal code in $FG_ROOT/Nasal to redirect such menubar building to the new menubar code - roughly 5-15 lines of code, and aircraft won't ever notice the difference that way - they'll "just work".
To try this, and see for yourself, consider this snippet of pseudo code (untested):
- Code: Select all
var mySetFile = "aircraft-set.xml";
var fgroot = getprop("/sim/fg-root");
var path = fgroot ~ mySetFile;
var myXMLFile = io.read_properties(path);
var myAircraft_menu = myXMLFile.getNode("/sim/menubar").getValues();
debug.dump(myAircraftMenu);
Like I said, I haven't tested this - but something along these lines will allow you to support hard-coded aircraft-specific menus without any other work being required.
Equally, dynamically-added menus can be supported using another 5-10 lines of code
Overall, it's cool to see that you're starting to think like a programmer - but it seems a little like you have come up with a few solutions for problems that aren't quite there - so, I wouldn't over-engineer things. As you can probably tell by now, we can provide snippets of code solving this problems pretty quickly, and also explain how they work. Thus, it might be better to make this thing functional "as is", and then explore new options afterwards. Everything you've described from a functionality standpoint can be supported using another 50-80 lines of code, based on adapting existing code, and referring to snippets in tooltip.nas
The implementation strategy you propose would make this massively complex and less-flexible for other purposes - e.g. imagine someone wanting to reuse the menubar for a MFD instrument.
Performance is not going to be a problem at all - those are just bindings and you could trigger hundreds of those per frame with seeing fps/latency being affected, getting out a binding and calling it will be just 5 lines of code, and it will typically be either Nasal or fgcommands (or a combination of both), which are both really fast.
So, I'd suggest to proceed more slowly here, using less thinking in terms of "visions" and ideas, and more thinking in terms of actual experiments/code that do /something/ - I can walk you through making this thing 100% functional by posting another 5-7 snippets of code and then demonstrate how to integrate those - which would be another 3-5 evenings of spare-time coding, i.e. less than 3 hours in total probably - you'll spend more time asking questions and applying code that we post. And you'll end up with a pretty generic snippet of code that can easily be made to support all your ideas without too much work - but the approach you suggested is too complex, too narrow and too much work for someone getting started with Nasal - and the outcome would be inferior to a more generic solution.
So it's up to you obviously how you'd like to proceed - but you'll certainly get stuck pretty soon by focusing on everything else except the most basic functionality.
The key here really is to come up with a handful of generic building blocks and integrate those properly, instead of coming up with separate code for each of your features.
One you think about it, a menubar will not need much in terms of code, it's really just:
- reading/processing XML (done)
- creating windows/popups (done!)
- creating buttons/widgets (done!)
- creating event handlers (done)
Everything else is just a matter of applying existing functionality in another context, so the code can be simply reused.