/* 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)); }
/** * 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); }
static void img_cell_renderer_anim_render( GtkCellRenderer *cell, GdkDrawable *window, GtkWidget *widget, GdkRectangle *background_a, GdkRectangle *cell_a, GdkRectangle *expose_a, GtkCellRendererState state ) { ImgCellRendererAnimPrivate *priv; GdkPixbufAnimationIter *iter; GdkPixbuf *pixbuf; cairo_t *cr; GdkRectangle rect, draw_rect; priv = IMG_CELL_RENDERER_ANIM_GET_PRIVATE ( cell ); /* Get image size */ img_cell_renderer_anim_get_size( cell, widget, cell_a, &rect.x, &rect.y, &rect.width, &rect.height ); rect.x += cell_a->x + cell->xpad; rect.y += cell_a->y + cell->ypad; rect.width -= 2 * cell->xpad; rect.height -= 2 * cell->ypad; /* Check for overlaping */ if( ! gdk_rectangle_intersect( cell_a, &rect, &draw_rect ) || ! gdk_rectangle_intersect( expose_a, &draw_rect, &draw_rect ) ) return; /* Draw indicators */ cr = gdk_cairo_create( window ); /* Draw the current frame of the GdkPixbufAnimation */ iter = g_object_get_data( G_OBJECT( priv->anim ), "iter" ); if( ! iter ) { gint delay; /* Initialiize iter */ iter = gdk_pixbuf_animation_get_iter( priv->anim, NULL ); g_object_set_data_full( G_OBJECT( priv->anim ), "iter", iter, (GDestroyNotify)g_object_unref ); /* Install timeout */ delay = gdk_pixbuf_animation_iter_get_delay_time( iter ); gdk_threads_add_timeout( delay, (GSourceFunc)cb_timeout, iter ); } g_object_set_data( G_OBJECT( iter ), "widget", widget ); pixbuf = gdk_pixbuf_animation_iter_get_pixbuf( iter ); gdk_cairo_set_source_pixbuf( cr, pixbuf, rect.x, rect.y ); gdk_cairo_rectangle( cr, &draw_rect ); cairo_fill( cr ); cairo_destroy( cr ); }
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; }
bool wxAnimationCtrl::Play() { if (m_anim == NULL) return false; // init the iterator and start a one-shot timer ResetIter(); m_iter = gdk_pixbuf_animation_get_iter (m_anim, NULL); m_bPlaying = true; // gdk_pixbuf_animation_iter_get_delay_time() may return -1 which means // that the timer should not start int n = gdk_pixbuf_animation_iter_get_delay_time(m_iter); if (n >= 0) m_timer.Start(n, true); return true; }
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 ); }
int main (int argc, char *argv[]) { if(argc > 1 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-H"))) { printf("Ponies for Linux/GTK+ by rabbit\n"); printf("Command list:\n"); printf("No Parameters: Run with the settings used from last run\n"); printf("-h: Display this help\n"); printf("file path: Set new file path to look for pony gif files\n"); printf("ponyname: Sets to run one of the pony type listed\n"); return 0; } for(int i = 1; i < argc; i++) if(*argv[i] == '/') setPonyDirectory(argv[i]); char* ponyDirectory = NULL; char* ponyHomeFile = NULL; ponyHomeFile = malloc((strlen(getenv("HOME"))+ 9) * sizeof(char)); if(!ponyHomeFile) { printf("Could not allocate memory for ponyHomeFile\n"); return 0; } strcpy(ponyHomeFile, getenv("HOME")); strcat(ponyHomeFile,"/.ponies"); ponyDirectory = getPonyDirectory(); if(!ponyDirectory) { free(ponyHomeFile); printf("Error locating pony directory\n"); return 0; } //Initialize GTK+ and set up loggers GError* error = NULL; g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL); gtk_init (&argc, &argv); g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL); //For command line commands later, require input on inital load //Normally would close, but hard coded in for easier testing int numberOfPonies = 0; if(argc == 1) { //Read in from ~/.ponies file to find saved settings FILE* ifp = NULL; char buffer[256]; ifp = fopen(ponyHomeFile,"r"); if(!ifp) { free(ponyHomeFile); free(ponyDirectory); printf("Could not open file for reading\n"); return 0; } //fread(buffer, sizeof(char), 256, ifp); while(fgets(buffer, 256, ifp)) if(buffer[0] != '\n') numberOfPonies++; fclose(ifp); numberOfPonies--;//First line is directory } //Not default arguments else { for(int i = 1; i < argc; i++) { if(*argv[i] == '/') continue; numberOfPonies++; } } //Seed the randomizer srand(time(0)); //Number of ponies pony ponyArray[numberOfPonies]; char buffer[256]; FILE* ifp = NULL; ifp = fopen(ponyHomeFile,"r"); if(!ifp) { printf("Could not open ~/.ponies\n"); free(ponyDirectory); free(ponyHomeFile); return 0; } fgets(buffer, 256, ifp);//throw away first line //0 Ponies if(!numberOfPonies) { free(ponyDirectory); free(ponyHomeFile); printf("No ponies in the ~/.ponies file! Add some ponies!\n"); printf("allowable ponies are: "); for(int i = 0; i <= Zecora; i++) printf("%s ", getDirectoryName(i)); return 0; } //Make pony windows for( int i = 0; i < numberOfPonies; i++) { fgets(buffer, 256, ifp); char* temp = NULL; temp = strchr(buffer, '\n'); if(temp) buffer[temp - buffer] = '\0'; ponyArray[i].name = ponyNameFromString(buffer); ponyArray[i].direction = DirNone; ponyArray[i].dragActive = 0; ponyArray[i].speed = SpeedStopped; ponyArray[i].animation = AnimIdle; ponyArray[i].active = 1; ponyArray[i].facing = FaceLeft; //Create animation from file, default is idle_left char* initialPicturePath; initialPicturePath = malloc((strlen(ponyDirectory) + strlen(getDirectoryName(ponyArray[i].name)) + 14) * sizeof(char)); if(!initialPicturePath) { printf("Unable to allocate memory for directory"); continue; } strcpy(initialPicturePath, ponyDirectory); strcat(initialPicturePath, getDirectoryName(ponyArray[i].name)); strcat(initialPicturePath, "/idle_left.gif"); ponyArray[i].pictureanim = gdk_pixbuf_animation_new_from_file (initialPicturePath, &error); free(initialPicturePath); ponyArray[i].image = gtk_image_new_from_animation(ponyArray[i].pictureanim); ponyArray[i].pictureanimit = gdk_pixbuf_animation_get_iter (ponyArray[i].pictureanim, NULL); ponyArray[i].win = gtk_window_new(GTK_WINDOW_TOPLEVEL); //Resize everytime the gif updates g_timeout_add(gdk_pixbuf_animation_iter_get_delay_time(ponyArray[i]. pictureanimit),(GSourceFunc)updateWinSize, &ponyArray[i]); //Name the window the name of the pony being animated gtk_window_set_title(GTK_WINDOW(ponyArray[i].win), getPonyName(ponyArray[i].name)); //Size down the window before showing it gtk_window_set_default_size(GTK_WINDOW(ponyArray[i].win), gdk_pixbuf_animation_get_width(ponyArray[i]. pictureanim), gdk_pixbuf_animation_get_height (ponyArray[i].pictureanim)); //Remove the titlebar gtk_window_set_decorated(GTK_WINDOW(ponyArray[i].win), FALSE); //Set up the signals ponyArray[i].clickEventID = g_signal_connect(G_OBJECT(ponyArray[i].win), "button_press_event", G_CALLBACK(click_event), &ponyArray[i]); ponyArray[i].enterEventID = g_signal_connect(G_OBJECT(ponyArray[i].win), "enter-notify-event", G_CALLBACK(enter_event), &ponyArray[i]); ponyArray[i].leaveEventID = g_signal_connect(G_OBJECT(ponyArray[i].win), "leave-notify-event", G_CALLBACK(enter_event), &ponyArray[i]); gtk_widget_add_events(ponyArray[i].win, GDK_BUTTON_PRESS_MASK); gtk_container_add(GTK_CONTAINER(ponyArray[i].win), GTK_WIDGET(ponyArray[i]. image)); //Get rid of taskbar item gtk_window_set_skip_taskbar_hint(GTK_WINDOW(ponyArray[i].win), TRUE); //Make it so it can't be selected gtk_window_set_accept_focus(GTK_WINDOW(ponyArray[i].win), FALSE); gtk_widget_realize(ponyArray[i].win); //Always on top gtk_window_set_keep_above(GTK_WINDOW(ponyArray[i].win), TRUE); updateWinSize(&ponyArray[i]); if(error != NULL) break; } free(ponyDirectory); free(ponyHomeFile); //Quit out if there were any errors and give a message if( error != NULL) { printf("%s\n",error->message); return 0; } //Make it transparent? /*cr = gdk_cairo_create(win->window); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0); cairo_set_operator( cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(image));*/ //Main loop for( int i = 0; i < numberOfPonies; i++) gtk_widget_show_all(ponyArray[i].win); gtk_main(); return 0; }
static VALUE rg_delay_time(VALUE self) { return INT2NUM(gdk_pixbuf_animation_iter_get_delay_time(RVAL2ITR(self))); }