atk/atkcomponent.[c|h] docs/atk-sections.txt, docs/tmpl/atkcomponent.sgml
[platform/upstream/atk.git] / atk / atkcomponent.c
1 /* ATK -  Accessibility Toolkit
2  * Copyright 2001 Sun Microsystems Inc.
3  *
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.
8  *
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.
13  *
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.
18  */
19
20
21 #include "atkcomponent.h"
22
23 static gboolean   atk_component_real_contains                (AtkComponent *component,
24                                                               gint         x,
25                                                               gint         y,
26                                                               AtkCoordType coord_type);
27
28 static AtkObject* atk_component_real_ref_accessible_at_point (AtkComponent *component,
29                                                               gint         x,
30                                                               gint         y,
31                                                               AtkCoordType coord_type);
32
33 static void      atk_component_real_get_position             (AtkComponent *component,
34                                                               gint         *x,
35                                                               gint         *y,
36                                                               AtkCoordType coord_type);
37
38 static void      atk_component_real_get_size                 (AtkComponent *component,
39                                                               gint         *width,
40                                                               gint         *height);
41
42 GType
43 atk_component_get_type ()
44 {
45   static GType type = 0;
46
47   if (!type) {
48     static const GTypeInfo tinfo =
49     {
50       sizeof (AtkComponentIface),
51       (GBaseInitFunc) NULL,
52       (GBaseFinalizeFunc) NULL,
53
54     };
55
56     type = g_type_register_static (G_TYPE_INTERFACE, "AtkComponent", &tinfo, 0);
57   }
58
59   return type;
60 }
61
62 /**
63  * atk_component_add_focus_handler:
64  * @component: The #AtkComponent to attach the @handler to
65  * @handler: The #AtkFocusHandler to be attached to @component
66  *
67  * Add the specified handler to the set of functions to be called 
68  * when this object receives focus events (in or out).
69  *
70  * Returns:
71  **/
72 guint
73 atk_component_add_focus_handler (AtkComponent    *component,
74                                  AtkFocusHandler handler)
75 {
76   AtkComponentIface *iface = NULL;
77   g_return_val_if_fail (ATK_IS_COMPONENT (component), 0);
78
79   iface = ATK_COMPONENT_GET_IFACE (component);
80
81   if (iface->add_focus_handler)
82     return (iface->add_focus_handler) (component, handler);
83   else
84     return 0;
85 }
86
87 /**
88  * atk_component_remove_focus_handler:
89  * @component: the #AtkComponent to remove the focus handler from
90  * @handler_id: the handler id of the focus handler to be removed
91  * from @component
92  *
93  * Remove the handler specified by @handler_id from the list of
94  * functions to be executed when this object receives focus events 
95  * (in or out).
96  **/
97 void
98 atk_component_remove_focus_handler (AtkComponent    *component,
99                                     guint           handler_id)
100 {
101   AtkComponentIface *iface = NULL;
102   g_return_if_fail (ATK_IS_COMPONENT (component));
103
104   iface = ATK_COMPONENT_GET_IFACE (component);
105
106   if (iface->remove_focus_handler)
107     (iface->remove_focus_handler) (component, handler_id);
108 }
109
110 /**
111  * atk_component_contains:
112  * @component: the #AtkComponent
113  * @x: x coordinate
114  * @y: y coordinate
115  * @coord_type: specifies whether the coordinates are relative to the screen
116  * or to the components top level window
117  *
118  * Checks whether the specified point is within the extent of the @component.
119  *
120  * Returns: %TRUE or %FALSE indicating whether the specified point is within
121  * the extent of the @component or not
122  **/
123 gboolean
124 atk_component_contains (AtkComponent    *component,
125                         gint            x,
126                         gint            y,
127                         AtkCoordType    coord_type)
128 {
129   AtkComponentIface *iface = NULL;
130   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
131
132   iface = ATK_COMPONENT_GET_IFACE (component);
133
134   if (iface->contains)
135     return (iface->contains) (component, x, y, coord_type);
136   else
137   {
138     /*
139      * if this method is not overridden use the default implementation.
140      */
141     return atk_component_real_contains (component, x, y, coord_type);
142   }
143 }
144
145 /**
146  * atk_component_ref_accessible_at_point:
147  * @component: the #AtkComponent
148  * @x: x coordinate
149  * @y: y coordinate
150  * @coord_type: specifies whether the coordinates are relative to the screen
151  * or to the components top level window
152  *
153  * Gets a reference to the accessible child, if one exists, at the
154  * coordinate point specified by @x and @y.
155  *
156  * Returns: a reference to the accessible child, if one exists
157  **/
158 AtkObject*
159 atk_component_ref_accessible_at_point (AtkComponent    *component,
160                                        gint            x,
161                                        gint            y,
162                                        AtkCoordType    coord_type)
163 {
164   AtkComponentIface *iface = NULL;
165   g_return_val_if_fail (ATK_IS_COMPONENT (component), NULL);
166
167   iface = ATK_COMPONENT_GET_IFACE (component);
168
169   if (iface->ref_accessible_at_point)
170     return (iface->ref_accessible_at_point) (component, x, y, coord_type);
171   else
172   {
173     /*
174      * if this method is not overridden use the default implementation.
175      */
176     return atk_component_real_ref_accessible_at_point (component, x, y, coord_type);
177   }
178 }
179
180 /**
181  * atk_component_get_extents:
182  * @component: an #AtkComponent
183  * @x: address of #gint to put x coordinate
184  * @y: address of #gint to put y coordinate
185  * @width: address of #gint to put width
186  * @height: address of #gint to put height
187  * @coord_type: specifies whether the coordinates are relative to the screen
188  * or to the components top level window
189  *
190  * Gets the rectangle which gives the extent of the @component.
191  *
192  **/
193 void
194 atk_component_get_extents    (AtkComponent    *component,
195                               gint            *x,
196                               gint            *y,
197                               gint            *width,
198                               gint            *height,
199                               AtkCoordType    coord_type)
200 {
201   AtkComponentIface *iface = NULL;
202   g_return_if_fail (ATK_IS_COMPONENT (component));
203
204   iface = ATK_COMPONENT_GET_IFACE (component);
205
206   if (iface->get_extents)
207     (iface->get_extents) (component, x, y, width, height, coord_type);
208 }
209
210 /**
211  * atk_component_get_position:
212  * @component: an #AtkComponent
213  * @x: address of #gint to put x coordinate position
214  * @y: address of #gint to put y coordinate position
215  * @coord_type: specifies whether the coordinates are relative to the screen
216  * or to the components top level window
217  *
218  * Gets the position of @component in the form of 
219  * a point specifying @component's top-left corner.
220  **/
221 void
222 atk_component_get_position   (AtkComponent    *component,
223                               gint            *x,
224                               gint            *y,
225                               AtkCoordType    coord_type)
226 {
227   AtkComponentIface *iface = NULL;
228   g_return_if_fail (ATK_IS_COMPONENT (component));
229
230   iface = ATK_COMPONENT_GET_IFACE (component);
231
232   if (iface->get_position)
233     (iface->get_position) (component, x, y, coord_type);
234   else
235   {
236     /*
237      * if this method is not overridden use the default implementation.
238      */
239     atk_component_real_get_position (component, x, y, coord_type);
240   }
241 }
242
243 /**
244  * atk_component_get_size:
245  * @component: an #AtkComponent
246  * @width: address of #gint to put width of @component
247  * @height: address of #gint to put height of @component
248  *
249  * Gets the size of the @component in terms of width and height.
250  **/
251 void
252 atk_component_get_size       (AtkComponent    *component,
253                               gint            *width,
254                               gint            *height)
255 {
256   AtkComponentIface *iface = NULL;
257   g_return_if_fail (ATK_IS_COMPONENT (component));
258
259   iface = ATK_COMPONENT_GET_IFACE (component);
260
261   if (iface->get_size)
262     (iface->get_size) (component, width, height);
263   else
264   {
265     /*
266      * if this method is not overridden use the default implementation.
267      */
268     atk_component_real_get_size (component, width, height);
269   }
270 }
271
272 /**
273  * atk_component_grab_focus:
274  * @component: an #AtkComponent
275  *
276  * Grabs focus for this @component.
277  *
278  * Returns: %TRUE if successful, %FALSE otherwise.
279  **/
280 gboolean
281 atk_component_grab_focus (AtkComponent    *component)
282 {
283   AtkComponentIface *iface = NULL;
284   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
285
286   iface = ATK_COMPONENT_GET_IFACE (component);
287
288   if (iface->grab_focus)
289     return (iface->grab_focus) (component);
290   else
291     return FALSE;
292 }
293
294 /**
295  * atk_component_set_extents:
296  * @component: an #AtkComponent
297  * @x: x coordinate
298  * @y: y coordinate
299  * @width: width to set for @component
300  * @height: height to set for @component
301  * @coord_type: specifies whether the coordinates are relative to the screen
302  * or to the components top level window
303  *
304  * Sets the extents of @component.
305  *
306  * Returns: %TRUE or %FALSE whether the extents were set or not
307  **/
308 gboolean
309 atk_component_set_extents   (AtkComponent    *component,
310                              gint            x,
311                              gint            y,
312                              gint            width,
313                              gint            height,
314                              AtkCoordType    coord_type)
315 {
316   AtkComponentIface *iface = NULL;
317   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
318
319   iface = ATK_COMPONENT_GET_IFACE (component);
320
321   if (iface->set_extents)
322     return (iface->set_extents) (component, x, y, width, height, coord_type);
323   else
324     return FALSE;
325 }
326
327 /**
328  * atk_component_set_position:
329  * @component: an #AtkComponent
330  * @x: x coordinate
331  * @y: y coordinate
332  * @coord_type: specifies whether the coordinates are relative to the screen
333  * or to the components top level window
334  *
335  * Sets the postition of @component.
336  * 
337  * Returns: %TRUE or %FALSE whether or not the position was set or not
338  **/
339 gboolean
340 atk_component_set_position   (AtkComponent    *component,
341                               gint            x,
342                               gint            y,
343                               AtkCoordType    coord_type)
344 {
345   AtkComponentIface *iface = NULL;
346   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
347
348   iface = ATK_COMPONENT_GET_IFACE (component);
349
350   if (iface->set_position)
351     return (iface->set_position) (component, x, y, coord_type);
352   else
353     return FALSE;
354 }
355
356 /**
357  * atk_component_set_size:
358  * @component: an #AtkComponent
359  * @width: width to set for @component
360  * @height: height to set for @component
361  *
362  * Set the size of the @component in terms of width and height.
363  *
364  * Returns: %TRUE or %FALSE whether the size was set or not
365  **/
366 gboolean
367 atk_component_set_size       (AtkComponent    *component,
368                               gint            x,
369                               gint            y)
370 {
371   AtkComponentIface *iface = NULL;
372   g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE);
373
374   iface = ATK_COMPONENT_GET_IFACE (component);
375
376   if (iface->set_size)
377     return (iface->set_size) (component, x, y);
378   else
379     return FALSE;
380 }
381
382 static gboolean
383 atk_component_real_contains (AtkComponent *component,
384                              gint         x,
385                              gint         y,
386                              AtkCoordType coord_type)
387 {
388   gint real_x, real_y, width, height;
389
390   real_x = real_y = width = height = 0;
391
392   atk_component_get_extents (component, &real_x, &real_y, &width, &height, coord_type);
393
394   if ((x >= real_x) &&
395       (x < real_x + width) &&
396       (y >= real_y) &&
397       (y < real_y + height))
398     return TRUE;
399   else
400     return FALSE;
401 }
402
403 static AtkObject* 
404 atk_component_real_ref_accessible_at_point (AtkComponent *component,
405                                             gint         x,
406                                             gint         y,
407                                             AtkCoordType coord_type)
408 {
409   gint count, i;
410
411   count = atk_object_get_n_accessible_children (ATK_OBJECT (component));
412
413   g_return_val_if_fail (count != 0, NULL);
414
415   for (i = 0; i < count; i++)
416   {
417     AtkObject *obj;
418
419     obj = atk_object_ref_accessible_child (ATK_OBJECT (component), i);
420
421     if (obj != NULL)
422     {
423       if (atk_component_contains (ATK_COMPONENT (obj), x, y, coord_type))
424       {
425         return obj;
426       }
427       else
428       {
429         g_object_unref (obj);
430       }
431     }
432   }
433   return NULL;
434 }
435
436 static void
437 atk_component_real_get_position (AtkComponent *component,
438                                  gint         *x,
439                                  gint         *y,
440                                  AtkCoordType coord_type)
441 {
442   gint width, height;
443
444   atk_component_get_extents (component, x, y, &width, &height, coord_type);
445 }
446
447 static void
448 atk_component_real_get_size (AtkComponent *component,
449                              gint         *width,
450                              gint         *height)
451 {
452   gint x, y;
453   AtkCoordType coord_type;
454
455   /*
456    * Pick one coordinate type; it does not matter for size
457    */
458   coord_type = ATK_XY_WINDOW;
459
460   atk_component_get_extents (component, &x, &y, width, height, coord_type);
461 }