forked from AuroraMiddleware/gtk
GtkWidget: Add ::pick vmethod
The default implementation iterates through all children, so should suffice for most widgets.
This commit is contained in:
parent
fee289cd06
commit
9c97bf0c02
@ -947,6 +947,78 @@ gtk_widget_real_snapshot (GtkWidget *widget,
|
|||||||
/* nothing to do here */
|
/* nothing to do here */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
transform_to_child_coords (GtkWidget *widget,
|
||||||
|
GtkWidget *child,
|
||||||
|
gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
gdouble *x_out,
|
||||||
|
gdouble *y_out)
|
||||||
|
{
|
||||||
|
GtkAllocation alloc, child_alloc;
|
||||||
|
GdkWindow *window;
|
||||||
|
gdouble dx = 0, dy = 0;
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (widget, &alloc);
|
||||||
|
gtk_widget_get_allocation (child, &child_alloc);
|
||||||
|
|
||||||
|
child_alloc.x -= alloc.x;
|
||||||
|
child_alloc.y -= alloc.y;
|
||||||
|
|
||||||
|
window = _gtk_widget_get_window (child);
|
||||||
|
|
||||||
|
while (window != _gtk_widget_get_window (widget))
|
||||||
|
{
|
||||||
|
gdk_window_coords_to_parent (window, dx, dy, &dx, &dy);
|
||||||
|
window = gdk_window_get_parent (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
*x_out = x - child_alloc.x - dx;
|
||||||
|
*y_out = y - child_alloc.y - dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkWidget *
|
||||||
|
gtk_widget_real_pick (GtkWidget *widget,
|
||||||
|
gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
gdouble *x_out,
|
||||||
|
gdouble *y_out)
|
||||||
|
{
|
||||||
|
GtkAllocation allocation, parent_allocation;
|
||||||
|
GtkWidget *child;
|
||||||
|
|
||||||
|
gtk_widget_get_allocation (widget, &parent_allocation);
|
||||||
|
|
||||||
|
for (child = _gtk_widget_get_last_child (widget);
|
||||||
|
child;
|
||||||
|
child = _gtk_widget_get_prev_sibling (child))
|
||||||
|
{
|
||||||
|
gdouble tx = x, ty = y;
|
||||||
|
|
||||||
|
if (!gtk_widget_is_sensitive (child) ||
|
||||||
|
!gtk_widget_is_drawable (child))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
transform_to_child_coords (widget, child, tx, ty, &tx, &ty);
|
||||||
|
_gtk_widget_get_allocation (child, &allocation);
|
||||||
|
allocation.x = 0;
|
||||||
|
allocation.y = 0;
|
||||||
|
|
||||||
|
if (gdk_rectangle_contains_point (&allocation, tx, ty))
|
||||||
|
{
|
||||||
|
if (x_out && y_out)
|
||||||
|
{
|
||||||
|
*x_out = tx;
|
||||||
|
*y_out = ty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_widget_class_init (GtkWidgetClass *klass)
|
gtk_widget_class_init (GtkWidgetClass *klass)
|
||||||
{
|
{
|
||||||
@ -1061,6 +1133,8 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
|||||||
klass->queue_draw_region = gtk_widget_real_queue_draw_region;
|
klass->queue_draw_region = gtk_widget_real_queue_draw_region;
|
||||||
klass->queue_draw_child = gtk_widget_real_queue_draw_child;
|
klass->queue_draw_child = gtk_widget_real_queue_draw_child;
|
||||||
|
|
||||||
|
klass->pick = gtk_widget_real_pick;
|
||||||
|
|
||||||
widget_props[PROP_NAME] =
|
widget_props[PROP_NAME] =
|
||||||
g_param_spec_string ("name",
|
g_param_spec_string ("name",
|
||||||
P_("Widget name"),
|
P_("Widget name"),
|
||||||
|
@ -480,6 +480,12 @@ struct _GtkWidgetClass
|
|||||||
void (* snapshot) (GtkWidget *widget,
|
void (* snapshot) (GtkWidget *widget,
|
||||||
GtkSnapshot *snapshot);
|
GtkSnapshot *snapshot);
|
||||||
|
|
||||||
|
GtkWidget * (* pick) (GtkWidget *widget,
|
||||||
|
gdouble x,
|
||||||
|
gdouble y,
|
||||||
|
gdouble *x_out,
|
||||||
|
gdouble *y_out);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
|
||||||
GtkWidgetClassPrivate *priv;
|
GtkWidgetClassPrivate *priv;
|
||||||
|
Loading…
Reference in New Issue
Block a user