TemplateCanvas cannot access template objects immediately

Greetings,

if one adds a template to a TemplateCanvas object via script by appending to the dataset one cannot access the newly created template in the same script.

Let say this code executes on a button action on a page containing a TemplateCanvas object “Canvas”, with a blank template dataset containing columns= [ name, template, x,y,width,height,z] eg default

Then appending a template is easy enough

canvas=event.source.parent.getComponent('Canvas')
cd=canvas.templates
cd=system.dataset.addRow(cd,["Template1","sometemplate", 0,0,100,100,0])
canvas.template=cd
templates=canvas.getAllTemplates()

The problem here is that templates returns an empty list instead of an instance of sometemplate

So thinking maybe template is created async on another thread and takes time to turn up

Append this to above code:

#really ugly code that should not really go into UI thread since it is blocking code
abortcount=0 #use to stop execution crashing UI
ncount=cd.rowCount-1 #have already added a row hence decrement
import time,sys 
while len(canvas.getAllTemplates())==ncount and abortcount<100:
   time.sleep(0.1)
   abortcount+=1
it abortcount>=100:
   sys.exit()

Now it times out.

After action completes template is visible and available.

So it seems the object only becomes available once script finishes execution.

Is this behaviour expected?

Is the only solution to fire of thread and do it async?

[quote=“gekkoman”]Is the only solution to fire of thread and do it async?[/quote]No and yes. You can do it in the foreground, but you have to allow the propertyChange events you’ve triggered to run. Use system.util.invokeLater() with a zero delay. That’ll put your follow-up code at the end of the event queue.

Yes - hence the async comment. This works.

I have nested TemplateCanvas, and it gets real messy doing it this way…I ended up having to nest 4 invokeLaters for it to work, which was pretty nasty.

Found a better workflow by using intializeTemplate function within the child TemplateCanvas to size things properly and feeding it template reference from the Parent Template Canvas, so I can add it with the info I need.

I have created a dashboard project (see image) which allows me to add templates dynamically at runtime. The nesting occurs because I wrap the templates with the window decorations (titlebar, close buttons etc)

Have got it to the point where adding, dragging and deleting templates all work. The windows (wrapped templates) are freely draggable anywhere on the canvas.

The problem was not knowing the size of the template one is adding at runtime. I had major hassles not using the layout manager on the Template Canvas as it did strange scaling all the time. I ressorted to using absolute positioning with the layout manager and this works a treat.

[attachment=0]dashboard.png[/attachment]

Hello gekkoman,

I am attempting to do something similar in my own project and was hoping you could share some information with me on how you enabled the dragging around of templates in your canvas? I would be extremely grateful for any help you could offer.

Hi denji26,

Take a look at this blog post: nickmudge.info/post/drag-and-dro … ate-canvas

It provides a project that shows how to drag templates around on a template canvas.

Best,

Hi gekkoman
I did this same as you propose
Except that getAllTemplates() duly returned me a list of templates which can be iterated to find the required template, in this case “Template1”.

I see this post is a few years ago, so if you are still seeking a solution please let me know

Regards,
Ross