[gtk+/rendering-cleanup-next] API: Add gtk_widget_get_transform_to_window()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/rendering-cleanup-next] API: Add gtk_widget_get_transform_to_window()
- Date: Wed, 22 Sep 2010 14:12:51 +0000 (UTC)
commit 5ec429c864ca746211893865bebe2b3ba74bacc0
Author: Benjamin Otte <otte redhat com>
Date: Wed Sep 22 16:10:45 2010 +0200
API: Add gtk_widget_get_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.
docs/reference/gtk/gtk3-sections.txt | 1 +
gtk/gtk.symbols | 1 +
gtk/gtkwidget.c | 99 +++++++++++++++++++++++++---------
gtk/gtkwidget.h | 3 +
4 files changed, 79 insertions(+), 25 deletions(-)
---
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index 918bcd8..cfbac8a 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -4897,6 +4897,7 @@ gtk_widget_set_has_tooltip
gtk_widget_trigger_tooltip_query
gtk_widget_get_window
gtk_cairo_should_draw_window
+gtk_widget_get_transform_to_window
gtk_widget_get_allocated_width
gtk_widget_get_allocated_height
gtk_widget_get_allocation
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index 8039e0c..14ba8e1 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_widget_get_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 5afd974..e52239c 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4519,6 +4519,70 @@ gtk_widget_translate_coordinates (GtkWidget *src_widget,
return TRUE;
}
+/**
+ * gtk_widget_get_transform_to_window:
+ * @widget: the widget to translate from
+ * @window: the window to translate to
+ * @matrix: (out): location to take the return matrix.
+ *
+ * Computes the transformation to be applied for transforming the
+ * coordinate space of @widget to the coordinate space of @window.
+ *
+ * Gtk applies the inverse of this function when preparing a
+ * #GdkExposeEvent to be emitted with GtkWidget::draw. So this
+ * function is useful to reverse this transformation and work in
+ * the @window's coordinate space as was the case with GTK 2.
+ *
+ * If the @widget's window is not an ancestor of @window, @matrix
+ * will be set to the identity matrix and %FALSE will be returned.
+ *
+ * Returns: %TRUE if a tranformation was set.
+ **/
+gboolean
+gtk_widget_get_transform_to_window (GtkWidget *widget,
+ GdkWindow *window,
+ cairo_matrix_t *matrix)
+{
+ GdkWindow *w, *widget_window;
+ int x, y;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+ g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+ g_return_val_if_fail (matrix != NULL, FALSE);
+
+ 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)
+ {
+ cairo_matrix_init_translate (matrix, x, y);
+ return TRUE;
+ }
+ else
+ {
+ cairo_matrix_init_identity (matrix);
+ return FALSE;
+ }
+}
+
static void
gtk_widget_real_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
@@ -5266,10 +5330,10 @@ gint
gtk_widget_send_expose (GtkWidget *widget,
GdkEvent *event)
{
- GdkWindow *window, *w;
gboolean result = FALSE;
+ cairo_matrix_t matrix;
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);
@@ -5282,32 +5346,17 @@ gtk_widget_send_expose (GtkWidget *widget,
gdk_cairo_region (cr, event->expose.region);
cairo_clip (cr);
- if (!gtk_widget_get_has_window (widget))
+ do_clip = gtk_widget_get_transform_to_window (widget,
+ event->expose.window,
+ &matrix);
+ /* matrix is just a translation so must be invertible */
+ if (cairo_matrix_invert (&matrix) != CAIRO_STATUS_SUCCESS)
{
- x = widget->priv->allocation.x;
- y = widget->priv->allocation.y;
+ g_assert_not_reached ();
}
- 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);
+ cairo_transform (cr, &matrix);
- _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 d154985..cb326df 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -807,6 +807,9 @@ gboolean gtk_widget_translate_coordinates (GtkWidget *src_widget,
gint src_y,
gint *dest_x,
gint *dest_y);
+gboolean gtk_widget_get_transform_to_window (GtkWidget *widget,
+ GdkWindow *window,
+ cairo_matrix_t *matrix);
/* Hide widget and return TRUE.
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]