/src/wrappers/gtk/examples/gtk-demo/pixbufs.e
Specman e | 298 lines | 21 code | 68 blank | 209 comment | 2 complexity | 3155bb4d0e5953d03a8e316ca116e524 MD5 | raw file
1indexing 2 description: "." 3 copyright: "[ 4 Copyright (C) 2006 Paolo Redaelli, GTK+ team 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public License 8 as published by the Free Software Foundation; either version 2.1 of 9 the License, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with this library; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA 20 ]" 21 22class PIXBUFS 23 24creation make 25 26feature 27-- /* Pixbufs 28-- * 29-- * A GdkPixbuf represents an image, normally in RGB or RGBA format. 30-- * Pixbufs are normally used to load files from disk and perform 31-- * image scaling. 32-- * 33-- * This demo is not all that educational, but looks cool. It was written 34-- * by Extreme Pixbuf Hacker Federico Mena Quintero. It also shows 35-- * off how to use GtkDrawingArea to do a simple animation. 36-- * 37-- * Look at the Image demo for additional pixbuf usage examples. 38-- * 39-- */ 40 41-- #include <stdlib.h> 42-- #include <gtk/gtk.h> 43-- #include <math.h> 44 45-- #include "demo-common.h" 46 47-- #define FRAME_DELAY 50 48 49-- #define BACKGROUND_NAME "background.jpg" 50 51-- static const char *image_names[] = { 52-- "apple-red.png", 53-- "gnome-applets.png", 54-- "gnome-calendar.png", 55-- "gnome-foot.png", 56-- "gnome-gmush.png", 57-- "gnome-gimp.png", 58-- "gnome-gsame.png", 59-- "gnu-keys.png" 60-- }; 61 62-- #define N_IMAGES G_N_ELEMENTS (image_names) 63 64-- /* demo window */ 65-- static GtkWidget *window = NULL; 66 67-- /* Current frame */ 68-- static GdkPixbuf *frame; 69 70-- /* Background image */ 71-- static GdkPixbuf *background; 72-- static gint back_width, back_height; 73 74-- /* Images */ 75-- static GdkPixbuf *images[N_IMAGES]; 76 77-- /* Widgets */ 78-- static GtkWidget *da; 79 80-- /* Loads the images for the demo and returns whether the operation succeeded */ 81-- static gboolean 82-- load_pixbufs (GError **error) 83-- { 84-- gint i; 85-- char *filename; 86 87-- if (background) 88-- return TRUE; /* already loaded earlier */ 89 90-- /* demo_find_file() looks in the the current directory first, 91-- * so you can run gtk-demo without installing GTK, then looks 92-- * in the location where the file is installed. 93-- */ 94-- filename = demo_find_file (BACKGROUND_NAME, error); 95-- if (!filename) 96-- return FALSE; /* note that "error" was filled in and returned */ 97 98-- background = gdk_pixbuf_new_from_file (filename, error); 99-- g_free (filename); 100 101-- if (!background) 102-- return FALSE; /* Note that "error" was filled with a GError */ 103 104-- back_width = gdk_pixbuf_get_width (background); 105-- back_height = gdk_pixbuf_get_height (background); 106 107-- for (i = 0; i < N_IMAGES; i++) 108-- { 109-- filename = demo_find_file (image_names[i], error); 110-- if (!filename) 111-- return FALSE; /* Note that "error" was filled with a GError */ 112 113-- images[i] = gdk_pixbuf_new_from_file (filename, error); 114-- g_free (filename); 115 116-- if (!images[i]) 117-- return FALSE; /* Note that "error" was filled with a GError */ 118-- } 119 120-- return TRUE; 121-- } 122 123-- /* Expose callback for the drawing area */ 124-- static gint 125-- expose_cb (GtkWidget *widget, 126-- GdkEventExpose *event, 127-- gpointer data) 128-- { 129-- guchar *pixels; 130-- int rowstride; 131 132-- rowstride = gdk_pixbuf_get_rowstride (frame); 133 134-- pixels = gdk_pixbuf_get_pixels (frame) + rowstride * event->area.y + event->area.x * 3; 135 136-- gdk_draw_rgb_image_dithalign (widget->window, 137-- widget->style->black_gc, 138-- event->area.x, event->area.y, 139-- event->area.width, event->area.height, 140-- GDK_RGB_DITHER_NORMAL, 141-- pixels, rowstride, 142-- event->area.x, event->area.y); 143 144-- return TRUE; 145-- } 146 147-- #define CYCLE_LEN 60 148 149-- static int frame_num; 150 151-- /* Timeout handler to regenerate the frame */ 152-- static gint 153-- timeout (gpointer data) 154-- { 155-- double f; 156-- int i; 157-- double xmid, ymid; 158-- double radius; 159 160-- gdk_pixbuf_copy_area (background, 0, 0, back_width, back_height, 161-- frame, 0, 0); 162 163-- f = (double) (frame_num % CYCLE_LEN) / CYCLE_LEN; 164 165-- xmid = back_width / 2.0; 166-- ymid = back_height / 2.0; 167 168-- radius = MIN (xmid, ymid) / 2.0; 169 170-- for (i = 0; i < N_IMAGES; i++) 171-- { 172-- double ang; 173-- int xpos, ypos; 174-- int iw, ih; 175-- double r; 176-- GdkRectangle r1, r2, dest; 177-- double k; 178 179-- ang = 2.0 * G_PI * (double) i / N_IMAGES - f * 2.0 * G_PI; 180 181-- iw = gdk_pixbuf_get_width (images[i]); 182-- ih = gdk_pixbuf_get_height (images[i]); 183 184-- r = radius + (radius / 3.0) * sin (f * 2.0 * G_PI); 185 186-- xpos = floor (xmid + r * cos (ang) - iw / 2.0 + 0.5); 187-- ypos = floor (ymid + r * sin (ang) - ih / 2.0 + 0.5); 188 189-- k = (i & 1) ? sin (f * 2.0 * G_PI) : cos (f * 2.0 * G_PI); 190-- k = 2.0 * k * k; 191-- k = MAX (0.25, k); 192 193-- r1.x = xpos; 194-- r1.y = ypos; 195-- r1.width = iw * k; 196-- r1.height = ih * k; 197 198-- r2.x = 0; 199-- r2.y = 0; 200-- r2.width = back_width; 201-- r2.height = back_height; 202 203-- if (gdk_rectangle_intersect (&r1, &r2, &dest)) 204-- gdk_pixbuf_composite (images[i], 205-- frame, 206-- dest.x, dest.y, 207-- dest.width, dest.height, 208-- xpos, ypos, 209-- k, k, 210-- GDK_INTERP_NEAREST, 211-- ((i & 1) 212-- ? MAX (127, fabs (255 * sin (f * 2.0 * G_PI))) 213-- : MAX (127, fabs (255 * cos (f * 2.0 * G_PI))))); 214-- } 215 216-- gtk_widget_queue_draw (da); 217 218-- frame_num++; 219-- return TRUE; 220-- } 221 222-- static guint timeout_id; 223 224-- static void 225-- cleanup_callback (GtkObject *object, 226-- gpointer data) 227-- { 228-- g_source_remove (timeout_id); 229-- timeout_id = 0; 230-- } 231 232-- GtkWidget * 233-- do_pixbufs (GtkWidget *do_widget) 234-- { 235-- if (!window) 236-- { 237-- GError *error; 238 239-- window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 240-- gtk_window_set_screen (GTK_WINDOW (window), 241-- gtk_widget_get_screen (do_widget)); 242-- gtk_window_set_title (GTK_WINDOW (window), "Pixbufs"); 243-- gtk_window_set_resizable (GTK_WINDOW (window), FALSE); 244 245-- g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window); 246-- g_signal_connect (window, "destroy", G_CALLBACK (cleanup_callback), NULL); 247 248 249-- error = NULL; 250-- if (!load_pixbufs (&error)) 251-- { 252-- GtkWidget *dialog; 253 254-- dialog = gtk_message_dialog_new (GTK_WINDOW (window), 255-- GTK_DIALOG_DESTROY_WITH_PARENT, 256-- GTK_MESSAGE_ERROR, 257-- GTK_BUTTONS_CLOSE, 258-- "Failed to load an image: %s", 259-- error->message); 260 261-- g_error_free (error); 262 263-- g_signal_connect (dialog, "response", 264-- G_CALLBACK (gtk_widget_destroy), NULL); 265 266-- gtk_widget_show (dialog); 267-- } 268-- else 269-- { 270-- gtk_widget_set_size_request (window, back_width, back_height); 271 272-- frame = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, back_width, back_height); 273 274-- da = gtk_drawing_area_new (); 275 276-- g_signal_connect (da, "expose_event", 277-- G_CALLBACK (expose_cb), NULL); 278 279-- gtk_container_add (GTK_CONTAINER (window), da); 280 281-- timeout_id = g_timeout_add (FRAME_DELAY, timeout, NULL); 282-- } 283-- } 284 285-- if (!GTK_WIDGET_VISIBLE (window)) 286-- { 287-- gtk_widget_show_all (window); 288-- } 289-- else 290-- { 291-- gtk_widget_destroy (window); 292-- window = NULL; 293-- g_object_unref (frame); 294-- } 295 296-- return window; 297-- } 298end