Commit 8432ea35 authored by Matthias Clasen's avatar Matthias Clasen
Browse files

Convert GailButton to GtkButtonAccessible

This drops the AtkText implementation, and also strips handling
of children out. Instead of listening for enter/leave/press/released,
just listen for state changes on the widget.
parent a3113386
......@@ -7,7 +7,7 @@ gail_c_sources = \
gtkarrowaccessible.c \
gailbooleancell.c \
gtkboxaccessible.c \
gailbutton.c \
gtkbuttonaccessible.c \
gailcell.c \
gailcellparent.c \
gtkcheckmenuitemaccessible.c \
......@@ -58,7 +58,7 @@ gail_private_h_sources = \
gtkarrowaccessible.h \
gailbooleancell.h \
gtkboxaccessible.h \
gailbutton.h \
gtkbuttonaccessible.h \
gailcell.h \
gailcellparent.h \
gtkcheckmenuitemaccessible.h \
......
......@@ -24,7 +24,6 @@
#include <gtk/gtkx.h>
#include "gailbooleancell.h"
#include "gailbutton.h"
#include "gailcell.h"
#include "gailcontainer.h"
#include "gailcontainercell.h"
......@@ -84,7 +83,6 @@ static GQuark quark_focus_object = 0;
GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_WIDGET, GailWidget, gail_widget, GTK_TYPE_WIDGET)
GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_CONTAINER, GailContainer, gail_container, GTK_TYPE_CONTAINER)
GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_BUTTON, GailButton, gail_button, GTK_TYPE_BUTTON)
GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU_SHELL, GailMenuShell, gail_menu_shell, GTK_TYPE_MENU_SHELL)
GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_MENU, GailMenu, gail_menu, GTK_TYPE_MENU)
GAIL_IMPLEMENT_FACTORY (GAIL_TYPE_WINDOW, GailWindow, gail_window, GTK_TYPE_BIN)
......@@ -834,7 +832,6 @@ gail_accessibility_module_init (void)
GAIL_WIDGET_SET_FACTORY (GTK_TYPE_WIDGET, gail_widget);
GAIL_WIDGET_SET_FACTORY (GTK_TYPE_CONTAINER, gail_container);
GAIL_WIDGET_SET_FACTORY (GTK_TYPE_BUTTON, gail_button);
GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU_BAR, gail_menu_shell);
GAIL_WIDGET_SET_FACTORY (GTK_TYPE_MENU, gail_menu);
GAIL_WIDGET_SET_FACTORY (GTK_TYPE_WINDOW, gail_window);
......
This diff is collapsed.
/* 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 "gtkbuttonaccessible.h"
#include <libgail-util/gailmisc.h>
static void atk_action_interface_init (AtkActionIface *iface);
static void atk_image_interface_init (AtkImageIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkButtonAccessible, gtk_button_accessible, GAIL_TYPE_CONTAINER,
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init))
static void
state_changed_cb (GtkWidget *widget, GtkStateFlags previous_flags)
{
AtkObject *accessible;
GtkStateFlags flags;
gboolean was_active;
gboolean active;
flags = gtk_widget_get_state_flags (widget);
was_active = (previous_flags & GTK_STATE_FLAG_ACTIVE) != 0;
active = (flags & GTK_STATE_FLAG_ACTIVE) != 0;
accessible = gtk_widget_get_accessible (widget);
if (active && !was_active)
atk_object_notify_state_change (accessible, ATK_STATE_ARMED, TRUE);
else if (!active && was_active)
atk_object_notify_state_change (accessible, ATK_STATE_ARMED, FALSE);
}
static void
gtk_button_accessible_initialize (AtkObject *obj,
gpointer data)
{
GtkWidget *parent;
ATK_OBJECT_CLASS (gtk_button_accessible_parent_class)->initialize (obj, data);
g_signal_connect (data, "state-flags-changed", G_CALLBACK (state_changed_cb), NULL);
parent = gtk_widget_get_parent (gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)));
if (GTK_IS_TREE_VIEW (parent))
{
/* Even though the accessible parent of the column header will
* be reported as the table because the parent widget of the
* GtkTreeViewColumn's button is the GtkTreeView we set
* the accessible parent for column header to be the table
* to ensure that atk_object_get_index_in_parent() returns
* the correct value; see gail_widget_get_index_in_parent().
*/
atk_object_set_parent (obj, gtk_widget_get_accessible (parent));
obj->role = ATK_ROLE_TABLE_COLUMN_HEADER;
}
else
obj->role = ATK_ROLE_PUSH_BUTTON;
}
static GtkWidget *
get_image_from_button (GtkWidget *button)
{
GtkWidget *image;
image = gtk_button_get_image (GTK_BUTTON (button));
if (GTK_IS_IMAGE (image))
return image;
return NULL;
}
static GtkWidget *
find_label_child (GtkContainer *container)
{
GList *children, *tmp_list;
GtkWidget *child;
children = gtk_container_get_children (container);
child = NULL;
for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next)
{
if (GTK_IS_LABEL (tmp_list->data))
{
child = GTK_WIDGET (tmp_list->data);
break;
}
else if (GTK_IS_CONTAINER (tmp_list->data))
{
child = find_label_child (GTK_CONTAINER (tmp_list->data));
if (child)
break;
}
}
g_list_free (children);
return child;
}
static GtkWidget *
get_label_from_button (GtkWidget *button)
{
GtkWidget *child;
child = gtk_bin_get_child (GTK_BIN (button));
if (GTK_IS_ALIGNMENT (child))
child = gtk_bin_get_child (GTK_BIN (child));
if (GTK_IS_CONTAINER (child))
child = find_label_child (GTK_CONTAINER (child));
else if (!GTK_IS_LABEL (child))
child = NULL;
return child;
}
static const gchar *
gtk_button_accessible_get_name (AtkObject *obj)
{
const gchar *name = NULL;
GtkWidget *widget;
GtkWidget *child;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
if (widget == NULL)
return NULL;
name = ATK_OBJECT_CLASS (gtk_button_accessible_parent_class)->get_name (obj);
if (name != NULL)
return name;
child = get_label_from_button (widget);
if (GTK_IS_LABEL (child))
name = gtk_label_get_text (GTK_LABEL (child));
else
{
GtkWidget *image;
image = get_image_from_button (widget);
if (GTK_IS_IMAGE (image))
{
AtkObject *atk_obj;
atk_obj = gtk_widget_get_accessible (image);
name = atk_object_get_name (atk_obj);
}
}
return name;
}
static gint
gtk_button_accessible_get_n_children (AtkObject* obj)
{
return 0;
}
static AtkObject *
gtk_button_accessible_ref_child (AtkObject *obj,
gint i)
{
return NULL;
}
static AtkStateSet *
gtk_button_accessible_ref_state_set (AtkObject *obj)
{
AtkStateSet *state_set;
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
if (widget == NULL)
return NULL;
state_set = ATK_OBJECT_CLASS (gtk_button_accessible_parent_class)->ref_state_set (obj);
if ((gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_ACTIVE) != 0)
atk_state_set_add_state (state_set, ATK_STATE_ARMED);
if (!gtk_widget_get_can_focus (widget))
atk_state_set_remove_state (state_set, ATK_STATE_SELECTABLE);
return state_set;
}
static void
gtk_button_accessible_notify_gtk (GObject *obj,
GParamSpec *pspec)
{
GtkWidget *widget = GTK_WIDGET (obj);
AtkObject *atk_obj = gtk_widget_get_accessible (widget);
if (strcmp (pspec->name, "label") == 0)
{
if (atk_obj->name == NULL)
g_object_notify (G_OBJECT (atk_obj), "accessible-name");
g_signal_emit_by_name (atk_obj, "visible_data_changed");
}
else
GAIL_WIDGET_CLASS (gtk_button_accessible_parent_class)->notify_gtk (obj, pspec);
}
static void
gtk_button_accessible_class_init (GtkButtonAccessibleClass *klass)
{
AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
GailContainerClass *container_class = (GailContainerClass*)klass;
GailWidgetClass *widget_class = (GailWidgetClass*)klass;
class->get_name = gtk_button_accessible_get_name;
class->get_n_children = gtk_button_accessible_get_n_children;
class->ref_child = gtk_button_accessible_ref_child;
class->ref_state_set = gtk_button_accessible_ref_state_set;
class->initialize = gtk_button_accessible_initialize;
widget_class->notify_gtk = gtk_button_accessible_notify_gtk;
container_class->add_gtk = NULL;
container_class->remove_gtk = NULL;
}
static void
gtk_button_accessible_init (GtkButtonAccessible *button)
{
}
static gboolean
gtk_button_accessible_do_action (AtkAction *action,
gint i)
{
GtkWidget *widget;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
if (widget == NULL)
return FALSE;
if (i != 0)
return FALSE;
if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
return FALSE;
gtk_button_clicked (GTK_BUTTON (widget));
return TRUE;
}
static gint
gtk_button_accessible_get_n_actions (AtkAction *action)
{
return 1;
}
static const gchar *
gtk_button_accessible_get_keybinding (AtkAction *action,
gint i)
{
GtkButtonAccessible *button;
gchar *return_value = NULL;
GtkWidget *widget;
GtkWidget *label;
guint key_val;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
if (widget == NULL)
return NULL;
if (i != 0)
return NULL;
button = GTK_BUTTON_ACCESSIBLE (action);
label = get_label_from_button (widget);
if (GTK_IS_LABEL (label))
{
key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
if (key_val != GDK_KEY_VoidSymbol)
return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
}
if (return_value == NULL)
{
/* Find labelled-by relation */
AtkRelationSet *set;
AtkRelation *relation;
GPtrArray *target;
gpointer target_object;
set = atk_object_ref_relation_set (ATK_OBJECT (action));
if (set)
{
relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_LABELLED_BY);
if (relation)
{
target = atk_relation_get_target (relation);
target_object = g_ptr_array_index (target, 0);
label = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
}
g_object_unref (set);
}
if (GTK_IS_LABEL (label))
{
key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
if (key_val != GDK_KEY_VoidSymbol)
return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
}
}
return return_value;
}
static const gchar *
gtk_button_accessible_action_get_name (AtkAction *action,
gint i)
{
if (i != 0)
return NULL;
return "click";
}
static void
atk_action_interface_init (AtkActionIface *iface)
{
iface->do_action = gtk_button_accessible_do_action;
iface->get_n_actions = gtk_button_accessible_get_n_actions;
iface->get_keybinding = gtk_button_accessible_get_keybinding;
iface->get_name = gtk_button_accessible_action_get_name;
}
static const gchar *
gtk_button_accessible_get_image_description (AtkImage *image)
{
GtkWidget *widget;
GtkWidget *button_image;
AtkObject *obj;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
if (widget == NULL)
return NULL;
button_image = get_image_from_button (widget);
if (GTK_IS_IMAGE (button_image))
{
obj = gtk_widget_get_accessible (button_image);
return atk_image_get_image_description (ATK_IMAGE (obj));
}
return NULL;
}
static void
gtk_button_accessible_get_image_position (AtkImage *image,
gint *x,
gint *y,
AtkCoordType coord_type)
{
GtkWidget *widget;
GtkImage *button_image;
AtkObject *obj;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
if (widget == NULL)
{
*x = G_MININT;
*y = G_MININT;
return;
}
button_image = get_image_from_button (widget);
if (button_image != NULL)
{
obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
atk_component_get_position (ATK_COMPONENT (obj), x, y, coord_type);
}
else
{
*x = G_MININT;
*y = G_MININT;
}
}
static void
gtk_button_accessible_get_image_size (AtkImage *image,
gint *width,
gint *height)
{
GtkWidget *widget;
GtkImage *button_image;
AtkObject *obj;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
if (widget == NULL)
{
*width = -1;
*height = -1;
return;
}
button_image = get_image_from_button (widget);
if (button_image != NULL)
{
obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
atk_image_get_image_size (ATK_IMAGE (obj), width, height);
}
else
{
*width = -1;
*height = -1;
}
}
static gboolean
gtk_button_accessible_set_image_description (AtkImage *image,
const gchar *description)
{
GtkWidget *widget;
GtkImage *button_image;
AtkObject *obj;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
if (widget == NULL)
return FALSE;
button_image = get_image_from_button (widget);
if (button_image != NULL)
{
obj = gtk_widget_get_accessible (GTK_WIDGET (button_image));
return atk_image_set_image_description (ATK_IMAGE (obj), description);
}
return FALSE;
}
static void
atk_image_interface_init (AtkImageIface *iface)
{
iface->get_image_description = gtk_button_accessible_get_image_description;
iface->get_image_position = gtk_button_accessible_get_image_position;
iface->get_image_size = gtk_button_accessible_get_image_size;
iface->set_image_description = gtk_button_accessible_set_image_description;
}
......@@ -17,45 +17,36 @@
* Boston, MA 02111-1307, USA.
*/
#ifndef __GAIL_BUTTON_H__
#define __GAIL_BUTTON_H__
#ifndef __GTK_BUTTON_ACCESSIBLE_H__
#define __GTK_BUTTON_ACCESSIBLE_H__
#include "gailcontainer.h"
#include "gailtextutil.h"
G_BEGIN_DECLS
#define GAIL_TYPE_BUTTON (gail_button_get_type ())
#define GAIL_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAIL_TYPE_BUTTON, GailButton))
#define GAIL_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAIL_TYPE_BUTTON, GailButtonClass))
#define GAIL_IS_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAIL_TYPE_BUTTON))
#define GAIL_IS_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAIL_TYPE_BUTTON))
#define GAIL_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAIL_TYPE_BUTTON, GailButtonClass))
#define GTK_TYPE_BUTTON_ACCESSIBLE (gtk_button_accessible_get_type ())
#define GTK_BUTTON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_BUTTON_ACCESSIBLE, GtkButtonAccessible))
#define GTK_BUTTON_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_BUTTON_ACCESSIBLE, GtkButtonAccessibleClass))
#define GTK_IS_BUTTON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_BUTTON_ACCESSIBLE))
#define GTK_IS_BUTTON_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_BUTTON_ACCESSIBLE))
#define GTK_BUTTON_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_BUTTON_ACCESSIBLE, GtkButtonAccessibleClass))
typedef struct _GailButton GailButton;
typedef struct _GailButtonClass GailButtonClass;
typedef struct _GtkButtonAccessible GtkButtonAccessible;
typedef struct _GtkButtonAccessibleClass GtkButtonAccessibleClass;
struct _GailButton
struct _GtkButtonAccessible
{
GailContainer parent;
/*
* Cache the widget state so we know the previous state when it changed
*/
gint8 state;
gchar *click_keybinding;
GailTextUtil *textutil;
};
GType gail_button_get_type (void);
struct _GailButtonClass
struct _GtkButtonAccessibleClass
{
GailContainerClass parent_class;
};
GType gtk_button_accessible_get_type (void);
G_END_DECLS
#endif /* __GAIL_BUTTON_H__ */
#endif /* __GTK_BUTTON_ACCESSIBLE_H__ */
......@@ -190,7 +190,7 @@ gtk_link_button_accessible_get_hyperlink (AtkHyperlinkImpl *impl)
static void atk_hypertext_impl_interface_init (AtkHyperlinkImplIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkLinkButtonAccessible, gtk_link_button_accessible, GAIL_TYPE_BUTTON,
G_DEFINE_TYPE_WITH_CODE (GtkLinkButtonAccessible, gtk_link_button_accessible, GTK_TYPE_BUTTON_ACCESSIBLE,
G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERLINK_IMPL, atk_hypertext_impl_interface_init))
static void
......
......@@ -20,7 +20,7 @@
#ifndef __GTK_LINK_BUTTON_ACCESSIBLE_H__
#define __GTK_LINK_BUTTON_ACCESSIBLE_H__
#include "gailbutton.h"
#include "gtkbuttonaccessible.h"
G_BEGIN_DECLS
......@@ -36,14 +36,14 @@ typedef struct _GtkLinkButtonAccessibleClass GtkLinkButtonAccessibleClass;
struct _GtkLinkButtonAccessible
{
GailButton parent;
GtkButtonAccessible parent;
AtkHyperlink *link;
};
struct _GtkLinkButtonAccessibleClass
{
GailButtonClass parent_class;
GtkButtonAccessibleClass parent_class;
};
GType gtk_link_button_accessible_get_type (void);
......
......@@ -28,7 +28,7 @@
static void atk_action_interface_init (AtkActionIface *iface);
static void atk_value_interface_init (AtkValueIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkScaleButtonAccessible, gtk_scale_button_accessible, GAIL_TYPE_BUTTON,
G_DEFINE_TYPE_WITH_CODE (GtkScaleButtonAccessible, gtk_scale_button_accessible, GTK_TYPE_BUTTON_ACCESSIBLE,
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init));
......