GtkWidget: Add gtk_widget_insert_action_group()

This allows adding a GActionGroup with a given name at an arbitrary
point in the widget tree.

This patch also adds an internal _get_action_muxer() API.  Calling this
will create a GActionMuxer associated with the widget.  The parent of
the muxer will be the muxer of the widget's conceptual parent.  For
non-menus, that is the normal parent.  For menus, it is the attach
widget.

In this way, we end up with a hierarchy of GActionMuxer that largely
reflects the hierarchy of GtkWidget, but only in places that the action
context has been requested.  These muxers are the ones on which the
inserted actions groups are installed.

A following patch will add a user of this API.
This commit is contained in:
Lars Uebernickel 2012-08-17 18:09:35 -04:00 committed by Ryan Lortie
parent 2e57819477
commit d30d56452c
6 changed files with 81 additions and 0 deletions

View File

@ -5291,6 +5291,7 @@ gtk_widget_get_mapped
gtk_widget_get_requisition gtk_widget_get_requisition
gtk_widget_device_is_shadowed gtk_widget_device_is_shadowed
gtk_widget_get_modifier_mask gtk_widget_get_modifier_mask
gtk_widget_insert_action_group
<SUBSECTION> <SUBSECTION>
gtk_widget_get_path gtk_widget_get_path

View File

@ -3828,6 +3828,7 @@ gtk_widget_unmap
gtk_widget_unparent gtk_widget_unparent
gtk_widget_unrealize gtk_widget_unrealize
gtk_widget_unset_state_flags gtk_widget_unset_state_flags
gtk_widget_insert_action_group
#ifdef GDK_WINDOWING_WIN32 #ifdef GDK_WINDOWING_WIN32
gtk_win32_embed_widget_get_type gtk_win32_embed_widget_get_type
#endif #endif

View File

@ -1220,6 +1220,8 @@ gtk_menu_attach_to_widget (GtkMenu *menu,
/* Attach the widget to the toplevel window. */ /* Attach the widget to the toplevel window. */
gtk_window_set_attached_to (GTK_WINDOW (menu->priv->toplevel), attach_widget); gtk_window_set_attached_to (GTK_WINDOW (menu->priv->toplevel), attach_widget);
_gtk_widget_update_parent_muxer (GTK_WIDGET (menu));
/* Fallback title for menu comes from attach widget */ /* Fallback title for menu comes from attach widget */
gtk_menu_update_title (menu); gtk_menu_update_title (menu);
@ -1294,6 +1296,8 @@ gtk_menu_detach (GtkMenu *menu)
g_slice_free (GtkMenuAttachData, data); g_slice_free (GtkMenuAttachData, data);
_gtk_widget_update_parent_muxer (GTK_WIDGET (menu));
/* Fallback title for menu comes from attach widget */ /* Fallback title for menu comes from attach widget */
gtk_menu_update_title (menu); gtk_menu_update_title (menu);

View File

@ -390,6 +390,9 @@ struct _GtkWidgetPrivate
/* The widget's requested sizes */ /* The widget's requested sizes */
SizeRequestCache requests; SizeRequestCache requests;
/* actions attached to this or any parent widget */
GActionMuxer *muxer;
/* The widget's window or its parent window if it does /* The widget's window or its parent window if it does
* not have a window. (Which will be indicated by the * not have a window. (Which will be indicated by the
* GTK_NO_WINDOW flag being set). * GTK_NO_WINDOW flag being set).
@ -3899,6 +3902,8 @@ gtk_widget_unparent (GtkWidget *widget)
if (priv->context) if (priv->context)
gtk_style_context_set_parent (priv->context, NULL); gtk_style_context_set_parent (priv->context, NULL);
_gtk_widget_update_parent_muxer (widget);
g_signal_emit (widget, widget_signals[PARENT_SET], 0, old_parent); g_signal_emit (widget, widget_signals[PARENT_SET], 0, old_parent);
if (toplevel) if (toplevel)
{ {
@ -7968,6 +7973,8 @@ gtk_widget_set_parent (GtkWidget *widget,
gtk_style_context_set_parent (priv->context, gtk_style_context_set_parent (priv->context,
gtk_widget_get_style_context (parent)); gtk_widget_get_style_context (parent));
_gtk_widget_update_parent_muxer (widget);
g_signal_emit (widget, widget_signals[PARENT_SET], 0, NULL); g_signal_emit (widget, widget_signals[PARENT_SET], 0, NULL);
if (priv->parent->priv->anchored) if (priv->parent->priv->anchored)
_gtk_widget_propagate_hierarchy_changed (widget, NULL); _gtk_widget_propagate_hierarchy_changed (widget, NULL);
@ -10268,6 +10275,8 @@ gtk_widget_dispose (GObject *object)
priv->in_destruction = FALSE; priv->in_destruction = FALSE;
} }
g_clear_object (&priv->muxer);
G_OBJECT_CLASS (gtk_widget_parent_class)->dispose (object); G_OBJECT_CLASS (gtk_widget_parent_class)->dispose (object);
} }
@ -14072,3 +14081,61 @@ _gtk_widget_set_style (GtkWidget *widget,
{ {
widget->priv->style = style; widget->priv->style = style;
} }
void
_gtk_widget_update_parent_muxer (GtkWidget *widget)
{
GtkWidget *parent;
GActionMuxer *parent_muxer;
if (widget->priv->muxer == NULL)
return;
if (GTK_IS_MENU (widget))
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
else
parent = gtk_widget_get_parent (widget);
parent_muxer = parent ? _gtk_widget_get_action_muxer (parent) : NULL;
g_action_muxer_set_parent (widget->priv->muxer, parent_muxer);
}
GActionMuxer *
_gtk_widget_get_action_muxer (GtkWidget *widget)
{
if (widget->priv->muxer == NULL)
{
widget->priv->muxer = g_action_muxer_new ();
_gtk_widget_update_parent_muxer (widget);
}
return widget->priv->muxer;
}
/**
* gtk_widget_insert_action_group:
* @widget: a #GtkWidget
* @name: the prefix for actions in @group
* @group: a #GActionGroup
*
* Inserts @group into @widget. Children of @widget that implement
* #GtkActionable can then be associated with actions in @group by
* setting their 'action-name' to @prefix.<action-name>.
*
* Since: 3.6
*/
void
gtk_widget_insert_action_group (GtkWidget *widget,
const gchar *name,
GActionGroup *group)
{
GActionMuxer *muxer;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (name != NULL);
muxer = _gtk_widget_get_action_muxer (widget);
g_action_muxer_insert (muxer, name, group);
}

View File

@ -886,6 +886,10 @@ GDK_AVAILABLE_IN_3_4
GdkModifierType gtk_widget_get_modifier_mask (GtkWidget *widget, GdkModifierType gtk_widget_get_modifier_mask (GtkWidget *widget,
GdkModifierIntent intent); GdkModifierIntent intent);
GDK_AVAILABLE_IN_3_6
void gtk_widget_insert_action_group (GtkWidget *widget,
const gchar *name,
GActionGroup *group);
G_END_DECLS G_END_DECLS

View File

@ -27,6 +27,7 @@
#include "gtkcsstypesprivate.h" #include "gtkcsstypesprivate.h"
#include "gtkwidget.h" #include "gtkwidget.h"
#include "gactionmuxer.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -178,6 +179,9 @@ void _gtk_widget_invalidate_style_context (GtkWidget *widget
GtkCssChange change); GtkCssChange change);
void _gtk_widget_style_context_invalidated (GtkWidget *widget); void _gtk_widget_style_context_invalidated (GtkWidget *widget);
void _gtk_widget_update_parent_muxer (GtkWidget *widget);
GActionMuxer * _gtk_widget_get_action_muxer (GtkWidget *widget);
G_END_DECLS G_END_DECLS
#endif /* __GTK_WIDGET_PRIVATE_H__ */ #endif /* __GTK_WIDGET_PRIVATE_H__ */