]> Pileus Git - ~andy/gtk/blob - gtk/a11y/gailscalebutton.c
gail: Move from modules/other/gail to gtk/a11y
[~andy/gtk] / gtk / a11y / gailscalebutton.c
1 /* GAIL - The GNOME Accessibility Implementation Library
2  * Copyright 2008 Jan Arne Petersen
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 "gailscalebutton.h"
24 #include "gailadjustment.h"
25 #include "gail-private-macros.h"
26
27 #include <string.h>
28
29 static void gail_scale_button_class_init (GailScaleButtonClass *klass);
30 static void gail_scale_button_init       (GailScaleButton      *button);
31
32 /* GailWidget */
33 static void gail_scale_button_real_notify_gtk (GObject    *obj,
34                                                GParamSpec *pspec);
35
36 /* AtkObject */
37 static void gail_scale_button_real_initialize (AtkObject *obj,
38                                                gpointer   data);
39
40 /* AtkAction */
41 static void                  atk_action_interface_init        (AtkActionIface *iface);
42 static gboolean              gail_scale_button_do_action      (AtkAction      *action,
43                                                                gint           i);
44 static gint                  gail_scale_button_get_n_actions  (AtkAction      *action);
45 static const gchar* gail_scale_button_get_description(AtkAction      *action,
46                                                                gint           i);
47 static const gchar* gail_scale_button_action_get_name(AtkAction      *action,
48                                                                gint           i);
49 static const gchar* gail_scale_button_get_keybinding (AtkAction      *action,
50                                                                gint           i);
51 static gboolean              gail_scale_button_set_description(AtkAction      *action,
52                                                                gint           i,
53                                                                const gchar    *desc);
54
55 /* AtkValue */
56 static void     atk_value_interface_init                (AtkValueIface  *iface);
57 static void     gail_scale_button_get_current_value     (AtkValue       *obj,
58                                                          GValue         *value);
59 static void     gail_scale_button_get_maximum_value     (AtkValue       *obj,
60                                                          GValue         *value);
61 static void     gail_scale_button_get_minimum_value     (AtkValue       *obj,
62                                                          GValue         *value);
63 static void     gail_scale_button_get_minimum_increment (AtkValue       *obj,
64                                                          GValue         *value);
65 static gboolean gail_scale_button_set_current_value     (AtkValue       *obj,
66                                                          const GValue   *value);
67 static void     gail_scale_button_value_changed         (GtkAdjustment  *adjustment,
68                                                          gpointer       data);
69
70 G_DEFINE_TYPE_WITH_CODE (GailScaleButton, gail_scale_button, GAIL_TYPE_BUTTON,
71                          G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
72                          G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init));
73
74 static void
75 gail_scale_button_class_init (GailScaleButtonClass *klass)
76 {
77   AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
78   GailWidgetClass *widget_class = GAIL_WIDGET_CLASS (klass);
79
80   atk_object_class->initialize = gail_scale_button_real_initialize;
81
82   widget_class->notify_gtk = gail_scale_button_real_notify_gtk;
83 }
84
85 static void
86 gail_scale_button_init (GailScaleButton *button)
87 {
88 }
89
90 static void
91 gail_scale_button_real_initialize (AtkObject *obj,
92                                    gpointer  data)
93 {
94   GailScaleButton *scale_button = GAIL_SCALE_BUTTON (obj);
95   GtkScaleButton *gtk_scale_button;
96   GtkAdjustment *gtk_adjustment;
97
98   ATK_OBJECT_CLASS (gail_scale_button_parent_class)->initialize (obj, data);
99
100   gtk_scale_button = GTK_SCALE_BUTTON (data);
101   gtk_adjustment = gtk_scale_button_get_adjustment (gtk_scale_button);
102   /*
103    * If a GtkAdjustment already exists for the scale_button,
104    * create the GailAdjustment
105    */
106   if (gtk_adjustment)
107     {
108       scale_button->adjustment = gail_adjustment_new (gtk_adjustment);
109       g_signal_connect (gtk_adjustment,
110                         "value-changed",
111                         G_CALLBACK (gail_scale_button_value_changed),
112                         obj);
113     }
114   else
115     scale_button->adjustment = NULL;
116
117   obj->role = ATK_ROLE_SLIDER;
118 }
119
120 static void
121 atk_action_interface_init (AtkActionIface *iface)
122 {
123   iface->do_action = gail_scale_button_do_action;
124   iface->get_n_actions = gail_scale_button_get_n_actions;
125   iface->get_description = gail_scale_button_get_description;
126   iface->get_keybinding = gail_scale_button_get_keybinding;
127   iface->get_name = gail_scale_button_action_get_name;
128   iface->set_description = gail_scale_button_set_description;
129 }
130
131 static gboolean
132 gail_scale_button_do_action(AtkAction *action,
133                             gint       i)
134 {
135   GtkWidget *widget;
136
137   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
138   if (widget == NULL)
139     return FALSE;
140
141   if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
142     return FALSE;
143
144   switch (i) {
145     case 0:
146       g_signal_emit_by_name (widget, "popup");
147       return TRUE;
148     case 1:
149       g_signal_emit_by_name (widget, "podown");
150       return TRUE;
151     default:
152       return FALSE;
153   }
154 }
155
156 static gint
157 gail_scale_button_get_n_actions (AtkAction *action)
158 {
159   return 2;
160 }
161
162 static const gchar*
163 gail_scale_button_get_description (AtkAction *action,
164                                    gint       i)
165 {
166   return NULL;
167 }
168
169 static const gchar*
170 gail_scale_button_action_get_name (AtkAction *action,
171                                    gint       i)
172 {
173   switch (i) {
174     case 0:
175       return "popup";
176     case 1:
177       return "popdown";
178     default:
179       return NULL;
180   }
181 }
182
183 static const gchar*
184 gail_scale_button_get_keybinding (AtkAction *action,
185                                   gint       i)
186 {
187   return NULL;
188 }
189
190 static gboolean
191 gail_scale_button_set_description (AtkAction   *action,
192                                    gint         i,
193                                    const gchar *desc)
194 {
195   return FALSE;
196 }
197
198
199 static void
200 atk_value_interface_init (AtkValueIface *iface)
201 {
202   iface->get_current_value = gail_scale_button_get_current_value;
203   iface->get_maximum_value = gail_scale_button_get_maximum_value;
204   iface->get_minimum_value = gail_scale_button_get_minimum_value;
205   iface->get_minimum_increment = gail_scale_button_get_minimum_increment;
206   iface->set_current_value = gail_scale_button_set_current_value;
207 }
208
209 static void
210 gail_scale_button_get_current_value (AtkValue *obj,
211                                      GValue   *value)
212 {
213   GailScaleButton *scale_button;
214
215   g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
216
217   scale_button = GAIL_SCALE_BUTTON (obj);
218   if (scale_button->adjustment == NULL)
219     /*
220      * Adjustment has not been specified
221      */
222     return;
223
224   atk_value_get_current_value (ATK_VALUE (scale_button->adjustment), value);
225 }
226
227 static void
228 gail_scale_button_get_maximum_value (AtkValue *obj,
229                                      GValue   *value)
230 {
231   GailScaleButton *scale_button;
232
233   g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
234
235   scale_button = GAIL_SCALE_BUTTON (obj);
236   if (scale_button->adjustment == NULL)
237     /*
238      * Adjustment has not been specified
239      */
240     return;
241
242   atk_value_get_maximum_value (ATK_VALUE (scale_button->adjustment), value);
243 }
244
245 static void
246 gail_scale_button_get_minimum_value (AtkValue *obj,
247                                      GValue   *value)
248 {
249   GailScaleButton *scale_button;
250
251   g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
252
253   scale_button = GAIL_SCALE_BUTTON (obj);
254   if (scale_button->adjustment == NULL)
255     /*
256      * Adjustment has not been specified
257      */
258     return;
259
260   atk_value_get_minimum_value (ATK_VALUE (scale_button->adjustment), value);
261 }
262
263 static void
264 gail_scale_button_get_minimum_increment (AtkValue *obj,
265                                          GValue   *value)
266 {
267   GailScaleButton *scale_button;
268
269   g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
270
271   scale_button = GAIL_SCALE_BUTTON (obj);
272   if (scale_button->adjustment == NULL)
273     /*
274      * Adjustment has not been specified
275      */
276     return;
277
278   atk_value_get_minimum_increment (ATK_VALUE (scale_button->adjustment), value);
279 }
280
281 static gboolean
282 gail_scale_button_set_current_value (AtkValue     *obj,
283                                      const GValue *value)
284 {
285   GailScaleButton *scale_button;
286
287   g_return_val_if_fail (GAIL_IS_SCALE_BUTTON (obj), FALSE);
288
289   scale_button = GAIL_SCALE_BUTTON (obj);
290   if (scale_button->adjustment == NULL)
291     /*
292      * Adjustment has not been specified
293      */
294     return FALSE;
295
296   return atk_value_set_current_value (ATK_VALUE (scale_button->adjustment), value);
297 }
298
299 static void
300 gail_scale_button_real_notify_gtk (GObject    *obj,
301                                    GParamSpec *pspec)
302 {
303   GtkScaleButton *gtk_scale_button;
304   GailScaleButton *scale_button;
305
306   g_return_if_fail (GTK_IS_SCALE_BUTTON (obj));
307
308   gtk_scale_button = GTK_SCALE_BUTTON (obj);
309   scale_button = GAIL_SCALE_BUTTON (gtk_widget_get_accessible (GTK_WIDGET (gtk_scale_button)));
310
311   if (strcmp (pspec->name, "adjustment") == 0)
312     {
313       /*
314        * Get rid of the GailAdjustment for the GtkAdjustment
315        * which was associated with the scale_button.
316        */
317       GtkAdjustment* gtk_adjustment;
318
319       if (scale_button->adjustment)
320         {
321           g_object_unref (scale_button->adjustment);
322           scale_button->adjustment = NULL;
323         }
324       /*
325        * Create the GailAdjustment when notify for "adjustment" property
326        * is received
327        */
328       gtk_adjustment = gtk_scale_button_get_adjustment (gtk_scale_button);
329       scale_button->adjustment = gail_adjustment_new (gtk_adjustment);
330       g_signal_connect (gtk_adjustment,
331                         "value-changed",
332                         G_CALLBACK (gail_scale_button_value_changed),
333                         scale_button);
334     }
335   else
336     {
337       GAIL_WIDGET_CLASS (gail_scale_button_parent_class)->notify_gtk (obj, pspec);
338     }
339 }
340
341 static void
342 gail_scale_button_value_changed (GtkAdjustment    *adjustment,
343                                  gpointer         data)
344 {
345   GailScaleButton *scale_button;
346
347   gail_return_if_fail (adjustment != NULL);
348   gail_return_if_fail (data != NULL);
349
350   scale_button = GAIL_SCALE_BUTTON (data);
351
352   g_object_notify (G_OBJECT (scale_button), "accessible-value");
353 }
354