From a0b3a069f11806729c09a579483dd7a33276f87c Mon Sep 17 00:00:00 2001 From: Li Yuan Date: Thu, 26 Feb 2009 07:58:30 +0000 Subject: [PATCH] Bug #519090. Add accessibility support to GtkScaleButton. Support action 2009-02-26 Li Yuan * Makefile.am: * gail.c: (gail_accessibility_module_init): * gail.h: * gailscalebutton.c: (gail_scale_button_class_init), (gail_scale_button_init), (gail_scale_button_initialize), (atk_action_interface_init), (gail_scale_button_do_action), (gail_scale_button_get_n_actions), (gail_scale_button_get_description), (gail_scale_button_action_get_name), (gail_scale_button_get_keybinding), (gail_scale_button_set_description), (atk_value_interface_init), (gail_scale_button_get_current_value), (gail_scale_button_get_maximum_value), (gail_scale_button_get_minimum_value), (gail_scale_button_get_minimum_increment), (gail_scale_button_set_current_value), (gail_scale_button_notify_gtk): * gailscalebutton.h: Bug #519090. Add accessibility support to GtkScaleButton. Support action and value interfaces. Patch from Jan Arne Petersen. svn path=/trunk/; revision=22411 --- modules/other/gail/ChangeLog | 23 ++ modules/other/gail/Makefile.am | 2 + modules/other/gail/gail.c | 2 + modules/other/gail/gail.h | 1 + modules/other/gail/gailscalebutton.c | 301 +++++++++++++++++++++++++++ modules/other/gail/gailscalebutton.h | 52 +++++ 6 files changed, 381 insertions(+) create mode 100644 modules/other/gail/gailscalebutton.c create mode 100644 modules/other/gail/gailscalebutton.h diff --git a/modules/other/gail/ChangeLog b/modules/other/gail/ChangeLog index a4449dd585..7833ca4a9b 100644 --- a/modules/other/gail/ChangeLog +++ b/modules/other/gail/ChangeLog @@ -1,3 +1,26 @@ +2009-02-26 Li Yuan + + * Makefile.am: + * gail.c: (gail_accessibility_module_init): + * gail.h: + * gailscalebutton.c: (gail_scale_button_class_init), + (gail_scale_button_init), (gail_scale_button_initialize), + (atk_action_interface_init), (gail_scale_button_do_action), + (gail_scale_button_get_n_actions), + (gail_scale_button_get_description), + (gail_scale_button_action_get_name), + (gail_scale_button_get_keybinding), + (gail_scale_button_set_description), (atk_value_interface_init), + (gail_scale_button_get_current_value), + (gail_scale_button_get_maximum_value), + (gail_scale_button_get_minimum_value), + (gail_scale_button_get_minimum_increment), + (gail_scale_button_set_current_value), + (gail_scale_button_notify_gtk): + * gailscalebutton.h: + Bug #519090. Add accessibility support to GtkScaleButton. + Support action and value interfaces. Patch from Jan Arne Petersen. + 2009-02-26 Li Yuan * gailbutton.c: (idle_do_action): diff --git a/modules/other/gail/Makefile.am b/modules/other/gail/Makefile.am index ea88fc0725..a6f875791e 100644 --- a/modules/other/gail/Makefile.am +++ b/modules/other/gail/Makefile.am @@ -52,6 +52,7 @@ gail_c_sources = \ gailrange.c \ gailrenderercell.c \ gailscale.c \ + gailscalebutton.c \ gailscrollbar.c \ gailscrolledwindow.c \ gailseparator.c \ @@ -112,6 +113,7 @@ gail_private_h_sources = \ gailrange.h \ gailrenderercell.h \ gailscale.h \ + gailscalebutton.h \ gailscrollbar.h \ gailscrolledwindow.h \ gailseparator.h \ diff --git a/modules/other/gail/gail.c b/modules/other/gail/gail.c index 1218180230..37e948d9c4 100644 --- a/modules/other/gail/gail.c +++ b/modules/other/gail/gail.c @@ -90,6 +90,7 @@ GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU, GailMenu, gail_menu, GTK_TYPE_MENU) GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_WINDOW, GailWindow, gail_window, GTK_TYPE_BIN) GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_RANGE, GailRange, gail_range, GTK_TYPE_RANGE) GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCALE, GailScale, gail_scale, GTK_TYPE_SCALE) +GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_SCALE_BUTTON, GailScaleButton, gail_scale_button, GTK_TYPE_SCALE_BUTTON) GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_CLIST, GailCList, gail_clist, GTK_TYPE_CLIST) GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_LABEL, GailLabel, gail_label, GTK_TYPE_LABEL) GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_STATUSBAR, GailStatusbar, gail_statusbar, GTK_TYPE_STATUSBAR) @@ -903,6 +904,7 @@ gail_accessibility_module_init (void) GAIL_WIDGET_SET_FACTORY (GTK_TYPE_WINDOW, gail_window); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_RANGE, gail_range); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCALE, gail_scale); + GAIL_WIDGET_SET_FACTORY (GTK_TYPE_SCALE_BUTTON, gail_scale_button); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CLIST, gail_clist); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_LABEL, gail_label); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_STATUSBAR, gail_statusbar); diff --git a/modules/other/gail/gail.h b/modules/other/gail/gail.h index 69da60a739..97da104c3d 100644 --- a/modules/other/gail/gail.h +++ b/modules/other/gail/gail.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/modules/other/gail/gailscalebutton.c b/modules/other/gail/gailscalebutton.c new file mode 100644 index 0000000000..aa0ac2fb7b --- /dev/null +++ b/modules/other/gail/gailscalebutton.c @@ -0,0 +1,301 @@ +/* GAIL - The GNOME Accessibility Implementation Library + * Copyright 2008 Jan Arne Petersen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include +#include "gailscalebutton.h" +#include "gailadjustment.h" +#include "gail-private-macros.h" + +#include + +static void gail_scale_button_class_init (GailScaleButtonClass *klass); +static void gail_scale_button_init (GailScaleButton *button); + +/* GailWidget */ +static void gail_scale_button_notify_gtk (GObject *obj, + GParamSpec *pspec); + +/* AtkObject */ +static void gail_scale_button_initialize (AtkObject *obj, + gpointer data); + +/* AtkAction */ +static void atk_action_interface_init (AtkActionIface *iface); +static gboolean gail_scale_button_do_action (AtkAction *action, + gint i); +static gint gail_scale_button_get_n_actions (AtkAction *action); +static G_CONST_RETURN gchar* gail_scale_button_get_description(AtkAction *action, + gint i); +static G_CONST_RETURN gchar* gail_scale_button_action_get_name(AtkAction *action, + gint i); +static G_CONST_RETURN gchar* gail_scale_button_get_keybinding (AtkAction *action, + gint i); +static gboolean gail_scale_button_set_description(AtkAction *action, + gint i, + const gchar *desc); + +/* AtkValue */ +static void atk_value_interface_init (AtkValueIface *iface); +static void gail_scale_button_get_current_value (AtkValue *obj, + GValue *value); +static void gail_scale_button_get_maximum_value (AtkValue *obj, + GValue *value); +static void gail_scale_button_get_minimum_value (AtkValue *obj, + GValue *value); +static void gail_scale_button_get_minimum_increment (AtkValue *obj, + GValue *value); +static gboolean gail_scale_button_set_current_value (AtkValue *obj, + const GValue *value); + +G_DEFINE_TYPE_WITH_CODE (GailScaleButton, gail_scale_button, GAIL_TYPE_BUTTON, + G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init) + G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init)); + +static void +gail_scale_button_class_init (GailScaleButtonClass *klass) +{ + AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass); + GailWidgetClass *widget_class = GAIL_WIDGET_CLASS (klass); + + atk_object_class->initialize = gail_scale_button_initialize; + + widget_class->notify_gtk = gail_scale_button_notify_gtk; +} + +static void +gail_scale_button_init (GailScaleButton *button) +{ +} + +static void +gail_scale_button_initialize (AtkObject *obj, + gpointer data) +{ + ATK_OBJECT_CLASS (gail_scale_button_parent_class)->initialize (obj, data); + + obj->role = ATK_ROLE_SLIDER; +} + +static void +atk_action_interface_init (AtkActionIface *iface) +{ + iface->do_action = gail_scale_button_do_action; + iface->get_n_actions = gail_scale_button_get_n_actions; + iface->get_description = gail_scale_button_get_description; + iface->get_keybinding = gail_scale_button_get_keybinding; + iface->get_name = gail_scale_button_action_get_name; + iface->set_description = gail_scale_button_set_description; +} + +static gboolean +gail_scale_button_do_action(AtkAction *action, + gint i) +{ + GtkWidget *widget; + + widget = GTK_ACCESSIBLE (action)->widget; + if (widget == NULL) + return FALSE; + + if (!GTK_WIDGET_IS_SENSITIVE (widget) || !GTK_WIDGET_VISIBLE (widget)) + return FALSE; + + switch (i) { + case 0: + g_signal_emit_by_name (widget, "popup"); + return TRUE; + case 1: + g_signal_emit_by_name (widget, "podown"); + return TRUE; + default: + return FALSE; + } +} + +static gint +gail_scale_button_get_n_actions (AtkAction *action) +{ + return 2; +} + +static G_CONST_RETURN gchar* +gail_scale_button_get_description (AtkAction *action, + gint i) +{ + return NULL; +} + +static G_CONST_RETURN gchar* +gail_scale_button_action_get_name (AtkAction *action, + gint i) +{ + switch (i) { + case 0: + return "popup"; + case 1: + return "popdown"; + default: + return NULL; + } +} + +static G_CONST_RETURN gchar* +gail_scale_button_get_keybinding (AtkAction *action, + gint i) +{ + return NULL; +} + +static gboolean +gail_scale_button_set_description (AtkAction *action, + gint i, + const gchar *desc) +{ + return FALSE; +} + + +static void +atk_value_interface_init (AtkValueIface *iface) +{ + iface->get_current_value = gail_scale_button_get_current_value; + iface->get_maximum_value = gail_scale_button_get_maximum_value; + iface->get_minimum_value = gail_scale_button_get_minimum_value; + iface->get_minimum_increment = gail_scale_button_get_minimum_increment; + iface->set_current_value = gail_scale_button_set_current_value; +} + +static void +gail_scale_button_get_current_value (AtkValue *obj, + GValue *value) +{ + GailScaleButton *scale_button; + GtkScaleButton *gtk_scale_button; + + g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj)); + + scale_button = GAIL_SCALE_BUTTON (obj); + gtk_scale_button = GTK_SCALE_BUTTON (GTK_ACCESSIBLE (obj)->widget); + + g_value_set_double (g_value_init (value, G_TYPE_DOUBLE), + gtk_scale_button_get_value (gtk_scale_button)); +} + +static void +gail_scale_button_get_maximum_value (AtkValue *obj, + GValue *value) +{ + GtkWidget *gtk_widget; + GtkAdjustment *adj; + + g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj)); + + gtk_widget = GTK_ACCESSIBLE (obj)->widget; + if (gtk_widget == NULL) + return; + + adj = gtk_scale_button_get_adjustment (GTK_SCALE_BUTTON (gtk_widget)); + if (adj != NULL) + g_value_set_double (g_value_init (value, G_TYPE_DOUBLE), + adj->upper); +} + +static void +gail_scale_button_get_minimum_value (AtkValue *obj, + GValue *value) +{ + GtkWidget *gtk_widget; + GtkAdjustment *adj; + + g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj)); + + gtk_widget = GTK_ACCESSIBLE (obj)->widget; + if (gtk_widget == NULL) + return; + + adj = gtk_scale_button_get_adjustment (GTK_SCALE_BUTTON (gtk_widget)); + if (adj != NULL) + g_value_set_double (g_value_init (value, G_TYPE_DOUBLE), + adj->lower); +} + +static void +gail_scale_button_get_minimum_increment (AtkValue *obj, + GValue *value) +{ + GtkWidget *gtk_widget; + GtkAdjustment *adj; + + g_return_if_fail (GAIL_IS_SCALE_BUTTON (obj)); + + gtk_widget = GTK_ACCESSIBLE (obj)->widget; + if (gtk_widget == NULL) + return; + + adj = gtk_scale_button_get_adjustment (GTK_SCALE_BUTTON (gtk_widget)); + if (adj != NULL) + g_value_set_double (g_value_init (value, G_TYPE_DOUBLE), + adj->step_increment); +} + +static gboolean +gail_scale_button_set_current_value (AtkValue *obj, + const GValue *value) +{ + GtkWidget *gtk_widget; + + g_return_val_if_fail (GAIL_IS_SCALE_BUTTON (obj), FALSE); + + gtk_widget = GTK_ACCESSIBLE (obj)->widget; + if (gtk_widget == NULL) + return FALSE; + + if (G_VALUE_HOLDS_DOUBLE (value)) + { + gtk_scale_button_set_value (GTK_SCALE_BUTTON (gtk_widget), g_value_get_double (value)); + return TRUE; + } + return FALSE; +} + +static void +gail_scale_button_notify_gtk (GObject *obj, + GParamSpec *pspec) +{ + GtkScaleButton *gtk_scale_button; + GailScaleButton *scale_button; + + g_return_if_fail (GTK_IS_SCALE_BUTTON (obj)); + + gtk_scale_button = GTK_SCALE_BUTTON (obj); + scale_button = GAIL_SCALE_BUTTON (gtk_widget_get_accessible (GTK_WIDGET (gtk_scale_button))); + + if (strcmp (pspec->name, "value") == 0) + { + g_object_notify (G_OBJECT (scale_button), "accessible-value"); + } + else + { + GAIL_WIDGET_CLASS (gail_scale_button_parent_class)->notify_gtk (obj, pspec); + } +} + + diff --git a/modules/other/gail/gailscalebutton.h b/modules/other/gail/gailscalebutton.h new file mode 100644 index 0000000000..d0ec878799 --- /dev/null +++ b/modules/other/gail/gailscalebutton.h @@ -0,0 +1,52 @@ +/* GAIL - The GNOME Accessibility Implementation Library + * Copyright 2008 Jan Arne Petersen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GAIL_SCALE_BUTTON_H__ +#define __GAIL_SCALE_BUTTON_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GAIL_TYPE_SCALE_BUTTON (gail_scale_button_get_type ()) +#define GAIL_SCALE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_SCALE_BUTTON, GailScaleButton)) +#define GAIL_SCALE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_SCALE_BUTTON, GailScaleButtonClass)) +#define GAIL_IS_SCALE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_SCALE_BUTTON)) +#define GAIL_IS_SCALE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_SCALE_BUTTON)) +#define GAIL_SCALE_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_SCALE_BUTTON, GailScaleButtonClass)) + +typedef struct _GailScaleButton GailScaleButton; +typedef struct _GailScaleButtonClass GailScaleButtonClass; + +struct _GailScaleButton +{ + GailButton parent; +}; + +struct _GailScaleButtonClass +{ + GailButtonClass parent_class; +}; + +GType gail_scale_button_get_type (void); + +G_END_DECLS + +#endif /* __GAIL_SCALE_BUTTON_H__ */