role: fix name for ATK_ROLE_EDITBAR
[atk.git] / atk / atkcomponent.c
blob9a574c723f2280a808926e6d0b47c10fcbabbf61
1 /* ATK - Accessibility Toolkit
2 * Copyright 2001 Sun Microsystems Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 #include "atkcomponent.h"
23 /**
24 * SECTION:atkcomponent
25 * @Short_description: The ATK interface provided by UI components
26 * which occupy a physical area on the screen.
27 * which the user can activate/interact with.
28 * @Title:AtkComponent
30 * #AtkComponent should be implemented by most if not all UI elements
31 * with an actual on-screen presence, i.e. components which can be
32 * said to have a screen-coordinate bounding box. Virtually all
33 * widgets will need to have #AtkComponent implementations provided
34 * for their corresponding #AtkObject class. In short, only UI
35 * elements which are *not* GUI elements will omit this ATK interface.
37 * A possible exception might be textual information with a
38 * transparent background, in which case text glyph bounding box
39 * information is provided by #AtkText.
42 enum {
43 BOUNDS_CHANGED,
44 LAST_SIGNAL
47 static void atk_component_base_init (AtkComponentIface *class);
49 static gboolean atk_component_real_contains (AtkComponent *component,
50 gint x,
51 gint y,
52 AtkCoordType coord_type);
54 static AtkObject* atk_component_real_ref_accessible_at_point (AtkComponent *component,
55 gint x,
56 gint y,
57 AtkCoordType coord_type);
59 static void atk_component_real_get_position (AtkComponent *component,
60 gint *x,
61 gint *y,
62 AtkCoordType coord_type);
64 static void atk_component_real_get_size (AtkComponent *component,
65 gint *width,
66 gint *height);
68 static guint atk_component_signals[LAST_SIGNAL] = { 0 };
70 GType
71 atk_component_get_type (void)
73 static GType type = 0;
75 if (!type) {
76 static const GTypeInfo tinfo =
78 sizeof (AtkComponentIface),
79 (GBaseInitFunc) atk_component_base_init,
80 (GBaseFinalizeFunc) NULL,
84 type = g_type_register_static (G_TYPE_INTERFACE, "AtkComponent", &tinfo, 0);
87 return type;
90 static void
91 atk_component_base_init (AtkComponentIface *class)
93 static gboolean initialized = FALSE;
95 if (! initialized)
97 class->ref_accessible_at_point = atk_component_real_ref_accessible_at_point;
98 class->contains = atk_component_real_contains;
99 class->get_position = atk_component_real_get_position;
100 class->get_size = atk_component_real_get_size;
104 * AtkComponent::bounds-changed:
105 * @atkcomponent: the object which received the signal.
106 * @arg1: The AtkRectangle giving the new position and size.
108 * The 'bounds-changed" signal is emitted when the bposition or
109 * size of the component changes.
111 atk_component_signals[BOUNDS_CHANGED] =
112 g_signal_new ("bounds_changed",
113 ATK_TYPE_COMPONENT,
114 G_SIGNAL_RUN_LAST,
115 G_STRUCT_OFFSET (AtkComponentIface, bounds_changed),
116 (GSignalAccumulator) NULL, NULL,
117 g_cclosure_marshal_VOID__BOXED,
118 G_TYPE_NONE, 1,
119 ATK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
121 initialized = TRUE;
127 * atk_component_add_focus_handler:
128 * @component: The #AtkComponent to attach the @handler to
129 * @handler: The #AtkFocusHandler to be attached to @component
131 * Add the specified handler to the set of functions to be called
132 * when this object receives focus events (in or out). If the handler is
133 * already added it is not added again
135 * Deprecated: This method is deprecated since ATK version 2.9.4. If
136 * you need to track when an object gains or lose the focus, use
137 * state-changed:focused notification instead.
139 * Returns: a handler id which can be used in atk_component_remove_focus_handler()
140 * or zero if the handler was already added.
142 guint
143 atk_component_add_focus_handler (AtkComponent *component,
144 AtkFocusHandler handler)
146 AtkComponentIface *iface = NULL;
147 g_return_val_if_fail (ATK_IS_COMPONENT (component), 0);
149 iface = ATK_COMPONENT_GET_IFACE (component);
151 if (iface->add_focus_handler)
152 return (iface->add_focus_handler) (component, handler);
153 else
154 return 0;
158 * atk_component_remove_focus_handler:
159 * @component: the #AtkComponent to remove the focus handler from
160 * @handler_id: the handler id of the focus handler to be removed
161 * from @component
163 * Remove the handler specified by @handler_id from the list of
164 * functions to be executed when this object receives focus events
165 * (in or out).
167 * Deprecated: This method is deprecated since ATK version 2.9.4. If
168 * you need to track when an object gains or lose the focus, use
169 * state-changed:focused notification instead.
172 void
173 atk_component_remove_focus_handler (AtkComponent *component,
174 guint handler_id)
176 AtkComponentIface *iface = NULL;
177 g_return_if_fail (ATK_IS_COMPONENT (component));
179 iface = ATK_COMPONENT_GET_IFACE (component);
181 if (iface->remove_focus_handler)
182 (iface->remove_focus_handler) (component, handler_id);
186 * atk_component_contains:
187 * @component: the #AtkComponent
188 * @x: x coordinate
189 * @y: y coordinate
190 * @coord_type: specifies whether the coordinates are relative to the screen
191 * or to the components top level window
193 * Checks whether the specified point is within the extent of the @component.
195 * Returns: %TRUE or %FALSE indicating whether the specified point is within
196 * the extent of the @component or not
198 gboolean
199 atk_component_contains (AtkComponent *component,
200 gint x,
201 gint y,
202 AtkCoordType coord_type)
204 AtkComponentIface *iface = NULL;
205 g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
207 iface = ATK_COMPONENT_GET_IFACE (component);
209 if (iface->contains)
210 return (iface->contains) (component, x, y, coord_type);
211 else
212 return FALSE;
216 * atk_component_ref_accessible_at_point:
217 * @component: the #AtkComponent
218 * @x: x coordinate
219 * @y: y coordinate
220 * @coord_type: specifies whether the coordinates are relative to the screen
221 * or to the components top level window
223 * Gets a reference to the accessible child, if one exists, at the
224 * coordinate point specified by @x and @y.
226 * Returns: (transfer full): a reference to the accessible child, if one exists
228 AtkObject*
229 atk_component_ref_accessible_at_point (AtkComponent *component,
230 gint x,
231 gint y,
232 AtkCoordType coord_type)
234 AtkComponentIface *iface = NULL;
235 g_return_val_if_fail (ATK_IS_COMPONENT (component), NULL);
237 iface = ATK_COMPONENT_GET_IFACE (component);
239 if (iface->ref_accessible_at_point)
240 return (iface->ref_accessible_at_point) (component, x, y, coord_type);
241 else
242 return NULL;
246 * atk_component_get_extents:
247 * @component: an #AtkComponent
248 * @x: address of #gint to put x coordinate
249 * @y: address of #gint to put y coordinate
250 * @width: address of #gint to put width
251 * @height: address of #gint to put height
252 * @coord_type: specifies whether the coordinates are relative to the screen
253 * or to the components top level window
255 * Gets the rectangle which gives the extent of the @component.
258 void
259 atk_component_get_extents (AtkComponent *component,
260 gint *x,
261 gint *y,
262 gint *width,
263 gint *height,
264 AtkCoordType coord_type)
266 AtkComponentIface *iface = NULL;
267 gint local_x, local_y, local_width, local_height;
268 gint *real_x, *real_y, *real_width, *real_height;
270 g_return_if_fail (ATK_IS_COMPONENT (component));
272 if (x)
273 real_x = x;
274 else
275 real_x = &local_x;
276 if (y)
277 real_y = y;
278 else
279 real_y = &local_y;
280 if (width)
281 real_width = width;
282 else
283 real_width = &local_width;
284 if (height)
285 real_height = height;
286 else
287 real_height = &local_height;
289 iface = ATK_COMPONENT_GET_IFACE (component);
291 if (iface->get_extents)
292 (iface->get_extents) (component, real_x, real_y, real_width, real_height, coord_type);
296 * atk_component_get_position:
297 * @component: an #AtkComponent
298 * @x: address of #gint to put x coordinate position
299 * @y: address of #gint to put y coordinate position
300 * @coord_type: specifies whether the coordinates are relative to the screen
301 * or to the components top level window
303 * Gets the position of @component in the form of
304 * a point specifying @component's top-left corner.
306 void
307 atk_component_get_position (AtkComponent *component,
308 gint *x,
309 gint *y,
310 AtkCoordType coord_type)
312 AtkComponentIface *iface = NULL;
313 gint local_x, local_y;
314 gint *real_x, *real_y;
316 g_return_if_fail (ATK_IS_COMPONENT (component));
318 if (x)
319 real_x = x;
320 else
321 real_x = &local_x;
322 if (y)
323 real_y = y;
324 else
325 real_y = &local_y;
327 iface = ATK_COMPONENT_GET_IFACE (component);
329 if (iface->get_position)
330 (iface->get_position) (component, real_x, real_y, coord_type);
334 * atk_component_get_size:
335 * @component: an #AtkComponent
336 * @width: address of #gint to put width of @component
337 * @height: address of #gint to put height of @component
339 * Gets the size of the @component in terms of width and height.
341 void
342 atk_component_get_size (AtkComponent *component,
343 gint *width,
344 gint *height)
346 AtkComponentIface *iface = NULL;
347 gint local_width, local_height;
348 gint *real_width, *real_height;
350 g_return_if_fail (ATK_IS_COMPONENT (component));
352 if (width)
353 real_width = width;
354 else
355 real_width = &local_width;
356 if (height)
357 real_height = height;
358 else
359 real_height = &local_height;
361 g_return_if_fail (ATK_IS_COMPONENT (component));
363 iface = ATK_COMPONENT_GET_IFACE (component);
365 if (iface->get_size)
366 (iface->get_size) (component, real_width, real_height);
370 * atk_component_get_layer:
371 * @component: an #AtkComponent
373 * Gets the layer of the component.
375 * Returns: an #AtkLayer which is the layer of the component
377 AtkLayer
378 atk_component_get_layer (AtkComponent *component)
380 AtkComponentIface *iface;
382 g_return_val_if_fail (ATK_IS_COMPONENT (component), ATK_LAYER_INVALID);
384 iface = ATK_COMPONENT_GET_IFACE (component);
385 if (iface->get_layer)
386 return (iface->get_layer) (component);
387 else
388 return ATK_LAYER_WIDGET;
392 * atk_component_get_mdi_zorder:
393 * @component: an #AtkComponent
395 * Gets the zorder of the component. The value G_MININT will be returned
396 * if the layer of the component is not ATK_LAYER_MDI or ATK_LAYER_WINDOW.
398 * Returns: a gint which is the zorder of the component, i.e. the depth at
399 * which the component is shown in relation to other components in the same
400 * container.
402 gint
403 atk_component_get_mdi_zorder (AtkComponent *component)
405 AtkComponentIface *iface;
407 g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
409 iface = ATK_COMPONENT_GET_IFACE (component);
410 if (iface->get_mdi_zorder)
411 return (iface->get_mdi_zorder) (component);
412 else
413 return G_MININT;
417 * atk_component_get_alpha:
418 * @component: an #AtkComponent
420 * Returns the alpha value (i.e. the opacity) for this
421 * @component, on a scale from 0 (fully transparent) to 1.0
422 * (fully opaque).
424 * Returns: An alpha value from 0 to 1.0, inclusive.
425 * Since: 1.12
427 gdouble
428 atk_component_get_alpha (AtkComponent *component)
430 AtkComponentIface *iface;
432 g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
434 iface = ATK_COMPONENT_GET_IFACE (component);
435 if (iface->get_alpha)
436 return (iface->get_alpha) (component);
437 else
438 return (gdouble) 1.0;
442 * atk_component_grab_focus:
443 * @component: an #AtkComponent
445 * Grabs focus for this @component.
447 * Returns: %TRUE if successful, %FALSE otherwise.
449 gboolean
450 atk_component_grab_focus (AtkComponent *component)
452 AtkComponentIface *iface = NULL;
453 g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
455 iface = ATK_COMPONENT_GET_IFACE (component);
457 if (iface->grab_focus)
458 return (iface->grab_focus) (component);
459 else
460 return FALSE;
464 * atk_component_set_extents:
465 * @component: an #AtkComponent
466 * @x: x coordinate
467 * @y: y coordinate
468 * @width: width to set for @component
469 * @height: height to set for @component
470 * @coord_type: specifies whether the coordinates are relative to the screen
471 * or to the components top level window
473 * Sets the extents of @component.
475 * Returns: %TRUE or %FALSE whether the extents were set or not
477 gboolean
478 atk_component_set_extents (AtkComponent *component,
479 gint x,
480 gint y,
481 gint width,
482 gint height,
483 AtkCoordType coord_type)
485 AtkComponentIface *iface = NULL;
486 g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
488 iface = ATK_COMPONENT_GET_IFACE (component);
490 if (iface->set_extents)
491 return (iface->set_extents) (component, x, y, width, height, coord_type);
492 else
493 return FALSE;
497 * atk_component_set_position:
498 * @component: an #AtkComponent
499 * @x: x coordinate
500 * @y: y coordinate
501 * @coord_type: specifies whether the coordinates are relative to the screen
502 * or to the components top level window
504 * Sets the postition of @component.
506 * Returns: %TRUE or %FALSE whether or not the position was set or not
508 gboolean
509 atk_component_set_position (AtkComponent *component,
510 gint x,
511 gint y,
512 AtkCoordType coord_type)
514 AtkComponentIface *iface = NULL;
515 g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
517 iface = ATK_COMPONENT_GET_IFACE (component);
519 if (iface->set_position)
520 return (iface->set_position) (component, x, y, coord_type);
521 else
522 return FALSE;
526 * atk_component_set_size:
527 * @component: an #AtkComponent
528 * @width: width to set for @component
529 * @height: height to set for @component
531 * Set the size of the @component in terms of width and height.
533 * Returns: %TRUE or %FALSE whether the size was set or not
535 gboolean
536 atk_component_set_size (AtkComponent *component,
537 gint x,
538 gint y)
540 AtkComponentIface *iface = NULL;
541 g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
543 iface = ATK_COMPONENT_GET_IFACE (component);
545 if (iface->set_size)
546 return (iface->set_size) (component, x, y);
547 else
548 return FALSE;
551 static gboolean
552 atk_component_real_contains (AtkComponent *component,
553 gint x,
554 gint y,
555 AtkCoordType coord_type)
557 gint real_x, real_y, width, height;
559 real_x = real_y = width = height = 0;
561 atk_component_get_extents (component, &real_x, &real_y, &width, &height, coord_type);
563 if ((x >= real_x) &&
564 (x < real_x + width) &&
565 (y >= real_y) &&
566 (y < real_y + height))
567 return TRUE;
568 else
569 return FALSE;
572 static AtkObject*
573 atk_component_real_ref_accessible_at_point (AtkComponent *component,
574 gint x,
575 gint y,
576 AtkCoordType coord_type)
578 gint count, i;
580 count = atk_object_get_n_accessible_children (ATK_OBJECT (component));
582 for (i = 0; i < count; i++)
584 AtkObject *obj;
586 obj = atk_object_ref_accessible_child (ATK_OBJECT (component), i);
588 if (obj != NULL)
590 if (atk_component_contains (ATK_COMPONENT (obj), x, y, coord_type))
592 return obj;
594 else
596 g_object_unref (obj);
600 return NULL;
603 static void
604 atk_component_real_get_position (AtkComponent *component,
605 gint *x,
606 gint *y,
607 AtkCoordType coord_type)
609 gint width, height;
611 atk_component_get_extents (component, x, y, &width, &height, coord_type);
614 static void
615 atk_component_real_get_size (AtkComponent *component,
616 gint *width,
617 gint *height)
619 gint x, y;
620 AtkCoordType coord_type;
623 * Pick one coordinate type; it does not matter for size
625 coord_type = ATK_XY_WINDOW;
627 atk_component_get_extents (component, &x, &y, width, height, coord_type);
630 static AtkRectangle *
631 atk_rectangle_copy (const AtkRectangle *rectangle)
633 AtkRectangle *result = g_new (AtkRectangle, 1);
634 *result = *rectangle;
636 return result;
639 GType
640 atk_rectangle_get_type (void)
642 static GType our_type = 0;
644 if (our_type == 0)
645 our_type = g_boxed_type_register_static ("AtkRectangle",
646 (GBoxedCopyFunc)atk_rectangle_copy,
647 (GBoxedFreeFunc)g_free);
648 return our_type;