GNOME Bugzilla – Bug 116331
no way to stop/start a GdkPixbufAnimation.
Last modified: 2010-07-10 04:05:32 UTC
In my application, I am tring to start and stop the animation when events occur, similar to the way mozilla and most browsers animate when they are looking up a page. I tried various things approaches and was able to stop the animation at a particular frame (using the GdkPixbufAnimationIter's) but could not find a way of starting (or continuing) the animation from the same frame it stoped at. It would be much better if there were functions as below: gdk_pixbuf_animation_start(guint frame_number); gdk_pixbuf_animation_stop(); gdk_pixbuf_animation_iter_get_frame_number(GdkPixbufAnimationIter *iter); This way a user could find out what frame they are on at any given time, and when events start again, they could start the animation from which ever frame they left of from.
Just another thought, but perhaps there could be a function which provids information about when the animation was at the end of its cycle? That way when events stop in an application, the user can request a callback for the end of the animation, and when it is called they can stop it themselves.
I don't think there's anything to add to the animation api here. Animations are not started or stopped, they are just there. You use an iter to actually play them. I think what you have to do to pause and continue an animation is to record the current time when you pause the animation, and advance relative to that time when you continue. Something like (untested pseudo code) toggle_paused() { if (paused) { pause_time += current_time - pause_start; paused = false; } else { pause_start = current_time; paused = true; } } advance_iter () { iter_advance (current_time - pause_time); } Regarding a way to find the end of a cycling animation, there's currently some discussion about that on gtk-devel-list@gnome.org.
After considering this approach some more, there are limitations to the current way it works. If I use GTimeVal's to represent t0 (start time) t1 (pause or stop time) and t2 is the interval between t0 and t1. If I want to calculate the interval (t2) I would use g_get_current_time () and then add to the GTimeVal the number of microseconds using g_time_val_add (). The value in microseconds can be a maximum of just over an hour ~71 minutes (given the value of 2^32 for a an unsigned integer). This means that if the animation is running for more than an hour then there are problems. If, on the other hand there was a function to get the current frame and to get the iter for a particular frame, then all my problems would be solved. Another solution would be to know when the end of the cycle occurs so the animation can be reset periodically and the interval would always be within the maximum.
Hmm, but GTimeVal has 32 bits for microseconds + 32 bits for seconds. If we agree that an hour has approximately 2^12 seconds, you should be able to get by for 2^20 or roughly 1.000.000 hours. I don't think any animation should last longer...
I don't think there is anything to fix here. It's admittedly a little tricky to to do the computations to create a "virtual" time from the real time that the animation has been on, but I can't imagine what we would change to make it easier... maybe some more GTimeVal arithmetic convenience functions in GLib.
The 32 bits for the seconds are fine, it is the 32 bits for the micro seconds I am concerned with. When I use g_time_val_add() I have to specify a value in micro seconds. This means that I can only add a maximum of 2^32 micro seconds (~71 minutes) at a time. As I understand it this means that if the animation was playing for 4 hours constantly and then an event proceeded to pause the frame, that interval from start to pause would be 4 x the maximum size for a long int. I have resorted to being accurate to the nearest second. Perhaps there is nothing to fix here, but yes, more convenience functions would be greatly welcomed in this area. If I new how many frames there were to an animation, that would make life a lot easier!
What you're probably missing is a way to add two timevals ? You could certainly remember the paused/elapsed time as a timeval.
Yes, I was just about to suggest that. Really g_time_val_add () should be g_time_val_add_in_milliseconds () and g_time_val_add () should accept a GTimeVal structure instead. Then all would be peachy! :)