Board index FlightGear Development Canvas

Canvas G1000

Canvas is FlightGear's new fully scriptable 2D drawing system that will allow you to easily create new instruments, HUDs and even GUI dialogs and custom GUI widgets, without having to write C++ code and without having to rebuild FlightGear.

Re: Canvas G1000

Postby Hooray » Fri Jan 12, 2018 7:50 pm

To be honest, you may still already want to share your current work "as is" - simply because none of what you mentioned is a real problem on technical grounds - as a matter of fact, what you have created so far, would enormously help the FG1000 by enabling the removal of the PUI dependency without having to create custom Canvas widgets - thus, please don't waste any of your time "micro-optimizing" pixel level issues. It is more important to have a functional replacement rather than a nice-looking one that matches the real thing 1:1

The point being that once you provide this artwork, the work to drop the PUI dialog can be started - and for that, it is not important if there are any visual issues.
Besides, there's still the option to replace the artwork in the future should you come up with a refined/more accurate set of images.
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: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby Michat » Sat Jan 13, 2018 7:24 pm

Little pattience was needed. Now I have the job completed but is not discarded any error, if so we could amended that later.


Here the G1000 Main Interface. Created with Inkscape 0.91 r13725

Image


Hope you like it.

29.92
Last edited by Michat on Wed Dec 02, 2020 9:46 pm, edited 2 times in total.
User avatar
Michat
 
Posts: 1226
Joined: Mon Jan 25, 2010 7:24 pm
Location: Spain
Version: 191b
OS: MX 21 Fluxbox oniMac

Re: Canvas G1000

Postby Hooray » Sat Jan 13, 2018 7:35 pm

Hi,

that's looking really good - thanks for sharing this with us !
Are you able to post download links for the SVG files that you have created, so that this can be comitted to the fgdata repository ?

EDIT: Sorry, I missed your PM: https://ombx.io/UZKoPzBL
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: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby Michat » Sat Jan 13, 2018 8:36 pm

Just add that this job is made for FG . Don't need any especial attribution of my person. Is a present-donation to FG.

Me, Michat. I donate the so called garmin1000B.svg file created by me using GPL Inkscape software to FlightGear, the Free Flight Simulator as a present to the flightgear.org. Since now I derived all legal rights to FlightGear via two active developers representatives on this forum topic: Stuart and hooray. They will proceed to upload the file to the FG repository, choosing the best license in order to protect FlightGear from any scammer simulation software, if is possible. Having account the nature of the Flightgear project as public well.

The 13TH of January 2018 in Madrid Spain.

Michat.
User avatar
Michat
 
Posts: 1226
Joined: Mon Jan 25, 2010 7:24 pm
Location: Spain
Version: 191b
OS: MX 21 Fluxbox oniMac

Re: Canvas G1000

Postby stuart » Sat Jan 13, 2018 9:59 pm

Hi Michat,

Thanks very much for your contribution! That looks really great!

Once I read up a little more on canvas UIs, I'll use this to replace the PUI version.

Best regards,

-Stuart
G-MWLX
User avatar
stuart
Moderator
 
Posts: 1629
Joined: Wed Nov 29, 2006 10:56 am
Location: Edinburgh
Callsign: G-MWLX

Re: Canvas G1000

Postby Hooray » Sat Jan 13, 2018 10:24 pm

The basic workflow is pretty straightforward actually, and would not involve touching any of your existing code:


To make the clipping/button handling work, you'll primarily need the coordinates/dimensions of the corresponding rectangles - which can be easily obtained by setting up a global event listeners for the whole Canvas for the DRAG/DROP event, and dumping the corresponding x/y coordinates to the console, to populate a vector with hashes contains all buttons - that is how rleibner's oscilloscope code (see fgaddon) works, too.

To actually treat another Canvas (the FG1000 MFD) as a raster image that can be added to the dialog, it needs to be added using a special "filename syntax" - for details, see the links below.

Like I said previously, for the bindings part (Emesary Notifications) it would seem like a good idea to set up dedicated fgcommands via the addcommand API and simply use an fgcommand factory to map the "buttons" to the corresponding notifications, without using custom Nasal blobs all over the place. That way, it would be trivial for other processes/back-ends (including FGQCanvas and/or Phi) to use the existing fgcommand infrastructure, without requiring any dedicated Canvas event handling support, which I understand is still lacking anyway.

This kind of design/setup would make it possible to instantiate an arbitrary number of FG1000 instances for different purposes, possibly using different "drivers" (data provider back-ends), which would also be a good opportunity to do stress-testing for benchmarking purposes, and to help identify potential bottlenecks that may need to be augmented via dedicated C++ space hooks sooner or later (which is to say, both the httpd and telnet/props mechanisms can access the fgcommand layer, and thus it'd be straightforward to hook up Phi/FGQCanvas to the FG1000 back-end).

HTH

Plot2D and graph helpers
Hooray wrote:
If that's something that you'd like to explore, the relevant pointers are these:

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: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby stuart » Sat Jan 13, 2018 10:44 pm

Hi Hooray,

Thanks for the pointers - just what I needed and very timely too!

Re: the global event listener - presumably we don't have a way to bind to the individual elements within an SVG file? I suspect that the FG1000 surround that MiChat has created won't render as SVG due to Canvas' limited SVG support so I'll need to render it as a raster anyway.

I can see how addcommand is helpful. I'll add that at some point soon. Too many things on the TODO list, but progress is good: I've got the NAV/COM linked up, and it'll sync up really nicely with the C172p. I've also separated out the data provider (airportinfo() etc) so they are retrieved over an Emesary bridge, so it will be easy to replace them with other drivers in the future.

-Stuart
G-MWLX
User avatar
stuart
Moderator
 
Posts: 1629
Joined: Wed Nov 29, 2006 10:56 am
Location: Edinburgh
Callsign: G-MWLX

Re: Canvas G1000

Postby Hooray » Sat Jan 13, 2018 10:55 pm

Yes, we do have that (binding to individual elements) - keep in mind, any element you see on the screen is also just that: a Canvas element, so any event handling can be made to work that, too.
The most common way this is done is looking up the ID of the SVG element and then you'll get a Canvas.Element from it, and you can use all the APIs there.
Obviously, that means that all elements that you want to look up, need a valid/unique ID.

The baseclass API being this: http://wiki.flightgear.org/Canvas_Element
And the Canvas-specific mapping from SVG element to Canvas space is the Canvas.Path child class: http://wiki.flightgear.org/Canvas_Path

Basic example to look up an SVG element by its SVG/XML id and treating it as a Canvas element/path, is shown here: http://wiki.flightgear.org/Canvas_SVG_P ... ic_example

Regarding your other comments of treating it as svg/xml vs. raster image - that's a valid concern, and even if the SVG/XML file can be simplified to make it work (or the parser extended accordingly), it may still be a worthwhile optimization - especially assuming that multiple instances of the dialog may be instantiating multiple "nodes" for the whole shell.

I believe it would be a good simplification for now to create a set of raster images for our needs, and only commit the SVG file as "source code".
If however, the SVG/XML can be fed to svg.nas/parsesvg() "as is", I would simply do just that, and look at the previously mentioned pointers regarding the "SymbolCache" - it is the equivalent of a caching scheme for creating raster images from SVG/XML images - if the latter need to be instanced many times (or are sufficiently complex, which I believe to be the case here)

Note that you can also create/use conventional texture maps using the Canvas system:
http://wiki.flightgear.org/Canvas_Image#src
http://wiki.flightgear.org/Howto:Using_ ... xture_Maps

Yes, I do agree that you've been making enormous progress here - and I believe this is an excellent project, because it shows what can be accomplished if people actually team up temporarily to help eachother out - which is remarkably exemplified by Michat's most recent contribution to this effort, as well as the great MFD/Emesary groundwork created by Richard obviously, not to mention TheTom and his Canvas system to begin with.

PS: If the SVG/XML is too complex for the parsesvg implementation right now and cannot be easily reduced in complexity, another possibility might be revisiting the patch that adds raster image support to svg.nas, to move some of the complexity of the "shell" into a separate texture map, to only use a safe subset of SVG/XML, which should also be a good optimization from the Canvas standpoint.
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: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby Richard » Sun Jan 14, 2018 3:25 pm

stuart wrote in Sat Jan 13, 2018 10:44 pm:so they are retrieved over an Emesary bridge, so it will be easy to replace them with other drivers in the future.


This is actually a good use of Emesary; a defined set of notifications become the API layer, and can easily be swapped out, debugged etc.

To illustrate instead of having a data provider, a factory and glue logic to abstract an API you can instead do

Code: Select all
var notification = GetAirportsNotification.new(30);
if (!emesary.Transmitter.IsFailed(transmitter.NotifyAll(notification))) {
    # at this point notification.AirportList contains the list of airports.
}
else
    print("Failed to get list of airports within range");


Generally I'd refer to something as bridge in an Emesary contenxt when it connects two transmitters together, often over a process / machine boundary. Bridges are less often required on a local instance but can still be used if needed.
Richard
 
Posts: 810
Joined: Sun Nov 02, 2014 11:17 pm
Version: Git
OS: Win10

Re: Canvas G1000

Postby Hooray » Sun Jan 14, 2018 9:37 pm

FWIW, now that Emesary is actually being adopted, it might make sense to also review the delegates used for the MapStructure setup, because those should ideally also be using Emesary instead of using hard-coded assumptions.
I guess for now, it'd suffice to just add a comment to the code to keep this in mind - because otherwise the MFD may behave erratically, since none of the MapStructure stuff knows about Emesary (obviously).
Speaking in general, Stuart's recent work on wrapping the navdb/navcache calls via Emesary "bindings" would actually qualify as being sufficiently generic in nature to be moved into $FG_ROOT/Nasal - and possibly an emesary specific sub-folder there (aka sub-module), e.g. $FG_ROOT/Nasal/emesary.
That would make it possible to easily use the FG1000 approach elsewhere - alternatively, these bindings could be added as the default "wrappers" to Richard's MFD framework, what do you think ?

Besides, since you mention using Emesary across process/machine boundaries: are you aware of Nasal's thread module (thread.newthrad) ?
I am asking because that might obviously be a first step to move some stuff to a separate thread - Nasal itself is actually designed to be thread-safe as long as it's using any fg extension APIs. So, it would be interesting to identify what is missing to run certain "tasks" outside the fgfs main thread. Navcache queries could in theory be a potential candidate for that - for instance, we've seen web-api based navdb replacements that are doing asynchronous web API queries anyway - thus, it would not seem far-fetched to also let the underlying Emesary code run outside the main thread (if possible).

Note that I am not saying that this is relevant right now or that this should even be done - just asking about your thoughts regarding Nasal/Emesary use outside the main thread.
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: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby Michat » Sun Jan 14, 2018 9:58 pm

Hi there.

During some conversations with Hooray related with svg-design-solutions, I've received this question which we want to share:

Thanks again, here's a question for you:

The svg parser (support) available in FlightGear/Canvas is currently still very simple.
So it is sometimes not able to load/display some files, due to their complexity (using certain SVG features that Canvas knows nothing about).
Thus, the question is, how difficult would you say is it to reduce the complexity of the SVG markup, e.g. by using separate textures ?
Please note that I am NOT asking you to do ANY work here - just wondering what you think.
I have been in touch with Stuart to discuss other options - but maybe you could update the topic and tell us what you think ?

Again, the problem is not that bad actually - because we can simply use SVG to export the SVG to a raster image.
So mainly asking for your feedback, not any work !



My response:

I'm not sure if we can reduce some complexity in the markup, I think gradients are kind of that, as I get processor 100% when I apply that effect on Inkscape. Another complexity is that some elements are transparent in order to match the result, I know it because I tried to use absolute alpha channel and is not working well, i mean the result is basic quality, cement color effect. Even don't know if the raster bitmap is substantially cheaper in Kb with or without gradients-trans .

Referred to your question I'll say that the entirely panel design can be divided into symbolic parts without breaking it into pieces just by using a subset element with the desire dimensions, file-column or square tile element to be on the bottom for the png exportation selection area, this tile element will contain all the pixel information onset over it. The scariest thing of that is how crazy is Inkscape to tile as there isn't any crop or selection tool. The result with tile element as selection mask is okay, use to be tiled but with some micra invisible blank spaces between tiles that occurs when I join them back together. I hope is about Inkscape runtime render. :?

From the svg point of view, also the entire design should be transformed into a clon with new redesign, dimensions, file-column layout. With this approach the final quality aka eye candy can not match the best results, but maybe we can find a good looking plus performance solution, avoiding transparencies and or gradients. I'm afraid that like I said, some button have been created with opacity in order to match best results. So if for example we use a raster texture of a rotary button and we turn it. Maybe the texture will not match background coherency with gradients trans. Should work fine for on-click lit on, and perhaps may work too in non rotary buttons states like button_pressed.

Another strategy could be to attack with simpler solid based color vectorial design parts ( mainly basic shapes) that could resolve a general aesthetic of the instrument. Initially I predicted an scenery like this, so I created a modular design where some pieces like files and columns are independent but highly dependent on how they combine each other at the watcher's eye.

For me is not a big problem to move elements since they've just been created once, I can manipulated them easily.
Again answering to your question as an example, we can work with different fragment sizes, I believe in some cases we need to adopt some kind of responsive design for huge screen resolution and ratios..? In that case we can scale up relative or absolute

Just tell me what the best for your work, if there is a header, column, footer layout, or if it's gonna be a grid, a kind of layer by layer composition, sizes, or whatever you want to try


Thanks


Just a parenthesis into your code conversation.

29.92
User avatar
Michat
 
Posts: 1226
Joined: Mon Jan 25, 2010 7:24 pm
Location: Spain
Version: 191b
OS: MX 21 Fluxbox oniMac

Re: Canvas G1000

Postby stuart » Sun Jan 14, 2018 10:01 pm

Hi All,

Thanks to Michat's great work on the SVG surround, and Hoorays pointers to where to look for the right code to use, I've just pushed an SVG UI for the FG1000, replacing the PUI version.

Image

You can access it from the Debug menu. All the buttons and knobs are set up, though some of them don't actually do anything!

See the Garmin website for documentation, but for a quick cheat's guide:
- Use the outer FMS knob (shift-mouse wheel on the FMS knob on the bottom right) to navigate through the page groups.
- Use the inner FMS knob (mouse wheel on the FMS knob on the bottom right) to navigate through the pages within the group.
- To moved around the page, click on the FMS knob, and then use the FMS knob to navigate around the page.
- Press ENT when any frequency is highlighted to load it into the standby frequency of the NAV/COM.

-Stuart
G-MWLX
User avatar
stuart
Moderator
 
Posts: 1629
Joined: Wed Nov 29, 2006 10:56 am
Location: Edinburgh
Callsign: G-MWLX

Re: Canvas G1000

Postby Richard » Sun Jan 14, 2018 10:21 pm

Hooray wrote in Sun Jan 14, 2018 9:37 pm:Note that I am not saying that this is relevant right now or that this should even be done - just asking about your thoughts regarding Nasal/Emesary use outside the main thread.


Emesary was originally, by design, strictly synchronous[1], and although this has changed I still feel that it works best when synchronous. What I mean by this is "notifyAll" will block whilst the transmitter iterates recipients and notifies them.

In the C# bindings I had something using lambdas (pseudocode below) that would allow a section of code to be executed when in an incoming message was in response to a uniquely identified outgoing message, based on a GUID). It was quite nice to write syntactically as it effectively bound an outgoing response to a reply - that could happen minutes or hours later.

Code: Select all
    notifyAll(notification).response( (QueryResponseNotification completednotification) => {
        if (completedNotificationis QueryResponseNotification)
        {
            // do something with the return notification - this will happen asynchronously
            return ReceiptStatus.OK;
        }
        return ReceiptStatus.NotProcessed;
    });

----------------

[1] Mostly bridges will have to result in asynchronous operation; and in this case the bridge will return "ReceiptStatus_Pending" which indicates that the notification has not been processed. The C# version supports queues that can run on separate threads, but mostly queues are best avoided because of the inherent complexities in handling asynchronous code.
Richard
 
Posts: 810
Joined: Sun Nov 02, 2014 11:17 pm
Version: Git
OS: Win10

Re: Canvas G1000

Postby Hooray » Sun Jan 14, 2018 10:47 pm

Just been looking briefly at the latest commit/changes: It seems this is using a single Canvas, but I would still suggest to consider using the Canvas.Image based approach - since that means, that the shell/skin can be better/more easily shared between multiple instances of the dialog - that is also how the native Canvas GUI dialogs are creating their window decoration (i.e. dialog bar - if in doubt, use the property browser to see for yourself).

Referring to the previously mentioned pointers, this would mean setting up a separate Canvas for the MFD screen (middle part of the instrument) and referencing that via a corresponding canvas image element.

That way, it would be trivial to re-use the surround part for other instances of the same MFD (without unnecessarily replicating the texture/canvas) - but at the same time, it would be easier for cockpit models to provide a dialog/full-screen option, because the shell dialog would merely be told to render an already existing MFD in the middle of the screen.

Doing that may also have performance implications - especially if we begin animating the shell, because the inner part of the display would not need to be updated/re-rendered if a button/dial is pressed/selected - otherwise, the whole canvas would be marked as "dirty" (i.e. all its MapStructure layers) - whereas the canvas.Image based approach would treat the other canvas as a conventional raster image only (think of it as streaming one canvas to another one).

Apart from that, the vector with hotspots could probably use an additional tooltip member to provide hotspot-specific tooltips, which is what rleibner is using IIRC.
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: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby stuart » Mon Jan 15, 2018 4:52 pm

Hi Hooray,

Re: using the Canvas.Image based approach. Yes - I'll almost certainly do that when I get the chance next. I've been looking at providing a scaled version and simply being able to scale the image would be handy - as it stands it's a bit too big to be useable in-sim, even on a large monitor, so having a 50% or 75% scale version would be valuable.

Adding tooltips for the hotspots is a great idea - hopefully it should be easy enough to do.

-Stuart
G-MWLX
User avatar
stuart
Moderator
 
Posts: 1629
Joined: Wed Nov 29, 2006 10:56 am
Location: Edinburgh
Callsign: G-MWLX

PreviousNext

Return to Canvas

Who is online

Users browsing this forum: No registered users and 3 guests