Secret of the WebCanvas

What is the secret of the WebCanvas? I have 7 visible canvases acting as buttons (they are of the same subclass)… 6 buttons are 27x25 and one is 17x 15. They don’t draw unless I click on them (how is the end user going to know where to click to get them to display?). I even added a WebButton I could click on that forces a refresh on each “button” to try to get them to redraw. I’ve already put all of the initialization in a WebTimer to avoid the black box of death. It shouldn’t be this hard.

Update: If I resize the web browser window enough, 5 of the 7 buttons do draw.

WebCanvases are extremely strange beasts. I ended up devising a new control based on ImageWell in RubberViewsWE because WebCanvases became invisible when moved or resized.

I would try to replace those webCanvases by imageviews if you need pictures, or by styled labels.

[quote=284499:@Christian Miller]What is the secret of the WebCanvas? I have 7 visible canvases acting as buttons (they are of the same subclass)… 6 buttons are 27x25 and one is 17x 15. They don’t draw unless I click on them (how is the end user going to know where to click to get them to display?). I even added a WebButton I could click on that forces a refresh on each “button” to try to get them to redraw. I’ve already put all of the initialization in a WebTimer to avoid the black box of death. It shouldn’t be this hard.

Update: If I resize the web browser window enough, 5 of the 7 buttons do draw.[/quote]
I’d be curious to see a sample of your subclass to see if there’s a bug that needs fixing, but to be honest using them for drawing buttons is not what I usually see them used for. The round trip latency is just too great for any sort of responsive interaction.

Something to keep in mind… WebCanvas uses a diff algorithm so that it only sends the minimal number of instructions down to the browser each time. For instance, if in your paint event, the only thing that differed between the up and down states was the background color change, that one instruction is sent to the browser and is used to replace the corresponding instruction on he browser.

One of the caveats of using a diff engine like this is that the instructions must be transmitted and received in the same order. That means that if they get out of sequence, the framework must send a completely fresh drawing down to the browser, so there may be occasional speed differences.

That said, this mechanism can get fooled into sending more data or taking significantly more CPU time if the paint event changes drastically from one call to the next. You can turn off the diff engine for each of the canvas instances if necessary.

What I’m getting at here is that WebCanvas isn’t inherently good for highly interactive controls because Paint events don’t fire nor affect the canvas instantaneously as they do on the desktop. Unfortunately, because our desktop computers are so powerful relative to an average web server and latency is so low during debugging, it’s easy to forget that time between refreshes can be relatively high when deployed to the internet.

Well… we are both near Raleigh.

Turning off the diff engine fixed the buttons.

I also have 2 canvases acting as grids. Drawing a WebPicture instead of a Picture causes the grid to not draw when hosted on 64-bit Linux, and does draw locally, 32-bit OS X. Changing the diff engine here didn’t help. Any recommendations for creating a grid that needs edit fields, checkboxes, images?

All these are being converted from original Desktop classes. I’m trying to get these things working in a browser.

Be aware that a WebCanvas differs very sensibly from the Desktop Canvas. Xojo presents to you controls that on the surface look and act similarly, but their inner working is completely different.

Yeah, use the WebSDK for this. You’ll never get the performance you need for and edit field. The WebSDK lets you create client side controls which only send changes when they have to.

I think I have a feature request in there for being able to set a block of drawing code to go with the control to the browser on initial load. Otherwise there is no way to have it show up with content, it will show up blank and then draw in a bit later. I’d love to get a paint event BEFORE it’s sent to the browser so it can take it’s first load of commands with it for the initial show :wink:

This can be a quite pronounced delay if you’re communicating from a mobile device over an encrypted connection too. I’m also still getting the occasional javascript error on page loading if it’s the first time the page has loaded that contains them. I’ve got some timing thing where it’s trying to draw before it’s all setup in the framework, none of the other controls do this and I’m not doing anything differently for the canvas. It’s frustrating enough that I actually moved my big canvas display control to a webSDK control and wrote the javascript drawing code directly in javascript. That has worked very well and may be the only solution to some of the issues. Though you’re going to experience some of the horrible pain of trying to write cross platform javascript code if you do that :wink: It will make you appreciate even more all the work the xojo crew have done for us on this stuff :slight_smile:

If I can figure out what I’m doing goofy in the open and shown events that are throwing the error I’ll make a bug report but so far I can’t duplicate it except in the project :wink: But there are still some very odd things with the web canvas that may be bugs or may be just the limitations of the whole idea of the thing. One thing you can try if the drawing is not working properly is to disable the diff engine, it seems thats still supported to turn off. That will potentially dramatically increase the amount of data sent back and forth but it did help me to debug some earlier problems I was having with it. I don’t see the property in the language reference, but it’s webCanvas.DisableDiffEngine = true I was executing that in the Open event when I needed to experiment with it.

You really should get a paint event as soon as the canvas is in the window though, can you put some logging or something in the paint events so you can see for sure that it’s firing when the page loads and it’s not some other problem in there that is keeping the drawing from getting done?

[quote=284787:@James Sentman]I think I have a feature request in there for being able to set a block of drawing code to go with the control to the browser on initial load. Otherwise there is no way to have it show up with content, it will show up blank and then draw in a bit later. I’d love to get a paint event BEFORE it’s sent to the browser so it can take it’s first load of commands with it for the initial show :wink:

[/quote]

This is actually a problem with every WebControl. It’s why everything gets put in the SHOWN event rather than the OPEN event. For example if you do ExecuteJavascript in the OPEN event it throws exceptions cause the control hasn’t rendered yet.

The “ExecuteJavascript()” method on the control should be smart enough to know that the control hasn’t been rendered yet and then queue it to the end of when the control is rendered, and likewise with a WebCanvas’ initial paint. This sort of logic would allow the WebCanvas and all controls to not have a delay between getting sent to the browser and then having to call back for their shown() event causing a delay.

It’s more of a problem with dynamically generated controls. With a static control the control already knows what text it’s displaying and such and they just go to the browser and show up with the proper settings and text and such. For dynamically generated controls I think the official word is that I must wait till the shown event to touch them, but this looks horrible. The control shows up without any text or anything and then the data pops in later.

Though you’re not supposed to do it, you can actually set MOST of the properties of a control that you’ve created dynamically in it’s open event, or immediately after new’ing the container. This way the new settings are sent to the browser along with the control. Some things do not work that way, sizing and such are just wrong until it’s bene shown, but you can set the text of a webLabel for instance without any difficulty.

That might change since it’s not officially supported and all my testing that it works may still result in nothing but javascript errors for you :wink: But with much fiddling around it does work for me.

For dynamically generated controls especially we really need an official way to setup the container control before it’s first sent to the browser. Doing the same for a canvas would be terrific too.

Well on a WebControlWrapper object you do have access to ControlAvailableInBrowser and can prevent your ExecuteJavascript from running if the control is not.

and once you’re done testing your javascript you may wish to wrap the calls in a

try{ … }catch(err){}

block in javascript anyway, as strange things still happen. That will let it fail gracefully and just do nothing instead of bringing up the javascript error dialog if things aren’t ready when it arrives there. Again maybe it’s only me, but I’ve had to do that to keep random strangeness from popping up periodically with the javascript error console even with checking the ControlAvailableInBrowser first.

You could also easily trap the error instead if ignoring it and send a message back to the app via the webControlWrapper messaging feature so that you could log what happened where and in what it happened.

Off to WebSDK land I guess…