Reputation: 1175
I'm using gtk+-3.2.4 on Ubuntu 11.04 (Natty). I'm trying to draw in a GtkDrawingArea with Cairo and have the drawing area be scrollable. The code runs without errors but no drawing is done. What am I doing wrong ?
// gcc -Wextra -o scrol `pkg-config --cflags --libs gtk+-3.0` scrol1.c
#include <gtk/gtk.h>
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
static gboolean draw_cb (GtkWidget *widget, GdkEventExpose *event)
{
cairo_t *cr;
cr = gdk_cairo_create (gtk_widget_get_window (widget));
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_paint(cr);
cairo_set_source_rgb (cr, 0.42, 0.65, 0.80);
cairo_set_line_width (cr,6);
cairo_rectangle (cr, 3, 3, 100, 100);
cairo_stroke (cr);
cairo_destroy(cr);
return FALSE;
}
int main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
GtkWidget *window;
GtkWidget *grid;
GtkWidget *swindow;
GtkWidget *viewport;
GtkWidget *darea;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
grid = gtk_grid_new();
swindow = gtk_scrolled_window_new (NULL,NULL);
viewport = gtk_viewport_new (NULL,NULL);
darea = gtk_drawing_area_new();
gtk_container_add (GTK_CONTAINER(viewport), darea);
gtk_container_add (GTK_CONTAINER(swindow), viewport);
gtk_grid_attach (GTK_GRID(grid), swindow, 0, 1, 1, 2);
gtk_container_add (GTK_CONTAINER(window), grid);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (darea, "draw", G_CALLBACK(draw_cb), NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
Upvotes: 2
Views: 3429
Reputation: 484
Here's a screenshot of the window that your code creates:
I imagine that you were expecting to see a square. However, all that you get to see is the top left of that square. This is because the drawing area has requested a very small amount of space, resulting in a small window. This means that your wonderful artwork is being clipped to fit in a window of this minimal size. There are a couple of things you could do:
Set the minimum size of the scrolled window that contains the drawing area:
gtk_widget_set_size_request( swindow, 500, 500 );
This will result in a 500 by 500 pixel drawing area being visible (which is lots more than you need for the square). However, if you make the window larger, then the drawing area will not fill it.
Set the scrolled window to take on all horizontal and vertical space it can get:
gtk_widget_set_hexpand( swindow, TRUE );
gtk_widget_set_vexpand( swindow, TRUE );
If you just do this, then the window will initially look the same as the one in your original code. However, if you manually resize the window, then you'll see that the scrolled window (and hence the drawing area) expands to fill all of the space it can in the window. If you expand it enough, you'll see your square.
If you combine both of the above, then you'll get a window that's initially ~500x500 pixels. If you resize it, then the drawing area will expand to fill the window.
You could also add a gtk_widget_set_size_request
call to set the size of the drawing area widget. If you set it to be larger than the scrolled window's size, then you'll get scrollbars.
Upvotes: 3
Reputation: 1175
// gcc -Wextra -o grid1 `pkg-config --cflags --libs gtk+-3.0` grid1.c
#include <gtk/gtk.h>
#define WINDOW_WIDTH 200
#define WINDOW_HEIGHT 80
static gboolean draw_cb (GtkWidget *widget, GdkEventExpose *event)
{
cairo_t *cr;
cr = gdk_cairo_create (gtk_widget_get_window (widget));
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_paint(cr);
cairo_set_source_rgb (cr, 0.42, 0.65, 0.80);
cairo_set_line_width (cr,6);
cairo_rectangle (cr, 3, 3, 400, 100);
cairo_stroke (cr);
cairo_destroy(cr);
return TRUE;
}
int main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
GtkWidget *window;
GtkWidget *grid;
GtkWidget *swindow;
GtkWidget *viewport;
GtkWidget *darea;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
grid = gtk_grid_new();
swindow = gtk_scrolled_window_new (NULL,NULL);
viewport = gtk_viewport_new (NULL,NULL);
darea = gtk_drawing_area_new();
gtk_widget_set_size_request (window, 200, 100);
gtk_widget_set_size_request (darea, 406, 106);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
GTK_POLICY_ALWAYS,
GTK_POLICY_NEVER);
gtk_widget_set_hexpand(GTK_WIDGET(swindow), TRUE);
gtk_widget_set_vexpand(GTK_WIDGET(swindow), TRUE);
gtk_container_add (GTK_CONTAINER(viewport), darea);
gtk_container_add (GTK_CONTAINER(swindow), viewport);
gtk_grid_attach (GTK_GRID(grid), swindow, 0, 0, 1, 1);
gtk_container_add (GTK_CONTAINER(window), grid);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (darea, "draw", G_CALLBACK(draw_cb), NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
Upvotes: 0
Reputation: 1175
I figured it out.
http://www.gtkforums.com/viewtopic.php?f=3&t=988&p=195381#p195381
Upvotes: -2
Reputation: 9877
The drawing is done, however it's just in the top-left corner of the window. I added the following two calls and everything looks fine to me:
gtk_widget_set_hexpand(GTK_WIDGET(swindow), TRUE);
gtk_widget_set_vexpand(GTK_WIDGET(swindow), TRUE);
Upvotes: 2
Reputation: 57920
Try returning TRUE
from the on_draw()
callback to block the default handler; perhaps the default handler is drawing empty space over your drawing?
Upvotes: 1