TAGS :Viewed: 9 - Published at: a few seconds ago

[ GtkDrawingArea with Cairo - how to make it scrollable ]

Followed is a small code to use cairo to draw something. The problem is that the canvas drawn by cairo is larger than the area of gtk's scrolled_window. But the scrolled_window doesn't scroll so I can only see the part of the canvas.

Any suggestion? My environment: MinGW + gtk2.10.11.

#include <gtk/gtk.h>

static gboolean draw_cb (GtkWidget *widget, GdkEventExpose *event) 
{
  cairo_t *cr;
  cr = gdk_cairo_create (widget->window);
  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, 30, 30, 100, 100);
  cairo_stroke (cr); 
  cairo_destroy(cr);
  return FALSE;
}

int main (int argc, char *argv[])
{
  gtk_init (&argc, &argv);
  GtkWidget *window;
  GtkWidget *sw;
  GtkWidget *cr;

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_policy((GtkWindow *)window, FALSE, FALSE, FALSE);
  sw = gtk_scrolled_window_new (NULL,NULL);
  gtk_widget_set_usize(sw, 100, 100);
  cr = gtk_drawing_area_new();

  gtk_scrolled_window_add_with_viewport(GTK_CONTAINER(sw), cr);
  gtk_container_add (GTK_CONTAINER(window), sw);

  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
  g_signal_connect (cr, "expose-event", G_CALLBACK(draw_cb),  NULL);

  gtk_widget_show_all (window);
  gtk_main ();
  return 0;
  }

Answer 1


Usually, when drawing you have two choices:

  1. either you want the drawn content to adapt to the available size, and you use cairo_scale for that
  2. or you use a scrolled view, as you're doing.

In case 2, Cairo has no way of knowing you're drawing out of bounds. And in some cases, drawing out of bounds is even what you want. So here, what is missing is setting the drawing area's size. This can be done using gtk_widget_set_size_request.