Arne Böckmann
Arne Böckmann

Reputation: 487

Scrolling a very large GtkDrawingArea

I have a GtkDrawingArea that is used to visualize data. Depending on the database and user input the drawing can grow really large (larger than the maximum allowed GtkDrawingArea size). Therefore I would like to use a drawing area that is just as big as the current window and update it manually upon scrolling.

If I use the ScrolledWindow + Viewport method to add scroll-bars to the drawing area it does obviously not work because the drawing area is not big enough to need scroll-bars.

Is there any way that that I can trick the viewport into thinking that the underlying widget is larger than it actually is? If not what would be the best way to solve this problem?

Note: I am using Gtk2 and switching to Gtk3 is not a possibility.

Upvotes: 5

Views: 944

Answers (2)

iain
iain

Reputation: 5683

You need to subclass GtkDrawingArea and override the set_scroll_adjustments signal. GtkWidget docs

In this signal you will get the adjustments for the scrolled window. I wrote some code a few years back that you can look at to see how to implement it.

MarlinSampleView code

This code was able to pretend that the widget was millions of pixels wide when in reality it wasn't any bigger than the window.

Upvotes: 2

Arne Böckmann
Arne Böckmann

Reputation: 487

It turned out to be quite simple:

The GtkScrolledWindow has another constructor which can be used to set the GtkAdjustments that the scrolled window should use.

//These adjustments will be attached to the scrollbars.
prvt->hAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 0, 0, 0, 0));
prvt->vAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 0, 0, 0, 0));

GtkWidget* scrolledTree = gtk_scrolled_window_new(prvt->hAdjustment, prvt->vAdjustment);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolledTree), drawing_area);

Now, whenever the size of the drawing changes you just need to modify the GTKAdjustments to simulate the change. There is no need to actually resize the drawing area.

gtk_adjustment_set_lower(prvt->hAdjustment, 0);
gtk_adjustment_set_step_increment(prvt->hAdjustment, 1);
gtk_adjustment_set_page_increment(prvt->hAdjustment, 10);
gtk_adjustment_set_upper(prvt->hAdjustment, picture_width);
gtk_adjustment_set_page_size(prvt->hAdjustment, scrollArea_width);
gtk_adjustment_changed(prvt->hAdjustment);

Notice that I call gtk_adjustment_changed in the end. This is important, otherwise the ScrolledWindow will not update the scrollbars.

Finaly the value_changed callback of the GtkAdjustmens can be used to catch the scroll events and adjust the drawing.

Edit: This does not work properly because the GtkScrolledWindow receives the scroll event as well and moves the image :(

Upvotes: 0

Related Questions