4 #include "my-atk-object.h"
6 static AtkObjectClass *atk_object_parent_class = NULL;
9 //add/remove child to/from array of parent(for internal use)
10 static void my_atk_object_add_child(MyAtkObject* parent, MyAtkObject* child)
12 g_ptr_array_add(parent->children, child);
15 g_signal_emit_by_name(parent, "children-changed::add",
16 parent->children->len - 1, child);
19 static void my_atk_object_remove_child(MyAtkObject* parent, MyAtkObject* child)
22 for(i = parent->children->len - 1; i >= 0; i--)
24 if(g_ptr_array_index(parent->children, i) == child) break;
28 g_ptr_array_remove_index(parent->children, i);
29 g_object_unref(child);
30 g_signal_emit_by_name(parent, "children-changed::remove",
34 static void my_atk_object_set_parent(AtkObject *accessible, AtkObject *parent)
36 //applicable only with corresponding type of parent
37 g_return_if_fail(parent == NULL || MY_IS_ATK_OBJECT(parent));
39 MyAtkObject *self = MY_ATK_OBJECT(accessible);
40 AtkObject *parent_old = (atk_object_get_parent(accessible));
42 if(parent_old == parent)
44 //nothing to do because parent does not change
48 //set field 'parent' in child using 'base-method'
49 atk_object_parent_class->set_parent(accessible, parent);
51 if(parent_old != NULL)
53 my_atk_object_remove_child((MyAtkObject*)parent_old, self);
57 my_atk_object_add_child((MyAtkObject*)parent, self);
61 static gint my_atk_object_get_n_children(AtkObject *accessible)
63 return MY_ATK_OBJECT(accessible)->children->len;
66 static AtkObject* my_atk_object_ref_child(AtkObject *accessible, gint i)
68 MyAtkObject *self = MY_ATK_OBJECT(accessible);
69 if(i < 0 || i >= self->children->len)
71 printf("ref_child: Incorrect index of child.\n");
75 AtkObject* child = (AtkObject*)
76 g_ptr_array_index(self->children, i);
78 return (child == NULL) ? NULL : g_object_ref(child);
81 static gint my_atk_object_get_index_in_parent(AtkObject *accessible)
83 AtkObject *parent = atk_object_get_parent(accessible);
84 if(parent == NULL) return -1;//no parent
86 MyAtkObject *parent_my = MY_ATK_OBJECT(parent);
88 int i = parent_my->children->len;
91 if(g_ptr_array_index(parent_my->children,i) == accessible)
94 if(i < 0)printf("Something wrong in parent-child strucutre.\n");
95 return i;//if error, i will be equal to -1
98 //function, needed in instance_finalize()
99 static void my_unref1(gpointer data, gpointer user_data)
101 g_object_unref(data);
104 static void my_atk_object_instance_finalize(GObject *obj)
106 MyAtkObject *self = (MyAtkObject*) obj;
107 //unrefs all children
108 g_ptr_array_foreach(self->children, my_unref1, NULL);
109 //then free array (without frees pointers)
110 g_ptr_array_free(self->children, FALSE);
111 //chain to parent class
112 G_OBJECT_CLASS(atk_object_parent_class)->finalize(obj);
115 void my_atk_object_class_init(gpointer g_class, gpointer g_class_data)
117 AtkObjectClass *atkObjectClass = (AtkObjectClass*)g_class;
119 ((GObjectClass*)g_class)->finalize = my_atk_object_instance_finalize;
120 //set pointers to new functions in table of virtuals functions
121 atkObjectClass->set_parent = my_atk_object_set_parent;
122 atkObjectClass->get_n_children = my_atk_object_get_n_children;
123 atkObjectClass->ref_child = my_atk_object_ref_child;
124 atkObjectClass->get_index_in_parent = my_atk_object_get_index_in_parent;
126 atk_object_parent_class = g_type_class_peek_parent(g_class);
129 static void my_atk_object_instance_init(GTypeInstance *obj, gpointer g_class)
131 MyAtkObject *self = (MyAtkObject*)obj;
133 self->children = g_ptr_array_sized_new(10);
136 GType my_atk_object_get_type()
138 static GType type = 0;
141 static const GTypeInfo typeInfo =
143 sizeof(MyAtkObjectClass),
145 NULL, //base_finalize
146 my_atk_object_class_init, //class_init
147 NULL, //class_finalize
151 my_atk_object_instance_init //instance_init
153 type = g_type_register_static(ATK_TYPE_OBJECT,"MyAtkObject",&typeInfo,0);