]> Pileus Git - ~andy/gtk/blob - gtk/a11y/gtkscrolledwindowaccessible.c
f3cf79de5d2c00f54e0ca3ca12fbb50c9f634278
[~andy/gtk] / gtk / a11y / gtkscrolledwindowaccessible.c
1 /* GAIL - The GNOME Accessibility Enabling Library
2  * Copyright 2001, 2002, 2003 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 #include "config.h"
21
22 #include <gtk/gtk.h>
23 #include "gtkscrolledwindowaccessible.h"
24
25
26 G_DEFINE_TYPE (GtkScrolledWindowAccessible, _gtk_scrolled_window_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE)
27
28 static void
29 visibility_changed (GObject    *object,
30                     GParamSpec *pspec,
31                     gpointer    user_data)
32 {
33   if (!g_strcmp0 (pspec->name, "visible"))
34     {
35       gint index;
36       gint n_children;
37       gboolean child_added = FALSE;
38       GList *children;
39       AtkObject *child;
40       GtkWidget *widget;
41       GtkScrolledWindow *scrolled_window;
42       GtkWidget *hscrollbar, *vscrollbar;
43       GtkAccessible *accessible = GTK_ACCESSIBLE (user_data);
44
45       widget = gtk_accessible_get_widget (user_data);
46       if (widget == NULL)
47         return;
48
49       scrolled_window = GTK_SCROLLED_WINDOW (widget);
50       children = gtk_container_get_children (GTK_CONTAINER (widget));
51       index = n_children = g_list_length (children);
52       g_list_free (children);
53
54       hscrollbar = gtk_scrolled_window_get_hscrollbar (scrolled_window);
55       vscrollbar = gtk_scrolled_window_get_vscrollbar (scrolled_window);
56
57       if ((gpointer) object == (gpointer) (hscrollbar))
58         {
59           if (gtk_scrolled_window_get_hscrollbar (scrolled_window))
60             child_added = TRUE;
61
62           child = gtk_widget_get_accessible (hscrollbar);
63         }
64       else if ((gpointer) object == (gpointer) (vscrollbar))
65         {
66           if (gtk_scrolled_window_get_vscrollbar (scrolled_window))
67             child_added = TRUE;
68
69           child = gtk_widget_get_accessible (vscrollbar);
70           if (gtk_scrolled_window_get_hscrollbar (scrolled_window))
71             index = n_children + 1;
72         }
73       else
74         {
75           g_assert_not_reached ();
76           return;
77         }
78
79       if (child_added)
80         g_signal_emit_by_name (accessible, "children-changed::add", index, child, NULL);
81       else
82         g_signal_emit_by_name (accessible, "children-changed::remove", index, child, NULL);
83
84     }
85 }
86
87 static void
88 gtk_scrolled_window_accessible_initialize (AtkObject *obj,
89                                            gpointer  data)
90 {
91   GtkScrolledWindow *window;
92
93   ATK_OBJECT_CLASS (_gtk_scrolled_window_accessible_parent_class)->initialize (obj, data);
94
95   window = GTK_SCROLLED_WINDOW (data);
96
97   g_signal_connect_data (gtk_scrolled_window_get_hscrollbar (window), "notify::visible",
98                          G_CALLBACK (visibility_changed),
99                          obj, NULL, FALSE);
100   g_signal_connect_data (gtk_scrolled_window_get_vscrollbar (window), "notify::visible",
101                          G_CALLBACK (visibility_changed),
102                          obj, NULL, FALSE);
103
104   obj->role = ATK_ROLE_SCROLL_PANE;
105 }
106
107 static gint
108 gtk_scrolled_window_accessible_get_n_children (AtkObject *object)
109 {
110   GtkWidget *widget;
111   GtkScrolledWindow *scrolled_window;
112   GList *children;
113   gint n_children;
114
115   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (object));
116   if (widget == NULL)
117     return 0;
118
119   scrolled_window = GTK_SCROLLED_WINDOW (widget);
120
121   children = gtk_container_get_children (GTK_CONTAINER (widget));
122   n_children = g_list_length (children);
123   g_list_free (children);
124
125   if (gtk_scrolled_window_get_hscrollbar (scrolled_window))
126     n_children++;
127   if (gtk_scrolled_window_get_vscrollbar (scrolled_window))
128     n_children++;
129
130   return n_children;
131 }
132
133 static AtkObject *
134 gtk_scrolled_window_accessible_ref_child (AtkObject *obj,
135                                           gint       child)
136 {
137   GtkWidget *widget;
138   GtkScrolledWindow *scrolled_window;
139   GtkWidget *hscrollbar, *vscrollbar;
140   GList *children, *tmp_list;
141   gint n_children;
142   AtkObject  *accessible = NULL;
143
144   g_return_val_if_fail (child >= 0, NULL);
145
146   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
147   if (widget == NULL)
148     return NULL;
149
150   scrolled_window = GTK_SCROLLED_WINDOW (widget);
151   hscrollbar = gtk_scrolled_window_get_hscrollbar (scrolled_window);
152   vscrollbar = gtk_scrolled_window_get_vscrollbar (scrolled_window);
153
154   children = gtk_container_get_children (GTK_CONTAINER (widget));
155   n_children = g_list_length (children);
156
157   if (child == n_children)
158     {
159       if (gtk_scrolled_window_get_hscrollbar (scrolled_window))
160         accessible = gtk_widget_get_accessible (hscrollbar);
161       else if (gtk_scrolled_window_get_vscrollbar (scrolled_window))
162         accessible = gtk_widget_get_accessible (vscrollbar);
163     }
164   else if (child == n_children + 1 &&
165            gtk_scrolled_window_get_hscrollbar (scrolled_window) &&
166            gtk_scrolled_window_get_vscrollbar (scrolled_window))
167     accessible = gtk_widget_get_accessible (vscrollbar);
168   else if (child < n_children)
169     {
170       tmp_list = g_list_nth (children, child);
171       if (tmp_list)
172         accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
173     }
174
175   g_list_free (children);
176   if (accessible)
177     g_object_ref (accessible);
178
179   return accessible;
180 }
181
182 static void
183 _gtk_scrolled_window_accessible_class_init (GtkScrolledWindowAccessibleClass *klass)
184 {
185   AtkObjectClass  *class = ATK_OBJECT_CLASS (klass);
186
187   class->get_n_children = gtk_scrolled_window_accessible_get_n_children;
188   class->ref_child = gtk_scrolled_window_accessible_ref_child;
189   class->initialize = gtk_scrolled_window_accessible_initialize;
190 }
191
192 static void
193 _gtk_scrolled_window_accessible_init (GtkScrolledWindowAccessible *window)
194 {
195 }