Board index FlightGear Development Canvas

Airbus Navigation Display

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: Airbus Navigation Display

Postby artix » Mon Jan 05, 2015 3:25 pm

Hooray wrote in Sun Jan 04, 2015 8:59 pm:stuff like instrumentation/efis/nd/managed-spd would ideally be moved to a delegate inside aircraftpos.controller, which would then be used by the MS/ND files, so that anything that is aircraft specific can be easily configured/overridden there


instrumentation/efis/nd/managed-spd is related to the "managed speed mode" Airbus feature, i don't know if there's some equivalent feature on Boeing: managed speed mode is activated by pushing the speed knob on the FCU panel and indicates that the flight management computer should handle the speed target. It's opposed to selected speed mode which means that the pilot manually sets the target speed by rotating the speed knob on the panel.
It's only used by the DECEL layer that's used to mark the deceleration point on the ND: deceleration point indicates the point where the aircraft should decrease speed to VAPP (approach speed). Overpassing the deceleration point when the aircraft is flying in managed speed mode makes the aircraft automatically reduce the speed (in that case the deceleration symbol is displayed in magenta).
I don't know if there's an equivalent feature (deceleration point) on Boeing aircrafts.
By the way, I don't think that managed/selected speed mode should be handled by aircraftpos.controller that's used for aircraft position (lat,long,altitude,...), IMHO.
artix
 
Posts: 93
Joined: Wed Jun 25, 2014 9:42 pm
OS: Mac OS X

Re: Airbus Navigation Display

Postby artix » Mon Jan 05, 2015 3:45 pm

Philosopher wrote in Sun Jan 04, 2015 10:03 pm: be careful with tabs vs 2 spaces vs 4 spaces – my version of MapStructure.nas only has tabs, api.nas uses 2 spaces, etc. while most of what I see added is 4-spaced ;-) It's not "bad", it just looks ugly on different editors...

Ok, my editor is set to 4-space and i didn't notice the difference because it also "renders" tabs with 4 spaces. I will take care of specific indent settings for every file i edit.
Philosopher wrote in Sun Jan 04, 2015 10:03 pm: do you have a use case for your getChildrenOfType/setColor? I would want to make sure Tom reviews those... also var children = array is unecessary – just call the argument children.... and I think it could be optimized a bit (no need to call regular .getChildren IMO)

getChildrenOfType is used by Group.setColor method that's used to set color to group children: it takes an optional vector argument that's used to filter the "class" of children, ie. grp.setColor(1,1,1,[Path]) means that all grp's chidren of type Path should be set to white. It's used on some symbols (ie. NDB).
Regarding the children = array you're right: it's unnecessary and i will remove it.

Philosopher wrote in Sun Jan 04, 2015 10:03 pm: is there a reason for making the argument to Map.addLayer be _options not options? personally, since the argument name is public-facing, I would make it named without the underscore. (looks like you just assign it back anyways, right?)


I remember that i had problems with passing the local variable 'opt' to the 'options' named parameter, so i quickly renamed the parameter to _options. If I remember correctly the options parameter in addLayer always took the options local var despite the fact i was passing the opt local variable, this was really weird. I've thought that this was a Nasal bug with same-named variables, or something related to the closure bindings that makes local variables outside the function call overlap with the function parameter names, but i really don't know. I just used the quickest workaround despite i know it's "ugly".
artix
 
Posts: 93
Joined: Wed Jun 25, 2014 9:42 pm
OS: Mac OS X

Re: Airbus Navigation Display

Postby Hooray » Mon Jan 05, 2015 3:51 pm

re: your first response:
okay, thanks for the explanation.
I'll let Gijs & Hyde comment on the Boeing requirements for this.
But I still do believe that we should NOT hard-code such properties - even if they're manufacturer-specific, it makes sense to encapsulate properties - so that they can be overridden.
In simple terms, the managed-spd functionality seems pretty close to the Td/Tc feature - i.e. it is about visualizing lat/lon points, kinda like "events".

So, from a MapStructure/coding standpoint, I would like to see similar features being unified/generalized.
For instance, we could have a common base class for both layers, where only symbology/computations and properties would be custom/overrridden.
That should allow us to have a simple base class that could be shared by both layers, despite different functionality - e.g.. Something like "NDMarker".


By the way, I don't think that managed/selected speed mode should be handled by aircraftpos.controller that's used for aircraft position (lat,long,altitude,...), IMHO.

it is true that this is currently the focus of the file - but back when we implemented this, Philosopher and I didn't communicate very much, so we implemented similar functionality using different methods.
The whole "NDSourceDriver" logic is basically an ugly workaround trying to accomplish the same thing. Philosopher's method is better/more elegant, but currently specific to "position" stuff.
Personally, I think the right thing would be to encapsulate all things that might be aircraft-specific. As that would allow to easily support different aircraft, while also supporting different "drivers" (think AI traffic). This is not so much required for actual use, but for proper coding/design, i.e. refactoring/regression testing. Because most of the folks involved in the MS/ND efforts are not going to fire up all kinds of different aircraft to test things - we prefer to open a bunch of GUI dialogs and test the map/nd that way. For that to work, it makes sense to support multiple AI traffic aircraft - which ensures that things are proper "instances" (i.e. independent).

The basic idea can be seen in the original thread (which is why I do still believe that any property/autopilot/route manager stuff needs to be fully encapsulated):
Subject: How to display Airport Chart?
Hooray wrote:Since I wanted to test if the navdisplay.mfd file has been sufficiently decoupled from the main aircraft/use, I put a quick hack together:

Image

compare groundspeed/headings etc in the main aircraft and in the canvas window.
(this is the same backend code, just with a driver hash to use AI traffic as the data source, rather than the main FG aircraft - and it's working NICELY, this is even superior to the built-in map dialog ! obviously AI aircraft doesn't have any cockpit buttons, so I had to use the property browser to set up the ND...)
Image



In fact, I would prefer extending navidsplay.mfd so that we can use to create procedural dialogs showing an ND without any aircraft dependencies - i.e. so that I can hook the ND up to an existing Ai aircraft for testing purposes. Equally, it would make sense to then add a simple wrapper for turning the ND into a proper Canvas widget, which should greatly help all people involved in developing/testing things - including multiple ND "styles" (types). For that to work, things MUST be properly encapsulated.

The basic idea can be seen below, where Gijs' ND code is simply used to show an ND embedded in a conventional PUI dialog, including proper switches for all layers, as well as support for changing the "data source" (i.e. to select an AI aircraft view):
Image
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: Airbus Navigation Display

Postby Philosopher » Sun Jan 25, 2015 3:36 am

This week I had a little time to check out MapStructure... I didn't pull the branch (yet... sorry) but I did verify that the master branch looked OK, and it did. (I did see some >300ms updates with FIX and all the layers, but disabling most of that left it at about ~20, which is good. I also verified everything deleted properly.)

Anyways, I just thought that we could pass levels of update to the canvas.Map.update(update_level). For example, the aircraft symbol would update >= 0, TFC if >= 1, VOR if >= 2, maybe FIX if >= 3 (just because there's generally more of those around = more overhead). We could define 0 as any time the position changes (aka every frame), 1 would be after a small delay (.1 sec?), 2 after a significant change in position, etc.

If only we could run them as threaded queries :(

I'll see if I can review your changes in more detail! If I see everything works I'll be happy to commit it into master.
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: Airbus Navigation Display

Postby onox » Sun Jan 25, 2015 6:26 am

Hooray, do you have a link to the exact precise code that creates that 2nd black Canvas Dialog in the 2nd screenshot?
onox
Retired
 
Posts: 431
Joined: Fri Jun 20, 2014 3:45 pm

Re: Airbus Navigation Display

Postby Hooray » Sun Jan 25, 2015 6:41 am

onox wrote in Sun Jan 25, 2015 6:26 am:Hooray, do you have a link to the exact precise code that creates that 2nd black Canvas Dialog in the 2nd screenshot?


do you just mean/need the Canvas dialog, then refer to the "Canvas Snippets" article
If you mean the Canvas dialog + the ND shown there, it's a conventional ND with a GUI placement
To see how this is set up, refer to the top of MapStructure.nas which sets up a test map and opens the whole thing in a GUI dialog.
If you want to have a full ND, you'll need to do the same thing with the ND setup code (as per the wiki instructions).
If you just need a separate window for an existing ND, it's just another placement - if you want a standalone ND, agnostic to the type of aircraft used, you need to set up the ND first and then attach it to the Canvas GUI dialog. The code doing this sort of thing is part of the MapStructure framework and also shown on the wiki (not sure if that's back already or not ...)
However, what I did have to do back then for the standalone ND was setting its properties up using the property browser - these days, you would probably want to procedurally create a handful of ND buttons and add those to the top of the Canvas showing the ND, analogous to the "Canvas/MapStructure Debugger" shown above (PUI)

BTW: IF you are specifically referring to the standalone Canvas ND using AI traffic as the data "source", I actually posted the corresponding snippet of code, too: viewtopic.php?p=193660#p193825

Most of this should still be applicable, but may need to be reviewed/updated to match ND/MapStructure changes that were implemented in the meantime.
But the general idea is still the same, even though some symbols/names may have changed - but nothing too difficult to update by looking at an arbitrary ND.nas file (e.g. 777/747) and fixing up properties/APIs.

As you can see, the MapStructure/ND APIs are sufficiently encapsulated to allow arbitrary traffic to be used as position/data source, including AI traffic - but also MP traffic.
Someone with your Nasal understanding should be able to adapt the corresponding code pretty quickly.
Philosopher wrote in Sun Jan 25, 2015 3:36 am:If only we could run them as threaded queries :(


So far, it seems that the navDB overhead is comparatively small - according to tikibar's recent findings, we're seeing rendering/rasterization taking some time, i.e. on the Canvas side (especially related to projection handling, which Gijs is hoping to address eventually) - and a while ago, Zakalawe said that supporting concurrent navdb queries would be problematic probably, and I guess he's in the best position if/how his code could be adapted. Overall, the navdb should be "read-only" at run-time, so should be conceptually straightforward to query concurrently - but I guess there are some hard-coded restrictions involved (e.g. static variables and so on) that might make this a little tricky. In addition, the navcache isn't implemented as a conventional SGSubsystem for the time being - this could prove to be both challenging and useful, simply because the navDB is merely an API and not a proper subsystem that is actually updated.

In essence, the whole notion of having a single-threaded "singleton" navdb kinda violates the whole concept of having a "database" in the first place - I mean, if this were a conventional mySQL database, it could obviously be accessed from hundreds of clients (processes/threads) concurrently - and I don't see any hard design restrictions why the underlying FG DB shouldn't also be safely accessed from multiple "clients".

In fact, in a multi-instance FlightGear setup (think multiplayer/multi-machine setup), having a common (or synchronized) navDB would be an important factor, e.g. imagine navaid info varying (frequencies, identifiers etc)
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: Airbus Navigation Display

Postby Hooray » Mon Jan 26, 2015 3:06 am

@artix, concerning your latest commit just a few comments:

  • the translation_callback approach looks much better to me than the original code, I think this is also addressing a few concerns regarding hard-coded assumptions that we inherited from Gijs' original code, but that may now be obsolete (i.e. canvas/texture size no longer having to match Gijs' original ND)
  • equally, I would suggest to move away from having stuff like setTranslation() with hard-coded assumptions (512/512 in this case) for the same reasons - I guess, it would be better to look up the original texture dimensions and add/subtract as needed, which would also allow us to use the code elswhere, including NDs with different resolutions - and we could also show multiple NDs in a single Canvas without having to fix up absolute coordinates manually
  • for now, I believe it is better to also adopt the original code to use your translation_callback method instead of the existing solution which keeps bloating up navdisplay.mfd unnecessarily
  • I don't think, you literally need to return an x/y tuple here - by passing the nd instance, you should be able to directly access nd.map.setTranslation() there ?
  • for newly introduced properties/attributes, I would suggest to retain the convention of having a telling suffix, e.g. dist-nm, crs-deg, lat-deg, long-deg to keep the code more self-explanatory, especially in the long-term, this will help future contributors getting started with our code.

Overall, I really keep being impressed by your commits - and I am pretty sure that even Philosopher (as the original MapStructure designer and developer) will be very impressed with your way of adopting and extending the framework (e.g. referring to HOLD.lcontroller). I really suggest that fellow MapStructure/ND contributors like Gijs, Hyde or omega95 look at your commits or get in touch with artix if Philosopher or myself should not be around, because artix seems to be able to quickly apply MapStructure concepts even to areas of the code that still contain much of the original code.
It is a bit unfortunate that the wiki is currently still n/a, but you have already addressed a few long-standing items on our roadmap, so thanks for your work, it's really appreciated !
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: Airbus Navigation Display

Postby artix » Mon Jan 26, 2015 3:29 am

@Hooray:

Thank you for your comments, the 512x512 size issue is an interesting point, i will look for a workaround.
I'm almost done with integrating Omega95's WXR_Live layer (the layer will be usable by Boeing/Airbus styles as well by canvas dialog too).
Tomorrow i will submit the commit and some screenshot.
artix
 
Posts: 93
Joined: Wed Jun 25, 2014 9:42 pm
OS: Mac OS X

Re: Airbus Navigation Display

Postby Hooray » Mon Jan 26, 2015 3:57 am

No "workaround" needed, you can just use canvas.getSize() (IIRC) which should give you the x/y dimensions - for now, I don't think that we support dynamically resizing a canvas, so you could save those in the ctor. However, there are some use-cases where the MapStructure map (and, thus, the ND) may only be allowed to use a portion of the whole canvas, so it does make sense to pass the map/ND coordinates to the constructor of the ND/map respectively. One such use-case would be the GPSMap196/GNS530 code, but also the Avidyne Entegra R9: all of those use a Canvas internally, but only a certain (clipped) area of the whole canvas would be available for mapping/charting purposes (i.e. the map/ND) - so it makes sense to encapsulate such things and move away from hard-coded dimensions, but also away form the hard-coded assumption that the whole Canvas will be available, or that the middle of the map is canvas.x/2 vs. canvas.y/2 - those are basically "design leftovers" from the original code, which would break once someone uses a differently-sized Canvas (think 256x256 or 768x768) - so this isn't unlike supporting multiple instances per aircraft or supporting multiple independent aircraft. if these 3 use-cases can be supported (independent instances, aircraft agnostic (i.e. styling), but also agnostic to the dimensions of the map/nd), the framework will be kept sufficiently generic.

Concerning your WXR work, that sounds good to me - I'd just suggest to send a heads-up to omega95 once this work is completed, so that he's aware of your effort.
Equally, should you consider porting his VSD work to MapStructure, we've had a few related discussions and suggestions on doing this "correctly".
Technically, I believe it is the correct approach to introduce the concept of "projections" (vertical & horizontal) - all existing MapStructure layers would be horizontal layers, while the VSD would be a vertical layer.
I don't think it should be too difficult to adapt MapStructure.nas accordingly, we would basically need to move some more things into the lcontroller files - but that would then allow us to also reuse VSD logic elsewhere, including other dialogs - e.g. for plotting flight profiles (think approach altitudes plotted against AGL altitudes).

If you should consider looking at this, I'd suggest to focus on porting just the existing Boeing VSD - because the real Airbus VSD (e.g. on the A350) is even a little more sophisticated than that:
http://www.flightglobal.com/news/articl ... gh-205721/
On the expanded navigation display (ND), there is the ability to get “a better understanding of the third dimension” with a vertical -situation display, says Roy. “Not only does it show what we are going to do in altitude versus distance with the different waypoints, but also with obstacle data coming from the EGPWS [enhanced ground proximity warning system] and also more information coming from the flight management system, improving situational awareness and enhancing safety,” he says.
Image


Also see: http://dspace.mit.edu/bitstream/handle/ ... sequence=1 (pages 41+ )
and: http://flightsafety.org/asw/oct07/preci ... b.pdf?dl=1 (page 12+)
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: Airbus Navigation Display

Postby artix » Mon Jan 26, 2015 9:38 am

I'm almost done with WXR_Live, but i'm having some trouble with the z-index: despite being set at -100 (both the element and the image), it's always displayed on top of all the other layers/symbol. I's' not the first time i have problems with the z-index. Do you know why?
artix
 
Posts: 93
Joined: Wed Jun 25, 2014 9:42 pm
OS: Mac OS X

Re: Airbus Navigation Display

Postby Hooray » Mon Jan 26, 2015 6:37 pm

I'd suggest to look at the whole group to inspect the other z-index attributes using the property browser - alternatively, dump the group/property tree to an XML file for inspection purposes via io.write_properties()

I think we do have some basic logic in place that will increment the z-index in a +=1 fashion via addLayer() unless you explicitly override that.
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: Airbus Navigation Display

Postby artix » Mon Jan 26, 2015 8:52 pm

I've successfully implemented Omega95's WXR_live layers into FGDATA Canvas, here's a screenshot:

Image

You can find it in the topic/airbus_nd branch. The layer is supported by both Boeing and Airbus ND styles.

Just a few notes:

- In order to move the WXR layer under the compass and mask (clip) it, i had to set z-index -1 to the whole 'map' element because i did't manage to move just the WXR layer. Anyway, it seems to me that it does make sense to have the "map" element below the compass/mask, because usually the map layers (route, navaids, ...) should be "clipped" inside the compass "area" (at least Airbus ND clips the map, i don't know if Boeing does it too).
However i guess that it's always better to make this setting configurable, because at the moment i just put it into navdisplay.mfd code, that it's already too messy and Boeing-centered.

- Maybe the most important issue with WXR_live: Omega95's WXR Live (and so the corresponding layers that i've implemented into MapStructure) fetch the weather map from a free API service called Wunderground (I suppose that you already know this). At the moment i have taken the wxr_api.xml file from the 'WXR_live' branch that was created by Omega95. That file contains an API Key but i don't know if belongs to Omega95 or to FlightGear.
The point is that Wunderground (using the 'free' plan) has a limit of 200 max. requests per-day. We cannot provide a unique API Key to all FG users, it's not feasible.
So i guess that every user who wants to use the WXR Live feature should create its own API Key on Wunderground and possibly store it inside FlightGear (maybe using an appropriate Dialog for this).
What do you think about it?
artix
 
Posts: 93
Joined: Wed Jun 25, 2014 9:42 pm
OS: Mac OS X

Re: Airbus Navigation Display

Postby Hooray » Mon Jan 26, 2015 8:53 pm

(I sent this via PM):

are you sure that you fully understand how this works ?
-100 will only be applied to all elements at the same level, so does not have affect for elements above/below the same level, consider:

image1 (-100)
image2( -99)
image3 (-98)

here, image1 would be the lowest, but now consider:

group1 (-100)
...image1(-100)
...image2(-200)
group2( -99)
...image1(-100)
group3 (-98)

image2 will be the lowest level in the group1 hierarchy, but it will still "inherit" the -100 hierarchy from the upper group - which acts kinda like a "layer" here.

Thus, z-indexing is there to organize groups/elements at the same hierarchy - but outside that hierarchy, the external z-index applies: http://wiki.flightgear.org/Canvas_Element#z-index
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: Airbus Navigation Display

Postby Hooray » Mon Jan 26, 2015 8:56 pm

Yes, regarding the API key, I would add a new "Configuration" dialog where canvas related settings can be configured - e.g. the API key in this case.
Storage can then be implemented using the userarchive attribute (no need to maintain a separate XML file IMO).
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: Airbus Navigation Display

Postby Hooray » Mon Jan 26, 2015 10:08 pm

Regarding your WXR_live commits: the screen shot is looking really good, I'd just make sure to keep a few things in mind - Canvas/MapStructure is not about a single instrument or about a single aircraft. Thus, it is really important that all Canvas/MapStructure additions support multiple independent instances running at the same time. This is the only reason why Gijs' original code has meanwhile seen contributions from 12+ different contributors, many of whom never took any interest in the original 744-based version. So by ensuring loose coupling, you also ensure that your work will be maintained by others, who may not even be particularly interested in any particular aircraft and/or instrument.

In other words:
  • it is good that the WXR_live layer is supported by both ND styles, but it should also be supported by the map-canvas.xml dialog
  • equally, the code should support independent positions - imagine using this with AI traffic (a use-case onox is apparently interested in)
  • inheritim from DotSym may not necessarily be the best option here - I'd suggest to extend MapStructure.nas and an "Overlay" class there (possbily wrapping just DotSym for now)
  • alternatively, we already have some helpers for dealing with raster images
  • URL building should probably be encapsulated, too - so that people can explore using alternate web APIs - for instance, TheTom added a URL building scheme which could/should be used here instead of omega95's code (see the original thread for additional pointers)
  • in the same thread, Philosopher suggested to favor systime() over getprop(elapsed-time)
  • I think it's a good thing that you used the resolution/fetch-radius properties there - there should be no hard-coded constants involved, or people would need to patch the layer in order to support different resolutions
  • in fact, such things (radius/resolution) could -at some point- also be exposed via some kind of canvas configuration dialog where Canvas avionics (think ND, PFD, EFB) could be set up (e.g. for API keys etc)
  • the callback passed to always() contains hard-coded properties (not relative to wxr_tree), so that this would break concurrent usage with different positions/configuration profiles (e.g. radius/resolution being different between 2 NDs and/or the map-canvas.xml dialog)

coming up with a simple configuration dialog should be easy - you can borrow snippets here: http://wiki.flightgear.org/Canvas_Snippets

If you don't intend to work on this anytime soon, I'd suggest to add a few comments to the code.
But basically, MapStructure layers are only ever sufficiently complete and generic once these criteria apply:

  • support different aircraft and GUI use-cases
  • support different independent instances
  • support styling

Ideally, any MapStructure layer would also support multiple instances per Canvas - imagine showing 3 different NDs (256x256,512x512,128x128) on a single Canvas texture (1024x1024) - that will help identify any remaining design issue (e.g. due to hard-coded constants).
This is one of the reasons why I previously suggested to generalize the MapStructure/ND stuff a little more so that it can be used as a Canvas widget - this will make any remaining issues very obvious.

Like I mentioned previously, your airbus work looks really good to me, but it seems that it's not using caching at all ?
Caching is important for heavy layers with many symbols (think FIX/WPT)

Overall, I'd suggest that you consider teaming up with tikibar and onox: all 3 of you have demonstrated an exceptional understanding of the concepts involved here, while being interested in very different use-cases, so the API should evolve "naturally" once you sit together and work out a way not to step on your toes :mrgreen:
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

PreviousNext

Return to Canvas

Who is online

Users browsing this forum: No registered users and 4 guests