Help request: gnome-canvas and images from data



Hi,

I'm trying to understand how to use gnome-canvas to display images, and
I could use some help/advice.

I've figured out how to display a .png image from a file on the canvas,
but I've bogged down on displaying an image from data (the functionality
provided by gdk-pixbuf_new_from_data(), for example).

Two approaches I've tried that almost seem to work are (I've attached
the code at the end):

1.  Create a pixbuf with gdk_pixbuf_new_from_data() and a blank drawable
    with gdk_pixmap_new(), fill in the drawable using
    gdk_pixbuf_render_to_drawable(), and then add it to the canvas with
    gnome_canvas_item_new() using the GNOME_TYPE_CANVAS_WIDGET
    type and providing the argument pair "widget" and a pointer to the
    drawable cast as a (GtkWidget *).

2.  Create a blank drawable with gdk_pixbuf_new(), draw the data into
    the drawable with gdk_draw_rgb_image(), and add the drawable to the
    canvas as above using gnome_canvas_item_new() and the
    GNOME_TYPE_WIDGET type.

Both methods produce a blank canvas, and a warning from GnomeUI: 

GnomeUI-WARNING **: gnome_canvas_item_construct(): invalid unclassed object pointer for argument type `GtkObject'

I've called gdk_rgb_set_verbose(TRUE), but that had no effect on the
error messages reported.  The error message seems to be coming from the
gnome_canvas_item_new() call.  If I comment it out, the error message
goes away.

Obviously, I'm missing something here.  I'd appreciate advice either as
to what I'm doing wrong or where I might look for enlightenment.

Thanks.

Frazer

=======================
Here's my code (mostly snarfed from the online books by Pennington and by
Sheets.
=======================

#include <gnome.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk-pixbuf/gdk-pixbuf-loader.h>

#define WIDTH   300
#define HEIGHT  300

static gint delete_event_cb(GtkWidget *window, GdkEventAny *e, gpointer data);

GtkWidget *app;


static guchar drawbuf[WIDTH*HEIGHT*6];      /* The calculated "image" */

void init_drawbuf(void);    /* A subroutine to calculate the "image".*/

static void
create_canvas_items(GtkWidget *canvas)
{
    GdkPixbuf *pixbuf;
    GdkDrawable *gpixmap;
    GnomeCanvasItem *citem;
    GnomeCanvasGroup *group;

    group = gnome_canvas_root(GNOME_CANVAS(canvas));

    init_drawbuf();
    gpixmap = (GdkDrawable *)gdk_pixmap_new(app->window, 20, 20, -1);

/* This is the code for the first method */
    pixbuf = gdk_pixbuf_new_from_data(drawbuf, GDK_COLORSPACE_RGB,
                                      FALSE, 8, 20, 20,
                                      WIDTH*3, NULL, NULL);
    gdk_pixbuf_render_to_drawable(pixbuf, gpixmap,
                                  app->style->bg_gc[GTK_STATE_NORMAL],
                                  0, 0, 0, 0, 20, 20,
                                  GDK_RGB_DITHER_NORMAL, 0, 0);


/* Alternately, I've also tried
 *  pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 40, 40);
 *  gdk_draw_rgb_image(gpixmap, app->style->fg_gc[GTK_STATE_NORMAL],
 *              0, 0, WIDTH, HEIGHT,
 *                     GDK_RGB_DITHER_NORMAL, 
 *                     drawbuf, WIDTH*3);
 */
 
    citem = gnome_canvas_item_new (group,
                                   GNOME_TYPE_CANVAS_WIDGET,
                                   "widget", (GtkWidget *)gpixmap,
                                   "x", 0., "y", 0.,
                                   "width", (double) WIDTH,
                                   "height", (double) HEIGHT,
                                   NULL);
    gnome_canvas_item_show(citem);
}

/*
 * This function calculates the "image".
 */
void init_drawbuf(void)
{
    gint x, y;
    gint pixel_offset;
    gint rowstride = WIDTH*3;

    for(y=0; y<HEIGHT; y++) {
        for(x=0; x<WIDTH; x++) {
            pixel_offset = y*rowstride +x*3;
            drawbuf[pixel_offset] = 255;
            drawbuf[pixel_offset + 1] = 255;
            drawbuf[pixel_offset + 2] = 255;
        }
    }
}

int
main(int argc, char *argv[])
{
    GtkWidget *sw;
    GtkWidget *canvas;

    gnome_init("canvas-example", "0.0", argc, argv);

    app = gnome_app_new("mytest", "My test program");
    gtk_widget_set_usize(GTK_WIDGET(app), WIDTH, HEIGHT);
    gtk_signal_connect(GTK_OBJECT(app), "delete_event",
                       GTK_SIGNAL_FUNC(delete_event_cb),
                       NULL);
    
    sw = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
                                   GTK_POLICY_AUTOMATIC,
                                   GTK_POLICY_AUTOMATIC);

    canvas = gnome_canvas_new_aa();

    gnome_canvas_set_scroll_region(GNOME_CANVAS(canvas), 0, 0,
                                   2*WIDTH, 2*HEIGHT);

    gtk_container_add(GTK_CONTAINER(sw), canvas);
    gnome_app_set_contents(GNOME_APP(app), sw);
    gtk_widget_show_all(app);
    create_canvas_items(canvas);
    gtk_widget_show_all(app);

    gtk_main();

    return 0;
}

static gint
delete_event_cb(GtkWidget *window, GdkEventAny *e, gpointer data)
{
    gtk_main_quit();
    return FALSE;
}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]