]> Pileus Git - ~andy/gtk/blob - modules/other/gail/gailscalebutton.c
Bug #519090. Add accessibility support to GtkScaleButton. Support action
[~andy/gtk] / modules / other / gail / 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_notify_gtk (GObject    *obj,
34                                           GParamSpec *pspec);
35
36 /* AtkObject */
37 static void gail_scale_button_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 G_CONST_RETURN gchar* gail_scale_button_get_description(AtkAction      *action,
46                                                                gint           i);
47 static G_CONST_RETURN gchar* gail_scale_button_action_get_name(AtkAction      *action,
48                                                                gint           i);
49 static G_CONST_RETURN 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
68 G_DEFINE_TYPE_WITH_CODE (GailScaleButton, gail_scale_button, GAIL_TYPE_BUTTON,
69                          G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
70                          G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init));
71
72 static void
73 gail_scale_button_class_init (GailScaleButtonClass *klass)
74 {
75   AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
76   GailWidgetClass *widget_class = GAIL_WIDGET_CLASS (klass);
77
78   atk_object_class->initialize = gail_scale_button_initialize;
79
80   widget_class->notify_gtk = gail_scale_button_notify_gtk;
81 }
82
83 static void
84 gail_scale_button_init (GailScaleButton *button)
85 {
86 }
87
88 static void
89 gail_scale_button_initialize (AtkObject *obj,
90                               gpointer   data)
91 {
92   ATK_OBJECT_CLASS (gail_scale_button_parent_class)->initialize (obj, data);
93
94   obj->role = ATK_ROLE_SLIDER;
95 }
96
97 static void
98 atk_action_interface_init (AtkActionIface *iface)
99 {
100   iface->do_action = gail_scale_button_do_action;
101   iface->get_n_actions = gail_scale_button_get_n_actions;
102   iface->get_description = gail_scale_button_get_description;
103   iface->get_keybinding = gail_scale_button_get_keybinding;
104   iface->get_name = gail_scale_button_action_get_name;
105   iface->set_description = gail_scale_button_set_description;
106 }
107
108 static gboolean
109 gail_scale_button_do_action(AtkAction *action,
110                             gint       i)
111 {
112   GtkWidget *widget;
113
114   widget = GTK_ACCESSIBLE (action)->widget;
115   if (widget == NULL)
116     return FALSE;
117
118   if (!GTK_WIDGET_IS_SENSITIVE (widget) || !GTK_WIDGET_VISIBLE (widget))
119     return FALSE;
120
121   switch (i) {
122     case 0:
123       g_signal_emit_by_name (widget, "popup");
124       return TRUE;
125     case 1:
126       g_signal_emit_by_name (widget, "podown");
127       return TRUE;
128     default:
129       return FALSE;
130   }
131 }
132
133 static gint
134 gail_scale_button_get_n_actions (AtkAction *action)
135 {
136   return 2;
137 }
138
139 static G_CONST_RETURN gchar*
140 gail_scale_button_get_description (AtkAction *action,
141                                    gint       i)
142 {
143   return NULL;
144 }
145
146 static G_CONST_RETURN gchar*
147 gail_scale_button_action_get_name (AtkAction *action,
148                                    gint       i)
149 {
150   switch (i) {
151     case 0:
152       return "popup";
153     case 1:
154       return "popdown";
155     default:
156       return NULL;
157   }
158 }
159
160 static G_CONST_RETURN gchar*
161 gail_scale_button_get_keybinding (AtkAction *action,
162                                   gint       i)
163 {
164   return NULL;
165 }
166
167 static gboolean
168 gail_scale_button_set_description (AtkAction   *action,
169                                    gint         i,
170                                    const gchar *desc)
171 {
172   return FALSE;
173 }
174
175
176 static void
177 atk_value_interface_init (AtkValueIface *iface)
178 {
179   iface->get_current_value = gail_scale_button_get_current_value;
180   iface->get_maximum_value = gail_scale_button_get_maximum_value;
181   iface->get_minimum_value = gail_scale_button_get_minimum_value;
182   iface->get_minimum_increment = gail_scale_button_get_minimum_increment;
183   iface->set_current_value = gail_scale_button_set_current_value;
184 }
185
186 static void
187 gail_scale_button_get_current_value (AtkValue *obj,
188                                      GValue   *value)
189 {
190   GailScaleButton *scale_button;
191   GtkScaleButton *gtk_scale_button;
192
193   g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
194
195   scale_button = GAIL_SCALE_BUTTON (obj);
196   gtk_scale_button = GTK_SCALE_BUTTON (GTK_ACCESSIBLE (obj)->widget);
197
198   g_value_set_double (g_value_init (value, G_TYPE_DOUBLE),
199                       gtk_scale_button_get_value (gtk_scale_button));
200 }
201
202 static void
203 gail_scale_button_get_maximum_value (AtkValue *obj,
204                                      GValue   *value)
205 {
206   GtkWidget *gtk_widget;
207   GtkAdjustment *adj;
208
209   g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
210
211   gtk_widget = GTK_ACCESSIBLE (obj)->widget;
212   if (gtk_widget == NULL)
213     return;
214
215   adj = gtk_scale_button_get_adjustment (GTK_SCALE_BUTTON (gtk_widget));
216   if (adj != NULL)
217     g_value_set_double (g_value_init (value, G_TYPE_DOUBLE),
218                         adj->upper);
219 }
220
221 static void
222 gail_scale_button_get_minimum_value (AtkValue *obj,
223                                      GValue   *value)
224 {
225   GtkWidget *gtk_widget;
226   GtkAdjustment *adj;
227
228   g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
229
230   gtk_widget = GTK_ACCESSIBLE (obj)->widget;
231   if (gtk_widget == NULL)
232     return;
233
234   adj = gtk_scale_button_get_adjustment (GTK_SCALE_BUTTON (gtk_widget));
235   if (adj != NULL)
236     g_value_set_double (g_value_init (value, G_TYPE_DOUBLE),
237                         adj->lower);
238 }
239
240 static void
241 gail_scale_button_get_minimum_increment (AtkValue *obj,
242                                          GValue   *value)
243 {
244   GtkWidget *gtk_widget;
245   GtkAdjustment *adj;
246
247   g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj));
248
249   gtk_widget = GTK_ACCESSIBLE (obj)->widget;
250   if (gtk_widget == NULL)
251     return;
252
253   adj = gtk_scale_button_get_adjustment (GTK_SCALE_BUTTON (gtk_widget));
254   if (adj != NULL)
255     g_value_set_double (g_value_init (value, G_TYPE_DOUBLE),
256                         adj->step_increment);
257 }
258
259 static gboolean
260 gail_scale_button_set_current_value (AtkValue     *obj,
261                                      const GValue *value)
262 {
263   GtkWidget *gtk_widget;
264
265   g_return_val_if_fail (GAIL_IS_SCALE_BUTTON (obj), FALSE);
266
267   gtk_widget = GTK_ACCESSIBLE (obj)->widget;
268   if (gtk_widget == NULL)
269     return FALSE;
270
271   if (G_VALUE_HOLDS_DOUBLE (value))
272     {
273       gtk_scale_button_set_value (GTK_SCALE_BUTTON (gtk_widget), g_value_get_double (value));
274       return TRUE;
275     }
276   return FALSE;
277 }
278
279 static void
280 gail_scale_button_notify_gtk (GObject    *obj,
281                               GParamSpec *pspec)
282 {
283   GtkScaleButton *gtk_scale_button;
284   GailScaleButton *scale_button;
285
286   g_return_if_fail (GTK_IS_SCALE_BUTTON (obj));
287
288   gtk_scale_button = GTK_SCALE_BUTTON (obj);
289   scale_button = GAIL_SCALE_BUTTON (gtk_widget_get_accessible (GTK_WIDGET (gtk_scale_button)));
290
291   if (strcmp (pspec->name, "value") == 0)
292     {
293       g_object_notify (G_OBJECT (scale_button), "accessible-value");
294     }
295   else
296     {
297       GAIL_WIDGET_CLASS (gail_scale_button_parent_class)->notify_gtk (obj, pspec);
298     }
299 }
300
301