a11y: Simplify GtkAccessible implementation for editables

This commit implements the idea brought up in #5032, and provides a
simple function for GtkEditable implementations using a delegate object.
The accessible state is proxied from the outher GtkEditable to the
delegate.
This commit is contained in:
Lukáš Tyrychtr 2023-01-16 11:39:41 +01:00 committed by Emmanuele Bassi
parent b710df6f45
commit 11d235d165
6 changed files with 62 additions and 56 deletions

View File

@ -1181,3 +1181,54 @@ gtk_editable_delegate_get_property (GObject *object,
return TRUE;
}
/**
* gtk_editable_delegate_get_accessible_platform_state:
* @editable: a `GtkEditable` implementation
* @state: what kind of accessible state to retrieve
*
* Retrieves the accessible platform state from the editable delegate.
*
* This is an helper function to retrieve the accessible state for
* `GtkEditable` interface implementations using a delegate pattern.
*
* You should call this function in your editable widget implementation
* of the [vfunc@Gtk.Accessible.get_platform_state] virtual function, for
* instance:
*
* ```c
* static void
* accessible_interface_init (GtkAccessibleInterface *iface)
* {
* iface->get_platform_state = your_editable_get_accessible_platform_state;
* }
*
* static gboolean
* your_editable_get_accessible_platform_state (GtkAccessible *accessible,
* GtkAccessiblePlatformState state)
* {
* return gtk_editable_delegate_get_accessible_platform_state (GTK_EDITABLE (accessible), state);
* }
* ```
*
* Since: 4.10
*/
gboolean
gtk_editable_delegate_get_accessible_platform_state (GtkEditable *editable,
GtkAccessiblePlatformState state)
{
GtkWidget *delegate = GTK_WIDGET (gtk_editable_get_delegate (editable));
switch (state)
{
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE:
return gtk_widget_get_focusable (delegate);
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (delegate);
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
return FALSE;
}
}

View File

@ -30,9 +30,9 @@
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkaccessible.h>
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
#define GTK_TYPE_EDITABLE (gtk_editable_get_type ())
@ -194,6 +194,9 @@ gboolean gtk_editable_delegate_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
GDK_AVAILABLE_IN_4_10
gboolean gtk_editable_delegate_get_accessible_platform_state (GtkEditable *editable,
GtkAccessiblePlatformState state);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEditable, g_object_unref)

View File

@ -339,20 +339,7 @@ static gboolean
gtk_entry_accessible_get_platform_state (GtkAccessible *self,
GtkAccessiblePlatformState state)
{
GtkEntry *entry = GTK_ENTRY (self);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
switch (state)
{
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE:
return gtk_widget_get_focusable (GTK_WIDGET (priv->text));
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (GTK_WIDGET (priv->text));
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
}
return gtk_editable_delegate_get_accessible_platform_state (GTK_EDITABLE (self), state);
}
static void

View File

@ -550,19 +550,7 @@ static gboolean
gtk_password_entry_accessible_get_platform_state (GtkAccessible *self,
GtkAccessiblePlatformState state)
{
GtkPasswordEntry *entry = GTK_PASSWORD_ENTRY (self);
switch (state)
{
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE:
return gtk_widget_get_focusable (GTK_WIDGET (entry->entry));
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (GTK_WIDGET (entry->entry));
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
}
return gtk_editable_delegate_get_accessible_platform_state (GTK_EDITABLE (self), state);
}
static void

View File

@ -484,19 +484,7 @@ static gboolean
gtk_search_entry_accessible_get_platform_state (GtkAccessible *self,
GtkAccessiblePlatformState state)
{
GtkSearchEntry *entry = GTK_SEARCH_ENTRY (self);
switch (state)
{
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE:
return gtk_widget_get_focusable (GTK_WIDGET (entry->entry));
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (GTK_WIDGET (entry->entry));
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
}
return gtk_editable_delegate_get_accessible_platform_state (GTK_EDITABLE (self), state);
}
static void

View File

@ -614,25 +614,14 @@ static gboolean
gtk_spin_button_accessible_get_platform_state (GtkAccessible *self,
GtkAccessiblePlatformState state)
{
GtkSpinButton *spin_button = GTK_SPIN_BUTTON (self);
switch (state)
{
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSABLE:
return gtk_widget_get_focusable (spin_button->entry);
case GTK_ACCESSIBLE_PLATFORM_STATE_FOCUSED:
return gtk_widget_has_focus (spin_button->entry);
case GTK_ACCESSIBLE_PLATFORM_STATE_ACTIVE:
return FALSE;
default:
g_assert_not_reached ();
}
return gtk_editable_delegate_get_accessible_platform_state (GTK_EDITABLE (self), state);
}
static void
gtk_spin_button_accessible_init (GtkAccessibleInterface *iface)
{
GtkAccessibleInterface *parent_iface = g_type_interface_peek_parent (iface);
iface->get_at_context = parent_iface->get_at_context;
iface->get_platform_state = gtk_spin_button_accessible_get_platform_state;
}