I haven't really been following the debate on the devel list - and I am not sure I will have the time to catch up with everything that's been said - there's just one thing I'd like to clarify: this is NOT a separate GUI effort, it is a parser that maps our existing PUI/XML tags to the Canvas widget set, and absent those, to lower level 2D drawing and event handling code - which is how it gets away with being under 400 LOC.
I haven't really touched that code in months - but IIRC, I came up with all the proof-of-concept code within just a few days (just see the wiki history), i.e. a single guy could prototype a tiny parser that would be able to handle all/any existing dialogs (including those outside fgdata/fgaddon), while also providing a migration path, and interim solution until other issues have been sorted out.
What I implemented only dealt with a subset of the tags/widgets supported (e.g. no table layouts), i.e. it would definitely need to be extended to support certain widgets that PUI already supports (think dropdown menu), that are not currently available as dedicated Canvas widgets, work that would typically be the equivalent of coming up with a SVG file that implements the artwork, and a Nasal callback that implements the logic (update/event handling).
However, personally I am not the slightest bit opposed to Qt5 - in fact, Tom and I talked about it, and being able to just use Qt5 for the Canvas UI would solve a ton of issues for the Canvas UI effort, too - that is, if we could assume it to be ALWAYS available - but given that Qt5 has been a controversial dependency with some folks (not us!), we simply cannot rely on it to be ALWAYS available for the Canvas use-case, which would mean that certain Canvas efforts (think MFDs) would only work for Qt5-enabled builds, which is obviously a no-go, because at that point, we would be the ones making an optional dependency a required one ...
The real motivation for the Canvas UI is not reinventing the wheel, but being able to render widgets to a MFD and MFDs to a GUI widget (which is unrelated to the appearance of the widget, i.e. has to do much more with event handling and propagating events between different layers properly - imagine rendering a space shuttle MFD inside a GUI dialog, e.g. as part of the tutorial system - which may in turn render GUI widgets and/or external camera views: with the Canvas approach, we have a straightforward way to make this happen in a portable fashion, without platform/build specifics).
That also applies to external GUIs, or multi-instance/multiplayer setups that can seamlessly deal with multiple fgfs instances and selectively propagate/sync relevant state
Besides, Torsten and James are correct in saying that there are widgets that are not currently available via Canvas and which would need to be implemented, which would usually mean additional Nasal overhead (mainly timers and listeners).
However, that is not inevatibly the case - before the Canvas UI effort got declared dead, we talked about using Torsten's autopilot/property-rule subsystems to dynamically instantiate "property controllers" on-demand as part of the /canvas sub-tree (per Canvas or per element) to help update/animate Canvas elements - this would mean that the degree of added Nasal overhead would be kept to an absolute minimum that would only come to bear during initialization of the corresponding C++ data structures, but afterwards everything would be pure C++ code
The main thing that prevented us from adding more widgets at the time was the degree of artwork needed, which is why Tom ended up borrowing artwork from Ubuntu, and we contemplated using a JavaScript/HTML widget set using SVG artwork, so that we would not have to draw dozens of widgets ...
Anyway, the code I originally came up with is to be found here: http://wiki.flightgear.org/Howto:Proces ... ource_Code
To test it, all that needs to be done is to put it into a Nasal file that is loaded during startup (the console may work, too) - I would recommend to put it into $FG_HOME/Nasal/pui2canvas.nas
Apart from that, there isn't anything else needed from an integration standpoint, it will go through the fgcommand layer so that the parser can be tested by using a line like this:
- Code: Select all
fgcommand("canvas-dialog-show", props.Node.new({'dialog-name':"view"}) );
Like I said, I haven't put much/any work, or thought, into extending it to support unsupported use-cases since there was so much opposition, but I don't believe it to be difficult to bring up to par with the functionality of PUI, including dialogs with embedded Nasal code, dialogs with embedded Canvas regions (airports.xml), as well as procedurally created/updated dialogs like the multiplayer/pilot list or performance monitor.
The work ahead is comparatively straightforward, and while it could definitely benefit from certain C++ additions, those are not needed - compared to the Qt5 work ahead of us, a dedicated fgdata contributor familiar with Nasal, Canvas and SVG editing could definitely provide a PUI replacement without requiring too much time - after all, the main work is extending the parser to support the existing PUI/XML format, and mapping that to existing Canvas features, and come up with new widgets for which we don't currently have matching Canvas widgets.
Which are basically the exact workflows aircraft/MFD developers are already familiar with.
From my standpoint, I would just like to use Qt5 if it was available, and I have been in touch with TheTom on adding the corresponding factories to the Canvas system - but if that is not an option because others don't want to require Qt5 for building FG, we still need a generic UI framework for all the use-cases not covered by optional Qt5 support.
As far as I can tell the main bottleneck is, like James and Torsten said, the number of available Canvas widgets/artwork - but if an existing SVG widget library is used, that could be quickly addressed, because we can already render SVGs and register event handlers.
Besides, the main loop/async point remains valid, but it would be possible for the Nasal/Canvas route to learn from Phi and use the same mongoose/httpd layer to run its property I/O and fgcommands asynchronously, at the mere cost of requiring the httpd service to be up and running for the UI to work in async mode. After all, all Nasal http I/O is already async anyway...
The best way to reduce Nasal overhead is expose more SimGear/FlighGear subsystems to scripting/Canvas space, so that e.g. property rules and state machines can be used for updating/animating Canvas elements - at that point, there's really no added Nasal overhead at all. Equally, it would be possible to not just support event handlers in the form of Nasal callbacks, but just fgcommands - which work without Nasal entirely.
The major benefit this would have is that Canvas is modern OpenGL/OSG code, and that it's integrated in an OSG--aware fashion, while also being property-tree enabled, which means that remote interaction scenarios can be easily implemented, which includes remote replication of UIs/MFDs etc.
I have seen some words of encouragement to pursue this further given the segfaults introduced by the Qt5 code, but it seems that bugman and James addressed some of those recently - so I haven't yet really thought about resurrecting the parser - however, it being just a fgdata module, it could obviously be added as a runtime option without requiring core developer support/endorsement necessarily - like some people said already on the forum, it might provide a sane option for users with AMD/ATI hardware that would otherwise not be able to use the UI at all.
Possibly, this may get more attention/traction once it is provided as a "fallback option" as part of the base package - and the way it is implemented, it is a Nasal sub-module that can be kept disabled by default, like some have suggested. However, it's not that it would actually "run" anything if the code is not used - the main overhead is the number of added GC symbols (variables), but otherwise there's no runtime footprint if it's not used
I will try to review the main points made on the devel list and see if a follow-up is needed, and/or if the parser should be resurrected (or just declared dead, too) - but like I said, none of the Canvas UI folks are opposed to Qt5 at all, if it were generally available (and not intended to remain optional), we would just jump onto the same bandwaggon and use it, as long as there are steps taken to ensure that we can render UI widgets to a Canvas texture and a Canvas texture to a Qt5 widget ...
Because this degree of supporting full "recursion" is it that would enable us to also create built-in tools (GUI editors) for creating, editing and maintaining resources like a HUD, 2D panel, cockpit instruments, splash screens or MFDs as a whole.
PS: I am also involved in a project using J661 (ARINC 661) in conjunction with FlightGear, which needs a way to render widgets to a MFD, so some of this is motivated by ARINC 661 compatibility - modern avionics like the Avidyne Entegra R9 will undoubtedly greatly benefit from a UI framework, unrelated to its appearance being different from the main UI or not - that's just a matter of styling, which the Canvas UI framework supports as a first class concept (it is even possible to retarget Canvas UIs to support mobile platforms, it's mainly scaleable vector graphics after all)