widget: Add gtk_widget_compute_transform
This commit is contained in:
committed by
Benjamin Otte
parent
4529f52c02
commit
dbf0654e5b
@@ -4541,6 +4541,7 @@ gtk_widget_get_allocated_size
|
||||
gtk_widget_get_width
|
||||
gtk_widget_get_height
|
||||
gtk_widget_compute_bounds
|
||||
gtk_widget_compute_transform
|
||||
gtk_widget_contains
|
||||
gtk_widget_pick
|
||||
gtk_widget_get_can_default
|
||||
|
||||
128
gtk/gtkwidget.c
128
gtk/gtkwidget.c
@@ -820,11 +820,11 @@ gtk_widget_real_pick (GtkWidget *widget,
|
||||
child = _gtk_widget_get_prev_sibling (child))
|
||||
{
|
||||
GtkWidget *picked;
|
||||
int dx, dy;
|
||||
double dx, dy;
|
||||
|
||||
gtk_widget_get_origin_relative_to_parent (child, &dx, &dy);
|
||||
gtk_widget_translate_coordinatesf (widget, child, x, y, &dx, &dy);
|
||||
|
||||
picked = gtk_widget_pick (child, x - dx, y - dy);
|
||||
picked = gtk_widget_pick (child, dx, dy);
|
||||
if (picked)
|
||||
return picked;
|
||||
}
|
||||
@@ -4507,54 +4507,31 @@ gtk_widget_translate_coordinatesf (GtkWidget *src_widget,
|
||||
double *dest_x,
|
||||
double *dest_y)
|
||||
{
|
||||
GtkWidget *ancestor;
|
||||
GtkWidget *parent;
|
||||
graphene_matrix_t transform;
|
||||
graphene_point_t p;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (src_widget), FALSE);
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (dest_widget), FALSE);
|
||||
|
||||
ancestor = gtk_widget_common_ancestor (src_widget, dest_widget);
|
||||
if (!ancestor)
|
||||
if (!gtk_widget_compute_transform (src_widget, dest_widget, &transform))
|
||||
{
|
||||
if (dest_x)
|
||||
*dest_x = 0;
|
||||
|
||||
if (dest_y)
|
||||
*dest_y = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
parent = src_widget;
|
||||
while (parent != ancestor)
|
||||
{
|
||||
int origin_x, origin_y;
|
||||
|
||||
gtk_widget_get_origin_relative_to_parent (parent, &origin_x, &origin_y);
|
||||
|
||||
src_x += origin_x;
|
||||
src_y += origin_y;
|
||||
|
||||
parent = _gtk_widget_get_parent (parent);
|
||||
}
|
||||
|
||||
parent = dest_widget;
|
||||
while (parent != ancestor)
|
||||
{
|
||||
int origin_x, origin_y;
|
||||
|
||||
gtk_widget_get_origin_relative_to_parent (parent, &origin_x, &origin_y);
|
||||
|
||||
src_x -= origin_x;
|
||||
src_y -= origin_y;
|
||||
|
||||
parent = _gtk_widget_get_parent (parent);
|
||||
}
|
||||
graphene_point_init (&p, src_x, src_y);
|
||||
graphene_matrix_transform_point (&transform, &p, &p);
|
||||
|
||||
if (dest_x)
|
||||
*dest_x = src_x;
|
||||
*dest_x = p.x;
|
||||
|
||||
if (dest_y)
|
||||
*dest_y = src_y;
|
||||
*dest_y = p.y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -11300,6 +11277,74 @@ gtk_widget_pick (GtkWidget *widget,
|
||||
return GTK_WIDGET_GET_CLASS (widget)->pick (widget, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_compute_transform:
|
||||
* @widget: a #GtkWidget
|
||||
* @target: the target widget that the matrix will transform to
|
||||
* @out_transform: (out caller-allocates): location to
|
||||
* store the final transformation
|
||||
*
|
||||
* Computes a matrix suitable to describe a transformation from
|
||||
* @widget's coordinate system into @target's coordinate system.
|
||||
*
|
||||
* Returns: %TRUE if the transform could be computed, %FALSE otherwise.
|
||||
* The transform can not be computed in certain cases, for example when
|
||||
* @widget and @target do not share a common ancestor.
|
||||
*/
|
||||
gboolean
|
||||
gtk_widget_compute_transform (GtkWidget *widget,
|
||||
GtkWidget *target,
|
||||
graphene_matrix_t *out_transform)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
GtkWidget *ancestor;
|
||||
graphene_matrix_t transform;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (target), FALSE);
|
||||
g_return_val_if_fail (out_transform != NULL, FALSE);
|
||||
|
||||
ancestor = gtk_widget_common_ancestor (widget, target);
|
||||
|
||||
if (!ancestor)
|
||||
return FALSE;
|
||||
|
||||
graphene_matrix_init_identity (&transform);
|
||||
parent = widget;
|
||||
while (parent != ancestor)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (parent);
|
||||
|
||||
graphene_matrix_multiply (&transform, &priv->transform, &transform);
|
||||
|
||||
parent = priv->parent;
|
||||
}
|
||||
|
||||
g_assert (parent == ancestor);
|
||||
|
||||
{
|
||||
graphene_matrix_t down_transform;
|
||||
graphene_matrix_t inv;
|
||||
|
||||
graphene_matrix_init_identity (&down_transform);
|
||||
|
||||
while (parent != ancestor)
|
||||
{
|
||||
graphene_matrix_multiply (&down_transform, &parent->priv->transform, &down_transform);
|
||||
parent = parent->priv->parent;
|
||||
}
|
||||
|
||||
graphene_matrix_inverse (&down_transform, &inv);
|
||||
|
||||
graphene_matrix_multiply (&transform, &inv, &transform);
|
||||
}
|
||||
|
||||
|
||||
*out_transform = transform;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_compute_bounds:
|
||||
* @widget: the #GtkWidget to query
|
||||
@@ -11323,26 +11368,23 @@ gtk_widget_compute_bounds (GtkWidget *widget,
|
||||
GtkWidget *target,
|
||||
graphene_rect_t *out_bounds)
|
||||
{
|
||||
graphene_matrix_t transform;
|
||||
GtkCssBoxes boxes;
|
||||
int x, y;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (target), FALSE);
|
||||
g_return_val_if_fail (out_bounds != NULL, FALSE);
|
||||
|
||||
if (!gtk_widget_translate_coordinates (widget,
|
||||
target,
|
||||
0, 0,
|
||||
&x, &y))
|
||||
if (!gtk_widget_compute_transform (widget, target, &transform))
|
||||
{
|
||||
graphene_rect_init_from_rect (out_bounds, graphene_rect_zero ());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_css_boxes_init (&boxes, widget);
|
||||
graphene_rect_offset_r (gtk_css_boxes_get_border_rect (&boxes),
|
||||
x, y,
|
||||
out_bounds);
|
||||
graphene_matrix_transform_bounds (&transform,
|
||||
gtk_css_boxes_get_border_rect (&boxes),
|
||||
out_bounds);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -614,6 +614,10 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_get_allocation (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_compute_transform (GtkWidget *widget,
|
||||
GtkWidget *target,
|
||||
graphene_matrix_t *out_transform);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_compute_bounds (GtkWidget *widget,
|
||||
GtkWidget *target,
|
||||
graphene_rect_t *out_bounds);
|
||||
|
||||
Reference in New Issue
Block a user