Howto:Creating a Canvas GUI Widget: Difference between revisions

Jump to navigation Jump to search
m
Reverted edits by Hooray (talk) to last revision by Red Leader
m (Reverted edits by Hooray (talk) to last revision by Red Leader)
Line 12: Line 12:
   }}</ref>
   }}</ref>


For the time being, this approach has a number of major advantages, i.e. it has proven to be able to deal with existing UI resources (dialogs, and [[Menubar]]), without the original legacy UI dialogs (or any C++ code) having to be touched/modified, so that the primary thing missing to parse/process these dialogs are a handful of missing Canvas widgets, which can also be implemented in scripting space usually.
For the time being, this approach has a number of major advantages, i.e. it has proven to be able to deal with existing resources, without the original legacy UI dialogs having to be touched/modified, so that the primary thing missing to parse/process these dialogs are a handful of missing Canvas widgets.  
 
For the time being, this approach also is the only effort that can easily support procedurally created and updated dialogs like [[Aircraft Checklists]] and [[Tutorials]].
Also, the '''pui2canvas''' approach can help address a number of long-standing PUI related issues, such as rendering arttfacts  on some ATI/AMD GPUs, but also PUI/Canvas inter-operability issues related to [[Canvas Event Handling]].


As the integrated, and fully script-able, [[Canvas GUI]] develops, new {{wikipedia|Widget (GUI)|widgets}} need to be added <ref>{{cite web
As the integrated, and fully script-able, [[Canvas GUI]] develops, new {{wikipedia|Widget (GUI)|widgets}} need to be added <ref>{{cite web
Line 36: Line 33:
For a complete list (including custom/undocumented widgets), refer to <code>FGPUIDialog::makeObject()</code> in {{flightgear file|src/GUI/FGPUIDialog.cxx|l=850}}
For a complete list (including custom/undocumented widgets), refer to <code>FGPUIDialog::makeObject()</code> in {{flightgear file|src/GUI/FGPUIDialog.cxx|l=850}}


In addition, FlightGear introduces a number of custom PUI widgets implemented in C++ space, that not even PUI itself supports directly:
In addition, FlightGear introduces a number of custom PUI widgets implemented in C++ space, that not even PUI itself supports directly.
* {{PUI widget|airport-list}}
However, many PUI widgets can be emulated/approximated by using a combination of existing widgets, and/or functionality found in existing wigets.
* {{PUI widget|waypoint-list}} (only used by the [[Route Manager]] i.e. {{Dialog file|dialog=route-manager}} 
* {{PUI widget|property-list}} (only used by the [[Property browser]] i.e. {{Dialog file|dialog=property-browser}}
 
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.


As of late June 2016, the following widgets are primarily needed to help getting rid of PUI (listed in ascending complexity):
As of late June 2016, the following widgets are primarily needed to help getting rid of PUI (listed in ascending complexity):
* {{PUI widget|vrule}} (not critical, could  be implemented OpenVG or simply by using a transparent image)
* {{PUI widget|vrule}} (not critical, could  be implemented OpenVG or simply by using a transparent image)
* {{PUI widget|hrule}} (not critical, could  be implemented OpenVG or simply by using a transparent image)
* {{PUI widget|hrule}} (not critical, could  be implemented OpenVG or simply by using a transparent image)
* {{PUI widget|radio}} (Canvas images using event handling to dynamically change the image based on mouse events)
* {{PUI widget|radio}} (Canvas images using event handling)
* {{PUI widget|slider}} (basically 3 buttons with the middle button supporting dragging, see also [https://forum.flightgear.org/viewtopic.php?f=71&t=19975])
* {{PUI widget|slider}} (basically 3 buttons with the middle button supporting dragging, see also [https://forum.flightgear.org/viewtopic.php?f=71&t=19975])
* {{PUI widget|dial}} (see also [https://forum.flightgear.org/viewtopic.php?f=71&t=19975])
* {{PUI widget|dial}} (see also [https://forum.flightgear.org/viewtopic.php?f=71&t=19975])
Line 53: Line 46:
The key ones really being the last 4 in that list (radio, slider, dial and combo/dropdown)
The key ones really being the last 4 in that list (radio, slider, dial and combo/dropdown)


Most other widgets currently missing can be implemented by using a combination of these widgets, e.g. a ScrollArea with buttons can be used to implement any type of list (airportlist, waypointlist, property-browser etc), just by adding event handling callbacks to each entry/button that invoke the corresponding bindings:
Most other widgets currently missing can be implemented by using a combination of these widgets, e.g. a ScrollArea with buttons can be used to implement any type of list (airportlist, waypointlist, property-browser etc)


<gallery>
However, once these basic widgets are supported, additional FlightGear/flight simulation specific widgets may be implemented, e.g. for picking a frequency, heading/course etc (see [[UI_Unification#Widget_tags]]).
Pui-airport-list-widget-in-canvas.png|airport-list widget re-implemented using Canvas ScrollArea and Buttons arranged in a VBox layout
Crude-canvas-property-parser.png|crude property-browser approximation using the pui2canvas parser (unmodified dialog), no layouts or sorting applied
</gallery>


This ScrollArea-based approach has the added benefit that improvements to the ScrollArea widget will automatically benefit widgets using it internally.  
A new Canvas widget will have two parts to it.  


However, once these basic widgets are supported, additional FlightGear/flight simulation specific widgets may be implemented sooner or later, e.g. for picking a frequency, heading/course etc (see [[UI_Unification#Widget_tags]]).
The first provides the background code and the APIs for that widget. The second defines the appearance of the widget, i.e. its style.


== Widget.nas ==
== Widget.nas ==
Line 84: Line 74:


== Part one ==
== Part one ==
A new Canvas widget will have two parts to it.
The first provides the background code and the APIs for that widget. The second defines the appearance of the widget, i.e. its style.
The first part is a Nasal file in {{fg root file|path=Nasal/canvas/gui/widgets}}, e.g., . They must follow the basic structure of the example below, replacing  
The first part is a Nasal file in {{fg root file|path=Nasal/canvas/gui/widgets}}, e.g., . They must follow the basic structure of the example below, replacing  
{{Canvas Widget Template|name=myWidget}}
{{Canvas Widget Template|name=myWidget}}
Line 128: Line 114:


== Examples ==
== Examples ==
{{Stub}}
=== Implementing a hrule widget ===
=== Implementing a hrule widget ===


Line 180: Line 164:
* <code>scrollTo()</code>
* <code>scrollTo()</code>
* ...
* ...
=== Implementing a graph widget ===
{{See also|Canvas_Snippets#Adding_OpenVG_Paths}}
[[File:Openvg-via-canvas.png|thumb]]
{{Canvas Widget Template|parent=Widget|name=graph}}
=== Map ===
{{Main article|MapStructure}}
{{WIP}}
[[File:MapStructure-map-widget.png|thumb|MapStructure Canvas widget prototyping]]
Assuming, we have access to a root group, the most minimal snippet of code to display a layered MapStructure map is the following:
<syntaxhighlight lang="nasal">
var TestMap = root.createChild("map");
TestMap.setController("Aircraft position");
TestMap.setRange(25);
TestMap.setTranslation(width, height);
    var r = func(name,vis=1,zindex=nil) return caller(0)[0];
    foreach(var type; [r('VOR'),r('APT'), r('APS') ] )
            TestMap.addLayer(factory: canvas.SymbolLayer, type_arg: type.name, visible: type.vis, priority: type.zindex,);
</syntaxhighlight>
Next, we need to wrap this in a Widget.nas child class:
Everything that we'd like to be able to customize at the widget level, needs to be exposed via a corresponding method added to the subclass inheriting from Widget.nas, for example:
* setController()
* setRange()
* setLayers()
* ...
To approximate the appearance of the legacy [[Map]] dialog, we will be using a hbox layout with two columns, with the left column containing a vbox layout with checkboxes added for each layer to control visibility of the layer, and the right hbox cell containing the actual MapStructure map:
Once we are finished, we can check if the widget is working properly by adding a handful of identical widgets to the same dialog, all of which should work independently, i.e. having their own checkbox/range widgets to control the corresponding map widget.
== References ==
{{Appendix}}
[[Category:Canvas GUI]]
[[Category:Canvas GUI]]

Navigation menu