1 /* GTK+ - accessibility implementations
2  * Copyright 2012 Red Hat, 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 <glib/gi18n-lib.h>
21 #include <gtk/gtk.h>
22 #include "gtkcolorswatchprivate.h"
23 #include "gtkcolorswatchaccessibleprivate.h"
24 
25 static void atk_action_interface_init (AtkActionIface *iface);
26 
G_DEFINE_TYPE_WITH_CODE(GtkColorSwatchAccessible,_gtk_color_swatch_accessible,GTK_TYPE_WIDGET_ACCESSIBLE,G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION,atk_action_interface_init))27 G_DEFINE_TYPE_WITH_CODE (GtkColorSwatchAccessible, _gtk_color_swatch_accessible, GTK_TYPE_WIDGET_ACCESSIBLE,
28                          G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
29 
30 static void
31 state_changed_cb (GtkWidget     *widget,
32                   GtkStateFlags  previous_flags)
33 {
34   AtkObject *accessible;
35   GtkStateFlags flags;
36   gboolean was_selected;
37   gboolean selected;
38 
39   flags = gtk_widget_get_state_flags (widget);
40 
41   was_selected = (previous_flags & GTK_STATE_FLAG_SELECTED) != 0;
42   selected = (flags & GTK_STATE_FLAG_SELECTED) != 0;
43 
44   accessible = gtk_widget_get_accessible (widget);
45   if (selected && !was_selected)
46     atk_object_notify_state_change (accessible, ATK_STATE_CHECKED, TRUE);
47   else if (!selected && was_selected)
48     atk_object_notify_state_change (accessible, ATK_STATE_CHECKED, FALSE);
49 }
50 
51 static void
gtk_color_swatch_accessible_initialize(AtkObject * obj,gpointer data)52 gtk_color_swatch_accessible_initialize (AtkObject *obj,
53                                         gpointer   data)
54 {
55   ATK_OBJECT_CLASS (_gtk_color_swatch_accessible_parent_class)->initialize (obj, data);
56 
57   g_signal_connect (data, "state-flags-changed",
58                     G_CALLBACK (state_changed_cb), NULL);
59 
60   atk_object_set_role (obj, ATK_ROLE_RADIO_BUTTON);
61 }
62 
63 static AtkStateSet *
gtk_color_swatch_accessible_ref_state_set(AtkObject * accessible)64 gtk_color_swatch_accessible_ref_state_set (AtkObject *accessible)
65 {
66   GtkWidget *widget;
67   AtkStateSet *state_set;
68 
69   state_set = ATK_OBJECT_CLASS (_gtk_color_swatch_accessible_parent_class)->ref_state_set (accessible);
70 
71   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
72   if (widget != NULL)
73     {
74       if ((gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_SELECTED) != 0)
75         atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
76     }
77 
78   return state_set;
79 }
80 
81 static void
gtk_color_swatch_accessible_notify_gtk(GObject * obj,GParamSpec * pspec)82 gtk_color_swatch_accessible_notify_gtk (GObject    *obj,
83                                         GParamSpec *pspec)
84 {
85   GtkWidget *widget = GTK_WIDGET (obj);
86   AtkObject *atk_obj = gtk_widget_get_accessible (widget);
87 
88   if (strcmp (pspec->name, "selectable") == 0)
89     {
90       if (gtk_color_swatch_get_selectable (GTK_COLOR_SWATCH (widget)))
91         atk_object_set_role (atk_obj, ATK_ROLE_RADIO_BUTTON);
92       else
93         atk_object_set_role (atk_obj, ATK_ROLE_PUSH_BUTTON);
94     }
95   else
96     GTK_WIDGET_ACCESSIBLE_CLASS (_gtk_color_swatch_accessible_parent_class)->notify_gtk (obj, pspec);
97 }
98 
99 static void
_gtk_color_swatch_accessible_class_init(GtkColorSwatchAccessibleClass * klass)100 _gtk_color_swatch_accessible_class_init (GtkColorSwatchAccessibleClass *klass)
101 {
102   AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass);
103   GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass *)klass;
104 
105   atk_class->initialize = gtk_color_swatch_accessible_initialize;
106   atk_class->ref_state_set = gtk_color_swatch_accessible_ref_state_set;
107 
108   widget_class->notify_gtk = gtk_color_swatch_accessible_notify_gtk;
109 }
110 
111 static void
_gtk_color_swatch_accessible_init(GtkColorSwatchAccessible * scale)112 _gtk_color_swatch_accessible_init (GtkColorSwatchAccessible *scale)
113 {
114 }
115 
116 static gint
gtk_color_swatch_accessible_get_n_actions(AtkAction * action)117 gtk_color_swatch_accessible_get_n_actions (AtkAction *action)
118 {
119   return 3;
120 }
121 
122 static const gchar *
gtk_color_swatch_accessible_get_keybinding(AtkAction * action,gint i)123 gtk_color_swatch_accessible_get_keybinding (AtkAction *action,
124                                             gint       i)
125 {
126   return NULL;
127 }
128 
129 static const gchar *
gtk_color_swatch_accessible_get_name(AtkAction * action,gint i)130 gtk_color_swatch_accessible_get_name (AtkAction *action,
131                                       gint       i)
132 {
133   switch (i)
134     {
135     case 0: return "select";
136     case 1: return "activate";
137     case 2: return "customize";
138     default: return NULL;
139     }
140 }
141 
142 static const gchar *
gtk_color_swatch_accessible_get_localized_name(AtkAction * action,gint i)143 gtk_color_swatch_accessible_get_localized_name (AtkAction *action,
144                                                 gint       i)
145 {
146   switch (i)
147     {
148     case 0: return C_("Action name", "Select");
149     case 1: return C_("Action name", "Activate");
150     case 2: return C_("Action name", "Customize");
151     default: return NULL;
152     }
153 }
154 
155 static const gchar *
gtk_color_swatch_accessible_get_description(AtkAction * action,gint i)156 gtk_color_swatch_accessible_get_description (AtkAction *action,
157                                              gint       i)
158 {
159   switch (i)
160     {
161     case 0: return C_("Action description", "Selects the color");
162     case 1: return C_("Action description", "Activates the color");
163     case 2: return C_("Action description", "Customizes the color");
164     default: return NULL;
165     }
166 }
167 
168 static gboolean
gtk_color_swatch_accessible_do_action(AtkAction * action,gint i)169 gtk_color_swatch_accessible_do_action (AtkAction *action,
170                                        gint       i)
171 {
172   GtkWidget *widget;
173 
174   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
175   if (widget == NULL)
176     return FALSE;
177 
178   switch (i)
179     {
180     case 0:
181       gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_SELECTED, FALSE);
182       break;
183 
184     case 1:
185       g_signal_emit_by_name (widget, "activate");
186       break;
187 
188     case 2:
189       g_signal_emit_by_name (widget, "customize");
190       break;
191 
192     default:
193       return FALSE;
194     }
195 
196   return TRUE;
197 }
198 
199 static void
atk_action_interface_init(AtkActionIface * iface)200 atk_action_interface_init (AtkActionIface *iface)
201 {
202   iface->do_action = gtk_color_swatch_accessible_do_action;
203   iface->get_n_actions = gtk_color_swatch_accessible_get_n_actions;
204   iface->get_keybinding = gtk_color_swatch_accessible_get_keybinding;
205   iface->get_name = gtk_color_swatch_accessible_get_name;
206   iface->get_localized_name = gtk_color_swatch_accessible_get_localized_name;
207   iface->get_description = gtk_color_swatch_accessible_get_description;
208 }
209