1 #include "AtkObject_parent_child.h"
4 static AtkObjectClass *atk_object_parent_class = NULL;
5 //redefines 'set_parent' function, and defines functions, which absents in AtkObject
7 static void my_parent_child_set_parent(AtkObject *accessible, AtkObject *parent);
9 static gint my_parent_child_get_n_children(AtkObject *accessible);
11 static AtkObject* my_parent_child_ref_child(AtkObject *accessible, gint i);
13 static gint my_parent_child_get_index_in_parent(AtkObject *accessible);
15 //function, needed in instance_finalize()
16 static void my_unref1(gpointer data, gpointer user_data)
20 //add/remove child to/from array of parent(for internal use)
21 static void my_parent_child_add_child(MyParentChild* parent, MyParentChild* child)
23 g_ptr_array_add(parent->children, child);
26 g_signal_emit_by_name(parent, "children-changed::add",
27 parent->children->len - 1, child);
29 static void my_parent_child_remove_child(MyParentChild* parent, MyParentChild* child)
32 for(i = parent->children->len - 1; i >= 0; i--)
34 if(g_ptr_array_index(parent->children, i) == child) break;
38 g_ptr_array_remove_index(parent->children, i);
39 g_object_unref(child);
40 g_signal_emit_by_name(parent, "children-changed::remove",
44 static void my_parent_child_instance_init(GTypeInstance *obj, gpointer g_class)
46 MyParentChild *self = (MyParentChild*)obj;
48 self->children = g_ptr_array_sized_new(10);
51 static void my_parent_child_instance_finalize(GObject *obj)
53 MyParentChild *self = (MyParentChild*) obj;
55 g_ptr_array_foreach(self->children, my_unref1, NULL);
56 //then free array (without frees pointers)
57 g_ptr_array_free(self->children, FALSE);
58 //chain to parent class
59 G_OBJECT_CLASS(atk_object_parent_class)->finalize(obj);
62 void my_parent_child_class_init(gpointer g_class, gpointer g_class_data)
64 AtkObjectClass *atkObjectClass = (AtkObjectClass*)g_class;
66 ((GObjectClass*)g_class)->finalize = my_parent_child_instance_finalize;
67 //set pointers to new functions in table of virtuals functions
68 atkObjectClass->set_parent = my_parent_child_set_parent;
69 atkObjectClass->get_n_children = my_parent_child_get_n_children;
70 atkObjectClass->ref_child = my_parent_child_ref_child;
71 atkObjectClass->get_index_in_parent = my_parent_child_get_index_in_parent;
73 atk_object_parent_class = g_type_class_peek_parent(g_class);
76 static void my_parent_child_set_parent(AtkObject *accessible, AtkObject *parent)
78 //applicable only with corresponding type of parent
79 g_return_if_fail(parent == NULL || MY_IS_PARENT_CHILD(parent));
81 MyParentChild *self = MY_PARENT_CHILD(accessible);
82 AtkObject *parent_old = (atk_object_get_parent(accessible));
84 if(parent_old == parent)
86 //nothing to do because parent does not change
90 //set field 'parent' in child using 'base-method'
91 atk_object_parent_class->set_parent(accessible, parent);
93 if(parent_old != NULL)
95 my_parent_child_remove_child((MyParentChild*)parent_old, self);
99 my_parent_child_add_child((MyParentChild*)parent, self);
103 static gint my_parent_child_get_n_children(AtkObject *accessible)
105 return MY_PARENT_CHILD(accessible)->children->len;
108 static AtkObject* my_parent_child_ref_child(AtkObject *accessible, gint i)
110 MyParentChild *self = MY_PARENT_CHILD(accessible);
111 if(i < 0 || i >= self->children->len)
113 printf("ref_child: Incorrect index of child.\n");
117 AtkObject* child = (AtkObject*)
118 g_ptr_array_index(self->children, i);
120 return (child == NULL) ? NULL : g_object_ref(child);
123 static gint my_parent_child_get_index_in_parent(AtkObject *accessible)
125 AtkObject *parent = atk_object_get_parent(accessible);
126 if(parent == NULL) return -1;//no parent
128 MyParentChild *parent_my = MY_PARENT_CHILD(parent);
130 int i = parent_my->children->len;
133 if(g_ptr_array_index(parent_my->children,i) == accessible)
136 if(i < 0)printf("Something wrong in parent-child strucutre.\n");
137 return i;//if error, i will be equal to -1
140 GType my_parent_child_get_type()
142 static GType type = 0;
145 static const GTypeInfo typeInfo =
147 sizeof(MyParentChildClass),
149 NULL, //base_finalize
150 my_parent_child_class_init, //class_init
151 NULL, //class_finalize
153 sizeof(MyParentChild),
155 my_parent_child_instance_init //instance_init
157 type = g_type_register_static(ATK_TYPE_OBJECT,"MyParentChild",&typeInfo,0);