X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=atk%2Fatkcomponent.c;h=f0beb10f7b9fb269439c422e29ea18be8af47565;hb=4f631cf8b3ceb2d8e8342850a0124426faa0a0c7;hp=f7a0ea4da263d17cb8bfdc7223629996b699f047;hpb=dba66b4bec94a908cd35a5537209db255fa5fa33;p=platform%2Fupstream%2Fatk.git diff --git a/atk/atkcomponent.c b/atk/atkcomponent.c old mode 100755 new mode 100644 index f7a0ea4..f0beb10 --- a/atk/atkcomponent.c +++ b/atk/atkcomponent.c @@ -17,11 +17,59 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" #include "atkcomponent.h" +/** + * SECTION:atkcomponent + * @Short_description: The ATK interface provided by UI components + * which occupy a physical area on the screen. + * which the user can activate/interact with. + * @Title:AtkComponent + * + * #AtkComponent should be implemented by most if not all UI elements + * with an actual on-screen presence, i.e. components which can be + * said to have a screen-coordinate bounding box. Virtually all + * widgets will need to have #AtkComponent implementations provided + * for their corresponding #AtkObject class. In short, only UI + * elements which are *not* GUI elements will omit this ATK interface. + * + * A possible exception might be textual information with a + * transparent background, in which case text glyph bounding box + * information is provided by #AtkText. + */ + +enum { + BOUNDS_CHANGED, + LAST_SIGNAL +}; + +static void atk_component_base_init (AtkComponentIface *class); + +static gboolean atk_component_real_contains (AtkComponent *component, + gint x, + gint y, + AtkCoordType coord_type); + +static AtkObject* atk_component_real_ref_accessible_at_point (AtkComponent *component, + gint x, + gint y, + AtkCoordType coord_type); + +static void atk_component_real_get_position (AtkComponent *component, + gint *x, + gint *y, + AtkCoordType coord_type); + +static void atk_component_real_get_size (AtkComponent *component, + gint *width, + gint *height); + +static guint atk_component_signals[LAST_SIGNAL] = { 0 }; + GType -atk_component_get_type () +atk_component_get_type (void) { static GType type = 0; @@ -29,8 +77,8 @@ atk_component_get_type () static const GTypeInfo tinfo = { sizeof (AtkComponentIface), - NULL, - NULL, + (GBaseInitFunc) atk_component_base_init, + (GBaseFinalizeFunc) NULL, }; @@ -40,15 +88,62 @@ atk_component_get_type () return type; } +static void +atk_component_base_init (AtkComponentIface *class) +{ + static gboolean initialized = FALSE; + + if (! initialized) + { + class->ref_accessible_at_point = atk_component_real_ref_accessible_at_point; + class->contains = atk_component_real_contains; + class->get_position = atk_component_real_get_position; + class->get_size = atk_component_real_get_size; + + + /** + * AtkComponent::bounds-changed: + * @atkcomponent: the object which received the signal. + * @arg1: The AtkRectangle giving the new position and size. + * + * The 'bounds-changed" signal is emitted when the bposition or + * size of the component changes. + */ + atk_component_signals[BOUNDS_CHANGED] = + g_signal_new ("bounds_changed", + ATK_TYPE_COMPONENT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (AtkComponentIface, bounds_changed), + (GSignalAccumulator) NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + ATK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE); + + initialized = TRUE; + } +} + + /** + * atk_component_add_focus_handler: (skip) + * @component: The #AtkComponent to attach the @handler to + * @handler: The #AtkFocusHandler to be attached to @component + * + * Add the specified handler to the set of functions to be called + * when this object receives focus events (in or out). If the handler is + * already added it is not added again + * + * Deprecated: 2.9.4: If you need to track when an object gains or + * lose the focus, use the #AtkObject::state-change "focused" notification instead. * + * Returns: a handler id which can be used in atk_component_remove_focus_handler() + * or zero if the handler was already added. **/ guint atk_component_add_focus_handler (AtkComponent *component, AtkFocusHandler handler) { AtkComponentIface *iface = NULL; - g_return_val_if_fail (component != NULL, 0); g_return_val_if_fail (ATK_IS_COMPONENT (component), 0); iface = ATK_COMPONENT_GET_IFACE (component); @@ -60,6 +155,17 @@ atk_component_add_focus_handler (AtkComponent *component, } /** + * atk_component_remove_focus_handler: + * @component: the #AtkComponent to remove the focus handler from + * @handler_id: the handler id of the focus handler to be removed + * from @component + * + * Remove the handler specified by @handler_id from the list of + * functions to be executed when this object receives focus events + * (in or out). + * + * Deprecated: 2.9.4: If you need to track when an object gains or + * lose the focus, use the #AtkObject::state-change "focused" notification instead. * **/ void @@ -67,7 +173,6 @@ atk_component_remove_focus_handler (AtkComponent *component, guint handler_id) { AtkComponentIface *iface = NULL; - g_return_if_fail (component != NULL); g_return_if_fail (ATK_IS_COMPONENT (component)); iface = ATK_COMPONENT_GET_IFACE (component); @@ -76,158 +181,478 @@ atk_component_remove_focus_handler (AtkComponent *component, (iface->remove_focus_handler) (component, handler_id); } +/** + * atk_component_contains: + * @component: the #AtkComponent + * @x: x coordinate + * @y: y coordinate + * @coord_type: specifies whether the coordinates are relative to the screen + * or to the components top level window + * + * Checks whether the specified point is within the extent of the @component. + * + * Toolkit implementor note: ATK provides a default implementation for + * this virtual method. In general there are little reason to + * re-implement it. + * + * Returns: %TRUE or %FALSE indicating whether the specified point is within + * the extent of the @component or not + **/ gboolean atk_component_contains (AtkComponent *component, gint x, - gint y) + gint y, + AtkCoordType coord_type) { AtkComponentIface *iface = NULL; - g_return_val_if_fail (component != NULL, FALSE); g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE); iface = ATK_COMPONENT_GET_IFACE (component); if (iface->contains) - return (iface->contains) (component, x, y); + return (iface->contains) (component, x, y, coord_type); else return FALSE; } +/** + * atk_component_ref_accessible_at_point: + * @component: the #AtkComponent + * @x: x coordinate + * @y: y coordinate + * @coord_type: specifies whether the coordinates are relative to the screen + * or to the components top level window + * + * Gets a reference to the accessible child, if one exists, at the + * coordinate point specified by @x and @y. + * + * Returns: (nullable) (transfer full): a reference to the accessible + * child, if one exists + **/ AtkObject* -atk_component_get_accessible_at_point (AtkComponent *component, +atk_component_ref_accessible_at_point (AtkComponent *component, gint x, - gint y) + gint y, + AtkCoordType coord_type) { AtkComponentIface *iface = NULL; - g_return_val_if_fail (component != NULL, FALSE); - g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE); + g_return_val_if_fail (ATK_IS_COMPONENT (component), NULL); iface = ATK_COMPONENT_GET_IFACE (component); - if (iface->get_accessible_at_point) - return (iface->get_accessible_at_point) (component, x, y); + if (iface->ref_accessible_at_point) + return (iface->ref_accessible_at_point) (component, x, y, coord_type); else - return FALSE; + return NULL; } +/** + * atk_component_get_extents: + * @component: an #AtkComponent + * @x: (out) (optional): address of #gint to put x coordinate + * @y: (out) (optional): address of #gint to put y coordinate + * @width: (out) (optional): address of #gint to put width + * @height: (out) (optional): address of #gint to put height + * @coord_type: specifies whether the coordinates are relative to the screen + * or to the components top level window + * + * Gets the rectangle which gives the extent of the @component. + * + **/ void atk_component_get_extents (AtkComponent *component, gint *x, gint *y, gint *width, - gint *height) + gint *height, + AtkCoordType coord_type) { AtkComponentIface *iface = NULL; - g_return_if_fail (component != NULL); + gint local_x, local_y, local_width, local_height; + gint *real_x, *real_y, *real_width, *real_height; + g_return_if_fail (ATK_IS_COMPONENT (component)); + if (x) + real_x = x; + else + real_x = &local_x; + if (y) + real_y = y; + else + real_y = &local_y; + if (width) + real_width = width; + else + real_width = &local_width; + if (height) + real_height = height; + else + real_height = &local_height; + iface = ATK_COMPONENT_GET_IFACE (component); if (iface->get_extents) - (iface->get_extents) (component, x, y, width, height); + (iface->get_extents) (component, real_x, real_y, real_width, real_height, coord_type); } +/** + * atk_component_get_position: + * @component: an #AtkComponent + * @x: (out) (optional): address of #gint to put x coordinate position + * @y: (out) (optional): address of #gint to put y coordinate position + * @coord_type: specifies whether the coordinates are relative to the screen + * or to the components top level window + * + * Gets the position of @component in the form of + * a point specifying @component's top-left corner. + * + * Deprecated: Since 2.12. Use atk_component_get_extents() instead. + **/ void atk_component_get_position (AtkComponent *component, gint *x, - gint *y) + gint *y, + AtkCoordType coord_type) { AtkComponentIface *iface = NULL; - g_return_if_fail (component != NULL); + gint local_x, local_y; + gint *real_x, *real_y; + g_return_if_fail (ATK_IS_COMPONENT (component)); + if (x) + real_x = x; + else + real_x = &local_x; + if (y) + real_y = y; + else + real_y = &local_y; + iface = ATK_COMPONENT_GET_IFACE (component); if (iface->get_position) - (iface->get_position) (component, x, y); + (iface->get_position) (component, real_x, real_y, coord_type); } +/** + * atk_component_get_size: + * @component: an #AtkComponent + * @width: (out) (optional): address of #gint to put width of @component + * @height: (out) (optional): address of #gint to put height of @component + * + * Gets the size of the @component in terms of width and height. + * + * Deprecated: Since 2.12. Use atk_component_get_extents() instead. + **/ void -atk_component_get_position_on_screen (AtkComponent *component, - gint *x, - gint *y) +atk_component_get_size (AtkComponent *component, + gint *width, + gint *height) { AtkComponentIface *iface = NULL; - g_return_if_fail (component != NULL); + gint local_width, local_height; + gint *real_width, *real_height; + + g_return_if_fail (ATK_IS_COMPONENT (component)); + + if (width) + real_width = width; + else + real_width = &local_width; + if (height) + real_height = height; + else + real_height = &local_height; + g_return_if_fail (ATK_IS_COMPONENT (component)); iface = ATK_COMPONENT_GET_IFACE (component); - if (iface->get_position_on_screen) - return (iface->get_position_on_screen) (component, x, y); + if (iface->get_size) + (iface->get_size) (component, real_width, real_height); } -void -atk_component_get_size (AtkComponent *component, - gint *x, - gint *y) +/** + * atk_component_get_layer: + * @component: an #AtkComponent + * + * Gets the layer of the component. + * + * Returns: an #AtkLayer which is the layer of the component + **/ +AtkLayer +atk_component_get_layer (AtkComponent *component) { - AtkComponentIface *iface = NULL; - g_return_if_fail (component != NULL); - g_return_if_fail (ATK_IS_COMPONENT (component)); + AtkComponentIface *iface; + + g_return_val_if_fail (ATK_IS_COMPONENT (component), ATK_LAYER_INVALID); iface = ATK_COMPONENT_GET_IFACE (component); + if (iface->get_layer) + return (iface->get_layer) (component); + else + return ATK_LAYER_WIDGET; +} - if (iface->get_size) - (iface->get_size) (component, x, y); +/** + * atk_component_get_mdi_zorder: + * @component: an #AtkComponent + * + * Gets the zorder of the component. The value G_MININT will be returned + * if the layer of the component is not ATK_LAYER_MDI or ATK_LAYER_WINDOW. + * + * Returns: a gint which is the zorder of the component, i.e. the depth at + * which the component is shown in relation to other components in the same + * container. + **/ +gint +atk_component_get_mdi_zorder (AtkComponent *component) +{ + AtkComponentIface *iface; + + g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT); + + iface = ATK_COMPONENT_GET_IFACE (component); + if (iface->get_mdi_zorder) + return (iface->get_mdi_zorder) (component); + else + return G_MININT; } -void +/** + * atk_component_get_alpha: + * @component: an #AtkComponent + * + * Returns the alpha value (i.e. the opacity) for this + * @component, on a scale from 0 (fully transparent) to 1.0 + * (fully opaque). + * + * Returns: An alpha value from 0 to 1.0, inclusive. + * Since: 1.12 + **/ +gdouble +atk_component_get_alpha (AtkComponent *component) +{ + AtkComponentIface *iface; + + g_return_val_if_fail (ATK_IS_COMPONENT (component), G_MININT); + + iface = ATK_COMPONENT_GET_IFACE (component); + if (iface->get_alpha) + return (iface->get_alpha) (component); + else + return (gdouble) 1.0; +} + +/** + * atk_component_grab_focus: + * @component: an #AtkComponent + * + * Grabs focus for this @component. + * + * Returns: %TRUE if successful, %FALSE otherwise. + **/ +gboolean atk_component_grab_focus (AtkComponent *component) { AtkComponentIface *iface = NULL; - g_return_if_fail (component != NULL); - g_return_if_fail (ATK_IS_COMPONENT (component)); + g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE); iface = ATK_COMPONENT_GET_IFACE (component); if (iface->grab_focus) - (iface->grab_focus) (component); + return (iface->grab_focus) (component); + else + return FALSE; } -void +/** + * atk_component_set_extents: + * @component: an #AtkComponent + * @x: x coordinate + * @y: y coordinate + * @width: width to set for @component + * @height: height to set for @component + * @coord_type: specifies whether the coordinates are relative to the screen + * or to the components top level window + * + * Sets the extents of @component. + * + * Returns: %TRUE or %FALSE whether the extents were set or not + **/ +gboolean atk_component_set_extents (AtkComponent *component, gint x, gint y, gint width, - gint height) + gint height, + AtkCoordType coord_type) { AtkComponentIface *iface = NULL; - g_return_if_fail (component != NULL); - g_return_if_fail (ATK_IS_COMPONENT (component)); + g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE); iface = ATK_COMPONENT_GET_IFACE (component); if (iface->set_extents) - (iface->set_extents) (component, x, y, width, height); + return (iface->set_extents) (component, x, y, width, height, coord_type); + else + return FALSE; } -void +/** + * atk_component_set_position: + * @component: an #AtkComponent + * @x: x coordinate + * @y: y coordinate + * @coord_type: specifies whether the coordinates are relative to the screen + * or to the components top level window + * + * Sets the postition of @component. + * + * Returns: %TRUE or %FALSE whether or not the position was set or not + **/ +gboolean atk_component_set_position (AtkComponent *component, gint x, - gint y) + gint y, + AtkCoordType coord_type) { AtkComponentIface *iface = NULL; - g_return_if_fail (component != NULL); - g_return_if_fail (ATK_IS_COMPONENT (component)); + g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE); iface = ATK_COMPONENT_GET_IFACE (component); if (iface->set_position) - (iface->set_position) (component, x, y); + return (iface->set_position) (component, x, y, coord_type); + else + return FALSE; } -void +/** + * atk_component_set_size: + * @component: an #AtkComponent + * @width: width to set for @component + * @height: height to set for @component + * + * Set the size of the @component in terms of width and height. + * + * Returns: %TRUE or %FALSE whether the size was set or not + **/ +gboolean atk_component_set_size (AtkComponent *component, gint x, gint y) { AtkComponentIface *iface = NULL; - g_return_if_fail (component != NULL); - g_return_if_fail (ATK_IS_COMPONENT (component)); + g_return_val_if_fail (ATK_IS_COMPONENT (component), FALSE); iface = ATK_COMPONENT_GET_IFACE (component); if (iface->set_size) - (iface->set_size) (component, x, y); + return (iface->set_size) (component, x, y); + else + return FALSE; +} + +static gboolean +atk_component_real_contains (AtkComponent *component, + gint x, + gint y, + AtkCoordType coord_type) +{ + gint real_x, real_y, width, height; + + real_x = real_y = width = height = 0; + + atk_component_get_extents (component, &real_x, &real_y, &width, &height, coord_type); + + if ((x >= real_x) && + (x < real_x + width) && + (y >= real_y) && + (y < real_y + height)) + return TRUE; + else + return FALSE; +} + +static AtkObject* +atk_component_real_ref_accessible_at_point (AtkComponent *component, + gint x, + gint y, + AtkCoordType coord_type) +{ + gint count, i; + + count = atk_object_get_n_accessible_children (ATK_OBJECT (component)); + + for (i = 0; i < count; i++) + { + AtkObject *obj; + + obj = atk_object_ref_accessible_child (ATK_OBJECT (component), i); + + if (obj != NULL) + { + if (atk_component_contains (ATK_COMPONENT (obj), x, y, coord_type)) + { + return obj; + } + else + { + g_object_unref (obj); + } + } + } + return NULL; +} + +static void +atk_component_real_get_position (AtkComponent *component, + gint *x, + gint *y, + AtkCoordType coord_type) +{ + gint width, height; + + atk_component_get_extents (component, x, y, &width, &height, coord_type); +} + +static void +atk_component_real_get_size (AtkComponent *component, + gint *width, + gint *height) +{ + gint x, y; + AtkCoordType coord_type; + + /* + * Pick one coordinate type; it does not matter for size + */ + coord_type = ATK_XY_WINDOW; + + atk_component_get_extents (component, &x, &y, width, height, coord_type); +} + +static AtkRectangle * +atk_rectangle_copy (const AtkRectangle *rectangle) +{ + AtkRectangle *result = g_new (AtkRectangle, 1); + *result = *rectangle; + + return result; } + +GType +atk_rectangle_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static ("AtkRectangle", + (GBoxedCopyFunc)atk_rectangle_copy, + (GBoxedFreeFunc)g_free); + return our_type; +} +