Back to index

unity  6.0.0
unity-launcher-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 <glib/gi18n.h>
00032 
00033 #include "unity-launcher-accessible.h"
00034 #include "unity-launcher-icon-accessible.h"
00035 
00036 #include "unitya11y.h"
00037 #include "Launcher.h"
00038 #include "LauncherModel.h"
00039 
00040 using unity::launcher::Launcher;
00041 using unity::launcher::AbstractLauncherIcon;
00042 using unity::launcher::LauncherModel;
00043 
00044 /* GObject */
00045 static void unity_launcher_accessible_class_init(UnityLauncherAccessibleClass* klass);
00046 static void unity_launcher_accessible_init(UnityLauncherAccessible* self);
00047 static void unity_launcher_accessible_finalize(GObject* object);
00048 
00049 /* AtkObject.h */
00050 static void       unity_launcher_accessible_initialize(AtkObject* accessible,
00051                                                        gpointer   data);
00052 static gint       unity_launcher_accessible_get_n_children(AtkObject* obj);
00053 static AtkObject* unity_launcher_accessible_ref_child(AtkObject* obj,
00054                                                       gint i);
00055 static AtkStateSet* unity_launcher_accessible_ref_state_set(AtkObject* obj);
00056 
00057 /* AtkSelection */
00058 static void       atk_selection_interface_init(AtkSelectionIface* iface);
00059 static AtkObject* unity_launcher_accessible_ref_selection(AtkSelection* selection,
00060                                                           gint i);
00061 static gint       unity_launcher_accessible_get_selection_count(AtkSelection* selection);
00062 static gboolean   unity_launcher_accessible_is_child_selected(AtkSelection* selection,
00063                                                               gint i);
00064 
00065 /* private */
00066 static void on_selection_change_cb(AbstractLauncherIcon::Ptr selection, UnityLauncherAccessible* launcher_accessible);
00067 static void on_icon_added_cb(AbstractLauncherIcon::Ptr icon, UnityLauncherAccessible* self);
00068 static void on_icon_removed_cb(AbstractLauncherIcon::Ptr icon, UnityLauncherAccessible* self);
00069 static void on_order_change_cb(UnityLauncherAccessible* self);
00070 static void update_children_index(UnityLauncherAccessible* self);
00071 
00072 G_DEFINE_TYPE_WITH_CODE(UnityLauncherAccessible, unity_launcher_accessible,  NUX_TYPE_VIEW_ACCESSIBLE,
00073                         G_IMPLEMENT_INTERFACE(ATK_TYPE_SELECTION, atk_selection_interface_init))
00074 
00075 #define UNITY_LAUNCHER_ACCESSIBLE_GET_PRIVATE(obj)                      \
00076   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UNITY_TYPE_LAUNCHER_ACCESSIBLE,  \
00077                                 UnityLauncherAccessiblePrivate))
00078 
00079 struct _UnityLauncherAccessiblePrivate
00080 {
00081   sigc::connection on_selection_change_connection;
00082   sigc::connection on_icon_added_connection;
00083   sigc::connection on_icon_removed_connection;
00084   sigc::connection on_order_changed_connection;
00085 };
00086 
00087 
00088 static void
00089 unity_launcher_accessible_class_init(UnityLauncherAccessibleClass* klass)
00090 {
00091   GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
00092   AtkObjectClass* atk_class = ATK_OBJECT_CLASS(klass);
00093 
00094   gobject_class->finalize = unity_launcher_accessible_finalize;
00095 
00096   /* AtkObject */
00097   atk_class->get_n_children = unity_launcher_accessible_get_n_children;
00098   atk_class->ref_child = unity_launcher_accessible_ref_child;
00099   atk_class->initialize = unity_launcher_accessible_initialize;
00100   atk_class->ref_state_set = unity_launcher_accessible_ref_state_set;
00101 
00102   g_type_class_add_private(gobject_class, sizeof(UnityLauncherAccessiblePrivate));
00103 }
00104 
00105 static void
00106 unity_launcher_accessible_init(UnityLauncherAccessible* self)
00107 {
00108   UnityLauncherAccessiblePrivate* priv =
00109     UNITY_LAUNCHER_ACCESSIBLE_GET_PRIVATE(self);
00110 
00111   self->priv = priv;
00112 }
00113 
00114 static void
00115 unity_launcher_accessible_finalize(GObject* object)
00116 {
00117   UnityLauncherAccessible* self = UNITY_LAUNCHER_ACCESSIBLE(object);
00118 
00119   self->priv->on_selection_change_connection.disconnect();
00120   self->priv->on_icon_added_connection.disconnect();
00121   self->priv->on_icon_removed_connection.disconnect();
00122   self->priv->on_order_changed_connection.disconnect();
00123 
00124   G_OBJECT_CLASS(unity_launcher_accessible_parent_class)->finalize(object);
00125 }
00126 
00127 AtkObject*
00128 unity_launcher_accessible_new(nux::Object* object)
00129 {
00130   AtkObject* accessible = NULL;
00131 
00132   g_return_val_if_fail(dynamic_cast<Launcher*>(object), NULL);
00133 
00134   accessible = ATK_OBJECT(g_object_new(UNITY_TYPE_LAUNCHER_ACCESSIBLE, NULL));
00135 
00136   atk_object_initialize(accessible, object);
00137   atk_object_set_name(accessible, _("Launcher"));
00138 
00139   return accessible;
00140 }
00141 
00142 /* AtkObject.h */
00143 static void
00144 unity_launcher_accessible_initialize(AtkObject* accessible,
00145                                      gpointer data)
00146 {
00147   Launcher* launcher = NULL;
00148   nux::Object* nux_object = NULL;
00149   UnityLauncherAccessible* self = NULL;
00150   LauncherModel::Ptr model = NULL;
00151 
00152   ATK_OBJECT_CLASS(unity_launcher_accessible_parent_class)->initialize(accessible, data);
00153 
00154   accessible->role = ATK_ROLE_TOOL_BAR;
00155 
00156   self = UNITY_LAUNCHER_ACCESSIBLE(accessible);
00157   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(accessible));
00158 
00159   launcher = dynamic_cast<Launcher*>(nux_object);
00160 
00161   model = launcher->GetModel();
00162 
00163   if (model)
00164   {
00165     self->priv->on_selection_change_connection  =
00166       model->selection_changed.connect(sigc::bind(sigc::ptr_fun(on_selection_change_cb), self));
00167 
00168     self->priv->on_icon_added_connection =
00169       model->icon_added.connect(sigc::bind(sigc::ptr_fun(on_icon_added_cb), self));
00170 
00171     self->priv->on_icon_removed_connection =
00172       model->icon_removed.connect(sigc::bind(sigc::ptr_fun(on_icon_removed_cb), self));
00173 
00174     self->priv->on_order_changed_connection =
00175       model->order_changed.connect(sigc::bind(sigc::ptr_fun(on_order_change_cb), self));
00176   }
00177 }
00178 
00179 static gint
00180 unity_launcher_accessible_get_n_children(AtkObject* obj)
00181 {
00182   nux::Object* object = NULL;
00183   Launcher* launcher = NULL;
00184   LauncherModel::Ptr launcher_model;
00185 
00186   g_return_val_if_fail(UNITY_IS_LAUNCHER_ACCESSIBLE(obj), 0);
00187 
00188   object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj));
00189   if (!object) /* state is defunct */
00190     return 0;
00191 
00192   launcher = dynamic_cast<Launcher*>(object);
00193 
00194   launcher_model = launcher->GetModel();
00195 
00196   if (launcher_model)
00197     return launcher_model->Size();
00198   else
00199     return 0;
00200 }
00201 
00202 static AtkObject*
00203 unity_launcher_accessible_ref_child(AtkObject* obj,
00204                                     gint i)
00205 {
00206   gint num = 0;
00207   nux::Object* nux_object = NULL;
00208   Launcher* launcher = NULL;
00209   LauncherModel::Ptr launcher_model;
00210   LauncherModel::iterator it;
00211   nux::Object* child = NULL;
00212   AtkObject* child_accessible = NULL;
00213   AtkObject* parent = NULL;
00214 
00215   g_return_val_if_fail(UNITY_IS_LAUNCHER_ACCESSIBLE(obj), NULL);
00216   num = atk_object_get_n_accessible_children(obj);
00217   g_return_val_if_fail((i < num) && (i >= 0), NULL);
00218 
00219   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj));
00220   if (!nux_object) /* state is defunct */
00221     return 0;
00222 
00223   launcher = dynamic_cast<Launcher*>(nux_object);
00224 
00225   launcher_model = launcher->GetModel();
00226 
00227   it = launcher_model->begin();
00228   std::advance(it, i);
00229 
00230   child = dynamic_cast<nux::Object*>((*it).GetPointer());
00231   child_accessible = unity_a11y_get_accessible(child);
00232 
00233   parent = atk_object_get_parent(child_accessible);
00234   if (parent != obj)
00235     atk_object_set_parent(child_accessible, obj);
00236 
00237   g_object_ref(child_accessible);
00238 
00239   return child_accessible;
00240 }
00241 
00242 static AtkStateSet*
00243 unity_launcher_accessible_ref_state_set(AtkObject* obj)
00244 {
00245   AtkStateSet* state_set = NULL;
00246   nux::Object* nux_object = NULL;
00247 
00248   g_return_val_if_fail(UNITY_IS_LAUNCHER_ACCESSIBLE(obj), NULL);
00249 
00250   state_set =
00251     ATK_OBJECT_CLASS(unity_launcher_accessible_parent_class)->ref_state_set(obj);
00252 
00253   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(obj));
00254 
00255   if (nux_object == NULL) /* defunct */
00256     return state_set;
00257 
00258   /* The Launcher is always focusable */
00259   atk_state_set_add_state(state_set, ATK_STATE_FOCUSABLE);
00260 
00261   return state_set;
00262 }
00263 
00264 /* AtkSelection */
00265 static void
00266 atk_selection_interface_init(AtkSelectionIface* iface)
00267 {
00268   iface->ref_selection = unity_launcher_accessible_ref_selection;
00269   iface->get_selection_count = unity_launcher_accessible_get_selection_count;
00270   iface->is_child_selected = unity_launcher_accessible_is_child_selected;
00271 
00272   /* NOTE: for the moment we don't provide the implementation for the
00273      "interactable" methods, it is, the methods that allow to change
00274      the selected icon. The Launcher doesn't provide that API, and
00275      right now  we are focusing on a normal user input.*/
00276   /* iface->add_selection = unity_launcher_accessible_add_selection; */
00277   /* iface->clear_selection = unity_launcher_accessible_clear_selection; */
00278   /* iface->remove_selection = unity_launcher_accessible_remove_selection; */
00279 
00280   /* This method will never be implemented, as select all the launcher
00281      icons makes no sense */
00282   /* iface->select_all = unity_launcher_accessible_select_all_selection; */
00283 }
00284 
00285 static AtkObject*
00286 unity_launcher_accessible_ref_selection(AtkSelection* selection,
00287                                         gint i)
00288 {
00289   Launcher* launcher = NULL;
00290   AbstractLauncherIcon::Ptr selected_icon;
00291   nux::Object* nux_object = NULL;
00292   AtkObject* accessible_selected = NULL;
00293 
00294   g_return_val_if_fail(UNITY_IS_LAUNCHER_ACCESSIBLE(selection), 0);
00295   /* there can be only just item selected */
00296   g_return_val_if_fail(i == 0, NULL);
00297 
00298   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(selection));
00299   if (!nux_object) /* state is defunct */
00300     return 0;
00301 
00302   launcher = dynamic_cast<Launcher*>(nux_object);
00303   selected_icon = launcher->GetSelectedMenuIcon();
00304 
00305   if (selected_icon)
00306   {
00307     accessible_selected = unity_a11y_get_accessible(selected_icon.GetPointer());
00308     g_object_ref(accessible_selected);
00309   }
00310 
00311   return accessible_selected;
00312 }
00313 
00314 static gint
00315 unity_launcher_accessible_get_selection_count(AtkSelection* selection)
00316 {
00317   Launcher* launcher = NULL;
00318   AbstractLauncherIcon::Ptr selected_icon;
00319   nux::Object* nux_object = NULL;
00320 
00321   g_return_val_if_fail(UNITY_IS_LAUNCHER_ACCESSIBLE(selection), 0);
00322 
00323   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(selection));
00324   if (!nux_object) /* state is defunct */
00325     return 0;
00326 
00327   launcher = dynamic_cast<Launcher*>(nux_object);
00328   selected_icon = launcher->GetSelectedMenuIcon();
00329 
00330   if (!selected_icon)
00331     return 0;
00332   else
00333     return 1;
00334 }
00335 
00336 static gboolean
00337 unity_launcher_accessible_is_child_selected(AtkSelection* selection,
00338                                             gint i)
00339 {
00340   Launcher* launcher = NULL;
00341   AbstractLauncherIcon::Ptr icon;
00342   AbstractLauncherIcon::Ptr selected_icon;
00343   LauncherModel::Ptr launcher_model;
00344   LauncherModel::iterator it;
00345   nux::Object* nux_object = NULL;
00346 
00347   g_return_val_if_fail(UNITY_IS_LAUNCHER_ACCESSIBLE(selection), FALSE);
00348 
00349   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(selection));
00350   if (!nux_object) /* state is defunct */
00351     return 0;
00352 
00353   launcher = dynamic_cast<Launcher*>(nux_object);
00354   launcher_model = launcher->GetModel();
00355   it = launcher_model->begin();
00356   std::advance(it, i);
00357   icon = *it;
00358 
00359   selected_icon = launcher->GetSelectedMenuIcon();
00360 
00361   if (selected_icon == icon)
00362     return TRUE;
00363   else
00364     return FALSE;
00365 }
00366 
00367 /* private */
00368 static void on_selection_change_cb(AbstractLauncherIcon::Ptr selection, UnityLauncherAccessible* launcher_accessible)
00369 {
00370   g_signal_emit_by_name(ATK_OBJECT(launcher_accessible), "selection-changed");
00371 }
00372 
00373 
00374 static void
00375 on_icon_added_cb(AbstractLauncherIcon::Ptr icon,
00376                  UnityLauncherAccessible* self)
00377 {
00378   AtkObject* icon_accessible = NULL;
00379   nux::Object* nux_object = NULL;
00380   gint index = 0;
00381 
00382   g_return_if_fail(UNITY_IS_LAUNCHER_ACCESSIBLE(self));
00383 
00384   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(self));
00385   if (nux_object == NULL) /* state is defunct */
00386     return;
00387 
00388   icon_accessible = unity_a11y_get_accessible(icon.GetPointer());
00389   atk_object_set_parent(icon_accessible, ATK_OBJECT(self));
00390 
00391   update_children_index(self);
00392 
00393   index = atk_object_get_index_in_parent(icon_accessible);
00394 
00395   g_signal_emit_by_name(self, "children-changed::add",
00396                         index, icon_accessible, NULL);
00397 }
00398 
00399 static void
00400 on_icon_removed_cb(AbstractLauncherIcon::Ptr icon,
00401                    UnityLauncherAccessible* self)
00402 {
00403   AtkObject* icon_accessible = NULL;
00404   nux::Object* nux_object = NULL;
00405   gint index = 0;
00406 
00407   g_return_if_fail(UNITY_IS_LAUNCHER_ACCESSIBLE(self));
00408 
00409   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(self));
00410   if (nux_object == NULL) /* state is defunct */
00411     return;
00412 
00413   icon_accessible = unity_a11y_get_accessible(icon.GetPointer());
00414 
00415   index = atk_object_get_index_in_parent(icon_accessible);
00416 
00417   g_signal_emit_by_name(self, "children-changed::remove",
00418                         index, icon_accessible, NULL);
00419 
00420   update_children_index(self);
00421 }
00422 
00423 static void
00424 update_children_index(UnityLauncherAccessible* self)
00425 {
00426   gint index = 0;
00427   nux::Object* nux_object = NULL;
00428   Launcher* launcher = NULL;
00429   LauncherModel::Ptr launcher_model;
00430   LauncherModel::iterator it;
00431   nux::Object* child = NULL;
00432   AtkObject* child_accessible = NULL;
00433 
00434   nux_object = nux_object_accessible_get_object(NUX_OBJECT_ACCESSIBLE(self));
00435   if (!nux_object) /* state is defunct */
00436     return;
00437 
00438   launcher = dynamic_cast<Launcher*>(nux_object);
00439   launcher_model = launcher->GetModel();
00440 
00441   if (launcher_model == NULL)
00442     return;
00443 
00444   for (it = launcher_model->begin(); it != launcher_model->end(); it++)
00445   {
00446     child =  dynamic_cast<nux::Object*>((*it).GetPointer());
00447     child_accessible = unity_a11y_get_accessible(child);
00448 
00449     unity_launcher_icon_accessible_set_index(UNITY_LAUNCHER_ICON_ACCESSIBLE(child_accessible),
00450                                              index++);
00451   }
00452 }
00453 
00454 static void
00455 on_order_change_cb(UnityLauncherAccessible* self)
00456 {
00457   g_return_if_fail(UNITY_IS_LAUNCHER_ACCESSIBLE(self));
00458 
00459   update_children_index(self);
00460 }