diff options
author | Matthias Clasen <mclasen@redhat.com> | 2023-04-07 13:14:51 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2023-04-07 13:45:45 -0400 |
commit | 36c10033280d44ac9d82605516a55bbf7320392d (patch) | |
tree | c2be4babffc4a0995acfdc2dbf10ab4741121c5e | |
parent | 3eabcde8684dea8d41e27cb1fe779f08e5ac542a (diff) | |
download | gtk+-36c10033280d44ac9d82605516a55bbf7320392d.tar.gz |
inspector: Redo the actions list
Make the actions list implement GtkActionObserver
for the muxer case, and make updates work.
-rw-r--r-- | gtk/inspector/actions.c | 283 | ||||
-rw-r--r-- | gtk/inspector/actions.ui | 3 |
2 files changed, 249 insertions, 37 deletions
diff --git a/gtk/inspector/actions.c b/gtk/inspector/actions.c index a5d06fa7a2..3f2a2183a2 100644 --- a/gtk/inspector/actions.c +++ b/gtk/inspector/actions.c @@ -26,6 +26,8 @@ #include "gtkapplicationwindow.h" #include "gtkwidgetprivate.h" #include "gtkactionmuxerprivate.h" +#include "gtkactionobserverprivate.h" +#include "gtkactionobservableprivate.h" #include "gtkpopover.h" #include "gtklabel.h" #include "gtkstack.h" @@ -59,7 +61,10 @@ enum { PROP_BUTTON }; -G_DEFINE_TYPE (GtkInspectorActions, gtk_inspector_actions, GTK_TYPE_WIDGET) +static void gtk_inspector_actions_observer_iface_init (GtkActionObserverInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GtkInspectorActions, gtk_inspector_actions, GTK_TYPE_WIDGET, + G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTION_OBSERVER, gtk_inspector_actions_observer_iface_init)) static void gtk_inspector_actions_init (GtkInspectorActions *sl) @@ -120,20 +125,13 @@ setup_enabled_cb (GtkSignalListItemFactory *factory, } static void -bind_enabled_cb (GtkSignalListItemFactory *factory, - GtkListItem *list_item) +update_enabled (ActionHolder *holder, + GtkLabel *label) { - gpointer item; - GtkWidget *label; - GObject *owner; - const char *name; + GObject *owner = action_holder_get_owner (holder); + const char *name = action_holder_get_name (holder); gboolean enabled = FALSE; - item = gtk_list_item_get_item (list_item); - label = gtk_list_item_get_child (list_item); - - owner = action_holder_get_owner (ACTION_HOLDER (item)); - name = action_holder_get_name (ACTION_HOLDER (item)); if (G_IS_ACTION_GROUP (owner)) enabled = g_action_group_get_action_enabled (G_ACTION_GROUP (owner), name); else if (!GTK_IS_ACTION_MUXER (owner) || @@ -141,7 +139,29 @@ bind_enabled_cb (GtkSignalListItemFactory *factory, &enabled, NULL, NULL, NULL, NULL)) enabled = FALSE; - gtk_label_set_label (GTK_LABEL (label), enabled ? "+" : "-"); + gtk_label_set_label (label, enabled ? "+" : "-"); +} + +static void +bind_enabled_cb (GtkSignalListItemFactory *factory, + GtkListItem *list_item) +{ + gpointer item = gtk_list_item_get_item (list_item); + GtkWidget *label = gtk_list_item_get_child (list_item); + + g_signal_connect (item, "changed", G_CALLBACK (update_enabled), label); + + update_enabled (ACTION_HOLDER (item), GTK_LABEL (label)); +} + +static void +unbind_enabled_cb (GtkSignalListItemFactory *factory, + GtkListItem *list_item) +{ + gpointer item = gtk_list_item_get_item (list_item); + GtkWidget *label = gtk_list_item_get_child (list_item); + + g_signal_handlers_disconnect_by_func (item, update_enabled, label); } static void @@ -196,20 +216,13 @@ setup_state_cb (GtkSignalListItemFactory *factory, } static void -bind_state_cb (GtkSignalListItemFactory *factory, - GtkListItem *list_item) +update_state (ActionHolder *h, + GtkLabel *label) { - gpointer item; - GtkWidget *label; - GObject *owner; - const char *name; + GObject *owner = action_holder_get_owner (h); + const char *name = action_holder_get_name (h); GVariant *state; - item = gtk_list_item_get_item (list_item); - label = gtk_list_item_get_child (list_item); - - owner = action_holder_get_owner (ACTION_HOLDER (item)); - name = action_holder_get_name (ACTION_HOLDER (item)); if (G_IS_ACTION_GROUP (owner)) state = g_action_group_get_action_state (G_ACTION_GROUP (owner), name); else if (!GTK_IS_ACTION_MUXER (owner) || @@ -222,12 +235,34 @@ bind_state_cb (GtkSignalListItemFactory *factory, char *state_string; state_string = g_variant_print (state, FALSE); - gtk_label_set_label (GTK_LABEL (label), state_string); + gtk_label_set_label (label, state_string); g_free (state_string); g_variant_unref (state); } else - gtk_label_set_label (GTK_LABEL (label), ""); + gtk_label_set_label (label, ""); +} + +static void +bind_state_cb (GtkSignalListItemFactory *factory, + GtkListItem *list_item) +{ + gpointer item = gtk_list_item_get_item (list_item); + GtkWidget *label = gtk_list_item_get_child (list_item); + + g_signal_connect (item, "changed", G_CALLBACK (update_state), label); + + update_state (ACTION_HOLDER (item), GTK_LABEL (label)); +} + +static void +unbind_state_cb (GtkSignalListItemFactory *factory, + GtkListItem *list_item) +{ + gpointer item = gtk_list_item_get_item (list_item); + GtkWidget *label = gtk_list_item_get_child (list_item); + + g_signal_handlers_disconnect_by_func (item, update_state, label); } static void @@ -242,23 +277,34 @@ setup_changes_cb (GtkSignalListItemFactory *factory, } static void +update_changes (ActionHolder *h, + GtkInspectorActionEditor *editor) +{ + gtk_inspector_action_editor_update (editor); +} + +static void bind_changes_cb (GtkSignalListItemFactory *factory, GtkListItem *list_item) { - gpointer item; - GObject *owner; - const char *name; - GtkWidget *editor; + gpointer item = gtk_list_item_get_item (list_item); + GtkWidget *editor = gtk_list_item_get_child (list_item); + GObject *owner = action_holder_get_owner (ACTION_HOLDER (item)); + const char *name = action_holder_get_name (ACTION_HOLDER (item)); - item = gtk_list_item_get_item (list_item); - editor = gtk_list_item_get_child (list_item); + gtk_inspector_action_editor_set (GTK_INSPECTOR_ACTION_EDITOR (editor), owner, name); - owner = action_holder_get_owner (ACTION_HOLDER (item)); - name = action_holder_get_name (ACTION_HOLDER (item)); + g_signal_connect (item, "changed", G_CALLBACK (update_changes), editor); +} + +static void +unbind_changes_cb (GtkSignalListItemFactory *factory, + GtkListItem *list_item) +{ + gpointer item = gtk_list_item_get_item (list_item); + GtkWidget *editor = gtk_list_item_get_child (list_item); - gtk_inspector_action_editor_set (GTK_INSPECTOR_ACTION_EDITOR (editor), - owner, - name); + g_signal_handlers_disconnect_by_func (item, update_changes, editor); } static void @@ -323,6 +369,157 @@ refresh_all (GtkInspectorActions *sl) reload (sl); } +static void +action_changed (GtkInspectorActions *sl, + const char *name) +{ + unsigned int n_actions; + + n_actions = g_list_model_get_n_items (G_LIST_MODEL (sl->actions)); + for (unsigned int i = 0; i < n_actions; i++) + { + ActionHolder *h = ACTION_HOLDER (g_list_model_get_item (G_LIST_MODEL (sl->actions), i)); + + if (g_str_equal (action_holder_get_name (h), name)) + { + action_holder_changed (h); + g_object_unref (h); + break; + } + + g_object_unref (h); + } +} + +static void +action_enabled_changed (GActionGroup *group, + const char *action_name, + gboolean enabled, + GtkInspectorActions *sl) +{ + action_changed (sl, action_name); +} + +static void +action_state_changed (GActionGroup *group, + const char *action_name, + GVariant *state, + GtkInspectorActions *sl) +{ + action_changed (sl, action_name); +} + +static void +observer_action_added (GtkActionObserver *observer, + GtkActionObservable *observable, + const char *action_name, + const GVariantType *parameter_type, + gboolean enabled, + GVariant *state) +{ +} + +static void +observer_action_removed (GtkActionObserver *observer, + GtkActionObservable *observable, + const char *action_name) +{ +} + +static void +observer_action_enabled_changed (GtkActionObserver *observer, + GtkActionObservable *observable, + const char *action_name, + gboolean enabled) +{ + action_changed (GTK_INSPECTOR_ACTIONS (observer), action_name); +} + +static void +observer_action_state_changed (GtkActionObserver *observer, + GtkActionObservable *observable, + const char *action_name, + GVariant *state) +{ + action_changed (GTK_INSPECTOR_ACTIONS (observer), action_name); +} + +static void +observer_primary_accel_changed (GtkActionObserver *observer, + GtkActionObservable *observable, + const char *action_name, + const char *action_and_target) +{ +} + +static void +gtk_inspector_actions_observer_iface_init (GtkActionObserverInterface *iface) +{ + iface->action_added = observer_action_added; + iface->action_removed = observer_action_removed; + iface->action_enabled_changed = observer_action_enabled_changed; + iface->action_state_changed = observer_action_state_changed; + iface->primary_accel_changed = observer_primary_accel_changed; +} + +static void +connect (GtkInspectorActions *sl) +{ + if (G_IS_ACTION_GROUP (sl->object)) + { + g_signal_connect (sl->object, "action-enabled-changed", + G_CALLBACK (action_enabled_changed), sl); + g_signal_connect (sl->object, "action-state-changed", + G_CALLBACK (action_state_changed), sl); + } + else if (GTK_IS_WIDGET (sl->object)) + { + GtkActionMuxer *muxer; + + muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (sl->object), FALSE); + + if (muxer) + { + int i; + char **names; + + names = gtk_action_muxer_list_actions (muxer, FALSE); + for (i = 0; names[i]; i++) + { + gtk_action_observable_register_observer (GTK_ACTION_OBSERVABLE (muxer), names[i], GTK_ACTION_OBSERVER (sl)); + } + g_strfreev (names); + } + } +} + +static void +disconnect (GtkInspectorActions *sl) +{ + if (G_IS_ACTION_GROUP (sl->object)) + { + g_signal_handlers_disconnect_by_func (sl->object, action_enabled_changed, sl); + g_signal_handlers_disconnect_by_func (sl->object, action_state_changed, sl); + } + else if (GTK_IS_WIDGET (sl->object)) + { + GtkActionMuxer *muxer; + + muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (sl->object), FALSE); + + if (muxer) + { + int i; + char **names; + + names = gtk_action_muxer_list_actions (muxer, FALSE); + for (i = 0; names[i]; i++) + gtk_action_observable_unregister_observer (GTK_ACTION_OBSERVABLE (muxer), names[i], GTK_ACTION_OBSERVER (sl)); + g_strfreev (names); + } + } +} + void gtk_inspector_actions_set_object (GtkInspectorActions *sl, GObject *object) @@ -335,11 +532,17 @@ gtk_inspector_actions_set_object (GtkInspectorActions *sl, page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (sl)); gtk_stack_page_set_visible (page, FALSE); + if (sl->object) + disconnect (sl); + g_set_object (&sl->object, object); gtk_column_view_sort_by_column (GTK_COLUMN_VIEW (sl->list), sl->name, GTK_SORT_ASCENDING); loaded = reload (sl); gtk_stack_page_set_visible (page, loaded); + + if (sl->object) + connect (sl); } static void @@ -419,6 +622,9 @@ dispose (GObject *object) { GtkInspectorActions *sl = GTK_INSPECTOR_ACTIONS (object); + if (sl->object) + disconnect (sl); + g_clear_object (&sl->sorted); g_clear_object (&sl->actions); g_clear_object (&sl->object); @@ -451,12 +657,15 @@ gtk_inspector_actions_class_init (GtkInspectorActionsClass *klass) gtk_widget_class_bind_template_callback (widget_class, bind_name_cb); gtk_widget_class_bind_template_callback (widget_class, setup_enabled_cb); gtk_widget_class_bind_template_callback (widget_class, bind_enabled_cb); + gtk_widget_class_bind_template_callback (widget_class, unbind_enabled_cb); gtk_widget_class_bind_template_callback (widget_class, setup_parameter_cb); gtk_widget_class_bind_template_callback (widget_class, bind_parameter_cb); gtk_widget_class_bind_template_callback (widget_class, setup_state_cb); gtk_widget_class_bind_template_callback (widget_class, bind_state_cb); + gtk_widget_class_bind_template_callback (widget_class, unbind_state_cb); gtk_widget_class_bind_template_callback (widget_class, setup_changes_cb); gtk_widget_class_bind_template_callback (widget_class, bind_changes_cb); + gtk_widget_class_bind_template_callback (widget_class, unbind_changes_cb); gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT); } diff --git a/gtk/inspector/actions.ui b/gtk/inspector/actions.ui index a48b0ba638..55c3007f36 100644 --- a/gtk/inspector/actions.ui +++ b/gtk/inspector/actions.ui @@ -32,6 +32,7 @@ <object class="GtkSignalListItemFactory"> <signal name="setup" handler="setup_enabled_cb"/> <signal name="bind" handler="bind_enabled_cb"/> + <signal name="unbind" handler="unbind_enabled_cb"/> </object> </property> </object> @@ -54,6 +55,7 @@ <object class="GtkSignalListItemFactory"> <signal name="setup" handler="setup_state_cb"/> <signal name="bind" handler="bind_state_cb"/> + <signal name="unbind" handler="unbind_state_cb"/> </object> </property> </object> @@ -66,6 +68,7 @@ <object class="GtkSignalListItemFactory"> <signal name="setup" handler="setup_changes_cb"/> <signal name="bind" handler="bind_changes_cb"/> + <signal name="unbind" handler="unbind_changes_cb"/> </object> </property> </object> |