Centered zoom with GtkScrolledWindow
- From: Robert Reitenbach <reirob gmx net>
- To: gtk-app-devel-list gnome org
- Subject: Centered zoom with GtkScrolledWindow
- Date: Wed, 07 Sep 2005 13:18:18 +0200
Dear GTK developers and users,
It is my first use of the GTK library and maybe I did something wrong.
I stumbled about a problem and cannot find an answer to it, even if I
think, that there might be a more or less simple solution to it. I
looked through the mailing list archives but could not find a solution,
but maybe I did not search good enough, so I also will be happy if you
provide a link to a solution.
Here the overview of my problem:
I am putting a widget in a GtkScrolledWindow to be able to
scroll and scale the widget (this works). I connect a signal to
the widget to call a function when a mouse scroll event appears
(this works also). In this callback function I zoom in or out
the widget with the gtk_widget_set_size_request function which
works fine, but the anchor is in the top left corner of the
GtkScrolledWindow object and moves the center of the widget
south-east when zooming in or north-west when zooming out. I
like to keep the center of the widget where it was, so I
calculate the center and the appropriate adjustment values of
the scrolled window and scroll it back to the prior center by
calling by emitting the signals
g_signal_emit_by_name(hadj, "value_changed");
g_signal_emit_by_name(vadj, "value_changed");
which also works.
And here comes the problem:
The user sees that the image is scaled first, so there
is already a scrolling involved and then it is
automatically scrolled back.
Is there a possibility to block/suspend the scrolling, when resizing the
child widget and do both operations "visibly" at the same time, so that
the user has a clean centered zooming? I understand that this could be
maybe done by sub-classing the GtkScrolledWindow class, but it looks
like a too big task to me and I think there might be another way which I
have overlooked maybe?
Thanks in advance for any suggestions and help
reirob
P.S.: Here some code snippets if it might help:
1.) I am putting a widget in a GtkScrolledWindow to be able to scroll
and scale the widget:
GtkWidget *map_area, zoom_map;
...
/* Here the map_area widget is build and ready */
...
/* Adding the call back funtion */
gtk_widget_add_events(map_area, GDK_SCROLL_MASK);
g_signal_connect(
G_OBJECT(map_area), "scroll_event",
G_CALLBACK(button_scroll_map_cb), NULL
);
zoom_map = gtk_scrolled_window_new(NULL, NULL);
gtk_widget_show(zoom_map);
gtk_scrolled_window_set_policy(
GTK_SCROLLED_WINDOW(zoom_map),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC
);
gtk_scrolled_window_add_with_viewport(
GTK_SCROLLED_WINDOW(zoom_map), map_area
);
2.) In the callback funtion:
static gint button_scroll_map_cb(
GtkWidget * area, GdkEventScroll * event,
G_GNUC_UNUSED gpointer user_data
) {
gint width, height;
GtkScrolledWindow *zoom;
GtkAdjustment *hadj, *vadj;
gdouble hratio, vratio;
guint blocked_handlers = 0;
if (area->window == NULL || gmap->map == NULL)
return FALSE;
/* To get the scroll adjustment */
zoom = GTK_SCROLLED_WINDOW(
gtk_widget_get_parent(gtk_widget_get_parent(gmap->area))
);
/* To get the adjustments */
hadj = gtk_scrolled_window_get_hadjustment(zoom);
vadj = gtk_scrolled_window_get_vadjustment(zoom);
/* Calculate the ratio */
hratio = hadj->value / (hadj->upper - hadj->page_size);
vratio = vadj->value / (vadj->upper - vadj->page_size);
/* Ask the current widget size */
gtk_widget_get_size_request(gmap->area, &width, &height);
/* Zoom in or out by increasing or decreasing widget size */
switch(event->direction) {
case GDK_SCROLL_UP:
width *= 1.1;
height *= 1.1;
break;
case GDK_SCROLL_DOWN:
if(width >= MAP_WIDTH && height >= MAP_HEIGHT) {
width /= 1.1;
height /= 1.1;
}
break;
}
/* Recalculate the adjustment values */
hadj->upper = width;
vadj->upper = height;
hadj->value = hratio * (hadj->upper - hadj->page_size);
vadj->value = vratio * (vadj->upper - vadj->page_size);
hadj->value = isnan(hadj->value) ? 0.0 : hadj->value;
vadj->value = isnan(vadj->value) ? 0.0 : vadj->value;
/* Resize the widget size */
gtk_widget_set_size_request(gmap->area, width, height);
/* Change the adjustments of the scroll bars */
g_signal_emit_by_name(hadj, "value_changed");
g_signal_emit_by_name(vadj, "value_changed");
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]