/** * return number of frames per second and duration in msec */ gint pgpug_pixbuf_animation_get_detail (GdkPixbufAnimation *anim, gint *frames_count, gint *duration) { //FIXME: there should be a better way to get frames count from animation *frames_count = 0; *duration = 0; if (gdk_pixbuf_animation_is_static_image (anim)){ (*frames_count)++; return; } GTimeVal start_time = {0, 0}; GdkPixbufAnimationIter *iter = gdk_pixbuf_animation_get_iter (anim, &start_time); GdkPixbuf *cur_frame, *first_frame = gdk_pixbuf_animation_iter_get_pixbuf (iter); int delay_time = gdk_pixbuf_animation_iter_get_delay_time (iter); while (delay_time > 0){ g_time_val_add (&start_time, delay_time*1000); gboolean need_upd = gdk_pixbuf_animation_iter_advance (iter, &start_time); if (need_upd){ (*frames_count)++; *duration += delay_time; } cur_frame = gdk_pixbuf_animation_iter_get_pixbuf (iter); if (!need_upd || cur_frame == first_frame) { delay_time = -1; } } g_object_unref (iter); }
/* Auxiliary function - look for frame that's currently loading. */ static void update_currently_loaded_frame (FrameData* frame) { int tmp_count; if (gdk_pixbuf_animation_iter_on_currently_loading_frame(frame->iter)) return; /* frame is currently being loaded */ /* clear old content of pixbuf */ if (frame->pixbuf) g_object_unref (frame->pixbuf); frame->pixbuf = NULL; tmp_count = 0; do { int delay_time; if (++tmp_count > MAX_NUMBER_FRAMES) { /* protection against frames repeating */ return; } delay_time = gdk_pixbuf_animation_iter_get_delay_time (frame->iter); if (delay_time < 0) { /* this is last frame in the animation */ return; } g_time_val_add (&frame->time, delay_time * 1000); gdk_pixbuf_animation_iter_advance (frame->iter, &frame->time); } while (!gdk_pixbuf_animation_iter_on_currently_loading_frame (frame->iter)); /* store current content of the frame */ frame->pixbuf = gdk_pixbuf_copy (gdk_pixbuf_animation_iter_get_pixbuf (frame->iter)); }
static VALUE rg_advance(int argc, VALUE *argv, VALUE self) { VALUE current_time_sec, current_time_usec; GTimeVal current_time; rb_scan_args(argc, argv, "02", ¤t_time_sec, ¤t_time_usec); if (NIL_P(current_time_sec)) return CBOOL2RVAL(gdk_pixbuf_animation_iter_advance(RVAL2ITR(self), NULL)); current_time.tv_sec = NUM2LONG(current_time_sec); current_time.tv_usec = NIL_P(current_time_usec) ? 0 : NUM2LONG(current_time_usec); return CBOOL2RVAL(gdk_pixbuf_animation_iter_advance(RVAL2ITR(self), ¤t_time)); }
static gboolean ygtk_image_advance_frame_cb (gpointer data) { YGtkImage *image = (YGtkImage *) data; struct _YGtkImageAnimation *animation = image->animation; if (!animation->frame) // no frame yet loaded animation->frame = gdk_pixbuf_animation_get_iter (animation->pixbuf, NULL); else if (gdk_pixbuf_animation_iter_advance (animation->frame, NULL)) gtk_widget_queue_draw (GTK_WIDGET (image)); // shedule next frame int delay = gdk_pixbuf_animation_iter_get_delay_time (animation->frame); if (delay != -1) animation->timeout_id = g_timeout_add (delay, ygtk_image_advance_frame_cb, data); return FALSE; }
void wxAnimationCtrl::OnTimer(wxTimerEvent &ev) { wxASSERT(m_iter != NULL); // gdk_pixbuf_animation_iter_advance() will automatically restart // the animation, if necessary and we have no way to know !! if (gdk_pixbuf_animation_iter_advance(m_iter, NULL)) { // start a new one-shot timer int n = gdk_pixbuf_animation_iter_get_delay_time(m_iter); if (n >= 0) m_timer.Start(n, true); gtk_image_set_from_pixbuf(GTK_IMAGE(m_widget), gdk_pixbuf_animation_iter_get_pixbuf(m_iter)); } else { // no need to update the m_widget yet m_timer.Start(10, true); } }
/* **************************************************************************** * Local Declarations * ************************************************************************* */ static gboolean cb_timeout( GdkPixbufAnimationIter *iter ) { gint delay; gboolean flag; flag = gdk_pixbuf_animation_iter_advance( iter, NULL ); if( flag ) { /* FIXME: This code will work, but is ugly as hell when it comes to * non-ombo box cell views */ GtkWidget *widget; widget = g_object_get_data( G_OBJECT( iter ), "widget" ); if( ! GTK_WIDGET_VISIBLE( widget ) ) return( FALSE ); gtk_widget_queue_draw( widget ); } delay = gdk_pixbuf_animation_iter_get_delay_time( iter ); gdk_threads_add_timeout( delay, (GSourceFunc)cb_timeout, iter ); return( FALSE ); }
static GdkPixbufAnimation* compose_animation_from_array (animation_param_entry **anim_array, gint array_len, gint pix_size) { GdkPixbufSimpleAnim *result = NULL; gint frames = 1, duration = 0, duration_p, frames_p; /* calculate frames count as multiplication of all frames and duration as max */ gint i; GTimeVal start_time = {0, 0}; for (i = 0; i<array_len; i++){ /* initialize iterators for each animation*/ animation_param_entry *p_entry = anim_array[i]; p_entry->iter = gdk_pixbuf_animation_get_iter (p_entry->anim, &start_time); frames_p = duration_p = 0; pgpug_pixbuf_animation_get_detail (p_entry->anim, &frames_p, &duration_p); duration = duration < duration_p ? duration_p : duration; frames *= frames_p; } float fps = duration > 0 ? frames * 1000 / duration : 1; gint frame_change_time = duration / frames; DEBG_MSG ("Fps: %f. frame change time :%dmsec", fps,frame_change_time); result = gdk_pixbuf_simple_anim_new (pix_size, pix_size, fps); gint elapsed_time = 0, frames_counter = 1; while (elapsed_time <= duration && frames_counter++ <= frames){ animation_param_entry *p_entry = anim_array[0]; GdkPixbuf *base_pixbuf = gdk_pixbuf_copy (gdk_pixbuf_animation_iter_get_pixbuf (p_entry->iter)); g_time_val_add (&start_time, frame_change_time * 1000); gdk_pixbuf_animation_iter_advance (p_entry->iter, &start_time); for (i = 1; i < array_len; i++) { p_entry = anim_array[i]; GdkPixbuf *src_pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (p_entry->iter); gint x_offset, y_offset, src_size; src_size = gdk_pixbuf_get_width (src_pixbuf); pgpug_pixbuf_calculate_composition_offset (pix_size, src_size, p_entry->pos, &x_offset, &y_offset); gdk_pixbuf_composite (src_pixbuf, base_pixbuf, x_offset, y_offset, src_size, src_size, x_offset, y_offset, 1.0f, 1.0f, GDK_INTERP_BILINEAR, 255); gboolean res; res = gdk_pixbuf_animation_iter_advance (p_entry->iter, &start_time); } gdk_pixbuf_simple_anim_add_frame (result, base_pixbuf); elapsed_time += frame_change_time; } gdk_pixbuf_simple_anim_set_loop (result, TRUE); for (i=0;i<array_len;i++){ g_object_unref (anim_array[i]->iter); } return GDK_PIXBUF_ANIMATION (result); }