libgnomeui accessibility patch
- From: Federico Mena Quintero <federico ximian com>
- To: desktop-devel-list gnome org
- Cc: andersca gnu org
- Subject: libgnomeui accessibility patch
- Date: 09 May 2002 13:11:03 -0500
Hi, Anders, everyone,
We have a rather large patch that adds accessibility support for
libgnomeui, and would like to see it integrated with the main source
base. Right now it lives in the ximian-atk-branch of libgnomeui.
The patch is attached. It is not with respect to HEAD, but rather to a
March 30 snapshot. However, most of the stuff should still make sense,
and I can merge it myself if you think it is appropriate.
Your opinions on this would be very valuable :)
Thanks,
Federico
diff -pNaur libgnomeui/libgnomeui/Makefile.am libgnomeui-new/libgnomeui/Makefile.am
--- libgnomeui/libgnomeui/Makefile.am Thu Apr 18 05:08:48 2002
+++ libgnomeui-new/libgnomeui/Makefile.am Thu Apr 18 05:08:30 2002
@@ -38,6 +38,8 @@ INCLUDES = \
EXTRA_HEADERS =
libgnomeui_2_la_SOURCES = \
+ libgnomeui-access.c \
+ libgnomeui-access.h \
gnometypebuiltins.h \
gnometypebuiltins.c \
gnome-about.c \
diff -pNaur libgnomeui/libgnomeui/gnome-color-picker.c libgnomeui-new/libgnomeui/gnome-color-picker.c
--- libgnomeui/libgnomeui/gnome-color-picker.c Thu Apr 18 05:08:48 2002
+++ libgnomeui-new/libgnomeui/gnome-color-picker.c Thu Apr 18 05:08:30 2002
@@ -49,6 +49,8 @@
#include <libgnomeuiP.h>
+#include "libgnomeui-access.h"
+
/* These are the dimensions of the color sample in the color picker */
#define COLOR_PICKER_WIDTH 20
#define COLOR_PICKER_HEIGHT 12
@@ -444,10 +446,17 @@ gnome_color_picker_instance_init (GnomeC
{
GtkWidget *alignment;
GtkWidget *frame;
- /* Create the widgets */
+ /* Create the widgets */
cp->_priv = g_new0(GnomeColorPickerPrivate, 1);
+ /*
+ * The application may very well override these.
+ */
+ _add_atk_name_desc (GTK_WIDGET (cp),
+ _("Color Selector"),
+ _("Open a dialog to specify the color"));
+
alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_set_border_width (GTK_CONTAINER (alignment), COLOR_PICKER_PAD);
gtk_container_add (GTK_CONTAINER (cp), alignment);
diff -pNaur libgnomeui/libgnomeui/gnome-dateedit.c libgnomeui-new/libgnomeui/gnome-dateedit.c
--- libgnomeui/libgnomeui/gnome-dateedit.c Thu Apr 18 05:08:48 2002
+++ libgnomeui-new/libgnomeui/gnome-dateedit.c Thu Apr 18 05:08:30 2002
@@ -45,6 +45,9 @@
#include <libgnome/gnome-i18n.h>
#include "gnometypebuiltins.h"
+
+#include "libgnomeui-access.h"
+
struct _GnomeDateEditPrivate {
GtkWidget *date_entry;
GtkWidget *date_button;
@@ -727,15 +730,24 @@ create_children (GnomeDateEdit *gde)
GtkWidget *arrow;
gde->_priv->date_entry = gtk_entry_new ();
+ _add_atk_name_desc (GTK_WIDGET (gde->_priv->date_entry), _("Date"), NULL);
+
gtk_widget_set_size_request (gde->_priv->date_entry, 90, -1);
gtk_box_pack_start (GTK_BOX (gde), gde->_priv->date_entry, TRUE, TRUE, 0);
gtk_widget_show (gde->_priv->date_entry);
+
gde->_priv->date_button = gtk_button_new ();
g_signal_connect (gde->_priv->date_button, "clicked",
G_CALLBACK (select_clicked), gde);
gtk_box_pack_start (GTK_BOX (gde), gde->_priv->date_button, FALSE, FALSE, 0);
+ _add_atk_name_desc (GTK_WIDGET (gde->_priv->date_button),
+ _("Select Date"), _("Select the date from a calendar"));
+
+ _add_atk_relation (gde->_priv->date_button, gde->_priv->date_entry,
+ ATK_RELATION_CONTROLLER_FOR, ATK_RELATION_CONTROLLED_BY);
+
hbox = gtk_hbox_new (FALSE, 3);
gtk_container_add (GTK_CONTAINER (gde->_priv->date_button), hbox);
gtk_widget_show (hbox);
@@ -755,11 +767,19 @@ create_children (GnomeDateEdit *gde)
gtk_widget_show (gde->_priv->date_button);
gde->_priv->time_entry = gtk_entry_new ();
+ _add_atk_name_desc (GTK_WIDGET (gde->_priv->time_entry), _("Time"), NULL);
+
gtk_entry_set_max_length (GTK_ENTRY (gde->_priv->time_entry), 12);
gtk_widget_set_size_request (gde->_priv->time_entry, 88, -1);
gtk_box_pack_start (GTK_BOX (gde), gde->_priv->time_entry, TRUE, TRUE, 0);
gde->_priv->time_popup = gtk_option_menu_new ();
+ _add_atk_name_desc (GTK_WIDGET (gde->_priv->time_popup),
+ _("Select Time"), _("Select the time from a list"));
+
+ _add_atk_relation (GTK_WIDGET (gde->_priv->time_popup), GTK_WIDGET (gde->_priv->time_entry),
+ ATK_RELATION_CONTROLLED_BY, ATK_RELATION_CONTROLLER_FOR);
+
gtk_box_pack_start (GTK_BOX (gde), gde->_priv->time_popup, FALSE, FALSE, 0);
/* We do not create the popup menu with the hour range until we are
diff -pNaur libgnomeui/libgnomeui/gnome-entry.c libgnomeui-new/libgnomeui/gnome-entry.c
--- libgnomeui/libgnomeui/gnome-entry.c Thu Apr 18 05:08:48 2002
+++ libgnomeui-new/libgnomeui/gnome-entry.c Thu Apr 18 05:08:30 2002
@@ -46,6 +46,7 @@
#include "gnome-gconf-ui.h"
+#include "libgnomeui-access.h"
#include "gnome-entry.h"
enum {
diff -pNaur libgnomeui/libgnomeui/gnome-file-entry.c libgnomeui-new/libgnomeui/gnome-file-entry.c
--- libgnomeui/libgnomeui/gnome-file-entry.c Thu Apr 18 05:08:48 2002
+++ libgnomeui-new/libgnomeui/gnome-file-entry.c Thu Apr 18 05:08:30 2002
@@ -51,6 +51,8 @@
#include <libgnome/gnome-util.h>
#include "libgnomeuiP.h"
+#include "libgnomeui-access.h"
+
#include "gnome-file-entry.h"
struct _GnomeFileEntryPrivate {
@@ -567,6 +569,8 @@ gnome_file_entry_init (GnomeFileEntry *f
fentry->_priv->directory_entry = FALSE;
fentry->_priv->gentry = gnome_entry_new (NULL);
+ _add_atk_name_desc (fentry->_priv->gentry, _("Path"), _("Path to file"));
+
the_gtk_entry = gnome_file_entry_gtk_entry (fentry);
g_signal_connect (the_gtk_entry, "changed",
@@ -590,11 +594,17 @@ gnome_file_entry_init (GnomeFileEntry *f
gtk_widget_show (fentry->_priv->gentry);
button = gtk_button_new_with_mnemonic (_("_Browse..."));
+ _add_atk_description (button, _("Pop up a file selector to choose a file"));
+
g_signal_connect (button, "clicked",
G_CALLBACK (browse_clicked_signal),
fentry);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
+
+ _add_atk_relation (button, the_gtk_entry,
+ ATK_RELATION_CONTROLLER_FOR,
+ ATK_RELATION_CONTROLLED_BY);
}
static void
diff -pNaur libgnomeui/libgnomeui/gnome-href.c libgnomeui-new/libgnomeui/gnome-href.c
--- libgnomeui/libgnomeui/gnome-href.c Thu Apr 18 05:08:48 2002
+++ libgnomeui-new/libgnomeui/gnome-href.c Thu Apr 18 05:08:30 2002
@@ -31,6 +31,7 @@
#include <gtk/gtk.h>
#include <libgnome/gnome-url.h>
#include "gnome-href.h"
+#include "libgnomeui-access.h"
struct _GnomeHRefPrivate {
gchar *url;
@@ -172,6 +173,14 @@ gnome_href_instance_init (GnomeHRef *hre
/* the source dest is set on set_url */
g_signal_connect (href, "drag_data_get",
G_CALLBACK (drag_data_get), NULL);
+
+ /* Set our accessible description. We don't set the name as we want it
+ * to be the contents of the label, which is the default anyways.
+ */
+
+ _add_atk_name_desc (GTK_WIDGET (href),
+ NULL,
+ _("This button will take you to the URI that it displays."));
}
static void
diff -pNaur libgnomeui/libgnomeui/gnome-icon-entry.c libgnomeui-new/libgnomeui/gnome-icon-entry.c
--- libgnomeui/libgnomeui/gnome-icon-entry.c Thu Apr 18 05:08:48 2002
+++ libgnomeui-new/libgnomeui/gnome-icon-entry.c Thu Apr 18 05:08:30 2002
@@ -61,6 +61,7 @@
#include "gnome-icon-list.h"
#include "gnome-icon-sel.h"
#include "gnome-icon-entry.h"
+#include "libgnomeui-access.h"
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
@@ -692,7 +693,17 @@ ientry_browse(GnomeIconEntry *ientry)
G_CALLBACK (gtk_widget_destroyed),
&priv->pick_dialog);
+ /* Set up accessible properties for the pick dialog */
+ _add_atk_name_desc (priv->pick_dialog,
+ _("Icon selection dialog"),
+ _("This dialog box lets you select an icon."));
+ _add_atk_relation (priv->pickbutton, priv->pick_dialog,
+ ATK_RELATION_CONTROLLER_FOR, ATK_RELATION_CONTROLLED_BY);
+
priv->icon_sel = gnome_icon_selection_new ();
+ _add_atk_name_desc (priv->icon_sel,
+ _("Icon selector"),
+ _("Please pick the icon you want."));
gnome_icon_selection_add_directory (GNOME_ICON_SELECTION (priv->icon_sel),
priv->pick_dialog_dir);
@@ -928,6 +939,10 @@ gnome_icon_entry_instance_init (GnomeIco
gtk_widget_show (ientry->_priv->pickbutton);
ientry->_priv->fentry = gnome_file_entry_new (NULL, _("Browse"));
+ _add_atk_name_desc (ientry->_priv->fentry,
+ _("Icon path"),
+ _("Here you should enter the name of the directory "
+ "where icon images are located."));
/*BORPORP */
gnome_file_entry_set_modal (GNOME_FILE_ENTRY (ientry->_priv->fentry),
TRUE);
@@ -955,6 +970,11 @@ gnome_icon_entry_instance_init (GnomeIco
/*just in case there is a default that is an image*/
entry_changed(w,ientry);
+
+ /* Set our accessible name and description */
+ _add_atk_name_desc (GTK_WIDGET (ientry->_priv->pickbutton),
+ _("Icon Selector"),
+ _("This button will open a window to let you select an icon."));
}
/**
diff -pNaur libgnomeui/libgnomeui/gnome-icon-list.c libgnomeui-new/libgnomeui/gnome-icon-list.c
--- libgnomeui/libgnomeui/gnome-icon-list.c Thu Apr 18 05:08:48 2002
+++ libgnomeui-new/libgnomeui/gnome-icon-list.c Thu Apr 18 05:08:30 2002
@@ -50,6 +50,7 @@
#include <gdk/gdkkeysyms.h>
#include <libgnomeuiP.h>
+#include "libgnomeui-access.h"
/* Aliases to minimize screen use in my laptop */
#define GIL(x) GNOME_ICON_LIST(x)
@@ -223,6 +224,9 @@ struct _GnomeIconListPrivate {
};
+static GType gil_accessible_get_type (void);
+
+
static inline int
icon_line_height (Gil *gil, IconLine *il)
{
@@ -1055,6 +1059,7 @@ icon_list_append (Gil *gil, Icon *icon)
{
GnomeIconListPrivate *priv;
int pos;
+ AtkObject *accessible;
priv = gil->_priv;
@@ -1077,6 +1082,17 @@ icon_list_append (Gil *gil, Icon *icon)
} else
priv->dirty = TRUE;
+ /* Notify the accessible object
+ *
+ * FIXME: do we need to pass the accessible object for the new child
+ * as one of the signal parameters?
+ */
+
+ accessible = _accessibility_get_atk_object (gil);
+ if (accessible)
+ g_signal_emit_by_name (accessible, "children_changed::add",
+ priv->icons - 1, NULL, NULL);
+
return priv->icons - 1;
}
@@ -1084,6 +1100,7 @@ static void
icon_list_insert (Gil *gil, int pos, Icon *icon)
{
GnomeIconListPrivate *priv;
+ AtkObject *accessible;
priv = gil->_priv;
@@ -1114,6 +1131,17 @@ icon_list_insert (Gil *gil, int pos, Ico
priv->dirty = TRUE;
sync_selection (gil, pos, SYNC_INSERT);
+
+ /* Notify the accessible object
+ *
+ * FIXME: do we need to pass the accessible object for the new child
+ * as one of the signal parameters?
+ */
+
+ accessible = _accessibility_get_atk_object (gil);
+ if (accessible)
+ g_signal_emit_by_name (accessible, "children_changed::add",
+ pos, NULL, NULL);
}
/**
@@ -1246,6 +1274,7 @@ gnome_icon_list_remove (GnomeIconList *g
GnomeIconListPrivate *priv;
int was_selected;
Icon *icon;
+ AtkObject *accessible;
g_return_if_fail (gil != NULL);
g_return_if_fail (IS_GIL (gil));
@@ -1306,6 +1335,16 @@ gnome_icon_list_remove (GnomeIconList *g
gil_scrollbar_adjust (gil);
} else
priv->dirty = TRUE;
+
+ /* Notify the accessibility object
+ *
+ * FIXME: the child no longer exists! Do we still need to pass its
+ * corresponding accessible object as one of the signal parameters?
+ */
+ accessible = _accessibility_get_atk_object (gil);
+ if (accessible)
+ g_signal_emit_by_name (accessible, "children_changed::remove",
+ pos, NULL, NULL);
}
/**
@@ -1321,6 +1360,7 @@ gnome_icon_list_clear (GnomeIconList *gi
{
GnomeIconListPrivate *priv;
int i;
+ AtkObject *accessible;
g_return_if_fail (gil != NULL);
g_return_if_fail (IS_GIL (gil));
@@ -1344,6 +1384,12 @@ gnome_icon_list_clear (GnomeIconList *gi
gil_scrollbar_adjust (gil);
} else
priv->dirty = TRUE;
+
+ /* Notify the accessible object */
+
+ accessible = _accessibility_get_atk_object (gil);
+ if (accessible)
+ g_signal_emit_by_name (accessible, "children_changed", 0, NULL, NULL);
}
static void
@@ -1633,6 +1679,23 @@ real_toggle_cursor_selection (Gil *gil)
}
+/* Used from g_list_insert_sorted() */
+static gint
+selection_list_compare_cb (gconstpointer a, gconstpointer b)
+{
+ int ia, ib;
+
+ ia = GPOINTER_TO_INT (a);
+ ib = GPOINTER_TO_INT (b);
+
+ if (ia < ib)
+ return -1;
+ else if (ia > ib)
+ return 1;
+ else
+ return 0;
+}
+
static void
real_select_icon (Gil *gil, gint num, GdkEvent *event)
{
@@ -1652,7 +1715,8 @@ real_select_icon (Gil *gil, gint num, Gd
icon->selected = TRUE;
gnome_icon_text_item_select (icon->text, TRUE);
- priv->selection = g_list_append (priv->selection, GINT_TO_POINTER (num));
+ priv->selection = g_list_insert_sorted (priv->selection, GINT_TO_POINTER (num),
+ selection_list_compare_cb);
}
static void
@@ -2103,6 +2167,19 @@ gil_scroll (GtkWidget *widget, GdkEventS
return TRUE;
}
+static AtkObject *
+gil_get_accessible (GtkWidget *widget)
+{
+ AtkObject *accessible;
+
+ if ((accessible = _accessibility_get_atk_object (widget)) != NULL)
+ return accessible;
+
+ accessible = g_object_new (gil_accessible_get_type (), NULL);
+
+ return _accessibility_set_atk_object_return (widget, accessible);
+}
+
static void
gnome_icon_list_class_init (GilClass *gil_class)
{
@@ -2207,6 +2284,7 @@ gnome_icon_list_class_init (GilClass *gi
widget_class->focus_out_event = gil_focus_out;
widget_class->key_press_event = gil_key_press;
widget_class->scroll_event = gil_scroll;
+ widget_class->get_accessible = gil_get_accessible;
/* we override GtkLayout's set_scroll_adjustments signal instead
* of creating a new signal so as to keep binary compatibility.
@@ -3021,3 +3099,303 @@ gnome_icon_list_get_icon_pixbuf_item (Gn
return icon->image;
}
+
+
+/*** Accessible object for GnomeIconList ***/
+
+static void selection_interface_init (AtkSelectionIface *iface);
+
+static void gil_accessible_class_init (AtkObjectClass *class);
+
+/* AtkObjectClass implementations */
+static gint impl_get_n_children (AtkObject *accessible);
+static AtkObject *impl_ref_child (AtkObject *accessible, gint i);
+static void impl_initialize (AtkObject *accessible, gpointer data);
+
+/* AtkSelectionIface implementations */
+static gboolean impl_selection_add_selection (AtkSelection *selection, gint i);
+static gboolean impl_selection_clear_selection (AtkSelection *selection);
+static AtkObject* impl_selection_ref_selection (AtkSelection *selection, gint i);
+static gint impl_selection_get_selection_count (AtkSelection *selection);
+static gboolean impl_selection_is_child_selected (AtkSelection *selection, gint i);
+static gboolean impl_selection_remove_selection (AtkSelection *selection, gint i);
+static gboolean impl_selection_select_all_selection (AtkSelection *selection);
+
+static gpointer accessible_parent_class = NULL;
+
+
+/* get_type() function for the accessible object */
+static GType
+gil_accessible_get_type (void)
+{
+ static GType type;
+
+ if (!type) {
+ static GInterfaceInfo selection_info = {
+ (GInterfaceInitFunc) selection_interface_init,
+ NULL, /* interface_finalize */
+ NULL /* interface_data */
+ };
+
+ type = _accessibility_create_derived_type (
+ "GnomeIconListAccessible",
+ GNOME_TYPE_CANVAS,
+ gil_accessible_class_init);
+
+ g_type_add_interface_static (type, ATK_TYPE_SELECTION, &selection_info);
+ }
+
+ return type;
+}
+
+/* Fills the ATK selection interface vtable */
+static void
+selection_interface_init (AtkSelectionIface *iface)
+{
+ iface->add_selection = impl_selection_add_selection;
+ iface->clear_selection = impl_selection_clear_selection;
+ iface->ref_selection = impl_selection_ref_selection;
+ iface->get_selection_count = impl_selection_get_selection_count;
+ iface->is_child_selected = impl_selection_is_child_selected;
+ iface->remove_selection = impl_selection_remove_selection;
+ iface->select_all_selection = impl_selection_select_all_selection;
+}
+
+/* Class initialization function for the accessible object */
+static void
+gil_accessible_class_init (AtkObjectClass *class)
+{
+ accessible_parent_class = g_type_class_peek_parent (class);
+
+ class->get_n_children = impl_get_n_children;
+ class->ref_child = impl_ref_child;
+ class->initialize = impl_initialize;
+}
+
+
+
+/* AtkSelectionIface implementation */
+
+static gboolean
+impl_selection_add_selection (AtkSelection *selection, gint i)
+{
+ GtkWidget *widget;
+ GnomeIconList *gil;
+
+ widget = GTK_ACCESSIBLE (selection)->widget;
+ if (!widget)
+ return FALSE;
+
+ gil = GNOME_ICON_LIST (widget);
+ gnome_icon_list_select_icon (gil, i);
+ return TRUE;
+}
+
+static gboolean
+impl_selection_clear_selection (AtkSelection *selection)
+{
+ GtkWidget *widget;
+ GnomeIconList *gil;
+
+ widget = GTK_ACCESSIBLE (selection)->widget;
+ if (!widget)
+ return FALSE;
+
+ gil = GNOME_ICON_LIST (widget);
+ gnome_icon_list_unselect_all (gil);
+ return TRUE;
+}
+
+static AtkObject *
+impl_selection_ref_selection (AtkSelection *selection, gint i)
+{
+ GtkWidget *widget;
+ GnomeIconList *gil;
+ GList *sel, *l;
+ int n;
+ GnomeIconTextItem *iti;
+ AtkObject *atk_object;
+
+ widget = GTK_ACCESSIBLE (selection)->widget;
+ if (!widget)
+ return FALSE;
+
+ gil = GNOME_ICON_LIST (widget);
+
+ sel = gnome_icon_list_get_selection (gil);
+ l = g_list_nth (sel, i);
+ if (!l)
+ return NULL;
+
+ n = GPOINTER_TO_INT (l->data);
+ iti = gnome_icon_list_get_icon_text_item (gil, n);
+ if (!iti)
+ return NULL;
+
+ /* FIXME: is this what we need to return? How do we distinguish between
+ * the icon text item and the pixbuf?
+ */
+ atk_object = atk_gobject_accessible_for_object (G_OBJECT (iti));
+ g_object_ref (atk_object);
+ return atk_object;
+}
+
+static gint
+impl_selection_get_selection_count (AtkSelection *selection)
+{
+ GtkWidget *widget;
+ GnomeIconList *gil;
+ GList *sel;
+
+ widget = GTK_ACCESSIBLE (selection)->widget;
+ if (!widget)
+ return FALSE;
+
+ gil = GNOME_ICON_LIST (widget);
+ sel = gnome_icon_list_get_selection (gil);
+ return g_list_length (sel);
+}
+
+static gboolean
+impl_selection_is_child_selected (AtkSelection *selection, gint i)
+{
+ GtkWidget *widget;
+ GnomeIconList *gil;
+ GList *l;
+
+ widget = GTK_ACCESSIBLE (selection)->widget;
+ if (!widget)
+ return FALSE;
+
+ gil = GNOME_ICON_LIST (widget);
+ for (l = gnome_icon_list_get_selection (gil); l; l = l->next) {
+ int k;
+
+ k = GPOINTER_TO_INT (l->data);
+ if (k == i)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+impl_selection_remove_selection (AtkSelection *selection, gint i)
+{
+ GtkWidget *widget;
+ GnomeIconList *gil;
+ GList *sel, *l;
+ int n;
+
+ widget = GTK_ACCESSIBLE (selection)->widget;
+ if (!widget)
+ return FALSE;
+
+ gil = GNOME_ICON_LIST (widget);
+
+ sel = gnome_icon_list_get_selection (gil);
+ l = g_list_nth (sel, i);
+ if (!l)
+ return FALSE;
+
+ n = GPOINTER_TO_INT (l->data);
+
+ gnome_icon_list_unselect_icon (gil, n);
+ return TRUE;
+}
+
+static gboolean
+impl_selection_select_all_selection (AtkSelection *selection)
+{
+ GtkWidget *widget;
+ GnomeIconList *gil;
+ int n, i;
+
+ widget = GTK_ACCESSIBLE (selection)->widget;
+ if (!widget)
+ return FALSE;
+
+ gil = GNOME_ICON_LIST (widget);
+
+ if (gnome_icon_list_get_selection_mode (gil) != GTK_SELECTION_MULTIPLE)
+ return FALSE;
+
+ n = gnome_icon_list_get_num_icons (gil);
+
+ for (i = 0; i < n; i++)
+ gnome_icon_list_select_icon (gil, i);
+
+ return TRUE;
+}
+
+
+
+/* AtkObjectClass implementations */
+
+static gint
+impl_get_n_children (AtkObject *accessible)
+{
+ GtkWidget *widget;
+ GnomeIconList *gil;
+
+ widget = GTK_ACCESSIBLE (accessible)->widget;
+ if (!widget)
+ return 0;
+
+ gil = GNOME_ICON_LIST (widget);
+
+ return gnome_icon_list_get_num_icons (gil);
+}
+
+static AtkObject *
+impl_ref_child (AtkObject *accessible, gint i)
+{
+ GtkWidget *widget;
+ GnomeIconList *gil;
+ GnomeIconTextItem *iti;
+ AtkObject *atk_object;
+
+ widget = GTK_ACCESSIBLE (accessible)->widget;
+ if (!widget)
+ return NULL;
+
+ gil = GNOME_ICON_LIST (widget);
+
+ iti = gnome_icon_list_get_icon_text_item (gil, i);
+ if (!iti)
+ return NULL;
+
+ /* FIXME: is this what we need to return? How do we distinguish between
+ * the icon text item and the pixbuf?
+ */
+ atk_object = atk_gobject_accessible_for_object (G_OBJECT (iti));
+ g_object_ref (atk_object);
+ return atk_object;
+}
+
+/* Callback used when an icon changes its selection status */
+static void
+select_icon_cb (GnomeIconList *gil, gint num, GdkEvent *event, gpointer data)
+{
+ AtkObject *accessible;
+
+ accessible = ATK_OBJECT (data);
+ g_signal_emit_by_name (accessible, "selection_changed");
+}
+
+static void
+impl_initialize (AtkObject *accessible, gpointer data)
+{
+ GnomeIconList *gil;
+
+ ATK_OBJECT_CLASS (accessible_parent_class)->initialize (accessible, data);
+
+ gil = GNOME_ICON_LIST (GTK_ACCESSIBLE (accessible)->widget);
+
+ /* We use the same callback for both signals as the handler would do the
+ * same thing for both.
+ */
+ g_signal_connect (gil, "select_icon", G_CALLBACK (select_icon_cb), accessible);
+ g_signal_connect (gil, "unselect_icon", G_CALLBACK (select_icon_cb), accessible);
+}
+
diff -pNaur libgnomeui/libgnomeui/gnome-icon-sel.c libgnomeui-new/libgnomeui/gnome-icon-sel.c
--- libgnomeui/libgnomeui/gnome-icon-sel.c Thu Apr 18 05:08:48 2002
+++ libgnomeui-new/libgnomeui/gnome-icon-sel.c Thu Apr 18 05:08:30 2002
@@ -39,6 +39,7 @@
#include "gnome-uidefs.h"
#include "gnome-icon-sel.h"
+#include "libgnomeui-access.h"
#include <libgnomevfs/gnome-vfs-ops.h>
@@ -409,6 +410,8 @@ gnome_icon_selection_show_icons (GnomeIc
return;
label = gtk_label_new (_("Loading Icons..."));
+ _add_atk_relation (GTK_WIDGET (gis), label,
+ ATK_RELATION_LABELLED_BY, ATK_RELATION_LABEL_FOR);
gtk_box_pack_start (GTK_BOX (gis->_priv->box),
label, FALSE, FALSE, 0);
gtk_widget_show (label);
@@ -417,6 +420,8 @@ gnome_icon_selection_show_icons (GnomeIc
&label);
progressbar = gtk_progress_bar_new ();
+ _add_atk_relation (progressbar, label,
+ ATK_RELATION_LABELLED_BY, ATK_RELATION_LABEL_FOR);
gtk_box_pack_start (GTK_BOX (gis->_priv->box),
progressbar, FALSE, FALSE, 0);
gtk_widget_show (progressbar);
diff -pNaur libgnomeui/libgnomeui/gnome-pixmap-entry.c libgnomeui-new/libgnomeui/gnome-pixmap-entry.c
--- libgnomeui/libgnomeui/gnome-pixmap-entry.c Thu Apr 18 05:08:48 2002
+++ libgnomeui-new/libgnomeui/gnome-pixmap-entry.c Thu Apr 18 05:08:30 2002
@@ -57,6 +57,8 @@
#include <libgnomevfs/gnome-vfs-uri.h>
+#include "libgnomeui-access.h"
+
struct _GnomePixmapEntryPrivate {
GtkWidget *preview;
GtkWidget *preview_sw;
@@ -206,6 +208,10 @@ refresh_preview(GnomePixmapEntry *pentry
} else {
gtk_widget_destroy(pentry->_priv->preview->parent);
pentry->_priv->preview = gtk_image_new_from_pixbuf (pixbuf);
+ _add_atk_name_desc (pentry->_priv->preview,
+ _("Image Preview"),
+ _("A preview of the image currently specified"));
+
gtk_widget_show(pentry->_priv->preview);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(pentry->_priv->preview_sw),
pentry->_priv->preview);
diff -pNaur libgnomeui/libgnomeui/libgnomeui-access.c libgnomeui-new/libgnomeui/libgnomeui-access.c
--- libgnomeui/libgnomeui/libgnomeui-access.c Wed Dec 31 19:00:00 1969
+++ libgnomeui-new/libgnomeui/libgnomeui-access.c Thu Apr 18 05:08:30 2002
@@ -0,0 +1,280 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Copyright 2002 Sun Microsystems Inc.
+ *
+ * Lib GNOME UI Accessibility support module
+ *
+ * This code copied from Wipro's panel-access.c.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+#include <config.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkaccessible.h>
+#include <atk/atkrelationset.h>
+#include "libgnomeui-access.h"
+
+static gint is_gail_loaded (GtkWidget *widget);
+
+/* variable that indicates whether GAIL is loaded or not */
+gint gail_loaded = -1;
+
+/* Accessibility support routines for libgnomeui */
+static gint
+is_gail_loaded (GtkWidget *widget)
+{
+ AtkObject *aobj;
+ if (gail_loaded == -1) {
+ aobj = gtk_widget_get_accessible (widget);
+ if (!GTK_IS_ACCESSIBLE (aobj))
+ gail_loaded = 0;
+ else
+ gail_loaded = 1;
+ }
+ return gail_loaded;
+}
+
+/* routine to add accessible name and description to an atk object */
+void
+_add_atk_name_desc (GtkWidget *widget, gchar *name, gchar *desc)
+{
+ AtkObject *aobj;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ if (! is_gail_loaded (widget))
+ return;
+
+ aobj = gtk_widget_get_accessible (widget);
+
+ if (name)
+ atk_object_set_name (aobj, name);
+ if (desc)
+ atk_object_set_description (aobj, desc);
+}
+
+void
+_add_atk_description (GtkWidget *widget,
+ gchar *desc)
+{
+ _add_atk_name_desc (widget, NULL, desc);
+}
+
+void
+_add_atk_relation (GtkWidget *widget1, GtkWidget *widget2,
+ AtkRelationType w1_to_w2, AtkRelationType w2_to_w1)
+{
+ AtkObject *atk_widget1;
+ AtkObject *atk_widget2;
+ AtkRelationSet *relation_set;
+ AtkRelation *relation;
+ AtkObject *targets[1];
+
+ atk_widget1 = gtk_widget_get_accessible (widget1);
+ atk_widget2 = gtk_widget_get_accessible (widget2);
+
+ /* Create the widget1 -> widget2 relation */
+ relation_set = atk_object_ref_relation_set (atk_widget1);
+ targets[0] = atk_widget2;
+ relation = atk_relation_new (targets, 1, w1_to_w2);
+ atk_relation_set_add (relation_set, relation);
+ g_object_unref (relation);
+
+ /* Create the widget2 -> widget1 relation */
+ relation_set = atk_object_ref_relation_set (atk_widget2);
+ targets[0] = atk_widget1;
+ relation = atk_relation_new (targets, 1, w2_to_w1);
+ atk_relation_set_add (relation_set, relation);
+ g_object_unref (relation);
+}
+
+
+
+/* Copied from eel */
+
+static GQuark
+get_quark_accessible (void)
+{
+ static GQuark quark_accessible_object = 0;
+
+ if (!quark_accessible_object) {
+ quark_accessible_object = g_quark_from_static_string
+ ("accessible-object");
+ }
+
+ return quark_accessible_object;
+}
+
+static GQuark
+get_quark_gobject (void)
+{
+ static GQuark quark_accessible_gobject = 0;
+
+ if (!quark_accessible_gobject) {
+ quark_accessible_gobject = g_quark_from_static_string
+ ("object-for-accessible");
+ }
+
+ return quark_accessible_gobject;
+}
+
+/**
+ * _accessibility_get_atk_object:
+ * @object: a GObject of some sort
+ *
+ * gets an AtkObject associated with a GObject
+ *
+ * Return value: the associated accessible if one exists or NULL
+ **/
+AtkObject *
+_accessibility_get_atk_object (gpointer object)
+{
+ return g_object_get_qdata (object, get_quark_accessible ());
+}
+
+/**
+ * _accessibilty_for_object:
+ * @object: a GObject of some sort
+ *
+ * gets an AtkObject associated with a GObject and if it doesn't
+ * exist creates a suitable accessible object.
+ *
+ * Return value: an associated accessible.
+ **/
+AtkObject *
+_accessibility_for_object (gpointer object)
+{
+ if (GTK_IS_WIDGET (object))
+ return gtk_widget_get_accessible (object);
+
+ return atk_gobject_accessible_for_object (object);
+}
+
+/**
+ * _accessibility_get_gobject:
+ * @object: an AtkObject
+ *
+ * gets the GObject associated with the AtkObject, for which
+ * @object provides accessibility support.
+ *
+ * Return value: the accessible's associated GObject
+ **/
+gpointer
+_accessibility_get_gobject (AtkObject *object)
+{
+ return g_object_get_qdata (G_OBJECT (object), get_quark_gobject ());
+}
+
+static void
+_accessibility_weak_unref (gpointer data,
+ GObject *where_the_object_was)
+{
+ g_object_set_qdata (data, get_quark_gobject (), NULL);
+
+ atk_object_notify_state_change
+ (ATK_OBJECT (data), ATK_STATE_DEFUNCT, TRUE);
+
+ g_object_unref (data);
+}
+
+/**
+ * _accessibility_set_atk_object_return:
+ * @object: a GObject
+ * @atk_object: it's AtkObject
+ *
+ * used to register and return a new accessible object for something
+ *
+ * Return value: @atk_object.
+ **/
+AtkObject *
+_accessibility_set_atk_object_return (gpointer object,
+ AtkObject *atk_object)
+{
+ atk_object_initialize (atk_object, object);
+
+ if (!ATK_IS_GOBJECT_ACCESSIBLE (atk_object)) {
+ g_object_weak_ref (object, _accessibility_weak_unref, atk_object);
+ g_object_set_qdata
+ (object, get_quark_accessible (), atk_object);
+ g_object_set_qdata
+ (G_OBJECT (atk_object), get_quark_gobject (), object);
+ }
+
+ return atk_object;
+}
+
+/**
+ * _accessibility_create_derived_type:
+ * @type_name: the name for the new accessible type eg. NautilusIconCanvasItemAccessible
+ * @existing_gobject_with_proxy: the GType of an object that has a registered factory that
+ * manufactures the type we want to inherit from. ie. to inherit from a GailCanvasItem
+ * we need to pass GNOME_TYPE_CANVAS_ITEM - since GailCanvasItem is registered against
+ * that type.
+ * @class_init: the init function to run for this class
+ *
+ * This should be run to register the type, it can subsequently be run with
+ * the same name and will not re-register it, but simply return it.
+ *
+ * NB. to do instance init, you prolly want to override AtkObject::initialize
+ *
+ * Return value: the registered type, or 0 on failure.
+ **/
+GType
+_accessibility_create_derived_type (const char *type_name,
+ GType existing_gobject_with_proxy,
+ _AccessibilityClassInitFn class_init)
+{
+ GType type;
+ GType parent_atk_type;
+ GTypeInfo tinfo = { 0 };
+ GTypeQuery query;
+ AtkObjectFactory *factory;
+
+ if ((type = g_type_from_name (type_name))) {
+ return type;
+ }
+
+ factory = atk_registry_get_factory
+ (atk_get_default_registry (),
+ existing_gobject_with_proxy);
+ if (!factory) {
+ return G_TYPE_INVALID;
+ }
+
+ parent_atk_type = atk_object_factory_get_accessible_type (factory);
+ if (!parent_atk_type) {
+ return G_TYPE_INVALID;
+ }
+
+ /*
+ * Figure out the size of the class and instance
+ * we are deriving from
+ */
+ g_type_query (parent_atk_type, &query);
+
+ if (class_init) {
+ tinfo.class_init = (GClassInitFunc) class_init;
+ }
+
+ tinfo.class_size = query.class_size;
+ tinfo.instance_size = query.instance_size;
+
+ /* Register the type */
+ type = g_type_register_static (
+ parent_atk_type, type_name, &tinfo, 0);
+
+ return type;
+}
diff -pNaur libgnomeui/libgnomeui/libgnomeui-access.h libgnomeui-new/libgnomeui/libgnomeui-access.h
--- libgnomeui/libgnomeui/libgnomeui-access.h Wed Dec 31 19:00:00 1969
+++ libgnomeui-new/libgnomeui/libgnomeui-access.h Thu Apr 18 05:08:30 2002
@@ -0,0 +1,38 @@
+#ifndef __LIBGNOMEUI_ACCESS_H__
+#define __LIBGNOMEUI_ACCESS_H__
+/*
+ * Accessibility convenience functions.
+ *
+ * Copyright 2002, Sun Microsystems.
+ */
+
+#include <glib-object.h>
+#include <atk/atkobject.h>
+#include <atk/atkregistry.h>
+#include <atk/atkrelationset.h>
+#include <atk/atkobjectfactory.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtklabel.h>
+
+void _add_atk_name_desc (GtkWidget *widget, gchar *name, gchar *desc);
+void _add_atk_description (GtkWidget *widget, gchar *desc);
+void _add_atk_relation (GtkWidget *widget1, GtkWidget *widget2,
+ AtkRelationType w1_to_w2, AtkRelationType w2_to_w1);
+
+
+
+/* Copied from eel */
+
+typedef void (*_AccessibilityClassInitFn) (AtkObjectClass *klass);
+
+AtkObject *_accessibility_get_atk_object (gpointer object);
+AtkObject *_accessibility_for_object (gpointer object);
+gpointer _accessibility_get_gobject (AtkObject *object);
+AtkObject *_accessibility_set_atk_object_return (gpointer object,
+ AtkObject *atk_object);
+GType _accessibility_create_derived_type (const char *type_name,
+ GType existing_gobject_with_proxy,
+ _AccessibilityClassInitFn class_init);
+
+
+#endif /* ! __LIBGNOMEUI_ACCESS_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]