diff options
author | Matthias Clasen <mclasen@redhat.com> | 2011-06-30 22:11:13 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2011-07-05 16:08:56 -0400 |
commit | 318192b93747299f6e674fd68e1ea3b549e3048e (patch) | |
tree | 14e08e21e8db145463715f45203d60a3ac644e89 /gtk/a11y | |
parent | 6012f096c9a662bdf6deef2354911bedb6a275f7 (diff) | |
download | gtk+-318192b93747299f6e674fd68e1ea3b549e3048e.tar.gz |
Convert GailNotebook to GtkNotebookAccessible
Diffstat (limited to 'gtk/a11y')
-rw-r--r-- | gtk/a11y/Makefile.am | 4 | ||||
-rw-r--r-- | gtk/a11y/gail.c | 5 | ||||
-rw-r--r-- | gtk/a11y/gailnotebook.c | 481 | ||||
-rw-r--r-- | gtk/a11y/gailnotebookpage.c | 4 | ||||
-rw-r--r-- | gtk/a11y/gailnotebookpage.h | 11 | ||||
-rw-r--r-- | gtk/a11y/gtknotebookaccessible.c | 407 | ||||
-rw-r--r-- | gtk/a11y/gtknotebookaccessible.h (renamed from gtk/a11y/gailnotebook.h) | 32 |
7 files changed, 433 insertions, 511 deletions
diff --git a/gtk/a11y/Makefile.am b/gtk/a11y/Makefile.am index 6d2269d10e..01f5cbcb3b 100644 --- a/gtk/a11y/Makefile.am +++ b/gtk/a11y/Makefile.am @@ -25,7 +25,7 @@ gail_c_sources = \ gailmenu.c \ gailmenushell.c \ gailmenuitem.c \ - gailnotebook.c \ + gtknotebookaccessible.c \ gailnotebookpage.c \ gtkpanedaccessible.c \ gtkprogressbaraccessible.c \ @@ -76,7 +76,7 @@ gail_private_h_sources = \ gailmenu.h \ gailmenushell.h \ gailmenuitem.h \ - gailnotebook.h \ + gtknotebookaccessible.h \ gailnotebookpage.h \ gtkpanedaccessible.h \ gtkprogressbaraccessible.h \ diff --git a/gtk/a11y/gail.c b/gtk/a11y/gail.c index 0bea4e26b8..0acfa93535 100644 --- a/gtk/a11y/gail.c +++ b/gtk/a11y/gail.c @@ -34,7 +34,6 @@ #include "gailmenu.h" #include "gailmenushell.h" #include "gailmenuitem.h" -#include "gailnotebook.h" #include "gailradiomenuitem.h" #include "gailrenderercell.h" #include "gailstatusbar.h" @@ -64,8 +63,6 @@ static gboolean gail_switch_page_watcher(GSignalInvocationHint *ihint, guint n_param_values, const GValue *param_values, gpointer data); -static AtkObject* gail_get_accessible_for_widget (GtkWidget *widget, - gboolean *transient); static void gail_finish_select (GtkWidget *widget); static void gail_map_cb (GtkWidget *widget); static void gail_map_submenu_cb (GtkWidget *widget); @@ -98,7 +95,6 @@ GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU_SHELL, GailMenuShell, gail_menu_shell, GT 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_STATUSBAR, GailStatusbar, gail_statusbar, GTK_TYPE_STATUSBAR) -GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_NOTEBOOK, GailNotebook, gail_notebook, GTK_TYPE_NOTEBOOK) GAIL_IMPLEMENT_FACTORY_WITH_FUNC (GAIL_TYPE_CHECK_MENU_ITEM, GailCheckMenuItem, gail_check_menu_item, gail_check_menu_item_new) GAIL_IMPLEMENT_FACTORY_WITH_FUNC (GAIL_TYPE_RADIO_MENU_ITEM, GailRadioMenuItem, gail_radio_menu_item, gail_radio_menu_item_new) GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_EXPANDER, GailExpander, gail_expander, GTK_TYPE_EXPANDER) @@ -854,7 +850,6 @@ gail_accessibility_module_init (void) GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU, gail_menu); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_WINDOW, gail_window); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_STATUSBAR, gail_statusbar); - GAIL_WIDGET_SET_FACTORY (GTK_TYPE_NOTEBOOK, gail_notebook); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_TEXT, gail_text_cell); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_TOGGLE, gail_boolean_cell); GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CELL_RENDERER_PIXBUF, gail_image_cell); diff --git a/gtk/a11y/gailnotebook.c b/gtk/a11y/gailnotebook.c deleted file mode 100644 index c1d16ffe93..0000000000 --- a/gtk/a11y/gailnotebook.c +++ /dev/null @@ -1,481 +0,0 @@ -/* GAIL - The GNOME Accessibility Implementation Library - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * 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 "config.h" - -#include <string.h> -#include <gtk/gtk.h> -#include "gailnotebook.h" -#include "gailnotebookpage.h" - -static void gail_notebook_class_init (GailNotebookClass *klass); -static void gail_notebook_init (GailNotebook *notebook); -static void gail_notebook_finalize (GObject *object); -static void gail_notebook_real_initialize (AtkObject *obj, - gpointer data); - -static void gail_notebook_real_notify_gtk (GObject *obj, - GParamSpec *pspec); - -static AtkObject* gail_notebook_ref_child (AtkObject *obj, - gint i); -static void atk_selection_interface_init (AtkSelectionIface *iface); -static gboolean gail_notebook_add_selection (AtkSelection *selection, - gint i); -static AtkObject* gail_notebook_ref_selection (AtkSelection *selection, - gint i); -static gint gail_notebook_get_selection_count (AtkSelection *selection); -static gboolean gail_notebook_is_child_selected (AtkSelection *selection, - gint i); -static void create_notebook_page_accessible (GailNotebook *gail_notebook, - GtkNotebook *notebook, - GtkWidget *child, - int page_num); -static gboolean gail_notebook_focus_cb (GtkWidget *widget, - GtkDirectionType type); -static gboolean gail_notebook_check_focus_tab (gpointer data); -static void gail_notebook_destroyed (gpointer data); - - -G_DEFINE_TYPE_WITH_CODE (GailNotebook, gail_notebook, GAIL_TYPE_CONTAINER, - G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init)) - -static void -gail_notebook_class_init (GailNotebookClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - GailWidgetClass *widget_class; - - widget_class = (GailWidgetClass*)klass; - - gobject_class->finalize = gail_notebook_finalize; - - widget_class->notify_gtk = gail_notebook_real_notify_gtk; - - class->ref_child = gail_notebook_ref_child; - class->initialize = gail_notebook_real_initialize; - /* - * We do not provide an implementation of get_n_children - * as the implementation in GailContainer returns the correct - * number of children. - */ -} - -static void -gail_notebook_init (GailNotebook *notebook) -{ - notebook->pages = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - g_object_unref); - notebook->selected_page = -1; - notebook->focus_tab_page = -1; - notebook->idle_focus_id = 0; -} - -static AtkObject* -gail_notebook_ref_child (AtkObject *obj, - gint i) -{ - AtkObject *accessible = NULL; - GailNotebook *gail_notebook; - GtkNotebook *gtk_notebook; - GtkWidget *widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); - if (widget == NULL) - /* - * State is defunct - */ - return NULL; - - gail_notebook = GAIL_NOTEBOOK (obj); - gtk_notebook = GTK_NOTEBOOK (widget); - - accessible = g_hash_table_lookup (gail_notebook->pages, - gtk_notebook_get_nth_page (gtk_notebook, i)); - /* can return NULL when i >= n_children */ - - if (accessible) - g_object_ref (accessible); - - return accessible; -} - -static void -gail_notebook_page_added (GtkNotebook *gtk_notebook, - GtkWidget *child, - guint page_num, - gpointer data) -{ - AtkObject *atk_obj; - GailNotebook *notebook; - - atk_obj = gtk_widget_get_accessible (GTK_WIDGET (gtk_notebook)); - notebook = GAIL_NOTEBOOK (atk_obj); - create_notebook_page_accessible (notebook, gtk_notebook, child, page_num); -} - -static void -gail_notebook_page_removed (GtkNotebook *notebook, - GtkWidget *widget, - guint page_num, - gpointer data) -{ - GailNotebook *gail_notebook; - AtkObject *obj; - - gail_notebook = GAIL_NOTEBOOK (gtk_widget_get_accessible (GTK_WIDGET (notebook))); - - obj = g_hash_table_lookup (gail_notebook->pages, widget); - g_return_if_fail (obj); - g_signal_emit_by_name (gail_notebook, - "children_changed::remove", - page_num, - obj, - NULL); - gail_notebook_page_invalidate (GAIL_NOTEBOOK_PAGE (obj)); - g_hash_table_remove (gail_notebook->pages, widget); -} - -static void -gail_notebook_real_initialize (AtkObject *obj, - gpointer data) -{ - GailNotebook *notebook; - GtkNotebook *gtk_notebook; - gint i; - - ATK_OBJECT_CLASS (gail_notebook_parent_class)->initialize (obj, data); - - notebook = GAIL_NOTEBOOK (obj); - gtk_notebook = GTK_NOTEBOOK (data); - for (i = 0; i < gtk_notebook_get_n_pages (gtk_notebook); i++) - { - create_notebook_page_accessible (notebook, - gtk_notebook, - gtk_notebook_get_nth_page (gtk_notebook, i), - i); - } - notebook->selected_page = gtk_notebook_get_current_page (gtk_notebook); - - g_signal_connect (gtk_notebook, - "focus", - G_CALLBACK (gail_notebook_focus_cb), - NULL); - g_signal_connect (gtk_notebook, - "page-added", - G_CALLBACK (gail_notebook_page_added), - NULL); - g_signal_connect (gtk_notebook, - "page-removed", - G_CALLBACK (gail_notebook_page_removed), - NULL); - g_object_weak_ref (G_OBJECT(gtk_notebook), - (GWeakNotify) gail_notebook_destroyed, - obj); - - obj->role = ATK_ROLE_PAGE_TAB_LIST; -} - -static void -gail_notebook_real_notify_gtk (GObject *obj, - GParamSpec *pspec) -{ - GtkWidget *widget; - AtkObject* atk_obj; - - widget = GTK_WIDGET (obj); - atk_obj = gtk_widget_get_accessible (widget); - - if (strcmp (pspec->name, "page") == 0) - { - gint page_num, old_page_num; - gint focus_page_num = 0; - gint old_focus_page_num; - GailNotebook *gail_notebook; - GtkNotebook *gtk_notebook; - - gail_notebook = GAIL_NOTEBOOK (atk_obj); - gtk_notebook = GTK_NOTEBOOK (widget); - - /* - * Notify SELECTED state change for old and new page - */ - old_page_num = gail_notebook->selected_page; - page_num = gtk_notebook_get_current_page (gtk_notebook); - gail_notebook->selected_page = page_num; - gail_notebook->focus_tab_page = page_num; - old_focus_page_num = gail_notebook->focus_tab_page; - - if (page_num != old_page_num) - { - AtkObject *obj; - - if (old_page_num != -1) - { - obj = gail_notebook_ref_child (atk_obj, old_page_num); - if (obj) - { - atk_object_notify_state_change (obj, - ATK_STATE_SELECTED, - FALSE); - g_object_unref (obj); - } - } - obj = gail_notebook_ref_child (atk_obj, page_num); - if (obj) - { - atk_object_notify_state_change (obj, - ATK_STATE_SELECTED, - TRUE); - g_object_unref (obj); - /* - * The page which is being displayed has changed but there is - * no need to tell the focus tracker as the focus page will also - * change or a widget in the page will receive focus if the - * Notebook does not have tabs. - */ - } - g_signal_emit_by_name (atk_obj, "selection_changed"); - g_signal_emit_by_name (atk_obj, "visible_data_changed"); - } - if (gtk_notebook_get_show_tabs (gtk_notebook) && - (focus_page_num != old_focus_page_num)) - { - if (gail_notebook->idle_focus_id) - g_source_remove (gail_notebook->idle_focus_id); - gail_notebook->idle_focus_id = gdk_threads_add_idle (gail_notebook_check_focus_tab, atk_obj); - } - } - else - GAIL_WIDGET_CLASS (gail_notebook_parent_class)->notify_gtk (obj, pspec); -} - -static void -gail_notebook_finalize (GObject *object) -{ - GailNotebook *notebook = GAIL_NOTEBOOK (object); - - g_hash_table_destroy (notebook->pages); - - if (notebook->idle_focus_id) - g_source_remove (notebook->idle_focus_id); - - G_OBJECT_CLASS (gail_notebook_parent_class)->finalize (object); -} - -static void -atk_selection_interface_init (AtkSelectionIface *iface) -{ - iface->add_selection = gail_notebook_add_selection; - iface->ref_selection = gail_notebook_ref_selection; - iface->get_selection_count = gail_notebook_get_selection_count; - iface->is_child_selected = gail_notebook_is_child_selected; - /* - * The following don't make any sense for GtkNotebook widgets. - * Unsupported AtkSelection interfaces: - * clear_selection(); - * remove_selection(); - * select_all_selection(); - */ -} - -/* - * GtkNotebook only supports the selection of one page at a time. - * Selecting a page unselects any previous selection, so this - * changes the current selection instead of adding to it. - */ -static gboolean -gail_notebook_add_selection (AtkSelection *selection, - gint i) -{ - GtkNotebook *notebook; - GtkWidget *widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - /* - * State is defunct - */ - return FALSE; - - notebook = GTK_NOTEBOOK (widget); - gtk_notebook_set_current_page (notebook, i); - return TRUE; -} - -static AtkObject* -gail_notebook_ref_selection (AtkSelection *selection, - gint i) -{ - AtkObject *accessible; - GtkWidget *widget; - GtkNotebook *notebook; - gint pagenum; - - if (i != 0) - return NULL; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - /* State is defunct */ - return NULL; - - notebook = GTK_NOTEBOOK (widget); - pagenum = gtk_notebook_get_current_page (notebook); - if (pagenum == -1) - return NULL; - accessible = gail_notebook_ref_child (ATK_OBJECT (selection), pagenum); - - return accessible; -} - -/* - * Always return 1 because there can only be one page - * selected at any time - */ -static gint -gail_notebook_get_selection_count (AtkSelection *selection) -{ - GtkWidget *widget; - GtkNotebook *notebook; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - /* - * State is defunct - */ - return 0; - - notebook = GTK_NOTEBOOK (widget); - if (notebook == NULL || gtk_notebook_get_current_page (notebook) == -1) - return 0; - else - return 1; -} - -static gboolean -gail_notebook_is_child_selected (AtkSelection *selection, - gint i) -{ - GtkWidget *widget; - GtkNotebook *notebook; - gint pagenumber; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - /* - * State is defunct - */ - return FALSE; - - - notebook = GTK_NOTEBOOK (widget); - pagenumber = gtk_notebook_get_current_page(notebook); - - if (pagenumber == i) - return TRUE; - else - return FALSE; -} - -static void -create_notebook_page_accessible (GailNotebook *gail_notebook, - GtkNotebook *notebook, - GtkWidget *child, - int page_num) -{ - AtkObject *obj; - - obj = gail_notebook_page_new (gail_notebook, child); - g_hash_table_insert (gail_notebook->pages, - child, - obj); - atk_object_set_parent (obj, ATK_OBJECT (gail_notebook)); - g_signal_emit_by_name (gail_notebook, "children_changed::add", page_num, obj, NULL); -} - -static gboolean -gail_notebook_focus_cb (GtkWidget *widget, - GtkDirectionType type) -{ - AtkObject *atk_obj = gtk_widget_get_accessible (widget); - GailNotebook *gail_notebook = GAIL_NOTEBOOK (atk_obj); - - switch (type) - { - case GTK_DIR_LEFT: - case GTK_DIR_RIGHT: - if (gail_notebook->idle_focus_id == 0) - gail_notebook->idle_focus_id = gdk_threads_add_idle (gail_notebook_check_focus_tab, atk_obj); - break; - default: - break; - } - return FALSE; -} - -static gboolean -gail_notebook_check_focus_tab (gpointer data) -{ - GtkWidget *widget; - AtkObject *atk_obj; - gint focus_page_num, old_focus_page_num; - GailNotebook *gail_notebook; - GtkNotebook *gtk_notebook; - - atk_obj = ATK_OBJECT (data); - gail_notebook = GAIL_NOTEBOOK (atk_obj); - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_obj)); - - gtk_notebook = GTK_NOTEBOOK (widget); - - gail_notebook->idle_focus_id = 0; - - focus_page_num = gtk_notebook_get_current_page (gtk_notebook); - if (focus_page_num == -1) - return FALSE; - - old_focus_page_num = gail_notebook->focus_tab_page; - gail_notebook->focus_tab_page = focus_page_num; - if (old_focus_page_num != focus_page_num) - { - AtkObject *obj; - - obj = atk_object_ref_accessible_child (atk_obj, focus_page_num); - atk_focus_tracker_notify (obj); - g_object_unref (obj); - } - - return FALSE; -} - -static void -gail_notebook_destroyed (gpointer data) -{ - GailNotebook *gail_notebook = GAIL_NOTEBOOK (data); - - if (gail_notebook->idle_focus_id) - { - g_source_remove (gail_notebook->idle_focus_id); - gail_notebook->idle_focus_id = 0; - } -} diff --git a/gtk/a11y/gailnotebookpage.c b/gtk/a11y/gailnotebookpage.c index 9f6b0005fe..e15d7f51a2 100644 --- a/gtk/a11y/gailnotebookpage.c +++ b/gtk/a11y/gailnotebookpage.c @@ -140,7 +140,7 @@ gail_notebook_page_init (GailNotebookPage *page) } AtkObject* -gail_notebook_page_new (GailNotebook *notebook, +gail_notebook_page_new (GtkNotebookAccessible *notebook, GtkWidget *child) { GObject *object; @@ -148,7 +148,7 @@ gail_notebook_page_new (GailNotebook *notebook, GailNotebookPage *page; GtkWidget *label; - g_return_val_if_fail (GAIL_IS_NOTEBOOK (notebook), NULL); + g_return_val_if_fail (GTK_IS_NOTEBOOK_ACCESSIBLE (notebook), NULL); g_return_val_if_fail (GTK_WIDGET (child), NULL); object = g_object_new (GAIL_TYPE_NOTEBOOK_PAGE, NULL); diff --git a/gtk/a11y/gailnotebookpage.h b/gtk/a11y/gailnotebookpage.h index b8e7a292f0..b5ba31d987 100644 --- a/gtk/a11y/gailnotebookpage.h +++ b/gtk/a11y/gailnotebookpage.h @@ -20,7 +20,7 @@ #ifndef __GAIL_NOTEBOOK_PAGE_H__ #define __GAIL_NOTEBOOK_PAGE_H__ -#include "gailnotebook.h" +#include "gtknotebookaccessible.h" #include "gailtextutil.h" G_BEGIN_DECLS @@ -40,20 +40,21 @@ struct _GailNotebookPage AtkObject parent; GtkAccessible *notebook; - + GtkWidget *child; GailTextUtil *textutil; }; -GType gail_notebook_page_get_type (void); - struct _GailNotebookPageClass { AtkObjectClass parent_class; }; -AtkObject *gail_notebook_page_new (GailNotebook *notebook, GtkWidget *child); +GType gail_notebook_page_get_type (void); + +AtkObject *gail_notebook_page_new (GtkNotebookAccessible *notebook, + GtkWidget *child); void gail_notebook_page_invalidate (GailNotebookPage *page); diff --git a/gtk/a11y/gtknotebookaccessible.c b/gtk/a11y/gtknotebookaccessible.c new file mode 100644 index 0000000000..ba4040361f --- /dev/null +++ b/gtk/a11y/gtknotebookaccessible.c @@ -0,0 +1,407 @@ +/* GAIL - The GNOME Accessibility Implementation Library + * Copyright 2001, 2002, 2003 Sun Microsystems Inc. + * + * 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 "config.h" + +#include <string.h> +#include <gtk/gtk.h> +#include "gtknotebookaccessible.h" +#include "gailnotebookpage.h" + + +static void atk_selection_interface_init (AtkSelectionIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GtkNotebookAccessible, gtk_notebook_accessible, GAIL_TYPE_CONTAINER, + G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init)) + +static gboolean +check_focus_tab (gpointer data) +{ + GtkWidget *widget; + AtkObject *atk_obj; + gint focus_page_num, old_focus_page_num; + GtkNotebookAccessible *accessible; + GtkNotebook *notebook; + + atk_obj = ATK_OBJECT (data); + accessible = GTK_NOTEBOOK_ACCESSIBLE (atk_obj); + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_obj)); + notebook = GTK_NOTEBOOK (widget); + + accessible->idle_focus_id = 0; + + focus_page_num = gtk_notebook_get_current_page (notebook); + if (focus_page_num == -1) + return FALSE; + + old_focus_page_num = accessible->focus_tab_page; + accessible->focus_tab_page = focus_page_num; + if (old_focus_page_num != focus_page_num) + { + AtkObject *obj; + + obj = atk_object_ref_accessible_child (atk_obj, focus_page_num); + atk_focus_tracker_notify (obj); + g_object_unref (obj); + } + + return FALSE; +} + +static gboolean +focus_cb (GtkWidget *widget, + GtkDirectionType type) +{ + AtkObject *atk_obj = gtk_widget_get_accessible (widget); + GtkNotebookAccessible *accessible = GTK_NOTEBOOK_ACCESSIBLE (atk_obj); + + switch (type) + { + case GTK_DIR_LEFT: + case GTK_DIR_RIGHT: + if (accessible->idle_focus_id == 0) + accessible->idle_focus_id = gdk_threads_add_idle (check_focus_tab, atk_obj); + break; + default: + break; + } + return FALSE; +} + +static void +create_notebook_page_accessible (GtkNotebookAccessible *accessible, + GtkNotebook *notebook, + GtkWidget *child, + gint page_num) +{ + AtkObject *obj; + + obj = gail_notebook_page_new (accessible, child); + g_hash_table_insert (accessible->pages, child, obj); + atk_object_set_parent (obj, ATK_OBJECT (accessible)); + g_signal_emit_by_name (accessible, "children_changed::add", page_num, obj, NULL); +} + +static void +page_added_cb (GtkNotebook *notebook, + GtkWidget *child, + guint page_num, + gpointer data) +{ + AtkObject *atk_obj; + GtkNotebookAccessible *accessible; + + atk_obj = gtk_widget_get_accessible (GTK_WIDGET (notebook)); + accessible = GTK_NOTEBOOK_ACCESSIBLE (atk_obj); + create_notebook_page_accessible (accessible, notebook, child, page_num); +} + +static void +page_removed_cb (GtkNotebook *notebook, + GtkWidget *widget, + guint page_num, + gpointer data) +{ + GtkNotebookAccessible *accessible; + AtkObject *obj; + + accessible = GTK_NOTEBOOK_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (notebook))); + + obj = g_hash_table_lookup (accessible->pages, widget); + g_return_if_fail (obj); + g_signal_emit_by_name (accessible, "children_changed::remove", + page_num, obj, NULL); + gail_notebook_page_invalidate (GAIL_NOTEBOOK_PAGE (obj)); + g_hash_table_remove (accessible->pages, widget); +} + + +static void +accessible_destroyed (gpointer data) +{ + GtkNotebookAccessible *accessible = GTK_NOTEBOOK_ACCESSIBLE (data); + + if (accessible->idle_focus_id) + { + g_source_remove (accessible->idle_focus_id); + accessible->idle_focus_id = 0; + } +} +static void +gtk_notebook_accessible_initialize (AtkObject *obj, + gpointer data) +{ + GtkNotebookAccessible *accessible; + GtkNotebook *notebook; + gint i; + + ATK_OBJECT_CLASS (gtk_notebook_accessible_parent_class)->initialize (obj, data); + + accessible = GTK_NOTEBOOK_ACCESSIBLE (obj); + notebook = GTK_NOTEBOOK (data); + for (i = 0; i < gtk_notebook_get_n_pages (notebook); i++) + { + create_notebook_page_accessible (accessible, + notebook, + gtk_notebook_get_nth_page (notebook, i), + i); + } + accessible->selected_page = gtk_notebook_get_current_page (notebook); + + g_signal_connect (notebook, "focus", + G_CALLBACK (focus_cb), NULL); + g_signal_connect (notebook, "page-added", + G_CALLBACK (page_added_cb), NULL); + g_signal_connect (notebook, "page-removed", + G_CALLBACK (page_removed_cb), NULL); + + g_object_weak_ref (G_OBJECT (notebook), (GWeakNotify)accessible_destroyed, obj); + + obj->role = ATK_ROLE_PAGE_TAB_LIST; +} + +static void +gtk_notebook_accessible_finalize (GObject *object) +{ + GtkNotebookAccessible *accessible = GTK_NOTEBOOK_ACCESSIBLE (object); + + g_hash_table_destroy (accessible->pages); + + if (accessible->idle_focus_id) + g_source_remove (accessible->idle_focus_id); + + G_OBJECT_CLASS (gtk_notebook_accessible_parent_class)->finalize (object); +} + +static AtkObject * +gtk_notebook_accessible_ref_child (AtkObject *obj, + gint i) +{ + AtkObject *child; + GtkNotebookAccessible *accessible; + GtkNotebook *notebook; + GtkWidget *widget; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); + if (widget == NULL) + return NULL; + + accessible = GTK_NOTEBOOK_ACCESSIBLE (obj); + notebook = GTK_NOTEBOOK (widget); + + child = g_hash_table_lookup (accessible->pages, + gtk_notebook_get_nth_page (notebook, i)); + /* can return NULL when i >= n_children */ + + if (child) + g_object_ref (child); + + return child; +} + +static void +gtk_notebook_accessible_notify_gtk (GObject *obj, + GParamSpec *pspec) +{ + GtkWidget *widget; + AtkObject* atk_obj; + + widget = GTK_WIDGET (obj); + atk_obj = gtk_widget_get_accessible (widget); + + if (strcmp (pspec->name, "page") == 0) + { + gint page_num, old_page_num; + gint focus_page_num = 0; + gint old_focus_page_num; + GtkNotebookAccessible *accessible; + GtkNotebook *notebook; + + accessible = GTK_NOTEBOOK_ACCESSIBLE (atk_obj); + notebook = GTK_NOTEBOOK (widget); + + /* Notify SELECTED state change for old and new page */ + old_page_num = accessible->selected_page; + page_num = gtk_notebook_get_current_page (notebook); + accessible->selected_page = page_num; + accessible->focus_tab_page = page_num; + old_focus_page_num = accessible->focus_tab_page; + + if (page_num != old_page_num) + { + AtkObject *obj; + + if (old_page_num != -1) + { + obj = gtk_notebook_accessible_ref_child (atk_obj, old_page_num); + if (obj) + { + atk_object_notify_state_change (obj, ATK_STATE_SELECTED, FALSE); + g_object_unref (obj); + } + } + obj = gtk_notebook_accessible_ref_child (atk_obj, page_num); + if (obj) + { + atk_object_notify_state_change (obj, ATK_STATE_SELECTED, TRUE); + g_object_unref (obj); + /* + * The page which is being displayed has changed but there is + * no need to tell the focus tracker as the focus page will also + * change or a widget in the page will receive focus if the + * Notebook does not have tabs. + */ + } + g_signal_emit_by_name (atk_obj, "selection_changed"); + g_signal_emit_by_name (atk_obj, "visible_data_changed"); + } + if (gtk_notebook_get_show_tabs (notebook) && + (focus_page_num != old_focus_page_num)) + { + if (accessible->idle_focus_id) + g_source_remove (accessible->idle_focus_id); + accessible->idle_focus_id = gdk_threads_add_idle (check_focus_tab, atk_obj); + } + } + else + GAIL_WIDGET_CLASS (gtk_notebook_accessible_parent_class)->notify_gtk (obj, pspec); +} + +/* + * GtkNotebook only supports the selection of one page at a time. + * Selecting a page unselects any previous selection, so this + * changes the current selection instead of adding to it. + */ +static gboolean +gtk_notebook_accessible_add_selection (AtkSelection *selection, + gint i) +{ + GtkNotebook *notebook; + GtkWidget *widget; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); + if (widget == NULL) + return FALSE; + + notebook = GTK_NOTEBOOK (widget); + gtk_notebook_set_current_page (notebook, i); + return TRUE; +} + +static void +gtk_notebook_accessible_class_init (GtkNotebookAccessibleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + GailWidgetClass *widget_class = (GailWidgetClass*)klass; + + gobject_class->finalize = gtk_notebook_accessible_finalize; + + class->ref_child = gtk_notebook_accessible_ref_child; + class->initialize = gtk_notebook_accessible_initialize; + + widget_class->notify_gtk = gtk_notebook_accessible_notify_gtk; +} + +static void +gtk_notebook_accessible_init (GtkNotebookAccessible *notebook) +{ + notebook->pages = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + g_object_unref); + notebook->selected_page = -1; + notebook->focus_tab_page = -1; + notebook->idle_focus_id = 0; +} + +static AtkObject * +gtk_notebook_accessible_ref_selection (AtkSelection *selection, + gint i) +{ + AtkObject *accessible; + GtkWidget *widget; + GtkNotebook *notebook; + gint pagenum; + + if (i != 0) + return NULL; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); + if (widget == NULL) + return NULL; + + notebook = GTK_NOTEBOOK (widget); + pagenum = gtk_notebook_get_current_page (notebook); + if (pagenum == -1) + return NULL; + accessible = gtk_notebook_accessible_ref_child (ATK_OBJECT (selection), pagenum); + + return accessible; +} + +/* Always return 1 because there can only be one page + * selected at any time + */ +static gint +gtk_notebook_accessible_get_selection_count (AtkSelection *selection) +{ + GtkWidget *widget; + GtkNotebook *notebook; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); + if (widget == NULL) + return 0; + + notebook = GTK_NOTEBOOK (widget); + if (notebook == NULL || gtk_notebook_get_current_page (notebook) == -1) + return 0; + + return 1; +} + +static gboolean +gtk_notebook_accessible_is_child_selected (AtkSelection *selection, + gint i) +{ + GtkWidget *widget; + GtkNotebook *notebook; + gint pagenumber; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); + if (widget == NULL) + return FALSE; + + notebook = GTK_NOTEBOOK (widget); + pagenumber = gtk_notebook_get_current_page(notebook); + + if (pagenumber == i) + return TRUE; + + return FALSE; +} + +static void +atk_selection_interface_init (AtkSelectionIface *iface) +{ + iface->add_selection = gtk_notebook_accessible_add_selection; + iface->ref_selection = gtk_notebook_accessible_ref_selection; + iface->get_selection_count = gtk_notebook_accessible_get_selection_count; + iface->is_child_selected = gtk_notebook_accessible_is_child_selected; +} diff --git a/gtk/a11y/gailnotebook.h b/gtk/a11y/gtknotebookaccessible.h index a22c5f4f24..770c12b070 100644 --- a/gtk/a11y/gailnotebook.h +++ b/gtk/a11y/gtknotebookaccessible.h @@ -17,30 +17,30 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __GAIL_NOTEBOOK_H__ -#define __GAIL_NOTEBOOK_H__ +#ifndef __GTK_NOTEBOOK_ACCESSIBLE_H__ +#define __GTK_NOTEBOOK_ACCESSIBLE_H__ #include "gailcontainer.h" G_BEGIN_DECLS -#define GAIL_TYPE_NOTEBOOK (gail_notebook_get_type ()) -#define GAIL_NOTEBOOK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_NOTEBOOK, GailNotebook)) -#define GAIL_NOTEBOOK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_NOTEBOOK, GailNotebookClass)) -#define GAIL_IS_NOTEBOOK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_NOTEBOOK)) -#define GAIL_IS_NOTEBOOK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_NOTEBOOK)) -#define GAIL_NOTEBOOK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_NOTEBOOK, GailNotebookClass)) +#define GTK_TYPE_NOTEBOOK_ACCESSIBLE (gtk_notebook_accessible_get_type ()) +#define GTK_NOTEBOOK_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_NOTEBOOK_ACCESSIBLE, GtkNotebookAccessible)) +#define GTK_NOTEBOOK_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_NOTEBOOK_ACCESSIBLE, GtkNotebookAccessibleClass)) +#define GTK_IS_NOTEBOOK_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_NOTEBOOK_ACCESSIBLE)) +#define GTK_IS_NOTEBOOK_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_NOTEBOOK_ACCESSIBLE)) +#define GTK_NOTEBOOK_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_NOTEBOOK_ACCESSIBLE, GtkNotebookAccessibleClass)) -typedef struct _GailNotebook GailNotebook; -typedef struct _GailNotebookClass GailNotebookClass; +typedef struct _GtkNotebookAccessible GtkNotebookAccessible; +typedef struct _GtkNotebookAccessibleClass GtkNotebookAccessibleClass; -struct _GailNotebook +struct _GtkNotebookAccessible { GailContainer parent; /* * page_cache maintains a list of pre-ref'd Notebook Pages. - * This cache is queried by gail_notebook_ref_child(). + * This cache is queried by gtk_notebook_accessible_ref_child(). * If the page is found in the list then a new page does not * need to be created */ @@ -50,13 +50,13 @@ struct _GailNotebook guint idle_focus_id; }; -GType gail_notebook_get_type (void); - -struct _GailNotebookClass +struct _GtkNotebookAccessibleClass { GailContainerClass parent_class; }; +GType gtk_notebook_accessible_get_type (void); + G_END_DECLS -#endif /* __GAIL_NOTEBOOK_H__ */ +#endif /* __GTK_NOTEBOOK_ACCESSIBLE_H__ */ |