⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testanimation.c

📁 Linux下gtk图形界面开发的各种gtk控件调用方法示例
💻 C
字号:
/* testpixbuf -- test program for gdk-pixbuf code * Copyright (C) 1999 Mark Crichton, Larry Ewing * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <config.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <gtk/gtk.h>typedef struct _LoadContext LoadContext;struct _LoadContext{  gchar *filename;  GtkWidget *window;  GdkPixbufLoader *pixbuf_loader;  guint load_timeout;  FILE* image_stream;};static voiddestroy_context (gpointer data){  LoadContext *lc = data;  g_free (lc->filename);    if (lc->load_timeout)    g_source_remove (lc->load_timeout);  if (lc->image_stream)    fclose (lc->image_stream);  if (lc->pixbuf_loader)    {      gdk_pixbuf_loader_close (lc->pixbuf_loader, NULL);      g_object_unref (lc->pixbuf_loader);    }    g_free (lc);}static LoadContext*get_load_context (GtkWidget *image){  LoadContext *lc;  lc = g_object_get_data (G_OBJECT (image), "lc");  if (lc == NULL)    {      lc = g_new0 (LoadContext, 1);      g_object_set_data_full (G_OBJECT (image),                                      "lc",                              lc,                              destroy_context);    }  return lc;}static voidprogressive_prepared_callback (GdkPixbufLoader* loader,                               gpointer         data){  GdkPixbuf* pixbuf;  GtkWidget* image;  image = GTK_WIDGET (data);      pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);  /* Avoid displaying random memory contents, since the pixbuf   * isn't filled in yet.   */  gdk_pixbuf_fill (pixbuf, 0xaaaaaaff);  /* Could set the pixbuf instead, if we only wanted to display   * static images.   */  gtk_image_set_from_animation (GTK_IMAGE (image),                                gdk_pixbuf_loader_get_animation (loader));}static voidprogressive_updated_callback (GdkPixbufLoader* loader,                              gint x, gint y, gint width, gint height,                              gpointer data){  GtkWidget* image;    image = GTK_WIDGET (data);  /* We know the pixbuf inside the GtkImage has changed, but the image   * itself doesn't know this; so queue a redraw.  If we wanted to be   * really efficient, we could use a drawing area or something   * instead of a GtkImage, so we could control the exact position of   * the pixbuf on the display, then we could queue a draw for only   * the updated area of the image.   */  /* We only really need to redraw if the image's animation iterator   * is gdk_pixbuf_animation_iter_on_currently_loading_frame(), but   * who cares.   */    gtk_widget_queue_draw (image);}static gintprogressive_timeout (gpointer data){  GtkWidget *image;  LoadContext *lc;    image = GTK_WIDGET (data);  lc = get_load_context (image);    /* This shows off fully-paranoid error handling, so looks scary.   * You could factor out the error handling code into a nice separate   * function to make things nicer.   */    if (lc->image_stream)    {      size_t bytes_read;      guchar buf[256];      GError *error = NULL;            bytes_read = fread (buf, 1, 256, lc->image_stream);      if (ferror (lc->image_stream))        {          GtkWidget *dialog;                    dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),                                           GTK_DIALOG_DESTROY_WITH_PARENT,                                           GTK_MESSAGE_ERROR,                                           GTK_BUTTONS_CLOSE,                                           "Failure reading image file 'alphatest.png': %s",                                           g_strerror (errno));          g_signal_connect (dialog, "response",			    G_CALLBACK (gtk_widget_destroy), NULL);          fclose (lc->image_stream);          lc->image_stream = NULL;          gtk_widget_show (dialog);                    lc->load_timeout = 0;          return FALSE; /* uninstall the timeout */        }      if (!gdk_pixbuf_loader_write (lc->pixbuf_loader,                                    buf, bytes_read,                                    &error))        {          GtkWidget *dialog;                    dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),                                           GTK_DIALOG_DESTROY_WITH_PARENT,                                           GTK_MESSAGE_ERROR,                                           GTK_BUTTONS_CLOSE,                                           "Failed to load image: %s",                                           error->message);          g_error_free (error);                    g_signal_connect (dialog, "response",			    G_CALLBACK (gtk_widget_destroy), NULL);          fclose (lc->image_stream);          lc->image_stream = NULL;                    gtk_widget_show (dialog);          lc->load_timeout = 0;          return FALSE; /* uninstall the timeout */        }      if (feof (lc->image_stream))        {          fclose (lc->image_stream);          lc->image_stream = NULL;          /* Errors can happen on close, e.g. if the image           * file was truncated we'll know on close that           * it was incomplete.           */          error = NULL;          if (!gdk_pixbuf_loader_close (lc->pixbuf_loader,                                        &error))            {              GtkWidget *dialog;                            dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),                                               GTK_DIALOG_DESTROY_WITH_PARENT,                                               GTK_MESSAGE_ERROR,                                               GTK_BUTTONS_CLOSE,                                               "Failed to load image: %s",                                               error->message);                            g_error_free (error);                            g_signal_connect (dialog, "response",				G_CALLBACK (gtk_widget_destroy), NULL);                            gtk_widget_show (dialog);              g_object_unref (lc->pixbuf_loader);              lc->pixbuf_loader = NULL;                            lc->load_timeout = 0;                            return FALSE; /* uninstall the timeout */            }                    g_object_unref (lc->pixbuf_loader);          lc->pixbuf_loader = NULL;        }    }  else    {      lc->image_stream = fopen (lc->filename, "r");      if (lc->image_stream == NULL)        {          GtkWidget *dialog;                    dialog = gtk_message_dialog_new (GTK_WINDOW (lc->window),                                           GTK_DIALOG_DESTROY_WITH_PARENT,                                           GTK_MESSAGE_ERROR,                                           GTK_BUTTONS_CLOSE,                                           "Unable to open image file '%s': %s",                                           lc->filename,                                           g_strerror (errno));          g_signal_connect (dialog, "response",			    G_CALLBACK (gtk_widget_destroy), NULL);                    gtk_widget_show (dialog);          lc->load_timeout = 0;          return FALSE; /* uninstall the timeout */        }      if (lc->pixbuf_loader)        {          gdk_pixbuf_loader_close (lc->pixbuf_loader, NULL);          g_object_unref (lc->pixbuf_loader);          lc->pixbuf_loader = NULL;        }            lc->pixbuf_loader = gdk_pixbuf_loader_new ();            g_signal_connect (lc->pixbuf_loader, "area_prepared",			G_CALLBACK (progressive_prepared_callback), image);      g_signal_connect (lc->pixbuf_loader, "area_updated",			G_CALLBACK (progressive_updated_callback), image);    }  /* leave timeout installed */  return TRUE;}static voidstart_progressive_loading (GtkWidget *image){  LoadContext *lc;  lc = get_load_context (image);    /* This is obviously totally contrived (we slow down loading   * on purpose to show how incremental loading works).   * The real purpose of incremental loading is the case where   * you are reading data from a slow source such as the network.   * The timeout simply simulates a slow data source by inserting   * pauses in the reading process.   */  lc->load_timeout = gdk_threads_add_timeout (100,                                    progressive_timeout,                                    image);}static GtkWidget *do_image (const char *filename){  GtkWidget *frame;  GtkWidget *vbox;  GtkWidget *image;  GtkWidget *label;  GtkWidget *align;  GtkWidget *window;  gchar *str, *escaped;  LoadContext *lc;    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);  gtk_window_set_title (GTK_WINDOW (window), "Image Loading");  gtk_container_set_border_width (GTK_CONTAINER (window), 8);  vbox = gtk_vbox_new (FALSE, 8);  gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);  gtk_container_add (GTK_CONTAINER (window), vbox);  label = gtk_label_new (NULL);  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);  escaped = g_markup_escape_text (filename, -1);  str = g_strdup_printf ("Progressively loading: <b>%s</b>", escaped);  gtk_label_set_markup (GTK_LABEL (label),                        str);  g_free (escaped);  g_free (str);    gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);        frame = gtk_frame_new (NULL);  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);  /* The alignment keeps the frame from growing when users resize   * the window   */  align = gtk_alignment_new (0.5, 0.5, 0, 0);  gtk_container_add (GTK_CONTAINER (align), frame);  gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);        image = gtk_image_new_from_pixbuf (NULL);  gtk_container_add (GTK_CONTAINER (frame), image);  lc = get_load_context (image);  lc->window = window;  lc->filename = g_strdup (filename);    start_progressive_loading (image);  g_signal_connect (window, "destroy",		    G_CALLBACK (gtk_main_quit), NULL);    g_signal_connect (window, "delete_event",		    G_CALLBACK (gtk_main_quit), NULL);  gtk_widget_show_all (window);  return window;}static voiddo_nonprogressive (const gchar *filename){  GtkWidget *frame;  GtkWidget *vbox;  GtkWidget *image;  GtkWidget *label;  GtkWidget *align;  GtkWidget *window;  gchar *str, *escaped;    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);  gtk_window_set_title (GTK_WINDOW (window), "Animation");  gtk_container_set_border_width (GTK_CONTAINER (window), 8);  vbox = gtk_vbox_new (FALSE, 8);  gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);  gtk_container_add (GTK_CONTAINER (window), vbox);  label = gtk_label_new (NULL);  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);  escaped = g_markup_escape_text (filename, -1);  str = g_strdup_printf ("Loaded from file: <b>%s</b>", escaped);  gtk_label_set_markup (GTK_LABEL (label),                        str);  g_free (escaped);  g_free (str);    gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);        frame = gtk_frame_new (NULL);  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);  /* The alignment keeps the frame from growing when users resize   * the window   */  align = gtk_alignment_new (0.5, 0.5, 0, 0);  gtk_container_add (GTK_CONTAINER (align), frame);  gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);        image = gtk_image_new_from_file (filename);  gtk_container_add (GTK_CONTAINER (frame), image);  g_signal_connect (window, "destroy",		    G_CALLBACK (gtk_main_quit), NULL);    g_signal_connect (window, "delete_event",		    G_CALLBACK (gtk_main_quit), NULL);  gtk_widget_show_all (window);}intmain (int    argc,      char **argv){  gint i;    gtk_init (&argc, &argv);  i = 1;  while (i < argc)    {      do_image (argv[i]);      do_nonprogressive (argv[i]);            ++i;    }  gtk_main ();    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -