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