Hackathon Proposal:Canvas Widgets

From FlightGear wiki
Jump to navigation Jump to search

Title: Getting rid of PUI using the Canvas

about.xml parsed and rendered by the Canvas GUI system
Potential mentors: James Turner
Intro: implement missing Canvas widgets for the PUI/Canvas migration in Nasal
Interested Parties: please add yourself if you are interested in working on this
Status: RFC

1rightarrow.png See PUI#Replacement status for the main article about this subject.

The PUI replacement was going to be Qt but it started to get very complicated with changes in Qt 5.15 + Qt 6, so James is going with a more light-weight Canvas based approach now.

Qt added support for Vulkan / Metal / D3D starting in 5.15, but FlightGear / OpenSceneGraph can’t support those, so integrating the two renderers went from being ‘complicated but ok’ to ‘very very complicated’.

So now James is going with something much more lightweight using some C++ compatibility code, some Nasal for styling and the existing Canvas widget rendering from Thomas Geymayer (TheTom) with some extensions and additions, based on the plans originally discussed when the Canvas GUI system was added to FlightGear: some pieces are in FlightGear & FGData already.

James has basic dialogs working okay but not the more complex ones and everything looks kind of ugly, he needs to improve the visual look before he shares screenshots to avoid everyone freaking out :) The disadvantage of this approach is James is far from expert at creating visual appearances this way, so it’s kind on unrewarding and slow for him. If someone likes messing with CSS-type styling, border-images and hover-states, ping him since we could probably move things also faster [1]


The bigger issue here is we need to ditch PUI (which is in progress) and some OpenGL 1.0 code (HUD, 2D panels especially - can be #ifdef for now) so we can enable Core profile on Mac - since Mac 4.x support (we only hit about 4.3 alas, but with some extensions to get in sight of 4.5) is Core profile only, no Compatability mode.

Improving the frame-rate and modernised 3D rendering, can’t be worked on until the PUI code, 2D panels and Shiva are removed, but doing so is a frustrating slow path[2]

Given that with many graphics drivers PUI doesn't render correctly when higher shader quality is on, many people are convinced PUI needs to be replaced.[3]


1rightarrow.png See Howto:Creating a Canvas GUI Widget for the main article about this subject.

screen shot showing a view the contents of the ambiance classic tarball

The Canvas GUI system is using artwork from Ubuntu/Gtk, the corresponding theme is called "AmbianceClassic", i.e. existing artwork (button, checkbox) are using artwork from: https://www.gnome-look.org/p/1170869/ See also: https://www.gnome-look.org/p/1013157

James's current work is split between Simgear (see classes with widget / layout in the name) and in FGData. (Eg widgets/Button.nas) To be able to use the existing dialog XML files un-modified (which is a design goal), James is extending the widget types with additional ones (eg PUI has slider, dial, combo-box, checkbox, all of which need to be created, see Canvas widget matrix.

This is about 30% done and is the bit he's very slow at. Thomas’s canvas widgets have a very good separation of API + state from appearance, so all styling is in its own file (DefaultStyle.nas), and James is being very strict about maintaining this separation, so we also retain the re-styling feature of the PUI UI, which many people/dialogs also rely on. This does make the process of adding new widgets more complex, however.


The PUI subsystem in FlightGear supports ~15 documented widgets (see $FG_ROOT/Docs/README.gui#l219 for a list of widgets made available to FlightGear via PUI/XML). For a complete list (including custom/undocumented widgets), refer to FGPUIDialog::makeObject() in flightgear/src/GUI/FGPUIDialog.cxx (line 850)

In addition, FlightGear introduces a handful of custom PUI widgets implemented in C++ space, that not even PUI itself supports directly:

However, many PUI widgets can be emulated/approximated by using a combination of existing widgets, and/or functionality found in existing widgets, i.e. by referring to their source code.

For instance, all the data needed to obtain a list of airports or waypoints can be queried using the Navdb APIs exposed via Nasal/CppBind, specifically:

  • findAirportsWithinRange()
  • findNavaidsWithinRange()

At this point, we can map arbitrary navdb calls to help populate a ScrollArea with entries.

Thus, what is primarily needed to implement support for arbitrary -list types is a ScrollArea that uses buttons (or labels) for each entry.

Primarily, the following widgets are needed to help getting rid of PUI (listed in ascending complexity):

  • <combo> (README.gui#l330 | C++ code) (popup with a scrollArea that has buttons for each item (can be shared with <select>)

The key ones really being the last 4 in that list (radio, slider, dial and combo/dropdown)

Required skills: Property tree, PropertyList XML File, Nasal, Canvas, Timers, Listeners
Learning Opportunities:

Notes: to learn more about the underlying idea/approach, please refer to pui2canvas