diff options
Diffstat (limited to 'e-util/gal-a11y-e-cell-vbox.c')
-rw-r--r-- | e-util/gal-a11y-e-cell-vbox.c | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/e-util/gal-a11y-e-cell-vbox.c b/e-util/gal-a11y-e-cell-vbox.c new file mode 100644 index 0000000000..7864dc04ea --- /dev/null +++ b/e-util/gal-a11y-e-cell-vbox.c @@ -0,0 +1,235 @@ +/* + * + * This program 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) version 3. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Eric Zhao <eric.zhao@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * Copyright (C) 2004 Sun Microsystem, Inc. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "gal-a11y-e-cell-vbox.h" + +#include <atk/atk.h> + +#include "e-cell-vbox.h" +#include "gal-a11y-e-cell-registry.h" + +static GObjectClass *parent_class; +static AtkComponentIface *component_parent_iface; +#define PARENT_TYPE (gal_a11y_e_cell_get_type ()) + +static gint +ecv_get_n_children (AtkObject *a11y) +{ + g_return_val_if_fail (GAL_A11Y_IS_E_CELL_VBOX (a11y), 0); + + return GAL_A11Y_E_CELL_VBOX (a11y)->a11y_subcell_count; +} + +static void +subcell_destroyed (gpointer data) +{ + GalA11yECell *cell; + AtkObject *parent; + GalA11yECellVbox *gaev; + + g_return_if_fail (GAL_A11Y_IS_E_CELL (data)); + cell = GAL_A11Y_E_CELL (data); + + parent = atk_object_get_parent (ATK_OBJECT (cell)); + g_return_if_fail (GAL_A11Y_IS_E_CELL_VBOX (parent)); + gaev = GAL_A11Y_E_CELL_VBOX (parent); + + if (cell->view_col < gaev->a11y_subcell_count) + gaev->a11y_subcells[cell->view_col] = NULL; +} + +static AtkObject * +ecv_ref_child (AtkObject *a11y, + gint i) +{ + GalA11yECellVbox *gaev = GAL_A11Y_E_CELL_VBOX (a11y); + GalA11yECell *gaec = GAL_A11Y_E_CELL (a11y); + ECellVboxView *ecvv = (ECellVboxView *) (gaec->cell_view); + AtkObject *ret; + if (i < gaev->a11y_subcell_count) { + if (gaev->a11y_subcells[i] == NULL) { + ECellView *subcell_view; + gint model_col, row; + row = gaec->row; + model_col = ecvv->model_cols[i]; + subcell_view = ecvv->subcell_views[i]; + /* FIXME Should the view column use a fake + * one or the same as its parent? */ + ret = gal_a11y_e_cell_registry_get_object ( + NULL, + gaec->item, + subcell_view, + a11y, + model_col, + gaec->view_col, + row); + gaev->a11y_subcells[i] = ret; + g_object_ref (ret); + g_object_weak_ref ( + G_OBJECT (ret), + (GWeakNotify) subcell_destroyed, + ret); + } else { + ret = (AtkObject *) gaev->a11y_subcells[i]; + if (ATK_IS_OBJECT (ret)) + g_object_ref (ret); + else + ret = NULL; + } + } else { + ret = NULL; + } + + return ret; +} + +static void +ecv_dispose (GObject *object) +{ + GalA11yECellVbox *gaev = GAL_A11Y_E_CELL_VBOX (object); + if (gaev->a11y_subcells) + g_free (gaev->a11y_subcells); + + if (parent_class->dispose) + parent_class->dispose (object); +} + +/* AtkComponet interface */ +static AtkObject * +ecv_ref_accessible_at_point (AtkComponent *component, + gint x, + gint y, + AtkCoordType coord_type) +{ + gint x0, y0, width, height; + gint subcell_height, i; + + GalA11yECell *gaec = GAL_A11Y_E_CELL (component); + ECellVboxView *ecvv = (ECellVboxView *) (gaec->cell_view); + + atk_component_get_extents (component, &x0, &y0, &width, &height, coord_type); + x -= x0; + y -= y0; + if (x < 0 || x > width || y < 0 || y > height) + return NULL; + + for (i = 0; i < ecvv->subcell_view_count; i++) { + subcell_height = e_cell_height ( + ecvv->subcell_views[i], ecvv->model_cols[i], + gaec->view_col, gaec->row); + if (0 <= y && y <= subcell_height) { + return ecv_ref_child ((AtkObject *) component, i); + } else + y -= subcell_height; + } + + return NULL; +} + +static void +ecv_class_init (GalA11yECellVboxClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + AtkObjectClass *a11y_class = ATK_OBJECT_CLASS (class); + parent_class = g_type_class_ref (PARENT_TYPE); + + object_class->dispose = ecv_dispose; + + a11y_class->get_n_children = ecv_get_n_children; + a11y_class->ref_child = ecv_ref_child; +} + +static void +ecv_init (GalA11yECellVbox *a11y) +{ +} + +static void +ecv_atk_component_iface_init (AtkComponentIface *iface) +{ + component_parent_iface = g_type_interface_peek_parent (iface); + + iface->ref_accessible_at_point = ecv_ref_accessible_at_point; +} + +GType +gal_a11y_e_cell_vbox_get_type (void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof (GalA11yECellVboxClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) ecv_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (GalA11yECellVbox), + 0, + (GInstanceInitFunc) ecv_init, + NULL /* value_cell */ + }; + + static const GInterfaceInfo atk_component_info = { + (GInterfaceInitFunc) ecv_atk_component_iface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + + type = g_type_register_static (PARENT_TYPE, "GalA11yECellVbox", &info, 0); + gal_a11y_e_cell_type_add_action_interface (type); + g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info); + } + + return type; +} + +AtkObject *gal_a11y_e_cell_vbox_new (ETableItem *item, + ECellView *cell_view, + AtkObject *parent, + gint model_col, + gint view_col, + gint row) +{ + AtkObject *a11y; + GalA11yECell *gaec; + GalA11yECellVbox *gaev; + ECellVboxView *ecvv; + + a11y = g_object_new (gal_a11y_e_cell_vbox_get_type (), NULL); + + gal_a11y_e_cell_construct ( + a11y, item, cell_view, parent, model_col, view_col, row); + + gaec = GAL_A11Y_E_CELL (a11y); + gaev = GAL_A11Y_E_CELL_VBOX (a11y); + ecvv = (ECellVboxView *) (gaec->cell_view); + gaev->a11y_subcell_count = ecvv->subcell_view_count; + gaev->a11y_subcells = g_malloc0 (sizeof (AtkObject *) * gaev->a11y_subcell_count); + return a11y; +} |