diff options
author | Benjamin Otte <otte@redhat.com> | 2010-09-22 16:10:45 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2010-09-26 15:11:45 +0200 |
commit | 0795f1e0c9e678b13d6a6fb6dd9641480b5559c3 (patch) | |
tree | 5dd9a821514651b91b39cb31852535d9457fa9d0 /gtk | |
parent | e66129015de47d21006ff03f82964a77fdf7ca3d (diff) | |
download | gtk+-0795f1e0c9e678b13d6a6fb6dd9641480b5559c3.tar.gz |
API: Add gtk_cairo_transform_to_window()
The function reverses the transform that GTK does before emitting a draw
event. So we can use it in "old" widgets to revert the coordinate system
properly.
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtk.symbols | 1 | ||||
-rw-r--r-- | gtk/gtkwidget.c | 103 | ||||
-rw-r--r-- | gtk/gtkwidget.h | 3 |
3 files changed, 81 insertions, 26 deletions
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 6730ce993b..b9cb161639 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -4237,6 +4237,7 @@ gtk_widget_get_tooltip_markup gtk_widget_get_tooltip_text gtk_widget_get_tooltip_window gtk_widget_get_toplevel +gtk_cairo_transform_to_window gtk_widget_get_type G_GNUC_CONST gtk_widget_get_visible gtk_widget_get_visual diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 15f52143af..2b614a0295 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -5246,6 +5246,77 @@ gtk_widget_event (GtkWidget *widget, return gtk_widget_event_internal (widget, event); } +/* Returns TRUE if a translation should be done */ +static gboolean +gtk_widget_get_translation_to_window (GtkWidget *widget, + GdkWindow *window, + int *x, + int *y) +{ + GdkWindow *w, *widget_window; + + if (!gtk_widget_get_has_window (widget)) + { + *x = -widget->priv->allocation.x; + *y = -widget->priv->allocation.y; + } + else + { + *x = 0; + *y = 0; + } + + widget_window = gtk_widget_get_window (widget); + + for (w = window; w && w != widget_window; w = gdk_window_get_parent (w)) + { + int wx, wy; + gdk_window_get_position (w, &wx, &wy); + *x += wx; + *y += wy; + } + + if (w == NULL) + { + *x = 0; + *y = 0; + return FALSE; + } + + return TRUE; +} + + +/** + * gtk_cairo_transform_to_window: + * @cr: the cairo context to transform + * @widget: the widget the context is currently centered for + * @window: the window to transform the context to + * + * Transforms the given cairo context @cr that from @widget-relative + * coordinates to @window-relative coordinates. + * If the @widget's window is not an ancestor of @window, no + * modification will be applied. + * + * This is the inverse to the transformation GTK applies when + * preparing an expose event to be emitted with the GtkWidget::draw + * signal. It is intended to help porting multiwindow widgets from + * GTK 2 to the rendering architecture of GTK 3. + **/ +void +gtk_cairo_transform_to_window (cairo_t *cr, + GtkWidget *widget, + GdkWindow *window) +{ + int x, y; + + g_return_if_fail (cr != NULL); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (gtk_widget_get_translation_to_window (widget, window, &x, &y)) + cairo_translate (cr, x, y); +} /** * gtk_widget_send_expose: @@ -5270,10 +5341,10 @@ gint gtk_widget_send_expose (GtkWidget *widget, GdkEvent *event) { - GdkWindow *window, *w; gboolean result = FALSE; cairo_t *cr; int x, y; + gboolean do_clip; g_return_val_if_fail (GTK_IS_WIDGET (widget), TRUE); g_return_val_if_fail (gtk_widget_get_realized (widget), TRUE); @@ -5286,32 +5357,12 @@ gtk_widget_send_expose (GtkWidget *widget, gdk_cairo_region (cr, event->expose.region); cairo_clip (cr); - if (!gtk_widget_get_has_window (widget)) - { - x = widget->priv->allocation.x; - y = widget->priv->allocation.y; - } - else - { - x = 0; - y = 0; - } - - /* translate cairo context properly */ - window = gtk_widget_get_window (widget); - - for (w = event->expose.window; w && w != window; w = gdk_window_get_parent (w)) - { - int wx, wy; - gdk_window_get_position (w, &wx, &wy); - x -= wx; - y -= wy; - } - - if (w) - cairo_translate (cr, x, y); + do_clip = gtk_widget_get_translation_to_window (widget, + event->expose.window, + &x, &y); + cairo_translate (cr, -x, -y); - _gtk_widget_draw_internal (widget, cr, w != NULL); + _gtk_widget_draw_internal (widget, cr, do_clip); /* unset here, so if someone keeps a reference to cr we * don't leak the window. */ diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 3376466923..03fa0f4d9d 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -979,6 +979,9 @@ gboolean gtk_widget_get_has_tooltip (GtkWidget *widget); gboolean gtk_cairo_should_draw_window (cairo_t *cr, GdkWindow *window); +void gtk_cairo_transform_to_window (cairo_t *cr, + GtkWidget *widget, + GdkWindow *window); GType gtk_requisition_get_type (void) G_GNUC_CONST; GtkRequisition *gtk_requisition_new (void) G_GNUC_MALLOC; |