Back to index

unity  6.0.0
nux-layout-accessible.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Canonical Ltd
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License version 3 as
00006  * published by the Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00015  *
00016  * Authored by: Alejandro PiƱeiro Iglesias <apinheiro@igalia.com>
00017  */
00018 
00031 #include "nux-layout-accessible.h"
00032 
00033 #include "unitya11y.h"
00034 
00035 /* GObject */
00036 static void nux_layout_accessible_class_init(NuxLayoutAccessibleClass* klass);
00037 static void nux_layout_accessible_init(NuxLayoutAccessible* layout_accessible);
00038 
00039 /* AtkObject.h */
00040 static void       nux_layout_accessible_initialize(AtkObject* accessible,
00041                                                    gpointer   data);
00042 static gint       nux_layout_accessible_get_n_children(AtkObject* obj);
00043 static AtkObject* nux_layout_accessible_ref_child(AtkObject* obj,
00044                                                   gint i);
00045 
00046 /* private */
00047 static void       on_view_changed_cb(nux::Layout* layout,
00048                                      nux::Area* area,
00049                                      AtkObject* acccessible,
00050                                      gboolean is_add);
00051 static int        search_for_child(AtkObject* accessible,
00052                                    nux::Layout* layout,
00053                                    nux::Area* area);
00054 
00055 G_DEFINE_TYPE(NuxLayoutAccessible, nux_layout_accessible,  NUX_TYPE_AREA_ACCESSIBLE)
00056 
00057 static void
00058 nux_layout_accessible_class_init(NuxLayoutAccessibleClass* klass)
00059 {
00060   AtkObjectClass* atk_class = ATK_OBJECT_CLASS(klass);
00061 
00062   /* AtkObject */
00063   atk_class->initialize = nux_layout_accessible_initialize;
00064   atk_class->ref_child = nux_layout_accessible_ref_child;
00065   atk_class->get_n_children = nux_layout_accessible_get_n_children;
00066 }
00067 
00068 static void
00069 nux_layout_accessible_init(NuxLayoutAccessible* layout_accessible)
00070 {
00071 }
00072 
00073 AtkObject*
00074 nux_layout_accessible_new(nux::Object* object)
00075 {
00076   AtkObject* accessible = NULL;
00077 
00078   g_return_val_if_fail(dynamic_cast<nux::Layout*>(object), NULL);
00079 
00080   accessible = ATK_OBJECT(g_object_new(NUX_TYPE_LAYOUT_ACCESSIBLE, NULL));
00081 
00082   atk_object_initialize(accessible, object);
00083 
00084   return accessible;
00085 }
00086 
00087 /* AtkObject.h */
00088 static void
00089 nux_layout_accessible_initialize(AtkObject* accessible,
00090                                  gpointer data)
00091 {
00092   nux::Object* nux_object = NULL;
00093   nux::Layout* layout = NULL;
00094 
00095   ATK_OBJECT_CLASS(nux_layout_accessible_parent_class)->initialize(accessible, data);
00096 
00097   accessible->role = ATK_ROLE_PANEL;
00098 
00099   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(accessible));
00100   layout = dynamic_cast<nux::Layout*>(nux_object);
00101 
00102   layout->ViewAdded.connect(sigc::bind(sigc::ptr_fun(on_view_changed_cb),
00103                                        accessible, TRUE));
00104 
00105   layout->ViewRemoved.connect(sigc::bind(sigc::ptr_fun(on_view_changed_cb),
00106                                          accessible, FALSE));
00107 }
00108 
00109 static gint
00110 nux_layout_accessible_get_n_children(AtkObject* obj)
00111 {
00112   nux::Object* nux_object = NULL;
00113   nux::Layout* layout = NULL;
00114   std::list<nux::Area*> element_list;
00115 
00116   g_return_val_if_fail(NUX_IS_LAYOUT_ACCESSIBLE(obj), 0);
00117 
00118   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj));
00119   if (!nux_object) /* state is defunct */
00120     return 0;
00121 
00122   layout = dynamic_cast<nux::Layout*>(nux_object);
00123 
00124   element_list = layout->GetChildren();
00125 
00126   return element_list.size();
00127 }
00128 
00129 static AtkObject*
00130 nux_layout_accessible_ref_child(AtkObject* obj,
00131                                 gint i)
00132 {
00133   nux::Object* nux_object = NULL;
00134   nux::Object* child = NULL;
00135   AtkObject* child_accessible = NULL;
00136   nux::Layout* layout = NULL;
00137   std::list<nux::Area*> element_list;
00138   gint num = 0;
00139   std::list<nux::Area*>::iterator it;
00140 
00141   g_return_val_if_fail(NUX_IS_LAYOUT_ACCESSIBLE(obj), 0);
00142   num = atk_object_get_n_accessible_children(obj);
00143   g_return_val_if_fail((i < num) && (i >= 0), NULL);
00144 
00145   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj));
00146   if (!nux_object) /* state is defunct */
00147     return 0;
00148 
00149   layout = dynamic_cast<nux::Layout*>(nux_object);
00150 
00151   element_list = layout->GetChildren();
00152 
00153   it = element_list.begin();
00154   std::advance(it, i);
00155 
00156   child = dynamic_cast<nux::Object*>(*it);
00157   child_accessible = unity_a11y_get_accessible(child);
00158 
00159   g_object_ref(child_accessible);
00160 
00161   return child_accessible;
00162 }
00163 
00164 /* private */
00165 static void
00166 on_view_changed_cb(nux::Layout* layout,
00167                    nux::Area* area,
00168                    AtkObject* accessible,
00169                    gboolean is_add)
00170 {
00171   const gchar* signal_name = NULL;
00172   AtkObject* atk_child = NULL;
00173   gint index;
00174 
00175   g_return_if_fail(NUX_IS_LAYOUT_ACCESSIBLE(accessible));
00176 
00177   atk_child = unity_a11y_get_accessible(area);
00178 
00179   if (is_add)
00180   {
00181     signal_name = "children-changed::add";
00182     index = nux_layout_accessible_get_n_children(accessible) - 1;
00183   }
00184   else
00185   {
00186     signal_name = "children-changed::remove";
00187     index = search_for_child(accessible, layout, area);
00188   }
00189 
00190   g_signal_emit_by_name(accessible, signal_name, index, atk_child, NULL);
00191 }
00192 
00193 static int
00194 search_for_child(AtkObject* accessible,
00195                  nux::Layout* layout,
00196                  nux::Area* area)
00197 {
00198   std::list<nux::Area*> element_list;
00199   std::list<nux::Area*>::iterator it;
00200   nux::Area* current_area = NULL;
00201   gint result = 0;
00202   gboolean found = FALSE;
00203 
00204   element_list = layout->GetChildren();
00205 
00206   for (it = element_list.begin(); it != element_list.end(); it++, result++)
00207   {
00208     current_area = *it;
00209     if (current_area == area)
00210     {
00211       found = TRUE;
00212       break;
00213     }
00214   }
00215 
00216   if (!found) result = -1;
00217 
00218   return result;
00219 }