Release 2.14.0
[atk.git] / atk / atkcomponent.c
blobfc63c9d55056788a0e718123decd0ea9f12ca8d3
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.
20 #include "config.h"
22 #include "atkcomponent.h"
24 /**
25 * SECTION:atkcomponent
26 * @Short_description: The ATK interface provided by UI components
27 * which occupy a physical area on the screen.
28 * which the user can activate/interact with.
29 * @Title:AtkComponent
31 * #AtkComponent should be implemented by most if not all UI elements
32 * with an actual on-screen presence, i.e. components which can be
33 * said to have a screen-coordinate bounding box. Virtually all
34 * widgets will need to have #AtkComponent implementations provided
35 * for their corresponding #AtkObject class. In short, only UI
36 * elements which are *not* GUI elements will omit this ATK interface.
38 * A possible exception might be textual information with a
39 * transparent background, in which case text glyph bounding box
40 * information is provided by #AtkText.
43 enum {
44 BOUNDS_CHANGED,
45 LAST_SIGNAL
48 static void atk_component_base_init (AtkComponentIface *class);
50 static gboolean atk_component_real_contains (AtkComponent *component,
51 gint x,
52 gint y,
53 AtkCoordType coord_type);
55 static AtkObject* atk_component_real_ref_accessible_at_point (AtkComponent *component,
56 gint x,
57 gint y,
58 AtkCoordType coord_type);
60 static void atk_component_real_get_position (AtkComponent *component,
61 gint *x,
62 gint *y,
63 AtkCoordType coord_type);
65 static void atk_component_real_get_size (AtkComponent *component,
66 gint *width,
67 gint *height);
69 static guint atk_component_signals[LAST_SIGNAL] = { 0 };
71 GType
72 atk_component_get_type (void)
74 static GType type = 0;
76 if (!type) {
77 static const GTypeInfo tinfo =
79 sizeof (AtkComponentIface),
80 (GBaseInitFunc) atk_component_base_init,
81 (GBaseFinalizeFunc) NULL,
85 type = g_type_register_static (G_TYPE_INTERFACE, "AtkComponent", &tinfo, 0);
88 return type;
91 static void
92 atk_component_base_init (AtkComponentIface *class)
94 static gboolean initialized = FALSE;
96 if (! initialized)
98 class->ref_accessible_at_point = atk_component_real_ref_accessible_at_point;
99 class->contains = atk_component_real_contains;
100 class->get_position = atk_component_real_get_position;
101 class->get_size = atk_component_real_get_size;
105 * AtkComponent::bounds-changed:
106 * @atkcomponent: the object which received the signal.
107 * @arg1: The AtkRectangle giving the new position and size.
109 * The 'bounds-changed" signal is emitted when the bposition or
110 * size of the component changes.
112 atk_component_signals[BOUNDS_CHANGED] =
113 g_signal_new ("bounds_changed",
114 ATK_TYPE_COMPONENT,
115 G_SIGNAL_RUN_LAST,
116 G_STRUCT_OFFSET (AtkComponentIface, bounds_changed),
117 (GSignalAccumulator) NULL, NULL,
118 g_cclosure_marshal_VOID__BOXED,
119 G_TYPE_NONE, 1,
120 ATK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
122 initialized = TRUE;
128 * atk_component_add_focus_handler:
129 * @component: The #AtkComponent to attach the @handler to
130 * @handler: The #AtkFocusHandler to be attached to @component
132 * Add the specified handler to the set of functions to be called
133 * when this object receives focus events (in or out). If the handler is
134 * already added it is not added again
136 * Deprecated: This method is deprecated since ATK version 2.9.4. If
137 * you need to track when an object gains or lose the focus, use
138 * state-changed:focused notification instead.
140 * Returns: a handler id which can be used in atk_component_remove_focus_handler()
141 * or zero if the handler was already added.
143 guint
144 atk_component_add_focus_handler (AtkComponent *component,
145 AtkFocusHandler handler)
147 AtkComponentIface *iface = NULL;
148 g_return_val_if_fail (ATK_IS_COMPONENT (component), 0);
150 iface = ATK_COMPONENT_GET_IFACE (component);
152 if (iface->add_focus_handler)
153 return (iface->add_focus_handler) (component, handler);
154 else
155 return 0;
159 * atk_component_remove_focus_handler:
160 * @component: the #AtkComponent to remove the focus handler from
161 * @handler_id: the handler id of the focus handler to be removed
162 * from @component
164 * Remove the handler specified by @handler_id from the list of
165 * functions to be executed when this object receives focus events
166 * (in or out).
168 * Deprecated: This method is deprecated since ATK version 2.9.4. If
169 * you need to track when an object gains or lose the focus, use
170 * state-changed:focused notification instead.
173 void
174 atk_component_remove_focus_handler (AtkComponent *component,
175 guint handler_id)
177 AtkComponentIface *iface = NULL;
178 g_return_if_fail (ATK_IS_COMPONENT (component));
180 iface = ATK_COMPONENT_GET_IFACE (component);
182 if (iface->remove_focus_handler)
183 (iface->remove_focus_handler) (component, handler_id);
187 * atk_component_contains:
188 * @component: the #AtkComponent
189 * @x: x coordinate
190 * @y: y coordinate
191 * @coord_type: specifies whether the coordinates are relative to the screen
192 * or to the components top level window
194 * Checks whether the specified point is within the extent of the @component.
196 * Toolkit implementor note: ATK provides a default implementation for
197 * this virtual method. In general there are little reason to
198 * re-implement it.
200 * Returns: %TRUE or %FALSE indicating whether the specified point is within
201 * the extent of the @component or not
203 gboolean
204 atk_component_contains (AtkComponent *component,
205 gint x,
206 gint y,
207 AtkCoordType coord_type)
209 AtkComponentIface *iface = NULL;
210 g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
212 iface = ATK_COMPONENT_GET_IFACE (component);
214 if (iface->contains)
215 return (iface->contains) (component, x, y, coord_type);
216 else
217 return FALSE;
221 * atk_component_ref_accessible_at_point:
222 * @component: the #AtkComponent
223 * @x: x coordinate
224 * @y: y coordinate
225 * @coord_type: specifies whether the coordinates are relative to the screen
226 * or to the components top level window
228 * Gets a reference to the accessible child, if one exists, at the
229 * coordinate point specified by @x and @y.
231 * Returns: (nullable) (transfer full): a reference to the accessible
232 * child, if one exists
234 AtkObject*
235 atk_component_ref_accessible_at_point (AtkComponent *component,
236 gint x,
237 gint y,
238 AtkCoordType coord_type)
240 AtkComponentIface *iface = NULL;
241 g_return_val_if_fail (ATK_IS_COMPONENT (component), NULL);
243 iface = ATK_COMPONENT_GET_IFACE (component);
245 if (iface->ref_accessible_at_point)
246 return (iface->ref_accessible_at_point) (component, x, y, coord_type);
247 else
248 return NULL;
252 * atk_component_get_extents:
253 * @component: an #AtkComponent
254 * @x: address of #gint to put x coordinate
255 * @y: address of #gint to put y coordinate
256 * @width: address of #gint to put width
257 * @height: address of #gint to put height
258 * @coord_type: specifies whether the coordinates are relative to the screen
259 * or to the components top level window
261 * Gets the rectangle which gives the extent of the @component.
264 void
265 atk_component_get_extents (AtkComponent *component,
266 gint *x,
267 gint *y,
268 gint *width,
269 gint *height,
270 AtkCoordType coord_type)
272 AtkComponentIface *iface = NULL;
273 gint local_x, local_y, local_width, local_height;
274 gint *real_x, *real_y, *real_width, *real_height;
276 g_return_if_fail (ATK_IS_COMPONENT (component));
278 if (x)
279 real_x = x;
280 else
281 real_x = &local_x;
282 if (y)
283 real_y = y;
284 else
285 real_y = &local_y;
286 if (width)
287 real_width = width;
288 else
289 real_width = &local_width;
290 if (height)
291 real_height = height;
292 else
293 real_height = &local_height;
295 iface = ATK_COMPONENT_GET_IFACE (component);
297 if (iface->get_extents)
298 (iface->get_extents) (component, real_x, real_y, real_width, real_height, coord_type);
302 * atk_component_get_position:
303 * @component: an #AtkComponent
304 * @x: address of #gint to put x coordinate position
305 * @y: address of #gint to put y coordinate position
306 * @coord_type: specifies whether the coordinates are relative to the screen
307 * or to the components top level window
309 * Gets the position of @component in the form of
310 * a point specifying @component's top-left corner.
312 * Deprecated: Since 2.12. Use atk_component_get_extents() instead.
314 void
315 atk_component_get_position (AtkComponent *component,
316 gint *x,
317 gint *y,
318 AtkCoordType coord_type)
320 AtkComponentIface *iface = NULL;
321 gint local_x, local_y;
322 gint *real_x, *real_y;
324 g_return_if_fail (ATK_IS_COMPONENT (component));
326 if (x)
327 real_x = x;
328 else
329 real_x = &local_x;
330 if (y)
331 real_y = y;
332 else
333 real_y = &local_y;
335 iface = ATK_COMPONENT_GET_IFACE (component);
337 if (iface->get_position)
338 (iface->get_position) (component, real_x, real_y, coord_type);
342 * atk_component_get_size:
343 * @component: an #AtkComponent
344 * @width: address of #gint to put width of @component
345 * @height: address of #gint to put height of @component
347 * Gets the size of the @component in terms of width and height.
349 * Deprecated: Since 2.12. Use atk_component_get_extents() instead.
351 void
352 atk_component_get_size (AtkComponent *component,
353 gint *width,
354 gint *height)
356 AtkComponentIface *iface = NULL;
357 gint local_width, local_height;
358 gint *real_width, *real_height;
360 g_return_if_fail (ATK_IS_COMPONENT (component));
362 if (width)
363 real_width = width;
364 else
365 real_width = &local_width;
366 if (height)
367 real_height = height;
368 else
369 real_height = &local_height;
371 g_return_if_fail (ATK_IS_COMPONENT (component));
373 iface = ATK_COMPONENT_GET_IFACE (component);
375 if (iface->get_size)
376 (iface->get_size) (component, real_width, real_height);
380 * atk_component_get_layer:
381 * @component: an #AtkComponent
383 * Gets the layer of the component.
385 * Returns: an #AtkLayer which is the layer of the component
387 AtkLayer
388 atk_component_get_layer (AtkComponent *component)
390 AtkComponentIface *iface;
392 g_return_val_if_fail (ATK_IS_COMPONENT (component), ATK_LAYER_INVALID);
394 iface = ATK_COMPONENT_GET_IFACE (component);
395 if (iface->get_layer)
396 return (iface->get_layer) (component);
397 else
398 return ATK_LAYER_WIDGET;
402 * atk_component_get_mdi_zorder:
403 * @component: an #AtkComponent
405 * Gets the zorder of the component. The value G_MININT will be returned
406 * if the layer of the component is not ATK_LAYER_MDI or ATK_LAYER_WINDOW.
408 * Returns: a gint which is the zorder of the component, i.e. the depth at
409 * which the component is shown in relation to other components in the same
410 * container.
412 gint
413 atk_component_get_mdi_zorder (AtkComponent *component)
415 AtkComponentIface *iface;
417 g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
419 iface = ATK_COMPONENT_GET_IFACE (component);
420 if (iface->get_mdi_zorder)
421 return (iface->get_mdi_zorder) (component);
422 else
423 return G_MININT;
427 * atk_component_get_alpha:
428 * @component: an #AtkComponent
430 * Returns the alpha value (i.e. the opacity) for this
431 * @component, on a scale from 0 (fully transparent) to 1.0
432 * (fully opaque).
434 * Returns: An alpha value from 0 to 1.0, inclusive.
435 * Since: 1.12
437 gdouble
438 atk_component_get_alpha (AtkComponent *component)
440 AtkComponentIface *iface;
442 g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT);
444 iface = ATK_COMPONENT_GET_IFACE (component);
445 if (iface->get_alpha)
446 return (iface->get_alpha) (component);
447 else
448 return (gdouble) 1.0;
452 * atk_component_grab_focus:
453 * @component: an #AtkComponent
455 * Grabs focus for this @component.
457 * Returns: %TRUE if successful, %FALSE otherwise.
459 gboolean
460 atk_component_grab_focus (AtkComponent *component)
462 AtkComponentIface *iface = NULL;
463 g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
465 iface = ATK_COMPONENT_GET_IFACE (component);
467 if (iface->grab_focus)
468 return (iface->grab_focus) (component);
469 else
470 return FALSE;
474 * atk_component_set_extents:
475 * @component: an #AtkComponent
476 * @x: x coordinate
477 * @y: y coordinate
478 * @width: width to set for @component
479 * @height: height to set for @component
480 * @coord_type: specifies whether the coordinates are relative to the screen
481 * or to the components top level window
483 * Sets the extents of @component.
485 * Returns: %TRUE or %FALSE whether the extents were set or not
487 gboolean
488 atk_component_set_extents (AtkComponent *component,
489 gint x,
490 gint y,
491 gint width,
492 gint height,
493 AtkCoordType coord_type)
495 AtkComponentIface *iface = NULL;
496 g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
498 iface = ATK_COMPONENT_GET_IFACE (component);
500 if (iface->set_extents)
501 return (iface->set_extents) (component, x, y, width, height, coord_type);
502 else
503 return FALSE;
507 * atk_component_set_position:
508 * @component: an #AtkComponent
509 * @x: x coordinate
510 * @y: y coordinate
511 * @coord_type: specifies whether the coordinates are relative to the screen
512 * or to the components top level window
514 * Sets the postition of @component.
516 * Returns: %TRUE or %FALSE whether or not the position was set or not
518 gboolean
519 atk_component_set_position (AtkComponent *component,
520 gint x,
521 gint y,
522 AtkCoordType coord_type)
524 AtkComponentIface *iface = NULL;
525 g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
527 iface = ATK_COMPONENT_GET_IFACE (component);
529 if (iface->set_position)
530 return (iface->set_position) (component, x, y, coord_type);
531 else
532 return FALSE;
536 * atk_component_set_size:
537 * @component: an #AtkComponent
538 * @width: width to set for @component
539 * @height: height to set for @component
541 * Set the size of the @component in terms of width and height.
543 * Returns: %TRUE or %FALSE whether the size was set or not
545 gboolean
546 atk_component_set_size (AtkComponent *component,
547 gint x,
548 gint y)
550 AtkComponentIface *iface = NULL;
551 g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
553 iface = ATK_COMPONENT_GET_IFACE (component);
555 if (iface->set_size)
556 return (iface->set_size) (component, x, y);
557 else
558 return FALSE;
561 static gboolean
562 atk_component_real_contains (AtkComponent *component,
563 gint x,
564 gint y,
565 AtkCoordType coord_type)
567 gint real_x, real_y, width, height;
569 real_x = real_y = width = height = 0;
571 atk_component_get_extents (component, &real_x, &real_y, &width, &height, coord_type);
573 if ((x >= real_x) &&
574 (x < real_x + width) &&
575 (y >= real_y) &&
576 (y < real_y + height))
577 return TRUE;
578 else
579 return FALSE;
582 static AtkObject*
583 atk_component_real_ref_accessible_at_point (AtkComponent *component,
584 gint x,
585 gint y,
586 AtkCoordType coord_type)
588 gint count, i;
590 count = atk_object_get_n_accessible_children (ATK_OBJECT (component));
592 for (i = 0; i < count; i++)
594 AtkObject *obj;
596 obj = atk_object_ref_accessible_child (ATK_OBJECT (component), i);
598 if (obj != NULL)
600 if (atk_component_contains (ATK_COMPONENT (obj), x, y, coord_type))
602 return obj;
604 else
606 g_object_unref (obj);
610 return NULL;
613 static void
614 atk_component_real_get_position (AtkComponent *component,
615 gint *x,
616 gint *y,
617 AtkCoordType coord_type)
619 gint width, height;
621 atk_component_get_extents (component, x, y, &width, &height, coord_type);
624 static void
625 atk_component_real_get_size (AtkComponent *component,
626 gint *width,
627 gint *height)
629 gint x, y;
630 AtkCoordType coord_type;
633 * Pick one coordinate type; it does not matter for size
635 coord_type = ATK_XY_WINDOW;
637 atk_component_get_extents (component, &x, &y, width, height, coord_type);
640 static AtkRectangle *
641 atk_rectangle_copy (const AtkRectangle *rectangle)
643 AtkRectangle *result = g_new (AtkRectangle, 1);
644 *result = *rectangle;
646 return result;
649 GType
650 atk_rectangle_get_type (void)
652 static GType our_type = 0;
654 if (our_type == 0)
655 our_type = g_boxed_type_register_static ("AtkRectangle",
656 (GBoxedCopyFunc)atk_rectangle_copy,
657 (GBoxedFreeFunc)g_free);
658 return our_type;