mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 14:31:10 +00:00
widget: Fix gtk_widget_pick() on 3d-transformed widgets
Picking is done by drawing a line along the parent's z axis and picking at the intersection with the child's z=0 plane. However, the previous code was casting a ray along the child's z axis. This patch actually transforms the line to pick into the target's coordinate system and then computes the corrrect intersection with the z=0 plane. Using graphene_point3d_interpolate() to compute the final intersection point is a bit of abuse of that function, but I found no better way in Graphene to achieve the same thing.
This commit is contained in:
parent
8ceff21497
commit
bed4c68041
@ -822,13 +822,20 @@ gtk_widget_real_pick (GtkWidget *widget,
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (child);
|
||||
graphene_matrix_t inv;
|
||||
GtkWidget *picked;
|
||||
graphene_point_t p;
|
||||
graphene_point3d_t p0, p1, res;
|
||||
|
||||
graphene_matrix_inverse (&priv->transform, &inv);
|
||||
graphene_point_init (&p, x, y);
|
||||
graphene_matrix_transform_point (&inv, &p, &p);
|
||||
if (!graphene_matrix_inverse (&priv->transform, &inv))
|
||||
continue;
|
||||
graphene_point3d_init (&p0, x, y, 0);
|
||||
graphene_point3d_init (&p1, x, y, 1);
|
||||
graphene_matrix_transform_point3d (&inv, &p0, &p0);
|
||||
graphene_matrix_transform_point3d (&inv, &p1, &p1);
|
||||
if (fabs (p0.z - p1.z) < 1.f / 4096)
|
||||
continue;
|
||||
|
||||
picked = gtk_widget_pick (child, p.x, p.y);
|
||||
graphene_point3d_interpolate (&p0, &p1, p0.z / (p0.z - p1.z), &res);
|
||||
|
||||
picked = gtk_widget_pick (child, res.x, res.y);
|
||||
if (picked)
|
||||
return picked;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user