[evince/gnome-3-12] a11y: managing atk states on EvPageAccessible



commit 83e8534d8e5f541c3d82d8e18a9e7564c98e43fb
Author: Alejandro Piñeiro <apinheiro igalia com>
Date:   Mon Apr 7 18:29:30 2014 +0200

    a11y: managing atk states on EvPageAccessible
    
    This includes:
     * Implements ref_state_set on EvPageAccessible
     * Notify FOCUSED state changes
    
    https://bugzilla.gnome.org/show_bug.cgi?id=724965

 libview/ev-page-accessible.c |   49 ++++++++++++++++++++++++++++++++++++++++++
 libview/ev-view-accessible.c |   47 ++++++++++++++++++++++++++++++++++++++++
 libview/ev-view-accessible.h |    1 +
 3 files changed, 97 insertions(+), 0 deletions(-)
---
diff --git a/libview/ev-page-accessible.c b/libview/ev-page-accessible.c
index 4f66726..ac322c1 100644
--- a/libview/ev-page-accessible.c
+++ b/libview/ev-page-accessible.c
@@ -180,6 +180,54 @@ ev_page_accessible_ref_relation_set (AtkObject *accessible)
        return relation_set;
 }
 
+/* page accessible's state set is a copy ev-view accessible's state
+ * set but removing ATK_STATE_SHOWING if the page is not on screen and
+ * ATK_STATE_FOCUSED if it is not the relevant page. */
+static AtkStateSet *
+ev_page_accessible_ref_state_set (AtkObject *accessible)
+{
+       AtkStateSet *state_set;
+       AtkStateSet *copy_set;
+       AtkStateSet *view_accessible_state_set;
+       EvPageAccessible *self;
+       EvView *view;
+       gint relevant_page;
+
+       g_return_val_if_fail (EV_IS_PAGE_ACCESSIBLE (accessible), NULL);
+       self = EV_PAGE_ACCESSIBLE (accessible);
+       view = ev_page_accessible_get_view (self);
+
+       state_set = ATK_OBJECT_CLASS (ev_page_accessible_parent_class)->ref_state_set (accessible);
+       atk_state_set_clear_states (state_set);
+
+       view_accessible_state_set = atk_object_ref_state_set (ATK_OBJECT (self->priv->view_accessible));
+       copy_set = atk_state_set_or_sets (state_set, view_accessible_state_set);
+
+       if (self->priv->page >= view->start_page && self->priv->page <= view->end_page)
+               atk_state_set_add_state (copy_set, ATK_STATE_SHOWING);
+       else
+               atk_state_set_remove_state (copy_set, ATK_STATE_SHOWING);
+
+       relevant_page = ev_view_accessible_get_relevant_page (self->priv->view_accessible);
+       if (atk_state_set_contains_state (view_accessible_state_set, ATK_STATE_FOCUSED) &&
+           self->priv->page == relevant_page)
+               atk_state_set_add_state (copy_set, ATK_STATE_FOCUSED);
+       else
+               atk_state_set_remove_state (copy_set, ATK_STATE_FOCUSED);
+
+       relevant_page = ev_view_accessible_get_relevant_page (self->priv->view_accessible);
+       if (atk_state_set_contains_state (view_accessible_state_set, ATK_STATE_FOCUSED) &&
+           self->priv->page == relevant_page)
+               atk_state_set_add_state (copy_set, ATK_STATE_FOCUSED);
+       else
+               atk_state_set_remove_state (copy_set, ATK_STATE_FOCUSED);
+
+       g_object_unref (state_set);
+       g_object_unref (view_accessible_state_set);
+
+       return copy_set;
+}
+
 static void
 ev_page_accessible_class_init (EvPageAccessibleClass *klass)
 {
@@ -190,6 +238,7 @@ ev_page_accessible_class_init (EvPageAccessibleClass *klass)
 
        atk_class->get_parent  = ev_page_accessible_get_parent;
        atk_class->ref_relation_set = ev_page_accessible_ref_relation_set;
+       atk_class->ref_state_set = ev_page_accessible_ref_state_set;
 
        g_object_class->get_property = ev_page_accessible_get_property;
        g_object_class->set_property = ev_page_accessible_set_property;
diff --git a/libview/ev-view-accessible.c b/libview/ev-view-accessible.c
index ccf5efe..6b4c8b9 100644
--- a/libview/ev-view-accessible.c
+++ b/libview/ev-view-accessible.c
@@ -314,7 +314,16 @@ ev_view_accessible_cursor_moved (EvView *view,
        EvPageAccessible *page_accessible = NULL;
 
        if (priv->previous_cursor_page != page) {
+               AtkObject *previous_page = NULL;
+               AtkObject *current_page = NULL;
+
+               previous_page = g_ptr_array_index (priv->children,
+                                                  priv->previous_cursor_page);
+               atk_object_notify_state_change (previous_page, ATK_STATE_FOCUSED, FALSE);
                priv->previous_cursor_page = page;
+               current_page = g_ptr_array_index (priv->children, page);
+               atk_object_notify_state_change (current_page, ATK_STATE_FOCUSED, TRUE);
+
 #if ATK_CHECK_VERSION (2, 11, 2)
                /* +1 as user start to count on 1, but evince starts on 0 */
                g_signal_emit_by_name (accessible, "page-changed", page + 1);
@@ -418,6 +427,27 @@ ev_view_accessible_set_model (EvViewAccessible *accessible,
                          accessible);
 }
 
+static gboolean
+ev_view_accessible_focus_changed (GtkWidget        *widget,
+                                 GdkEventFocus    *event,
+                                 EvViewAccessible *self)
+{
+       AtkObject *page_accessible;
+
+       g_return_val_if_fail (EV_IS_VIEW (widget), FALSE);
+       g_return_val_if_fail (EV_IS_VIEW_ACCESSIBLE (self), FALSE);
+
+       if (self->priv->children == NULL)
+               return FALSE;
+
+       page_accessible = g_ptr_array_index (self->priv->children,
+                                            get_relevant_page (EV_VIEW (widget)));
+       atk_object_notify_state_change (page_accessible,
+                                       ATK_STATE_FOCUSED, event->in);
+
+       return FALSE;
+}
+
 AtkObject *
 ev_view_accessible_new (GtkWidget *widget)
 {
@@ -435,6 +465,12 @@ ev_view_accessible_new (GtkWidget *widget)
        g_signal_connect (widget, "selection-changed",
                          G_CALLBACK (ev_view_accessible_selection_changed),
                          accessible);
+       g_signal_connect (widget, "focus-in-event",
+                         G_CALLBACK (ev_view_accessible_focus_changed),
+                         accessible);
+       g_signal_connect (widget, "focus-out-event",
+                         G_CALLBACK (ev_view_accessible_focus_changed),
+                         accessible);
 
        view = EV_VIEW (widget);
        if (view->model)
@@ -444,3 +480,14 @@ ev_view_accessible_new (GtkWidget *widget)
        return accessible;
 }
 
+gint
+ev_view_accessible_get_relevant_page (EvViewAccessible *accessible)
+{
+       EvView *view;
+
+       g_return_val_if_fail (EV_IS_VIEW_ACCESSIBLE (accessible), -1);
+
+       view = EV_VIEW (gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)));
+
+       return get_relevant_page (view);
+}
diff --git a/libview/ev-view-accessible.h b/libview/ev-view-accessible.h
index 44e7bc8..32798c3 100644
--- a/libview/ev-view-accessible.h
+++ b/libview/ev-view-accessible.h
@@ -53,6 +53,7 @@ AtkObject *ev_view_accessible_new       (GtkWidget *widget);
 void       ev_view_accessible_set_model (EvViewAccessible *accessible,
                                         EvDocumentModel  *model);
 gint       ev_view_accessible_get_n_pages (EvViewAccessible *accessible);
+gint       ev_view_accessible_get_relevant_page (EvViewAccessible *accessible);
 
 #endif  /* __EV_VIEW_ACCESSIBLE_H__ */
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]