mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-07 01:00:28 +00:00
switch: Add accessibility implementation
Modelled on GailToggleButton. https://bugzilla.gnome.org/show_bug.cgi?id=634987
This commit is contained in:
parent
044040dfd1
commit
ae95cdf8fc
166
gtk/gtkswitch.c
166
gtk/gtkswitch.c
@ -43,13 +43,13 @@
|
||||
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include "gtkaccessible.h"
|
||||
#include "gtkactivatable.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkstyle.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkwidget.h"
|
||||
#include "gtkactivatable.h"
|
||||
#include "gtktoggleaction.h"
|
||||
#include "gtkwidget.h"
|
||||
|
||||
#define DEFAULT_SLIDER_WIDTH (36)
|
||||
#define DEFAULT_SLIDER_HEIGHT (22)
|
||||
@ -82,6 +82,8 @@ enum
|
||||
|
||||
static GParamSpec *switch_props[LAST_PROP] = { NULL, };
|
||||
|
||||
static GType gtk_switch_accessible_factory_get_type (void);
|
||||
|
||||
static void gtk_switch_activatable_interface_init (GtkActivatableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkSwitch, gtk_switch, GTK_TYPE_WIDGET,
|
||||
@ -579,6 +581,38 @@ gtk_switch_draw (GtkWidget *widget,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static AtkObject *
|
||||
gtk_switch_get_accessible (GtkWidget *widget)
|
||||
{
|
||||
static gboolean first_time = TRUE;
|
||||
|
||||
if (G_UNLIKELY (first_time))
|
||||
{
|
||||
AtkObjectFactory *factory;
|
||||
AtkRegistry *registry;
|
||||
GType derived_type;
|
||||
GType derived_atk_type;
|
||||
|
||||
/* Figure out whether accessibility is enabled by looking at the
|
||||
* type of the accessible object which would be created for the
|
||||
* parent type of GtkSwitch
|
||||
*/
|
||||
derived_type = g_type_parent (GTK_TYPE_SWITCH);
|
||||
|
||||
registry = atk_get_default_registry ();
|
||||
factory = atk_registry_get_factory (registry, derived_type);
|
||||
derived_atk_type = atk_object_factory_get_accessible_type (factory);
|
||||
if (g_type_is_a (derived_atk_type, GTK_TYPE_ACCESSIBLE))
|
||||
atk_registry_set_factory_type (registry,
|
||||
GTK_TYPE_SWITCH,
|
||||
gtk_switch_accessible_factory_get_type ());
|
||||
|
||||
first_time = FALSE;
|
||||
}
|
||||
|
||||
return GTK_WIDGET_CLASS (gtk_switch_parent_class)->get_accessible (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_switch_set_related_action (GtkSwitch *sw,
|
||||
GtkAction *action)
|
||||
@ -727,6 +761,7 @@ gtk_switch_class_init (GtkSwitchClass *klass)
|
||||
widget_class->enter_notify_event = gtk_switch_enter;
|
||||
widget_class->leave_notify_event = gtk_switch_leave;
|
||||
widget_class->key_release_event = gtk_switch_key_release;
|
||||
widget_class->get_accessible = gtk_switch_get_accessible;
|
||||
|
||||
/**
|
||||
* GtkSwitch:slider-width:
|
||||
@ -785,6 +820,8 @@ gtk_switch_set_active (GtkSwitch *sw,
|
||||
|
||||
if (priv->is_active != is_active)
|
||||
{
|
||||
AtkObject *accessible;
|
||||
|
||||
priv->is_active = is_active;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (sw), switch_props[PROP_ACTIVE]);
|
||||
@ -792,6 +829,9 @@ gtk_switch_set_active (GtkSwitch *sw,
|
||||
if (priv->action)
|
||||
gtk_action_activate (priv->action);
|
||||
|
||||
accessible = gtk_widget_get_accessible (GTK_WIDGET (sw));
|
||||
atk_object_notify_state_change (accessible, ATK_STATE_CHECKED, priv->is_active);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (sw));
|
||||
}
|
||||
}
|
||||
@ -862,3 +902,123 @@ gtk_switch_activatable_interface_init (GtkActivatableIface *iface)
|
||||
iface->sync_action_properties = gtk_switch_sync_action_properties;
|
||||
}
|
||||
|
||||
/* accessibility: object */
|
||||
|
||||
static AtkObjectClass *a11y_parent_class = NULL;
|
||||
|
||||
static AtkStateSet *
|
||||
gtk_switch_accessible_ref_state_set (AtkObject *accessible)
|
||||
{
|
||||
AtkStateSet *state_set;
|
||||
GtkWidget *widget;
|
||||
|
||||
state_set = a11y_parent_class->ref_state_set (accessible);
|
||||
|
||||
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
|
||||
if (widget == NULL)
|
||||
return state_set;
|
||||
|
||||
if (gtk_switch_get_active (GTK_SWITCH (widget)))
|
||||
atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
|
||||
|
||||
return state_set;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_switch_accessible_initialize (AtkObject *accessible,
|
||||
gpointer widget)
|
||||
{
|
||||
a11y_parent_class->initialize (accessible, widget);
|
||||
|
||||
atk_object_set_role (accessible, ATK_ROLE_TOGGLE_BUTTON);
|
||||
atk_object_set_name (accessible, C_("light switch widget", "Switch"));
|
||||
atk_object_set_description (accessible, _("Switches between on and off states"));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_switch_accessible_class_init (AtkObjectClass *klass)
|
||||
{
|
||||
a11y_parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
klass->initialize = gtk_switch_accessible_initialize;
|
||||
klass->ref_state_set = gtk_switch_accessible_ref_state_set;
|
||||
}
|
||||
|
||||
static GType
|
||||
gtk_switch_accessible_get_type (void)
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
/* Action interface
|
||||
Name etc. ... */
|
||||
if (G_UNLIKELY (type == 0))
|
||||
{
|
||||
GType parent_atk_type;
|
||||
GTypeInfo tinfo = { 0 };
|
||||
GTypeQuery query;
|
||||
AtkObjectFactory *factory;
|
||||
|
||||
if ((type = g_type_from_name ("GtkSwitchAccessible")) != G_TYPE_INVALID)
|
||||
return type;
|
||||
|
||||
/* we inherit from the same ATK factory that provides support
|
||||
* for GtkWidget; if Gail is being used then this means GailWidget.
|
||||
*/
|
||||
factory = atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET);
|
||||
if (factory == G_TYPE_INVALID)
|
||||
return G_TYPE_INVALID;
|
||||
|
||||
parent_atk_type = atk_object_factory_get_accessible_type (factory);
|
||||
if (parent_atk_type == G_TYPE_INVALID)
|
||||
return G_TYPE_INVALID;
|
||||
|
||||
g_type_query (parent_atk_type, &query);
|
||||
|
||||
tinfo.class_init = (GClassInitFunc) gtk_switch_accessible_class_init;
|
||||
tinfo.class_size = query.class_size;
|
||||
tinfo.instance_size = query.instance_size;
|
||||
|
||||
type = g_type_register_static (parent_atk_type,
|
||||
I_("GtkSwitchAccessible"),
|
||||
&tinfo, 0);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
/* accessibility: factory */
|
||||
|
||||
typedef AtkObjectFactoryClass GtkSwitchAccessibleFactoryClass;
|
||||
typedef AtkObjectFactory GtkSwitchAccessibleFactory;
|
||||
|
||||
G_DEFINE_TYPE (GtkSwitchAccessibleFactory,
|
||||
gtk_switch_accessible_factory,
|
||||
ATK_TYPE_OBJECT_FACTORY);
|
||||
|
||||
static GType
|
||||
gtk_switch_accessible_factory_get_accessible_type (void)
|
||||
{
|
||||
return gtk_switch_accessible_get_type ();
|
||||
}
|
||||
|
||||
static AtkObject *
|
||||
gtk_switch_accessible_factory_create_accessible (GObject *obj)
|
||||
{
|
||||
AtkObject *accessible;
|
||||
|
||||
accessible = g_object_new (gtk_switch_accessible_get_type (), NULL);
|
||||
atk_object_initialize (accessible, obj);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_switch_accessible_factory_class_init (AtkObjectFactoryClass *klass)
|
||||
{
|
||||
klass->create_accessible = gtk_switch_accessible_factory_create_accessible;
|
||||
klass->get_accessible_type = gtk_switch_accessible_factory_get_accessible_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_switch_accessible_factory_init (AtkObjectFactory *factory)
|
||||
{
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user