Graphic loop and App.DoEvents

Yes, I know that I have to avoid App.DoEvents in GUI applications.
But I don’t know how to avoid it in this situation:

  1. I have an application that shows the deformation of a structure.
  2. There is a button with caption “Animation”. When you press it, its caption changes to “stop” and starts animation.
  3. Animation consists in a loop drawing the deformation with a factor 0 to 1 step 0.1 up and down indefinitely until you press “stop”.
  4. This loop can not be in a thread because it manipulates the UI.
  5. If I don’t use App.DoEvents I can not capture the Action event of the button

Any suggestion?
Thanks in advance.

Use a Timer ?

When you say 4), there is a Xojo example named “DrawingWithThreads”, perhaps it could help ?

Cheers,
Guy.

Thanks Guy.
I’ll have a look at the example.

I assume you are updating a CANVAS somehow?
Are you using INVALIDATE or REFRESH (or either?) to update the display?

Invalidate tells the Canvas to refresh when there is some “free” time
Refresh says “do it now”… in 99% of the cases Invalidate is the proper choice, but Refresh has its place.

You could also create a Timer that you run during the animation that calls theCanvas.Invalidate. Set the Timer Period to 50ms or so and the set the mode to 2 when you start the animation and 0 when the animation completes.

The problem with App.DoEvents in this situation is that your refresh may take longer than a single run loop and you could then end up in a recursive App.DoEvents looped mess.

Place your drawing code into a thread. Instruct the code to draw to a picture instead of directly to the Canvas. Have a Timer in the window that fires every .5 second that fetches the picture and draws it to the Canvas. That will allow the UI to remain responsive.

Unfortunately, I won’t be able to help much with implementation details during the conference this week, but my Animation Kit will handle this for you nicely: http://thezaz.com/code/animationkit/

Basically, your thread will prepare an array of pictures to use for the frames of the animation. When the thread is complete, those pictures can be piped into an AKFrameTask, set not to loop, and shown in the canvas over a specified duration.

You’ll need to use a timer to watch for the thread to complete before you start the animation, but that is true of nearly all UI which relies on a thread.

I thank you all for your help and suggestions.
Perhaps I forgot to say something that may be it’s very important: my animation is through OpenGL, so I don’t have any picture not any canvas but and OpenGLSurface. Instead I have a loop of Render.

Anyway all your suggestions with Timers may help me to do it without Doevents, although I must admit that it works perfectly well until now.

Ramon,

If it works well, why would you choose another path ? :slight_smile:

Regarding threads, OpenGL support very well threaded updates, the only thing to be aware is that each thread has its own OpenGL context so you have to make sure your context is set (MakeCurrent) in the thread you are drawing.

Aside from that, you should be perfectly safe to do all your OpenGL drawings in a thread.

Cheers,
Guy.