4 #include "my-atk-object.h"
6 static AtkObjectClass *atk_object_parent_class = NULL;
8 void my_atk_object_add_child(MyAtkObject* parent, MyAtkObject* child)
10 g_ptr_array_add(parent->children, child);
11 g_object_ref_sink(child);
13 g_signal_emit_by_name(parent, "children-changed::add",
14 parent->children->len - 1, child);
17 void my_atk_object_remove_child(MyAtkObject* parent, MyAtkObject* child)
20 for(i = parent->children->len - 1; i >= 0; i--)
22 if(g_ptr_array_index(parent->children, i) == child) break;
26 g_ptr_array_remove_index(parent->children, i);
27 g_object_unref(child);
28 g_signal_emit_by_name(parent, "children-changed::remove",
32 static void my_atk_object_set_parent(AtkObject *accessible, AtkObject *parent)
34 //applicable only with corresponding type of parent
35 g_return_if_fail(parent == NULL || MY_IS_ATK_OBJECT(parent));
37 MyAtkObject *self = MY_ATK_OBJECT(accessible);
38 AtkObject *parent_old = (atk_object_get_parent(accessible));
40 if(parent_old == parent)
42 //nothing to do because parent does not change
46 //set field 'parent' in child using 'base-method'
47 atk_object_parent_class->set_parent(accessible, parent);
49 if(parent_old != NULL)
51 my_atk_object_remove_child((MyAtkObject*)parent_old, self);
55 my_atk_object_add_child((MyAtkObject*)parent, self);
59 static gint my_atk_object_get_n_children(AtkObject *accessible)
61 return MY_ATK_OBJECT(accessible)->children->len;
64 static AtkObject* my_atk_object_ref_child(AtkObject *accessible, gint i)
66 MyAtkObject *self = MY_ATK_OBJECT(accessible);
67 if(i < 0 || i >= self->children->len)
69 printf("ref_child: Incorrect index of child.\n");
73 AtkObject* child = (AtkObject*)
74 g_ptr_array_index(self->children, i);
76 return (child == NULL) ? NULL : g_object_ref(child);
79 static gint my_atk_object_get_index_in_parent(AtkObject *accessible)
81 AtkObject *parent = atk_object_get_parent(accessible);
82 if(parent == NULL) return -1;//no parent
84 MyAtkObject *parent_my = MY_ATK_OBJECT(parent);
86 int i = parent_my->children->len;
89 if(g_ptr_array_index(parent_my->children,i) == accessible)
92 if(i < 0)printf("Something wrong in parent-child strucutre.\n");
93 return i;//if error, i will be equal to -1
96 //function, needed in instance_finalize()
97 static void my_unref1(gpointer data, gpointer user_data)
102 static void my_atk_object_instance_finalize(GObject *obj)
104 MyAtkObject *self = (MyAtkObject*) obj;
105 //unrefs all children
106 g_ptr_array_foreach(self->children, my_unref1, NULL);
107 //then free array (without frees pointers)
108 g_ptr_array_free(self->children, FALSE);
109 //chain to parent class
110 G_OBJECT_CLASS(atk_object_parent_class)->finalize(obj);
113 void my_atk_object_class_init(gpointer g_class, gpointer g_class_data)
115 AtkObjectClass *atkObjectClass = (AtkObjectClass*)g_class;
117 ((GObjectClass*)g_class)->finalize = my_atk_object_instance_finalize;
118 //set pointers to new functions in table of virtuals functions
119 atkObjectClass->set_parent = my_atk_object_set_parent;
120 atkObjectClass->get_n_children = my_atk_object_get_n_children;
121 atkObjectClass->ref_child = my_atk_object_ref_child;
122 atkObjectClass->get_index_in_parent = my_atk_object_get_index_in_parent;
124 atk_object_parent_class = g_type_class_peek_parent(g_class);
127 static void my_atk_object_instance_init(GTypeInstance *obj, gpointer g_class)
129 MyAtkObject *self = (MyAtkObject*)obj;
131 self->children = g_ptr_array_sized_new(10);
134 GType my_atk_object_get_type()
136 static GType type = 0;
139 static const GTypeInfo typeInfo =
141 sizeof(MyAtkObjectClass),
143 NULL, //base_finalize
144 my_atk_object_class_init, //class_init
145 NULL, //class_finalize
149 my_atk_object_instance_init //instance_init
151 type = g_type_register_static(ATK_TYPE_OBJECT,"MyAtkObject",&typeInfo,0);